Both of these functions can set the final values of the addresses in the header in several places, which can be hard to follow. Change it to use temporary locals, 'src' and 'dst' to track the addresses we're going to want then write it to the actual header in one place. This will make some subsequent changes easier. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- udp.c | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/udp.c b/udp.c index e3c51bae..a07c1a62 100644 --- a/udp.c +++ b/udp.c @@ -588,18 +588,14 @@ static size_t udp_update_hdr4(const struct ctx *c, struct udp4_l2_buf_t *b, const struct timespec *now) { size_t ip_len = datalen + sizeof(b->iph) + sizeof(b->uh); + const struct in_addr *src = &b->s_in.sin_addr; in_port_t src_port = ntohs(b->s_in.sin_port); - struct in_addr *src = &b->s_in.sin_addr; - - b->iph.tot_len = htons(ip_len); - b->iph.daddr = c->ip4.addr_seen.s_addr; if (!IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match) && IN4_ARE_ADDR_EQUAL(src, &c->ip4.dns_host) && src_port == 53) { - b->iph.saddr = c->ip4.dns_match.s_addr; + src = &c->ip4.dns_match; } else if (IN4_IS_ADDR_LOOPBACK(src) || IN4_ARE_ADDR_EQUAL(src, &c->ip4.addr_seen)) { - b->iph.saddr = c->ip4.gw.s_addr; udp_tap_map[V4][src_port].ts = now->tv_sec; udp_tap_map[V4][src_port].flags |= PORT_LOCAL; @@ -609,12 +605,15 @@ static size_t udp_update_hdr4(const struct ctx *c, struct udp4_l2_buf_t *b, udp_tap_map[V4][src_port].flags &= ~PORT_LOOPBACK; bitmap_set(udp_act[V4][UDP_ACT_TAP], src_port); - } else { - b->iph.saddr = src->s_addr; + + src = &c->ip4.gw; } + b->iph.tot_len = htons(ip_len); + b->iph.daddr = c->ip4.addr_seen.s_addr; + b->iph.saddr = src->s_addr; udp_update_check4(b); - b->uh.source = b->s_in.sin_port; + b->uh.source = htons(src_port); b->uh.dest = htons(dstport); b->uh.len = htons(datalen + sizeof(b->uh)); @@ -636,29 +635,19 @@ static size_t udp_update_hdr6(const struct ctx *c, struct udp6_l2_buf_t *b, const struct timespec *now) { size_t ip_len = datalen + sizeof(b->ip6h) + sizeof(b->uh); + const struct in6_addr *src = &b->s_in6.sin6_addr; + const struct in6_addr *dst = &c->ip6.addr_seen; in_port_t src_port = ntohs(b->s_in6.sin6_port); - struct in6_addr *src = &b->s_in6.sin6_addr; - - b->ip6h.payload_len = htons(datalen + sizeof(b->uh)); if (IN6_IS_ADDR_LINKLOCAL(src)) { - b->ip6h.daddr = c->ip6.addr_ll_seen; - b->ip6h.saddr = b->s_in6.sin6_addr; + dst = &c->ip6.addr_ll_seen; } else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match) && IN6_ARE_ADDR_EQUAL(src, &c->ip6.dns_host) && src_port == 53) { - b->ip6h.daddr = c->ip6.addr_seen; - b->ip6h.saddr = c->ip6.dns_match; + src = &c->ip6.dns_match; } else if (IN6_IS_ADDR_LOOPBACK(src) || IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr_seen) || IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr)) { - b->ip6h.daddr = c->ip6.addr_ll_seen; - - if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw)) - b->ip6h.saddr = c->ip6.gw; - else - b->ip6h.saddr = c->ip6.addr_ll; - udp_tap_map[V6][src_port].ts = now->tv_sec; udp_tap_map[V6][src_port].flags |= PORT_LOCAL; @@ -673,12 +662,18 @@ static size_t udp_update_hdr6(const struct ctx *c, struct udp6_l2_buf_t *b, udp_tap_map[V6][src_port].flags &= ~PORT_GUA; bitmap_set(udp_act[V6][UDP_ACT_TAP], src_port); - } else { - b->ip6h.daddr = c->ip6.addr_seen; - b->ip6h.saddr = b->s_in6.sin6_addr; + + dst = &c->ip6.addr_ll_seen; + if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw)) + src = &c->ip6.gw; + else + src = &c->ip6.addr_ll; } - b->uh.source = b->s_in6.sin6_port; + b->ip6h.payload_len = htons(datalen + sizeof(b->uh)); + b->ip6h.saddr = *src; + b->ip6h.daddr = *dst; + b->uh.source = htons(src_port); b->uh.dest = htons(dstport); b->uh.len = b->ip6h.payload_len; -- 2.44.0