X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet.c;h=f8c7306d18bdc7512f20b082e18b1b8aa2a61e2a;hp=b3474c371b8bf85cf37d37948a9b6eba1cc6e6bf;hb=803f908078e87f433727a3ddf2d61734e1ed9233;hpb=78532475238b23eb52ac88d905fbf966d97a79d2 diff --git a/src/net.c b/src/net.c index b3474c37..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; @@ -107,11 +105,13 @@ cp } total_socket_out += r; + + cl->want_ping = 1; cp return 0; } -int xrecv(conn_list_t *cl, real_packet_t *packet) +int xrecv(conn_list_t *cl, void *packet) { vpn_packet_t vp; int lenin; @@ -123,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; } @@ -304,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 */ @@ -561,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; @@ -666,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; } @@ -707,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)); @@ -841,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 @@ -1004,6 +984,9 @@ cp break; } } + + cl->last_ping_time = time(NULL); + cl->want_ping = 0; cp return 0; } @@ -1115,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(;;) { @@ -1134,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; }