diff --git a/src/libknot/xdp/protocols.h b/src/libknot/xdp/protocols.h index 691d64935dc4733ee6d68d88d4fc082d88b70e14..db48848db5de504f95463d74cc4456a54274b5a0 100644 --- a/src/libknot/xdp/protocols.h +++ b/src/libknot/xdp/protocols.h @@ -49,8 +49,10 @@ enum { PROT_TCP_OPT_ENDOP = 0, PROT_TCP_OPT_NOOP = 1, PROT_TCP_OPT_MSS = 2, + PROT_TCP_OPT_WSC = 3, // window scale PROT_TCP_OPT_LEN_MSS = 4, + PROT_TCP_OPT_LEN_WSC = 3, }; inline static void *prot_read_tcp(void *data, knot_xdp_msg_t *msg, uint16_t *src_port, uint16_t *dst_port) @@ -185,7 +187,7 @@ inline static size_t prot_write_hdrs_len(const knot_xdp_msg_t *msg) } if (msg->flags & KNOT_XDP_MSG_TCP) { - res += sizeof(struct tcphdr) - sizeof(struct udphdr); + res += sizeof(struct tcphdr) - sizeof(struct udphdr) + 4; // 4 == PROT_TCP_OPT_LEN_WSC + align if (msg->flags & KNOT_XDP_MSG_MSS) { res += PROT_TCP_OPT_LEN_MSS; @@ -268,7 +270,7 @@ inline static void prot_write_tcp(void *data, const knot_xdp_msg_t *msg, void *d tcp->dest = dst_port; tcp->seq = htobe32(msg->seqno); tcp->ack_seq = htobe32(msg->ackno); - tcp->window = htobe16(0x8000); // TODO proper window size handling in TCP streams + tcp->window = htobe16(0xffff); // Practically infinite window (see also WSC option below) tcp->check = 0; // Temporarily initialize before checksum calculation. tcp->syn = ((msg->flags & KNOT_XDP_MSG_SYN) ? 1 : 0); @@ -277,6 +279,11 @@ inline static void prot_write_tcp(void *data, const knot_xdp_msg_t *msg, void *d tcp->rst = ((msg->flags & KNOT_XDP_MSG_RST) ? 1 : 0); uint8_t *hdr_end = data + sizeof(*tcp); + hdr_end[0] = PROT_TCP_OPT_WSC; + hdr_end[1] = PROT_TCP_OPT_LEN_WSC; + hdr_end[2] = 14; // Maximum possible. + hdr_end += PROT_TCP_OPT_LEN_WSC; + *hdr_end++ = PROT_TCP_OPT_NOOP; if (msg->flags & KNOT_XDP_MSG_MSS) { uint16_t mss = htobe16(1460); // TODO: set proper MSS value hdr_end[0] = PROT_TCP_OPT_MSS;