1368c31abSDavid du Colombier #include <u.h>
2368c31abSDavid du Colombier #include <libc.h>
3368c31abSDavid du Colombier #include <oventi.h>
4368c31abSDavid du Colombier #include "session.h"
5368c31abSDavid du Colombier
6368c31abSDavid du Colombier static char EAuthState[] = "bad authentication state";
7368c31abSDavid du Colombier static char ENotServer[] = "not a server session";
8368c31abSDavid du Colombier static char EVersion[] = "incorrect version number";
9368c31abSDavid du Colombier static char EProtocolBotch[] = "venti protocol botch";
10368c31abSDavid du Colombier
11368c31abSDavid du Colombier VtSession *
vtServerAlloc(VtServerVtbl * vtbl)12368c31abSDavid du Colombier vtServerAlloc(VtServerVtbl *vtbl)
13368c31abSDavid du Colombier {
14368c31abSDavid du Colombier VtSession *z = vtAlloc();
15368c31abSDavid du Colombier z->vtbl = vtMemAlloc(sizeof(VtServerVtbl));
16*225077b0SDavid du Colombier setmalloctag(z->vtbl, getcallerpc(&vtbl));
17368c31abSDavid du Colombier *z->vtbl = *vtbl;
18368c31abSDavid du Colombier return z;
19368c31abSDavid du Colombier }
20368c31abSDavid du Colombier
21368c31abSDavid du Colombier static int
srvHello(VtSession * z,char * version,char * uid,int,uchar *,int,uchar *,int)22368c31abSDavid du Colombier srvHello(VtSession *z, char *version, char *uid, int , uchar *, int , uchar *, int )
23368c31abSDavid du Colombier {
24368c31abSDavid du Colombier vtLock(z->lk);
25368c31abSDavid du Colombier if(z->auth.state != VtAuthHello) {
26368c31abSDavid du Colombier vtSetError(EAuthState);
27368c31abSDavid du Colombier goto Err;
28368c31abSDavid du Colombier }
29368c31abSDavid du Colombier if(strcmp(version, vtGetVersion(z)) != 0) {
30368c31abSDavid du Colombier vtSetError(EVersion);
31368c31abSDavid du Colombier goto Err;
32368c31abSDavid du Colombier }
33368c31abSDavid du Colombier vtMemFree(z->uid);
34368c31abSDavid du Colombier z->uid = vtStrDup(uid);
35368c31abSDavid du Colombier z->auth.state = VtAuthOK;
36368c31abSDavid du Colombier vtUnlock(z->lk);
37368c31abSDavid du Colombier return 1;
38368c31abSDavid du Colombier Err:
39368c31abSDavid du Colombier z->auth.state = VtAuthFailed;
40368c31abSDavid du Colombier vtUnlock(z->lk);
41368c31abSDavid du Colombier return 0;
42368c31abSDavid du Colombier }
43368c31abSDavid du Colombier
44368c31abSDavid du Colombier
45368c31abSDavid du Colombier static int
dispatchHello(VtSession * z,Packet ** pkt)46368c31abSDavid du Colombier dispatchHello(VtSession *z, Packet **pkt)
47368c31abSDavid du Colombier {
48368c31abSDavid du Colombier char *version, *uid;
49368c31abSDavid du Colombier uchar *crypto, *codec;
50368c31abSDavid du Colombier uchar buf[10];
51368c31abSDavid du Colombier int ncrypto, ncodec, cryptoStrength;
52368c31abSDavid du Colombier int ret;
53368c31abSDavid du Colombier Packet *p;
54368c31abSDavid du Colombier
55368c31abSDavid du Colombier p = *pkt;
56368c31abSDavid du Colombier
57368c31abSDavid du Colombier version = nil;
58368c31abSDavid du Colombier uid = nil;
59368c31abSDavid du Colombier crypto = nil;
60368c31abSDavid du Colombier codec = nil;
61368c31abSDavid du Colombier
62368c31abSDavid du Colombier ret = 0;
63368c31abSDavid du Colombier if(!vtGetString(p, &version))
64368c31abSDavid du Colombier goto Err;
65368c31abSDavid du Colombier if(!vtGetString(p, &uid))
66368c31abSDavid du Colombier goto Err;
67368c31abSDavid du Colombier if(!packetConsume(p, buf, 2))
68368c31abSDavid du Colombier goto Err;
69368c31abSDavid du Colombier cryptoStrength = buf[0];
70368c31abSDavid du Colombier ncrypto = buf[1];
71368c31abSDavid du Colombier crypto = vtMemAlloc(ncrypto);
72368c31abSDavid du Colombier if(!packetConsume(p, crypto, ncrypto))
73368c31abSDavid du Colombier goto Err;
74368c31abSDavid du Colombier
75368c31abSDavid du Colombier if(!packetConsume(p, buf, 1))
76368c31abSDavid du Colombier goto Err;
77368c31abSDavid du Colombier ncodec = buf[0];
78368c31abSDavid du Colombier codec = vtMemAlloc(ncodec);
79368c31abSDavid du Colombier if(!packetConsume(p, codec, ncodec))
80368c31abSDavid du Colombier goto Err;
81368c31abSDavid du Colombier
82368c31abSDavid du Colombier if(packetSize(p) != 0) {
83368c31abSDavid du Colombier vtSetError(EProtocolBotch);
84368c31abSDavid du Colombier goto Err;
85368c31abSDavid du Colombier }
86368c31abSDavid du Colombier if(!srvHello(z, version, uid, cryptoStrength, crypto, ncrypto, codec, ncodec)) {
87368c31abSDavid du Colombier packetFree(p);
88368c31abSDavid du Colombier *pkt = nil;
89368c31abSDavid du Colombier } else {
90368c31abSDavid du Colombier if(!vtAddString(p, vtGetSid(z)))
91368c31abSDavid du Colombier goto Err;
92368c31abSDavid du Colombier buf[0] = vtGetCrypto(z);
93368c31abSDavid du Colombier buf[1] = vtGetCodec(z);
94368c31abSDavid du Colombier packetAppend(p, buf, 2);
95368c31abSDavid du Colombier }
96368c31abSDavid du Colombier ret = 1;
97368c31abSDavid du Colombier Err:
98368c31abSDavid du Colombier vtMemFree(version);
99368c31abSDavid du Colombier vtMemFree(uid);
100368c31abSDavid du Colombier vtMemFree(crypto);
101368c31abSDavid du Colombier vtMemFree(codec);
102368c31abSDavid du Colombier return ret;
103368c31abSDavid du Colombier }
104368c31abSDavid du Colombier
105368c31abSDavid du Colombier static int
dispatchRead(VtSession * z,Packet ** pkt)106368c31abSDavid du Colombier dispatchRead(VtSession *z, Packet **pkt)
107368c31abSDavid du Colombier {
108368c31abSDavid du Colombier Packet *p;
109368c31abSDavid du Colombier int type, n;
110368c31abSDavid du Colombier uchar score[VtScoreSize], buf[4];
111368c31abSDavid du Colombier
112368c31abSDavid du Colombier p = *pkt;
113368c31abSDavid du Colombier if(!packetConsume(p, score, VtScoreSize))
114368c31abSDavid du Colombier return 0;
115368c31abSDavid du Colombier if(!packetConsume(p, buf, 4))
116368c31abSDavid du Colombier return 0;
117368c31abSDavid du Colombier type = buf[0];
118368c31abSDavid du Colombier n = (buf[2]<<8) | buf[3];
119368c31abSDavid du Colombier if(packetSize(p) != 0) {
120368c31abSDavid du Colombier vtSetError(EProtocolBotch);
121368c31abSDavid du Colombier return 0;
122368c31abSDavid du Colombier }
123368c31abSDavid du Colombier packetFree(p);
124368c31abSDavid du Colombier *pkt = (*z->vtbl->read)(z, score, type, n);
125368c31abSDavid du Colombier return 1;
126368c31abSDavid du Colombier }
127368c31abSDavid du Colombier
128368c31abSDavid du Colombier static int
dispatchWrite(VtSession * z,Packet ** pkt)129368c31abSDavid du Colombier dispatchWrite(VtSession *z, Packet **pkt)
130368c31abSDavid du Colombier {
131368c31abSDavid du Colombier Packet *p;
132368c31abSDavid du Colombier int type;
133368c31abSDavid du Colombier uchar score[VtScoreSize], buf[4];
134368c31abSDavid du Colombier
135368c31abSDavid du Colombier p = *pkt;
136368c31abSDavid du Colombier if(!packetConsume(p, buf, 4))
137368c31abSDavid du Colombier return 0;
138368c31abSDavid du Colombier type = buf[0];
139368c31abSDavid du Colombier if(!(z->vtbl->write)(z, score, type, p)) {
140368c31abSDavid du Colombier *pkt = 0;
141368c31abSDavid du Colombier } else {
142368c31abSDavid du Colombier *pkt = packetAlloc();
143368c31abSDavid du Colombier packetAppend(*pkt, score, VtScoreSize);
144368c31abSDavid du Colombier }
145368c31abSDavid du Colombier return 1;
146368c31abSDavid du Colombier }
147368c31abSDavid du Colombier
148368c31abSDavid du Colombier static int
dispatchSync(VtSession * z,Packet ** pkt)149368c31abSDavid du Colombier dispatchSync(VtSession *z, Packet **pkt)
150368c31abSDavid du Colombier {
151368c31abSDavid du Colombier (z->vtbl->sync)(z);
152368c31abSDavid du Colombier if(packetSize(*pkt) != 0) {
153368c31abSDavid du Colombier vtSetError(EProtocolBotch);
154368c31abSDavid du Colombier return 0;
155368c31abSDavid du Colombier }
156368c31abSDavid du Colombier return 1;
157368c31abSDavid du Colombier }
158368c31abSDavid du Colombier
159368c31abSDavid du Colombier int
vtExport(VtSession * z)160368c31abSDavid du Colombier vtExport(VtSession *z)
161368c31abSDavid du Colombier {
162368c31abSDavid du Colombier Packet *p;
163368c31abSDavid du Colombier uchar buf[10], *hdr;
164368c31abSDavid du Colombier int op, tid, clean;
165368c31abSDavid du Colombier
166368c31abSDavid du Colombier if(z->vtbl == nil) {
167368c31abSDavid du Colombier vtSetError(ENotServer);
168368c31abSDavid du Colombier return 0;
169368c31abSDavid du Colombier }
170368c31abSDavid du Colombier
171368c31abSDavid du Colombier /* fork off slave */
172368c31abSDavid du Colombier switch(rfork(RFNOWAIT|RFMEM|RFPROC)){
173368c31abSDavid du Colombier case -1:
174368c31abSDavid du Colombier vtOSError();
175368c31abSDavid du Colombier return 0;
176368c31abSDavid du Colombier case 0:
177368c31abSDavid du Colombier break;
178368c31abSDavid du Colombier default:
179368c31abSDavid du Colombier return 1;
180368c31abSDavid du Colombier }
181368c31abSDavid du Colombier
182368c31abSDavid du Colombier
183368c31abSDavid du Colombier p = nil;
184368c31abSDavid du Colombier clean = 0;
185368c31abSDavid du Colombier vtAttach();
186368c31abSDavid du Colombier if(!vtConnect(z, nil))
187368c31abSDavid du Colombier goto Exit;
188368c31abSDavid du Colombier
189368c31abSDavid du Colombier vtDebug(z, "server connected!\n");
190368c31abSDavid du Colombier if(0) vtSetDebug(z, 1);
191368c31abSDavid du Colombier
192368c31abSDavid du Colombier for(;;) {
193368c31abSDavid du Colombier p = vtRecvPacket(z);
194368c31abSDavid du Colombier if(p == nil) {
195368c31abSDavid du Colombier break;
196368c31abSDavid du Colombier }
197368c31abSDavid du Colombier vtDebug(z, "server recv: ");
198368c31abSDavid du Colombier vtDebugMesg(z, p, "\n");
199368c31abSDavid du Colombier
200368c31abSDavid du Colombier if(!packetConsume(p, buf, 2)) {
201368c31abSDavid du Colombier vtSetError(EProtocolBotch);
202368c31abSDavid du Colombier break;
203368c31abSDavid du Colombier }
204368c31abSDavid du Colombier op = buf[0];
205368c31abSDavid du Colombier tid = buf[1];
206368c31abSDavid du Colombier switch(op) {
207368c31abSDavid du Colombier default:
208368c31abSDavid du Colombier vtSetError(EProtocolBotch);
209368c31abSDavid du Colombier goto Exit;
210368c31abSDavid du Colombier case VtQPing:
211368c31abSDavid du Colombier break;
212368c31abSDavid du Colombier case VtQGoodbye:
213368c31abSDavid du Colombier clean = 1;
214368c31abSDavid du Colombier goto Exit;
215368c31abSDavid du Colombier case VtQHello:
216368c31abSDavid du Colombier if(!dispatchHello(z, &p))
217368c31abSDavid du Colombier goto Exit;
218368c31abSDavid du Colombier break;
219368c31abSDavid du Colombier case VtQRead:
220368c31abSDavid du Colombier if(!dispatchRead(z, &p))
221368c31abSDavid du Colombier goto Exit;
222368c31abSDavid du Colombier break;
223368c31abSDavid du Colombier case VtQWrite:
224368c31abSDavid du Colombier if(!dispatchWrite(z, &p))
225368c31abSDavid du Colombier goto Exit;
226368c31abSDavid du Colombier break;
227368c31abSDavid du Colombier case VtQSync:
228368c31abSDavid du Colombier if(!dispatchSync(z, &p))
229368c31abSDavid du Colombier goto Exit;
230368c31abSDavid du Colombier break;
231368c31abSDavid du Colombier }
232368c31abSDavid du Colombier if(p != nil) {
233368c31abSDavid du Colombier hdr = packetHeader(p, 2);
234368c31abSDavid du Colombier hdr[0] = op+1;
235368c31abSDavid du Colombier hdr[1] = tid;
236368c31abSDavid du Colombier } else {
237368c31abSDavid du Colombier p = packetAlloc();
238368c31abSDavid du Colombier hdr = packetHeader(p, 2);
239368c31abSDavid du Colombier hdr[0] = VtRError;
240368c31abSDavid du Colombier hdr[1] = tid;
241368c31abSDavid du Colombier if(!vtAddString(p, vtGetError()))
242368c31abSDavid du Colombier goto Exit;
243368c31abSDavid du Colombier }
244368c31abSDavid du Colombier
245368c31abSDavid du Colombier vtDebug(z, "server send: ");
246368c31abSDavid du Colombier vtDebugMesg(z, p, "\n");
247368c31abSDavid du Colombier
248368c31abSDavid du Colombier if(!vtSendPacket(z, p)) {
249368c31abSDavid du Colombier p = nil;
250368c31abSDavid du Colombier goto Exit;
251368c31abSDavid du Colombier }
252368c31abSDavid du Colombier }
253368c31abSDavid du Colombier Exit:
254368c31abSDavid du Colombier if(p != nil)
255368c31abSDavid du Colombier packetFree(p);
256368c31abSDavid du Colombier if(z->vtbl->closing)
257368c31abSDavid du Colombier z->vtbl->closing(z, clean);
258368c31abSDavid du Colombier vtClose(z);
259368c31abSDavid du Colombier vtFree(z);
260368c31abSDavid du Colombier vtDetach();
261368c31abSDavid du Colombier
262368c31abSDavid du Colombier exits(0);
263368c31abSDavid du Colombier return 0; /* never gets here */
264368c31abSDavid du Colombier }
265368c31abSDavid du Colombier
266