diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c index 80e18b7cecb..74923cfb956 100644 --- a/src/openvpn/mroute.c +++ b/src/openvpn/mroute.c @@ -454,6 +454,7 @@ mroute_addr_print_ex(const struct mroute_addr *ma, buf_printf(&out, "UNKNOWN"); break; } + buf_printf(&out, "|%d", maddr.proto); return BSTR(&out); } else diff --git a/src/openvpn/mroute.h b/src/openvpn/mroute.h index 8b457d4e029..26596953361 100644 --- a/src/openvpn/mroute.h +++ b/src/openvpn/mroute.h @@ -74,7 +74,7 @@ struct mroute_addr { uint8_t len; /* length of address */ - uint8_t unused; + uint8_t proto; uint8_t type; /* MR_ADDR/MR_WITH flags */ uint8_t netbits; /* number of bits in network part of address, * valid if MR_WITH_NETBITS is set */ @@ -183,6 +183,15 @@ mroute_extract_addr_from_packet(struct mroute_addr *src, { unsigned int ret = 0; verify_align_4(buf); + + /* + * Since we don't really need the protocol on vaddresses for internal VPN + * payload packets, make sure we have the same value to avoid hashing insert + * and search issues. + */ + src->proto = 0; + dest->proto = src->proto; + if (tunnel_type == DEV_TYPE_TUN) { ret = mroute_extract_addr_ip(src, dest, buf); @@ -201,6 +210,10 @@ mroute_addr_equal(const struct mroute_addr *a1, const struct mroute_addr *a2) { return false; } + if (a1->proto != a2->proto) + { + return false; + } if (a1->netbits != a2->netbits) { return false; @@ -216,13 +229,13 @@ static inline const uint8_t * mroute_addr_hash_ptr(const struct mroute_addr *a) { /* NOTE: depends on ordering of struct mroute_addr */ - return (uint8_t *) &a->type; + return (uint8_t *) &a->proto; } static inline uint32_t mroute_addr_hash_len(const struct mroute_addr *a) { - return (uint32_t) a->len + 2; + return (uint32_t) a->len + 3; } static inline void diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c index 6d1d5a080a7..62ed044a93e 100644 --- a/src/openvpn/mtcp.c +++ b/src/openvpn/mtcp.c @@ -56,6 +56,7 @@ multi_create_instance_tcp(struct multi_context *m, struct link_socket *ls) mi = multi_create_instance(m, NULL, ls); if (mi) { + mi->real.proto = ls->info.proto; struct hash_element *he; const uint32_t hv = hash_value(hash, &mi->real); struct hash_bucket *bucket = hash_bucket(hash, hv); diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index 61375784115..4f2bbd7a47f 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -192,6 +192,7 @@ multi_get_create_instance_udp(struct multi_context *m, bool *floated, struct mroute_addr real = {0}; struct multi_instance *mi = NULL; struct hash *hash = m->hash; + real.proto = ls->info.proto; if (mroute_extract_openvpn_sockaddr(&real, &m->top.c2.from.dest, true) && m->top.c2.buf.len > 0) diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 3f55dd724ca..9c8c014f722 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -794,6 +794,7 @@ multi_create_instance(struct multi_context *m, const struct mroute_addr *real, { goto err; } + mi->real.proto = ls->info.proto; generate_prefix(mi); } @@ -1243,6 +1244,7 @@ multi_learn_in_addr_t(struct multi_context *m, CLEAR(remote_si); remote_si.addr.in4.sin_family = AF_INET; remote_si.addr.in4.sin_addr.s_addr = htonl(a); + addr.proto = 0; ASSERT(mroute_extract_openvpn_sockaddr(&addr, &remote_si, false)); if (netbits >= 0) @@ -3548,7 +3550,6 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags const int dev_type = TUNNEL_TYPE(m->top.c1.tuntap); int16_t vid = 0; - #ifdef MULTI_DEBUG_EVENT_LOOP printf("TUN -> TCP/UDP [%d]\n", BLEN(&m->top.c2.buf)); #endif