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

1998/1118/ip/tcp.c (diff list | history)

1998/1008/sys/src/9/ip/tcp.c:38,431998/1118/sys/src/9/ip/tcp.c:38,44 (short | long | prev | next)
1997/0327    
	MSPTICK		= 50,		/* Milliseconds per timer tick */ 
	DEF_MSS		= 1024,		/* Default mean segment */ 
1998/0630    
	DEF_RTT		= 150,		/* Default round trip */ 
1998/1118    
	DEF_KAT		= 10000,	/* Default keep alive trip in ms */ 
1997/0327    
	TCP_LISTEN	= 0,		/* Listen connection */ 
	TCP_CONNECT	= 1,		/* Outgoing connection */ 
 
1998/1008/sys/src/9/ip/tcp.c:171,1811998/1118/sys/src/9/ip/tcp.c:172,182
1997/0327    
	Timer	timer;			/* Activity timer */ 
	Timer	acktimer;		/* Acknowledge timer */ 
	Timer	rtt_timer;		/* Round trip timer */ 
1998/1118    
	Timer	katimer;		/* keep alive timer */ 
1997/0327    
	ulong	rttseq;			/* Round trip sequence */ 
	int	srtt;			/* Shortened round trip */ 
	int	mdev;			/* Mean deviation of round trip */ 
	int	kacounter;		/* count down for keep alive */ 
	int	f2counter;		/* count down for finwait2 state */ 
	uint	sndsyntime;		/* time syn sent */ 
1998/0306    
 
	Tcphdr	protohdr;		/* prototype header */ 
1998/1008/sys/src/9/ip/tcp.c:237,2421998/1118/sys/src/9/ip/tcp.c:238,244
1997/0327    
void	tcpsndsyn(Tcpctl*); 
void	tcprcvwin(Conv*); 
void	tcpacktimer(Conv*); 
1998/1118    
void	tcpkeepalive(Conv*); 
1997/0327    
 
void 
1998/0306    
tcpsetstate(Conv *s, uchar newstate) 
1998/1008/sys/src/9/ip/tcp.c:554,5591998/1118/sys/src/9/ip/tcp.c:556,562
1998/0313    
	tcphalt(tpriv, &tcb->timer); 
	tcphalt(tpriv, &tcb->rtt_timer); 
1998/0925    
	tcphalt(tpriv, &tcb->acktimer); 
1998/1118    
	tcphalt(tpriv, &tcb->katimer); 
1997/0327    
 
	/* Flush reassembly queue; nothing more can arrive */ 
	for(rp = tcb->reseq; rp != nil; rp = rp1) { 
1998/1008/sys/src/9/ip/tcp.c:594,5991998/1118/sys/src/9/ip/tcp.c:597,606
1997/0327    
	tcb->acktimer.start = TCP_ACK / MSPTICK; 
	tcb->acktimer.func = tcpacktimer; 
	tcb->acktimer.arg = s; 
1998/1118    
	tcb->kacounter = 0; 
	tcb->katimer.start = DEF_KAT / MSPTICK; 
	tcb->katimer.func = tcpkeepalive; 
	tcb->katimer.arg = s; 
1998/0306    
 
	/* create a prototype(pseudo) header */ 
	if(ipcmp(s->laddr, IPnoaddr) == 0) 
1998/1008/sys/src/9/ip/tcp.c:1007,10141998/1118/sys/src/9/ip/tcp.c:1014,1019
1998/0313    
	tpriv = s->p->priv; 
1997/0327    
	tcb = (Tcpctl*)s->ptcl; 
 
	tcb->kacounter = MAXBACKOFF;	/* keep alive count down */ 
                 
	if(seq_gt(seg->ack, tcb->snd.nxt)) { 
		tcb->flags |= FORCE; 
		return; 
1998/1008/sys/src/9/ip/tcp.c:1224,12291998/1118/sys/src/9/ip/tcp.c:1229,1237
1997/0327    
	tcb = (Tcpctl*)s->ptcl; 
	qlock(tcb); 
 
1998/1118    
	if(tcb->kacounter > 0) 
		tcb->kacounter = MAXBACKOFF; 
 
1997/0327    
	switch(tcb->state) { 
	case Closed: 
1998/0313    
		sndrst(tcp, source, dest, length, &seg); 
1998/1008/sys/src/9/ip/tcp.c:1343,13511998/1118/sys/src/9/ip/tcp.c:1351,1359
1997/0327    
		case Finwait1: 
			update(s, &seg); 
			if(tcb->sndcnt == 0){ 
				tcb->f2counter = MAXBACKOFF; 
1998/1118    
				tcb->kacounter = MAXBACKOFF; 
1997/0327    
				tcpsetstate(s, Finwait2); 
				tcb->timer.start = MSL2 * (1000 / MSPTICK); 
1998/1118    
				tcb->katimer.start = MSL2 * (1000 / MSPTICK); 
1998/0313    
				tcpgo(tpriv, &tcb->timer); 
1997/0327    
			} 
			break; 
1998/1008/sys/src/9/ip/tcp.c:1686,16911998/1118/sys/src/9/ip/tcp.c:1694,1701
1997/0327    
		} 
 
1998/0313    
		tpriv->tstats.tcpOutSegs++; 
1998/1118    
		if(tcb->kacounter > 0) 
			tcpgo(tpriv, &tcb->katimer); 
1998/0313    
		ipoput(f, hbp, 0, s->ttl); 
1997/0327    
	} 
} 
1998/1008/sys/src/9/ip/tcp.c:1694,17001998/1118/sys/src/9/ip/tcp.c:1704,1710
1998/0306    
 *  the BSD convention (hack?) for keep alives.  resend last uchar acked. 
