462 |
pcb->unacked = seg; |
pcb->unacked = seg; |
463 |
useg = seg; |
useg = seg; |
464 |
} else { |
} else { |
465 |
useg->next = seg; |
/* In the case of fast retransmit, the packet should not go to the end |
466 |
useg = useg->next; |
* of the unacked queue, but rather at the start. We need to check for |
467 |
|
* this case. -STJ Jul 27, 2004 */ |
468 |
|
if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){ |
469 |
|
seg->next = pcb->unacked; |
470 |
|
pcb->unacked = seg; |
471 |
|
} else { |
472 |
|
useg->next = seg; |
473 |
|
useg = useg->next; |
474 |
|
} |
475 |
} |
} |
476 |
} else { |
} else { |
477 |
tcp_seg_free(seg); |
tcp_seg_free(seg); |
577 |
} |
} |
578 |
|
|
579 |
void |
void |
580 |
|
tcp_rexmit_rto(struct tcp_pcb *pcb) |
581 |
|
{ |
582 |
|
struct tcp_seg *seg; |
583 |
|
|
584 |
|
if (pcb->unacked == NULL) { |
585 |
|
return; |
586 |
|
} |
587 |
|
|
588 |
|
/* Move all unacked segments to the unsent queue. */ |
589 |
|
for (seg = pcb->unacked; seg->next != NULL; seg = seg->next); |
590 |
|
seg->next = pcb->unsent; |
591 |
|
pcb->unsent = pcb->unacked; |
592 |
|
pcb->unacked = NULL; |
593 |
|
|
594 |
|
pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno); |
595 |
|
|
596 |
|
++pcb->nrtx; |
597 |
|
|
598 |
|
/* Don't take any rtt measurements after retransmitting. */ |
599 |
|
pcb->rttest = 0; |
600 |
|
|
601 |
|
/* Do the actual retransmission. */ |
602 |
|
tcp_output(pcb); |
603 |
|
|
604 |
|
} |
605 |
|
|
606 |
|
void |
607 |
tcp_rexmit(struct tcp_pcb *pcb) |
tcp_rexmit(struct tcp_pcb *pcb) |
608 |
{ |
{ |
609 |
struct tcp_seg *seg; |
struct tcp_seg *seg; |
630 |
|
|
631 |
} |
} |
632 |
|
|
633 |
|
|
634 |
void |
void |
635 |
tcp_keepalive(struct tcp_pcb *pcb) |
tcp_keepalive(struct tcp_pcb *pcb) |
636 |
{ |
{ |