The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/rpc/svc_dg.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: svc_dg.c,v 1.4 2000/07/06 03:10:35 christos Exp $      */
    2 
    3 /*
    4  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
    5  * unrestricted use provided that this legend is included on all tape
    6  * media and as a part of the software program in whole or part.  Users
    7  * may copy or modify Sun RPC without charge, but are not authorized
    8  * to license or distribute it to anyone else except as part of a product or
    9  * program developed by the user.
   10  * 
   11  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
   12  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
   13  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
   14  * 
   15  * Sun RPC is provided with no support and without any obligation on the
   16  * part of Sun Microsystems, Inc. to assist in its use, correction,
   17  * modification or enhancement.
   18  * 
   19  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
   20  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
   21  * OR ANY PART THEREOF.
   22  * 
   23  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
   24  * or profits or other special, indirect and consequential damages, even if
   25  * Sun has been advised of the possibility of such damages.
   26  * 
   27  * Sun Microsystems, Inc.
   28  * 2550 Garcia Avenue
   29  * Mountain View, California  94043
   30  */
   31 
   32 /*
   33  * Copyright (c) 1986-1991 by Sun Microsystems Inc.
   34  */
   35 
   36 #if defined(LIBC_SCCS) && !defined(lint)
   37 #ident  "@(#)svc_dg.c   1.17    94/04/24 SMI"
   38 #endif
   39 #include <sys/cdefs.h>
   40 __FBSDID("$FreeBSD: releng/8.1/sys/rpc/svc_dg.c 199583 2009-11-20 15:27:52Z jhb $");
   41 
   42 /*
   43  * svc_dg.c, Server side for connectionless RPC.
   44  */
   45 
   46 #include <sys/param.h>
   47 #include <sys/lock.h>
   48 #include <sys/kernel.h>
   49 #include <sys/malloc.h>
   50 #include <sys/mbuf.h>
   51 #include <sys/mutex.h>
   52 #include <sys/protosw.h>
   53 #include <sys/queue.h>
   54 #include <sys/socket.h>
   55 #include <sys/socketvar.h>
   56 #include <sys/sx.h>
   57 #include <sys/systm.h>
   58 #include <sys/uio.h>
   59 
   60 #include <net/vnet.h>
   61 
   62 #include <rpc/rpc.h>
   63 
   64 #include <rpc/rpc_com.h>
   65 
   66 static enum xprt_stat svc_dg_stat(SVCXPRT *);
   67 static bool_t svc_dg_recv(SVCXPRT *, struct rpc_msg *,
   68     struct sockaddr **, struct mbuf **);
   69 static bool_t svc_dg_reply(SVCXPRT *, struct rpc_msg *,
   70     struct sockaddr *, struct mbuf *);
   71 static void svc_dg_destroy(SVCXPRT *);
   72 static bool_t svc_dg_control(SVCXPRT *, const u_int, void *);
   73 static int svc_dg_soupcall(struct socket *so, void *arg, int waitflag);
   74 
   75 static struct xp_ops svc_dg_ops = {
   76         .xp_recv =      svc_dg_recv,
   77         .xp_stat =      svc_dg_stat,
   78         .xp_reply =     svc_dg_reply,
   79         .xp_destroy =   svc_dg_destroy,
   80         .xp_control =   svc_dg_control,
   81 };
   82 
   83 /*
   84  * Usage:
   85  *      xprt = svc_dg_create(sock, sendsize, recvsize);
   86  * Does other connectionless specific initializations.
   87  * Once *xprt is initialized, it is registered.
   88  * see (svc.h, xprt_register). If recvsize or sendsize are 0 suitable
   89  * system defaults are chosen.
   90  * The routines returns NULL if a problem occurred.
   91  */
   92 static const char svc_dg_str[] = "svc_dg_create: %s";
   93 static const char svc_dg_err1[] = "could not get transport information";
   94 static const char svc_dg_err2[] = "transport does not support data transfer";
   95 static const char __no_mem_str[] = "out of memory";
   96 
   97 SVCXPRT *
   98 svc_dg_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
   99     size_t recvsize)
  100 {
  101         SVCXPRT *xprt;
  102         struct __rpc_sockinfo si;
  103         struct sockaddr* sa;
  104         int error;
  105 
  106         CURVNET_SET(so->so_vnet);
  107         if (!__rpc_socket2sockinfo(so, &si)) {
  108                 printf(svc_dg_str, svc_dg_err1);
  109                 CURVNET_RESTORE();
  110                 return (NULL);
  111         }
  112         /*
  113          * Find the receive and the send size
  114          */
  115         sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
  116         recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
  117         if ((sendsize == 0) || (recvsize == 0)) {
  118                 printf(svc_dg_str, svc_dg_err2);
  119                 CURVNET_RESTORE();
  120                 return (NULL);
  121         }
  122 
  123         xprt = svc_xprt_alloc();
  124         sx_init(&xprt->xp_lock, "xprt->xp_lock");
  125         xprt->xp_pool = pool;
  126         xprt->xp_socket = so;
  127         xprt->xp_p1 = NULL;
  128         xprt->xp_p2 = NULL;
  129         xprt->xp_ops = &svc_dg_ops;
  130 
  131         error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
  132         CURVNET_RESTORE();
  133         if (error)
  134                 goto freedata;
  135 
  136         memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
  137         free(sa, M_SONAME);
  138 
  139         xprt_register(xprt);
  140 
  141         SOCKBUF_LOCK(&so->so_rcv);
  142         soupcall_set(so, SO_RCV, svc_dg_soupcall, xprt);
  143         SOCKBUF_UNLOCK(&so->so_rcv);
  144 
  145         return (xprt);
  146 freedata:
  147         (void) printf(svc_dg_str, __no_mem_str);
  148         if (xprt) {
  149                 svc_xprt_free(xprt);
  150         }
  151         return (NULL);
  152 }
  153 
  154 /*ARGSUSED*/
  155 static enum xprt_stat
  156 svc_dg_stat(SVCXPRT *xprt)
  157 {
  158 
  159         if (soreadable(xprt->xp_socket))
  160                 return (XPRT_MOREREQS);
  161 
  162         return (XPRT_IDLE);
  163 }
  164 
  165 static bool_t
  166 svc_dg_recv(SVCXPRT *xprt, struct rpc_msg *msg,
  167     struct sockaddr **addrp, struct mbuf **mp)
  168 {
  169         struct uio uio;
  170         struct sockaddr *raddr;
  171         struct mbuf *mreq;
  172         XDR xdrs;
  173         int error, rcvflag;
  174 
  175         /*
  176          * Serialise access to the socket.
  177          */
  178         sx_xlock(&xprt->xp_lock);
  179 
  180         /*
  181          * The socket upcall calls xprt_active() which will eventually
  182          * cause the server to call us here. We attempt to read a
  183          * packet from the socket and process it. If the read fails,
  184          * we have drained all pending requests so we call
  185          * xprt_inactive().
  186          */
  187         uio.uio_resid = 1000000000;
  188         uio.uio_td = curthread;
  189         mreq = NULL;
  190         rcvflag = MSG_DONTWAIT;
  191         error = soreceive(xprt->xp_socket, &raddr, &uio, &mreq, NULL, &rcvflag);
  192 
  193         if (error == EWOULDBLOCK) {
  194                 /*
  195                  * We must re-test for readability after taking the
  196                  * lock to protect us in the case where a new packet
  197                  * arrives on the socket after our call to soreceive
  198                  * fails with EWOULDBLOCK. The pool lock protects us
  199                  * from racing the upcall after our soreadable() call
  200                  * returns false.
  201                  */
  202                 mtx_lock(&xprt->xp_pool->sp_lock);
  203                 if (!soreadable(xprt->xp_socket))
  204                         xprt_inactive_locked(xprt);
  205                 mtx_unlock(&xprt->xp_pool->sp_lock);
  206                 sx_xunlock(&xprt->xp_lock);
  207                 return (FALSE);
  208         }
  209 
  210         if (error) {
  211                 SOCKBUF_LOCK(&xprt->xp_socket->so_rcv);
  212                 soupcall_clear(xprt->xp_socket, SO_RCV);
  213                 SOCKBUF_UNLOCK(&xprt->xp_socket->so_rcv);
  214                 xprt_inactive(xprt);
  215                 sx_xunlock(&xprt->xp_lock);
  216                 return (FALSE);
  217         }
  218 
  219         sx_xunlock(&xprt->xp_lock);
  220 
  221         xdrmbuf_create(&xdrs, mreq, XDR_DECODE);
  222         if (! xdr_callmsg(&xdrs, msg)) {
  223                 XDR_DESTROY(&xdrs);
  224                 return (FALSE);
  225         }
  226 
  227         *addrp = raddr;
  228         *mp = xdrmbuf_getall(&xdrs);
  229         XDR_DESTROY(&xdrs);
  230 
  231         return (TRUE);
  232 }
  233 
  234 static bool_t
  235 svc_dg_reply(SVCXPRT *xprt, struct rpc_msg *msg,
  236     struct sockaddr *addr, struct mbuf *m)
  237 {
  238         XDR xdrs;
  239         struct mbuf *mrep;
  240         bool_t stat = TRUE;
  241         int error;
  242 
  243         MGETHDR(mrep, M_WAIT, MT_DATA);
  244         mrep->m_len = 0;
  245 
  246         xdrmbuf_create(&xdrs, mrep, XDR_ENCODE);
  247 
  248         if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
  249             msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
  250                 if (!xdr_replymsg(&xdrs, msg))
  251                         stat = FALSE;
  252                 else
  253                         xdrmbuf_append(&xdrs, m);
  254         } else {
  255                 stat = xdr_replymsg(&xdrs, msg);
  256         }
  257 
  258         if (stat) {
  259                 m_fixhdr(mrep);
  260                 error = sosend(xprt->xp_socket, addr, NULL, mrep, NULL,
  261                     0, curthread);
  262                 if (!error) {
  263                         stat = TRUE;
  264                 }
  265         } else {
  266                 m_freem(mrep);
  267         }
  268 
  269         XDR_DESTROY(&xdrs);
  270         xprt->xp_p2 = NULL;
  271 
  272         return (stat);
  273 }
  274 
  275 static void
  276 svc_dg_destroy(SVCXPRT *xprt)
  277 {
  278 
  279         SOCKBUF_LOCK(&xprt->xp_socket->so_rcv);
  280         soupcall_clear(xprt->xp_socket, SO_RCV);
  281         SOCKBUF_UNLOCK(&xprt->xp_socket->so_rcv);
  282 
  283         sx_destroy(&xprt->xp_lock);
  284         if (xprt->xp_socket)
  285                 (void)soclose(xprt->xp_socket);
  286 
  287         if (xprt->xp_netid)
  288                 (void) mem_free(xprt->xp_netid, strlen(xprt->xp_netid) + 1);
  289         svc_xprt_free(xprt);
  290 }
  291 
  292 static bool_t
  293 /*ARGSUSED*/
  294 svc_dg_control(xprt, rq, in)
  295         SVCXPRT *xprt;
  296         const u_int     rq;
  297         void            *in;
  298 {
  299 
  300         return (FALSE);
  301 }
  302 
  303 static int
  304 svc_dg_soupcall(struct socket *so, void *arg, int waitflag)
  305 {
  306         SVCXPRT *xprt = (SVCXPRT *) arg;
  307 
  308         xprt_active(xprt);
  309         return (SU_OK);
  310 }

Cache object: 6892bb35247135023c17da01b77c3313


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.