Blame


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"
5 056fe1ba 2003-11-23 devnull
6 8baa0cbd 2004-06-09 devnull long ventisendbytes, ventisendpackets;
7 8baa0cbd 2004-06-09 devnull long ventirecvbytes, ventirecvpackets;
8 8baa0cbd 2004-06-09 devnull
9 056fe1ba 2003-11-23 devnull static int
10 056fe1ba 2003-11-23 devnull _vtsend(VtConn *z, Packet *p)
11 056fe1ba 2003-11-23 devnull {
12 056fe1ba 2003-11-23 devnull IOchunk ioc;
13 5ddc97fc 2005-02-14 devnull int n, tot;
14 33b446b8 2009-05-25 rsc uchar buf[4];
15 8baa0cbd 2004-06-09 devnull
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;
19 056fe1ba 2003-11-23 devnull }
20 056fe1ba 2003-11-23 devnull
21 056fe1ba 2003-11-23 devnull /* add framing */
22 056fe1ba 2003-11-23 devnull n = packetsize(p);
23 33b446b8 2009-05-25 rsc if(z->version[1] == '2') {
24 33b446b8 2009-05-25 rsc if(n >= (1<<16)) {
25 33b446b8 2009-05-25 rsc werrstr("packet too large");
26 33b446b8 2009-05-25 rsc packetfree(p);
27 33b446b8 2009-05-25 rsc return -1;
28 33b446b8 2009-05-25 rsc }
29 33b446b8 2009-05-25 rsc buf[0] = n>>8;
30 33b446b8 2009-05-25 rsc buf[1] = n;
31 33b446b8 2009-05-25 rsc packetprefix(p, buf, 2);
32 33b446b8 2009-05-25 rsc ventisendbytes += n+2;
33 33b446b8 2009-05-25 rsc } else {
34 33b446b8 2009-05-25 rsc buf[0] = n>>24;
35 33b446b8 2009-05-25 rsc buf[1] = n>>16;
36 33b446b8 2009-05-25 rsc buf[2] = n>>8;
37 33b446b8 2009-05-25 rsc buf[3] = n;
38 33b446b8 2009-05-25 rsc packetprefix(p, buf, 4);
39 33b446b8 2009-05-25 rsc ventisendbytes += n+4;
40 056fe1ba 2003-11-23 devnull }
41 8baa0cbd 2004-06-09 devnull ventisendpackets++;
42 056fe1ba 2003-11-23 devnull
43 5ddc97fc 2005-02-14 devnull tot = 0;
44 056fe1ba 2003-11-23 devnull for(;;){
45 056fe1ba 2003-11-23 devnull n = packetfragments(p, &ioc, 1, 0);
46 056fe1ba 2003-11-23 devnull if(n == 0)
47 056fe1ba 2003-11-23 devnull break;
48 056fe1ba 2003-11-23 devnull if(write(z->outfd, ioc.addr, ioc.len) < ioc.len){
49 5ddc97fc 2005-02-14 devnull vtlog(VtServerLog, "<font size=-1>%T %s:</font> sending packet %p: %r<br>\n", z->addr, p);
50 056fe1ba 2003-11-23 devnull packetfree(p);
51 13096891 2008-06-15 rsc return -1;
52 056fe1ba 2003-11-23 devnull }
53 056fe1ba 2003-11-23 devnull packetconsume(p, nil, ioc.len);
54 5ddc97fc 2005-02-14 devnull tot += ioc.len;
55 056fe1ba 2003-11-23 devnull }
56 5ddc97fc 2005-02-14 devnull vtlog(VtServerLog, "<font size=-1>%T %s:</font> sent packet %p (%d bytes)<br>\n", z->addr, p, tot);
57 056fe1ba 2003-11-23 devnull packetfree(p);
58 056fe1ba 2003-11-23 devnull return 1;
59 056fe1ba 2003-11-23 devnull }
60 056fe1ba 2003-11-23 devnull
61 0c148046 2004-06-16 devnull static int
62 0c148046 2004-06-16 devnull interrupted(void)
63 0c148046 2004-06-16 devnull {
64 0c148046 2004-06-16 devnull char e[ERRMAX];
65 0c148046 2004-06-16 devnull
66 0c148046 2004-06-16 devnull rerrstr(e, sizeof e);
67 0c148046 2004-06-16 devnull return strstr(e, "interrupted") != nil;
68 0c148046 2004-06-16 devnull }
69 0c148046 2004-06-16 devnull
70 0c148046 2004-06-16 devnull
71 056fe1ba 2003-11-23 devnull static Packet*
72 056fe1ba 2003-11-23 devnull _vtrecv(VtConn *z)
73 056fe1ba 2003-11-23 devnull {
74 056fe1ba 2003-11-23 devnull uchar buf[10], *b;
75 33b446b8 2009-05-25 rsc int n, need;
76 056fe1ba 2003-11-23 devnull Packet *p;
77 056fe1ba 2003-11-23 devnull int size, len;
78 056fe1ba 2003-11-23 devnull
79 056fe1ba 2003-11-23 devnull if(z->state != VtStateConnected) {
80 056fe1ba 2003-11-23 devnull werrstr("session not connected");
81 056fe1ba 2003-11-23 devnull return nil;
82 056fe1ba 2003-11-23 devnull }
83 056fe1ba 2003-11-23 devnull
84 056fe1ba 2003-11-23 devnull p = z->part;
85 056fe1ba 2003-11-23 devnull /* get enough for head size */
86 056fe1ba 2003-11-23 devnull size = packetsize(p);
87 33b446b8 2009-05-25 rsc need = z->version[1] - '0'; // 2 or 4
88 33b446b8 2009-05-25 rsc while(size < need) {
89 33b446b8 2009-05-25 rsc b = packettrailer(p, need);
90 056fe1ba 2003-11-23 devnull assert(b != nil);
91 a09e80f9 2004-05-23 devnull if(0) fprint(2, "%d read hdr\n", getpid());
92 33b446b8 2009-05-25 rsc n = read(z->infd, b, need);
93 a09e80f9 2004-05-23 devnull if(0) fprint(2, "%d got %d (%r)\n", getpid(), n);
94 0c148046 2004-06-16 devnull if(n==0 || (n<0 && !interrupted()))
95 056fe1ba 2003-11-23 devnull goto Err;
96 056fe1ba 2003-11-23 devnull size += n;
97 056fe1ba 2003-11-23 devnull packettrim(p, 0, size);
98 056fe1ba 2003-11-23 devnull }
99 056fe1ba 2003-11-23 devnull
100 33b446b8 2009-05-25 rsc if(packetconsume(p, buf, need) < 0)
101 056fe1ba 2003-11-23 devnull goto Err;
102 33b446b8 2009-05-25 rsc if(z->version[1] == '2') {
103 33b446b8 2009-05-25 rsc len = (buf[0] << 8) | buf[1];
104 33b446b8 2009-05-25 rsc size -= 2;
105 33b446b8 2009-05-25 rsc } else {
106 33b446b8 2009-05-25 rsc len = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
107 33b446b8 2009-05-25 rsc size -= 4;
108 33b446b8 2009-05-25 rsc }
109 056fe1ba 2003-11-23 devnull
110 056fe1ba 2003-11-23 devnull while(size < len) {
111 361e279c 2005-01-18 devnull n = len - size;
112 361e279c 2005-01-18 devnull if(n > MaxFragSize)
113 056fe1ba 2003-11-23 devnull n = MaxFragSize;
114 056fe1ba 2003-11-23 devnull b = packettrailer(p, n);
115 a09e80f9 2004-05-23 devnull if(0) fprint(2, "%d read body %d\n", getpid(), n);
116 a09e80f9 2004-05-23 devnull n = read(z->infd, b, n);
117 a09e80f9 2004-05-23 devnull if(0) fprint(2, "%d got %d (%r)\n", getpid(), n);
118 a09e80f9 2004-05-23 devnull if(n > 0)
119 a09e80f9 2004-05-23 devnull size += n;
120 a09e80f9 2004-05-23 devnull packettrim(p, 0, size);
121 0c148046 2004-06-16 devnull if(n==0 || (n<0 && !interrupted()))
122 056fe1ba 2003-11-23 devnull goto Err;
123 056fe1ba 2003-11-23 devnull }
124 8baa0cbd 2004-06-09 devnull ventirecvbytes += len;
125 8baa0cbd 2004-06-09 devnull ventirecvpackets++;
126 056fe1ba 2003-11-23 devnull p = packetsplit(p, len);
127 5ddc97fc 2005-02-14 devnull vtlog(VtServerLog, "<font size=-1>%T %s:</font> read packet %p len %d<br>\n", z->addr, p, len);
128 056fe1ba 2003-11-23 devnull return p;
129 fa325e9b 2020-01-10 cross Err:
130 5ddc97fc 2005-02-14 devnull vtlog(VtServerLog, "<font size=-1>%T %s:</font> error reading packet: %r<br>\n", z->addr);
131 fa325e9b 2020-01-10 cross return nil;
132 056fe1ba 2003-11-23 devnull }
133 056fe1ba 2003-11-23 devnull
134 056fe1ba 2003-11-23 devnull /*
135 056fe1ba 2003-11-23 devnull * If you fork off two procs running vtrecvproc and vtsendproc,
136 fa325e9b 2020-01-10 cross * then vtrecv/vtsend (and thus vtrpc) will never block except on
137 056fe1ba 2003-11-23 devnull * rendevouses, which is nice when it's running in one thread of many.
138 056fe1ba 2003-11-23 devnull */
139 056fe1ba 2003-11-23 devnull void
140 056fe1ba 2003-11-23 devnull vtrecvproc(void *v)
141 056fe1ba 2003-11-23 devnull {
142 056fe1ba 2003-11-23 devnull Packet *p;
143 056fe1ba 2003-11-23 devnull VtConn *z;
144 056fe1ba 2003-11-23 devnull Queue *q;
145 056fe1ba 2003-11-23 devnull
146 056fe1ba 2003-11-23 devnull z = v;
147 056fe1ba 2003-11-23 devnull q = _vtqalloc();
148 056fe1ba 2003-11-23 devnull
149 056fe1ba 2003-11-23 devnull qlock(&z->lk);
150 056fe1ba 2003-11-23 devnull z->readq = q;
151 056fe1ba 2003-11-23 devnull qlock(&z->inlk);
152 056fe1ba 2003-11-23 devnull rwakeup(&z->rpcfork);
153 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
154 056fe1ba 2003-11-23 devnull
155 056fe1ba 2003-11-23 devnull while((p = _vtrecv(z)) != nil)
156 056fe1ba 2003-11-23 devnull if(_vtqsend(q, p) < 0){
157 056fe1ba 2003-11-23 devnull packetfree(p);
158 056fe1ba 2003-11-23 devnull break;
159 056fe1ba 2003-11-23 devnull }
160 056fe1ba 2003-11-23 devnull qunlock(&z->inlk);
161 056fe1ba 2003-11-23 devnull qlock(&z->lk);
162 056fe1ba 2003-11-23 devnull _vtqhangup(q);
163 056fe1ba 2003-11-23 devnull while((p = _vtnbqrecv(q)) != nil)
164 056fe1ba 2003-11-23 devnull packetfree(p);
165 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
166 056fe1ba 2003-11-23 devnull z->readq = nil;
167 056fe1ba 2003-11-23 devnull rwakeup(&z->rpcfork);
168 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
169 056fe1ba 2003-11-23 devnull vthangup(z);
170 056fe1ba 2003-11-23 devnull }
171 056fe1ba 2003-11-23 devnull
172 056fe1ba 2003-11-23 devnull void
173 056fe1ba 2003-11-23 devnull vtsendproc(void *v)
174 056fe1ba 2003-11-23 devnull {
175 056fe1ba 2003-11-23 devnull Queue *q;
176 056fe1ba 2003-11-23 devnull Packet *p;
177 056fe1ba 2003-11-23 devnull VtConn *z;
178 056fe1ba 2003-11-23 devnull
179 056fe1ba 2003-11-23 devnull z = v;
180 056fe1ba 2003-11-23 devnull q = _vtqalloc();
181 056fe1ba 2003-11-23 devnull
182 056fe1ba 2003-11-23 devnull qlock(&z->lk);
183 056fe1ba 2003-11-23 devnull z->writeq = q;
184 056fe1ba 2003-11-23 devnull qlock(&z->outlk);
185 056fe1ba 2003-11-23 devnull rwakeup(&z->rpcfork);
186 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
187 056fe1ba 2003-11-23 devnull
188 056fe1ba 2003-11-23 devnull while((p = _vtqrecv(q)) != nil)
189 056fe1ba 2003-11-23 devnull if(_vtsend(z, p) < 0)
190 056fe1ba 2003-11-23 devnull break;
191 056fe1ba 2003-11-23 devnull qunlock(&z->outlk);
192 056fe1ba 2003-11-23 devnull qlock(&z->lk);
193 056fe1ba 2003-11-23 devnull _vtqhangup(q);
194 056fe1ba 2003-11-23 devnull while((p = _vtnbqrecv(q)) != nil)
195 056fe1ba 2003-11-23 devnull packetfree(p);
196 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
197 056fe1ba 2003-11-23 devnull z->writeq = nil;
198 056fe1ba 2003-11-23 devnull rwakeup(&z->rpcfork);
199 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
200 056fe1ba 2003-11-23 devnull return;
201 056fe1ba 2003-11-23 devnull }
202 056fe1ba 2003-11-23 devnull
203 056fe1ba 2003-11-23 devnull Packet*
204 056fe1ba 2003-11-23 devnull vtrecv(VtConn *z)
205 056fe1ba 2003-11-23 devnull {
206 056fe1ba 2003-11-23 devnull Packet *p;
207 4f6d2bb1 2007-04-08 devnull Queue *q;
208 056fe1ba 2003-11-23 devnull
209 056fe1ba 2003-11-23 devnull qlock(&z->lk);
210 056fe1ba 2003-11-23 devnull if(z->state != VtStateConnected){
211 056fe1ba 2003-11-23 devnull werrstr("not connected");
212 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
213 056fe1ba 2003-11-23 devnull return nil;
214 056fe1ba 2003-11-23 devnull }
215 056fe1ba 2003-11-23 devnull if(z->readq){
216 4f6d2bb1 2007-04-08 devnull q = _vtqincref(z->readq);
217 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
218 4f6d2bb1 2007-04-08 devnull p = _vtqrecv(q);
219 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
220 4f6d2bb1 2007-04-08 devnull return p;
221 056fe1ba 2003-11-23 devnull }
222 056fe1ba 2003-11-23 devnull
223 056fe1ba 2003-11-23 devnull qlock(&z->inlk);
224 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
225 056fe1ba 2003-11-23 devnull p = _vtrecv(z);
226 056fe1ba 2003-11-23 devnull qunlock(&z->inlk);
227 056fe1ba 2003-11-23 devnull if(!p)
228 056fe1ba 2003-11-23 devnull vthangup(z);
229 056fe1ba 2003-11-23 devnull return p;
230 056fe1ba 2003-11-23 devnull }
231 056fe1ba 2003-11-23 devnull
232 056fe1ba 2003-11-23 devnull int
233 056fe1ba 2003-11-23 devnull vtsend(VtConn *z, Packet *p)
234 056fe1ba 2003-11-23 devnull {
235 4f6d2bb1 2007-04-08 devnull Queue *q;
236 4f6d2bb1 2007-04-08 devnull
237 056fe1ba 2003-11-23 devnull qlock(&z->lk);
238 056fe1ba 2003-11-23 devnull if(z->state != VtStateConnected){
239 056fe1ba 2003-11-23 devnull packetfree(p);
240 056fe1ba 2003-11-23 devnull werrstr("not connected");
241 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
242 056fe1ba 2003-11-23 devnull return -1;
243 056fe1ba 2003-11-23 devnull }
244 056fe1ba 2003-11-23 devnull if(z->writeq){
245 4f6d2bb1 2007-04-08 devnull q = _vtqincref(z->writeq);
246 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
247 4f6d2bb1 2007-04-08 devnull if(_vtqsend(q, p) < 0){
248 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
249 056fe1ba 2003-11-23 devnull packetfree(p);
250 056fe1ba 2003-11-23 devnull return -1;
251 056fe1ba 2003-11-23 devnull }
252 4f6d2bb1 2007-04-08 devnull _vtqdecref(q);
253 056fe1ba 2003-11-23 devnull return 0;
254 056fe1ba 2003-11-23 devnull }
255 056fe1ba 2003-11-23 devnull
256 056fe1ba 2003-11-23 devnull qlock(&z->outlk);
257 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
258 056fe1ba 2003-11-23 devnull if(_vtsend(z, p) < 0){
259 056fe1ba 2003-11-23 devnull qunlock(&z->outlk);
260 056fe1ba 2003-11-23 devnull vthangup(z);
261 fa325e9b 2020-01-10 cross return -1;
262 056fe1ba 2003-11-23 devnull }
263 056fe1ba 2003-11-23 devnull qunlock(&z->outlk);
264 056fe1ba 2003-11-23 devnull return 0;
265 056fe1ba 2003-11-23 devnull }