Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/lib/rpc/clnt_raw.c
39536 views
1
/* @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC */
2
/*
3
* Copyright (c) 2010, Oracle America, Inc.
4
*
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions are met:
9
*
10
* * Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
*
13
* * Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in
15
* the documentation and/or other materials provided with the
16
* distribution.
17
*
18
* * Neither the name of the "Oracle America, Inc." nor the names of
19
* its contributors may be used to endorse or promote products
20
* derived from this software without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
*/
34
#if !defined(lint) && defined(SCCSIDS)
35
static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
36
#endif
37
38
/*
39
* clnt_raw.c
40
*
41
* Memory based rpc for simple testing and timing.
42
* Interface to create an rpc client and server in the same process.
43
* This lets us similate rpc and get round trip overhead, without
44
* any interference from the kernel.
45
*/
46
47
#include <gssrpc/rpc.h>
48
49
#define MCALL_MSG_SIZE 24
50
51
/*
52
* This is the "network" we will be moving stuff over.
53
*/
54
static struct clntraw_private {
55
CLIENT client_object;
56
XDR xdr_stream;
57
char _raw_buf[UDPMSGSIZE];
58
union {
59
struct rpc_msg mashl_rpcmsg;
60
char mashl_callmsg[MCALL_MSG_SIZE];
61
} u;
62
u_int mcnt;
63
} *clntraw_private;
64
65
static enum clnt_stat clntraw_call(CLIENT *, rpcproc_t, xdrproc_t,
66
void *, xdrproc_t, void *,
67
struct timeval);
68
static void clntraw_abort(CLIENT *);
69
static void clntraw_geterr(CLIENT *, struct rpc_err *);
70
static bool_t clntraw_freeres(CLIENT *, xdrproc_t, void *);
71
static bool_t clntraw_control(CLIENT *, int, void *);
72
static void clntraw_destroy(CLIENT *);
73
74
static struct clnt_ops client_ops = {
75
clntraw_call,
76
clntraw_abort,
77
clntraw_geterr,
78
clntraw_freeres,
79
clntraw_destroy,
80
clntraw_control
81
};
82
83
void svc_getreq(int);
84
85
/*
86
* Create a client handle for memory based rpc.
87
*/
88
CLIENT *
89
clntraw_create(
90
rpcprog_t prog,
91
rpcvers_t vers)
92
{
93
struct clntraw_private *clp;
94
struct rpc_msg call_msg;
95
XDR *xdrs;
96
CLIENT *client;
97
98
if (clntraw_private == NULL) {
99
clntraw_private = calloc(1, sizeof(*clp));
100
if (clntraw_private == NULL)
101
return (NULL);
102
}
103
clp = clntraw_private;
104
xdrs = &clp->xdr_stream;
105
client = &clp->client_object;
106
/*
107
* pre-serialize the staic part of the call msg and stash it away
108
*/
109
call_msg.rm_direction = CALL;
110
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
111
call_msg.rm_call.cb_prog = prog;
112
call_msg.rm_call.cb_vers = vers;
113
xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
114
if (! xdr_callhdr(xdrs, &call_msg)) {
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 = &client_ops;
129
client->cl_auth = authnone_create();
130
return (client);
131
}
132
133
static enum clnt_stat
134
clntraw_call(
135
CLIENT *h,
136
rpcproc_t proc,
137
xdrproc_t xargs,
138
void * argsp,
139
xdrproc_t xresults,
140
void * resultsp,
141
struct timeval timeout)
142
{
143
struct clntraw_private *clp = clntraw_private;
144
XDR *xdrs = &clp->xdr_stream;
145
struct rpc_msg msg;
146
enum clnt_stat status;
147
struct rpc_err error;
148
long procl = proc;
149
150
if (clp == 0)
151
return (RPC_FAILED);
152
call_again:
153
/*
154
* send request
155
*/
156
xdrs->x_op = XDR_ENCODE;
157
XDR_SETPOS(xdrs, 0);
158
clp->u.mashl_rpcmsg.rm_xid ++ ;
159
if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) ||
160
(! XDR_PUTLONG(xdrs, &procl)) ||
161
(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
162
(! (*xargs)(xdrs, argsp))) {
163
return (RPC_CANTENCODEARGS);
164
}
165
(void)XDR_GETPOS(xdrs); /* called just to cause overhead */
166
167
/*
168
* We have to call server input routine here because this is
169
* all going on in one process. Yuk.
170
*/
171
svc_getreq(1);
172
173
/*
174
* get results
175
*/
176
xdrs->x_op = XDR_DECODE;
177
XDR_SETPOS(xdrs, 0);
178
msg.acpted_rply.ar_verf = gssrpc__null_auth;
179
msg.acpted_rply.ar_results.where = resultsp;
180
msg.acpted_rply.ar_results.proc = xresults;
181
if (! xdr_replymsg(xdrs, &msg)) {
182
/*
183
* It's possible for xdr_replymsg() to fail partway
184
* through its attempt to decode the result from the
185
* server. If this happens, it will leave the reply
186
* structure partially populated with dynamically
187
* allocated memory. (This can happen if someone uses
188
* clntudp_bufcreate() to create a CLIENT handle and
189
* specifies a receive buffer size that is too small.)
190
* This memory must be free()ed to avoid a leak.
191
*/
192
enum xdr_op op = xdrs->x_op;
193
xdrs->x_op = XDR_FREE;
194
xdr_replymsg(xdrs, &msg);
195
xdrs->x_op = op;
196
return (RPC_CANTDECODERES);
197
}
198
gssrpc__seterr_reply(&msg, &error);
199
status = error.re_status;
200
201
if (status == RPC_SUCCESS) {
202
if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
203
status = RPC_AUTHERROR;
204
}
205
} /* end successful completion */
206
else {
207
if (AUTH_REFRESH(h->cl_auth, &msg))
208
goto call_again;
209
} /* end of unsuccessful completion */
210
211
if (status == RPC_SUCCESS) {
212
if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
213
status = RPC_AUTHERROR;
214
}
215
if (msg.acpted_rply.ar_verf.oa_base != NULL) {
216
xdrs->x_op = XDR_FREE;
217
(void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
218
}
219
}
220
221
return (status);
222
}
223
224
/*ARGSUSED*/
225
static void
226
clntraw_geterr(
227
CLIENT *cl,
228
struct rpc_err *err)
229
{
230
}
231
232
233
static bool_t
234
clntraw_freeres(
235
CLIENT *cl,
236
xdrproc_t xdr_res,
237
void *res_ptr)
238
{
239
struct clntraw_private *clp = clntraw_private;
240
XDR *xdrs = &clp->xdr_stream;
241
bool_t rval;
242
243
if (clp == 0)
244
{
245
rval = (bool_t) RPC_FAILED;
246
return (rval);
247
}
248
xdrs->x_op = XDR_FREE;
249
return ((*xdr_res)(xdrs, res_ptr));
250
}
251
252
/*ARGSUSED*/
253
static void
254
clntraw_abort(CLIENT *cl)
255
{
256
}
257
258
/*ARGSUSED*/
259
static bool_t
260
clntraw_control(
261
CLIENT *cl,
262
int request,
263
void *info)
264
{
265
return (FALSE);
266
}
267
268
/*ARGSUSED*/
269
static void
270
clntraw_destroy(CLIENT *cl)
271
{
272
}
273
274