plan 9 kernel history: overview | file list | diff list

port/tcpinput.c (diff list | history)

1991/0424/sys/src/9/port/tcpinput.c:657,6631991/0625/sys/src/9/port/tcpinput.c:657,662 (short | long)
1991/0424    
	qlock(&reseqlock); 
	if(!reseqfree) { 
		qunlock(&reseqlock); 
		print("tcp: no resequence descriptors\n"); 
		freeb(bp); 
		return; 
	} 
1991/0625/sys/src/9/port/tcpinput.c:21,261991/0705/sys/src/9/port/tcpinput.c:21,38 (short | long)
1991/0424    
	"Closing", 	"Last_ack", 	"Time_wait" }; 
 
void 
1991/0705    
tcpinit(void) 
{ 
	Reseq *r; 
 
	reseqfree = ialloc(sizeof(Reseq)*Nreseq, 0); 
	for(r = reseqfree; r < &reseqfree[Nreseq-1]; r++) 
		r->next = r+1; 
 
	r->next = 0; 
} 
 
void 
1991/0424    
tcp_input(Ipconv *ipc, Block *bp) 
{ 
	Ipconv *s, *new, *etab; 
1991/0625/sys/src/9/port/tcpinput.c:657,6621991/0705/sys/src/9/port/tcpinput.c:669,675
1991/0424    
	qlock(&reseqlock); 
	if(!reseqfree) { 
		qunlock(&reseqlock); 
1991/0705    
		print("tcp: no resequence descriptors\n"); 
1991/0424    
		freeb(bp); 
		return; 
	} 
1991/0705/sys/src/9/port/tcpinput.c:9,151991/0727/sys/src/9/port/tcpinput.c:9,15 (short | long)
1991/0424    
 
int tcpdbg = 0; 
#define DPRINT	if(tcpdbg) print 
#define LPRINT  print 
1991/0727    
#define LPRINT  if(tcpdbg) print 
1991/0424    
 
extern Queue *Tcpoutput; 
QLock	reseqlock; 
1991/0727/sys/src/9/port/tcpinput.c:438,4441991/0926/sys/src/9/port/tcpinput.c:438,444 (short | long)
1991/0424    
			close_self(s, Etimedout); 
		break; 
	case ICMP_SOURCEQUENCH: 
		tcb->cwind /= 2; 
1991/0926    
		tcb->cwind = tcb->cwind/2; 
1991/0424    
		tcb->cwind = MAX(tcb->mss,tcb->cwind); 
		break; 
	} 
1991/0926/sys/src/9/port/tcpinput.c:11,171991/1019/sys/src/9/port/tcpinput.c:11,16 (short | long)
1991/0424    
#define DPRINT	if(tcpdbg) print 
1991/0727    
#define LPRINT  if(tcpdbg) print 
1991/0424    
 
extern Queue *Tcpoutput; 
QLock	reseqlock; 
Reseq	*reseqfree; 
 
1991/0926/sys/src/9/port/tcpinput.c:497,5031991/1019/sys/src/9/port/tcpinput.c:496,502
1991/0424    
	DPRINT("Reset: seq = %lux ack = %d flags = %lux\n", 
	       seg->seq, seg->ack, seg->flags); 
 
	PUTNEXT(Tcpoutput, hbp); 
1991/1019    
	PUTNEXT(Ipoutput, hbp); 
1991/0424    
} 
 
void 
1991/1019/sys/src/9/port/tcpinput.c:34,401991/1023/sys/src/9/port/tcpinput.c:34,40 (short | long)
1991/0705    
void 
1991/0424    
tcp_input(Ipconv *ipc, Block *bp) 
{ 
	Ipconv *s, *new, *etab; 
1991/1023    
	Ipconv *s, *new; 
1991/0424    
	Tcpctl *tcb;		 
	Tcphdr *h; 
	Tcp seg; 
1991/1019/sys/src/9/port/tcpinput.c:108,1281991/1023/sys/src/9/port/tcpinput.c:108,115
1991/0424    
			goto clear; 
		} 
 
		/* Find a conversation to clone onto */ 
		etab = &ipc[conf.ip]; 
		for(new = ipc; new < etab; new++) { 
			if(new->ref == 0 && canqlock(new)) { 
				if(new->ref || new->tcpctl.state != CLOSED) { 
					qunlock(new); 
					continue; 
				} 
				new->ref++; 
				qunlock(new); 
				break; 
			} 
		} 
                 
		if(new == etab) 
1991/1023    
		new = ipincoming(ipc); 
		if(new == 0) 
1991/0424    
			goto clear; 
 
		s->curlog++; 
1991/1019/sys/src/9/port/tcpinput.c:137,1471991/1023/sys/src/9/port/tcpinput.c:124,134
1991/0424    
		new->tcpctl.acktimer.arg = new; 
		new->tcpctl.acktimer.state = TIMER_STOP; 
 
1991/1023    
		new->newcon = 1; 
1991/0424    
		new->ipinterface = s->ipinterface; 
		s->ipinterface->ref++; 
                 
		/* Wake the sleeping dodo */ 
		wakeup(&s->listenr); 
1991/1023    
 
1991/0424    
		s = new; 
	} 
	 
1991/1023/sys/src/9/port/tcpinput.c:39,451991/1030/sys/src/9/port/tcpinput.c:39,44 (short | long)
1991/0424    
	Tcphdr *h; 
	Tcp seg; 
	int hdrlen;	 
	Block *oobbp; 
	Ipaddr source, dest; 
	char tos; 
	ushort length; 
1991/1023/sys/src/9/port/tcpinput.c:293,3141991/1030/sys/src/9/port/tcpinput.c:292,300
1991/0424    
		} 
 
		if ((seg.flags&URG) && seg.up) { 
			DPRINT("tcpin: oob: up = %u seq = %u rcv.up = %u\n", 
			       seg.up, seg.seq, tcb->rcv.up); 
			if (seq_gt(seg.up + seg.seq, tcb->rcv.up)) { 
				tcb->rcv.up = seg.up + seg.seq; 
				tcb->oobflags &= ~(TCPOOB_HAVEDATA|TCPOOB_HADDATA); 
				extract_oob(&bp, &oobbp, &seg); 
				if (oobbp) { 
					DPRINT("tcpin: oob delivered\n"); 
					appendb(&tcb->rcvoobq, oobbp); 
					tcb->rcvoobcnt += blen(oobbp); 
					tcb->oobmark = tcb->rcvcnt; 
					tcb->oobflags |= TCPOOB_HAVEDATA; 
#ifdef NOTIFY 
					urg_signal(s); 
#endif 
				} 
1991/1030    
				copyupb(&bp, 0, seg.up); 
1991/0424    
			} 
		}  
		else if (seq_gt(tcb->rcv.nxt, tcb->rcv.up)) 
1991/1023/sys/src/9/port/tcpinput.c:386,3921991/1030/sys/src/9/port/tcpinput.c:372,378
1991/0424    
				goto gotone; 
		} 
		break; 
gotone:; 
1991/1030    
		gotone:; 
1991/0424    
	} 
output: 
	tcp_output(s); 
