V9/sys/inet/tcp_ld.c

Compare this file to the similar file:
Show the results in this format:

/*
 * tcp line discipline; only one, to be pushed on /dev/ip6.
 */

#include "tcp.h"
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/stream.h"
#include "../h/inio.h"
#include "../h/ttyio.h"
#include "../h/ttyld.h"
#include "../h/map.h"
#include "../h/buf.h"
/*#include "../h/ubavar.h"*/
#include "../h/conf.h"

#include "../h/inet/mbuf.h"
#include "../h/inet/in.h"
#include "../h/inet/ip.h"
#include "../h/inet/ip_var.h"
#include "../h/inet/tcp.h"
#include "../h/inet/tcp_fsm.h"
#include "../h/inet/tcp_seq.h"
#include "../h/inet/tcp_timer.h"
#include "../h/inet/tcp_var.h"
#include "../h/inet/tcpip.h"

extern int tcp_busy;	/* set to discourage timers */
int tcp_maxseg = 512;	/* default that doesn't last long */
struct queue *tcpqueue;

int	tcpopen(), tcpiput(), tcpisrv(), tcpclose();
int	tcposrv();
static	struct qinit tcprinit = { tcpiput, tcpisrv, tcpopen, tcpclose, 4096, 64 };
static	struct qinit tcpwinit = { putq, tcposrv, tcpopen, tcpclose, 512, 64 };
struct streamtab tcpinfo = { &tcprinit, &tcpwinit };

tcpopen(q, dev)
register struct queue *q;
{
	static int timing;
	extern int rbsize[];

	if (q->ptr)
		return(0);
	tcpqueue = q;	/* RD queue */
	if(!timing){
		timing = 1;
		tcp_fasttimo();
		tcp_slowtimo();
	}
	q->flag |= QDELIM;
	WR(q)->flag |= QDELIM;
	q->ptr = (caddr_t)1;
	WR(q)->ptr = (caddr_t)1;
	q->flag |= QNOENB;	/* ipiput calls qenable() */
	tcp_maxseg = rbsize[3]-sizeof(struct tcpiphdr);	/* to fit in a BLKBIG */
	return(1);
}

tcpclose(q)
register struct queue *q;
{
	if(tcpqueue == q)
		tcpqueue = 0;
}

tcpisrv(q)
register struct queue *q;
{
	register struct block *bp, *head, *tail;

	/* there is now a whole packet waiting
	 * on this queue; strip it off and pass to tcp_input().
	 * things other than data or delims are forwarded directly
	 * by tcpiput().
	 */
	head = tail = (struct block *) 0;
	while(bp = getq(q)){
		if(bp->type == M_DELIM){
			freeb(bp);
			if(head){
				tcp_busy++;
				MCHECK(head);
				tcp_input(head);
				--tcp_busy;
			} else {
				printf("tcpisrv: no data\n");
			}
			head = tail = (struct block *) 0;
		} else if(bp->type == M_DATA){
			bp->next = (struct block *) 0;
			if(head == (struct block *) 0){
				head = bp;
			} else {
				tail->next = bp;
			}
			tail = bp;
		} else {
			printf("tcpisrv: weird type %d\n", bp->type);
			(*q->next->qinfo->putp)(q->next, bp);
		}	
	}
	if (head)
		bp_putback(q, head);
}


tcpiput(q, bp)
register struct queue *q;
register struct block *bp;
{
	switch(bp->type){
	case M_DATA:
		putq(q, bp);	/* putq does compression into blocks */
		break;
	case M_DELIM:
		putq(q, bp);
		qenable(q);
		break;
	default:
		(*q->next->qinfo->putp)(q->next, bp);
		break;
	}
		
}

tcposrv(q)
register struct queue *q;
{
	register union stmsg *sp;
	register struct block *bp;

	register int *intp;

	while(bp = getq(q)){
		if(bp->type == M_IOCTL){
			sp = (union stmsg *)bp->rptr;
			switch(sp->ioc0.com){
			case TCPIOMAXSEG:
				intp = (int *)(sp->iocx.xxx);
				tcp_maxseg = *intp;
				bp->type = M_IOCACK;
				qreply(q, bp);
				break;
			default:
				(*q->next->qinfo->putp)(q->next, bp);
				break;
			}
		} else {
			(*q->next->qinfo->putp)(q->next, bp);
		}
	}
}

tcp_ldout(bp)
register struct block *bp;
{
	register struct block *bp1;
	register struct queue *q;

	if(tcpqueue == 0){
		bp_free(bp);
		return(1);
	}
	q = WR(tcpqueue);
	if(q->next->flag&QFULL){
		printf("tcp_ldout: QFULL\n");
		bp_free(bp);
		return(1);
	}
	MCHECK(bp);
	while(bp){
		bp1 = bp->next;
		(*q->next->qinfo->putp)(q->next, bp);
		bp = bp1;
	}
	bp1 = allocb(0);
	if(bp1){
		bp1->type = M_DELIM;
		(*q->next->qinfo->putp)(q->next, bp1);
	} else {
		printf("tcp_ldout: no allocb for delim\n");
		return(1);
	}
	return(0);
}