FreeBSD/Linux Kernel Cross Reference
sys/rpc/clnt_vc.c
1 /* $NetBSD: clnt_vc.c,v 1.4 2000/07/14 08:40:42 fvdl Exp $ */
2
3 /*-
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Copyright (c) 2009, Sun Microsystems, Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 * - Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 * - Neither the name of Sun Microsystems, 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 "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #if defined(LIBC_SCCS) && !defined(lint)
34 static char *sccsid2 = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
35 static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";
36 static char sccsid3[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro";
37 #endif
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40
41 /*
42 * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
43 *
44 * Copyright (C) 1984, Sun Microsystems, Inc.
45 *
46 * TCP based RPC supports 'batched calls'.
47 * A sequence of calls may be batched-up in a send buffer. The rpc call
48 * return immediately to the client even though the call was not necessarily
49 * sent. The batching occurs if the results' xdr routine is NULL (0) AND
50 * the rpc timeout value is zero (see clnt.h, rpc).
51 *
52 * Clients should NOT casually batch calls that in fact return results; that is,
53 * the server side should be aware that a call is batched and not produce any
54 * return message. Batched calls that produce many result messages can
55 * deadlock (netlock) the client and the server....
56 *
57 * Now go hang yourself.
58 */
59
60 #include "opt_kern_tls.h"
61
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/kernel.h>
65 #include <sys/kthread.h>
66 #include <sys/ktls.h>
67 #include <sys/lock.h>
68 #include <sys/malloc.h>
69 #include <sys/mbuf.h>
70 #include <sys/mutex.h>
71 #include <sys/pcpu.h>
72 #include <sys/proc.h>
73 #include <sys/protosw.h>
74 #include <sys/socket.h>
75 #include <sys/socketvar.h>
76 #include <sys/sx.h>
77 #include <sys/syslog.h>
78 #include <sys/time.h>
79 #include <sys/uio.h>
80
81 #include <net/vnet.h>
82
83 #include <netinet/tcp.h>
84
85 #include <rpc/rpc.h>
86 #include <rpc/rpc_com.h>
87 #include <rpc/krpc.h>
88 #include <rpc/rpcsec_tls.h>
89
90 struct cmessage {
91 struct cmsghdr cmsg;
92 struct cmsgcred cmcred;
93 };
94
95 static enum clnt_stat clnt_vc_call(CLIENT *, struct rpc_callextra *,
96 rpcproc_t, struct mbuf *, struct mbuf **, struct timeval);
97 static void clnt_vc_geterr(CLIENT *, struct rpc_err *);
98 static bool_t clnt_vc_freeres(CLIENT *, xdrproc_t, void *);
99 static void clnt_vc_abort(CLIENT *);
100 static bool_t clnt_vc_control(CLIENT *, u_int, void *);
101 static void clnt_vc_close(CLIENT *);
102 static void clnt_vc_destroy(CLIENT *);
103 static bool_t time_not_ok(struct timeval *);
104 static int clnt_vc_soupcall(struct socket *so, void *arg, int waitflag);
105 static void clnt_vc_dotlsupcall(void *data);
106
107 static const struct clnt_ops clnt_vc_ops = {
108 .cl_call = clnt_vc_call,
109 .cl_abort = clnt_vc_abort,
110 .cl_geterr = clnt_vc_geterr,
111 .cl_freeres = clnt_vc_freeres,
112 .cl_close = clnt_vc_close,
113 .cl_destroy = clnt_vc_destroy,
114 .cl_control = clnt_vc_control
115 };
116
117 static void clnt_vc_upcallsdone(struct ct_data *);
118
119 /*
120 * Create a client handle for a connection.
121 * Default options are set, which the user can change using clnt_control()'s.
122 * The rpc/vc package does buffering similar to stdio, so the client
123 * must pick send and receive buffer sizes, 0 => use the default.
124 * NB: fd is copied into a private area.
125 * NB: The rpch->cl_auth is set null authentication. Caller may wish to
126 * set this something more useful.
127 *
128 * fd should be an open socket
129 */
130 CLIENT *
131 clnt_vc_create(
132 struct socket *so, /* open file descriptor */
133 struct sockaddr *raddr, /* servers address */
134 const rpcprog_t prog, /* program number */
135 const rpcvers_t vers, /* version number */
136 size_t sendsz, /* buffer recv size */
137 size_t recvsz, /* buffer send size */
138 int intrflag) /* interruptible */
139 {
140 CLIENT *cl; /* client handle */
141 struct ct_data *ct = NULL; /* client handle */
142 struct timeval now;
143 struct rpc_msg call_msg;
144 static uint32_t disrupt;
145 struct __rpc_sockinfo si;
146 XDR xdrs;
147 int error, interrupted, one = 1, sleep_flag;
148 struct sockopt sopt;
149
150 if (disrupt == 0)
151 disrupt = (uint32_t)(long)raddr;
152
153 cl = (CLIENT *)mem_alloc(sizeof (*cl));
154 ct = (struct ct_data *)mem_alloc(sizeof (*ct));
155
156 mtx_init(&ct->ct_lock, "ct->ct_lock", NULL, MTX_DEF);
157 ct->ct_threads = 0;
158 ct->ct_closing = FALSE;
159 ct->ct_closed = FALSE;
160 ct->ct_upcallrefs = 0;
161 ct->ct_rcvstate = RPCRCVSTATE_NORMAL;
162
163 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
164 error = soconnect(so, raddr, curthread);
165 SOCK_LOCK(so);
166 interrupted = 0;
167 sleep_flag = PSOCK;
168 if (intrflag != 0)
169 sleep_flag |= PCATCH;
170 while ((so->so_state & SS_ISCONNECTING)
171 && so->so_error == 0) {
172 error = msleep(&so->so_timeo, SOCK_MTX(so),
173 sleep_flag, "connec", 0);
174 if (error) {
175 if (error == EINTR || error == ERESTART)
176 interrupted = 1;
177 break;
178 }
179 }
180 if (error == 0) {
181 error = so->so_error;
182 so->so_error = 0;
183 }
184 SOCK_UNLOCK(so);
185 if (error) {
186 if (!interrupted)
187 so->so_state &= ~SS_ISCONNECTING;
188 rpc_createerr.cf_stat = RPC_SYSTEMERROR;
189 rpc_createerr.cf_error.re_errno = error;
190 goto err;
191 }
192 }
193
194 if (!__rpc_socket2sockinfo(so, &si)) {
195 goto err;
196 }
197
198 if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
199 bzero(&sopt, sizeof(sopt));
200 sopt.sopt_dir = SOPT_SET;
201 sopt.sopt_level = SOL_SOCKET;
202 sopt.sopt_name = SO_KEEPALIVE;
203 sopt.sopt_val = &one;
204 sopt.sopt_valsize = sizeof(one);
205 sosetopt(so, &sopt);
206 }
207
208 if (so->so_proto->pr_protocol == IPPROTO_TCP) {
209 bzero(&sopt, sizeof(sopt));
210 sopt.sopt_dir = SOPT_SET;
211 sopt.sopt_level = IPPROTO_TCP;
212 sopt.sopt_name = TCP_NODELAY;
213 sopt.sopt_val = &one;
214 sopt.sopt_valsize = sizeof(one);
215 sosetopt(so, &sopt);
216 }
217
218 ct->ct_closeit = FALSE;
219
220 /*
221 * Set up private data struct
222 */
223 ct->ct_socket = so;
224 ct->ct_wait.tv_sec = -1;
225 ct->ct_wait.tv_usec = -1;
226 memcpy(&ct->ct_addr, raddr, raddr->sa_len);
227
228 /*
229 * Initialize call message
230 */
231 getmicrotime(&now);
232 ct->ct_xid = ((uint32_t)++disrupt) ^ __RPC_GETXID(&now);
233 call_msg.rm_xid = ct->ct_xid;
234 call_msg.rm_direction = CALL;
235 call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
236 call_msg.rm_call.cb_prog = (uint32_t)prog;
237 call_msg.rm_call.cb_vers = (uint32_t)vers;
238
239 /*
240 * pre-serialize the static part of the call msg and stash it away
241 */
242 xdrmem_create(&xdrs, ct->ct_mcallc, MCALL_MSG_SIZE,
243 XDR_ENCODE);
244 if (! xdr_callhdr(&xdrs, &call_msg)) {
245 if (ct->ct_closeit) {
246 soclose(ct->ct_socket);
247 }
248 goto err;
249 }
250 ct->ct_mpos = XDR_GETPOS(&xdrs);
251 XDR_DESTROY(&xdrs);
252 ct->ct_waitchan = "rpcrecv";
253 ct->ct_waitflag = 0;
254
255 /*
256 * Create a client handle which uses xdrrec for serialization
257 * and authnone for authentication.
258 */
259 sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
260 recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
261 error = soreserve(ct->ct_socket, sendsz, recvsz);
262 if (error != 0) {
263 if (ct->ct_closeit) {
264 soclose(ct->ct_socket);
265 }
266 goto err;
267 }
268 cl->cl_refs = 1;
269 cl->cl_ops = &clnt_vc_ops;
270 cl->cl_private = ct;
271 cl->cl_auth = authnone_create();
272
273 SOCKBUF_LOCK(&ct->ct_socket->so_rcv);
274 soupcall_set(ct->ct_socket, SO_RCV, clnt_vc_soupcall, ct);
275 SOCKBUF_UNLOCK(&ct->ct_socket->so_rcv);
276
277 ct->ct_raw = NULL;
278 ct->ct_record = NULL;
279 ct->ct_record_resid = 0;
280 ct->ct_sslrefno = 0;
281 TAILQ_INIT(&ct->ct_pending);
282 return (cl);
283
284 err:
285 mtx_destroy(&ct->ct_lock);
286 mem_free(ct, sizeof (struct ct_data));
287 mem_free(cl, sizeof (CLIENT));
288
289 return ((CLIENT *)NULL);
290 }
291
292 static enum clnt_stat
293 clnt_vc_call(
294 CLIENT *cl, /* client handle */
295 struct rpc_callextra *ext, /* call metadata */
296 rpcproc_t proc, /* procedure number */
297 struct mbuf *args, /* pointer to args */
298 struct mbuf **resultsp, /* pointer to results */
299 struct timeval utimeout)
300 {
301 struct ct_data *ct = (struct ct_data *) cl->cl_private;
302 AUTH *auth;
303 struct rpc_err *errp;
304 enum clnt_stat stat;
305 XDR xdrs;
306 struct rpc_msg reply_msg;
307 bool_t ok;
308 int nrefreshes = 2; /* number of times to refresh cred */
309 struct timeval timeout;
310 uint32_t xid;
311 struct mbuf *mreq = NULL, *results;
312 struct ct_request *cr;
313 int error, maxextsiz, trycnt;
314 #ifdef KERN_TLS
315 u_int maxlen;
316 #endif
317
318 cr = malloc(sizeof(struct ct_request), M_RPC, M_WAITOK);
319
320 mtx_lock(&ct->ct_lock);
321
322 if (ct->ct_closing || ct->ct_closed) {
323 mtx_unlock(&ct->ct_lock);
324 free(cr, M_RPC);
325 return (RPC_CANTSEND);
326 }
327 ct->ct_threads++;
328
329 if (ext) {
330 auth = ext->rc_auth;
331 errp = &ext->rc_err;
332 } else {
333 auth = cl->cl_auth;
334 errp = &ct->ct_error;
335 }
336
337 cr->cr_mrep = NULL;
338 cr->cr_error = 0;
339
340 if (ct->ct_wait.tv_usec == -1) {
341 timeout = utimeout; /* use supplied timeout */
342 } else {
343 timeout = ct->ct_wait; /* use default timeout */
344 }
345
346 /*
347 * After 15sec of looping, allow it to return RPC_CANTSEND, which will
348 * cause the clnt_reconnect layer to create a new TCP connection.
349 */
350 trycnt = 15 * hz;
351 call_again:
352 mtx_assert(&ct->ct_lock, MA_OWNED);
353 if (ct->ct_closing || ct->ct_closed) {
354 ct->ct_threads--;
355 wakeup(ct);
356 mtx_unlock(&ct->ct_lock);
357 free(cr, M_RPC);
358 return (RPC_CANTSEND);
359 }
360
361 ct->ct_xid++;
362 xid = ct->ct_xid;
363
364 mtx_unlock(&ct->ct_lock);
365
366 /*
367 * Leave space to pre-pend the record mark.
368 */
369 mreq = m_gethdr(M_WAITOK, MT_DATA);
370 mreq->m_data += sizeof(uint32_t);
371 KASSERT(ct->ct_mpos + sizeof(uint32_t) <= MHLEN,
372 ("RPC header too big"));
373 bcopy(ct->ct_mcallc, mreq->m_data, ct->ct_mpos);
374 mreq->m_len = ct->ct_mpos;
375
376 /*
377 * The XID is the first thing in the request.
378 */
379 *mtod(mreq, uint32_t *) = htonl(xid);
380
381 xdrmbuf_create(&xdrs, mreq, XDR_ENCODE);
382
383 errp->re_status = stat = RPC_SUCCESS;
384
385 if ((! XDR_PUTINT32(&xdrs, &proc)) ||
386 (! AUTH_MARSHALL(auth, xid, &xdrs,
387 m_copym(args, 0, M_COPYALL, M_WAITOK)))) {
388 errp->re_status = stat = RPC_CANTENCODEARGS;
389 mtx_lock(&ct->ct_lock);
390 goto out;
391 }
392 mreq->m_pkthdr.len = m_length(mreq, NULL);
393
394 /*
395 * Prepend a record marker containing the packet length.
396 */
397 M_PREPEND(mreq, sizeof(uint32_t), M_WAITOK);
398 *mtod(mreq, uint32_t *) =
399 htonl(0x80000000 | (mreq->m_pkthdr.len - sizeof(uint32_t)));
400
401 cr->cr_xid = xid;
402 mtx_lock(&ct->ct_lock);
403 /*
404 * Check to see if the other end has already started to close down
405 * the connection. The upcall will have set ct_error.re_status
406 * to RPC_CANTRECV if this is the case.
407 * If the other end starts to close down the connection after this
408 * point, it will be detected later when cr_error is checked,
409 * since the request is in the ct_pending queue.
410 */
411 if (ct->ct_error.re_status == RPC_CANTRECV) {
412 if (errp != &ct->ct_error) {
413 errp->re_errno = ct->ct_error.re_errno;
414 errp->re_status = RPC_CANTRECV;
415 }
416 stat = RPC_CANTRECV;
417 goto out;
418 }
419
420 /* For TLS, wait for an upcall to be done, as required. */
421 while ((ct->ct_rcvstate & (RPCRCVSTATE_NORMAL |
422 RPCRCVSTATE_NONAPPDATA)) == 0)
423 msleep(&ct->ct_rcvstate, &ct->ct_lock, 0, "rpcrcvst", hz);
424
425 TAILQ_INSERT_TAIL(&ct->ct_pending, cr, cr_link);
426 mtx_unlock(&ct->ct_lock);
427
428 if (ct->ct_sslrefno != 0) {
429 /*
430 * Copy the mbuf chain to a chain of ext_pgs mbuf(s)
431 * as required by KERN_TLS.
432 */
433 maxextsiz = TLS_MAX_MSG_SIZE_V10_2;
434 #ifdef KERN_TLS
435 if (rpctls_getinfo(&maxlen, false, false))
436 maxextsiz = min(maxextsiz, maxlen);
437 #endif
438 mreq = _rpc_copym_into_ext_pgs(mreq, maxextsiz);
439 }
440 /*
441 * sosend consumes mreq.
442 */
443 error = sosend(ct->ct_socket, NULL, NULL, mreq, NULL, 0, curthread);
444 mreq = NULL;
445 if (error == EMSGSIZE || (error == ERESTART &&
446 (ct->ct_waitflag & PCATCH) == 0 && trycnt-- > 0)) {
447 SOCKBUF_LOCK(&ct->ct_socket->so_snd);
448 sbwait(ct->ct_socket, SO_SND);
449 SOCKBUF_UNLOCK(&ct->ct_socket->so_snd);
450 AUTH_VALIDATE(auth, xid, NULL, NULL);
451 mtx_lock(&ct->ct_lock);
452 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link);
453 /* Sleep for 1 clock tick before trying the sosend() again. */
454 mtx_unlock(&ct->ct_lock);
455 pause("rpclpsnd", 1);
456 mtx_lock(&ct->ct_lock);
457 goto call_again;
458 }
459
460 reply_msg.acpted_rply.ar_verf.oa_flavor = AUTH_NULL;
461 reply_msg.acpted_rply.ar_verf.oa_base = cr->cr_verf;
462 reply_msg.acpted_rply.ar_verf.oa_length = 0;
463 reply_msg.acpted_rply.ar_results.where = NULL;
464 reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
465
466 mtx_lock(&ct->ct_lock);
467 if (error) {
468 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link);
469 errp->re_errno = error;
470 errp->re_status = stat = RPC_CANTSEND;
471 goto out;
472 }
473
474 /*
475 * Check to see if we got an upcall while waiting for the
476 * lock. In both these cases, the request has been removed
477 * from ct->ct_pending.
478 */
479 if (cr->cr_error) {
480 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link);
481 errp->re_errno = cr->cr_error;
482 errp->re_status = stat = RPC_CANTRECV;
483 goto out;
484 }
485 if (cr->cr_mrep) {
486 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link);
487 goto got_reply;
488 }
489
490 /*
491 * Hack to provide rpc-based message passing
492 */
493 if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
494 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link);
495 errp->re_status = stat = RPC_TIMEDOUT;
496 goto out;
497 }
498
499 error = msleep(cr, &ct->ct_lock, ct->ct_waitflag, ct->ct_waitchan,
500 tvtohz(&timeout));
501
502 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link);
503
504 if (error) {
505 /*
506 * The sleep returned an error so our request is still
507 * on the list. Turn the error code into an
508 * appropriate client status.
509 */
510 errp->re_errno = error;
511 switch (error) {
512 case EINTR:
513 stat = RPC_INTR;
514 break;
515 case EWOULDBLOCK:
516 stat = RPC_TIMEDOUT;
517 break;
518 default:
519 stat = RPC_CANTRECV;
520 }
521 errp->re_status = stat;
522 goto out;
523 } else {
524 /*
525 * We were woken up by the upcall. If the
526 * upcall had a receive error, report that,
527 * otherwise we have a reply.
528 */
529 if (cr->cr_error) {
530 errp->re_errno = cr->cr_error;
531 errp->re_status = stat = RPC_CANTRECV;
532 goto out;
533 }
534 }
535
536 got_reply:
537 /*
538 * Now decode and validate the response. We need to drop the
539 * lock since xdr_replymsg may end up sleeping in malloc.
540 */
541 mtx_unlock(&ct->ct_lock);
542
543 if (ext && ext->rc_feedback)
544 ext->rc_feedback(FEEDBACK_OK, proc, ext->rc_feedback_arg);
545
546 xdrmbuf_create(&xdrs, cr->cr_mrep, XDR_DECODE);
547 ok = xdr_replymsg(&xdrs, &reply_msg);
548 cr->cr_mrep = NULL;
549
550 if (ok) {
551 if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
552 (reply_msg.acpted_rply.ar_stat == SUCCESS))
553 errp->re_status = stat = RPC_SUCCESS;
554 else
555 stat = _seterr_reply(&reply_msg, errp);
556
557 if (stat == RPC_SUCCESS) {
558 results = xdrmbuf_getall(&xdrs);
559 if (!AUTH_VALIDATE(auth, xid,
560 &reply_msg.acpted_rply.ar_verf,
561 &results)) {
562 errp->re_status = stat = RPC_AUTHERROR;
563 errp->re_why = AUTH_INVALIDRESP;
564 } else {
565 KASSERT(results,
566 ("auth validated but no result"));
567 *resultsp = results;
568 }
569 } /* end successful completion */
570 /*
571 * If unsuccessful AND error is an authentication error
572 * then refresh credentials and try again, else break
573 */
574 else if (stat == RPC_AUTHERROR)
575 /* maybe our credentials need to be refreshed ... */
576 if (nrefreshes > 0 &&
577 AUTH_REFRESH(auth, &reply_msg)) {
578 nrefreshes--;
579 XDR_DESTROY(&xdrs);
580 mtx_lock(&ct->ct_lock);
581 goto call_again;
582 }
583 /* end of unsuccessful completion */
584 } /* end of valid reply message */
585 else {
586 errp->re_status = stat = RPC_CANTDECODERES;
587 }
588 XDR_DESTROY(&xdrs);
589 mtx_lock(&ct->ct_lock);
590 out:
591 mtx_assert(&ct->ct_lock, MA_OWNED);
592
593 KASSERT(stat != RPC_SUCCESS || *resultsp,
594 ("RPC_SUCCESS without reply"));
595
596 if (mreq)
597 m_freem(mreq);
598 if (cr->cr_mrep)
599 m_freem(cr->cr_mrep);
600
601 ct->ct_threads--;
602 if (ct->ct_closing)
603 wakeup(ct);
604
605 mtx_unlock(&ct->ct_lock);
606
607 if (auth && stat != RPC_SUCCESS)
608 AUTH_VALIDATE(auth, xid, NULL, NULL);
609
610 free(cr, M_RPC);
611
612 return (stat);
613 }
614
615 static void
616 clnt_vc_geterr(CLIENT *cl, struct rpc_err *errp)
617 {
618 struct ct_data *ct = (struct ct_data *) cl->cl_private;
619
620 *errp = ct->ct_error;
621 }
622
623 static bool_t
624 clnt_vc_freeres(CLIENT *cl, xdrproc_t xdr_res, void *res_ptr)
625 {
626 XDR xdrs;
627 bool_t dummy;
628
629 xdrs.x_op = XDR_FREE;
630 dummy = (*xdr_res)(&xdrs, res_ptr);
631
632 return (dummy);
633 }
634
635 /*ARGSUSED*/
636 static void
637 clnt_vc_abort(CLIENT *cl)
638 {
639 }
640
641 static bool_t
642 clnt_vc_control(CLIENT *cl, u_int request, void *info)
643 {
644 struct ct_data *ct = (struct ct_data *)cl->cl_private;
645 void *infop = info;
646 SVCXPRT *xprt;
647 uint64_t *p;
648 int error;
649 static u_int thrdnum = 0;
650
651 mtx_lock(&ct->ct_lock);
652
653 switch (request) {
654 case CLSET_FD_CLOSE:
655 ct->ct_closeit = TRUE;
656 mtx_unlock(&ct->ct_lock);
657 return (TRUE);
658 case CLSET_FD_NCLOSE:
659 ct->ct_closeit = FALSE;
660 mtx_unlock(&ct->ct_lock);
661 return (TRUE);
662 default:
663 break;
664 }
665
666 /* for other requests which use info */
667 if (info == NULL) {
668 mtx_unlock(&ct->ct_lock);
669 return (FALSE);
670 }
671 switch (request) {
672 case CLSET_TIMEOUT:
673 if (time_not_ok((struct timeval *)info)) {
674 mtx_unlock(&ct->ct_lock);
675 return (FALSE);
676 }
677 ct->ct_wait = *(struct timeval *)infop;
678 break;
679 case CLGET_TIMEOUT:
680 *(struct timeval *)infop = ct->ct_wait;
681 break;
682 case CLGET_SERVER_ADDR:
683 (void) memcpy(info, &ct->ct_addr, (size_t)ct->ct_addr.ss_len);
684 break;
685 case CLGET_SVC_ADDR:
686 /*
687 * Slightly different semantics to userland - we use
688 * sockaddr instead of netbuf.
689 */
690 memcpy(info, &ct->ct_addr, ct->ct_addr.ss_len);
691 break;
692 case CLSET_SVC_ADDR: /* set to new address */
693 mtx_unlock(&ct->ct_lock);
694 return (FALSE);
695 case CLGET_XID:
696 *(uint32_t *)info = ct->ct_xid;
697 break;
698 case CLSET_XID:
699 /* This will set the xid of the NEXT call */
700 /* decrement by 1 as clnt_vc_call() increments once */
701 ct->ct_xid = *(uint32_t *)info - 1;
702 break;
703 case CLGET_VERS:
704 /*
705 * This RELIES on the information that, in the call body,
706 * the version number field is the fifth field from the
707 * beginning of the RPC header. MUST be changed if the
708 * call_struct is changed
709 */
710 *(uint32_t *)info =
711 ntohl(*(uint32_t *)(void *)(ct->ct_mcallc +
712 4 * BYTES_PER_XDR_UNIT));
713 break;
714
715 case CLSET_VERS:
716 *(uint32_t *)(void *)(ct->ct_mcallc +
717 4 * BYTES_PER_XDR_UNIT) =
718 htonl(*(uint32_t *)info);
719 break;
720
721 case CLGET_PROG:
722 /*
723 * This RELIES on the information that, in the call body,
724 * the program number field is the fourth field from the
725 * beginning of the RPC header. MUST be changed if the
726 * call_struct is changed
727 */
728 *(uint32_t *)info =
729 ntohl(*(uint32_t *)(void *)(ct->ct_mcallc +
730 3 * BYTES_PER_XDR_UNIT));
731 break;
732
733 case CLSET_PROG:
734 *(uint32_t *)(void *)(ct->ct_mcallc +
735 3 * BYTES_PER_XDR_UNIT) =
736 htonl(*(uint32_t *)info);
737 break;
738
739 case CLSET_WAITCHAN:
740 ct->ct_waitchan = (const char *)info;
741 break;
742
743 case CLGET_WAITCHAN:
744 *(const char **) info = ct->ct_waitchan;
745 break;
746
747 case CLSET_INTERRUPTIBLE:
748 if (*(int *) info)
749 ct->ct_waitflag = PCATCH;
750 else
751 ct->ct_waitflag = 0;
752 break;
753
754 case CLGET_INTERRUPTIBLE:
755 if (ct->ct_waitflag)
756 *(int *) info = TRUE;
757 else
758 *(int *) info = FALSE;
759 break;
760
761 case CLSET_BACKCHANNEL:
762 xprt = (SVCXPRT *)info;
763 if (ct->ct_backchannelxprt == NULL) {
764 xprt->xp_p2 = ct;
765 if (ct->ct_sslrefno != 0)
766 xprt->xp_tls = RPCTLS_FLAGS_HANDSHAKE;
767 ct->ct_backchannelxprt = xprt;
768 }
769 break;
770
771 case CLSET_TLS:
772 p = (uint64_t *)info;
773 ct->ct_sslsec = *p++;
774 ct->ct_sslusec = *p++;
775 ct->ct_sslrefno = *p;
776 if (ct->ct_sslrefno != RPCTLS_REFNO_HANDSHAKE) {
777 mtx_unlock(&ct->ct_lock);
778 /* Start the kthread that handles upcalls. */
779 error = kthread_add(clnt_vc_dotlsupcall, ct,
780 NULL, NULL, 0, 0, "krpctls%u", thrdnum++);
781 if (error != 0)
782 panic("Can't add KRPC thread error %d", error);
783 } else
784 mtx_unlock(&ct->ct_lock);
785 return (TRUE);
786
787 case CLSET_BLOCKRCV:
788 if (*(int *) info) {
789 ct->ct_rcvstate &= ~RPCRCVSTATE_NORMAL;
790 ct->ct_rcvstate |= RPCRCVSTATE_TLSHANDSHAKE;
791 } else {
792 ct->ct_rcvstate &= ~RPCRCVSTATE_TLSHANDSHAKE;
793 ct->ct_rcvstate |= RPCRCVSTATE_NORMAL;
794 }
795 break;
796
797 default:
798 mtx_unlock(&ct->ct_lock);
799 return (FALSE);
800 }
801
802 mtx_unlock(&ct->ct_lock);
803 return (TRUE);
804 }
805
806 static void
807 clnt_vc_close(CLIENT *cl)
808 {
809 struct ct_data *ct = (struct ct_data *) cl->cl_private;
810 struct ct_request *cr;
811
812 mtx_lock(&ct->ct_lock);
813
814 if (ct->ct_closed) {
815 mtx_unlock(&ct->ct_lock);
816 return;
817 }
818
819 if (ct->ct_closing) {
820 while (ct->ct_closing)
821 msleep(ct, &ct->ct_lock, 0, "rpcclose", 0);
822 KASSERT(ct->ct_closed, ("client should be closed"));
823 mtx_unlock(&ct->ct_lock);
824 return;
825 }
826
827 if (ct->ct_socket) {
828 ct->ct_closing = TRUE;
829 mtx_unlock(&ct->ct_lock);
830
831 SOCKBUF_LOCK(&ct->ct_socket->so_rcv);
832 if (ct->ct_socket->so_rcv.sb_upcall != NULL) {
833 soupcall_clear(ct->ct_socket, SO_RCV);
834 clnt_vc_upcallsdone(ct);
835 }
836 SOCKBUF_UNLOCK(&ct->ct_socket->so_rcv);
837
838 /*
839 * Abort any pending requests and wait until everyone
840 * has finished with clnt_vc_call.
841 */
842 mtx_lock(&ct->ct_lock);
843 TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) {
844 cr->cr_xid = 0;
845 cr->cr_error = ESHUTDOWN;
846 wakeup(cr);
847 }
848
849 while (ct->ct_threads)
850 msleep(ct, &ct->ct_lock, 0, "rpcclose", 0);
851 }
852
853 ct->ct_closing = FALSE;
854 ct->ct_closed = TRUE;
855 wakeup(&ct->ct_sslrefno);
856 mtx_unlock(&ct->ct_lock);
857 wakeup(ct);
858 }
859
860 static void
861 clnt_vc_destroy(CLIENT *cl)
862 {
863 struct ct_data *ct = (struct ct_data *) cl->cl_private;
864 struct socket *so = NULL;
865 SVCXPRT *xprt;
866 uint32_t reterr;
867
868 clnt_vc_close(cl);
869
870 mtx_lock(&ct->ct_lock);
871 xprt = ct->ct_backchannelxprt;
872 ct->ct_backchannelxprt = NULL;
873 if (xprt != NULL) {
874 mtx_unlock(&ct->ct_lock); /* To avoid a LOR. */
875 sx_xlock(&xprt->xp_lock);
876 mtx_lock(&ct->ct_lock);
877 xprt->xp_p2 = NULL;
878 sx_xunlock(&xprt->xp_lock);
879 }
880
881 if (ct->ct_socket) {
882 if (ct->ct_closeit) {
883 so = ct->ct_socket;
884 }
885 }
886
887 /* Wait for the upcall kthread to terminate. */
888 while ((ct->ct_rcvstate & RPCRCVSTATE_UPCALLTHREAD) != 0)
889 msleep(&ct->ct_sslrefno, &ct->ct_lock, 0,
890 "clntvccl", hz);
891 mtx_unlock(&ct->ct_lock);
892
893 mtx_destroy(&ct->ct_lock);
894 if (so) {
895 if (ct->ct_sslrefno != 0) {
896 /*
897 * If the TLS handshake is in progress, the upcall
898 * will fail, but the socket should be closed by the
899 * daemon, since the connect upcall has just failed.
900 */
901 if (ct->ct_sslrefno != RPCTLS_REFNO_HANDSHAKE) {
902 /*
903 * If the upcall fails, the socket has
904 * probably been closed via the rpctlscd
905 * daemon having crashed or been
906 * restarted, so ignore return stat.
907 */
908 rpctls_cl_disconnect(ct->ct_sslsec,
909 ct->ct_sslusec, ct->ct_sslrefno,
910 &reterr);
911 }
912 /* Must sorele() to get rid of reference. */
913 CURVNET_SET(so->so_vnet);
914 sorele(so);
915 CURVNET_RESTORE();
916 } else {
917 soshutdown(so, SHUT_WR);
918 soclose(so);
919 }
920 }
921 m_freem(ct->ct_record);
922 m_freem(ct->ct_raw);
923 mem_free(ct, sizeof(struct ct_data));
924 if (cl->cl_netid && cl->cl_netid[0])
925 mem_free(cl->cl_netid, strlen(cl->cl_netid) +1);
926 if (cl->cl_tp && cl->cl_tp[0])
927 mem_free(cl->cl_tp, strlen(cl->cl_tp) +1);
928 mem_free(cl, sizeof(CLIENT));
929 }
930
931 /*
932 * Make sure that the time is not garbage. -1 value is disallowed.
933 * Note this is different from time_not_ok in clnt_dg.c
934 */
935 static bool_t
936 time_not_ok(struct timeval *t)
937 {
938 return (t->tv_sec <= -1 || t->tv_sec > 100000000 ||
939 t->tv_usec <= -1 || t->tv_usec > 1000000);
940 }
941
942 int
943 clnt_vc_soupcall(struct socket *so, void *arg, int waitflag)
944 {
945 struct ct_data *ct = (struct ct_data *) arg;
946 struct uio uio;
947 struct mbuf *m, *m2;
948 struct ct_request *cr;
949 int error, rcvflag, foundreq;
950 uint32_t xid_plus_direction[2], header;
951 SVCXPRT *xprt;
952 struct cf_conn *cd;
953 u_int rawlen;
954 struct cmsghdr *cmsg;
955 struct tls_get_record tgr;
956
957 /*
958 * RPC-over-TLS needs to block reception during
959 * upcalls since the upcall will be doing I/O on
960 * the socket via openssl library calls.
961 */
962 mtx_lock(&ct->ct_lock);
963 if ((ct->ct_rcvstate & (RPCRCVSTATE_NORMAL |
964 RPCRCVSTATE_NONAPPDATA)) == 0) {
965 /* Mark that a socket upcall needs to be done. */
966 if ((ct->ct_rcvstate & (RPCRCVSTATE_UPCALLNEEDED |
967 RPCRCVSTATE_UPCALLINPROG)) != 0)
968 ct->ct_rcvstate |= RPCRCVSTATE_SOUPCALLNEEDED;
969 mtx_unlock(&ct->ct_lock);
970 return (SU_OK);
971 }
972 mtx_unlock(&ct->ct_lock);
973
974 /*
975 * If another thread is already here, it must be in
976 * soreceive(), so just return to avoid races with it.
977 * ct_upcallrefs is protected by the SOCKBUF_LOCK(),
978 * which is held in this function, except when
979 * soreceive() is called.
980 */
981 if (ct->ct_upcallrefs > 0)
982 return (SU_OK);
983 ct->ct_upcallrefs++;
984
985 /*
986 * Read as much as possible off the socket and link it
987 * onto ct_raw.
988 */
989 for (;;) {
990 uio.uio_resid = 1000000000;
991 uio.uio_td = curthread;
992 m2 = m = NULL;
993 rcvflag = MSG_DONTWAIT | MSG_SOCALLBCK;
994 if (ct->ct_sslrefno != 0 && (ct->ct_rcvstate &
995 RPCRCVSTATE_NORMAL) != 0)
996 rcvflag |= MSG_TLSAPPDATA;
997 SOCKBUF_UNLOCK(&so->so_rcv);
998 error = soreceive(so, NULL, &uio, &m, &m2, &rcvflag);
999 SOCKBUF_LOCK(&so->so_rcv);
1000
1001 if (error == EWOULDBLOCK) {
1002 /*
1003 * We must re-test for readability after
1004 * taking the lock to protect us in the case
1005 * where a new packet arrives on the socket
1006 * after our call to soreceive fails with
1007 * EWOULDBLOCK.
1008 */
1009 error = 0;
1010 if (!soreadable(so))
1011 break;
1012 continue;
1013 }
1014 if (error == 0 && m == NULL) {
1015 /*
1016 * We must have got EOF trying
1017 * to read from the stream.
1018 */
1019 error = ECONNRESET;
1020 }
1021
1022 /*
1023 * A return of ENXIO indicates that there is an
1024 * alert record at the head of the
1025 * socket's receive queue, for TLS connections.
1026 * This record needs to be handled in userland
1027 * via an SSL_read() call, so do an upcall to the daemon.
1028 */
1029 if (ct->ct_sslrefno != 0 && error == ENXIO) {
1030 /* Disable reception, marking an upcall needed. */
1031 mtx_lock(&ct->ct_lock);
1032 ct->ct_rcvstate |= RPCRCVSTATE_UPCALLNEEDED;
1033 /*
1034 * If an upcall in needed, wake up the kthread
1035 * that runs clnt_vc_dotlsupcall().
1036 */
1037 wakeup(&ct->ct_sslrefno);
1038 mtx_unlock(&ct->ct_lock);
1039 break;
1040 }
1041 if (error != 0)
1042 break;
1043
1044 /* Process any record header(s). */
1045 if (m2 != NULL) {
1046 cmsg = mtod(m2, struct cmsghdr *);
1047 if (cmsg->cmsg_type == TLS_GET_RECORD &&
1048 cmsg->cmsg_len == CMSG_LEN(sizeof(tgr))) {
1049 memcpy(&tgr, CMSG_DATA(cmsg), sizeof(tgr));
1050 /*
1051 * TLS_RLTYPE_ALERT records should be handled
1052 * since soreceive() would have returned
1053 * ENXIO. Just throw any other
1054 * non-TLS_RLTYPE_APP records away.
1055 */
1056 if (tgr.tls_type != TLS_RLTYPE_APP) {
1057 m_freem(m);
1058 m_free(m2);
1059 mtx_lock(&ct->ct_lock);
1060 ct->ct_rcvstate &=
1061 ~RPCRCVSTATE_NONAPPDATA;
1062 ct->ct_rcvstate |= RPCRCVSTATE_NORMAL;
1063 mtx_unlock(&ct->ct_lock);
1064 continue;
1065 }
1066 }
1067 m_free(m2);
1068 }
1069
1070 if (ct->ct_raw != NULL)
1071 m_last(ct->ct_raw)->m_next = m;
1072 else
1073 ct->ct_raw = m;
1074 }
1075 rawlen = m_length(ct->ct_raw, NULL);
1076
1077 /* Now, process as much of ct_raw as possible. */
1078 for (;;) {
1079 /*
1080 * If ct_record_resid is zero, we are waiting for a
1081 * record mark.
1082 */
1083 if (ct->ct_record_resid == 0) {
1084 if (rawlen < sizeof(uint32_t))
1085 break;
1086 m_copydata(ct->ct_raw, 0, sizeof(uint32_t),
1087 (char *)&header);
1088 header = ntohl(header);
1089 ct->ct_record_resid = header & 0x7fffffff;
1090 ct->ct_record_eor = ((header & 0x80000000) != 0);
1091 m_adj(ct->ct_raw, sizeof(uint32_t));
1092 rawlen -= sizeof(uint32_t);
1093 } else {
1094 /*
1095 * Move as much of the record as possible to
1096 * ct_record.
1097 */
1098 if (rawlen == 0)
1099 break;
1100 if (rawlen <= ct->ct_record_resid) {
1101 if (ct->ct_record != NULL)
1102 m_last(ct->ct_record)->m_next =
1103 ct->ct_raw;
1104 else
1105 ct->ct_record = ct->ct_raw;
1106 ct->ct_raw = NULL;
1107 ct->ct_record_resid -= rawlen;
1108 rawlen = 0;
1109 } else {
1110 m = m_split(ct->ct_raw, ct->ct_record_resid,
1111 M_NOWAIT);
1112 if (m == NULL)
1113 break;
1114 if (ct->ct_record != NULL)
1115 m_last(ct->ct_record)->m_next =
1116 ct->ct_raw;
1117 else
1118 ct->ct_record = ct->ct_raw;
1119 rawlen -= ct->ct_record_resid;
1120 ct->ct_record_resid = 0;
1121 ct->ct_raw = m;
1122 }
1123 if (ct->ct_record_resid > 0)
1124 break;
1125
1126 /*
1127 * If we have the entire record, see if we can
1128 * match it to a request.
1129 */
1130 if (ct->ct_record_eor) {
1131 /*
1132 * The XID is in the first uint32_t of
1133 * the reply and the message direction
1134 * is the second one.
1135 */
1136 if (ct->ct_record->m_len <
1137 sizeof(xid_plus_direction) &&
1138 m_length(ct->ct_record, NULL) <
1139 sizeof(xid_plus_direction)) {
1140 /*
1141 * What to do now?
1142 * The data in the TCP stream is
1143 * corrupted such that there is no
1144 * valid RPC message to parse.
1145 * I think it best to close this
1146 * connection and allow
1147 * clnt_reconnect_call() to try
1148 * and establish a new one.
1149 */
1150 printf("clnt_vc_soupcall: "
1151 "connection data corrupted\n");
1152 error = ECONNRESET;
1153 goto wakeup_all;
1154 }
1155 m_copydata(ct->ct_record, 0,
1156 sizeof(xid_plus_direction),
1157 (char *)xid_plus_direction);
1158 xid_plus_direction[0] =
1159 ntohl(xid_plus_direction[0]);
1160 xid_plus_direction[1] =
1161 ntohl(xid_plus_direction[1]);
1162 /* Check message direction. */
1163 if (xid_plus_direction[1] == CALL) {
1164 /* This is a backchannel request. */
1165 mtx_lock(&ct->ct_lock);
1166 xprt = ct->ct_backchannelxprt;
1167 if (xprt == NULL) {
1168 mtx_unlock(&ct->ct_lock);
1169 /* Just throw it away. */
1170 m_freem(ct->ct_record);
1171 ct->ct_record = NULL;
1172 } else {
1173 cd = (struct cf_conn *)
1174 xprt->xp_p1;
1175 m2 = cd->mreq;
1176 /*
1177 * The requests are chained
1178 * in the m_nextpkt list.
1179 */
1180 while (m2 != NULL &&
1181 m2->m_nextpkt != NULL)
1182 /* Find end of list. */
1183 m2 = m2->m_nextpkt;
1184 if (m2 != NULL)
1185 m2->m_nextpkt =
1186 ct->ct_record;
1187 else
1188 cd->mreq =
1189 ct->ct_record;
1190 ct->ct_record->m_nextpkt =
1191 NULL;
1192 ct->ct_record = NULL;
1193 xprt_active(xprt);
1194 mtx_unlock(&ct->ct_lock);
1195 }
1196 } else {
1197 mtx_lock(&ct->ct_lock);
1198 foundreq = 0;
1199 TAILQ_FOREACH(cr, &ct->ct_pending,
1200 cr_link) {
1201 if (cr->cr_xid ==
1202 xid_plus_direction[0]) {
1203 /*
1204 * This one
1205 * matches. We leave
1206 * the reply mbuf in
1207 * cr->cr_mrep. Set
1208 * the XID to zero so
1209 * that we will ignore
1210 * any duplicated
1211 * replies.
1212 */
1213 cr->cr_xid = 0;
1214 cr->cr_mrep =
1215 ct->ct_record;
1216 cr->cr_error = 0;
1217 foundreq = 1;
1218 wakeup(cr);
1219 break;
1220 }
1221 }
1222 mtx_unlock(&ct->ct_lock);
1223
1224 if (!foundreq)
1225 m_freem(ct->ct_record);
1226 ct->ct_record = NULL;
1227 }
1228 }
1229 }
1230 }
1231
1232 if (error != 0) {
1233 wakeup_all:
1234 /*
1235 * This socket is broken, so mark that it cannot
1236 * receive and fail all RPCs waiting for a reply
1237 * on it, so that they will be retried on a new
1238 * TCP connection created by clnt_reconnect_X().
1239 */
1240 mtx_lock(&ct->ct_lock);
1241 ct->ct_error.re_status = RPC_CANTRECV;
1242 ct->ct_error.re_errno = error;
1243 TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) {
1244 cr->cr_error = error;
1245 wakeup(cr);
1246 }
1247 mtx_unlock(&ct->ct_lock);
1248 }
1249
1250 ct->ct_upcallrefs--;
1251 if (ct->ct_upcallrefs < 0)
1252 panic("rpcvc upcall refcnt");
1253 if (ct->ct_upcallrefs == 0)
1254 wakeup(&ct->ct_upcallrefs);
1255 return (SU_OK);
1256 }
1257
1258 /*
1259 * Wait for all upcalls in progress to complete.
1260 */
1261 static void
1262 clnt_vc_upcallsdone(struct ct_data *ct)
1263 {
1264
1265 SOCKBUF_LOCK_ASSERT(&ct->ct_socket->so_rcv);
1266
1267 while (ct->ct_upcallrefs > 0)
1268 (void) msleep(&ct->ct_upcallrefs,
1269 SOCKBUF_MTX(&ct->ct_socket->so_rcv), 0, "rpcvcup", 0);
1270 }
1271
1272 /*
1273 * Do a TLS upcall to the rpctlscd daemon, as required.
1274 * This function runs as a kthread.
1275 */
1276 static void
1277 clnt_vc_dotlsupcall(void *data)
1278 {
1279 struct ct_data *ct = (struct ct_data *)data;
1280 enum clnt_stat ret;
1281 uint32_t reterr;
1282
1283 mtx_lock(&ct->ct_lock);
1284 ct->ct_rcvstate |= RPCRCVSTATE_UPCALLTHREAD;
1285 while (!ct->ct_closed) {
1286 if ((ct->ct_rcvstate & RPCRCVSTATE_UPCALLNEEDED) != 0) {
1287 ct->ct_rcvstate &= ~RPCRCVSTATE_UPCALLNEEDED;
1288 ct->ct_rcvstate |= RPCRCVSTATE_UPCALLINPROG;
1289 if (ct->ct_sslrefno != 0 && ct->ct_sslrefno !=
1290 RPCTLS_REFNO_HANDSHAKE) {
1291 mtx_unlock(&ct->ct_lock);
1292 ret = rpctls_cl_handlerecord(ct->ct_sslsec,
1293 ct->ct_sslusec, ct->ct_sslrefno, &reterr);
1294 mtx_lock(&ct->ct_lock);
1295 }
1296 ct->ct_rcvstate &= ~RPCRCVSTATE_UPCALLINPROG;
1297 if (ret == RPC_SUCCESS && reterr == RPCTLSERR_OK)
1298 ct->ct_rcvstate |= RPCRCVSTATE_NORMAL;
1299 else
1300 ct->ct_rcvstate |= RPCRCVSTATE_NONAPPDATA;
1301 wakeup(&ct->ct_rcvstate);
1302 }
1303 if ((ct->ct_rcvstate & RPCRCVSTATE_SOUPCALLNEEDED) != 0) {
1304 ct->ct_rcvstate &= ~RPCRCVSTATE_SOUPCALLNEEDED;
1305 mtx_unlock(&ct->ct_lock);
1306 SOCKBUF_LOCK(&ct->ct_socket->so_rcv);
1307 clnt_vc_soupcall(ct->ct_socket, ct, M_NOWAIT);
1308 SOCKBUF_UNLOCK(&ct->ct_socket->so_rcv);
1309 mtx_lock(&ct->ct_lock);
1310 }
1311 msleep(&ct->ct_sslrefno, &ct->ct_lock, 0, "clntvcdu", hz);
1312 }
1313 ct->ct_rcvstate &= ~RPCRCVSTATE_UPCALLTHREAD;
1314 wakeup(&ct->ct_sslrefno);
1315 mtx_unlock(&ct->ct_lock);
1316 kthread_exit();
1317 }
Cache object: 22fc2d19d88752d01b8088971fbe8aa6
|