Make sure the 1.1 branch compiles in a MinGW environment.

UNIX domain sockets, of course, don't exist on Windows. For now, when compiling
tinc in a MinGW environment, try to use a TCP socket bound to localhost as an
alternative.
This commit is contained in:
Guus Sliepen 2009-11-05 23:29:28 +01:00
parent 08615e420b
commit 075264a9e1
7 changed files with 95 additions and 25 deletions

View file

@ -98,7 +98,7 @@ dnl Checks for header files.
dnl We do this in multiple stages, because unlike Linux all the other operating systems really suck and don't include their own dependencies. dnl We do this in multiple stages, because unlike Linux all the other operating systems really suck and don't include their own dependencies.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h]) AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/un.h sys/wait.h netdb.h arpa/inet.h])
AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h], AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h],
[], [], [#include "have.h"] [], [], [#include "have.h"]
) )

4
have.h
View file

@ -100,6 +100,10 @@
#include <sys/uio.h> #include <sys/uio.h>
#endif #endif
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
/* SunOS really wants sys/socket.h BEFORE net/if.h, /* SunOS really wants sys/socket.h BEFORE net/if.h,
and FreeBSD wants these lines below the rest. */ and FreeBSD wants these lines below the rest. */

View file

@ -32,12 +32,14 @@ extern const char *winerror(int);
#define sockwouldblock(x) ((x) == WSAEWOULDBLOCK || (x) == WSAEINTR) #define sockwouldblock(x) ((x) == WSAEWOULDBLOCK || (x) == WSAEINTR)
#define sockmsgsize(x) ((x) == WSAEMSGSIZE) #define sockmsgsize(x) ((x) == WSAEMSGSIZE)
#define sockinprogress(x) ((x) == WSAEINPROGRESS || (x) == WSAEWOULDBLOCK) #define sockinprogress(x) ((x) == WSAEINPROGRESS || (x) == WSAEWOULDBLOCK)
#define sockinuse(x) ((x) == WSAEADDRINUSE)
#else #else
#define sockerrno errno #define sockerrno errno
#define sockstrerror(x) strerror(x) #define sockstrerror(x) strerror(x)
#define sockwouldblock(x) ((x) == EWOULDBLOCK || (x) == EINTR) #define sockwouldblock(x) ((x) == EWOULDBLOCK || (x) == EINTR)
#define sockmsgsize(x) ((x) == EMSGSIZE) #define sockmsgsize(x) ((x) == EMSGSIZE)
#define sockinprogress(x) ((x) == EINPROGRESS) #define sockinprogress(x) ((x) == EINPROGRESS)
#define sockinuse(x) ((x) == EADDRINUSE)
#endif #endif
extern unsigned int bitfield_to_int(void *bitfield, size_t size); extern unsigned int bitfield_to_int(void *bitfield, size_t size);

View file

