|
|
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.