Blame


1 551445b9 2004-04-21 devnull #include <u.h>
2 551445b9 2004-04-21 devnull #include <libc.h>
3 4c06b8ee 2005-05-19 devnull #include <ip.h>
4 551445b9 2004-04-21 devnull #include <thread.h>
5 551445b9 2004-04-21 devnull #include <sunrpc.h>
6 551445b9 2004-04-21 devnull
7 551445b9 2004-04-21 devnull /*
8 551445b9 2004-04-21 devnull * Sun RPC server; for now, no reply cache
9 551445b9 2004-04-21 devnull */
10 551445b9 2004-04-21 devnull
11 551445b9 2004-04-21 devnull static void sunrpcproc(void*);
12 551445b9 2004-04-21 devnull static void sunrpcrequestthread(void*);
13 551445b9 2004-04-21 devnull static void sunrpcreplythread(void*);
14 551445b9 2004-04-21 devnull static void sunrpcforkthread(void*);
15 551445b9 2004-04-21 devnull static SunProg *sunfindprog(SunSrv*, SunMsg*, SunRpc*, Channel**);
16 551445b9 2004-04-21 devnull
17 551445b9 2004-04-21 devnull typedef struct Targ Targ;
18 551445b9 2004-04-21 devnull struct Targ
19 551445b9 2004-04-21 devnull {
20 551445b9 2004-04-21 devnull void (*fn)(void*);
21 551445b9 2004-04-21 devnull void *arg;
22 551445b9 2004-04-21 devnull };
23 551445b9 2004-04-21 devnull
24 551445b9 2004-04-21 devnull SunSrv*
25 551445b9 2004-04-21 devnull sunsrv(void)
26 551445b9 2004-04-21 devnull {
27 551445b9 2004-04-21 devnull SunSrv *srv;
28 551445b9 2004-04-21 devnull
29 551445b9 2004-04-21 devnull srv = emalloc(sizeof(SunSrv));
30 551445b9 2004-04-21 devnull srv->chatty = 0;
31 551445b9 2004-04-21 devnull srv->crequest = chancreate(sizeof(SunMsg*), 16);
32 551445b9 2004-04-21 devnull srv->creply = chancreate(sizeof(SunMsg*), 16);
33 551445b9 2004-04-21 devnull srv->cthread = chancreate(sizeof(Targ), 4);
34 551445b9 2004-04-21 devnull
35 551445b9 2004-04-21 devnull proccreate(sunrpcproc, srv, SunStackSize);
36 551445b9 2004-04-21 devnull return srv;
37 551445b9 2004-04-21 devnull }
38 551445b9 2004-04-21 devnull
39 551445b9 2004-04-21 devnull void
40 551445b9 2004-04-21 devnull sunsrvprog(SunSrv *srv, SunProg *prog, Channel *c)
41 551445b9 2004-04-21 devnull {
42 551445b9 2004-04-21 devnull if(srv->nprog%16 == 0){
43 551445b9 2004-04-21 devnull srv->prog = erealloc(srv->prog, (srv->nprog+16)*sizeof(srv->prog[0]));
44 551445b9 2004-04-21 devnull srv->cdispatch = erealloc(srv->cdispatch, (srv->nprog+16)*sizeof(srv->cdispatch[0]));
45 551445b9 2004-04-21 devnull }
46 551445b9 2004-04-21 devnull srv->prog[srv->nprog] = prog;
47 551445b9 2004-04-21 devnull srv->cdispatch[srv->nprog] = c;
48 551445b9 2004-04-21 devnull srv->nprog++;
49 551445b9 2004-04-21 devnull }
50 551445b9 2004-04-21 devnull
51 551445b9 2004-04-21 devnull static void
52 551445b9 2004-04-21 devnull sunrpcproc(void *v)
53 551445b9 2004-04-21 devnull {
54 551445b9 2004-04-21 devnull threadcreate(sunrpcreplythread, v, SunStackSize);
55 551445b9 2004-04-21 devnull threadcreate(sunrpcrequestthread, v, SunStackSize);
56 551445b9 2004-04-21 devnull threadcreate(sunrpcforkthread, v, SunStackSize);
57 551445b9 2004-04-21 devnull
58 551445b9 2004-04-21 devnull }
59 551445b9 2004-04-21 devnull
60 551445b9 2004-04-21 devnull static void
61 551445b9 2004-04-21 devnull sunrpcforkthread(void *v)
62 551445b9 2004-04-21 devnull {
63 551445b9 2004-04-21 devnull SunSrv *srv = v;
64 551445b9 2004-04-21 devnull Targ t;
65 551445b9 2004-04-21 devnull
66 551445b9 2004-04-21 devnull while(recv(srv->cthread, &t) == 1)
67 551445b9 2004-04-21 devnull threadcreate(t.fn, t.arg, SunStackSize);
68 551445b9 2004-04-21 devnull }
69 551445b9 2004-04-21 devnull
70 551445b9 2004-04-21 devnull void
71 551445b9 2004-04-21 devnull sunsrvthreadcreate(SunSrv *srv, void (*fn)(void*), void *arg)
72 551445b9 2004-04-21 devnull {
73 551445b9 2004-04-21 devnull Targ t;
74 551445b9 2004-04-21 devnull
75 551445b9 2004-04-21 devnull t.fn = fn;
76 551445b9 2004-04-21 devnull t.arg = arg;
77 551445b9 2004-04-21 devnull send(srv->cthread, &t);
78 551445b9 2004-04-21 devnull }
79 551445b9 2004-04-21 devnull
80 551445b9 2004-04-21 devnull static void
81 551445b9 2004-04-21 devnull sunrpcrequestthread(void *v)
82 551445b9 2004-04-21 devnull {
83 4c06b8ee 2005-05-19 devnull int status;
84 551445b9 2004-04-21 devnull uchar *p, *ep;
85 551445b9 2004-04-21 devnull Channel *c;
86 551445b9 2004-04-21 devnull SunSrv *srv = v;
87 551445b9 2004-04-21 devnull SunMsg *m;
88 551445b9 2004-04-21 devnull SunProg *pg;
89 551445b9 2004-04-21 devnull SunStatus ok;
90 551445b9 2004-04-21 devnull
91 551445b9 2004-04-21 devnull while((m = recvp(srv->crequest)) != nil){
92 551445b9 2004-04-21 devnull /* could look up in cache here? */
93 551445b9 2004-04-21 devnull
94 551445b9 2004-04-21 devnull if(srv->chatty) fprint(2, "sun msg %p count %d\n", m, m->count);
95 551445b9 2004-04-21 devnull m->srv = srv;
96 551445b9 2004-04-21 devnull p = m->data;
97 551445b9 2004-04-21 devnull ep = p+m->count;
98 4c06b8ee 2005-05-19 devnull status = m->rpc.status;
99 551445b9 2004-04-21 devnull if(sunrpcunpack(p, ep, &p, &m->rpc) != SunSuccess){
100 551445b9 2004-04-21 devnull fprint(2, "in: %.*H unpack failed\n", m->count, m->data);
101 551445b9 2004-04-21 devnull sunmsgdrop(m);
102 551445b9 2004-04-21 devnull continue;
103 551445b9 2004-04-21 devnull }
104 551445b9 2004-04-21 devnull if(srv->chatty)
105 551445b9 2004-04-21 devnull fprint(2, "in: %B\n", &m->rpc);
106 4c06b8ee 2005-05-19 devnull if(status){
107 4c06b8ee 2005-05-19 devnull sunmsgreplyerror(m, status);
108 4c06b8ee 2005-05-19 devnull continue;
109 4c06b8ee 2005-05-19 devnull }
110 551445b9 2004-04-21 devnull if(srv->alwaysreject){
111 551445b9 2004-04-21 devnull if(srv->chatty)
112 551445b9 2004-04-21 devnull fprint(2, "\trejecting\n");
113 551445b9 2004-04-21 devnull sunmsgreplyerror(m, SunAuthTooWeak);
114 551445b9 2004-04-21 devnull continue;
115 551445b9 2004-04-21 devnull }
116 551445b9 2004-04-21 devnull
117 551445b9 2004-04-21 devnull if(!m->rpc.iscall){
118 551445b9 2004-04-21 devnull sunmsgreplyerror(m, SunGarbageArgs);
119 551445b9 2004-04-21 devnull continue;
120 551445b9 2004-04-21 devnull }
121 551445b9 2004-04-21 devnull
122 551445b9 2004-04-21 devnull if((pg = sunfindprog(srv, m, &m->rpc, &c)) == nil){
123 551445b9 2004-04-21 devnull /* sunfindprog sent error */
124 551445b9 2004-04-21 devnull continue;
125 551445b9 2004-04-21 devnull }
126 551445b9 2004-04-21 devnull
127 551445b9 2004-04-21 devnull p = m->rpc.data;
128 551445b9 2004-04-21 devnull ep = p+m->rpc.ndata;
129 551445b9 2004-04-21 devnull m->call = nil;
130 551445b9 2004-04-21 devnull if((ok = suncallunpackalloc(pg, m->rpc.proc<<1, p, ep, &p, &m->call)) != SunSuccess){
131 551445b9 2004-04-21 devnull sunmsgreplyerror(m, ok);
132 551445b9 2004-04-21 devnull continue;
133 551445b9 2004-04-21 devnull }
134 551445b9 2004-04-21 devnull m->call->rpc = m->rpc;
135 551445b9 2004-04-21 devnull
136 551445b9 2004-04-21 devnull if(srv->chatty)
137 551445b9 2004-04-21 devnull fprint(2, "\t%C\n", m->call);
138 551445b9 2004-04-21 devnull
139 551445b9 2004-04-21 devnull m->pg = pg;
140 551445b9 2004-04-21 devnull sendp(c, m);
141 551445b9 2004-04-21 devnull }
142 551445b9 2004-04-21 devnull }
143 551445b9 2004-04-21 devnull
144 551445b9 2004-04-21 devnull static SunProg*
145 551445b9 2004-04-21 devnull sunfindprog(SunSrv *srv, SunMsg *m, SunRpc *rpc, Channel **pc)
146 551445b9 2004-04-21 devnull {
147 886a6f6c 2006-05-04 devnull int i, vlo, vhi, any;
148 551445b9 2004-04-21 devnull SunProg *pg;
149 551445b9 2004-04-21 devnull
150 886a6f6c 2006-05-04 devnull vlo = 0;
151 886a6f6c 2006-05-04 devnull vhi = 0;
152 886a6f6c 2006-05-04 devnull any = 0;
153 551445b9 2004-04-21 devnull
154 551445b9 2004-04-21 devnull for(i=0; i<srv->nprog; i++){
155 551445b9 2004-04-21 devnull pg = srv->prog[i];
156 551445b9 2004-04-21 devnull if(pg->prog != rpc->prog)
157 551445b9 2004-04-21 devnull continue;
158 551445b9 2004-04-21 devnull if(pg->vers == rpc->vers){
159 551445b9 2004-04-21 devnull *pc = srv->cdispatch[i];
160 551445b9 2004-04-21 devnull return pg;
161 551445b9 2004-04-21 devnull }
162 551445b9 2004-04-21 devnull /* right program, wrong version: record range */
163 886a6f6c 2006-05-04 devnull if(!any++){
164 551445b9 2004-04-21 devnull vlo = pg->vers;
165 551445b9 2004-04-21 devnull vhi = pg->vers;
166 886a6f6c 2006-05-04 devnull }else{
167 886a6f6c 2006-05-04 devnull if(pg->vers < vlo)
168 886a6f6c 2006-05-04 devnull vlo = pg->vers;
169 886a6f6c 2006-05-04 devnull if(pg->vers > vhi)
170 886a6f6c 2006-05-04 devnull vhi = pg->vers;
171 886a6f6c 2006-05-04 devnull }
172 551445b9 2004-04-21 devnull }
173 551445b9 2004-04-21 devnull if(vhi == -1){
174 551445b9 2004-04-21 devnull if(srv->chatty)
175 551445b9 2004-04-21 devnull fprint(2, "\tprogram %ud unavailable\n", rpc->prog);
176 551445b9 2004-04-21 devnull sunmsgreplyerror(m, SunProgUnavail);
177 551445b9 2004-04-21 devnull }else{
178 551445b9 2004-04-21 devnull /* putting these in rpc is a botch */
179 551445b9 2004-04-21 devnull rpc->low = vlo;
180 551445b9 2004-04-21 devnull rpc->high = vhi;
181 551445b9 2004-04-21 devnull if(srv->chatty)
182 551445b9 2004-04-21 devnull fprint(2, "\tversion %ud unavailable; have %d-%d\n", rpc->vers, vlo, vhi);
183 551445b9 2004-04-21 devnull sunmsgreplyerror(m, SunProgMismatch);
184 551445b9 2004-04-21 devnull }
185 551445b9 2004-04-21 devnull return nil;
186 551445b9 2004-04-21 devnull }
187 551445b9 2004-04-21 devnull
188 551445b9 2004-04-21 devnull static void
189 551445b9 2004-04-21 devnull sunrpcreplythread(void *v)
190 551445b9 2004-04-21 devnull {
191 551445b9 2004-04-21 devnull SunMsg *m;
192 551445b9 2004-04-21 devnull SunSrv *srv = v;
193 551445b9 2004-04-21 devnull
194 551445b9 2004-04-21 devnull while((m = recvp(srv->creply)) != nil){
195 551445b9 2004-04-21 devnull /* could record in cache here? */
196 551445b9 2004-04-21 devnull sendp(m->creply, m);
197 fa325e9b 2020-01-10 cross }
198 551445b9 2004-04-21 devnull }
199 551445b9 2004-04-21 devnull
200 551445b9 2004-04-21 devnull int
201 551445b9 2004-04-21 devnull sunmsgreplyerror(SunMsg *m, SunStatus error)
202 551445b9 2004-04-21 devnull {
203 551445b9 2004-04-21 devnull uchar *p, *bp, *ep;
204 551445b9 2004-04-21 devnull int n;
205 551445b9 2004-04-21 devnull
206 551445b9 2004-04-21 devnull m->rpc.status = error;
207 551445b9 2004-04-21 devnull m->rpc.iscall = 0;
208 551445b9 2004-04-21 devnull m->rpc.verf.flavor = SunAuthNone;
209 551445b9 2004-04-21 devnull m->rpc.data = nil;
210 551445b9 2004-04-21 devnull m->rpc.ndata = 0;
211 551445b9 2004-04-21 devnull
212 551445b9 2004-04-21 devnull if(m->srv->chatty)
213 551445b9 2004-04-21 devnull fprint(2, "out: %B\n", &m->rpc);
214 551445b9 2004-04-21 devnull
215 551445b9 2004-04-21 devnull n = sunrpcsize(&m->rpc);
216 551445b9 2004-04-21 devnull bp = emalloc(n);
217 551445b9 2004-04-21 devnull ep = bp+n;
218 551445b9 2004-04-21 devnull p = bp;
219 0cfb3760 2012-10-21 rsc if((int32)sunrpcpack(p, ep, &p, &m->rpc) < 0){
220 551445b9 2004-04-21 devnull fprint(2, "sunrpcpack failed\n");
221 551445b9 2004-04-21 devnull sunmsgdrop(m);
222 551445b9 2004-04-21 devnull return 0;
223 551445b9 2004-04-21 devnull }
224 551445b9 2004-04-21 devnull if(p != ep){
225 551445b9 2004-04-21 devnull fprint(2, "sunmsgreplyerror: rpc sizes didn't work out\n");
226 551445b9 2004-04-21 devnull sunmsgdrop(m);
227 551445b9 2004-04-21 devnull return 0;
228 551445b9 2004-04-21 devnull }
229 551445b9 2004-04-21 devnull free(m->data);
230 551445b9 2004-04-21 devnull m->data = bp;
231 551445b9 2004-04-21 devnull m->count = n;
232 551445b9 2004-04-21 devnull sendp(m->srv->creply, m);
233 551445b9 2004-04-21 devnull return 0;
234 551445b9 2004-04-21 devnull }
235 551445b9 2004-04-21 devnull
236 551445b9 2004-04-21 devnull int
237 551445b9 2004-04-21 devnull sunmsgreply(SunMsg *m, SunCall *c)
238 551445b9 2004-04-21 devnull {
239 551445b9 2004-04-21 devnull int n1, n2;
240 551445b9 2004-04-21 devnull uchar *bp, *p, *ep;
241 551445b9 2004-04-21 devnull
242 551445b9 2004-04-21 devnull c->type = m->call->type+1;
243 551445b9 2004-04-21 devnull c->rpc.iscall = 0;
244 551445b9 2004-04-21 devnull c->rpc.prog = m->rpc.prog;
245 551445b9 2004-04-21 devnull c->rpc.vers = m->rpc.vers;
246 551445b9 2004-04-21 devnull c->rpc.proc = m->rpc.proc;
247 551445b9 2004-04-21 devnull c->rpc.xid = m->rpc.xid;
248 551445b9 2004-04-21 devnull
249 551445b9 2004-04-21 devnull if(m->srv->chatty){
250 551445b9 2004-04-21 devnull fprint(2, "out: %B\n", &c->rpc);
251 551445b9 2004-04-21 devnull fprint(2, "\t%C\n", c);
252 551445b9 2004-04-21 devnull }
253 551445b9 2004-04-21 devnull
254 551445b9 2004-04-21 devnull n1 = sunrpcsize(&c->rpc);
255 551445b9 2004-04-21 devnull n2 = suncallsize(m->pg, c);
256 551445b9 2004-04-21 devnull
257 551445b9 2004-04-21 devnull bp = emalloc(n1+n2);
258 551445b9 2004-04-21 devnull ep = bp+n1+n2;
259 551445b9 2004-04-21 devnull p = bp;
260 551445b9 2004-04-21 devnull if(sunrpcpack(p, ep, &p, &c->rpc) != SunSuccess){
261 551445b9 2004-04-21 devnull fprint(2, "sunrpcpack failed\n");
262 551445b9 2004-04-21 devnull return sunmsgdrop(m);
263 551445b9 2004-04-21 devnull }
264 551445b9 2004-04-21 devnull if(suncallpack(m->pg, p, ep, &p, c) != SunSuccess){
265 551445b9 2004-04-21 devnull fprint(2, "pg->pack failed\n");
266 551445b9 2004-04-21 devnull return sunmsgdrop(m);
267 551445b9 2004-04-21 devnull }
268 551445b9 2004-04-21 devnull if(p != ep){
269 551445b9 2004-04-21 devnull fprint(2, "sunmsgreply: sizes didn't work out\n");
270 551445b9 2004-04-21 devnull return sunmsgdrop(m);
271 551445b9 2004-04-21 devnull }
272 551445b9 2004-04-21 devnull free(m->data);
273 551445b9 2004-04-21 devnull m->data = bp;
274 551445b9 2004-04-21 devnull m->count = n1+n2;
275 551445b9 2004-04-21 devnull
276 551445b9 2004-04-21 devnull sendp(m->srv->creply, m);
277 551445b9 2004-04-21 devnull return 0;
278 551445b9 2004-04-21 devnull }
279 551445b9 2004-04-21 devnull
280 551445b9 2004-04-21 devnull int
281 551445b9 2004-04-21 devnull sunmsgdrop(SunMsg *m)
282 551445b9 2004-04-21 devnull {
283 551445b9 2004-04-21 devnull free(m->data);
284 551445b9 2004-04-21 devnull free(m->call);
285 551445b9 2004-04-21 devnull memset(m, 0xFB, sizeof *m);
286 551445b9 2004-04-21 devnull free(m);
287 551445b9 2004-04-21 devnull return 0;
288 551445b9 2004-04-21 devnull }