1991/1023/sys/src/9/port/tcpinput.c:490,4981991/1030/sys/src/9/port/tcpinput.c:476,485
1991/0424    
update(Ipconv *s, Tcp *seg) 
{ 
	ushort acked; 
	ushort oobacked; 
	ushort expand; 
	Tcpctl *tcb = &s->tcpctl; 
1991/1030    
	int rtt; 
	int abserr; 
1991/0424    
 
	if(seq_gt(seg->ack, tcb->snd.nxt)) { 
		tcb->flags |= FORCE; 
1991/1023/sys/src/9/port/tcpinput.c:512,5181991/1030/sys/src/9/port/tcpinput.c:499,504
1991/0424    
		return;	 
 
	acked = seg->ack - tcb->snd.una; 
                 
	if(tcb->cwind < tcb->snd.wnd) { 
		if(tcb->cwind < tcb->ssthresh) 
			expand = MIN(acked,tcb->mss); 
1991/1023/sys/src/9/port/tcpinput.c:521,5331991/1030/sys/src/9/port/tcpinput.c:507,516
1991/0424    
 
		if(tcb->cwind + expand < tcb->cwind) 
			expand = 65535 - tcb->cwind; 
                 
		if(tcb->cwind + expand > tcb->snd.wnd) 
			expand = tcb->snd.wnd - tcb->cwind; 
                 
		if(expand != 0) 
			tcb->cwind += expand; 
                 
	} 
 
	/* Round trip time estimation */ 
1991/1023/sys/src/9/port/tcpinput.c:534,5451991/1030/sys/src/9/port/tcpinput.c:517,525
1991/0424    
	if(run_timer(&tcb->rtt_timer) && seq_ge(seg->ack, tcb->rttseq)) { 
		stop_timer(&tcb->rtt_timer); 
		if(!(tcb->flags & RETRAN)) { 
			int rtt;	/* measured round trip time */ 
			int abserr;	/* abs(rtt - srtt) */ 
 
			rtt = tcb->rtt_timer.start - tcb->rtt_timer.count; 
			rtt *= MSPTICK;	 
                 
			if(rtt > tcb->srtt && 
			  (tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED)) 
				tcb->srtt = rtt; 
1991/1023/sys/src/9/port/tcpinput.c:556,5831991/1030/sys/src/9/port/tcpinput.c:536,551
1991/0424    
	} 
 
	/* If we're waiting for an ack of our SYN, note it and adjust count */ 
	if(!(tcb->flags & SYNACK)){ 
1991/1030    
	if((tcb->flags & SYNACK) == 0){ 
1991/0424    
		tcb->flags |= SYNACK; 
		acked--; 
		tcb->sndcnt--; 
	} 
 
	/* Acking some oob data if relevant */ 
	if(tcb->sndoobq && seq_ge(tcb->snd.up,tcb->snd.una) && 
	   seq_gt(seg->ack, tcb->snd.up)) { 
		oobacked = seg->ack - tcb->snd.up; 
		acked -= oobacked; 
		copyupb(&tcb->sndoobq, 0, oobacked); 
		tcb->sndoobcnt -= oobacked; 
		DPRINT("update: oobacked = %d\n", oobacked); 
	} 
                 
	copyupb(&tcb->sndq, 0, acked); 
 
	/* This will include the FIN if there is one */ 
	tcb->sndcnt -= acked; 
	tcb->snd.una = seg->ack; 
	/* If ack includes some out-of-band data then update urgent pointer */ 
	if (seq_gt(seg->ack, tcb->snd.up)) 
		tcb->snd.up = seg->ack; 
 
1991/1023/sys/src/9/port/tcpinput.c:588,5961991/1030/sys/src/9/port/tcpinput.c:556,561
1991/0424    
	if(tcb->snd.una != tcb->snd.nxt) 
		start_timer(&tcb->timer); 
 
	/* If retransmissions have been occurring, make sure the 
	 * send pointer doesn't repeat ancient history 
	 */ 
	if(seq_lt(tcb->snd.ptr, tcb->snd.una)) 
		tcb->snd.ptr = tcb->snd.una; 
 
1991/1023/sys/src/9/port/tcpinput.c:605,6121991/1030/sys/src/9/port/tcpinput.c:570,576
1991/0424    
int 
in_window(Tcpctl *tcb, int seq) 
{ 
	return seq_within(seq, tcb->rcv.nxt,  
			 (int)(tcb->rcv.nxt+tcb->rcv.wnd-1)); 
1991/1030    
	return seq_within(seq, tcb->rcv.nxt, (int)(tcb->rcv.nxt+tcb->rcv.wnd-1)); 
1991/0424    
} 
 
void 
1991/1023/sys/src/9/port/tcpinput.c:629,6351991/1030/sys/src/9/port/tcpinput.c:593,598
1991/0424    
		tcb->mss = seg->mss; 
 
	tcb->max_snd = seg->wnd; 
                 
	if((mtu = s->ipinterface->maxmtu) != 0) { 
		mtu -= TCP_HDRSIZE + TCP_EHSIZE + TCP_PHDRSIZE;  
		tcb->cwind = tcb->mss = MIN(mtu, tcb->mss); 
1991/1023/sys/src/9/port/tcpinput.c:677,6841991/1030/sys/src/9/port/tcpinput.c:640,646
1991/0424    
	}  
	else { 
		for(;;){ 
			if(rp1->next == 0 || 
			   seq_lt(seg->seq, rp1->next->seg.seq)) { 
1991/1030    
			if(rp1->next == 0 || seq_lt(seg->seq, rp1->next->seg.seq)) { 
1991/0424    
				rp->next = rp1->next; 
				rp1->next = rp; 
				break; 
1991/1023/sys/src/9/port/tcpinput.c:688,6941991/1030/sys/src/9/port/tcpinput.c:650,655
1991/0424    
	} 
} 
 
                 
void 
get_reseq(Tcpctl *tcb, char *tos, Tcp *seg, Block **bp, ushort *length) 
{ 
1991/1023/sys/src/9/port/tcpinput.c:729,7351991/1030/sys/src/9/port/tcpinput.c:690,697
1991/0424    
	if(tcb->rcv.wnd == 0) { 
		if(seg->seq == tcb->rcv.nxt && len == 0) 
			return 0; 
	} else { 
1991/1030    
	} 
	else { 
1991/0424    
		/* Some part of the segment must be in the window */ 
		if(in_window(tcb,seg->seq)) { 
			accept++; 
1991/1023/sys/src/9/port/tcpinput.c:771,7771991/1030/sys/src/9/port/tcpinput.c:733,739
1991/0424    
		} 
	} 
	excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd); 
	if(excess > 0){ 
1991/1030    
	if(excess > 0) { 
1991/0424    
		tcb->rerecv += excess; 
		*length -= excess; 
		nbp = copyb(*bp, *length); 
1991/1023/sys/src/9/port/tcpinput.c:782,8001991/1030/sys/src/9/port/tcpinput.c:744,749
1991/0424    
	return 0; 
} 
 
void 
extract_oob(Block **bp, Block **oobbp, Tcp *seg) 
                 
{ 
	DPRINT("extract_oob: size = %u\n", seg->up); 
                 
	if (*oobbp = allocb(seg->up)) 
		(*oobbp)->wptr = (*oobbp)->wptr + 
			         copyupb(bp, (*oobbp)->rptr, seg->up); 
	else 
		copyupb(bp, 0, seg->up); 
} 
                 
int 
copyupb(Block **bph, uchar *data, int count) 
{ 
1991/1023/sys/src/9/port/tcpinput.c:821,8271991/1030/sys/src/9/port/tcpinput.c:770,775
1991/0424    
			freeb(bp); 
		} 
	} 
                 
	return bytes; 
} 
 
1991/1023/sys/src/9/port/tcpinput.c:949,9551991/1030/sys/src/9/port/tcpinput.c:897,902
1991/0424    
 
	tcb->reseq = 0; 
	s->err = reason; 
                 
	setstate(s, CLOSED); 
} 
 
1991/1023/sys/src/9/port/tcpinput.c:968,9741991/1030/sys/src/9/port/tcpinput.c:915,922
1991/0424    
	if(low <= high){ 
		if(low <= x && x <= high) 
			return 1; 
	} else { 
1991/1030    
	} 
	else { 
1991/0424    
		if(low >= x && x >= high) 
			return 1; 
	} 
1991/1023/sys/src/9/port/tcpinput.c:1007,10131991/1030/sys/src/9/port/tcpinput.c:955,960
1991/0424    
 
	oldstate = tcb->state; 
	tcb->state = newstate; 
                 
	state_upcall(s, oldstate, newstate); 
} 
 
1991/1023/sys/src/9/port/tcpinput.c:1107,11131991/1030/sys/src/9/port/tcpinput.c:1054,1060
1991/0424    
	for(optr = h->tcpopt, i = TCP_HDRSIZE; i < hdrlen;) { 
		switch(*optr++){ 
		case EOL_KIND: 
			goto eol; 
1991/1030    
			return hdrlen; 
1991/0424    
		case NOOP_KIND: 
			i++; 
			break; 
1991/1023/sys/src/9/port/tcpinput.c:1119,11241991/1030/sys/src/9/port/tcpinput.c:1066,1070
1991/0424    
			break; 
		} 
	} 
eol: 
	return hdrlen; 
} 
1991/1030/sys/src/9/port/tcpinput.c:34,401991/1102/sys/src/9/port/tcpinput.c:34,40 (short | long)
1991/0705    
void 
1991/0424    
tcp_input(Ipconv *ipc, Block *bp) 
{ 
1991/1023    
	Ipconv *s, *new; 
1991/1102    
	Ipconv *s, *e, *new; 
1991/0424    
	Tcpctl *tcb;		 
	Tcphdr *h; 
	Tcp seg; 
1991/1030/sys/src/9/port/tcpinput.c:85,1361991/1102/sys/src/9/port/tcpinput.c:85,137
1991/0424    
	if(bp == 0) 
		return; 
 
	if (!(s = ip_conn(ipc, seg.dest, seg.source, source, IP_TCPPROTO))) { 
1991/1102    
	s = ip_conn(ipc, seg.dest, seg.source, source, IP_TCPPROTO); 
	if (s == 0) { 
1991/0424    
		LPRINT("tcpin: look for listen on %d\n", seg.dest); 
 
		if(!(seg.flags & SYN)) { 
			LPRINT("tcpin: No SYN\n"); 
		clear: 
			LPRINT("tcpin: call cleared\n"); 
			freeb(bp);    
                        reset(source, dest, tos, length, &seg); 
                        return; 
		}		 
                 
		if(!(s = ip_conn(ipc, seg.dest, 0, 0, IP_TCPPROTO))) { 
			LPRINT("tcpin: No socket dest on %d\n", seg.dest); 
1991/1102    
		if((seg.flags & SYN) == 0) 
1991/0424    
			goto clear; 
		} 
 
		if(s->curlog >= s->backlog) { 
			LPRINT("too many pending\n"); 
			goto clear; 
		} 
1991/1102    
		e = &ipc[conf.ip]; 
		for(s = ipc; s < e; s++) { 
			if(s->tcpctl.state == LISTEN) 
			if(s->pdst == 0) 
			if(s->dst == 0) { 
				if(s->curlog >= s->backlog) 
					goto clear; 
1991/0424    
 
1991/1023    
		new = ipincoming(ipc); 
		if(new == 0) 
1991/0424    
			goto clear; 
1991/1102    
				new = ipincoming(ipc); 
				if(new == 0) 
					goto clear; 
1991/0424    
 
		s->curlog++; 
		LPRINT("tcpin: cloning socket\n"); 
		new->psrc = s->psrc; 
		new->pdst = seg.source; 
		new->dst = source; 
		memmove(&new->tcpctl, &s->tcpctl, sizeof(Tcpctl)); 
		new->tcpctl.flags &= ~CLONE; 
		new->tcpctl.timer.arg = new; 
		new->tcpctl.timer.state = TIMER_STOP; 
		new->tcpctl.acktimer.arg = new; 
		new->tcpctl.acktimer.state = TIMER_STOP; 
1991/1102    
				s->curlog++; 
				LPRINT("tcpin: cloning socket\n"); 
				new->psrc = seg.dest; 
				new->pdst = seg.source; 
				new->dst = source; 
				memmove(&new->tcpctl, &s->tcpctl, sizeof(Tcpctl)); 
				new->tcpctl.flags &= ~CLONE; 
				new->tcpctl.timer.arg = new; 
				new->tcpctl.timer.state = TIMER_STOP; 
				new->tcpctl.acktimer.arg = new; 
				new->tcpctl.acktimer.state = TIMER_STOP; 
1991/0424    
 
1991/1023    
		new->newcon = 1; 
1991/0424    
		new->ipinterface = s->ipinterface; 
		s->ipinterface->ref++; 
		wakeup(&s->listenr); 
1991/1102    
				new->newcon = 1; 
				new->ipinterface = s->ipinterface; 
				s->ipinterface->ref++; 
				wakeup(&s->listenr); 
1991/1023    
 
1991/0424    
		s = new; 
1991/1102    
				s = new; 
				goto process; 
			} 
		} 
	clear: 
		LPRINT("tcpin: call cleared\n"); 
		freeb(bp);    
		reset(source, dest, tos, length, &seg); 
		return; 
1991/0424    
	} 
	                 
1991/1102    
process:	 
1991/0424    
	tcb = &s->tcpctl; 
	qlock(tcb); 
 
1991/1102/sys/src/9/port/tcpinput.c:57,701991/1104/sys/src/9/port/tcpinput.c:57,67 (short | long)
1991/0424    
			print("tcpin: allocb failure."); 
			return; 
		} 
		DPRINT("tcpin: Duplicate packet %lux\n", bp); 
	} 
 
	h->Unused = 0; 
	hnputs(h->tcplen, length - (TCP_IPLEN+TCP_PHDRSIZE)); 
                 
	if(ptcl_csum(bp, TCP_EHSIZE+TCP_IPLEN, length - TCP_IPLEN)) { 
		DPRINT("tcpin: Bad checksum.\n"); 
		freeb(bp); 
		return; 
	} 
1991/1102/sys/src/9/port/tcpinput.c:74,861991/1104/sys/src/9/port/tcpinput.c:71,76
1991/0424    
 
	/* Adjust the data length */ 
	length -= (hdrlen+TCP_IPLEN+TCP_PHDRSIZE); 
	                 
	DPRINT("tcpin: lport = %d, rport = %d hdrlen %d", 
		seg.dest, seg.source, hdrlen); 
	DPRINT(" flags = 0x%lux, seqo = %d, seqi = %d len %d\n",  
		seg.flags, seg.seq, seg.ack, length); 
                 
	/* Trim the packet down to just the data */ 
	bp = btrim(bp, hdrlen+TCP_PKT, length); 
	if(bp == 0) 
		return; 
1991/1102/sys/src/9/port/tcpinput.c:87,941991/1104/sys/src/9/port/tcpinput.c:77,82
1991/0424    
 
1991/1102    
	s = ip_conn(ipc, seg.dest, seg.source, source, IP_TCPPROTO); 
	if (s == 0) { 
1991/0424    
		LPRINT("tcpin: look for listen on %d\n", seg.dest); 
                 
1991/1102    
		if((seg.flags & SYN) == 0) 
1991/0424    
			goto clear; 
 
1991/1102/sys/src/9/port/tcpinput.c:105,1111991/1104/sys/src/9/port/tcpinput.c:93,98
1991/1102    
					goto clear; 
1991/0424    
 
1991/1102    
				s->curlog++; 
				LPRINT("tcpin: cloning socket\n"); 
				new->psrc = seg.dest; 
				new->pdst = seg.source; 
				new->dst = source; 
1991/1102/sys/src/9/port/tcpinput.c:115,1321991/1104/sys/src/9/port/tcpinput.c:102,117
1991/1102    
				new->tcpctl.timer.state = TIMER_STOP; 
				new->tcpctl.acktimer.arg = new; 
				new->tcpctl.acktimer.state = TIMER_STOP; 
1991/0424    
                 
1991/1102    
				new->newcon = 1; 
				new->ipinterface = s->ipinterface; 
1991/1104    
 
1991/1102    
				s->ipinterface->ref++; 
				wakeup(&s->listenr); 
1991/1023    
                 
1991/1102    
				s = new; 
				goto process; 
			} 
		} 
	clear: 
		LPRINT("tcpin: call cleared\n"); 
		freeb(bp);    
		reset(source, dest, tos, length, &seg); 
		return; 
1991/1102/sys/src/9/port/tcpinput.c:219,2261991/1104/sys/src/9/port/tcpinput.c:204,210
1991/0424    
		goto done; 
	} 
 
	if(seg.seq != tcb->rcv.nxt 
	 && (length != 0 || (seg.flags & (SYN|FIN)) )) { 
1991/1104    
	if(seg.seq != tcb->rcv.nxt && (length != 0 || (seg.flags & (SYN|FIN)) )) { 
1991/0424    
		add_reseq(tcb, tos, &seg, bp, length); 
		tcb->flags |= FORCE; 
		goto output; 
1991/1102/sys/src/9/port/tcpinput.c:301,3091991/1104/sys/src/9/port/tcpinput.c:285,290
1991/0424    
		else if (seq_gt(tcb->rcv.nxt, tcb->rcv.up)) 
			tcb->rcv.up = tcb->rcv.nxt; 
 
		DPRINT("tcpin: Append pkt len=%d state=%s\n",  
			length, tcpstate[tcb->state]); 
                 
		if(length != 0){ 
			switch(tcb->state){ 
			case SYN_RECEIVED: 
1991/1102/sys/src/9/port/tcpinput.c:366,3731991/1104/sys/src/9/port/tcpinput.c:347,353
1991/0424    
				break; 
			} 
		} 
		while(tcb->reseq != 0 && 
		      seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq)){ 
1991/1104    
		while(tcb->reseq != 0 && seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq)) { 
1991/0424    
			get_reseq(tcb, &tos, &seg, &bp, &length); 
			if(trim(tcb, &seg, &bp, &length) == 0) 
				goto gotone; 
1991/1102/sys/src/9/port/tcpinput.c:466,4741991/1104/sys/src/9/port/tcpinput.c:446,451
1991/0424    
	seg->mss = 0; 
	if((hbp = htontcp(seg, 0, &ph)) == 0) 
		return; 
                 
	DPRINT("Reset: seq = %lux ack = %d flags = %lux\n", 
	       seg->seq, seg->ack, seg->flags); 
 
1991/1019    
	PUTNEXT(Ipoutput, hbp); 
1991/0424    
} 
1991/1104/sys/src/9/port/tcpinput.c:52,641991/1106/sys/src/9/port/tcpinput.c:52,57 (short | long)
1991/0424    
	tos = h->tos; 
	length = nhgets(h->length); 
 
	if (dest == source) { 
		if (!(bp = copyb(bp, blen(bp)))) { 
			print("tcpin: allocb failure."); 
			return; 
		} 
	} 
                 
	h->Unused = 0; 
	hnputs(h->tcplen, length - (TCP_IPLEN+TCP_PHDRSIZE)); 
	if(ptcl_csum(bp, TCP_EHSIZE+TCP_IPLEN, length - TCP_IPLEN)) { 
1991/1106/sys/src/9/port/tcpinput.c:81,871991/1115/sys/src/9/port/tcpinput.c:81,87 (short | long)
1991/1102    
				if(s->curlog >= s->backlog) 
					goto clear; 
1991/0424    
 
1991/1102    
				new = ipincoming(ipc); 
1991/1115    
				new = ipincoming(ipc, s); 
1991/1102    
				if(new == 0) 
					goto clear; 
1991/0424    
 
1991/1115/sys/src/9/port/tcpinput.c:800,8211991/1122/sys/src/9/port/tcpinput.c:800,830 (short | long)
1991/0424    
Block * 
copyb(Block *bp, int count) 
{ 
	Block *nbp; 
1991/1122    
	Block *nbp, *head, *tail; 
1991/0424    
	int i; 
 
	nbp = allocb(count); 
	if(nbp == 0) 
		return 0; 
                 
1991/1122    
	head = 0; 
1991/0424    
	while(bp && count) { 
		i = MIN(count, BLEN(bp)); 
1991/1122    
		i = BLEN(bp); 
		nbp = allocb(i); 
		if(i > nbp->lim-nbp->wptr) { 
			if(head) 
				freeb(head); 
			return 0; 
		} 
1991/0424    
		memmove(nbp->wptr, bp->rptr, i); 
		nbp->wptr += i; 
		count -= i; 
1991/1122    
		if(head == 0) 
			head = nbp; 
		else 
			tail->next = nbp; 
 
		tail = nbp; 
1991/0424    
		bp = bp->next; 
	} 
 
	return nbp;	 
1991/1122    
	return head;	 
1991/0424    
} 
 
ushort tcp_mss = DEF_MSS;	/* Maximum segment size to be sent with SYN */ 
1991/1122/sys/src/9/port/tcpinput.c:744,7651991/1126/sys/src/9/port/tcpinput.c:744,749 (short | long)
1991/0424    
	return bytes; 
} 
 
void 
appendb(Block **list, Block *bp) 
{ 
	Block *f; 
                 
	if(f = *list) { 
		while(f->next) 
			f = f->next; 
		f->next = bp; 
	} 
	else 
		*list = bp; 
                 
	bp->next = 0; 
} 
                 
int 
dupb(Block **hp, Block *bp, int offset, int count) 
{ 
1991/1122/sys/src/9/port/tcpinput.c:803,8091991/1126/sys/src/9/port/tcpinput.c:787,793
1991/1122    
	Block *nbp, *head, *tail; 
1991/0424    
	int i; 
 
1991/1122    
	head = 0; 
1991/1126    
	head = tail = 0; 
1991/0424    
	while(bp && count) { 
1991/1122    
		i = BLEN(bp); 
		nbp = allocb(i); 
1991/1126/sys/src/9/port/tcpinput.c:75,811991/12171/sys/src/9/port/tcpinput.c:75,81 (short | long)
1991/0424    
 
1991/1102    
		e = &ipc[conf.ip]; 
		for(s = ipc; s < e; s++) { 
			if(s->tcpctl.state == LISTEN) 
1991/12171    
			if(s->tcpctl.state == Listen) 
1991/1102    
			if(s->pdst == 0) 
			if(s->dst == 0) { 
				if(s->curlog >= s->backlog) 
1991/1126/sys/src/9/port/tcpinput.c:114,1241991/12171/sys/src/9/port/tcpinput.c:114,124
1991/0424    
	qlock(tcb); 
 
	switch(tcb->state) { 
	case CLOSED: 
1991/12171    
	case Closed: 
1991/0424    
		freeb(bp); 
		reset(source, dest, tos, length, &seg); 
		goto done; 
	case LISTEN: 
1991/12171    
	case Listen: 
1991/0424    
		if(seg.flags & RST) { 
			freeb(bp); 
			goto done; 
1991/1126/sys/src/9/port/tcpinput.c:131,1371991/12171/sys/src/9/port/tcpinput.c:131,137
1991/0424    
		if(seg.flags & SYN) { 
			proc_syn(s, tos, &seg); 
			send_syn(tcb); 
			setstate(s, SYN_RECEIVED);		 
1991/12171    
			setstate(s, Syn_received);		 
1991/0424    
			if(length != 0 || (seg.flags & FIN))  
				break; 
			freeb(bp); 
1991/1126/sys/src/9/port/tcpinput.c:139,1451991/12171/sys/src/9/port/tcpinput.c:139,145
1991/0424    
		} 
		freeb(bp); 
		goto done; 
	case SYN_SENT: 
1991/12171    
	case Syn_sent: 
1991/0424    
		if(seg.flags & ACK) { 
			if(!seq_within(seg.ack, tcb->iss+1, tcb->snd.nxt)) { 
				freeb(bp); 
1991/1126/sys/src/9/port/tcpinput.c:163,1721991/12171/sys/src/9/port/tcpinput.c:163,172
1991/0424    
			proc_syn(s, tos, &seg); 
			if(seg.flags & ACK){ 
				update(s, &seg); 
				setstate(s, ESTABLISHED); 
1991/12171    
				setstate(s, Established); 
1991/0424    
			} 
			else  
				setstate(s, SYN_RECEIVED); 
1991/12171    
				setstate(s, Syn_received); 
1991/0424    
 
			if(length != 0 || (seg.flags & FIN)) 
				break; 
1991/1126/sys/src/9/port/tcpinput.c:205,2131991/12171/sys/src/9/port/tcpinput.c:205,213
1991/0424    
 
	for(;;) { 
		if(seg.flags & RST) { 
			if(tcb->state == SYN_RECEIVED 
1991/12171    
			if(tcb->state == Syn_received 
1991/0424    
			   && !(tcb->flags & (CLONE|ACTIVE)))  
				setstate(s, LISTEN); 
1991/12171    
				setstate(s, Listen); 
1991/0424    
			else 
				close_self(s, Econrefused); 
 
1991/1126/sys/src/9/port/tcpinput.c:227,2361991/12171/sys/src/9/port/tcpinput.c:227,236
1991/0424    
		} 
 
		switch(tcb->state) { 
		case SYN_RECEIVED: 
1991/12171    
		case Syn_received: 
1991/0424    
			if(seq_within(seg.ack, tcb->snd.una+1, tcb->snd.nxt)){ 
				update(s, &seg); 
				setstate(s, ESTABLISHED); 
1991/12171    
				setstate(s, Established); 
1991/0424    
			} 
			else { 
				freeb(bp); 
1991/1126/sys/src/9/port/tcpinput.c:238,2701991/12171/sys/src/9/port/tcpinput.c:238,270
1991/0424    
				goto done; 
			} 
			break; 
		case ESTABLISHED: 
		case CLOSE_WAIT: 
1991/12171    
		case Established: 
		case Close_wait: 
1991/0424    
			update(s, &seg); 
			break; 
		case FINWAIT1: 
1991/12171    
		case Finwait1: 
1991/0424    
			update(s, &seg); 
			if(tcb->sndcnt == 0) 
				setstate(s, FINWAIT2); 
1991/12171    
				setstate(s, Finwait2); 
1991/0424    
			break; 
		case FINWAIT2: 
1991/12171    
		case Finwait2: 
1991/0424    
			update(s, &seg); 
			break; 
		case CLOSING: 
1991/12171    
		case Closing: 
1991/0424    
			update(s, &seg); 
			if(tcb->sndcnt == 0){ 
				setstate(s, TIME_WAIT); 
1991/12171    
				setstate(s, Time_wait); 
1991/0424    
				tcb->timer.start = MSL2 * (1000 / MSPTICK); 
				start_timer(&tcb->timer); 
			} 
			break; 
		case LAST_ACK: 
1991/12171    
		case Last_ack: 
1991/0424    
			update(s, &seg); 
			if(tcb->sndcnt == 0) { 
				close_self(s, 0); 
				goto done; 
			}			 
		case TIME_WAIT: 
1991/12171    
		case Time_wait: 
1991/0424    
			tcb->flags |= FORCE; 
			start_timer(&tcb->timer); 
		} 
1991/1126/sys/src/9/port/tcpinput.c:280,2891991/12171/sys/src/9/port/tcpinput.c:280,289
1991/0424    
 
		if(length != 0){ 
			switch(tcb->state){ 
			case SYN_RECEIVED: 
			case ESTABLISHED: 
			case FINWAIT1: 
			case FINWAIT2: 
1991/12171    
			case Syn_received: 
			case Established: 
			case Finwait1: 
			case Finwait2: 
1991/0424    
				/* Place on receive queue */ 
				tcb->rcvcnt += blen(bp); 
				if(s->readq && bp) { 
1991/1126/sys/src/9/port/tcpinput.c:310,3411991/12171/sys/src/9/port/tcpinput.c:310,341
1991/0424    
			tcb->flags |= FORCE; 
 
			switch(tcb->state) { 
			case SYN_RECEIVED: 
			case ESTABLISHED: 
1991/12171    
			case Syn_received: 
			case Established: 
1991/0424    
				tcb->rcv.nxt++; 
				setstate(s, CLOSE_WAIT); 
1991/12171    
				setstate(s, Close_wait); 
1991/0424    
				break; 
			case FINWAIT1: 
1991/12171    
			case Finwait1: 
1991/0424    
				tcb->rcv.nxt++; 
				if(tcb->sndcnt == 0) { 
					setstate(s, TIME_WAIT); 
1991/12171    
					setstate(s, Time_wait); 
1991/0424    
					tcb->timer.start = MSL2 * (1000/MSPTICK); 
					start_timer(&tcb->timer); 
				} 
				else  
					setstate(s, CLOSING); 
1991/12171    
					setstate(s, Closing); 
1991/0424    
				break; 
			case FINWAIT2: 
1991/12171    
			case Finwait2: 
1991/0424    
				tcb->rcv.nxt++; 
				setstate(s, TIME_WAIT); 
1991/12171    
				setstate(s, Time_wait); 
1991/0424    
				tcb->timer.start = MSL2 * (1000/MSPTICK); 
				start_timer(&tcb->timer); 
				break; 
			case CLOSE_WAIT: 
			case CLOSING: 
			case LAST_ACK: 
1991/12171    
			case Close_wait: 
			case Closing: 
			case Last_ack: 
1991/0424    
				break; 
			case TIME_WAIT: 
1991/12171    
			case Time_wait: 
1991/0424    
				start_timer(&tcb->timer); 
				break; 
			} 
1991/1126/sys/src/9/port/tcpinput.c:374,3861991/12171/sys/src/9/port/tcpinput.c:374,386
1991/0424    
	case ICMP_UNREACH: 
		tcb->type = type; 
		tcb->code = code; 
		if(tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED) 
1991/12171    
		if(tcb->state == Syn_sent || tcb->state == Syn_received) 
1991/0424    
			close_self(s, Enetunreach); 
		break; 
	case ICMP_TIMXCEED: 
		tcb->type = type; 
		tcb->code = code; 
		if(tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED) 
1991/12171    
		if(tcb->state == Syn_sent || tcb->state == Syn_received) 
1991/0424    
			close_self(s, Etimedout); 
		break; 
	case ICMP_SOURCEQUENCH: 
1991/1126/sys/src/9/port/tcpinput.c:492,4981991/12171/sys/src/9/port/tcpinput.c:492,498
1991/0424    
			rtt = tcb->rtt_timer.start - tcb->rtt_timer.count; 
			rtt *= MSPTICK;	 
			if(rtt > tcb->srtt && 
			  (tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED)) 
1991/12171    
			  (tcb->state == Syn_sent || tcb->state == Syn_received)) 
1991/0424    
				tcb->srtt = rtt; 
			else { 
				abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt; 
1991/1126/sys/src/9/port/tcpinput.c:861,8671991/12171/sys/src/9/port/tcpinput.c:861,867
1991/0424    
 
	tcb->reseq = 0; 
	s->err = reason; 
	setstate(s, CLOSED); 
1991/12171    
	setstate(s, Closed); 
1991/0424    
} 
 
int 
1991/12171/sys/src/9/port/tcpinput.c:784,8141992/0105/sys/src/9/port/tcpinput.c:784,820 (short | long)
1991/0424    
Block * 
copyb(Block *bp, int count) 
{ 
1991/1122    
	Block *nbp, *head, *tail; 
1991/0424    
	int i; 
1992/0105    
	Block *nb, *head, **p; 
	int l; 
1991/0424    
 
1991/1126    
	head = tail = 0; 
1991/0424    
	while(bp && count) { 
1991/1122    
		i = BLEN(bp); 
		nbp = allocb(i); 
		if(i > nbp->lim-nbp->wptr) { 
			if(head) 
				freeb(head); 
			return 0; 
		} 
1991/0424    
		memmove(nbp->wptr, bp->rptr, i); 
		nbp->wptr += i; 
		count -= i; 
1991/1122    
		if(head == 0) 
			head = nbp; 
		else 
			tail->next = nbp; 
                 
		tail = nbp; 
1992/0105    
	p = &head; 
	while(count) { 
		l = BLEN(bp); 
		if(count < l) 
			l = count; 
		nb = allocb(l); 
		if(nb == 0) 
			panic("copyb.1"); 
		memmove(nb->wptr, bp->rptr, l); 
		nb->wptr += l; 
		count -= l; 
		*p = nb; 
		p = &nb->next; 
1991/0424    
		bp = bp->next; 
1992/0105    
		if(bp == 0) 
			break; 
1991/0424    
	} 
                 
1991/1122    
	return head;	 
1992/0105    
	if(count) { 
		nb = allocb(count); 
		if(nb == 0) 
			panic("copyb.2"); 
		memset(nb->wptr, 0, count); 
		nb->wptr += count; 
		*p = nb; 
	} 
	if(blen(head) == 0) 
		print("copyb: zero length\n"); 
	return head; 
1991/0424    
} 
 
ushort tcp_mss = DEF_MSS;	/* Maximum segment size to be sent with SYN */ 
1992/0105/sys/src/9/port/tcpinput.c:798,8031992/0106/sys/src/9/port/tcpinput.c:798,805 (short | long)
1992/0105    
		memmove(nb->wptr, bp->rptr, l); 
		nb->wptr += l; 
		count -= l; 
1992/0106    
		if(bp->flags & S_DELIM) 
			nb->flags |= S_DELIM; 
1992/0105    
		*p = nb; 
		p = &nb->next; 
1991/0424    
		bp = bp->next; 
1992/0105/sys/src/9/port/tcpinput.c:810,8191992/0106/sys/src/9/port/tcpinput.c:812,823
1992/0105    
			panic("copyb.2"); 
		memset(nb->wptr, 0, count); 
		nb->wptr += count; 
1992/0106    
		nb->flags |= S_DELIM; 
1992/0105    
		*p = nb; 
	} 
	if(blen(head) == 0) 
		print("copyb: zero length\n"); 
1992/0106    
 
1992/0105    
	return head; 
1991/0424    
} 
 
1992/0105/sys/src/9/port/tcpinput.c:964,9691992/0106/sys/src/9/port/tcpinput.c:968,975
1991/0424    
	 
	h = (Tcphdr *)(data->rptr); 
	h->proto = IP_TCPPROTO; 
1992/0106    
	h->frag[0] = 0; 
	h->frag[1] = 0; 
1991/0424    
	hnputs(h->tcplen, hdrlen + dlen); 
	hnputs(h->tcpsport, tcph->source); 
	hnputs(h->tcpdport, tcph->dest); 
1992/0106/sys/src/9/port/tcpinput.c:3,91992/0111/sys/src/9/port/tcpinput.c:3,9 (short | long)
Move error.h to ../port. Change errors to actual strings.
rsc Fri Mar 4 12:44:25 2005
1991/0424    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"errno.h" 
1992/0111    
#include	"../port/error.h" 
1991/0424    
#include 	"arp.h" 
#include 	"ipdat.h" 
 
1992/0106/sys/src/9/port/tcpinput.c:261,2671992/0111/sys/src/9/port/tcpinput.c:261,267
1991/12171    
		case Last_ack: 
1991/0424    
			update(s, &seg); 
			if(tcb->sndcnt == 0) { 
				close_self(s, 0); 
1992/0111    
				close_self(s, Enoerror); 
1991/0424    
				goto done; 
			}			 
1991/12171    
		case Time_wait: 
1992/0106/sys/src/9/port/tcpinput.c:849,8551992/0111/sys/src/9/port/tcpinput.c:849,855
1991/0424    
} 
 
void 
close_self(Ipconv *s, int reason) 
1992/0111    
close_self(Ipconv *s, char reason[]) 
1991/0424    
{ 
	Reseq *rp,*rp1; 
	Tcpctl *tcb = &s->tcpctl; 
1992/0111/sys/src/9/port/tcpinput.c:824,8291992/0128/sys/src/9/port/tcpinput.c:824,835 (short | long)
1991/0424    
ushort tcp_mss = DEF_MSS;	/* Maximum segment size to be sent with SYN */ 
int tcp_irtt = DEF_RTT;		/* Initial guess at round trip time */ 
 
1992/0128    
static void 
cleartcp(struct Tctl *a) 
{ 
	memset(a, 0, sizeof(struct Tctl)); 
} 
 
1991/0424    
void 
init_tcpctl(Ipconv *s) 
{ 
1992/0111/sys/src/9/port/tcpinput.c:830,8361992/0128/sys/src/9/port/tcpinput.c:836,842
1991/0424    
 
	Tcpctl *tcb = &s->tcpctl; 
 
	memset(tcb, 0, sizeof(Tcpctl)); 
1992/0128    
	cleartcp(tcb); 
1991/0424    
 
	tcb->cwind = tcb->mss = tcp_mss; 
	tcb->ssthresh = 65535; 
1992/0128/sys/src/9/port/tcpinput.c:85,911992/0306/sys/src/9/port/tcpinput.c:85,93 (short | long)
1991/1102    
				if(new == 0) 
					goto clear; 
1991/0424    
 
1992/0306    
				qlock(s); 
1991/1102    
				s->curlog++; 
1992/0306    
				qunlock(s); 
1991/1102    
				new->psrc = seg.dest; 
				new->pdst = seg.source; 
				new->dst = source; 
1992/0306/sys/src/9/port/tcpinput.c:199,2051992/0310/sys/src/9/port/tcpinput.c:199,206 (short | long)
1991/0424    
		goto done; 
	} 
 
1991/1104    
	if(seg.seq != tcb->rcv.nxt && (length != 0 || (seg.flags & (SYN|FIN)) )) { 
1992/0310    
	if(seg.seq != tcb->rcv.nxt) 
	if(length != 0 || (seg.flags & (SYN|FIN))) { 
1991/0424    
		add_reseq(tcb, tos, &seg, bp, length); 
		tcb->flags |= FORCE; 
		goto output; 
1992/0306/sys/src/9/port/tcpinput.c:254,2601992/0310/sys/src/9/port/tcpinput.c:255,261
1991/0424    
			break; 
1991/12171    
		case Closing: 
1991/0424    
			update(s, &seg); 
			if(tcb->sndcnt == 0){ 
1992/0310    
			if(tcb->sndcnt == 0) { 
1991/12171    
				setstate(s, Time_wait); 
1991/0424    
				tcb->timer.start = MSL2 * (1000 / MSPTICK); 
				start_timer(&tcb->timer); 
1992/0306/sys/src/9/port/tcpinput.c:271,2871992/0310/sys/src/9/port/tcpinput.c:272,292
1991/0424    
			start_timer(&tcb->timer); 
		} 
 
		if ((seg.flags&URG) && seg.up) { 
			if (seq_gt(seg.up + seg.seq, tcb->rcv.up)) { 
1992/0310    
		if((seg.flags&URG) && seg.up) { 
			if(seq_gt(seg.up + seg.seq, tcb->rcv.up)) { 
1991/0424    
				tcb->rcv.up = seg.up + seg.seq; 
1991/1030    
				copyupb(&bp, 0, seg.up); 
1991/0424    
			} 
		}  
		else if (seq_gt(tcb->rcv.nxt, tcb->rcv.up)) 
1992/0310    
		else if(seq_gt(tcb->rcv.nxt, tcb->rcv.up)) 
1991/0424    
			tcb->rcv.up = tcb->rcv.nxt; 
 
		if(length != 0){ 
1992/0310    
		if(length != 0) { 
1991/0424    
			switch(tcb->state){ 
1992/0310    
			default: 
				/* Ignore segment text */ 
				freeb(bp); 
				break; 
1991/12171    
			case Syn_received: 
			case Established: 
			case Finwait1: 
1992/0306/sys/src/9/port/tcpinput.c:298,3101992/0310/sys/src/9/port/tcpinput.c:303,311
1991/0424    
	 
				start_timer(&tcb->acktimer); 
 
				if (tcb->max_snd <= tcb->rcv.nxt-tcb->last_ack) 
1992/0310    
				if(tcb->max_snd <= tcb->rcv.nxt-tcb->last_ack) 
1991/0424    
					tcb->flags |= FORCE; 
				break; 
			default: 
				/* Ignore segment text */ 
				freeb(bp); 
				break; 
			} 
		} 
 
1992/0306/sys/src/9/port/tcpinput.c:414,4311992/0310/sys/src/9/port/tcpinput.c:415,427
1991/0424    
	seg->source = tmp; 
 
	rflags = RST; 
1992/0310    
 
	/* convince the other end that this reset is in band */ 
1991/0424    
	if(seg->flags & ACK) { 
		/* This reset is being sent to clear a half-open connection. 
		 * Set the sequence number of the RST to the incoming ACK 
		 * so it will be acceptable. 
		 */ 
		seg->seq = seg->ack; 
		seg->ack = 0; 
	} 
	else { 
		/* We're rejecting a connect request (SYN) from LISTEN state 
		 * so we have to "acknowledge" their SYN. 
		 */ 
		rflags |= ACK; 
		seg->ack = seg->seq; 
		seg->seq = 0; 
1992/0306/sys/src/9/port/tcpinput.c:532,5411992/0310/sys/src/9/port/tcpinput.c:528,534
1991/0424    
	if(seq_lt(tcb->snd.ptr, tcb->snd.una)) 
		tcb->snd.ptr = tcb->snd.una; 
 
	/* Clear the retransmission flag since the oldest 
	 * unacknowledged segment (the only one that is ever retransmitted) 
	 * has now been acked. 
	 */ 
1992/0310    
	/* All data is acked now */ 
1991/0424    
	tcb->flags &= ~RETRAN; 
	tcb->backoff = 0; 
} 
1992/0306/sys/src/9/port/tcpinput.c:558,5641992/0310/sys/src/9/port/tcpinput.c:551,557
1991/0424    
	if(PREC(tos) > PREC(tcb->tos)) 
		tcb->tos = tos; 
 
	tcb->rcv.up = tcb->rcv.nxt = seg->seq + 1;	/* p 68 */ 
1992/0310    
	tcb->rcv.up = tcb->rcv.nxt = seg->seq + 1; 
1991/0424    
	tcb->snd.wl1 = tcb->irs = seg->seq; 
	tcb->snd.wnd = seg->wnd; 
 
1992/0306/sys/src/9/port/tcpinput.c:648,6551992/0310/sys/src/9/port/tcpinput.c:641,649
1991/0424    
trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length) 
{ 
	Block *nbp; 
	long dupcnt,excess; 
	ushort len;		/* Segment length including flags */ 
1992/0310    
	long dupcnt; 
	long excess; 
	ushort len; 
1991/0424    
	char accept; 
 
	accept = 0; 
1992/0306/sys/src/9/port/tcpinput.c:659,6651992/0310/sys/src/9/port/tcpinput.c:653,658
1991/0424    
	if(seg->flags & FIN) 
		len++; 
 
	/* Acceptability tests */ 
	if(tcb->rcv.wnd == 0) { 
		if(seg->seq == tcb->rcv.nxt && len == 0) 
			return 0; 
1992/0310/sys/src/9/port/tcpinput.c:156,1661992/0313/sys/src/9/port/tcpinput.c:156,168 (short | long)
1991/0424    
			goto done; 
		} 
 
		if((seg.flags & ACK) && PREC(tos) != PREC(tcb->tos)){ 
1992/0313    
		if(seg.flags & ACK) 
		if(PREC(tos) != PREC(tcb->tos)){ 
1991/0424    
			freeb(bp); 
			reset(source, dest, tos, length, &seg); 
			goto done; 
		} 
1992/0313    
 
1991/0424    
		if(seg.flags & SYN) { 
			proc_syn(s, tos, &seg); 
			if(seg.flags & ACK){ 
1992/0310/sys/src/9/port/tcpinput.c:193,1991992/0313/sys/src/9/port/tcpinput.c:195,202
1991/0424    
	/* If we have no opens and the other end is sending data then 
	 * reply with a reset 
	 */ 
	if(s->readq == 0 && length) { 
1992/0313    
	if(length) 
	if(s->readq == 0) { 
1991/0424    
		freeb(bp); 
		reset(source, dest, tos, length, &seg); 
		goto done; 
1992/0310/sys/src/9/port/tcpinput.c:293,2991992/0313/sys/src/9/port/tcpinput.c:296,303
1991/12171    
			case Finwait2: 
1991/0424    
				/* Place on receive queue */ 
				tcb->rcvcnt += blen(bp); 
				if(s->readq && bp) { 
1992/0313    
				if(bp) 
				if(s->readq) { 
1991/0424    
					PUTNEXT(s->readq, bp); 
					bp = 0; 
				} 
1992/0310/sys/src/9/port/tcpinput.c:358,3991992/0313/sys/src/9/port/tcpinput.c:362,367
1991/0424    
} 
 
void 
tcp_icmp(Ipconv *ipc, Ipaddr source, Ipaddr dest, char type, char code, Block **bpp) 
{ 
	Tcp seg; 
	Tcpctl *tcb; 
	Ipconv *s; 
                 
	ntohtcp(&seg, bpp); 
	if(!(s = ip_conn(ipc, seg.source, seg.dest, dest, IP_TCPPROTO))) 
		return; 
                 
	tcb = &s->tcpctl; 
                 
	if(!seq_within(seg.seq, tcb->snd.una, tcb->snd.nxt)) 
		return; 
                 
	switch((uchar)type) { 
	case ICMP_UNREACH: 
		tcb->type = type; 
		tcb->code = code; 
1991/12171    
		if(tcb->state == Syn_sent || tcb->state == Syn_received) 
1991/0424    
			close_self(s, Enetunreach); 
		break; 
	case ICMP_TIMXCEED: 
		tcb->type = type; 
		tcb->code = code; 
1991/12171    
		if(tcb->state == Syn_sent || tcb->state == Syn_received) 
1991/0424    
			close_self(s, Etimedout); 
		break; 
	case ICMP_SOURCEQUENCH: 
1991/0926    
		tcb->cwind = tcb->cwind/2; 
1991/0424    
		tcb->cwind = MAX(tcb->mss,tcb->cwind); 
		break; 
	} 
} 
                 
void 
reset(Ipaddr source, Ipaddr dest, char tos, ushort length, Tcp *seg) 
{ 
	Block *hbp; 
1992/0310/sys/src/9/port/tcpinput.c:455,4641992/0313/sys/src/9/port/tcpinput.c:423,434
1991/0424    
		return; 
	} 
 
	if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1)  
	 && seq_ge(seg->ack,tcb->snd.wl2))) { 
		if(tcb->snd.wnd == 0 && seg->wnd != 0) 
1992/0313    
	if(seq_ge(seg->ack,tcb->snd.wl2)) 
	if(seq_gt(seg->seq,tcb->snd.wl1) || (seg->seq == tcb->snd.wl1)) { 
		if(seg->wnd != 0) 
		if(tcb->snd.wnd == 0) 
1991/0424    
			tcb->snd.ptr = tcb->snd.una; 
1992/0313    
 
1991/0424    
		tcb->snd.wnd = seg->wnd; 
		tcb->snd.wl1 = seg->seq; 
		tcb->snd.wl2 = seg->ack; 
1992/0310/sys/src/9/port/tcpinput.c:483,4921992/0313/sys/src/9/port/tcpinput.c:453,463
1991/0424    
	} 
 
	/* Round trip time estimation */ 
	if(run_timer(&tcb->rtt_timer) && seq_ge(seg->ack, tcb->rttseq)) { 
1992/0313    
	if(run_timer(&tcb->rtt_timer)) 
	if(seq_ge(seg->ack, tcb->rttseq)) { 
1991/0424    
		stop_timer(&tcb->rtt_timer); 
		if(!(tcb->flags & RETRAN)) { 
 
1992/0313    
		if(!(tcb->flags & RETRAN)) { 
1991/0424    
			rtt = tcb->rtt_timer.start - tcb->rtt_timer.count; 
			rtt *= MSPTICK;	 
			if(rtt > tcb->srtt && 
1992/0310/sys/src/9/port/tcpinput.c:654,6601992/0313/sys/src/9/port/tcpinput.c:625,632
1991/0424    
		len++; 
 
	if(tcb->rcv.wnd == 0) { 
		if(seg->seq == tcb->rcv.nxt && len == 0) 
1992/0313    
		if(len == 0) 
		if(seg->seq == tcb->rcv.nxt) 
1991/0424    
			return 0; 
1991/1030    
	} 
	else { 
1992/0313/sys/src/9/port/tcpinput.c:748,7931992/0318/sys/src/9/port/tcpinput.c:748,753 (short | long)
1991/0424    
	return bytes; 
} 
 
Block * 
copyb(Block *bp, int count) 
{ 
1992/0105    
	Block *nb, *head, **p; 
	int l; 
1991/0424    
                 
1992/0105    
	p = &head; 
	while(count) { 
		l = BLEN(bp); 
		if(count < l) 
			l = count; 
		nb = allocb(l); 
		if(nb == 0) 
			panic("copyb.1"); 
		memmove(nb->wptr, bp->rptr, l); 
		nb->wptr += l; 
		count -= l; 
1992/0106    
		if(bp->flags & S_DELIM) 
			nb->flags |= S_DELIM; 
1992/0105    
		*p = nb; 
		p = &nb->next; 
1991/0424    
		bp = bp->next; 
1992/0105    
		if(bp == 0) 
			break; 
1991/0424    
	} 
1992/0105    
	if(count) { 
		nb = allocb(count); 
		if(nb == 0) 
			panic("copyb.2"); 
		memset(nb->wptr, 0, count); 
		nb->wptr += count; 
1992/0106    
		nb->flags |= S_DELIM; 
1992/0105    
		*p = nb; 
	} 
	if(blen(head) == 0) 
		print("copyb: zero length\n"); 
1992/0106    
                 
1992/0105    
	return head; 
1991/0424    
} 
                 
ushort tcp_mss = DEF_MSS;	/* Maximum segment size to be sent with SYN */ 
int tcp_irtt = DEF_RTT;		/* Initial guess at round trip time */ 
 
1992/0318/sys/src/9/port/tcpinput.c:42,471992/0319/sys/src/9/port/tcpinput.c:42,48 (short | long)
1991/0424    
	Ipaddr source, dest; 
	char tos; 
	ushort length; 
1992/0319    
	Block *f; 
1991/0424    
 
	DPRINT("tcp_input.\n"); 
 
1992/0318/sys/src/9/port/tcpinput.c:290,2951992/0319/sys/src/9/port/tcpinput.c:291,297
1992/0310    
				/* Ignore segment text */ 
				freeb(bp); 
				break; 
1992/0319    
 
1991/12171    
			case Syn_received: 
			case Established: 
			case Finwait1: 
1992/0318/sys/src/9/port/tcpinput.c:298,3031992/0319/sys/src/9/port/tcpinput.c:300,312
1991/0424    
				tcb->rcvcnt += blen(bp); 
1992/0313    
				if(bp) 
				if(s->readq) { 
1992/0319    
					print("bl %d ty %d\n", blen(bp), bp->rptr[0]); 
					for(f = bp; bp->next; f = f->next) 
						; 
					if((f->flags&S_DELIM) == 0) { 
						print("No delim upstream rcp"); 
						f->flags |= S_DELIM; 
					}		 
1991/0424    
					PUTNEXT(s->readq, bp); 
					bp = 0; 
				} 
1992/0318/sys/src/9/port/tcpinput.c:347,3531992/0319/sys/src/9/port/tcpinput.c:356,364
1991/0424    
				break; 
			} 
		} 
1991/1104    
		while(tcb->reseq != 0 && seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq)) { 
1992/0319    
		while(tcb->reseq != 0) { 
			if(seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq) == 0) 
				break; 
1991/0424    
			get_reseq(tcb, &tos, &seg, &bp, &length); 
			if(trim(tcb, &seg, &bp, &length) == 0) 
				goto gotone; 
1992/0318/sys/src/9/port/tcpinput.c:880,8861992/0319/sys/src/9/port/tcpinput.c:891,898
1991/0424    
 
	if(data) { 
		dlen = blen(data);	 
		if((data = padb(data, hdrlen + TCP_PKT)) == 0) 
1992/0319    
		data = padb(data, hdrlen + TCP_PKT); 
		if(data == 0) 
1991/0424    
			return 0; 
		/* If we collected blocks delimit the end of the chain */ 
		for(bp = data; bp->next; bp = bp->next) 
1992/0318/sys/src/9/port/tcpinput.c:976,9791992/0319/sys/src/9/port/tcpinput.c:988,1027
1991/0424    
		} 
	} 
	return hdrlen; 
1992/0319    
} 
 
void 
tcpdumpconv(Ipconv *c) 
{ 
	if(c->tcpctl.state == Closed) 
		return; 
 
	print("%s %d -> %d.%d.%d.%d/%d snd %d recv %d una %d nxt %d ptr %d wnd %d\n", 
	tcpstate[c->tcpctl.state], 
	c->psrc, 
	fmtaddr(c->dst), 
	c->pdst, 
	c->tcpctl.sndcnt, 
	c->tcpctl.rcvcnt, 
	c->tcpctl.snd.una, 
	c->tcpctl.snd.nxt, 
	c->tcpctl.snd.ptr, 
	c->tcpctl.snd.wnd); 
} 
 
void 
tcpdump(void) 
{ 
	Ipifc *ep, *ifp; 
	Ipconv *cp, *ecp; 
	extern Ipifc *ipifc; 
 
	ep = &ipifc[conf.ipif]; 
	for(ifp = ipifc; ifp < ep; ifp++) 
		if(strcmp(ifp->name, "TCP") == 0) { 
			ecp = &ifp->connections[conf.ip]; 
			for(cp = ifp->connections; cp < ecp; cp++) 
				tcpdumpconv(cp); 
			break; 
		} 
1991/0424    
} 
1992/0319/sys/src/9/port/tcpinput.c:42,511992/0320/sys/src/9/port/tcpinput.c:42,48 (short | long)
1991/0424    
	Ipaddr source, dest; 
	char tos; 
	ushort length; 
1992/0319    
	Block *f; 
1991/0424    
 
	DPRINT("tcp_input.\n"); 
                 
	h = (Tcphdr *)(bp->rptr); 
	dest = nhgetl(h->tcpdst); 
	source = nhgetl(h->tcpsrc); 
1992/0319/sys/src/9/port/tcpinput.c:300,3121992/0320/sys/src/9/port/tcpinput.c:297,302
1991/0424    
				tcb->rcvcnt += blen(bp); 
1992/0313    
				if(bp) 
				if(s->readq) { 
1992/0319    
					print("bl %d ty %d\n", blen(bp), bp->rptr[0]); 
					for(f = bp; bp->next; f = f->next) 
						; 
					if((f->flags&S_DELIM) == 0) { 
						print("No delim upstream rcp"); 
						f->flags |= S_DELIM; 
					}		 
1991/0424    
					PUTNEXT(s->readq, bp); 
					bp = 0; 
				} 
1992/0319/sys/src/9/port/tcpinput.c:467,4741992/0320/sys/src/9/port/tcpinput.c:457,463
1992/0313    
	if(run_timer(&tcb->rtt_timer)) 
	if(seq_ge(seg->ack, tcb->rttseq)) { 
1991/0424    
		stop_timer(&tcb->rtt_timer); 
                 
1992/0313    
		if(!(tcb->flags & RETRAN)) { 
1992/0320    
		if((tcb->flags&RETRAN) == 0) { 
1991/0424    
			rtt = tcb->rtt_timer.start - tcb->rtt_timer.count; 
			rtt *= MSPTICK;	 
			if(rtt > tcb->srtt && 
1992/0319/sys/src/9/port/tcpinput.c:475,4871992/0320/sys/src/9/port/tcpinput.c:464,478
1991/12171    
			  (tcb->state == Syn_sent || tcb->state == Syn_received)) 
1991/0424    
				tcb->srtt = rtt; 
			else { 
				abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt; 
1992/0320    
				if(rtt > tcb->srtt) 
					abserr = rtt - tcb->srtt; 
				else 
					abserr = tcb->srtt - rtt; 
1991/0424    
				tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt) / AGAIN; 
				tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr) / DGAIN; 
				DPRINT("tcpout: rtt %d, srtt %d, mdev %d\n",  
					rtt, tcb->srtt, tcb->mdev); 
			} 
                 
			tcb->backoff = 0; 
		} 
	} 
1992/0319/sys/src/9/port/tcpinput.c:988,10271992/0320/sys/src/9/port/tcpinput.c:979,982
1991/0424    
		} 
	} 
	return hdrlen; 
1992/0319    
} 
                 
void 
tcpdumpconv(Ipconv *c) 
{ 
	if(c->tcpctl.state == Closed) 
		return; 
                 
	print("%s %d -> %d.%d.%d.%d/%d snd %d recv %d una %d nxt %d ptr %d wnd %d\n", 
	tcpstate[c->tcpctl.state], 
	c->psrc, 
	fmtaddr(c->dst), 
	c->pdst, 
	c->tcpctl.sndcnt, 
	c->tcpctl.rcvcnt, 
	c->tcpctl.snd.una, 
	c->tcpctl.snd.nxt, 
	c->tcpctl.snd.ptr, 
	c->tcpctl.snd.wnd); 
} 
                 
void 
tcpdump(void) 
{ 
	Ipifc *ep, *ifp; 
	Ipconv *cp, *ecp; 
	extern Ipifc *ipifc; 
                 
	ep = &ipifc[conf.ipif]; 
	for(ifp = ipifc; ifp < ep; ifp++) 
		if(strcmp(ifp->name, "TCP") == 0) { 
			ecp = &ifp->connections[conf.ip]; 
			for(cp = ifp->connections; cp < ecp; cp++) 
				tcpdumpconv(cp); 
			break; 
		} 
1991/0424    
} 
1992/0320/sys/src/9/port/tcpinput.c:1,51992/0321/sys/src/9/port/tcpinput.c:1,5 (short | long)
Move lib.h to ../port.
rsc Fri Mar 4 12:44:25 2005
1991/0424    
#include	"u.h" 
#include	"lib.h" 
1992/0321    
#include	"../port/lib.h" 
1991/0424    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)