Skip to content

Commit

Permalink
tcp: Fix snd_next adjustments
Browse files Browse the repository at this point in the history
We can't adjust snd_next in tcp_sendmsg, because then ACKs will result
in weird segments with sequence numbers that would indicate a gap in
data. Instead of that, adjust snd_next in tcp_output.

Signed-off-by: Pedro Falcato <[email protected]>
  • Loading branch information
heatd committed Jan 31, 2025
1 parent 19a6caa commit 4098752
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions kernel/kernel/net/tcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,8 @@ void tcp_stop_retransmit(struct tcp_socket *sock)

static bool tcp_snd_wnd_check(struct tcp_socket *tp, struct packetbuf *pbf)
{
u32 end = tcp_pbf_end_seq(pbf);
CHECK(pbf->tpi.seq == 0);
u32 end = tp->snd_next + tcp_pbf_end_seq(pbf);
return !after(end, tcp_wnd_end(tp));
}

Expand All @@ -521,6 +522,10 @@ int tcp_output(struct tcp_socket *sock)
if (sock->nagle_enabled && !tcp_nagle_can_send(sock, pbf, len))
break;

/* We're outputting this segment - assign snd_next and bump it */
pbf->tpi.seq = sock->snd_next;
sock->snd_next += pbf->tpi.seq_len;

struct packetbuf *clone = packetbuf_clone(pbf);
if (!clone)
return -ENOBUFS;
Expand Down Expand Up @@ -758,16 +763,12 @@ static void tcp_prepare_segment(struct tcp_socket *sock, struct packetbuf *pbf)
unsigned int flags = TCP_FLAG_ACK;
pbf_init_tcp(pbf);
auto segment_len = pbf_length(pbf);
pbf->tpi.seq = sock->snd_next;
pbf->tpi.seq = 0;
pbf->tpi.seq_len = segment_len;
pbf->tpi.ack = 1;
sock->snd_next += segment_len;

if (flags & TCP_FLAG_FIN)
{
pbf->tpi.seq_len++;
sock->snd_next++;
}
}

static int tcp_write_alloc(struct tcp_socket *sock);
Expand Down Expand Up @@ -865,7 +866,6 @@ static int tcp_append_to_segment(struct tcp_socket *tp, struct packetbuf *pbf,
len += pf.len;
write_space -= len;
pbf->tpi.seq_len += pf.len;
tp->snd_next += pf.len;
iter->advance(to_add);
}

Expand Down Expand Up @@ -1110,7 +1110,7 @@ static int tcp_send_fin(struct tcp_socket *sock)

pbf_reserve_headers(pbf, MAX_TCP_HEADER_LENGTH);
pbf_init_tcp(pbf);
pbf->tpi.seq = sock->snd_next++;
pbf->tpi.seq = 0;
pbf->tpi.seq_len = 1;
pbf->tpi.ack = pbf->tpi.fin = 1;
tcp_queue_packet(sock, pbf);
Expand Down

0 comments on commit 4098752

Please sign in to comment.