Path: blob/main/crypto/krb5/src/lib/rpc/clnt_raw.c
39536 views
/* @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC */1/*2* Copyright (c) 2010, Oracle America, Inc.3*4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions are met:8*9* * Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* * Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in14* the documentation and/or other materials provided with the15* distribution.16*17* * Neither the name of the "Oracle America, Inc." nor the names of18* its contributors may be used to endorse or promote products19* derived from this software without specific prior written permission.20*21* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS22* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED23* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A24* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT25* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,26* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED27* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR28* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF29* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING30* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS31* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.32*/33#if !defined(lint) && defined(SCCSIDS)34static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";35#endif3637/*38* clnt_raw.c39*40* Memory based rpc for simple testing and timing.41* Interface to create an rpc client and server in the same process.42* This lets us similate rpc and get round trip overhead, without43* any interference from the kernel.44*/4546#include <gssrpc/rpc.h>4748#define MCALL_MSG_SIZE 244950/*51* This is the "network" we will be moving stuff over.52*/53static struct clntraw_private {54CLIENT client_object;55XDR xdr_stream;56char _raw_buf[UDPMSGSIZE];57union {58struct rpc_msg mashl_rpcmsg;59char mashl_callmsg[MCALL_MSG_SIZE];60} u;61u_int mcnt;62} *clntraw_private;6364static enum clnt_stat clntraw_call(CLIENT *, rpcproc_t, xdrproc_t,65void *, xdrproc_t, void *,66struct timeval);67static void clntraw_abort(CLIENT *);68static void clntraw_geterr(CLIENT *, struct rpc_err *);69static bool_t clntraw_freeres(CLIENT *, xdrproc_t, void *);70static bool_t clntraw_control(CLIENT *, int, void *);71static void clntraw_destroy(CLIENT *);7273static struct clnt_ops client_ops = {74clntraw_call,75clntraw_abort,76clntraw_geterr,77clntraw_freeres,78clntraw_destroy,79clntraw_control80};8182void svc_getreq(int);8384/*85* Create a client handle for memory based rpc.86*/87CLIENT *88clntraw_create(89rpcprog_t prog,90rpcvers_t vers)91{92struct clntraw_private *clp;93struct rpc_msg call_msg;94XDR *xdrs;95CLIENT *client;9697if (clntraw_private == NULL) {98clntraw_private = calloc(1, sizeof(*clp));99if (clntraw_private == NULL)100return (NULL);101}102clp = clntraw_private;103xdrs = &clp->xdr_stream;104client = &clp->client_object;105/*106* pre-serialize the staic part of the call msg and stash it away107*/108call_msg.rm_direction = CALL;109call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;110call_msg.rm_call.cb_prog = prog;111call_msg.rm_call.cb_vers = vers;112xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);113if (! xdr_callhdr(xdrs, &call_msg)) {114perror("clnt_raw.c - Fatal header serialization error.");115}116clp->mcnt = XDR_GETPOS(xdrs);117XDR_DESTROY(xdrs);118119/*120* Set xdrmem for client/server shared buffer121*/122xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);123124/*125* create client handle126*/127client->cl_ops = &client_ops;128client->cl_auth = authnone_create();129return (client);130}131132static enum clnt_stat133clntraw_call(134CLIENT *h,135rpcproc_t proc,136xdrproc_t xargs,137void * argsp,138xdrproc_t xresults,139void * resultsp,140struct timeval timeout)141{142struct clntraw_private *clp = clntraw_private;143XDR *xdrs = &clp->xdr_stream;144struct rpc_msg msg;145enum clnt_stat status;146struct rpc_err error;147long procl = proc;148149if (clp == 0)150return (RPC_FAILED);151call_again:152/*153* send request154*/155xdrs->x_op = XDR_ENCODE;156XDR_SETPOS(xdrs, 0);157clp->u.mashl_rpcmsg.rm_xid ++ ;158if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) ||159(! XDR_PUTLONG(xdrs, &procl)) ||160(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||161(! (*xargs)(xdrs, argsp))) {162return (RPC_CANTENCODEARGS);163}164(void)XDR_GETPOS(xdrs); /* called just to cause overhead */165166/*167* We have to call server input routine here because this is168* all going on in one process. Yuk.169*/170svc_getreq(1);171172/*173* get results174*/175xdrs->x_op = XDR_DECODE;176XDR_SETPOS(xdrs, 0);177msg.acpted_rply.ar_verf = gssrpc__null_auth;178msg.acpted_rply.ar_results.where = resultsp;179msg.acpted_rply.ar_results.proc = xresults;180if (! xdr_replymsg(xdrs, &msg)) {181/*182* It's possible for xdr_replymsg() to fail partway183* through its attempt to decode the result from the184* server. If this happens, it will leave the reply185* structure partially populated with dynamically186* allocated memory. (This can happen if someone uses187* clntudp_bufcreate() to create a CLIENT handle and188* specifies a receive buffer size that is too small.)189* This memory must be free()ed to avoid a leak.190*/191enum xdr_op op = xdrs->x_op;192xdrs->x_op = XDR_FREE;193xdr_replymsg(xdrs, &msg);194xdrs->x_op = op;195return (RPC_CANTDECODERES);196}197gssrpc__seterr_reply(&msg, &error);198status = error.re_status;199200if (status == RPC_SUCCESS) {201if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {202status = RPC_AUTHERROR;203}204} /* end successful completion */205else {206if (AUTH_REFRESH(h->cl_auth, &msg))207goto call_again;208} /* end of unsuccessful completion */209210if (status == RPC_SUCCESS) {211if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {212status = RPC_AUTHERROR;213}214if (msg.acpted_rply.ar_verf.oa_base != NULL) {215xdrs->x_op = XDR_FREE;216(void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));217}218}219220return (status);221}222223/*ARGSUSED*/224static void225clntraw_geterr(226CLIENT *cl,227struct rpc_err *err)228{229}230231232static bool_t233clntraw_freeres(234CLIENT *cl,235xdrproc_t xdr_res,236void *res_ptr)237{238struct clntraw_private *clp = clntraw_private;239XDR *xdrs = &clp->xdr_stream;240bool_t rval;241242if (clp == 0)243{244rval = (bool_t) RPC_FAILED;245return (rval);246}247xdrs->x_op = XDR_FREE;248return ((*xdr_res)(xdrs, res_ptr));249}250251/*ARGSUSED*/252static void253clntraw_abort(CLIENT *cl)254{255}256257/*ARGSUSED*/258static bool_t259clntraw_control(260CLIENT *cl,261int request,262void *info)263{264return (FALSE);265}266267/*ARGSUSED*/268static void269clntraw_destroy(CLIENT *cl)270{271}272273274