--- gvpe/src/vpn.C 2007/12/01 23:35:31 1.40 +++ gvpe/src/vpn.C 2007/12/04 17:17:20 1.44 @@ -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. @@ -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) { @@ -133,7 +146,8 @@ 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) { @@ -172,7 +186,8 @@ 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) @@ -255,6 +270,9 @@ } #endif + dnsv4_tos = -1; + dnsv4_fd = -1; + #if ENABLE_DNS if (THISNODE->protocols & PROT_DNSv4) { @@ -313,15 +331,19 @@ fcntl (tap->fd, F_SETFD, FD_CLOEXEC); + run_script_cb cb; + cb.set (this); + 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)) + cb.set (this); + if (!run_script (cb, true)) { slog (L_ERR, _("if-up command execution failed, exiting.")); exit (EXIT_FAILURE); @@ -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); } @@ -766,20 +782,20 @@ } vpn::vpn (void) -: event (this, &vpn::event_cb) -, udpv4_ev_watcher (this, &vpn::udpv4_ev) -, ipv4_ev_watcher (this, &vpn::ipv4_ev) +{ + event .set (this); + udpv4_ev_watcher .set (this); + ipv4_ev_watcher .set (this); #if ENABLE_TCP -, tcpv4_ev_watcher (this, &vpn::tcpv4_ev) + tcpv4_ev_watcher .set (this); #endif #if ENABLE_ICMP -, icmpv4_ev_watcher(this, &vpn::icmpv4_ev) + icmpv4_ev_watcher.set (this); #endif #if ENABLE_DNS -, dnsv4_ev_watcher (this, &vpn::dnsv4_ev) + dnsv4_ev_watcher .set (this); #endif -, tap_ev_watcher (this, &vpn::tap_ev) -{ + tap_ev_watcher .set (this); } vpn::~vpn ()