1/*
2 * linux/net/sunrpc/svc.c
3 *
4 * High-level RPC service routines
5 *
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */
8
9#define __KERNEL_SYSCALLS__
10#include <linux/linkage.h>
11#include <linux/sched.h>
12#include <linux/errno.h>
13#include <linux/net.h>
14#include <linux/in.h>
15#include <linux/unistd.h>
16
17#include <linux/sunrpc/types.h>
18#include <linux/sunrpc/xdr.h>
19#include <linux/sunrpc/stats.h>
20#include <linux/sunrpc/svcsock.h>
21#include <linux/sunrpc/clnt.h>
22
23#define RPCDBG_FACILITY	RPCDBG_SVCDSP
24#define RPC_PARANOIA 1
25
26/*
27 * Create an RPC service
28 */
29struct svc_serv *
30svc_create(struct svc_program *prog, unsigned int bufsize, unsigned int xdrsize)
31{
32	struct svc_serv	*serv;
33
34	if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL)))
35		return NULL;
36
37	memset(serv, 0, sizeof(*serv));
38	serv->sv_program   = prog;
39	serv->sv_nrthreads = 1;
40	serv->sv_stats     = prog->pg_stats;
41	serv->sv_bufsz	   = bufsize? bufsize : 4096;
42	serv->sv_xdrsize   = xdrsize;
43	INIT_LIST_HEAD(&serv->sv_threads);
44	INIT_LIST_HEAD(&serv->sv_sockets);
45	INIT_LIST_HEAD(&serv->sv_tempsocks);
46	INIT_LIST_HEAD(&serv->sv_permsocks);
47	spin_lock_init(&serv->sv_lock);
48
49	serv->sv_name      = prog->pg_name;
50
51	/* Remove any stale portmap registrations */
52	svc_register(serv, 0, 0);
53
54	return serv;
55}
56
57/*
58 * Destroy an RPC service
59 */
60void
61svc_destroy(struct svc_serv *serv)
62{
63	struct svc_sock	*svsk;
64
65	dprintk("RPC: svc_destroy(%s, %d)\n",
66				serv->sv_program->pg_name,
67				serv->sv_nrthreads);
68
69	if (serv->sv_nrthreads) {
70		if (--(serv->sv_nrthreads) != 0) {
71			svc_sock_update_bufs(serv);
72			return;
73		}
74	} else
75		printk("svc_destroy: no threads for serv=%p!\n", serv);
76
77	while (!list_empty(&serv->sv_tempsocks)) {
78		svsk = list_entry(serv->sv_tempsocks.next,
79				  struct svc_sock,
80				  sk_list);
81		svc_delete_socket(svsk);
82	}
83	while (!list_empty(&serv->sv_permsocks)) {
84		svsk = list_entry(serv->sv_permsocks.next,
85				  struct svc_sock,
86				  sk_list);
87		svc_delete_socket(svsk);
88	}
89
90	/* Unregister service with the portmapper */
91	svc_register(serv, 0, 0);
92	kfree(serv);
93}
94
95/*
96 * Allocate an RPC server buffer
97 * Later versions may do nifty things by allocating multiple pages
98 * of memory directly and putting them into the bufp->iov.
99 */
100int
101svc_init_buffer(struct svc_buf *bufp, unsigned int size)
102{
103	if (!(bufp->area = (u32 *) kmalloc(size, GFP_KERNEL)))
104		return 0;
105	bufp->base   = bufp->area;
106	bufp->buf    = bufp->area;
107	bufp->len    = 0;
108	bufp->buflen = size >> 2;
109
110	bufp->iov[0].iov_base = bufp->area;
111	bufp->iov[0].iov_len  = size;
112	bufp->nriov = 1;
113
114	return 1;
115}
116
117/*
118 * Release an RPC server buffer
119 */
120void
121svc_release_buffer(struct svc_buf *bufp)
122{
123	kfree(bufp->area);
124	bufp->area = 0;
125}
126
127/*
128 * Create a server thread
129 */
130int
131svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
132{
133	struct svc_rqst	*rqstp;
134	int		error = -ENOMEM;
135
136	rqstp = kmalloc(sizeof(*rqstp), GFP_KERNEL);
137	if (!rqstp)
138		goto out;
139
140	memset(rqstp, 0, sizeof(*rqstp));
141	init_waitqueue_head(&rqstp->rq_wait);
142
143	if (!(rqstp->rq_argp = (u32 *) kmalloc(serv->sv_xdrsize, GFP_KERNEL))
144	 || !(rqstp->rq_resp = (u32 *) kmalloc(serv->sv_xdrsize, GFP_KERNEL))
145	 || !svc_init_buffer(&rqstp->rq_defbuf, serv->sv_bufsz))
146		goto out_thread;
147
148	serv->sv_nrthreads++;
149	rqstp->rq_server = serv;
150	error = kernel_thread((int (*)(void *)) func, rqstp, 0);
151	if (error < 0)
152		goto out_thread;
153	svc_sock_update_bufs(serv);
154	error = 0;
155out:
156	return error;
157
158out_thread:
159	svc_exit_thread(rqstp);
160	goto out;
161}
162
163/*
164 * Destroy an RPC server thread
165 */
166void
167svc_exit_thread(struct svc_rqst *rqstp)
168{
169	struct svc_serv	*serv = rqstp->rq_server;
170
171	svc_release_buffer(&rqstp->rq_defbuf);
172	if (rqstp->rq_resp)
173		kfree(rqstp->rq_resp);
174	if (rqstp->rq_argp)
175		kfree(rqstp->rq_argp);
176	kfree(rqstp);
177
178	/* Release the server */
179	if (serv)
180		svc_destroy(serv);
181}
182
183/*
184 * Register an RPC service with the local portmapper.
185 * To unregister a service, call this routine with
186 * proto and port == 0.
187 */
188int
189svc_register(struct svc_serv *serv, int proto, unsigned short port)
190{
191	struct svc_program	*progp;
192	unsigned long		flags;
193	int			i, error = 0, dummy;
194
195	progp = serv->sv_program;
196
197	dprintk("RPC: svc_register(%s, %s, %d)\n",
198		progp->pg_name, proto == IPPROTO_UDP? "udp" : "tcp", port);
199
200	if (!port)
201		current->sigpending = 0;
202
203	for (i = 0; i < progp->pg_nvers; i++) {
204		if (progp->pg_vers[i] == NULL)
205			continue;
206		error = rpc_register(progp->pg_prog, i, proto, port, &dummy);
207		if (error < 0)
208			break;
209		if (port && !dummy) {
210			error = -EACCES;
211			break;
212		}
213	}
214
215	if (!port) {
216		spin_lock_irqsave(&current->sigmask_lock, flags);
217		recalc_sigpending(current);
218		spin_unlock_irqrestore(&current->sigmask_lock, flags);
219	}
220
221	return error;
222}
223
224/*
225 * Process the RPC request.
226 */
227int
228svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
229{
230	struct svc_program	*progp;
231	struct svc_version	*versp = NULL;	/* compiler food */
232	struct svc_procedure	*procp = NULL;
233	struct svc_buf *	argp = &rqstp->rq_argbuf;
234	struct svc_buf *	resp = &rqstp->rq_resbuf;
235	kxdrproc_t		xdr;
236	u32			*bufp, *statp;
237	u32			dir, prog, vers, proc,
238				auth_stat, rpc_stat;
239
240	rpc_stat = rpc_success;
241	bufp = argp->buf;
242
243	if (argp->len < 5)
244		goto err_short_len;
245
246	dir  = ntohl(*bufp++);
247	vers = ntohl(*bufp++);
248
249	/* First words of reply: */
250	svc_putlong(resp, xdr_one);		/* REPLY */
251	svc_putlong(resp, xdr_zero);		/* ACCEPT */
252
253	if (dir != 0)		/* direction != CALL */
254		goto err_bad_dir;
255	if (vers != 2)		/* RPC version number */
256		goto err_bad_rpc;
257
258	rqstp->rq_prog = prog = ntohl(*bufp++);	/* program number */
259	rqstp->rq_vers = vers = ntohl(*bufp++);	/* version number */
260	rqstp->rq_proc = proc = ntohl(*bufp++);	/* procedure number */
261
262	argp->buf += 5;
263	argp->len -= 5;
264
265	/* Used by nfsd to only allow the NULL procedure for amd. */
266	if (rqstp->rq_auth && !rqstp->rq_client && proc) {
267		auth_stat = rpc_autherr_badcred;
268		goto err_bad_auth;
269	}
270
271	/*
272	 * Decode auth data, and add verifier to reply buffer.
273	 * We do this before anything else in order to get a decent
274	 * auth verifier.
275	 */
276	svc_authenticate(rqstp, &rpc_stat, &auth_stat);
277
278	if (rpc_stat != rpc_success)
279		goto err_garbage;
280
281	if (auth_stat != rpc_auth_ok)
282		goto err_bad_auth;
283
284	progp = serv->sv_program;
285	if (prog != progp->pg_prog)
286		goto err_bad_prog;
287
288	if (vers >= progp->pg_nvers ||
289	  !(versp = progp->pg_vers[vers]))
290		goto err_bad_vers;
291
292	procp = versp->vs_proc + proc;
293	if (proc >= versp->vs_nproc || !procp->pc_func)
294		goto err_bad_proc;
295	rqstp->rq_server   = serv;
296	rqstp->rq_procinfo = procp;
297
298	/* Syntactic check complete */
299	serv->sv_stats->rpccnt++;
300
301	/* Build the reply header. */
302	statp = resp->buf;
303	svc_putlong(resp, rpc_success);		/* RPC_SUCCESS */
304
305	/* Bump per-procedure stats counter */
306	procp->pc_count++;
307
308	/* Initialize storage for argp and resp */
309	memset(rqstp->rq_argp, 0, procp->pc_argsize);
310	memset(rqstp->rq_resp, 0, procp->pc_ressize);
311
312	/* un-reserve some of the out-queue now that we have a
313	 * better idea of reply size
314	 */
315	if (procp->pc_xdrressize)
316		svc_reserve(rqstp, procp->pc_xdrressize<<2);
317
318	/* Call the function that processes the request. */
319	if (!versp->vs_dispatch) {
320		/* Decode arguments */
321		xdr = procp->pc_decode;
322		if (xdr && !xdr(rqstp, rqstp->rq_argbuf.buf, rqstp->rq_argp))
323			goto err_garbage;
324
325		*statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
326
327		/* Encode reply */
328		if (*statp == rpc_success && (xdr = procp->pc_encode)
329		 && !xdr(rqstp, rqstp->rq_resbuf.buf, rqstp->rq_resp)) {
330			dprintk("svc: failed to encode reply\n");
331			/* serv->sv_stats->rpcsystemerr++; */
332			*statp = rpc_system_err;
333		}
334	} else {
335		dprintk("svc: calling dispatcher\n");
336		if (!versp->vs_dispatch(rqstp, statp))
337			goto dropit;
338	}
339
340	/* Check RPC status result */
341	if (*statp != rpc_success)
342		resp->len = statp + 1 - resp->base;
343
344	/* Release reply info */
345	if (procp->pc_release)
346		procp->pc_release(rqstp, NULL, rqstp->rq_resp);
347
348	if (procp->pc_encode == NULL)
349		goto dropit;
350sendit:
351	return svc_send(rqstp);
352
353dropit:
354	dprintk("svc: svc_process dropit\n");
355	svc_drop(rqstp);
356	return 0;
357
358err_short_len:
359#ifdef RPC_PARANOIA
360	printk("svc: short len %d, dropping request\n", argp->len);
361#endif
362	goto dropit;			/* drop request */
363
364err_bad_dir:
365#ifdef RPC_PARANOIA
366	printk("svc: bad direction %d, dropping request\n", dir);
367#endif
368	serv->sv_stats->rpcbadfmt++;
369	goto dropit;			/* drop request */
370
371err_bad_rpc:
372	serv->sv_stats->rpcbadfmt++;
373	resp->buf[-1] = xdr_one;	/* REJECT */
374	svc_putlong(resp, xdr_zero);	/* RPC_MISMATCH */
375	svc_putlong(resp, xdr_two);	/* Only RPCv2 supported */
376	svc_putlong(resp, xdr_two);
377	goto sendit;
378
379err_bad_auth:
380	dprintk("svc: authentication failed (%d)\n", ntohl(auth_stat));
381	serv->sv_stats->rpcbadauth++;
382	resp->buf[-1] = xdr_one;	/* REJECT */
383	svc_putlong(resp, xdr_one);	/* AUTH_ERROR */
384	svc_putlong(resp, auth_stat);	/* status */
385	goto sendit;
386
387err_bad_prog:
388#ifdef RPC_PARANOIA
389	if (prog != 100227 || progp->pg_prog != 100003)
390		printk("svc: unknown program %d (me %d)\n", prog, progp->pg_prog);
391	/* else it is just a Solaris client seeing if ACLs are supported */
392#endif
393	serv->sv_stats->rpcbadfmt++;
394	svc_putlong(resp, rpc_prog_unavail);
395	goto sendit;
396
397err_bad_vers:
398#ifdef RPC_PARANOIA
399	printk("svc: unknown version (%d)\n", vers);
400#endif
401	serv->sv_stats->rpcbadfmt++;
402	svc_putlong(resp, rpc_prog_mismatch);
403	svc_putlong(resp, htonl(progp->pg_lovers));
404	svc_putlong(resp, htonl(progp->pg_hivers));
405	goto sendit;
406
407err_bad_proc:
408#ifdef RPC_PARANOIA
409	printk("svc: unknown procedure (%d)\n", proc);
410#endif
411	serv->sv_stats->rpcbadfmt++;
412	svc_putlong(resp, rpc_proc_unavail);
413	goto sendit;
414
415err_garbage:
416#ifdef RPC_PARANOIA
417	printk("svc: failed to decode args\n");
418#endif
419	serv->sv_stats->rpcbadfmt++;
420	svc_putlong(resp, rpc_garbage_args);
421	goto sendit;
422}
423