--- gvpe/src/protocol.C 2003/03/28 04:05:10 1.21 +++ gvpe/src/protocol.C 2003/03/28 16:21:09 1.25 @@ -60,15 +60,6 @@ #define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic -static u8 -best_protocol (u8 protset) -{ - if (protset & PROT_IPv4) - return PROT_IPv4; - - return PROT_UDPv4; -} - struct crypto_ctx { EVP_CIPHER_CTX cctx; @@ -583,17 +574,18 @@ struct auth_req_packet : config_packet { char magic[8]; - u8 initiate, can_recv; // false if this is just an automatic reply + u8 initiate; // false if this is just an automatic reply + u8 protocols; // supported protocols (will get patches on forward) u8 pad2, pad3; rsaid id; rsaencrdata encr; - auth_req_packet (int dst, bool initiate_, u8 can_recv_) + auth_req_packet (int dst, bool initiate_, u8 protocols_) { config_packet::setup (PT_AUTH_REQ, dst); strncpy (magic, MAGIC, 8); initiate = !!initiate_; - can_recv = can_recv_; + protocols = protocols_; len = sizeof (*this) - sizeof (net_packet); } @@ -616,12 +608,13 @@ struct connect_req_packet : vpn_packet { - u8 id; - u8 pad1, pad2, pad3; + u8 id, protocols; + u8 pad1, pad2; - connect_req_packet (int dst, int id_) + connect_req_packet (int dst, int id_, u8 protocols_) + : id(id_) + , protocols(protocols_) { - id = id_; set_hdr (PT_CONNECT_REQ, dst); len = sizeof (*this) - sizeof (net_packet); } @@ -629,15 +622,15 @@ struct connect_info_packet : vpn_packet { - u8 id, can_recv; + u8 id, protocols; u8 pad1, pad2; sockinfo si; - connect_info_packet (int dst, int id_, sockinfo &si_, u8 can_recv_) + connect_info_packet (int dst, int id_, const sockinfo &si_, u8 protocols_) + : id(id_) + , protocols(protocols_) + , si(si_) { - id = id_; - can_recv = can_recv_; - si = si_; set_hdr (PT_CONNECT_INFO, dst); len = sizeof (*this) - sizeof (net_packet); @@ -680,10 +673,9 @@ void connection::send_auth_request (const sockinfo &si, bool initiate) { - auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->can_recv); + auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols); - // the next line is very conservative - prot_send = best_protocol (THISNODE->can_send & THISNODE->can_recv & conf->can_recv); + protocol = best_protocol (THISNODE->protocols & conf->protocols); rsachallenge chg; @@ -720,6 +712,20 @@ } void +connection::send_connect_info (int rid, const sockinfo &rsi, u8 rprotocols) +{ + slog (L_TRACE, ">>%d PT_CONNECT_INFO(%d,%s)\n", + conf->id, rid, (const char *)rsi); + + connect_info_packet *r = new connect_info_packet (conf->id, rid, rsi, rprotocols); + + r->hmac_set (octx); + send_vpn_packet (r, si); + + delete r; +} + +void connection::establish_connection_cb (tstamp &ts) { if (ictx || conf == THISNODE @@ -842,7 +848,7 @@ // we send pings instead of auth packets after some retries, // so reset the retry counter and establish a connection // when we receive a ping. - if (!ictx && !octx) + if (!ictx) { if (auth_rate_limiter.can (rsi)) send_auth_request (rsi, true); @@ -911,7 +917,7 @@ octx = new crypto_ctx (k, 1); oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff; - conf->can_recv = p->can_recv; + conf->protocols = p->protocols; send_auth_response (rsi, p->id, k); break; @@ -977,8 +983,9 @@ connectmode = conf->connectmode; - slog (L_INFO, _("%s(%s): connection established, protocol version %d.%d"), + slog (L_INFO, _("%s(%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) @@ -1054,7 +1061,7 @@ 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]; slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n", @@ -1064,29 +1071,8 @@ { // send connect_info packets to both sides, in case one is // behind a nat firewall (or both ;) - { - slog (L_TRACE, ">>%d PT_CONNECT_INFO(%d,%s)\n", - c->conf->id, conf->id, (const char *)si); - - connect_info_packet *r = new connect_info_packet (c->conf->id, conf->id, si, conf->can_recv); - - r->hmac_set (c->octx); - send_vpn_packet (r, c->si); - - delete r; - } - - { - slog (L_TRACE, ">>%d PT_CONNECT_INFO(%d,%s)\n", - conf->id, c->conf->id, (const char *)c->si); - - connect_info_packet *r = new connect_info_packet (conf->id, c->conf->id, c->si, c->conf->can_recv); - - r->hmac_set (octx); - send_vpn_packet (r, si); - - delete r; - } + c->send_connect_info (conf->id, si, conf->protocols); + send_connect_info (c->conf->id, c->si, c->conf->protocols); } } @@ -1098,13 +1084,12 @@ 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]; slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx); - c->conf->can_recv = p->can_recv; c->send_auth_request (p->si, true); } @@ -1127,21 +1112,20 @@ else if (NOW < last_activity + ::conf.keepalive) ts = last_activity + ::conf.keepalive; else if (conf->connectmode != conf_node::C_ONDEMAND - || THISNODE->connectmode != conf_node::C_ONDEMAND) + || THISNODE->connectmode != conf_node::C_ONDEMAND) { send_ping (si); ts = NOW + 5; } else reset_connection (); - } void connection::connect_request (int id) { - connect_req_packet *p = new connect_req_packet (conf->id, id); + connect_req_packet *p = new connect_req_packet (conf->id, id, conf->protocols); - slog (L_TRACE, ">>%d PT_CONNECT_REQ(%d)", id, conf->id); + slog (L_TRACE, ">>%d PT_CONNECT_REQ(%d)", conf->id, id); p->hmac_set (octx); send_vpn_packet (p, si); @@ -1181,7 +1165,7 @@ void connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) { - if (prot_send & PROT_IPv4) + if (protocol & PROT_IPv4) vpn->send_ipv4_packet (pkt, si, tos); else vpn->send_udpv4_packet (pkt, si, tos); @@ -1238,19 +1222,13 @@ int vpn::setup () { - u8 prots = 0; - - for (configuration::node_vector::iterator i = conf.nodes.begin (); - i != conf.nodes.end (); ++i) - prots |= (*i)->can_send | (*i)->can_recv; - sockinfo si; si.set (THISNODE); udpv4_fd = -1; - if (prots & PROT_UDPv4) + if (THISNODE->protocols & PROT_UDPv4) { udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -1283,7 +1261,7 @@ } ipv4_fd = -1; - if (prots & PROT_IPv4) + if (THISNODE->protocols & PROT_IPv4) { ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); @@ -1348,22 +1326,28 @@ slog (L_NOISE, _("<typ (), pkt->src (), pkt->dst (), pkt->len); - if (dst > conns.size () || pkt->typ () >= vpn_packet::PT_MAX) - slog (L_WARN, _("<typ (), pkt->src (), pkt->dst ()); - else if (dst == 0 && !THISNODE->routerprio) - slog (L_WARN, _("<<%d received broadcast, but we are no router"), dst); - else if (dst != 0 && dst != THISNODE->id) - slog (L_WARN, - _("received frame for node %d ('%s') from %s, but this is node %d ('%s')"), - dst, conns[dst - 1]->conf->nodename, - (const char *)rsi, - THISNODE->id, THISNODE->nodename); - else if (src == 0 || src > conns.size ()) - slog (L_WARN, _("received frame from unknown node %d (%s)"), - src, (const char *)rsi); + if (src == 0 || src > conns.size () + || dst > conns.size () + || pkt->typ () >= vpn_packet::PT_MAX) + slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), + (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); else - conns[src - 1]->recv_vpn_packet (pkt, rsi); + { + connection *c = conns[src - 1]; + + if (dst == 0 && !THISNODE->routerprio) + slog (L_WARN, _("%s(%s): received broadcast, but we are no router"), + c->conf->nodename, (const char *)rsi); + else if (dst != 0 && dst != THISNODE->id) + // FORWARDING NEEDED ;) + slog (L_WARN, + _("received frame for node %d ('%s') from %s, but this is node %d ('%s')"), + dst, conns[dst - 1]->conf->nodename, + (const char *)rsi, + THISNODE->id, THISNODE->nodename); + else + c->recv_vpn_packet (pkt, rsi); + } } void