cleanup spec
[platform/upstream/glibc.git] / sunrpc / clnt_raw.c
1 /*
2  * clnt_raw.c
3  *
4  * Copyright (c) 2010, Oracle America, Inc.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above
13  *       copyright notice, this list of conditions and the following
14  *       disclaimer in the documentation and/or other materials
15  *       provided with the distribution.
16  *     * Neither the name of the "Oracle America, Inc." nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Memory based rpc for simple testing and timing.
34  * Interface to create an rpc client and server in the same process.
35  * This lets us simulate rpc and get round trip overhead, without
36  * any interference from the kernel.
37  */
38
39 #include <rpc/rpc.h>
40 #include <rpc/svc.h>
41 #include <rpc/xdr.h>
42 #include <libintl.h>
43
44 #define MCALL_MSG_SIZE 24
45
46 /*
47  * This is the "network" we will be moving stuff over.
48  */
49 struct clntraw_private_s
50   {
51     CLIENT client_object;
52     XDR xdr_stream;
53     char _raw_buf[UDPMSGSIZE];
54     union
55     {
56       char msg[MCALL_MSG_SIZE];
57       u_long rm_xid;
58     } mashl_callmsg;
59     u_int mcnt;
60   };
61 #ifdef _RPC_THREAD_SAFE_
62 #define clntraw_private RPC_THREAD_VARIABLE(clntraw_private_s)
63 #else
64 static struct clntraw_private_s *clntraw_private;
65 #endif
66
67 static enum clnt_stat clntraw_call (CLIENT *, u_long, xdrproc_t, caddr_t,
68                                     xdrproc_t, caddr_t, struct timeval);
69 static void clntraw_abort (void);
70 static void clntraw_geterr (CLIENT *, struct rpc_err *);
71 static bool_t clntraw_freeres (CLIENT *, xdrproc_t, caddr_t);
72 static bool_t clntraw_control (CLIENT *, int, char *);
73 static void clntraw_destroy (CLIENT *);
74
75 static const struct clnt_ops client_ops =
76 {
77   clntraw_call,
78   clntraw_abort,
79   clntraw_geterr,
80   clntraw_freeres,
81   clntraw_destroy,
82   clntraw_control
83 };
84
85 /*
86  * Create a client handle for memory based rpc.
87  */
88 CLIENT *
89 clntraw_create (u_long prog, u_long vers)
90 {
91   struct clntraw_private_s *clp = clntraw_private;
92   struct rpc_msg call_msg;
93   XDR *xdrs;
94   CLIENT *client;
95
96   if (clp == 0)
97     {
98       clp = (struct clntraw_private_s *) calloc (1, sizeof (*clp));
99       if (clp == 0)
100         return (0);
101       clntraw_private = clp;
102     }
103   xdrs = &clp->xdr_stream;
104   client = &clp->client_object;
105   /*
106    * pre-serialize the static part of the call msg and stash it away
107    */
108   call_msg.rm_direction = CALL;
109   call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
110   call_msg.rm_call.cb_prog = prog;
111   call_msg.rm_call.cb_vers = vers;
112   xdrmem_create (xdrs, clp->mashl_callmsg.msg, MCALL_MSG_SIZE, XDR_ENCODE);
113   if (!xdr_callhdr (xdrs, &call_msg))
114     {
115       perror (_ ("clnt_raw.c: fatal header serialization error"));
116     }
117   clp->mcnt = XDR_GETPOS (xdrs);
118   XDR_DESTROY (xdrs);
119
120   /*
121    * Set xdrmem for client/server shared buffer
122    */
123   xdrmem_create (xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
124
125   /*
126    * create client handle
127    */
128   client->cl_ops = (struct clnt_ops *) &client_ops;
129   client->cl_auth = authnone_create ();
130   return client;
131 }
132 libc_hidden_nolink_sunrpc (clntraw_create, GLIBC_2_0)
133
134 static enum clnt_stat
135 clntraw_call (h, proc, xargs, argsp, xresults, resultsp, timeout)
136      CLIENT *h;
137      u_long proc;
138      xdrproc_t xargs;
139      caddr_t argsp;
140      xdrproc_t xresults;
141      caddr_t resultsp;
142      struct timeval timeout;
143 {
144   struct clntraw_private_s *clp = clntraw_private;
145   XDR *xdrs = &clp->xdr_stream;
146   struct rpc_msg msg;
147   enum clnt_stat status;
148   struct rpc_err error;
149
150   if (clp == NULL)
151     return RPC_FAILED;
152 call_again:
153   /*
154    * send request
155    */
156   xdrs->x_op = XDR_ENCODE;
157   XDR_SETPOS (xdrs, 0);
158   /* Just checking the union definition to access rm_xid is correct.  */
159   if (offsetof (struct rpc_msg, rm_xid) != 0)
160     abort ();
161   clp->mashl_callmsg.rm_xid++;
162   if ((!XDR_PUTBYTES (xdrs, clp->mashl_callmsg.msg, clp->mcnt)) ||
163       (!XDR_PUTLONG (xdrs, (long *) &proc)) ||
164       (!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
165       (!(*xargs) (xdrs, argsp)))
166     {
167       return (RPC_CANTENCODEARGS);
168     }
169   (void) XDR_GETPOS (xdrs);     /* called just to cause overhead */
170
171   /*
172    * We have to call server input routine here because this is
173    * all going on in one process. Yuk.
174    */
175   svc_getreq (1);
176
177   /*
178    * get results
179    */
180   xdrs->x_op = XDR_DECODE;
181   XDR_SETPOS (xdrs, 0);
182   msg.acpted_rply.ar_verf = _null_auth;
183   msg.acpted_rply.ar_results.where = resultsp;
184   msg.acpted_rply.ar_results.proc = xresults;
185   if (!xdr_replymsg (xdrs, &msg))
186     return RPC_CANTDECODERES;
187   _seterr_reply (&msg, &error);
188   status = error.re_status;
189
190   if (status == RPC_SUCCESS)
191     {
192       if (!AUTH_VALIDATE (h->cl_auth, &msg.acpted_rply.ar_verf))
193         {
194           status = RPC_AUTHERROR;
195         }
196     }                           /* end successful completion */
197   else
198     {
199       if (AUTH_REFRESH (h->cl_auth))
200         goto call_again;
201     }                           /* end of unsuccessful completion */
202
203   if (status == RPC_SUCCESS)
204     {
205       if (!AUTH_VALIDATE (h->cl_auth, &msg.acpted_rply.ar_verf))
206         {
207           status = RPC_AUTHERROR;
208         }
209       if (msg.acpted_rply.ar_verf.oa_base != NULL)
210         {
211           xdrs->x_op = XDR_FREE;
212           (void) xdr_opaque_auth (xdrs, &(msg.acpted_rply.ar_verf));
213         }
214     }
215
216   return status;
217 }
218
219 static void
220 clntraw_geterr (CLIENT *cl, struct rpc_err *err)
221 {
222 }
223
224
225 static bool_t
226 clntraw_freeres (cl, xdr_res, res_ptr)
227      CLIENT *cl;
228      xdrproc_t xdr_res;
229      caddr_t res_ptr;
230 {
231   struct clntraw_private_s *clp = clntraw_private;
232   XDR *xdrs = &clp->xdr_stream;
233   bool_t rval;
234
235   if (clp == NULL)
236     {
237       rval = (bool_t) RPC_FAILED;
238       return rval;
239     }
240   xdrs->x_op = XDR_FREE;
241   return (*xdr_res) (xdrs, res_ptr);
242 }
243
244 static void
245 clntraw_abort (void)
246 {
247 }
248
249 static bool_t
250 clntraw_control (CLIENT *cl, int i, char *c)
251 {
252   return FALSE;
253 }
254
255 static void
256 clntraw_destroy (CLIENT *cl)
257 {
258 }