|
|
1.1 root 1: /*
2: * tcp line discipline; only one, to be pushed on /dev/ip6.
3: */
4:
5: #include "tcp.h"
6: #if NTCP > 0
7: #include "../h/param.h"
8: #include "../h/systm.h"
9: #include "../h/stream.h"
10: #include "../h/ioctl.h"
11: #include "../h/ttyld.h"
12: #include "../h/map.h"
13: #include "../h/buf.h"
14: #include "../h/ubavar.h"
15: #include "../h/conf.h"
16:
17: extern int tcp_busy; /* set to discourage timers */
18: int tcp_maxseg = 1024; /* dynamic size of t_maxseg; was 512 originally*/
19: struct queue *tcpqueue;
20:
21: int tcpopen(), tcpiput(), tcpisrv(), tcpclose();
22: int tcposrv(), tcpoput();
23: static struct qinit tcprinit = { tcpiput, tcpisrv, tcpopen, tcpclose, 1024, 64 };
24: /* was 512, 64 */
25: static struct qinit tcpwinit = { putq, tcposrv, tcpopen, tcpclose, 1024, 64 };
26: /* was 512, 64 */
27: struct streamtab tcpinfo = { &tcprinit, &tcpwinit };
28:
29: tcpopen(q, dev)
30: register struct queue *q;
31: {
32: static int timing;
33:
34: if (q->ptr)
35: return(0);
36: tcpqueue = q; /* RD queue */
37: if(!timing){
38: timing = 1;
39: tcp_fasttimo();
40: tcp_slowtimo();
41: }
42: q->flag |= QDELIM;
43: WR(q)->flag |= QDELIM;
44: q->ptr = (caddr_t)1;
45: WR(q)->ptr = (caddr_t)1;
46: q->flag |= QNOENB; /* ipiput calls qenable() */
47: return(1);
48: }
49:
50: tcpclose(q)
51: register struct queue *q;
52: {
53: if(tcpqueue == q)
54: tcpqueue = 0;
55: }
56:
57: tcpisrv(q)
58: register struct queue *q;
59: {
60: register struct block *bp, *head, *tail;
61:
62: /* there is now a whole packet waiting
63: * on this queue; strip it off and pass to tcp_input().
64: * things other than data or delims are forwarded directly
65: * by tcpiput().
66: */
67: head = tail = (struct block *) 0;
68: while(bp = getq(q)){
69: if(bp->type == M_DELIM){
70: freeb(bp);
71: if(head){
72: tcp_busy++;
73: tcp_input(head);
74: --tcp_busy;
75: } else {
76: printf("tcpisrv: delim, no data\n");
77: }
78: head = tail = (struct block *) 0;
79: } else if(bp->type == M_DATA){
80: bp->next = (struct block *) 0;
81: if(head == (struct block *) 0){
82: head = bp;
83: } else {
84: tail->next = bp;
85: }
86: tail = bp;
87: } else {
88: printf("weird type 0%o in tcpisrv\n", bp->type);
89: (*q->next->qinfo->putp)(q->next, bp);
90: }
91: }
92: if(head || tail){
93: printf("tcpisrv: data & no dELIM\n");
94: }
95: }
96:
97:
98: tcpiput(q, bp)
99: register struct queue *q;
100: register struct block *bp;
101: {
102: switch(bp->type){
103: case M_DATA:
104: putq(q, bp); /* putq does compression into blocks */
105: break;
106: case M_DELIM:
107: putq(q, bp);
108: qenable(q);
109: break;
110: default:
111: (*q->next->qinfo->putp)(q->next, bp);
112: break;
113: }
114:
115: }
116:
117: tcposrv(q)
118: register struct queue *q;
119: {
120: register union stmsg *sp;
121: register struct block *bp;
122:
123: register int *intp;
124:
125: while(bp = getq(q)){
126: if(bp->type == M_IOCTL){
127: sp = (union stmsg *)bp->rptr;
128: switch(sp->ioc0.com){
129: case TCPIOMAXSEG:
130: intp = (int *)(sp->iocx.xxx);
131: tcp_maxseg = *intp;
132: bp->type = M_IOCACK;
133: qreply(q, bp);
134: break;
135: default:
136: (*q->next->qinfo->putp)(q->next, bp);
137: break;
138: }
139: } else {
140: (*q->next->qinfo->putp)(q->next, bp);
141: }
142: }
143: }
144:
145: tcp_ldout(bp)
146: register struct block *bp;
147: {
148: register struct block *bp1;
149: register struct queue *q;
150:
151: if(tcpqueue == 0){
152: bp_free(bp);
153: return(1);
154: }
155: q = WR(tcpqueue);
156: if(q->next->flag&QFULL){
157: printf("tcp_ldout: QFULL\n");
158: bp_free(bp);
159: return(1);
160: }
161: while(bp){
162: bp1 = bp->next;
163: (*q->next->qinfo->putp)(q->next, bp);
164: bp = bp1;
165: }
166: bp1 = allocb(0);
167: if(bp1){
168: bp1->type = M_DELIM;
169: (*q->next->qinfo->putp)(q->next, bp1);
170: } else {
171: printf("tcp_ldout: no allocb for delim\n");
172: return(1);
173: }
174: return(0);
175: }
176: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.