X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet.c;h=b6007b4871a4781341ea51ad1038df735640e797;hp=7b9133e0c02d005761300fa24a4bcf03fa8ae1b6;hb=e20e143f1e99bdc0a7d92e97da1bd0dc40e8a83b;hpb=8caa1b9d750bb7467d1c3330780b05ac2bbf9883 diff --git a/src/net.c b/src/net.c index 7b9133e0..b6007b48 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,6 +105,8 @@ cp } total_socket_out += r; + + cl->want_ping = 1; cp return 0; } @@ -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; @@ -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,41 @@ 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.get_pong = 0; + } + } } } cp @@ -1004,6 +983,9 @@ cp break; } } + + cl->last_ping_time = time(NULL); + cl->want_ping = 0; cp return 0; } @@ -1115,8 +1097,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 +1117,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; }