aboutgitcodebugslistschat
path: root/flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'flow.c')
-rw-r--r--flow.c136
1 files changed, 74 insertions, 62 deletions
diff --git a/flow.c b/flow.c
index 687e9fd..ee1221b 100644
--- a/flow.c
+++ b/flow.c
@@ -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: