|
|
1.1 ! root 1: #include "u.h" ! 2: #include "../port/lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "../port/error.h" ! 7: #include "arp.h" ! 8: #include "../port/ipdat.h" ! 9: ! 10: extern int tcpdbg; ! 11: #define DPRINT if(tcpdbg) print ! 12: ! 13: void ! 14: tcpxstate(Ipconv *s, char oldstate, char newstate) ! 15: { ! 16: int len; ! 17: Block *bp; ! 18: Tcpctl *tcb; ! 19: ! 20: if(oldstate == newstate) ! 21: return; ! 22: ! 23: tcb = &s->tcpctl; ! 24: switch(newstate) { ! 25: case Closed: ! 26: s->psrc = 0; /* This connection is toast */ ! 27: s->pdst = 0; ! 28: s->dst = 0; ! 29: /* fall through */ ! 30: ! 31: case Close_wait: /* Remote closes */ ! 32: if(s->err) { ! 33: len = strlen(s->err); ! 34: bp = allocb(len); ! 35: strcpy((char *)bp->wptr, s->err); ! 36: bp->wptr += len; ! 37: } ! 38: else ! 39: bp = allocb(0); ! 40: ! 41: bp->flags |= S_DELIM; ! 42: bp->type = M_HANGUP; ! 43: qlock(s); ! 44: if(waserror()) { ! 45: qunlock(s); ! 46: nexterror(); ! 47: } ! 48: if(s->readq == 0) { ! 49: if(newstate == Close_wait) ! 50: putb(&tcb->rcvq, bp); ! 51: else ! 52: freeb(bp); ! 53: } else ! 54: PUTNEXT(s->readq, bp); ! 55: if(tcb){ ! 56: tcb->sndfull = 0; ! 57: wakeup(&tcb->sndr); ! 58: } ! 59: poperror(); ! 60: qunlock(s); ! 61: break; ! 62: } ! 63: ! 64: if(oldstate == Syn_sent) ! 65: wakeup(&tcb->syner); ! 66: } ! 67: ! 68: static int ! 69: notsyner(void *ic) ! 70: { ! 71: return ((Tcpctl*)ic)->state != Syn_sent; ! 72: } ! 73: ! 74: void ! 75: tcpstart(Ipconv *s, int mode, ushort window, char tos) ! 76: { ! 77: Tcpctl *tcb; ! 78: ! 79: tcb = &s->tcpctl; ! 80: if(tcb->state != Closed || tcb->sndq != 0){ ! 81: print("tcpstart: %lux %d sndq %lux dest %d.%d.%d.%d %d to %d\n", ! 82: s, tcb->state, tcb->sndq, fmtaddr(s->dst), s->pdst, s->psrc); ! 83: error(Einuse); ! 84: } ! 85: ! 86: init_tcpctl(s); ! 87: ! 88: tcb->window = window; ! 89: tcb->rcv.wnd = window; ! 90: tcb->tos = tos; ! 91: ! 92: switch(mode){ ! 93: case TCP_PASSIVE: ! 94: tcb->flags |= CLONE; ! 95: tcpsetstate(s, Listen); ! 96: break; ! 97: ! 98: case TCP_ACTIVE: ! 99: /* Send SYN, go into SYN_SENT state */ ! 100: tcb->flags |= ACTIVE; ! 101: qlock(tcb); ! 102: if(waserror()) { ! 103: qunlock(tcb); ! 104: nexterror(); ! 105: } ! 106: tcpsndsyn(tcb); ! 107: tcpsetstate(s, Syn_sent); ! 108: tcpoutput(s); ! 109: poperror(); ! 110: qunlock(tcb); ! 111: tsleep(&tcb->syner, notsyner, tcb, 120*1000); ! 112: if(tcb->state != Established && tcb->state != Syn_received){ ! 113: if(s->err) ! 114: error(s->err); ! 115: error(Etimedout); ! 116: } ! 117: break; ! 118: } ! 119: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.