]> mj.ucw.cz Git - netgrind.git/commitdiff
Changed handling of TCP timeouts.
authorMartin Mares <mj@ucw.cz>
Fri, 20 Jun 2003 11:52:03 +0000 (11:52 +0000)
committerMartin Mares <mj@ucw.cz>
Fri, 20 Jun 2003 11:52:03 +0000 (11:52 +0000)
netgrind/tcp.c

index dcd378c48a9549c98f7f3ab4abded8c09cd9d80a..c914fb354747d948f5bc90ad0be9cc75985b5642 100644 (file)
@@ -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: