--- gvpe/src/connection.C 2005/03/04 08:15:04 1.44 +++ gvpe/src/connection.C 2005/06/03 05:07:31 1.56 @@ -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" @@ -30,8 +30,6 @@ #include #include -#include "gettext.h" - #include "conf.h" #include "slog.h" #include "device.h" @@ -99,44 +97,44 @@ void cleaner_cb (time_watcher &w); time_watcher cleaner; bool find (const rsaid &id, rsachallenge &chg) - { - for (iterator i = begin (); i != end (); ++i) - { - if (!memcmp (&id, &i->id, sizeof id) && i->expire > NOW) - { - memcpy (&chg, &i->chg, sizeof chg); + { + for (iterator i = begin (); i != end (); ++i) + { + if (!memcmp (&id, &i->id, sizeof id) && i->expire > NOW) + { + memcpy (&chg, &i->chg, sizeof chg); - erase (i); - return true; - } - } + erase (i); + return true; + } + } - if (cleaner.at < NOW) - cleaner.start (NOW + RSA_TTL); + if (cleaner.at < NOW) + cleaner.start (NOW + RSA_TTL); - return false; - } + return false; + } void gen (rsaid &id, rsachallenge &chg) - { - rsa_entry e; + { + rsa_entry e; - RAND_bytes ((unsigned char *)&id, sizeof id); - RAND_bytes ((unsigned char *)&chg, sizeof chg); + RAND_bytes ((unsigned char *)&id, sizeof id); + RAND_bytes ((unsigned char *)&chg, sizeof chg); - e.expire = NOW + RSA_TTL; - e.id = id; - memcpy (&e.chg, &chg, sizeof chg); + e.expire = NOW + RSA_TTL; + e.id = id; + memcpy (&e.chg, &chg, sizeof chg); - push_back (e); + push_back (e); - if (cleaner.at < NOW) - cleaner.start (NOW + RSA_TTL); - } + if (cleaner.at < NOW) + cleaner.start (NOW + RSA_TTL); + } rsa_cache () - : cleaner (this, &rsa_cache::cleaner_cb) - { } + : cleaner (this, &rsa_cache::cleaner_cb) + { } } rsa_cache; @@ -480,7 +478,7 @@ prot_minor = PROTOCOL_MINOR; randsize = RAND_SIZE; hmaclen = HMACLENGTH; - flags = ENABLE_COMPRESSION ? 0x81 : 0x80; + flags = 0; challengelen = sizeof (rsachallenge); features = get_features (); @@ -500,10 +498,6 @@ slog (L_WARN, _("rand size mismatch (remote %d <=> local %d)"), randsize, RAND_SIZE); else if (hmaclen != HMACLENGTH) slog (L_WARN, _("hmac length mismatch (remote %d <=> local %d)"), hmaclen, HMACLENGTH); -#if 0 // this implementation should handle all flag settings - else if (flags != curflags ()) - slog (L_WARN, _("flag mismatch (remote %x <=> local %x)"), flags, curflags ()); -#endif else if (challengelen != sizeof (rsachallenge)) slog (L_WARN, _("challenge length mismatch (remote %d <=> local %d)"), challengelen, sizeof (rsachallenge)); else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER))) @@ -646,8 +640,8 @@ if (r) { - slog (L_DEBUG, _("%s: no common protocol, trying indirectly through %s"), - conf->nodename, r->conf->nodename); + slog (L_DEBUG, _("%s: no common protocol, trying indirectly through %s (%s)"), + conf->nodename, r->conf->nodename, (const char *)r->si); return r->si; } else @@ -661,33 +655,7 @@ void connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) { - bool ok; - - switch (si.prot) - { - case PROT_IPv4: - ok = vpn->send_ipv4_packet (pkt, si, tos); break; - case PROT_UDPv4: - ok = vpn->send_udpv4_packet (pkt, si, tos); break; -#if ENABLE_TCP - case PROT_TCPv4: - ok = vpn->send_tcpv4_packet (pkt, si, tos); break; -#endif -#if ENABLE_ICMP - case PROT_ICMPv4: - ok = vpn->send_icmpv4_packet (pkt, si, tos); break; -#endif -#if ENABLE_DNS - case PROT_DNSv4: - ok = send_dnsv4_packet (pkt, si, tos); break; -#endif - - default: - slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si); - ok = false; - } - - if (!ok) + if (!vpn->send_vpn_packet (pkt, si, tos)) reset_connection (); } @@ -773,23 +741,24 @@ && connectmode != conf_node::C_DISABLED && NOW > w.at) { - double retry_int = double (retry_cnt & 3 ? (retry_cnt & 3) : 1 << (retry_cnt >> 2)) * 0.6; - - if (retry_int < conf->max_retry) - retry_cnt++; - else - retry_int = conf->max_retry; + w.at = TSTAMP_MAX; // first disable this watcher in case of recursion - w.start (NOW + retry_int); + double retry_int = double (retry_cnt & 3 + ? (retry_cnt & 3) + 1 + : 1 << (retry_cnt >> 2)); reset_si (); + bool slow = si.prot & PROT_SLOW; + if (si.prot && !si.host) vpn->send_connect_request (conf->id); else { const sockinfo &dsi = forward_si (si); + slow = slow || (dsi.prot & PROT_SLOW); + if (dsi.valid () && auth_rate_limiter.can (dsi)) { if (retry_cnt < 4) @@ -798,6 +767,15 @@ send_ping (dsi, 0); } } + + retry_int *= slow ? 8. : 0.7; + + if (retry_int < conf->max_retry) + retry_cnt++; + else + retry_int = conf->max_retry; + + w.start (NOW + retry_int); } } @@ -810,13 +788,14 @@ conf->nodename, (const char *)si); if (::conf.script_node_down) - run_script (run_script_cb (this, &connection::script_node_down), false); + if (!run_script (run_script_cb (this, &connection::script_node_down), false)) + slog (L_WARN, _("node-down command execution failed, continuing.")); } delete ictx; ictx = 0; delete octx; octx = 0; #if ENABLE_DNS - delete dns; dns = 0; + dnsv4_reset_connection (); #endif si.host = 0; @@ -871,7 +850,7 @@ send_data_packet (pkt); else { - if (!broadcast)//DDDD + if (!broadcast) data_queue.put (new tap_packet (*pkt)); establish_connection (); @@ -966,9 +945,6 @@ octx = new crypto_ctx (k, 1); oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff; - // compatibility code, remove when no longer required - if (p->flags & 1) p->features |= FEATURE_COMPRESSION; - conf->protocols = p->protocols; features = p->features & config_packet::get_features (); @@ -1044,7 +1020,8 @@ p->prot_major, p->prot_minor); if (::conf.script_node_up) - run_script (run_script_cb (this, &connection::script_node_up), false); + if (!run_script (run_script_cb (this, &connection::script_node_up), false)) + slog (L_WARN, _("node-up command execution failed, continuing.")); break; } @@ -1088,7 +1065,7 @@ if (si != rsi) { - // fast re-sync on connection changes, useful especially for tcp/ip + // fast re-sync on source address changes, useful especially for tcp/ip si = rsi; slog (L_INFO, _("%s(%s): socket address changed to %s"), @@ -1194,9 +1171,19 @@ delete p; } -void connection::script_node () +void connection::script_init_env (const char *ext) { - vpn->script_if_up (); + char *env; + asprintf (&env, "IFUPDATA%s=%s", ext, conf->if_up_data); putenv (env); + asprintf (&env, "NODENAME%s=%s", ext, conf->nodename); putenv (env); + asprintf (&env, "MAC%s=%02x:%02x:%02x:%02x:%02x:%02x", ext, + 0xfe, 0xfd, 0x80, 0x00, conf->id >> 8, + conf->id & 0xff); putenv (env); +} + +void connection::script_init_connect_env () +{ + vpn->script_init_env (); char *env; asprintf (&env, "DESTID=%d", conf->id); putenv (env); @@ -1207,20 +1194,32 @@ const char *connection::script_node_up () { - script_node (); + script_init_connect_env (); putenv ("STATE=up"); - return ::conf.script_node_up ? ::conf.script_node_up : "node-up"; + char *filename; + asprintf (&filename, + "%s/%s", + confbase, + ::conf.script_node_up ? ::conf.script_node_up : "node-up"); + + return filename; } const char *connection::script_node_down () { - script_node (); + script_init_connect_env (); putenv ("STATE=down"); - return ::conf.script_node_up ? ::conf.script_node_down : "node-down"; + char *filename; + asprintf (&filename, + "%s/%s", + confbase, + ::conf.script_node_down ? ::conf.script_node_down : "node-down"); + + return filename; } connection::connection (struct vpn *vpn, conf_node *conf)