X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet.c;h=f8c7306d18bdc7512f20b082e18b1b8aa2a61e2a;hp=83824df72dceafae5f09ce6b8236b93ecd222bd3;hb=b9a86ec70ed4ffe5009c4979454f0d99c8559b45;hpb=505b5ec2cd9d6cf3dc655284a8c4041ce8527a07 diff --git a/src/net.c b/src/net.c index 83824df7..f8c7306d 100644 --- a/src/net.c +++ b/src/net.c @@ -1,6 +1,6 @@ /* net.c -- most of the network code - Copyright (C) 1998,99 Ivo Timmermans + Copyright (C) 1998,1999,2000 Ivo Timmermans This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,8 +51,6 @@ int total_tap_out = 0; int total_socket_in = 0; int total_socket_out = 0; -time_t last_ping_time = 0; - /* The global list of existing connections */ conn_list_t *conn_list = NULL; conn_list_t *myself = NULL; @@ -94,8 +92,8 @@ int xsend(conn_list_t *cl, void *packet) cp do_encrypt((vpn_packet_t*)packet, &rp, cl->key); rp.from = htonl(myself->vpn_ip); - rp.data->len = htons(rp.data->len); - rp.len = htons(rp.data->len); + rp.data.len = htons(rp.data.len); + rp.len = htons(rp.len); if(debug_lvl > 3) syslog(LOG_ERR, "Sent %d bytes to %lx", ntohs(rp.len), cl->vpn_ip); @@ -107,6 +105,8 @@ cp } total_socket_out += r; + + cl->want_ping = 1; cp return 0; } @@ -116,10 +116,6 @@ int xrecv(conn_list_t *cl, void *packet) vpn_packet_t vp; int lenin; cp - packet->data->len = ntohs(packet->data->len); - packet->len = ntohs(packet->len); - packet->from = ntohl(packet->from); - do_decrypt((real_packet_t*)packet, &vp, cl->key); add_mac_addresses(&vp); @@ -127,6 +123,9 @@ cp syslog(LOG_ERR, "Can't write to tap device: %m"); else total_tap_out += lenin; + + cl->want_ping = 0; + cl->last_ping_time = time(NULL); cp return 0; } @@ -308,21 +307,6 @@ cp return xsend(cl, packet); } -int send_broadcast(conn_list_t *cl, vpn_packet_t *packet) -{ - conn_list_t *p; -cp - for(p = cl; p != NULL; p = p->next) - if(send_packet(p->real_ip, packet) < 0) - { - syslog(LOG_ERR, "Could not send a broadcast packet to %08lx (%08lx): %m", - p->vpn_ip, p->real_ip); - break; /* FIXME: should retry later, and send a ping over the metaconnection. */ - } -cp - return 0; -} - /* open the local ethertap device */ @@ -565,7 +549,7 @@ int setup_network_connections(void) config_t const *cfg; cp if((cfg = get_config_val(pingtimeout)) == NULL) - timeout = 10; + timeout = 5; else timeout = cfg->data.val; @@ -670,8 +654,8 @@ cp if(connect(nfd, (struct sockaddr *)&a, sizeof(a)) == -1) { - syslog(LOG_ERR, "Create connection to %08lx:%d failed: %m", ntohs(cl->real_ip), - cl->port); + syslog(LOG_ERR, "Connecting to " IP_ADDR_S ":%d failed: %m", + IP_ADDR_V(cl->real_ip), cl->port); return -1; } @@ -711,6 +695,8 @@ cp p->meta_socket = sfd; p->status.meta = 1; p->buflen = 0; + p->last_ping_time = time(NULL); + p->want_ping = 0; syslog(LOG_NOTICE, "Connection from %s:%d", p->hostname, htons(ci.sin_port)); @@ -777,6 +763,11 @@ cp return -1; } total_socket_in += lenin; + + rp.data.len = ntohs(rp.data.len); + rp.len = ntohs(rp.len); + rp.from = ntohl(rp.from); + if(rp.len >= 0) { f = lookup_conn(rp.from); @@ -840,52 +831,42 @@ cp } /* - send out a ping request to all active - connections -*/ -int send_broadcast_ping(void) -{ - conn_list_t *p; -cp - for(p = conn_list; p != NULL; p = p->next) - { - if(p->status.remove) - continue; - if(p->status.active && p->status.meta) - { - if(send_ping(p)) - terminate_connection(p); - else - { - p->status.pinged = 1; - p->status.got_pong = 0; - } - } - } - - last_ping_time = time(NULL); -cp - return 0; -} - -/* - end all connections that did not respond - to the ping probe in time + Check if the other end is active. + If we have sent packets, but didn't receive any, + then possibly the other end is dead. We send a + PING request over the meta connection. If the other + end does not reply in time, we consider them dead + and close the connection. */ int check_dead_connections(void) { conn_list_t *p; + time_t now; cp + now = time(NULL); for(p = conn_list; p != NULL; p = p->next) { if(p->status.remove) continue; - if(p->status.active && p->status.meta && p->status.pinged && !p->status.got_pong) + if(p->status.active && p->status.meta) { - syslog(LOG_INFO, "%s (" IP_ADDR_S ") didn't respond to ping", - p->hostname, IP_ADDR_V(p->vpn_ip)); - p->status.timeout = 1; - terminate_connection(p); + if(p->last_ping_time + timeout < now) + { + if(p->status.pinged && !p->status.got_pong) + { + syslog(LOG_INFO, "%s (" IP_ADDR_S ") didn't respond to ping", + p->hostname, IP_ADDR_V(p->vpn_ip)); + p->status.timeout = 1; + terminate_connection(p); + } + else if(p->want_ping) + { + send_ping(p); + p->last_ping_time = now; + p->status.pinged = 1; + p->status.got_pong = 0; + } + } } } cp @@ -929,7 +910,7 @@ cp int handle_incoming_meta_data(conn_list_t *cl) { int x, l = sizeof(x); - int request, oldlen, p, i; + int request, oldlen, i; int lenin = 0; cp if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0) @@ -1003,6 +984,9 @@ cp break; } } + + cl->last_ping_time = time(NULL); + cl->want_ping = 0; cp return 0; } @@ -1114,8 +1098,9 @@ void main_loop(void) fd_set fset; struct timeval tv; int r; + time_t last_ping_check; cp - last_ping_time = time(NULL); + last_ping_check = time(NULL); for(;;) { @@ -1133,11 +1118,11 @@ cp return; } - if(r == 0 || last_ping_time + timeout < time(NULL)) - /* Timeout... hm... something might be wrong. */ + if(last_ping_check + timeout < time(NULL)) + /* Let's check if everybody is still alive */ { check_dead_connections(); - send_broadcast_ping(); + last_ping_check = time(NULL); continue; }