diff options
Diffstat (limited to 'flow.c')
-rw-r--r-- | flow.c | 136 |
1 files changed, 74 insertions, 62 deletions
@@ -127,18 +127,18 @@ static struct timespec flow_timer_run; * @af: Address family (AF_INET or AF_INET6) * @eaddr: Endpoint address (pointer to in_addr or in6_addr) * @eport: Endpoint port - * @faddr: Forwarding address (pointer to in_addr or in6_addr) - * @fport: Forwarding port + * @oaddr: Our address (pointer to in_addr or in6_addr) + * @oport: Our port */ static void flowside_from_af(struct flowside *side, sa_family_t af, const void *eaddr, in_port_t eport, - const void *faddr, in_port_t fport) + const void *oaddr, in_port_t oport) { - if (faddr) - inany_from_af(&side->faddr, af, faddr); + if (oaddr) + inany_from_af(&side->oaddr, af, oaddr); else - side->faddr = inany_any6; - side->fport = fport; + side->oaddr = inany_any6; + side->oport = oport; if (eaddr) inany_from_af(&side->eaddr, af, eaddr); @@ -193,8 +193,8 @@ static int flowside_sock_splice(void *arg) * @tgt: Target flowside * @data: epoll reference portion for protocol handlers * - * Return: socket fd of protocol @proto bound to the forwarding address and port - * from @tgt (if specified). + * Return: socket fd of protocol @proto bound to our address and port from @tgt + * (if specified). */ int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif, const struct flowside *tgt, uint32_t data) @@ -205,11 +205,11 @@ int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif, ASSERT(pif_is_socket(pif)); - pif_sockaddr(c, &sa, &sl, pif, &tgt->faddr, tgt->fport); + pif_sockaddr(c, &sa, &sl, pif, &tgt->oaddr, tgt->oport); switch (pif) { case PIF_HOST: - if (inany_is_loopback(&tgt->faddr)) + if (inany_is_loopback(&tgt->oaddr)) ifname = NULL; else if (sa.sa_family == AF_INET) ifname = c->ip4.ifname_out; @@ -283,46 +283,60 @@ void flow_log_(const struct flow_common *f, int pri, const char *fmt, ...) "Flow %u (%s): %s", flow_idx(f), type_or_state, msg); } -/** - * flow_set_state() - Change flow's state - * @f: Flow changing state - * @state: New state +/** flow_log_details_() - Log the details of a flow + * @f: flow to log + * @pri: Log priority + * @state: State to log details according to + * + * Logs the details of the flow: endpoints, interfaces, type etc. */ -static void flow_set_state(struct flow_common *f, enum flow_state state) +void flow_log_details_(const struct flow_common *f, int pri, + enum flow_state state) { char estr0[INANY_ADDRSTRLEN], fstr0[INANY_ADDRSTRLEN]; char estr1[INANY_ADDRSTRLEN], fstr1[INANY_ADDRSTRLEN]; const struct flowside *ini = &f->side[INISIDE]; const struct flowside *tgt = &f->side[TGTSIDE]; - uint8_t oldstate = f->state; - - ASSERT(state < FLOW_NUM_STATES); - ASSERT(oldstate < FLOW_NUM_STATES); - - f->state = state; - flow_log_(f, LOG_DEBUG, "%s -> %s", flow_state_str[oldstate], - FLOW_STATE(f)); - if (MAX(state, oldstate) >= FLOW_STATE_TGT) - flow_log_(f, LOG_DEBUG, + if (state >= FLOW_STATE_TGT) + flow_log_(f, pri, "%s [%s]:%hu -> [%s]:%hu => %s [%s]:%hu -> [%s]:%hu", pif_name(f->pif[INISIDE]), inany_ntop(&ini->eaddr, estr0, sizeof(estr0)), ini->eport, - inany_ntop(&ini->faddr, fstr0, sizeof(fstr0)), - ini->fport, + inany_ntop(&ini->oaddr, fstr0, sizeof(fstr0)), + ini->oport, pif_name(f->pif[TGTSIDE]), - inany_ntop(&tgt->faddr, fstr1, sizeof(fstr1)), - tgt->fport, + inany_ntop(&tgt->oaddr, fstr1, sizeof(fstr1)), + tgt->oport, inany_ntop(&tgt->eaddr, estr1, sizeof(estr1)), tgt->eport); - else if (MAX(state, oldstate) >= FLOW_STATE_INI) - flow_log_(f, LOG_DEBUG, "%s [%s]:%hu -> [%s]:%hu => ?", + else if (state >= FLOW_STATE_INI) + flow_log_(f, pri, "%s [%s]:%hu -> [%s]:%hu => ?", pif_name(f->pif[INISIDE]), inany_ntop(&ini->eaddr, estr0, sizeof(estr0)), ini->eport, - inany_ntop(&ini->faddr, fstr0, sizeof(fstr0)), - ini->fport); + inany_ntop(&ini->oaddr, fstr0, sizeof(fstr0)), + ini->oport); +} + +/** + * flow_set_state() - Change flow's state + * @f: Flow changing state + * @state: New state + */ +static void flow_set_state(struct flow_common *f, enum flow_state state) +{ + uint8_t oldstate = f->state; + + ASSERT(state < FLOW_NUM_STATES); + ASSERT(oldstate < FLOW_NUM_STATES); + + f->state = state; + flow_log_(f, LOG_DEBUG, "%s -> %s", flow_state_str[oldstate], + FLOW_STATE(f)); + + flow_log_details_(f, LOG_DEBUG, MAX(state, oldstate)); } /** @@ -347,7 +361,7 @@ static void flow_initiate_(union flow *flow, uint8_t pif) * flow_initiate_af() - Move flow to INI, setting INISIDE details * @flow: Flow to change state * @pif: pif of the initiating side - * @af: Address family of @eaddr and @faddr + * @af: Address family of @saddr and @daddr * @saddr: Source address (pointer to in_addr or in6_addr) * @sport: Endpoint port * @daddr: Destination address (pointer to in_addr or in6_addr) @@ -384,10 +398,10 @@ const struct flowside *flow_initiate_sa(union flow *flow, uint8_t pif, inany_from_sockaddr(&ini->eaddr, &ini->eport, ssa); if (inany_v4(&ini->eaddr)) - ini->faddr = inany_any4; + ini->oaddr = inany_any4; else - ini->faddr = inany_any6; - ini->fport = dport; + ini->oaddr = inany_any6; + ini->oport = dport; flow_initiate_(flow, pif); return ini; } @@ -432,8 +446,8 @@ const struct flowside *flow_target(const struct ctx *c, union flow *flow, pif_name(f->pif[INISIDE]), inany_ntop(&ini->eaddr, estr, sizeof(estr)), ini->eport, - inany_ntop(&ini->faddr, fstr, sizeof(fstr)), - ini->fport); + inany_ntop(&ini->oaddr, fstr, sizeof(fstr)), + ini->oport); } if (tgtpif == PIF_NONE) @@ -561,18 +575,12 @@ static uint64_t flow_hash(const struct ctx *c, uint8_t proto, uint8_t pif, { struct siphash_state state = SIPHASH_INIT(c->hash_secret); - /* For the hash table to work, we need complete endpoint information, - * and at least a forwarding port. - */ - ASSERT(pif != PIF_NONE && !inany_is_unspecified(&side->eaddr) && - side->eport != 0 && side->fport != 0); - - inany_siphash_feed(&state, &side->faddr); + inany_siphash_feed(&state, &side->oaddr); inany_siphash_feed(&state, &side->eaddr); return siphash_final(&state, 38, (uint64_t)proto << 40 | (uint64_t)pif << 32 | - (uint64_t)side->fport << 16 | + (uint64_t)side->oport << 16 | (uint64_t)side->eport); } @@ -586,8 +594,11 @@ static uint64_t flow_hash(const struct ctx *c, uint8_t proto, uint8_t pif, static uint64_t flow_sidx_hash(const struct ctx *c, flow_sidx_t sidx) { const struct flow_common *f = &flow_at_sidx(sidx)->f; - return flow_hash(c, FLOW_PROTO(f), - f->pif[sidx.sidei], &f->side[sidx.sidei]); + const struct flowside *side = &f->side[sidx.sidei]; + uint8_t pif = f->pif[sidx.sidei]; + + ASSERT(pif != PIF_NONE); + return flow_hash(c, FLOW_PROTO(f), pif, side); } /** @@ -695,7 +706,7 @@ static flow_sidx_t flowside_lookup(const struct ctx *c, uint8_t proto, !(FLOW_PROTO(&flow->f) == proto && flow->f.pif[sidx.sidei] == pif && flowside_eq(&flow->f.side[sidx.sidei], side))) - b = (b + 1) % FLOW_HASH_SIZE; + b = mod_sub(b, 1, FLOW_HASH_SIZE); return flow_hashtab[b]; } @@ -707,20 +718,20 @@ static flow_sidx_t flowside_lookup(const struct ctx *c, uint8_t proto, * @pif: Interface of the flow * @af: Address family, AF_INET or AF_INET6 * @eaddr: Guest side endpoint address (guest local address) - * @faddr: Guest side forwarding address (guest remote address) + * @oaddr: Our guest side address (guest remote address) * @eport: Guest side endpoint port (guest local port) - * @fport: Guest side forwarding port (guest remote port) + * @oport: Our guest side port (guest remote port) * * Return: sidx of the matching flow & side, FLOW_SIDX_NONE if not found */ flow_sidx_t flow_lookup_af(const struct ctx *c, uint8_t proto, uint8_t pif, sa_family_t af, - const void *eaddr, const void *faddr, - in_port_t eport, in_port_t fport) + const void *eaddr, const void *oaddr, + in_port_t eport, in_port_t oport) { struct flowside side; - flowside_from_af(&side, af, eaddr, eport, faddr, fport); + flowside_from_af(&side, af, eaddr, eport, oaddr, oport); return flowside_lookup(c, proto, pif, &side); } @@ -730,22 +741,22 @@ flow_sidx_t flow_lookup_af(const struct ctx *c, * @proto: Protocol of the flow (IP L4 protocol number) * @pif: Interface of the flow * @esa: Socket address of the endpoint - * @fport: Forwarding port number + * @oport: Our port number * * Return: sidx of the matching flow & side, FLOW_SIDX_NONE if not found */ flow_sidx_t flow_lookup_sa(const struct ctx *c, uint8_t proto, uint8_t pif, - const void *esa, in_port_t fport) + const void *esa, in_port_t oport) { struct flowside side = { - .fport = fport, + .oport = oport, }; inany_from_sockaddr(&side.eaddr, &side.eport, esa); if (inany_v4(&side.eaddr)) - side.faddr = inany_any4; + side.oaddr = inany_any4; else - side.faddr = inany_any6; + side.oaddr = inany_any6; return flowside_lookup(c, proto, pif, &side); } @@ -830,7 +841,8 @@ void flow_defer_handler(const struct ctx *c, const struct timespec *now) closed = icmp_ping_timer(c, &flow->ping, now); break; case FLOW_UDP: - if (timer) + closed = udp_flow_defer(&flow->udp); + if (!closed && timer) closed = udp_flow_timer(c, &flow->udp, now); break; default: |