Localize rpcgen
[platform/upstream/glibc.git] / sunrpc / clnt_tcp.c
1 /*
2  * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
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  * TCP based RPC supports 'batched calls'.
34  * A sequence of calls may be batched-up in a send buffer.  The rpc call
35  * return immediately to the client even though the call was not necessarily
36  * sent.  The batching occurs if the results' xdr routine is NULL (0) AND
37  * the rpc timeout value is zero (see clnt.h, rpc).
38  *
39  * Clients should NOT casually batch calls that in fact return results; that is,
40  * the server side should be aware that a call is batched and not produce any
41  * return message.  Batched calls that produce many result messages can
42  * deadlock (netlock) the client and the server....
43  *
44  * Now go hang yourself.
45  */
46
47 #include <netdb.h>
48 #include <errno.h>
49 #include <stdio.h>
50 #include <unistd.h>
51 #include <libintl.h>
52 #include <rpc/rpc.h>
53 #include <sys/poll.h>
54 #include <sys/socket.h>
55 #include <rpc/pmap_clnt.h>
56 #include <wchar.h>
57
58 extern u_long _create_xid (void);
59
60 #define MCALL_MSG_SIZE 24
61
62 struct ct_data
63   {
64     int ct_sock;
65     bool_t ct_closeit;
66     struct timeval ct_wait;
67     bool_t ct_waitset;          /* wait set by clnt_control? */
68     struct sockaddr_in ct_addr;
69     struct rpc_err ct_error;
70     char ct_mcall[MCALL_MSG_SIZE];      /* marshalled callmsg */
71     u_int ct_mpos;              /* pos after marshal */
72     XDR ct_xdrs;
73   };
74
75 static int readtcp (char *, char *, int);
76 static int writetcp (char *, char *, int);
77
78 static enum clnt_stat clnttcp_call (CLIENT *, u_long, xdrproc_t, caddr_t,
79                                     xdrproc_t, caddr_t, struct timeval);
80 static void clnttcp_abort (void);
81 static void clnttcp_geterr (CLIENT *, struct rpc_err *);
82 static bool_t clnttcp_freeres (CLIENT *, xdrproc_t, caddr_t);
83 static bool_t clnttcp_control (CLIENT *, int, char *);
84 static void clnttcp_destroy (CLIENT *);
85
86 static const struct clnt_ops tcp_ops =
87 {
88   clnttcp_call,
89   clnttcp_abort,
90   clnttcp_geterr,
91   clnttcp_freeres,
92   clnttcp_destroy,
93   clnttcp_control
94 };
95
96 /*
97  * Create a client handle for a tcp/ip connection.
98  * If *sockp<0, *sockp is set to a newly created TCP socket and it is
99  * connected to raddr.  If *sockp non-negative then
100  * raddr is ignored.  The rpc/tcp package does buffering
101  * similar to stdio, so the client must pick send and receive buffer sizes,];
102  * 0 => use the default.
103  * If raddr->sin_port is 0, then a binder on the remote machine is
104  * consulted for the right port number.
105  * NB: *sockp is copied into a private area.
106  * NB: It is the clients responsibility to close *sockp.
107  * NB: The rpch->cl_auth is set null authentication.  Caller may wish to set this
108  * something more useful.
109  */
110 CLIENT *
111 clnttcp_create (struct sockaddr_in *raddr, u_long prog, u_long vers,
112                 int *sockp, u_int sendsz, u_int recvsz)
113 {
114   CLIENT *h;
115   struct ct_data *ct;
116   struct rpc_msg call_msg;
117
118   h = (CLIENT *) mem_alloc (sizeof (*h));
119   ct = (struct ct_data *) mem_alloc (sizeof (*ct));
120   if (h == NULL || ct == NULL)
121     {
122       struct rpc_createerr *ce = &get_rpc_createerr ();
123       (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
124       ce->cf_stat = RPC_SYSTEMERROR;
125       ce->cf_error.re_errno = ENOMEM;
126       goto fooy;
127     }
128
129   /*
130    * If no port number given ask the pmap for one
131    */
132   if (raddr->sin_port == 0)
133     {
134       u_short port;
135       if ((port = pmap_getport (raddr, prog, vers, IPPROTO_TCP)) == 0)
136         {
137           mem_free ((caddr_t) ct, sizeof (struct ct_data));
138           mem_free ((caddr_t) h, sizeof (CLIENT));
139           return ((CLIENT *) NULL);
140         }
141       raddr->sin_port = htons (port);
142     }
143
144   /*
145    * If no socket given, open one
146    */
147   if (*sockp < 0)
148     {
149       *sockp = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
150       (void) bindresvport (*sockp, (struct sockaddr_in *) 0);
151       if ((*sockp < 0)
152           || (__connect (*sockp, (struct sockaddr *) raddr,
153                          sizeof (*raddr)) < 0))
154         {
155           struct rpc_createerr *ce = &get_rpc_createerr ();
156           ce->cf_stat = RPC_SYSTEMERROR;
157           ce->cf_error.re_errno = errno;
158           if (*sockp >= 0)
159             (void) __close (*sockp);
160           goto fooy;
161         }
162       ct->ct_closeit = TRUE;
163     }
164   else
165     {
166       ct->ct_closeit = FALSE;
167     }
168
169   /*
170    * Set up private data struct
171    */
172   ct->ct_sock = *sockp;
173   ct->ct_wait.tv_usec = 0;
174   ct->ct_waitset = FALSE;
175   ct->ct_addr = *raddr;
176
177   /*
178    * Initialize call message
179    */
180   call_msg.rm_xid = _create_xid ();
181   call_msg.rm_direction = CALL;
182   call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
183   call_msg.rm_call.cb_prog = prog;
184   call_msg.rm_call.cb_vers = vers;
185
186   /*
187    * pre-serialize the static part of the call msg and stash it away
188    */
189   xdrmem_create (&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, XDR_ENCODE);
190   if (!xdr_callhdr (&(ct->ct_xdrs), &call_msg))
191     {
192       if (ct->ct_closeit)
193         {
194           (void) __close (*sockp);
195         }
196       goto fooy;
197     }
198   ct->ct_mpos = XDR_GETPOS (&(ct->ct_xdrs));
199   XDR_DESTROY (&(ct->ct_xdrs));
200
201   /*
202    * Create a client handle which uses xdrrec for serialization
203    * and authnone for authentication.
204    */
205   xdrrec_create (&(ct->ct_xdrs), sendsz, recvsz,
206                  (caddr_t) ct, readtcp, writetcp);
207   h->cl_ops = (struct clnt_ops *) &tcp_ops;
208   h->cl_private = (caddr_t) ct;
209   h->cl_auth = authnone_create ();
210   return h;
211
212 fooy:
213   /*
214    * Something goofed, free stuff and barf
215    */
216   mem_free ((caddr_t) ct, sizeof (struct ct_data));
217   mem_free ((caddr_t) h, sizeof (CLIENT));
218   return ((CLIENT *) NULL);
219 }
220 #ifdef EXPORT_RPC_SYMBOLS
221 libc_hidden_def (clnttcp_create)
222 #else
223 libc_hidden_nolink_sunrpc (clnttcp_create, GLIBC_2_0)
224 #endif
225
226 static enum clnt_stat
227 clnttcp_call (h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
228      CLIENT *h;
229      u_long proc;
230      xdrproc_t xdr_args;
231      caddr_t args_ptr;
232      xdrproc_t xdr_results;
233      caddr_t results_ptr;
234      struct timeval timeout;
235 {
236   struct ct_data *ct = (struct ct_data *) h->cl_private;
237   XDR *xdrs = &(ct->ct_xdrs);
238   struct rpc_msg reply_msg;
239   u_long x_id;
240   u_int32_t *msg_x_id = (u_int32_t *) (ct->ct_mcall);   /* yuk */
241   bool_t shipnow;
242   int refreshes = 2;
243
244   if (!ct->ct_waitset)
245     {
246       ct->ct_wait = timeout;
247     }
248
249   shipnow =
250     (xdr_results == (xdrproc_t) 0 && ct->ct_wait.tv_sec == 0
251      && ct->ct_wait.tv_usec == 0) ? FALSE : TRUE;
252
253 call_again:
254   xdrs->x_op = XDR_ENCODE;
255   ct->ct_error.re_status = RPC_SUCCESS;
256   x_id = ntohl (--(*msg_x_id));
257   if ((!XDR_PUTBYTES (xdrs, ct->ct_mcall, ct->ct_mpos)) ||
258       (!XDR_PUTLONG (xdrs, (long *) &proc)) ||
259       (!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
260       (!(*xdr_args) (xdrs, args_ptr)))
261     {
262       if (ct->ct_error.re_status == RPC_SUCCESS)
263         ct->ct_error.re_status = RPC_CANTENCODEARGS;
264       (void) xdrrec_endofrecord (xdrs, TRUE);
265       return (ct->ct_error.re_status);
266     }
267   if (!xdrrec_endofrecord (xdrs, shipnow))
268     return ct->ct_error.re_status = RPC_CANTSEND;
269   if (!shipnow)
270     return RPC_SUCCESS;
271   /*
272    * Hack to provide rpc-based message passing
273    */
274   if (ct->ct_wait.tv_sec == 0 && ct->ct_wait.tv_usec == 0)
275     {
276       return ct->ct_error.re_status = RPC_TIMEDOUT;
277     }
278
279
280   /*
281    * Keep receiving until we get a valid transaction id
282    */
283   xdrs->x_op = XDR_DECODE;
284   while (TRUE)
285     {
286       reply_msg.acpted_rply.ar_verf = _null_auth;
287       reply_msg.acpted_rply.ar_results.where = NULL;
288       reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
289       if (!xdrrec_skiprecord (xdrs))
290         return (ct->ct_error.re_status);
291       /* now decode and validate the response header */
292       if (!xdr_replymsg (xdrs, &reply_msg))
293         {
294           if (ct->ct_error.re_status == RPC_SUCCESS)
295             continue;
296           return ct->ct_error.re_status;
297         }
298       if ((u_int32_t) reply_msg.rm_xid == (u_int32_t) x_id)
299         break;
300     }
301
302   /*
303    * process header
304    */
305   _seterr_reply (&reply_msg, &(ct->ct_error));
306   if (ct->ct_error.re_status == RPC_SUCCESS)
307     {
308       if (!AUTH_VALIDATE (h->cl_auth, &reply_msg.acpted_rply.ar_verf))
309         {
310           ct->ct_error.re_status = RPC_AUTHERROR;
311           ct->ct_error.re_why = AUTH_INVALIDRESP;
312         }
313       else if (!(*xdr_results) (xdrs, results_ptr))
314         {
315           if (ct->ct_error.re_status == RPC_SUCCESS)
316             ct->ct_error.re_status = RPC_CANTDECODERES;
317         }
318       /* free verifier ... */
319       if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
320         {
321           xdrs->x_op = XDR_FREE;
322           (void) xdr_opaque_auth (xdrs, &(reply_msg.acpted_rply.ar_verf));
323         }
324     }                           /* end successful completion */
325   else
326     {
327       /* maybe our credentials need to be refreshed ... */
328       if (refreshes-- && AUTH_REFRESH (h->cl_auth))
329         goto call_again;
330     }                           /* end of unsuccessful completion */
331   return ct->ct_error.re_status;
332 }
333
334 static void
335 clnttcp_geterr (h, errp)
336      CLIENT *h;
337      struct rpc_err *errp;
338 {
339   struct ct_data *ct =
340   (struct ct_data *) h->cl_private;
341
342   *errp = ct->ct_error;
343 }
344
345 static bool_t
346 clnttcp_freeres (cl, xdr_res, res_ptr)
347      CLIENT *cl;
348      xdrproc_t xdr_res;
349      caddr_t res_ptr;
350 {
351   struct ct_data *ct = (struct ct_data *) cl->cl_private;
352   XDR *xdrs = &(ct->ct_xdrs);
353
354   xdrs->x_op = XDR_FREE;
355   return (*xdr_res) (xdrs, res_ptr);
356 }
357
358 static void
359 clnttcp_abort ()
360 {
361 }
362
363 static bool_t
364 clnttcp_control (CLIENT *cl, int request, char *info)
365 {
366   struct ct_data *ct = (struct ct_data *) cl->cl_private;
367   u_long ul;
368   u_int32_t ui32;
369
370
371   switch (request)
372     {
373     case CLSET_FD_CLOSE:
374       ct->ct_closeit = TRUE;
375       break;
376     case CLSET_FD_NCLOSE:
377       ct->ct_closeit = FALSE;
378       break;
379     case CLSET_TIMEOUT:
380       ct->ct_wait = *(struct timeval *) info;
381       ct->ct_waitset = TRUE;
382       break;
383     case CLGET_TIMEOUT:
384       *(struct timeval *) info = ct->ct_wait;
385       break;
386     case CLGET_SERVER_ADDR:
387       *(struct sockaddr_in *) info = ct->ct_addr;
388       break;
389     case CLGET_FD:
390       *(int *)info = ct->ct_sock;
391       break;
392     case CLGET_XID:
393       /*
394        * use the knowledge that xid is the
395        * first element in the call structure *.
396        * This will get the xid of the PREVIOUS call
397        */
398       memcpy (&ui32, ct->ct_mcall, sizeof (ui32));
399       ul = ntohl (ui32);
400       memcpy (info, &ul, sizeof (ul));
401       break;
402     case CLSET_XID:
403       /* This will set the xid of the NEXT call */
404       memcpy (&ul, info, sizeof (ul));
405       ui32 = htonl (ul - 1);
406       memcpy (ct->ct_mcall, &ui32, sizeof (ui32));
407       /* decrement by 1 as clnttcp_call() increments once */
408       break;
409     case CLGET_VERS:
410       /*
411        * This RELIES on the information that, in the call body,
412        * the version number field is the fifth field from the
413        * begining of the RPC header. MUST be changed if the
414        * call_struct is changed
415        */
416       memcpy (&ui32, ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, sizeof (ui32));
417       ul = ntohl (ui32);
418       memcpy (info, &ul, sizeof (ul));
419       break;
420     case CLSET_VERS:
421       memcpy (&ul, info, sizeof (ul));
422       ui32 = htonl (ul);
423       memcpy (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
424       break;
425     case CLGET_PROG:
426       /*
427        * This RELIES on the information that, in the call body,
428        * the program number field is the  field from the
429        * begining of the RPC header. MUST be changed if the
430        * call_struct is changed
431        */
432       memcpy (&ui32, ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, sizeof (ui32));
433       ul = ntohl (ui32);
434       memcpy (info, &ul, sizeof (ul));
435       break;
436     case CLSET_PROG:
437       memcpy (&ul, info, sizeof (ul));
438       ui32 = htonl (ul);
439       memcpy (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
440       break;
441     /* The following are only possible with TI-RPC */
442     case CLGET_RETRY_TIMEOUT:
443     case CLSET_RETRY_TIMEOUT:
444     case CLGET_SVC_ADDR:
445     case CLSET_SVC_ADDR:
446     case CLSET_PUSH_TIMOD:
447     case CLSET_POP_TIMOD:
448     default:
449       return FALSE;
450     }
451   return TRUE;
452 }
453
454
455 static void
456 clnttcp_destroy (CLIENT *h)
457 {
458   struct ct_data *ct =
459   (struct ct_data *) h->cl_private;
460
461   if (ct->ct_closeit)
462     {
463       (void) __close (ct->ct_sock);
464     }
465   XDR_DESTROY (&(ct->ct_xdrs));
466   mem_free ((caddr_t) ct, sizeof (struct ct_data));
467   mem_free ((caddr_t) h, sizeof (CLIENT));
468 }
469
470 /*
471  * Interface between xdr serializer and tcp connection.
472  * Behaves like the system calls, read & write, but keeps some error state
473  * around for the rpc level.
474  */
475 static int
476 readtcp (char *ctptr, char *buf, int len)
477 {
478   struct ct_data *ct = (struct ct_data *)ctptr;
479   struct pollfd fd;
480   int milliseconds = (ct->ct_wait.tv_sec * 1000) +
481     (ct->ct_wait.tv_usec / 1000);
482
483   if (len == 0)
484     return 0;
485
486   fd.fd = ct->ct_sock;
487   fd.events = POLLIN;
488   while (TRUE)
489     {
490       switch (__poll(&fd, 1, milliseconds))
491         {
492         case 0:
493           ct->ct_error.re_status = RPC_TIMEDOUT;
494           return -1;
495
496         case -1:
497           if (errno == EINTR)
498             continue;
499           ct->ct_error.re_status = RPC_CANTRECV;
500           ct->ct_error.re_errno = errno;
501           return -1;
502         }
503       break;
504     }
505   switch (len = __read (ct->ct_sock, buf, len))
506     {
507
508     case 0:
509       /* premature eof */
510       ct->ct_error.re_errno = ECONNRESET;
511       ct->ct_error.re_status = RPC_CANTRECV;
512       len = -1;                 /* it's really an error */
513       break;
514
515     case -1:
516       ct->ct_error.re_errno = errno;
517       ct->ct_error.re_status = RPC_CANTRECV;
518       break;
519     }
520   return len;
521 }
522
523 static int
524 writetcp (char *ctptr, char *buf, int len)
525 {
526   int i, cnt;
527   struct ct_data *ct = (struct ct_data*)ctptr;
528
529   for (cnt = len; cnt > 0; cnt -= i, buf += i)
530     {
531       if ((i = __write (ct->ct_sock, buf, cnt)) == -1)
532         {
533           ct->ct_error.re_errno = errno;
534           ct->ct_error.re_status = RPC_CANTSEND;
535           return -1;
536         }
537     }
538   return len;
539 }