title: RPC can't decode arguments for TCP transport
body: <p>I'm working on a multithreaded RPC server based on the example from this page: 
  <a href="http://bderzhavets.blogspot.ca/2005/11/multithreaded-rpc-server-in-white-box.html" rel="nofollow">http://bderzhavets.blogspot.ca/2005/11/multithreaded-rpc-server-in-white-box.html</a></p>
  
  <p>Unfortunately it didn't quite work out of the box, and after chasing the errors for some time, I've found that the server is failing to decode the arguments (based on the return code from <code>squareproc_2</code>). The execution on the server side seems to stop after the call to <code>squareproc_2_svc</code> in the function <code>serv_request</code>. See <code>case: SQUAREPROC</code> in the code below from square_svc.c</p>
  
  <pre><code>void *serv_request(void *data)
  {
      struct thr_data *ptr_data = (struct thr_data *)data;
      {
          square_in argument;
          square_out result;
          bool_t retval;
          xdrproc_t _xdr_argument, _xdr_result;
          bool_t (*local)(char *, void *, struct svc_req *);
          struct svc_req *rqstp = ptr_data-&gt;rqstp;
          register SVCXPRT *transp = ptr_data-&gt;transp;
          switch (rqstp-&gt;rq_proc) {
              case NULLPROC:
                  printf("NULLPROC called\n");
                  (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
                  return;
              case SQUAREPROC:
                  _xdr_argument = (xdrproc_t) xdr_square_in;
                  _xdr_result = (xdrproc_t) xdr_square_out;
                  printf("_xdr_result = %ld\n",_xdr_result);
                  local = (bool_t (*) (char *, void *,  struct svc_req *))squareproc_2_svc;
                  break;
              default:
                  printf("default case executed");
                  svcerr_noproc (transp);
                  return;
          }
          memset ((void *)&amp;argument, 0, sizeof (argument));
          if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &amp;argument)) {
              printf("svc_getargs failed");
              svcerr_decode (transp);
              return;
          }
          retval = (bool_t) (*local)((char *)&amp;argument, (void *)&amp;result, rqstp);
          printf("serv_request result: %d\n",retval);
          if (retval &gt; 0 &amp;&amp; !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&amp;result))
          {
              printf("something happened...\n");
              svcerr_systemerr (transp);
          }
          if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &amp;argument)) {
              fprintf (stderr, "%s", "unable to free arguments");
              exit (1);
          }
          if (!square_prog_2_freeresult (transp, _xdr_result, (caddr_t) &amp;result))
              fprintf (stderr, "%s", "unable to free results");
          return;
      }
  }
  </code></pre>
  
  <p>Here is the implementation of <code>squareproc_2_svc</code> from the file square_server.c:</p>
  
  <pre><code>bool_t squareproc_2_svc(square_in *inp,square_out *outp,struct svc_req *rqstp)
  {
      printf("Thread id = '%ld' started, arg = %ld\n",pthread_self(),inp-&gt;arg1);
      sleep(5);
      outp-&gt;res1=inp-&gt;arg1*inp-&gt;arg1;
      printf("Thread id = '%ld' is done %ld \n",pthread_self(),outp-&gt;res1);
      return(TRUE);
  }
  </code></pre>
  
  <p>Client side output:</p>
  
  <pre><code>yak@AcerPC:~/RPC/multithread_example$ ./ClientSQUARE localhost 2
  squareproc_2 called
  xdr_square_in result: 1
  function call failed; code: 11
  </code></pre>
  
  <p>Server side output:</p>
  
  <pre><code>yak@AcerPC:~/RPC/multithread_example$ sudo ./ServerSQUARE 
  creating threads
  SQUAREPROC called
  xdr_square_in result: 0
  </code></pre>
  
  <p>As you can see, xdr_square_in returns a FALSE result on the server side.
  Here is the square.x</p>
  
  <pre><code>struct square_in {
      long arg1;
  };
  
  struct square_out {
      long res1;
  };
  
  program SQUARE_PROG {
      version SQUARE_VERS {
          square_out SQUAREPROC(square_in) = 1;
      } = 2 ;
  } = 0x31230000;
  </code></pre>
  
  <p>and square_xdr.c</p>
  
  <pre><code>/*
   * Please do not edit this file.
   * It was generated using rpcgen.
   */
  
  #include "square.h"
  
  bool_t
  xdr_square_in (XDR *xdrs, square_in *objp)
  {
      register int32_t *buf;
      int retval;
      if (!xdr_long (xdrs, &amp;objp-&gt;arg1)) retval = FALSE;
      else retval = TRUE;
      printf("xdr_square_in result: %d\n",retval);
      return retval;
  }
  
  bool_t
  xdr_square_out (XDR *xdrs, square_out *objp)
  {
      register int32_t *buf;
      int retval;
      if (!xdr_long (xdrs, &amp;objp-&gt;res1)) retval = FALSE;
      else retval = TRUE;
      printf("xdr_square_out result: %d\n",retval);
      return retval;
  }
  </code></pre>
  
  <p>I'm working in Ubuntu 14.04 LTS, generating stubs and xdr code with <code>rpcgen -a -M</code>, and compiling with <code>gcc</code>.</p>
  
  <p>The error only seems to occur when using TCP as the transport method. I can get results using UDP as the transport, but some calls fail when requests from multiple clients arrive simultaneously. I would like to be able to support up to 15 clients. When I tried using UDP and 10 clients, 2 of the 10 calls failed with a different return code from <code>squareproc_2</code>.</p>