aboutgitcodebugslistschat
path: root/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcp.c')
-rw-r--r--tcp.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/tcp.c b/tcp.c
index 65a9aff..5f9d5f6 100644
--- a/tcp.c
+++ b/tcp.c
@@ -1081,15 +1081,17 @@ static int tcp_send_to_tap(struct ctx *c, struct tcp_tap_conn *conn,
uint32_t ack_offset = conn->seq_from_tap - conn->seq_ack_to_tap;
char buf[USHRT_MAX] = { 0 }, *data;
struct tcp_info info = { 0 };
+ int ws = 0, err, ack_pending;
socklen_t sl = sizeof(info);
struct tcphdr *th;
- int ws = 0, err;
- if (ack_offset < conn->tcpi_snd_wnd / 10 && !flags) {
+ if (!ack_offset && !flags) {
err = 0;
info.tcpi_bytes_acked = conn->tcpi_acked_last;
info.tcpi_snd_wnd = conn->tcpi_snd_wnd;
info.tcpi_snd_wscale = conn->ws;
+ } else if (conn->no_snd_wnd && !(flags & SYN)) {
+ err = 0;
} else {
err = getsockopt(conn->sock, SOL_TCP, TCP_INFO, &info, &sl);
if (err && !(flags & RST)) {
@@ -1135,21 +1137,32 @@ static int tcp_send_to_tap(struct ctx *c, struct tcp_tap_conn *conn,
conn->seq_to_tap += len;
}
- if (!err && ((info.tcpi_bytes_acked > conn->tcpi_acked_last) ||
- (flags & ACK) || len)) {
+ if (conn->no_snd_wnd) {
+ ack_pending = (conn->seq_from_tap - conn->seq_ack_to_tap) <
+ MAX_WINDOW;
+ } else {
+ ack_pending = info.tcpi_bytes_acked > conn->tcpi_acked_last;
+ }
+
+ if (!err && (ack_pending || (flags & ACK) || len)) {
th->ack = 1;
- conn->seq_ack_to_tap = info.tcpi_bytes_acked +
- conn->seq_init_from_tap;
+ if (conn->no_snd_wnd) {
+ conn->seq_ack_to_tap = conn->seq_from_tap;
+ } else {
+ conn->seq_ack_to_tap = info.tcpi_bytes_acked +
+ conn->seq_init_from_tap;
+ conn->tcpi_acked_last = info.tcpi_bytes_acked;
+ }
- if (conn->state == LAST_ACK) {
+ if (conn->state == LAST_ACK ||
+ conn->state == FIN_WAIT_1_SOCK_FIN)
conn->seq_ack_to_tap = conn->seq_from_tap + 1;
+
+ if (conn->state == LAST_ACK)
th->seq = htonl(ntohl(th->seq) + 1);
- }
th->ack_seq = htonl(conn->seq_ack_to_tap);
-
- conn->tcpi_acked_last = info.tcpi_bytes_acked;
} else {
if (!len && !flags)
return 0;