/* TCP timeout routines */ #include #include "global.h" #include "mbuf.h" #include "timer.h" #include "netuser.h" #include "internet.h" #include "tcp.h" /* Timer timeout */ void tcp_timeout(arg) char *arg; { register struct tcb *tcb; tcb = (struct tcb *)arg; if(tcb == NULLTCB) return; /* Make sure the timer has stopped (we might have been kicked) */ stop_timer(&tcb->timer); switch(tcb->state){ case TIME_WAIT: /* 2MSL timer has expired */ close_self(tcb,NORMAL); break; default: /* Retransmission timer has expired */ tcb->flags |= RETRAN; /* Indicate > 1 transmission */ /* Perform backoff calculation */ tcb->backoff++; tcb->timer.start = BETA * backoff(tcb->backoff) * max(tcb->srtt,1) / MSPTICK; #ifdef notdef tcb->timer.start = backoff(tcb->backoff) * (BETA * tcb->srtt)/MSPTICK; /* Never initialize the timer with zero; it won't run! */ tcb->timer.start = max(tcb->timer.start,1); #endif tcb->snd.ptr = tcb->snd.una; tcp_output(tcb); } } /* Backoff function - the subject of much research */ backoff(n) int n; { /* Use binary exponential up to retry #4, and quadratic after that * This yields the sequence * 1, 2, 4, 8, 16, 25, 36, 49, 64, 81, 100 ... */ if(n <= 4) return 1 << n; /* Binary exponential back off */ else return n * n; /* Quadratic back off */ }