aboutgitcodebugslistschat
path: root/tcp.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-09-26 23:38:22 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-09-27 01:28:02 +0200
commitdd581730e54b934f80d5b6a820136707dc71c664 (patch)
treec58b140d407f4b308e1fc1d21703b444ea34cabd /tcp.c
parentdfc451319034f594037822b3193a30fa5715175f (diff)
downloadpasst-dd581730e54b934f80d5b6a820136707dc71c664.tar
passt-dd581730e54b934f80d5b6a820136707dc71c664.tar.gz
passt-dd581730e54b934f80d5b6a820136707dc71c664.tar.bz2
passt-dd581730e54b934f80d5b6a820136707dc71c664.tar.lz
passt-dd581730e54b934f80d5b6a820136707dc71c664.tar.xz
passt-dd581730e54b934f80d5b6a820136707dc71c664.tar.zst
passt-dd581730e54b934f80d5b6a820136707dc71c664.zip
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 <sbrivio@redhat.com>
Diffstat (limited to 'tcp.c')
-rw-r--r--tcp.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/tcp.c b/tcp.c
index 645d525..b269e0e 100644
--- a/tcp.c
+++ b/tcp.c
@@ -333,6 +333,7 @@
#include <sys/random.h>
#include <sys/socket.h>
#include <sys/types.h>
+#include <sys/uio.h>
#include <unistd.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
@@ -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) {