@ -17,14 +17,13 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include <sys/un.h>
#include "system.h" #include "system.h"
#include "conf.h" #include "conf.h"
#include "control.h" #include "control.h"
#include "control_common.h" #include "control_common.h"
#include "graph.h" #include "graph.h"
#include "logger.h" #include "logger.h"
#include "utils.h"
#include "xalloc.h" #include "xalloc.h"
static int control_socket = -1; static int control_socket = -1;
@ -211,6 +210,16 @@ static int control_compare(const struct event *a, const struct event *b) {
bool init_control() { bool init_control() {
int result; int result;
#ifdef HAVE_MINGW
struct sockaddr_in addr;
memset(&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(0x7f000001);
addr.sin_port = htons(55555);
control_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
#else
struct sockaddr_un addr; struct sockaddr_un addr;
char *lastslash; char *lastslash;
@ -261,16 +270,20 @@ bool init_control() {
logger(LOG_ERR, "Control socket directory ownership/permissions insecure."); logger(LOG_ERR, "Control socket directory ownership/permissions insecure.");
goto bail; goto bail;
} }
#endif
result = bind(control_socket, (struct sockaddr *)&addr, sizeof addr); result = bind(control_socket, (struct sockaddr *)&addr, sizeof addr);
if(result < 0 && errno == EADDRINUSE) { if(result < 0 && sockinuse(sockerrno)) {
result = connect(control_socket, (struct sockaddr *)&addr, sizeof addr); result = connect(control_socket, (struct sockaddr *)&addr, sizeof addr);
#ifndef HAVE_MINGW
if(result < 0) { if(result < 0) {
logger(LOG_WARNING, "Removing old control socket."); logger(LOG_WARNING, "Removing old control socket.");
unlink(controlsocketname); unlink(controlsocketname);
result = bind(control_socket, (struct sockaddr *)&addr, sizeof addr); result = bind(control_socket, (struct sockaddr *)&addr, sizeof addr);
} else { } else
#endif
{
if(netname) if(netname)
logger(LOG_ERR, "Another tincd is already running for net `%s'.", netname); logger(LOG_ERR, "Another tincd is already running for net `%s'.", netname);
else else
@ -297,7 +310,7 @@ bool init_control() {
bail: bail:
if(control_socket != -1) { if(control_socket != -1) {
close(control_socket); closesocket(control_socket);
control_socket = -1; control_socket = -1;
} }
return false; return false;
@ -305,6 +318,6 @@ bail:
void exit_control() { void exit_control() {
event_del(&control_event); event_del(&control_event);
close(control_socket); closesocket(control_socket);
unlink(controlsocketname); unlink(controlsocketname);
} }

View file

@ -307,12 +307,19 @@ int main_loop(void) {
timeout_set(&timeout_event, timeout_handler, &timeout_event); timeout_set(&timeout_event, timeout_handler, &timeout_event);
event_add(&timeout_event, &(struct timeval){pingtimeout, 0}); event_add(&timeout_event, &(struct timeval){pingtimeout, 0});
#ifdef SIGHUP
signal_set(&sighup_event, SIGHUP, sighup_handler, NULL); signal_set(&sighup_event, SIGHUP, sighup_handler, NULL);
signal_add(&sighup_event, NULL); signal_add(&sighup_event, NULL);
#endif
#ifdef SIGTERM
signal_set(&sigterm_event, SIGTERM, sigterm_handler, NULL); signal_set(&sigterm_event, SIGTERM, sigterm_handler, NULL);
signal_add(&sigterm_event, NULL); signal_add(&sigterm_event, NULL);
#endif
#ifdef SIGQUIT
signal_set(&sigquit_event, SIGQUIT, sigterm_handler, NULL); signal_set(&sigquit_event, SIGQUIT, sigterm_handler, NULL);
signal_add(&sigquit_event, NULL); signal_add(&sigquit_event, NULL);
#endif
if(event_loop(0) < 0) { if(event_loop(0) < 0) {
logger(LOG_ERR, "Error while waiting for input: %s", strerror(errno)); logger(LOG_ERR, "Error while waiting for input: %s", strerror(errno));

View file

@ -19,13 +19,13 @@
#include "system.h" #include "system.h"
#include <sys/un.h>
#include <getopt.h> #include <getopt.h>
#include "xalloc.h" #include "xalloc.h"
#include "protocol.h" #include "protocol.h"
#include "control_common.h" #include "control_common.h"
#include "rsagen.h" #include "rsagen.h"
#include "utils.h"
/* The name this program was run with. */ /* The name this program was run with. */
char *program_name = NULL; char *program_name = NULL;
@ -47,6 +47,10 @@ static char *controlsocketname = NULL; /* pid file location */
char *netname = NULL; char *netname = NULL;
char *confbase = NULL; char *confbase = NULL;
#ifdef HAVE_MINGW
static struct WSAData wsa_state;
#endif
static struct option const long_options[] = { static struct option const long_options[] = {
{"config", required_argument, NULL, 'c'}, {"config", required_argument, NULL, 'c'},
{"net", required_argument, NULL, 'n'}, {"net", required_argument, NULL, 'n'},
@ -261,8 +265,6 @@ static void make_names(void) {
#ifdef HAVE_MINGW #ifdef HAVE_MINGW
if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) {
if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) { if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) {
if(!logfilename)
xasprintf(&logfilename, "%s/log/%s.log", identname);
if(!confbase) { if(!confbase) {
if(netname) if(netname)
xasprintf(&confbase, "%s/%s", installdir, netname); xasprintf(&confbase, "%s/%s", installdir, netname);
@ -300,7 +302,11 @@ static int fullread(int fd, void *data, size_t datalen) {
else if(rv == -1) else if(rv == -1)
return rv; return rv;
else if(rv == 0) { else if(rv == 0) {
#ifdef HAVE_MINGW
errno = 0;
#else
errno = ENODATA; errno = ENODATA;
#endif
return -1; return -1;
} }
len += rv; len += rv;
@ -317,23 +323,29 @@ static int send_ctl_request(int fd, enum request_type type,
size_t *indatalen_p) { size_t *indatalen_p) {
tinc_ctl_request_t req; tinc_ctl_request_t req;
int rv; int rv;
struct iovec vector[2] = {
{&req, sizeof req},
{(void*) outdata, outdatalen}
};
void *indata; void *indata;
if(res_errno_p == NULL)
return -1;
memset(&req, 0, sizeof req); memset(&req, 0, sizeof req);
req.length = sizeof req + outdatalen; req.length = sizeof req + outdatalen;
req.type = type; req.type = type;
req.res_errno = 0; req.res_errno = 0;
#ifdef HAVE_MINGW
if(send(fd, (void *)&req, sizeof req, 0) != sizeof req || send(fd, outdata, outdatalen, 0) != outdatalen)
return -1;
#else
struct iovec vector[2] = {
{&req, sizeof req},
{(void*) outdata, outdatalen}
};
if(res_errno_p == NULL)
return -1;
while((rv = writev(fd, vector, 2)) == -1 && errno == EINTR) ; while((rv = writev(fd, vector, 2)) == -1 && errno == EINTR) ;
if(rv != req.length) if(rv != req.length)
return -1; return -1;
#endif
if(fullread(fd, &req, sizeof req) == -1) if(fullread(fd, &req, sizeof req) == -1)
return -1; return -1;
@ -394,7 +406,6 @@ static int send_ctl_request_cooked(int fd, enum request_type type, void const *o
} }
int main(int argc, char *argv[], char *envp[]) { int main(int argc, char *argv[], char *envp[]) {
struct sockaddr_un addr;
tinc_ctl_greeting_t greeting; tinc_ctl_greeting_t greeting;
int fd; int fd;
int result; int result;
@ -449,6 +460,33 @@ int main(int argc, char *argv[], char *envp[]) {
* ancestors are writable only by trusted users, which we don't verify. * ancestors are writable only by trusted users, which we don't verify.
*/ */
#ifdef HAVE_MINGW
if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
return 1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(0x7f000001);
addr.sin_port = htons(55555);
fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(fd < 0) {
fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno));
return 1;
}
fprintf(stderr, "Got socket %d\n", fd);
unsigned long arg = 0;
if(ioctlsocket(fd, FIONBIO, &arg) != 0) {
fprintf(stderr, "ioctlsocket failed: %s", sockstrerror(sockerrno));
}
#else
struct sockaddr_un addr;
struct stat statbuf; struct stat statbuf;
char *lastslash = strrchr(controlsocketname, '/'); char *lastslash = strrchr(controlsocketname, '/');
if(lastslash != NULL) { if(lastslash != NULL) {
@ -483,15 +521,19 @@ int main(int argc, char *argv[], char *envp[]) {
memset(&addr, 0, sizeof addr); memset(&addr, 0, sizeof addr);
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, controlsocketname, sizeof addr.sun_path - 1); strncpy(addr.sun_path, controlsocketname, sizeof addr.sun_path - 1);
#endif
if(connect(fd, (struct sockaddr *)&addr, sizeof addr) < 0) { if(connect(fd, (struct sockaddr *)&addr, sizeof addr) < 0) {
fprintf(stderr, "Cannot connect to %s: %s\n", controlsocketname, strerror(errno));
fprintf(stderr, "Cannot connect to %s: %s\n", controlsocketname, sockstrerror(sockerrno));
return 1; return 1;
} }
fprintf(stderr, "Connected!\n");
if(fullread(fd, &greeting, sizeof greeting) == -1) { if(fullread(fd, &greeting, sizeof greeting) == -1) {
fprintf(stderr, "Cannot read greeting from control socket: %s\n", fprintf(stderr, "Cannot read greeting from control socket: %s\n",
strerror(errno)); sockstrerror(sockerrno));
return 1; return 1;
} }

View file

@ -345,6 +345,13 @@ int main(int argc, char **argv) {
return 0; return 0;
} }
#ifdef HAVE_MINGW
if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
logger(LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
return 1;
}
#endif
openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR);
if(!event_init()) { if(!event_init()) {
@ -373,11 +380,6 @@ int main(int argc, char **argv) {
} }
#ifdef HAVE_MINGW #ifdef HAVE_MINGW
if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
logger(LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
return 1;
}
if(!do_detach || !init_service()) if(!do_detach || !init_service())
return main2(argc, argv); return main2(argc, argv);
else else