From: Martin Mares Date: Fri, 20 Jun 2003 11:52:03 +0000 (+0000) Subject: Changed handling of TCP timeouts. X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=b4447c7bffa16b26192aacbd205fb4f38bd186dd;p=netgrind.git Changed handling of TCP timeouts. --- diff --git a/netgrind/tcp.c b/netgrind/tcp.c index dcd378c..c914fb3 100644 --- a/netgrind/tcp.c +++ b/netgrind/tcp.c @@ -145,8 +145,8 @@ static void tcp_time_step(uns now, uns doomsday) { struct flow *f = flow_heap[1]; HEAP_DELMIN(struct flow *, flow_heap, tcp_num_flows, FLOW_HEAP_LESS, FLOW_HEAP_SWAP); - DBG("%s for flow %p(%s/%s)\n", (doomsday ? "DOOMSDAY" : "TIMEOUT"), f, - pipe_state_names[f->pipe[0].state], pipe_state_names[f->pipe[1].state]); + DBG("%s for flow %p(%s/%s) now=%d\n", (doomsday ? "DOOMSDAY" : "TIMEOUT"), f, + flow_state_names[f->pipe[0].state], flow_state_names[f->pipe[1].state], now); if (f->pipe[0].state != FLOW_FINISHED || f->pipe[1].state != FLOW_FINISHED) { uns cause; @@ -185,7 +185,7 @@ static void tcp_enqueue_data(struct pipe *b, struct pkt *p) DBG("DATA:"); if (tcp_seq_lt(b->queue_start_seq, p->seq) && p->seq - b->queue_start_seq >= 0x40000) { - DBG(" OUT OF WINDOW (q-start=%u)\n", b->queue_start_seq); + DBG(" OUT OF WINDOW (q-start=%u)", b->queue_start_seq); pkt_free(p); return; } @@ -246,6 +246,7 @@ void tcp_got_packet(struct iphdr *iph, struct pkt *p) } fakehdr; struct pkt *q; uns now = timestamp_to_now(p->timestamp); + struct flow *f = NULL; tcp_time_step(now, 0); @@ -271,7 +272,7 @@ void tcp_got_packet(struct iphdr *iph, struct pkt *p) u32 seq = ntohl(tcph->seq); u32 ack = ntohl(tcph->ack_seq); - DBG("TCP %08x %08x %04x %04x seq=%u len=%u end=%u ack=%u%s%s%s%s%s%s\n", + DBG("TCP %08x %08x %04x %04x seq=%u len=%u end=%u ack=%u%s%s%s%s%s%s now=%d\n", ntohl(iph->saddr), ntohl(iph->daddr), ntohs(tcph->source), ntohs(tcph->dest), seq, pkt_len(p) - hdrlen, seq + pkt_len(p) - hdrlen, ack, (tcph->fin ? " FIN" : ""), @@ -279,9 +280,9 @@ void tcp_got_packet(struct iphdr *iph, struct pkt *p) (tcph->rst ? " RST" : ""), (tcph->psh ? " PSH" : ""), (tcph->ack ? " ACK" : ""), - (tcph->urg ? " URG" : "")); + (tcph->urg ? " URG" : ""), + now); - struct flow *f; struct pipe *a, *b; if (f = flow_lookup(iph->saddr, iph->daddr, tcph->source, tcph->dest)) { @@ -319,11 +320,13 @@ void tcp_got_packet(struct iphdr *iph, struct pkt *p) pkt_account(&f->stat_raw, p); pkt_pop(p, hdrlen); - DBG("\t%p %s (%s/%s) ", f, (a == &f->pipe[0] ? "A->B" : "B->A"), pipe_state_names[f->pipe[0].state], pipe_state_names[f->pipe[1].state]); + DBG("\t%p %s (%s/%s) ", f, (a == &f->pipe[0] ? "A->B" : "B->A"), flow_state_names[f->pipe[0].state], flow_state_names[f->pipe[1].state]); if (a->state == FLOW_FINISHED && b->state == FLOW_FINISHED) { + /* XXX: Here we probably should handle SYN (fast recycling of ports) */ DBG("closed\n"); pkt_account(&stat_tcp_on_closed, p); + f = NULL; /* Avoid shifting flow timeout */ goto drop; } @@ -333,12 +336,9 @@ void tcp_got_packet(struct iphdr *iph, struct pkt *p) cnt_tcp_causes[CAUSE_RESET]++; f->appl->close(f, CAUSE_RESET, p->timestamp); a->state = b->state = FLOW_FINISHED; - flow_set_timeout(f, now + 120); goto drop; } - flow_set_timeout(f, now + 3000); /* Somewhat arbitrary timeout */ - if (tcph->syn) { if (tcph->fin || pkt_len(p)) @@ -401,7 +401,6 @@ void tcp_got_packet(struct iphdr *iph, struct pkt *p) DBG("CLOSED BOTH WAYS\n"); cnt_tcp_causes[CAUSE_CLOSE]++; f->appl->close(f, CAUSE_CLOSE, p->timestamp); - flow_set_timeout(f, now + 300); /* FIXME */ goto drop; } else @@ -456,19 +455,30 @@ void tcp_got_packet(struct iphdr *iph, struct pkt *p) } } DBG("\n"); - return; + goto done; } else goto unex; + /* Not reached */ + dup: + DBG("DUP\n"); drop: pkt_free(p); + done: + if (f) + { + int timeout = 60; /* Connection setup timeout */ + if (f->pipe[0].state == FLOW_FINISHED && f->pipe[1].state == FLOW_FINISHED) + timeout = 30; /* After connection close; later the packets are just unmatched */ + else if ((f->pipe[0].state == FLOW_ESTABLISHED || f->pipe[0].state == FLOW_FIN_SENT || f->pipe[0].state == FLOW_FINISHED) && + (f->pipe[1].state == FLOW_ESTABLISHED || f->pipe[1].state == FLOW_FIN_SENT || f->pipe[1].state == FLOW_FINISHED)) + timeout = 900; /* Data phase timeout */ + DBG("timeout at %d\n", now+timeout); + flow_set_timeout(f, now + timeout); + } return; - dup: - DBG("DUP\n"); - goto drop; - unex: DBG("UNEXPECTED\n"); unexpected: