X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fnet_socket.c;h=1b49aeeb4090865dd357cc235e1dffc24fe0de72;hb=5b07039b0712bee0f19749d63116a10fb08a2d8b;hp=212649ba67f94c7013f0e65a302038caea6066ab;hpb=6bc5d626a8726fc23365ee705761a3c666a08ad4;p=tinc diff --git a/src/net_socket.c b/src/net_socket.c index 212649ba..1b49aeeb 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -1,7 +1,7 @@ /* net_socket.c -- Handle various kinds of sockets. Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2013 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -24,9 +24,11 @@ #include "conf.h" #include "connection.h" +#include "control_common.h" #include "list.h" #include "logger.h" #include "meta.h" +#include "names.h" #include "net.h" #include "netutl.h" #include "protocol.h" @@ -46,6 +48,9 @@ int udp_sndbuf = 0; listen_socket_t listen_socket[MAXSOCKETS]; int listen_sockets; +#ifndef HAVE_MINGW +io_t unix_socket; +#endif list_t *outgoing_list = NULL; /* Setup sockets */ @@ -289,10 +294,7 @@ void retry_outgoing(outgoing_t *outgoing) { void finish_connecting(connection_t *c) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); - if(proxytype != PROXY_EXEC) - configure_tcp(c); - - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; c->status.connecting = false; send_id(c); @@ -347,6 +349,9 @@ static void do_outgoing_pipe(connection_t *c, char *command) { } static void handle_meta_write(connection_t *c) { + if(c->outbuf.len <= c->outbuf.offset) + return; + ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); if(outlen <= 0) { if(!errno || errno == EPIPE) { @@ -368,10 +373,28 @@ static void handle_meta_write(connection_t *c) { } static void handle_meta_io(void *data, int flags) { + connection_t *c = data; + + if(c->status.connecting) { + c->status.connecting = false; + + int result; + socklen_t len = sizeof result; + getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&result, &len); + + if(!result) + finish_connecting(c); + else { + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(result)); + terminate_connection(c, false); + return; + } + } + if(flags & IO_WRITE) - handle_meta_write(data); + handle_meta_write(c); else - handle_meta_connection_data(data); + handle_meta_connection_data(c); } bool do_outgoing_connection(outgoing_t *outgoing) { @@ -436,6 +459,7 @@ begin: } logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport); c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP); + configure_tcp(c); } if(c->socket == -1) { @@ -484,11 +508,11 @@ begin: c->outdigest = myself->connection->outdigest; c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; connection_add(c); - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ|IO_WRITE); return true; } @@ -547,7 +571,7 @@ void handle_new_meta_connection(void *data, int flags) { c->address = sa; c->hostname = sockaddr2hostname(&sa); c->socket = fd; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); @@ -561,6 +585,45 @@ void handle_new_meta_connection(void *data, int flags) { send_id(c); } +#ifndef HAVE_MINGW +/* + accept a new UNIX socket connection +*/ +void handle_new_unix_connection(void *data, int flags) { + io_t *io = data; + connection_t *c; + sockaddr_t sa; + int fd; + socklen_t len = sizeof sa; + + fd = accept(io->fd, &sa.sa, &len); + + if(fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); + return; + } + + sockaddrunmap(&sa); + + c = new_connection(); + c->name = xstrdup(""); + c->address = sa; + c->hostname = xstrdup("localhost port unix"); + c->socket = fd; + c->last_ping_time = now.tv_sec; + + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); + + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); + + connection_add(c); + + c->allow_request = ID; + + send_id(c); +} +#endif + static void free_outgoing(outgoing_t *outgoing) { timeout_del(&outgoing->ev); @@ -611,7 +674,7 @@ void try_outgoing_connections(void) { } if(!found) { - outgoing_t *outgoing = xmalloc_and_zero(sizeof *outgoing); + outgoing_t *outgoing = xzalloc(sizeof *outgoing); outgoing->name = name; list_insert_tail(outgoing_list, outgoing); setup_outgoing_connection(outgoing);