From 075264a9e18f9fd58cad044c064a91557e9ed429 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 5 Nov 2009 23:29:28 +0100 Subject: [PATCH] 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. --- configure.in | 2 +- have.h | 4 ++++ lib/utils.h | 2 ++ src/control.c | 25 ++++++++++++++----- src/net.c | 7 ++++++ src/tincctl.c | 66 +++++++++++++++++++++++++++++++++++++++++---------- src/tincd.c | 12 ++++++---- 7 files changed, 94 insertions(+), 24 deletions(-) diff --git a/configure.in b/configure.in index 1db53d1c..573a30ee 100644 --- a/configure.in +++ b/configure.in @@ -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. 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], [], [], [#include "have.h"] ) diff --git a/have.h b/have.h index 49af8616..682fd2b7 100644 --- a/have.h +++ b/have.h @@ -100,6 +100,10 @@ #include #endif +#ifdef HAVE_SYS_UN_H +#include +#endif + /* SunOS really wants sys/socket.h BEFORE net/if.h, and FreeBSD wants these lines below the rest. */ diff --git a/lib/utils.h b/lib/utils.h index 4456616d..fddb8a67 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -32,12 +32,14 @@ extern const char *winerror(int); #define sockwouldblock(x) ((x) == WSAEWOULDBLOCK || (x) == WSAEINTR) #define sockmsgsize(x) ((x) == WSAEMSGSIZE) #define sockinprogress(x) ((x) == WSAEINPROGRESS || (x) == WSAEWOULDBLOCK) +#define sockinuse(x) ((x) == WSAEADDRINUSE) #else #define sockerrno errno #define sockstrerror(x) strerror(x) #define sockwouldblock(x) ((x) == EWOULDBLOCK || (x) == EINTR) #define sockmsgsize(x) ((x) == EMSGSIZE) #define sockinprogress(x) ((x) == EINPROGRESS) +#define sockinuse(x) ((x) == EADDRINUSE) #endif extern unsigned int bitfield_to_int(void *bitfield, size_t size); diff --git a/src/control.c b/src/control.c index 4775bdd4..8493f254 100644 --- a/src/control.c +++ b/src/control.c @@ -17,14 +17,13 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include - #include "system.h" #include "conf.h" #include "control.h" #include "control_common.h" #include "graph.h" #include "logger.h" +#include "utils.h" #include "xalloc.h" static int control_socket = -1; @@ -211,6 +210,16 @@ static int control_compare(const struct event *a, const struct event *b) { bool init_control() { 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; char *lastslash; @@ -261,16 +270,20 @@ bool init_control() { logger(LOG_ERR, "Control socket directory ownership/permissions insecure."); goto bail; } +#endif 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); +#ifndef HAVE_MINGW if(result < 0) { logger(LOG_WARNING, "Removing old control socket."); unlink(controlsocketname); result = bind(control_socket, (struct sockaddr *)&addr, sizeof addr); - } else { + } else +#endif + { if(netname) logger(LOG_ERR, "Another tincd is already running for net `%s'.", netname); else @@ -297,7 +310,7 @@ bool init_control() { bail: if(control_socket != -1) { - close(control_socket); + closesocket(control_socket); control_socket = -1; } return false; @@ -305,6 +318,6 @@ bail: void exit_control() { event_del(&control_event); - close(control_socket); + closesocket(control_socket); unlink(controlsocketname); } diff --git a/src/net.c b/src/net.c index 9445b68a..31cb3df5 100644 --- a/src/net.c +++ b/src/net.c @@ -307,12 +307,19 @@ int main_loop(void) { timeout_set(&timeout_event, timeout_handler, &timeout_event); event_add(&timeout_event, &(struct timeval){pingtimeout, 0}); + +#ifdef SIGHUP signal_set(&sighup_event, SIGHUP, sighup_handler, NULL); signal_add(&sighup_event, NULL); +#endif +#ifdef SIGTERM signal_set(&sigterm_event, SIGTERM, sigterm_handler, NULL); signal_add(&sigterm_event, NULL); +#endif +#ifdef SIGQUIT signal_set(&sigquit_event, SIGQUIT, sigterm_handler, NULL); signal_add(&sigquit_event, NULL); +#endif if(event_loop(0) < 0) { logger(LOG_ERR, "Error while waiting for input: %s", strerror(errno)); diff --git a/src/tincctl.c b/src/tincctl.c index f98547ba..7d82dc44 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -19,13 +19,13 @@ #include "system.h" -#include #include #include "xalloc.h" #include "protocol.h" #include "control_common.h" #include "rsagen.h" +#include "utils.h" /* The name this program was run with. */ char *program_name = NULL; @@ -47,6 +47,10 @@ static char *controlsocketname = NULL; /* pid file location */ char *netname = NULL; char *confbase = NULL; +#ifdef HAVE_MINGW +static struct WSAData wsa_state; +#endif + static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, {"net", required_argument, NULL, 'n'}, @@ -261,8 +265,6 @@ static void make_names(void) { #ifdef HAVE_MINGW if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) { - if(!logfilename) - xasprintf(&logfilename, "%s/log/%s.log", identname); if(!confbase) { if(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) return rv; else if(rv == 0) { +#ifdef HAVE_MINGW + errno = 0; +#else errno = ENODATA; +#endif return -1; } len += rv; @@ -317,23 +323,29 @@ static int send_ctl_request(int fd, enum request_type type, size_t *indatalen_p) { tinc_ctl_request_t req; int rv; + void *indata; + + memset(&req, 0, sizeof req); + req.length = sizeof req + outdatalen; + req.type = type; + 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} }; - void *indata; if(res_errno_p == NULL) return -1; - memset(&req, 0, sizeof req); - req.length = sizeof req + outdatalen; - req.type = type; - req.res_errno = 0; - while((rv = writev(fd, vector, 2)) == -1 && errno == EINTR) ; if(rv != req.length) return -1; +#endif if(fullread(fd, &req, sizeof req) == -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[]) { - struct sockaddr_un addr; tinc_ctl_greeting_t greeting; int fd; 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. */ +#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; char *lastslash = strrchr(controlsocketname, '/'); if(lastslash != NULL) { @@ -483,15 +521,19 @@ int main(int argc, char *argv[], char *envp[]) { memset(&addr, 0, sizeof addr); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, controlsocketname, sizeof addr.sun_path - 1); +#endif 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; } + fprintf(stderr, "Connected!\n"); + if(fullread(fd, &greeting, sizeof greeting) == -1) { fprintf(stderr, "Cannot read greeting from control socket: %s\n", - strerror(errno)); + sockstrerror(sockerrno)); return 1; } diff --git a/src/tincd.c b/src/tincd.c index 1a9bad0d..1761dc21 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -345,6 +345,13 @@ int main(int argc, char **argv) { 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); if(!event_init()) { @@ -373,11 +380,6 @@ int main(int argc, char **argv) { } #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()) return main2(argc, argv); else -- 2.39.5