--- gvpe/src/connection.C 2003/04/05 02:32:40 1.6 +++ gvpe/src/connection.C 2003/04/06 04:17:36 1.8 @@ -548,7 +548,7 @@ ///////////////////////////////////////////////////////////////////////////// void -connection::reset_dstaddr () +connection::reset_si () { protocol = best_protocol (THISNODE->protocols & conf->protocols); @@ -559,6 +559,28 @@ si.set (conf, protocol); } +// ensure sockinfo is valid, forward if necessary +const sockinfo & +connection::forward_si (const sockinfo &si) const +{ + if (!si.valid ()) + { + connection *r = vpn->find_router (); + + if (r) + { + slog (L_DEBUG, _("%s: no common protocol, trying indirectly through %s"), + conf->nodename, r->conf->nodename); + return r->si; + } + else + slog (L_DEBUG, _("%s: node unreachable, no common protocol"), + conf->nodename); + } + + return si; +} + void connection::send_ping (const sockinfo &si, u8 pong) { @@ -600,7 +622,8 @@ slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si); - vpn->send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly + vpn->send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly + delete pkt; } @@ -653,20 +676,22 @@ w.at = NOW + retry_int; - if (conf->hostname) + reset_si (); + + if (si.prot && !si.host) + vpn->connect_request (conf->id); + else { - reset_dstaddr (); + const sockinfo &dsi = forward_si (si); - if (si.valid () && auth_rate_limiter.can (si)) - { - if (retry_cnt < 4) - send_auth_request (si, true); - else - send_ping (si, 0); - } + if (dsi.valid () && auth_rate_limiter.can (dsi)) + { + if (retry_cnt < 4) + send_auth_request (dsi, true); + else + send_ping (dsi, 0); + } } - else - vpn->connect_request (conf->id); } } @@ -747,6 +772,14 @@ } } +void connection::inject_vpn_packet (vpn_packet *pkt, int tos) +{ + if (ictx && octx) + vpn->send_vpn_packet (pkt, si, tos); + else + establish_connection (); +} + void connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) { @@ -883,6 +916,7 @@ iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid si = rsi; + protocol = rsi.prot; rekey.start (NOW + ::conf.rekey); keepalive.start (NOW + ::conf.keepalive); @@ -896,9 +930,8 @@ connectmode = conf->connectmode; - slog (L_INFO, _("%s(%s): %s connection established, protocol version %d.%d"), + slog (L_INFO, _("%s(%s): connection established, protocol version %d.%d"), conf->nodename, (const char *)rsi, - strprotocol (protocol), p->prot_major, p->prot_minor); if (::conf.script_node_up) @@ -974,8 +1007,8 @@ connect_req_packet *p = (connect_req_packet *) pkt; assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything - conf->protocols = p->protocols; connection *c = vpn->conns[p->id - 1]; + conf->protocols = p->protocols; slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n", conf->id, p->id, c->ictx && c->octx); @@ -997,13 +1030,20 @@ connect_info_packet *p = (connect_info_packet *) pkt; assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything - conf->protocols = p->protocols; + connection *c = vpn->conns[p->id - 1]; + c->conf->protocols = p->protocols; + protocol = best_protocol (c->conf->protocols & THISNODE->protocols & p->si.supported_protocols (c->conf)); + p->si.upgrade_protocol (protocol, c->conf); + slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx); - c->send_auth_request (p->si, true); + const sockinfo &dsi = forward_si (p->si); + + if (dsi.valid ()) + c->send_auth_request (dsi, true); } break;