8 * Sun RPC server; for now, no reply cache
11 static void sunrpcproc(void*);
12 static void sunrpcrequestthread(void*);
13 static void sunrpcreplythread(void*);
14 static void sunrpcforkthread(void*);
15 static SunProg *sunfindprog(SunSrv*, SunMsg*, SunRpc*, Channel**);
17 typedef struct Targ Targ;
29 srv = emalloc(sizeof(SunSrv));
31 srv->crequest = chancreate(sizeof(SunMsg*), 16);
32 srv->creply = chancreate(sizeof(SunMsg*), 16);
33 srv->cthread = chancreate(sizeof(Targ), 4);
35 proccreate(sunrpcproc, srv, SunStackSize);
40 sunsrvprog(SunSrv *srv, SunProg *prog, Channel *c)
42 if(srv->nprog%16 == 0){
43 srv->prog = erealloc(srv->prog, (srv->nprog+16)*sizeof(srv->prog[0]));
44 srv->cdispatch = erealloc(srv->cdispatch, (srv->nprog+16)*sizeof(srv->cdispatch[0]));
46 srv->prog[srv->nprog] = prog;
47 srv->cdispatch[srv->nprog] = c;
54 threadcreate(sunrpcreplythread, v, SunStackSize);
55 threadcreate(sunrpcrequestthread, v, SunStackSize);
56 threadcreate(sunrpcforkthread, v, SunStackSize);
61 sunrpcforkthread(void *v)
66 while(recv(srv->cthread, &t) == 1)
67 threadcreate(t.fn, t.arg, SunStackSize);
71 sunsrvthreadcreate(SunSrv *srv, void (*fn)(void*), void *arg)
77 send(srv->cthread, &t);
81 sunrpcrequestthread(void *v)
91 while((m = recvp(srv->crequest)) != nil){
92 /* could look up in cache here? */
94 if(srv->chatty) fprint(2, "sun msg %p count %d\n", m, m->count);
98 status = m->rpc.status;
99 if(sunrpcunpack(p, ep, &p, &m->rpc) != SunSuccess){
100 fprint(2, "in: %.*H unpack failed\n", m->count, m->data);
105 fprint(2, "in: %B\n", &m->rpc);
107 sunmsgreplyerror(m, status);
110 if(srv->alwaysreject){
112 fprint(2, "\trejecting\n");
113 sunmsgreplyerror(m, SunAuthTooWeak);
118 sunmsgreplyerror(m, SunGarbageArgs);
122 if((pg = sunfindprog(srv, m, &m->rpc, &c)) == nil){
123 /* sunfindprog sent error */
130 if((ok = suncallunpackalloc(pg, m->rpc.proc<<1, p, ep, &p, &m->call)) != SunSuccess){
131 sunmsgreplyerror(m, ok);
134 m->call->rpc = m->rpc;
137 fprint(2, "\t%C\n", m->call);
145 sunfindprog(SunSrv *srv, SunMsg *m, SunRpc *rpc, Channel **pc)
153 for(i=0; i<srv->nprog; i++){
155 if(pg->prog != rpc->prog)
157 if(pg->vers == rpc->vers){
158 *pc = srv->cdispatch[i];
161 /* right program, wrong version: record range */
169 fprint(2, "\tprogram %ud unavailable\n", rpc->prog);
170 sunmsgreplyerror(m, SunProgUnavail);
172 /* putting these in rpc is a botch */
176 fprint(2, "\tversion %ud unavailable; have %d-%d\n", rpc->vers, vlo, vhi);
177 sunmsgreplyerror(m, SunProgMismatch);
183 sunrpcreplythread(void *v)
188 while((m = recvp(srv->creply)) != nil){
189 /* could record in cache here? */
195 sunmsgreplyerror(SunMsg *m, SunStatus error)
200 m->rpc.status = error;
202 m->rpc.verf.flavor = SunAuthNone;
207 fprint(2, "out: %B\n", &m->rpc);
209 n = sunrpcsize(&m->rpc);
213 if(sunrpcpack(p, ep, &p, &m->rpc) < 0){
214 fprint(2, "sunrpcpack failed\n");
219 fprint(2, "sunmsgreplyerror: rpc sizes didn't work out\n");
226 sendp(m->srv->creply, m);
231 sunmsgreply(SunMsg *m, SunCall *c)
236 c->type = m->call->type+1;
238 c->rpc.prog = m->rpc.prog;
239 c->rpc.vers = m->rpc.vers;
240 c->rpc.proc = m->rpc.proc;
241 c->rpc.xid = m->rpc.xid;
244 fprint(2, "out: %B\n", &c->rpc);
245 fprint(2, "\t%C\n", c);
248 n1 = sunrpcsize(&c->rpc);
249 n2 = suncallsize(m->pg, c);
254 if(sunrpcpack(p, ep, &p, &c->rpc) != SunSuccess){
255 fprint(2, "sunrpcpack failed\n");
256 return sunmsgdrop(m);
258 if(suncallpack(m->pg, p, ep, &p, c) != SunSuccess){
259 fprint(2, "pg->pack failed\n");
260 return sunmsgdrop(m);
263 fprint(2, "sunmsgreply: sizes didn't work out\n");
264 return sunmsgdrop(m);
270 sendp(m->srv->creply, m);
275 sunmsgdrop(SunMsg *m)
279 memset(m, 0xFB, sizeof *m);