/*
 * svc_raw.c,   This a toy for simple testing and timing.
 * Interface to create an rpc client and server in the same UNIX process.
 * This lets us simulate rpc and get rpc (round trip) overhead, without
 * any interference from the kernel.
 *
 * Copyright (c) 2010, Oracle America, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials
 *       provided with the distribution.
 *     * Neither the name of the "Oracle America, Inc." nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <rpc/rpc.h>
#include <rpc/svc.h>

/*
 * This is the "network" that we will be moving data over
 */
struct svcraw_private_s
  {
    char _raw_buf[UDPMSGSIZE];
    SVCXPRT server;
    XDR xdr_stream;
    char verf_body[MAX_AUTH_BYTES];
  };
#ifdef _RPC_THREAD_SAFE_
#define svcraw_private RPC_THREAD_VARIABLE(svcraw_private_s)
#else
static struct svcraw_private_s *svcraw_private;
#endif

static bool_t svcraw_recv (SVCXPRT *, struct rpc_msg *);
static enum xprt_stat svcraw_stat (SVCXPRT *);
static bool_t svcraw_getargs (SVCXPRT *, xdrproc_t, caddr_t);
static bool_t svcraw_reply (SVCXPRT *, struct rpc_msg *);
static bool_t svcraw_freeargs (SVCXPRT *, xdrproc_t, caddr_t);
static void svcraw_destroy (SVCXPRT *);

static const struct xp_ops server_ops =
{
  svcraw_recv,
  svcraw_stat,
  svcraw_getargs,
  svcraw_reply,
  svcraw_freeargs,
  svcraw_destroy
};

SVCXPRT *
svcraw_create (void)
{
  struct svcraw_private_s *srp = svcraw_private;

  if (srp == 0)
    {
      srp = (struct svcraw_private_s *) calloc (1, sizeof (*srp));
      if (srp == 0)
	return NULL;
    }
  srp->server.xp_sock = 0;
  srp->server.xp_port = 0;
  srp->server.xp_ops = (struct xp_ops *) &server_ops;
  srp->server.xp_verf.oa_base = srp->verf_body;
  xdrmem_create (&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE);
  return &srp->server;
}
libc_hidden_nolink_sunrpc (svcraw_create, GLIBC_2_0)

static enum xprt_stat
svcraw_stat (SVCXPRT *xprt)
{
  return XPRT_IDLE;
}

static bool_t
svcraw_recv (xprt, msg)
     SVCXPRT *xprt;
     struct rpc_msg *msg;
{
  struct svcraw_private_s *srp = svcraw_private;
  XDR *xdrs;

  if (srp == 0)
    return FALSE;
  xdrs = &srp->xdr_stream;
  xdrs->x_op = XDR_DECODE;
  XDR_SETPOS (xdrs, 0);
  if (!xdr_callmsg (xdrs, msg))
    return FALSE;
  return TRUE;
}

static bool_t
svcraw_reply (SVCXPRT *xprt, struct rpc_msg *msg)
{
  struct svcraw_private_s *srp = svcraw_private;
  XDR *xdrs;

  if (srp == 0)
    return FALSE;
  xdrs = &srp->xdr_stream;
  xdrs->x_op = XDR_ENCODE;
  XDR_SETPOS (xdrs, 0);
  if (!xdr_replymsg (xdrs, msg))
    return FALSE;
  (void) XDR_GETPOS (xdrs);	/* called just for overhead */
  return TRUE;
}

static bool_t
svcraw_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
{
  struct svcraw_private_s *srp = svcraw_private;

  if (srp == 0)
    return FALSE;
  return (*xdr_args) (&srp->xdr_stream, args_ptr);
}

static bool_t
svcraw_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
{
  struct svcraw_private_s *srp = svcraw_private;
  XDR *xdrs;

  if (srp == 0)
    return FALSE;
  xdrs = &srp->xdr_stream;
  xdrs->x_op = XDR_FREE;
  return (*xdr_args) (xdrs, args_ptr);
}

static void
svcraw_destroy (SVCXPRT *xprt)
{
}
