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