1997/0327    
 */ 
void 
tcpkeepalive(Conv *s) 
1998/1118    
tcpsendka(Conv *s) 
1997/0327    
{ 
	Tcp seg; 
	Tcpctl *tcb; 
1998/1008/sys/src/9/ip/tcp.c:1730,17361998/1118/sys/src/9/ip/tcp.c:1740,1787
1998/0313    
	ipoput(s->p->f, hbp, 0, s->ttl); 
1997/0327    
} 
 
1998/1118    
/* 
 *  if we've timed out, close the connection 
 *  otherwise, send a keepalive and restart the timer 
 */ 
1997/0327    
void 
1998/1118    
tcpkeepalive(Conv *s) 
{ 
	Tcpctl *tcb; 
 
	tcb = (Tcpctl*)s->ptcl; 
	if(--(tcb->kacounter) <= 0) 
		localclose(s, Etimedout); 
	else { 
		qlock(tcb); 
		tcpsendka(s); 
		qunlock(tcb); 
		tcpgo(s->p->priv, &tcb->katimer); 
	} 
} 
 
/* 
 *  start keepalive timer 
 */ 
char* 
tcpstartka(Conv *s, char **f, int n) 
{ 
	Tcpctl *tcb; 
	int x; 
 
	tcb = (Tcpctl*)s->ptcl; 
	if(n > 1){ 
		x = atoi(f[1]); 
		if(x >= MSPTICK) 
			tcb->katimer.start = x/MSPTICK; 
	} 
	tcb->kacounter = MAXBACKOFF; 
	tcpgo(s->p->priv, &tcb->katimer); 
 
	return nil; 
} 
 
void 
1997/0327    
tcprxmit(Conv *s) 
{ 
	Tcpctl *tcb; 
1998/1008/sys/src/9/ip/tcp.c:1782,17971998/1118/sys/src/9/ip/tcp.c:1833,1838
1997/0327    
		} 
		tcprxmit(s); 
		break; 
	case Finwait2: 
		if(--(tcb->f2counter) <= 0) 
			localclose(s, Etimedout); 
		else { 
			qlock(tcb); 
			tcpkeepalive(s); 
			qunlock(tcb); 
1998/0313    
			tcpgo(s->p->priv, &tcb->timer); 
1997/0327    
		} 
		break; 
	case Time_wait: 
		localclose(s, nil); 
		break; 
1998/1008/sys/src/9/ip/tcp.c:2001,20061998/1118/sys/src/9/ip/tcp.c:2042,2049
1997/0327    
{ 
	if(n == 1 && strcmp(f[0], "hangup") == 0) 
		return tcphangup(c); 
1998/1118    
	if(n >= 1 && strcmp(f[0], "keepalive") == 0) 
		return tcpstartka(c, f, n); 
1997/0327    
	return "unknown control request"; 
} 
 


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