--- gvpe/src/vpn.C 2005/04/19 03:47:32 1.37 +++ gvpe/src/vpn.C 2007/12/04 15:01:12 1.43 @@ -1,6 +1,6 @@ /* vpn.C -- handle the protocol, encryption, handshaking etc. - Copyright (C) 2003-2005 Marc Lehmann + Copyright (C) 2003-2007 Marc Lehmann This file is part of GVPE. @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with gvpe; if not, write to the Free Software - Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" @@ -48,6 +48,18 @@ ///////////////////////////////////////////////////////////////////////////// +static void inline +set_tos (int fd, int &tos_prev, int tos) +{ +#if defined(SOL_IP) && defined(IP_TOS) + if (tos_prev == tos) + return; + + tos_prev = tos; + setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos); +#endif +} + void vpn::script_init_env () { @@ -100,7 +112,8 @@ int vpn::setup () { - ipv4_fd = -1; + ipv4_tos = -1; + ipv4_fd = -1; if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) { @@ -130,10 +143,11 @@ exit (EXIT_FAILURE); } - ipv4_ev_watcher.start (ipv4_fd, EVENT_READ); + ipv4_ev_watcher.start (ipv4_fd, EV_READ); } - udpv4_fd = -1; + udpv4_tos = -1; + udpv4_fd = -1; if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) { @@ -169,10 +183,11 @@ exit (EXIT_FAILURE); } - udpv4_ev_watcher.start (udpv4_fd, EVENT_READ); + udpv4_ev_watcher.start (udpv4_fd, EV_READ); } - icmpv4_fd = -1; + icmpv4_tos = -1; + icmpv4_fd = -1; #if ENABLE_ICMP if (THISNODE->protocols & PROT_ICMPv4) @@ -214,7 +229,7 @@ exit (EXIT_FAILURE); } - icmpv4_ev_watcher.start (icmpv4_fd, EVENT_READ); + icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); } #endif @@ -251,10 +266,13 @@ exit (EXIT_FAILURE); } - tcpv4_ev_watcher.start (tcpv4_fd, EVENT_READ); + tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); } #endif + dnsv4_tos = -1; + dnsv4_fd = -1; + #if ENABLE_DNS if (THISNODE->protocols & PROT_DNSv4) { @@ -294,7 +312,7 @@ exit (EXIT_FAILURE); } - dnsv4_ev_watcher.start (dnsv4_fd, EVENT_READ); + dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); } #endif @@ -313,21 +331,25 @@ fcntl (tap->fd, F_SETFD, FD_CLOEXEC); + run_script_cb cb; + + callback_set (cb, this, vpn, script_if_init); if (tap->if_up () && - !run_script (run_script_cb (this, &vpn::script_if_init), true)) + !run_script (cb, true)) { slog (L_ERR, _("interface initialization command '%s' failed, exiting."), tap->if_up ()); exit (EXIT_FAILURE); } - if (!run_script (run_script_cb (this, &vpn::script_if_up), true)) + callback_set (cb, this, vpn, script_if_up); + if (!run_script (cb, true)) { slog (L_ERR, _("if-up command execution failed, exiting.")); exit (EXIT_FAILURE); } - tap_ev_watcher.start (tap->fd, EVENT_READ); + tap_ev_watcher.start (tap->fd, EV_READ); return 0; } @@ -335,9 +357,7 @@ bool vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) { -#if defined(SOL_IP) && defined(IP_TOS) - setsockopt (ipv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos); -#endif + set_tos (ipv4_fd, ipv4_tos, tos); sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); return true; @@ -370,10 +390,6 @@ bool vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) { -#if defined(SOL_IP) && defined(IP_TOS) - setsockopt (icmpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos); -#endif - pkt->unshift_hdr (4); icmp_header *hdr = (icmp_header *)&((*pkt)[0]); @@ -382,6 +398,7 @@ hdr->checksum = 0; hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); + set_tos (icmpv4_fd, icmpv4_tos, tos); sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); return true; @@ -391,9 +408,7 @@ bool vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) { -#if defined(SOL_IP) && defined(IP_TOS) - setsockopt (udpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos); -#endif + set_tos (udpv4_fd, udpv4_tos, tos); sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); return true; @@ -465,8 +480,10 @@ { case PROT_IPv4: return send_ipv4_packet (pkt, si, tos); + case PROT_UDPv4: return send_udpv4_packet (pkt, si, tos); + #if ENABLE_TCP case PROT_TCPv4: return send_tcpv4_packet (pkt, si, tos); @@ -479,7 +496,6 @@ case PROT_DNSv4: return send_dnsv4_packet (pkt, si, tos); #endif - default: slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si); } @@ -488,9 +504,9 @@ } void -vpn::ipv4_ev (io_watcher &w, short revents) +vpn::ipv4_ev (ev::io &w, int revents) { - if (revents & EVENT_READ) + if (revents & EV_READ) { vpn_packet *pkt = new vpn_packet; struct sockaddr_in sa; @@ -529,9 +545,9 @@ #if ENABLE_ICMP void -vpn::icmpv4_ev (io_watcher &w, short revents) +vpn::icmpv4_ev (ev::io &w, int revents) { - if (revents & EVENT_READ) + if (revents & EV_READ) { vpn_packet *pkt = new vpn_packet; struct sockaddr_in sa; @@ -577,9 +593,9 @@ #endif void -vpn::udpv4_ev (io_watcher &w, short revents) +vpn::udpv4_ev (ev::io &w, int revents) { - if (revents & EVENT_READ) + if (revents & EV_READ) { vpn_packet *pkt = new vpn_packet; struct sockaddr_in sa; @@ -614,9 +630,9 @@ } void -vpn::tap_ev (io_watcher &w, short revents) +vpn::tap_ev (ev::io &w, int revents) { - if (revents & EVENT_READ) + if (revents & EV_READ) { /* process data */ tap_packet *pkt; @@ -656,7 +672,7 @@ } void -vpn::event_cb (time_watcher &w) +vpn::event_cb (ev::timer &w, int) { if (events) { @@ -757,7 +773,7 @@ void vpn::dump_status () { - slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)NOW); + slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ()); for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) (*c)->dump_status ();