From dd581730e54b934f80d5b6a820136707dc71c664 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Sun, 26 Sep 2021 23:38:22 +0200 Subject: tap: Completely de-serialise input message batches Until now, messages would be passed to protocol handlers in a single batch only if they happened to be dequeued in a row. Packets interleaved between different connections would result in multiple calls to the same protocol handler for a single connection. Instead, keep track of incoming packet descriptors, arrange them in sequences, and call protocol handlers only as we completely sorted input messages in batches. Signed-off-by: Stefano Brivio --- tcp.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'tcp.c') diff --git a/tcp.c b/tcp.c index 645d525..b269e0e 100644 --- a/tcp.c +++ b/tcp.c @@ -333,6 +333,7 @@ #include #include #include +#include #include #include #include @@ -645,7 +646,7 @@ static struct mmsghdr tcp_l2_mh_tap [TCP_TAP_FRAMES] = { }; /* sendmsg() to socket */ -static struct iovec tcp_tap_iov [TAP_MSGS]; +static struct iovec tcp_tap_iov [UIO_MAXIOV]; /* Bitmap, activity monitoring needed for connection via tap */ static uint8_t tcp_act[MAX_TAP_CONNS / 8] = { 0 }; @@ -1968,7 +1969,7 @@ out_restore_iov: * @now: Current timestamp */ static void tcp_data_from_tap(struct ctx *c, struct tcp_tap_conn *conn, - struct tap_msg *msg, int count, + struct tap_l4_msg *msg, int count, struct timespec *now) { int i, iov_i, ack = 0, fin = 0, retr = 0, keep = -1; @@ -1979,10 +1980,13 @@ static void tcp_data_from_tap(struct ctx *c, struct tcp_tap_conn *conn, ssize_t len; for (i = 0, iov_i = 0; i < count; i++) { - struct tcphdr *th = (struct tcphdr *)msg[i].l4h; uint32_t seq, seq_offset, ack_seq; - size_t len = msg[i].l4_len, off; + struct tcphdr *th; char *data; + size_t off; + + th = (struct tcphdr *)(pkt_buf + msg[i].pkt_buf_offset); + len = msg[i].l4_len; if (len < sizeof(*th)) { tcp_rst(c, conn); @@ -2152,19 +2156,11 @@ out: * Return: count of consumed packets */ int tcp_tap_handler(struct ctx *c, int af, void *addr, - struct tap_msg *msg, int count, struct timespec *now) + struct tap_l4_msg *msg, int count, struct timespec *now) { - struct tcphdr *th = (struct tcphdr *)msg[0].l4h; - size_t len = msg[0].l4_len, off; + struct tcphdr *th = (struct tcphdr *)(pkt_buf + msg[0].pkt_buf_offset); + uint16_t len = msg[0].l4_len; struct tcp_tap_conn *conn; - int ws; - - if (len < sizeof(*th)) - return 1; - - off = th->doff * 4; - if (off < sizeof(*th) || off > len) - return 1; conn = tcp_hash_lookup(c, af, addr, htons(th->source), htons(th->dest)); if (!conn) { -- cgit v1.2.3