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:
parent
08615e420b
commit
075264a9e1
7 changed files with 95 additions and 25 deletions
|
@ -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
4
have.h
|
@ -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. */
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/tincd.c
12
src/tincd.c
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue