1 056fe1ba 2003-11-23 devnull #include <u.h>
2 056fe1ba 2003-11-23 devnull #include <libc.h>
3 056fe1ba 2003-11-23 devnull #include <venti.h>
4 056fe1ba 2003-11-23 devnull #include "queue.h"
6 8baa0cbd 2004-06-09 devnull long ventisendbytes, ventisendpackets;
7 8baa0cbd 2004-06-09 devnull long ventirecvbytes, ventirecvpackets;
9 056fe1ba 2003-11-23 devnull static int
10 056fe1ba 2003-11-23 devnull _vtsend(VtConn *z, Packet *p)
12 056fe1ba 2003-11-23 devnull IOchunk ioc;
13 5ddc97fc 2005-02-14 devnull int n, tot;
14 056fe1ba 2003-11-23 devnull uchar buf[2];
16 056fe1ba 2003-11-23 devnull if(z->state != VtStateConnected) {
17 056fe1ba 2003-11-23 devnull werrstr("session not connected");
18 056fe1ba 2003-11-23 devnull return -1;
21 056fe1ba 2003-11-23 devnull /* add framing */
22 056fe1ba 2003-11-23 devnull n = packetsize(p);
23 056fe1ba 2003-11-23 devnull if(n >= (1<<16)) {
24 056fe1ba 2003-11-23 devnull werrstr("packet too large");
25 056fe1ba 2003-11-23 devnull packetfree(p);
26 056fe1ba 2003-11-23 devnull return -1;
28 056fe1ba 2003-11-23 devnull buf[0] = n>>8;
29 056fe1ba 2003-11-23 devnull buf[1] = n;
30 056fe1ba 2003-11-23 devnull packetprefix(p, buf, 2);
31 8baa0cbd 2004-06-09 devnull ventisendbytes += n+2;
32 8baa0cbd 2004-06-09 devnull ventisendpackets++;
36 056fe1ba 2003-11-23 devnull n = packetfragments(p, &ioc, 1, 0);
37 056fe1ba 2003-11-23 devnull if(n == 0)
39 056fe1ba 2003-11-23 devnull if(write(z->outfd, ioc.addr, ioc.len) < ioc.len){
40 5ddc97fc 2005-02-14 devnull vtlog(VtServerLog, "<font size=-1>%T %s:</font> sending packet %p: %r<br>\n", z->addr, p);
41 056fe1ba 2003-11-23 devnull packetfree(p);
42 056fe1ba 2003-11-23 devnull return 0;
44 056fe1ba 2003-11-23 devnull packetconsume(p, nil, ioc.len);
45 5ddc97fc 2005-02-14 devnull tot += ioc.len;
47 5ddc97fc 2005-02-14 devnull vtlog(VtServerLog, "<font size=-1>%T %s:</font> sent packet %p (%d bytes)<br>\n", z->addr, p, tot);
48 056fe1ba 2003-11-23 devnull packetfree(p);
49 056fe1ba 2003-11-23 devnull return 1;
52 0c148046 2004-06-16 devnull static int
53 0c148046 2004-06-16 devnull interrupted(void)
55 0c148046 2004-06-16 devnull char e[ERRMAX];
57 0c148046 2004-06-16 devnull rerrstr(e, sizeof e);
58 0c148046 2004-06-16 devnull return strstr(e, "interrupted") != nil;
62 056fe1ba 2003-11-23 devnull static Packet*
63 056fe1ba 2003-11-23 devnull _vtrecv(VtConn *z)
65 056fe1ba 2003-11-23 devnull uchar buf[10], *b;
67 056fe1ba 2003-11-23 devnull Packet *p;
68 056fe1ba 2003-11-23 devnull int size, len;
70 056fe1ba 2003-11-23 devnull if(z->state != VtStateConnected) {
71 056fe1ba 2003-11-23 devnull werrstr("session not connected");
72 056fe1ba 2003-11-23 devnull return nil;
75 056fe1ba 2003-11-23 devnull p = z->part;
76 056fe1ba 2003-11-23 devnull /* get enough for head size */
77 056fe1ba 2003-11-23 devnull size = packetsize(p);
78 056fe1ba 2003-11-23 devnull while(size < 2) {
79 361e279c 2005-01-18 devnull b = packettrailer(p, 2);
80 056fe1ba 2003-11-23 devnull assert(b != nil);
81 a09e80f9 2004-05-23 devnull if(0) fprint(2, "%d read hdr\n", getpid());
82 361e279c 2005-01-18 devnull n = read(z->infd, b, 2);
83 a09e80f9 2004-05-23 devnull if(0) fprint(2, "%d got %d (%r)\n", getpid(), n);
84 0c148046 2004-06-16 devnull if(n==0 || (n<0 && !interrupted()))
85 056fe1ba 2003-11-23 devnull goto Err;
86 056fe1ba 2003-11-23 devnull size += n;
87 056fe1ba 2003-11-23 devnull packettrim(p, 0, size);
90 056fe1ba 2003-11-23 devnull if(packetconsume(p, buf, 2) < 0)
91 056fe1ba 2003-11-23 devnull goto Err;
92 056fe1ba 2003-11-23 devnull len = (buf[0] << 8) | buf[1];
93 056fe1ba 2003-11-23 devnull size -= 2;
95 056fe1ba 2003-11-23 devnull while(size < len) {
96 361e279c 2005-01-18 devnull n = len - size;
97 361e279c 2005-01-18 devnull if(n > MaxFragSize)
98 056fe1ba 2003-11-23 devnull n = MaxFragSize;
99 056fe1ba 2003-11-23 devnull b = packettrailer(p, n);
100 a09e80f9 2004-05-23 devnull if(0) fprint(2, "%d read body %d\n", getpid(), n);
101 a09e80f9 2004-05-23 devnull n = read(z->infd, b, n);
102 a09e80f9 2004-05-23 devnull if(0) fprint(2, "%d got %d (%r)\n", getpid(), n);
103 a09e80f9 2004-05-23 devnull if(n > 0)
104 a09e80f9 2004-05-23 devnull size += n;
105 a09e80f9 2004-05-23 devnull packettrim(p, 0, size);
106 0c148046 2004-06-16 devnull if(n==0 || (n<0 && !interrupted()))
107 056fe1ba 2003-11-23 devnull goto Err;
109 8baa0cbd 2004-06-09 devnull ventirecvbytes += len;
110 8baa0cbd 2004-06-09 devnull ventirecvpackets++;
111 056fe1ba 2003-11-23 devnull p = packetsplit(p, len);
112 5ddc97fc 2005-02-14 devnull vtlog(VtServerLog, "<font size=-1>%T %s:</font> read packet %p len %d<br>\n", z->addr, p, len);
113 056fe1ba 2003-11-23 devnull return p;
115 5ddc97fc 2005-02-14 devnull vtlog(VtServerLog, "<font size=-1>%T %s:</font> error reading packet: %r<br>\n", z->addr);
116 056fe1ba 2003-11-23 devnull return nil;
120 056fe1ba 2003-11-23 devnull * If you fork off two procs running vtrecvproc and vtsendproc,
121 056fe1ba 2003-11-23 devnull * then vtrecv/vtsend (and thus vtrpc) will never block except on
122 056fe1ba 2003-11-23 devnull * rendevouses, which is nice when it's running in one thread of many.
125 056fe1ba 2003-11-23 devnull vtrecvproc(void *v)
127 056fe1ba 2003-11-23 devnull Packet *p;
128 056fe1ba 2003-11-23 devnull VtConn *z;
129 056fe1ba 2003-11-23 devnull Queue *q;
132 056fe1ba 2003-11-23 devnull q = _vtqalloc();
134 056fe1ba 2003-11-23 devnull qlock(&z->lk);
135 056fe1ba 2003-11-23 devnull z->readq = q;
136 056fe1ba 2003-11-23 devnull qlock(&z->inlk);
137 056fe1ba 2003-11-23 devnull rwakeup(&z->rpcfork);
138 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
140 056fe1ba 2003-11-23 devnull while((p = _vtrecv(z)) != nil)
141 056fe1ba 2003-11-23 devnull if(_vtqsend(q, p) < 0){
142 056fe1ba 2003-11-23 devnull packetfree(p);
145 056fe1ba 2003-11-23 devnull qunlock(&z->inlk);
146 056fe1ba 2003-11-23 devnull qlock(&z->lk);
147 056fe1ba 2003-11-23 devnull _vtqhangup(q);
148 056fe1ba 2003-11-23 devnull while((p = _vtnbqrecv(q)) != nil)
149 056fe1ba 2003-11-23 devnull packetfree(p);
150 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
151 056fe1ba 2003-11-23 devnull z->readq = nil;
152 056fe1ba 2003-11-23 devnull rwakeup(&z->rpcfork);
153 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
154 056fe1ba 2003-11-23 devnull vthangup(z);
158 056fe1ba 2003-11-23 devnull vtsendproc(void *v)
160 056fe1ba 2003-11-23 devnull Queue *q;
161 056fe1ba 2003-11-23 devnull Packet *p;
162 056fe1ba 2003-11-23 devnull VtConn *z;
165 056fe1ba 2003-11-23 devnull q = _vtqalloc();
167 056fe1ba 2003-11-23 devnull qlock(&z->lk);
168 056fe1ba 2003-11-23 devnull z->writeq = q;
169 056fe1ba 2003-11-23 devnull qlock(&z->outlk);
170 056fe1ba 2003-11-23 devnull rwakeup(&z->rpcfork);
171 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
173 056fe1ba 2003-11-23 devnull while((p = _vtqrecv(q)) != nil)
174 056fe1ba 2003-11-23 devnull if(_vtsend(z, p) < 0)
176 056fe1ba 2003-11-23 devnull qunlock(&z->outlk);
177 056fe1ba 2003-11-23 devnull qlock(&z->lk);
178 056fe1ba 2003-11-23 devnull _vtqhangup(q);
179 056fe1ba 2003-11-23 devnull while((p = _vtnbqrecv(q)) != nil)
180 056fe1ba 2003-11-23 devnull packetfree(p);
181 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
182 056fe1ba 2003-11-23 devnull z->writeq = nil;
183 056fe1ba 2003-11-23 devnull rwakeup(&z->rpcfork);
184 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
189 056fe1ba 2003-11-23 devnull vtrecv(VtConn *z)
191 056fe1ba 2003-11-23 devnull Packet *p;
192 4f6d2bb1 2007-04-08 devnull Queue *q;
194 056fe1ba 2003-11-23 devnull qlock(&z->lk);
195 056fe1ba 2003-11-23 devnull if(z->state != VtStateConnected){
196 056fe1ba 2003-11-23 devnull werrstr("not connected");
197 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
198 056fe1ba 2003-11-23 devnull return nil;
200 056fe1ba 2003-11-23 devnull if(z->readq){
201 4f6d2bb1 2007-04-08 devnull q = _vtqincref(z->readq);
202 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
203 4f6d2bb1 2007-04-08 devnull p = _vtqrecv(q);
204 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
205 4f6d2bb1 2007-04-08 devnull return p;
208 056fe1ba 2003-11-23 devnull qlock(&z->inlk);
209 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
210 056fe1ba 2003-11-23 devnull p = _vtrecv(z);
211 056fe1ba 2003-11-23 devnull qunlock(&z->inlk);
213 056fe1ba 2003-11-23 devnull vthangup(z);
214 056fe1ba 2003-11-23 devnull return p;
218 056fe1ba 2003-11-23 devnull vtsend(VtConn *z, Packet *p)
220 4f6d2bb1 2007-04-08 devnull Queue *q;
222 056fe1ba 2003-11-23 devnull qlock(&z->lk);
223 056fe1ba 2003-11-23 devnull if(z->state != VtStateConnected){
224 056fe1ba 2003-11-23 devnull packetfree(p);
225 056fe1ba 2003-11-23 devnull werrstr("not connected");
226 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
227 056fe1ba 2003-11-23 devnull return -1;
229 056fe1ba 2003-11-23 devnull if(z->writeq){
230 4f6d2bb1 2007-04-08 devnull q = _vtqincref(z->writeq);
231 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
232 4f6d2bb1 2007-04-08 devnull if(_vtqsend(q, p) < 0){
233 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
234 056fe1ba 2003-11-23 devnull packetfree(p);
235 056fe1ba 2003-11-23 devnull return -1;
237 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
238 056fe1ba 2003-11-23 devnull return 0;
241 056fe1ba 2003-11-23 devnull qlock(&z->outlk);
242 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
243 056fe1ba 2003-11-23 devnull if(_vtsend(z, p) < 0){
244 056fe1ba 2003-11-23 devnull qunlock(&z->outlk);
245 056fe1ba 2003-11-23 devnull vthangup(z);
246 056fe1ba 2003-11-23 devnull return -1;
248 056fe1ba 2003-11-23 devnull qunlock(&z->outlk);
249 056fe1ba 2003-11-23 devnull return 0;