| plan 9 kernel history: overview | file list | diff list |
1992/0903/port/tcpif.c (diff list | history)
| port/tcpif.c on 1991/0424 | ||
| 1991/0424 | #include "u.h" | |
| 1992/0321 | #include "../port/lib.h" | |
| 1991/0424 | #include "mem.h" #include "dat.h" #include "fns.h" | |
| 1992/0111 | #include "../port/error.h" | |
| 1991/0424 | #include "arp.h" #include "ipdat.h" extern int tcpdbg; #define DPRINT if(tcpdbg) print void | |
| 1992/0903 | tcpxstate(Ipconv *s, char oldstate, char newstate) | |
| 1991/0424 | { int len; | |
| 1992/0903 | Block *bp; | |
| 1992/0303 | Tcpctl *tcb = &s->tcpctl; | |
| 1991/0424 | if(oldstate == newstate) return; switch(newstate) { | |
| 1991/12171 | case Closed: | |
| 1992/0903 | s->psrc = 0; /* This connection is toast */ | |
| 1991/0424 | s->pdst = 0; s->dst = 0; | |
| 1992/0903 | ||
| 1991/12171 | case Close_wait: /* Remote closes */ | |
| 1991/0424 | if(s->err) { | |
| 1992/0111 | len = strlen(s->err); | |
| 1991/0424 | bp = allocb(len); | |
| 1992/0111 | strcpy((char *)bp->wptr, s->err); | |
| 1991/1120 | bp->wptr += len; | |
| 1991/0424 | } else bp = allocb(0); | |
| 1991/1120 | bp->flags |= S_DELIM; bp->type = M_HANGUP; | |
| 1992/0223 | qlock(s); | |
| 1992/0322 | if(waserror()) { qunlock(s); nexterror(); } | |
| 1992/0903 | if(s->readq == 0) { | |
| 1992/0416 | if(newstate == Close_wait) putb(&tcb->rcvq, bp); else freeb(bp); } else | |
| 1992/0223 | PUTNEXT(s->readq, bp); | |
| 1992/0322 | poperror(); | |
| 1992/0223 | qunlock(s); | |
| 1991/1120 | break; | |
| 1991/0424 | } | |
| 1992/0303 | if(oldstate == Syn_sent) wakeup(&tcb->syner); | |
| 1991/0424 | } | |
| 1992/0303 | static int notsyner(void *ic) { return ((Tcpctl*)ic)->state != Syn_sent; } | |
| 1992/0325 | ||
| 1991/0424 | void | |
| 1991/1014 | tcpstart(Ipconv *s, int mode, ushort window, char tos) | |
| 1991/0424 | { Tcpctl *tcb = &s->tcpctl; | |
| 1991/12171 | if(tcb->state != Closed) | |
| 1991/0424 | return; init_tcpctl(s); tcb->window = tcb->rcv.wnd = window; tcb->tos = tos; switch(mode){ case TCP_PASSIVE: tcb->flags |= CLONE; | |
| 1992/0903 | tcpsetstate(s, Listen); | |
| 1991/0424 | break; | |
| 1992/0325 | ||
| 1991/0424 | case TCP_ACTIVE: /* Send SYN, go into SYN_SENT state */ tcb->flags |= ACTIVE; qlock(tcb); | |
| 1992/0322 | if(waserror()) { qunlock(tcb); nexterror(); } | |
| 1992/0903 | tcpsndsyn(tcb); tcpsetstate(s, Syn_sent); tcpoutput(s); | |
| 1992/0322 | poperror(); | |
| 1991/0424 | qunlock(tcb); | |
| 1992/0303 | sleep(&tcb->syner, notsyner, tcb); if(tcb->state != Established && tcb->state != Syn_received) error(Etimedout); | |
| 1991/0424 | break; } } | |