X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet.c;h=f4de67f205f73101923e939d8c14773776a8f291;hp=5a456832ed36dceb31fc9592d0c8de90e5ad7130;hb=173d606514d82fc5ae7895a178238d0abcaf6606;hpb=a56df1e06be3f47a775919e564c147687e961b5d diff --git a/src/net.c b/src/net.c index 5a456832..f4de67f2 100644 --- a/src/net.c +++ b/src/net.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: net.c,v 1.35.4.94 2001/01/13 16:36:21 guus Exp $ + $Id: net.c,v 1.35.4.99 2001/02/27 16:17:04 guus Exp $ */ #include "config.h" @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include #include @@ -112,7 +114,7 @@ int xsend(connection_t *cl, vpn_packet_t *inpkt) cp outpkt.len = inpkt->len; - /* Encrypt the packet. FIXME: we should use CBC, not CFB. */ + /* Encrypt the packet. */ EVP_EncryptInit(&ctx, cl->cipher_pkttype, cl->cipher_pktkey, cl->cipher_pktkey + cl->cipher_pkttype->key_len); EVP_EncryptUpdate(&ctx, outpkt.data, &outlen, inpkt->data, inpkt->len); @@ -202,6 +204,7 @@ int send_packet(ip_t to, vpn_packet_t *packet) { connection_t *cl; subnet_t *subnet; + vpn_packet_t *copy; cp if((subnet = lookup_subnet_ipv4(&to)) == NULL) { @@ -242,7 +245,13 @@ cp syslog(LOG_INFO, _("No valid key known yet for %s (%s), queueing packet"), cl->name, cl->hostname); - list_insert_tail(cl->queue, packet); + /* Since packet is on the stack of handle_tap_input(), + we have to make a copy of it first. */ + + copy = xmalloc(sizeof(vpn_packet_t)); + memcpy(copy, packet, sizeof(vpn_packet_t)); + + list_insert_tail(cl->queue, copy); if(!cl->status.waitingforkey) send_req_key(myself, cl); /* Keys should be sent to the host running the tincd */ @@ -260,7 +269,7 @@ cp void flush_queue(connection_t *cl) { list_node_t *node, *next; - +cp if(debug_lvl >= DEBUG_TRAFFIC) syslog(LOG_INFO, _("Flushing queue for %s (%s)"), cl->name, cl->hostname); @@ -270,6 +279,7 @@ void flush_queue(connection_t *cl) xsend(cl, (vpn_packet_t *)node->data); list_delete_node(cl->queue, node); } +cp } /* @@ -357,7 +367,7 @@ int setup_listen_meta_socket(int port) { int nfd, flags; struct sockaddr_in a; - const int one = 1; + int option; config_t const *cfg; cp if((nfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) @@ -366,22 +376,6 @@ cp return -1; } - if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) - { - close(nfd); - syslog(LOG_ERR, _("System call `%s' failed: %m"), - "setsockopt"); - return -1; - } - - if(setsockopt(nfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one))) - { - close(nfd); - syslog(LOG_ERR, _("System call `%s' failed: %m"), - "setsockopt"); - return -1; - } - flags = fcntl(nfd, F_GETFL); if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) { @@ -391,9 +385,19 @@ cp return -1; } + /* Optimize TCP settings */ + + option = 1; + setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); + setsockopt(nfd, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option)); + setsockopt(nfd, SOL_TCP, TCP_NODELAY, &option, sizeof(option)); + + option = IPTOS_LOWDELAY; + setsockopt(nfd, SOL_IP, IP_TOS, &option, sizeof(option)); + if((cfg = get_config_val(config, config_interface))) { - if(setsockopt(nfd, SOL_SOCKET, SO_KEEPALIVE, cfg->data.ptr, strlen(cfg->data.ptr))) + if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, cfg->data.ptr, strlen(cfg->data.ptr))) { close(nfd); syslog(LOG_ERR, _("Unable to bind listen socket to interface %s: %m"), cfg->data.ptr); @@ -445,13 +449,7 @@ cp return -1; } - if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) - { - close(nfd); - syslog(LOG_ERR, _("System call `%s' failed: %m"), - "setsockopt"); - return -1; - } + setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); flags = fcntl(nfd, F_GETFL); if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) @@ -485,6 +483,7 @@ int setup_outgoing_meta_socket(connection_t *cl) int flags; struct sockaddr_in a; config_t const *cfg; + int option; cp if(debug_lvl >= DEBUG_CONNECTIONS) syslog(LOG_INFO, _("Trying to connect to %s"), cl->hostname); @@ -514,6 +513,17 @@ cp syslog(LOG_ERR, _("System call `%s' failed: %m"), "bind"); return -1; } + + /* Optimize TCP settings */ + + option = 1; + setsockopt(cl->meta_socket, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option)); + setsockopt(cl->meta_socket, SOL_TCP, TCP_NODELAY, &option, sizeof(option)); + + option = IPTOS_LOWDELAY; + setsockopt(cl->meta_socket, SOL_IP, IP_TOS, &option, sizeof(option)); + + /* Connect */ a.sin_family = AF_INET; a.sin_port = htons(cl->port); @@ -808,7 +818,7 @@ cp cp /* Generate packet encryption key */ - myself->cipher_pkttype = EVP_bf_cfb(); + myself->cipher_pkttype = EVP_bf_cbc(); myself->cipher_pktkeylength = myself->cipher_pkttype->key_len + myself->cipher_pkttype->iv_len; @@ -981,13 +991,7 @@ cp return -1; } - if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) - { - close(nfd); - syslog(LOG_ERR, _("System call `%s' failed: %m"), - "setsockopt"); - return -1; - } + setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); flags = fcntl(nfd, F_GETFL); if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) @@ -1209,8 +1213,9 @@ cp /* Check if this was our outgoing connection */ - if(cl->status.outgoing && cl->status.active) + if(cl->status.outgoing) { + cl->status.outgoing = 0; signal(SIGALRM, sigalrm_handler); seconds_till_retry = 5; alarm(seconds_till_retry); @@ -1289,6 +1294,8 @@ cp } connection_add(ncn); + + send_id(ncn); cp return 0; }