--- gvpe/src/vpn_tcp.C 2007/11/10 05:14:23 1.17 +++ gvpe/src/vpn_tcp.C 2008/08/07 17:54:27 1.26 @@ -1,32 +1,42 @@ /* vpn_tcp.C -- handle the tcp part of the protocol. - Copyright (C) 2003-2005 Marc Lehmann + Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. - GVPE is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with gvpe; if not, write to the Free Software - Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + GVPE is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . + + Additional permission under GNU GPL version 3 section 7 + + If you modify this Program, or any covered work, by linking or + combining it with the OpenSSL project's OpenSSL library (or a modified + version of that library), containing parts covered by the terms of the + OpenSSL or SSLeay licenses, the licensors of this Program grant you + additional permission to convey the resulting work. Corresponding + Source for a non-source form of such a combination shall include the + source code for the parts of OpenSSL used as well as that of the + covered work. */ #include "config.h" #if ENABLE_TCP -// tcp processing is extremely ugly, since the vpe protocol is simply +// tcp processing is extremely ugly, since the gvpe protocol is simply // designed for unreliable datagram networks. tcp is implemented by // multiplexing packets over tcp. errors are completely ignored, as we -// rely on the higher level protocol to time out and reconnect. +// rely on the higher level layers to time out and reconnect. #include @@ -59,18 +69,22 @@ } }; -struct tcp_si_map : public map { - void cleaner_cb (ev::timer &w, int revents); ev::timer cleaner; +struct tcp_si_map : public map +{ + inline void cleaner_cb (ev::timer &w, int revents); ev::timer cleaner; tcp_si_map () - : cleaner(this, &tcp_si_map::cleaner_cb) { - cleaner.start (300, 300); + ev_default_loop (0); + cleaner.set (this); + cleaner.start (::conf.keepalive / 2, ::conf.keepalive / 2); } } tcp_si; -struct tcp_connection : ev::io { +struct tcp_connection : ev::io +{ + int tos; tstamp last_activity; const sockinfo si; vpn &v; @@ -88,7 +102,7 @@ int proxy_req_len; #endif - void tcpv4_ev (ev::io &w, int revents); + inline void tcpv4_ev (ev::io &w, int revents); bool send_packet (vpn_packet *pkt, int tos); bool write_packet (); @@ -106,13 +120,14 @@ void tcp_si_map::cleaner_cb (ev::timer &w, int revents) { - tstamp to = ev::ev_now () - ::conf.keepalive - 30 - 60; + tstamp to = ev_now () - ::conf.keepalive - 30 - 60; for (iterator i = begin (); i != end(); ) if (i->second->last_activity >= to) ++i; else { + delete i->second; erase (i); i = begin (); } @@ -202,7 +217,7 @@ void tcp_connection::tcpv4_ev (ev::io &w, int revents) { - last_activity = ev::ev_now (); + last_activity = ev_now (); if (revents & EV_WRITE) { @@ -347,7 +362,7 @@ bool tcp_connection::send_packet (vpn_packet *pkt, int tos) { - last_activity = ev::ev_now (); + last_activity = ev_now (); if (state == IDLE) { @@ -410,7 +425,11 @@ // how this maps to the underlying tcp packets we don't know // and we don't care. at least we tried ;) #if defined(SOL_IP) && defined(IP_TOS) - setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos); + if (tos != this->tos) + { + this->tos = tos; + setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos); + } #endif w_pkt = pkt; @@ -434,10 +453,13 @@ void tcp_connection::error () { + stop (); + if (fd >= 0) { close (fd); - fd = -1; + tos = -1; + fd = -1; } delete r_pkt; r_pkt = 0; @@ -446,19 +468,18 @@ free (proxy_req); proxy_req = 0; #endif - stop (); state = active ? IDLE : ERROR; } tcp_connection::tcp_connection (int fd_, const sockinfo &si_, vpn &v_) -: v(v_), si(si_), ev::io(this, &tcp_connection::tcpv4_ev) +: v(v_), si(si_) { - if (!tcp_si.cleaner.active) - tcp_si.cleaner.start (0); + set (this); - last_activity = ev::ev_now (); + last_activity = ev_now (); r_pkt = 0; w_pkt = 0; + tos = -1; fd = fd_; #if ENABLE_HTTP_PROXY proxy_req = 0;