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