|
|
1.1 root 1: /*
2: * tcp line discipline; only one, to be pushed on /dev/ip6.
3: */
4:
5: #include "sys/param.h"
6: #include "sys/stream.h"
7: #include "sys/inio.h"
8: #include "sys/conf.h"
9:
10: #include "sys/inet/in.h"
11: #include "sys/inet/ip.h"
12: #include "sys/inet/ip_var.h"
13: #include "sys/inet/tcp.h"
14: #include "sys/inet/tcp_fsm.h"
15: #include "sys/inet/tcp_seq.h"
16: #include "sys/inet/tcp_timer.h"
17: #include "sys/inet/tcp_var.h"
18: #include "sys/inet/tcpip.h"
19:
20: extern int tcp_busy; /* set to discourage timers */
21: int tcp_maxseg = 4096-sizeof(struct tcpiphdr); /* to fit in a 4k block */
22: struct queue *tcpqueue;
23:
24: int tcpiput(), tcpisrv(), tcpclose();
25: long tcpopen();
26: int tcposrv();
27: static struct qinit tcprinit = { tcpiput, tcpisrv, tcpopen, tcpclose, 4096, 64 };
28: static struct qinit tcpwinit = { putq, tcposrv, tcpopen, tcpclose, 512, 64 };
29: struct streamtab tcpstream = { &tcprinit, &tcpwinit };
30:
31: long
32: tcpopen(q, dev)
33: register struct queue *q;
34: {
35: static int timing;
36:
37: if (q->ptr)
38: return(0);
39: tcpqueue = q; /* RD queue */
40: if(!timing){
41: timing = 1;
42: tcp_fasttimo();
43: tcp_slowtimo();
44: }
45: q->flag |= QDELIM;
46: WR(q)->flag |= QDELIM;
47: q->ptr = (caddr_t)1;
48: WR(q)->ptr = (caddr_t)1;
49: q->flag |= QNOENB; /* ipiput calls qenable() */
50: return(1);
51: }
52:
53: tcpclose(q)
54: register struct queue *q;
55: {
56: if(tcpqueue == q)
57: tcpqueue = NULL;
58: }
59:
60: /*
61: * pass a whole packet to tcp_input
62: */
63: tcpisrv(q)
64: register struct queue *q;
65: {
66: register struct block *bp, *head, *tail;
67:
68: head = tail = NULL;
69: while(bp = getq(q)){
70: switch (bp->type) {
71: case M_DATA:
72: bp->next = NULL;
73: if (head == NULL)
74: head = bp;
75: else
76: tail->next = bp;
77: tail = bp;
78: if (bp->class&S_DELIM) {
79: bp->class &=~ S_DELIM;
80: tcp_busy++;
81: MCHECK(head);
82: tcp_input(head);
83: --tcp_busy;
84: head = tail = NULL;
85: }
86: break;
87:
88: default:
89: panic("tcpisrv");
90: }
91: }
92: if (head)
93: bp_putback(q, head);
94: }
95:
96: tcpiput(q, bp)
97: register struct queue *q;
98: register struct block *bp;
99: {
100: switch(bp->type){
101: case M_DATA:
102: putq(q, bp);
103: if (bp->class&S_DELIM)
104: qenable(q);
105: break;
106: default:
107: (*q->next->qinfo->putp)(q->next, bp);
108: break;
109: }
110:
111: }
112:
113: tcposrv(q)
114: register struct queue *q;
115: {
116: register struct block *bp;
117:
118: while(bp = getq(q)){
119: switch (bp->type) {
120: case M_IOCTL:
121: switch(stiocom(bp)){
122: case TCPIOMAXSEG:
123: tcp_maxseg = *(int *)stiodata(bp);
124: bp->type = M_IOCACK;
125: qreply(q, bp);
126: continue;
127: }
128: /* default: fall through and put if room */
129:
130: default:
131: if (q->next->flag & QFULL) {
132: putbq(q, bp);
133: return;
134: }
135: (*q->next->qinfo->putp)(q->next, bp);
136: continue;
137: }
138: }
139: }
140:
141: /*
142: * hand list bp (an IP packet)
143: * to the next stream module,
144: * usually IP
145: */
146:
147: tcp_ldout(bp)
148: register struct block *bp;
149: {
150: register struct block *bp1;
151: register struct queue *nq;
152:
153: if(tcpqueue == NULL){
154: bp_free(bp);
155: return(1);
156: }
157: nq = WR(tcpqueue)->next;
158: if(nq->flag&QFULL){
159: printf("tcp_ldout: QFULL\n");
160: bp_free(bp);
161: return(1);
162: }
163: MCHECK(bp);
164: while(bp){
165: bp1 = bp->next;
166: if (bp1==NULL)
167: bp->class |= S_DELIM;
168: (*nq->qinfo->putp)(nq, bp);
169: bp = bp1;
170: }
171: return(0);
172: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.