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.3/sys/rpc/svc_dg.c 220733 2011-04-16 23:30:53Z bz $");
   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         if (!__rpc_socket2sockinfo(so, &si)) {
  107                 printf(svc_dg_str, svc_dg_err1);
  108                 return (NULL);
  109         }
  110         /*
  111          * Find the receive and the send size
  112          */
  113         sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
  114         recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
  115         if ((sendsize == 0) || (recvsize == 0)) {
  116                 printf(svc_dg_str, svc_dg_err2);
  117                 return (NULL);
  118         }
  119 
  120         xprt = svc_xprt_alloc();
  121         sx_init(&xprt->xp_lock, "xprt->xp_lock");
  122         xprt->xp_pool = pool;
  123         xprt->xp_socket = so;
  124         xprt->xp_p1 = NULL;
  125         xprt->xp_p2 = NULL;
  126         xprt->xp_ops = &svc_dg_ops;
  127 
  128         CURVNET_SET(so->so_vnet);
  129         error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
  130         CURVNET_RESTORE();
  131         if (error)
  132                 goto freedata;
  133 
  134         memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
  135         free(sa, M_SONAME);
  136 
  137         xprt_register(xprt);
  138 
  139         SOCKBUF_LOCK(&so->so_rcv);
  140         soupcall_set(so, SO_RCV, svc_dg_soupcall, xprt);
  141         SOCKBUF_UNLOCK(&so->so_rcv);
  142 
  143         return (xprt);
  144 freedata:
  145         (void) printf(svc_dg_str, __no_mem_str);
  146         if (xprt) {
  147                 svc_xprt_free(xprt);
  148         }
  149         return (NULL);
  150 }
  151 
  152 /*ARGSUSED*/
  153 static enum xprt_stat
  154 svc_dg_stat(SVCXPRT *xprt)
  155 {
  156 
  157         if (soreadable(xprt->xp_socket))
  158                 return (XPRT_MOREREQS);
  159 
  160         return (XPRT_IDLE);
  161 }
  162 
  163 static bool_t
  164 svc_dg_recv(SVCXPRT *xprt, struct rpc_msg *msg,
  165     struct sockaddr **addrp, struct mbuf **mp)
  166 {
  167         struct uio uio;
  168         struct sockaddr *raddr;
  169         struct mbuf *mreq;
  170         XDR xdrs;
  171         int error, rcvflag;
  172 
  173         /*
  174          * Serialise access to the socket.
  175          */
  176         sx_xlock(&xprt->xp_lock);
  177 
  178         /*
  179          * The socket upcall calls xprt_active() which will eventually
  180          * cause the server to call us here. We attempt to read a
  181          * packet from the socket and process it. If the read fails,
  182          * we have drained all pending requests so we call
  183          * xprt_inactive().
  184          */
  185         uio.uio_resid = 1000000000;
  186         uio.uio_td = curthread;
  187         mreq = NULL;
  188         rcvflag = MSG_DONTWAIT;
  189         error = soreceive(xprt->xp_socket, &raddr, &uio, &mreq, NULL, &rcvflag);
  190 
  191         if (error == EWOULDBLOCK) {
  192                 /*
  193                  * We must re-test for readability after taking the
  194                  * lock to protect us in the case where a new packet
  195                  * arrives on the socket after our call to soreceive
  196                  * fails with EWOULDBLOCK. The pool lock protects us
  197                  * from racing the upcall after our soreadable() call
  198                  * returns false.
  199                  */
  200                 mtx_lock(&xprt->xp_pool->sp_lock);
  201                 if (!soreadable(xprt->xp_socket))
  202                         xprt_inactive_locked(xprt);
  203                 mtx_unlock(&xprt->xp_pool->sp_lock);
  204                 sx_xunlock(&xprt->xp_lock);
  205                 return (FALSE);
  206         }
  207 
  208         if (error) {
  209                 SOCKBUF_LOCK(&xprt->xp_socket->so_rcv);
  210                 soupcall_clear(xprt->xp_socket, SO_RCV);
  211                 SOCKBUF_UNLOCK(&xprt->xp_socket->so_rcv);
  212                 xprt_inactive(xprt);
  213                 sx_xunlock(&xprt->xp_lock);
  214                 return (FALSE);
  215         }
  216 
  217         sx_xunlock(&xprt->xp_lock);
  218 
  219         xdrmbuf_create(&xdrs, mreq, XDR_DECODE);
  220         if (! xdr_callmsg(&xdrs, msg)) {
  221                 XDR_DESTROY(&xdrs);
  222                 return (FALSE);
  223         }
  224 
  225         *addrp = raddr;
  226         *mp = xdrmbuf_getall(&xdrs);
  227         XDR_DESTROY(&xdrs);
  228 
  229         return (TRUE);
  230 }
  231 
  232 static bool_t
  233 svc_dg_reply(SVCXPRT *xprt, struct rpc_msg *msg,
  234     struct sockaddr *addr, struct mbuf *m)
  235 {
  236         XDR xdrs;
  237         struct mbuf *mrep;
  238         bool_t stat = TRUE;
  239         int error;
  240 
  241         MGETHDR(mrep, M_WAIT, MT_DATA);
  242         mrep->m_len = 0;
  243 
  244         xdrmbuf_create(&xdrs, mrep, XDR_ENCODE);
  245 
  246         if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
  247             msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
  248                 if (!xdr_replymsg(&xdrs, msg))
  249                         stat = FALSE;
  250                 else
  251                         xdrmbuf_append(&xdrs, m);
  252         } else {
  253                 stat = xdr_replymsg(&xdrs, msg);
  254         }
  255 
  256         if (stat) {
  257                 m_fixhdr(mrep);
  258                 error = sosend(xprt->xp_socket, addr, NULL, mrep, NULL,
  259                     0, curthread);
  260                 if (!error) {
  261                         stat = TRUE;
  262                 }
  263         } else {
  264                 m_freem(mrep);
  265         }
  266 
  267         XDR_DESTROY(&xdrs);
  268         xprt->xp_p2 = NULL;
  269 
  270         return (stat);
  271 }
  272 
  273 static void
  274 svc_dg_destroy(SVCXPRT *xprt)
  275 {
  276 
  277         SOCKBUF_LOCK(&xprt->xp_socket->so_rcv);
  278         soupcall_clear(xprt->xp_socket, SO_RCV);
  279         SOCKBUF_UNLOCK(&xprt->xp_socket->so_rcv);
  280 
  281         sx_destroy(&xprt->xp_lock);
  282         if (xprt->xp_socket)
  283                 (void)soclose(xprt->xp_socket);
  284 
  285         if (xprt->xp_netid)
  286                 (void) mem_free(xprt->xp_netid, strlen(xprt->xp_netid) + 1);
  287         svc_xprt_free(xprt);
  288 }
  289 
  290 static bool_t
  291 /*ARGSUSED*/
  292 svc_dg_control(xprt, rq, in)
  293         SVCXPRT *xprt;
  294         const u_int     rq;
  295         void            *in;
  296 {
  297 
  298         return (FALSE);
  299 }
  300 
  301 static int
  302 svc_dg_soupcall(struct socket *so, void *arg, int waitflag)
  303 {
  304         SVCXPRT *xprt = (SVCXPRT *) arg;
  305 
  306         xprt_active(xprt);
  307         return (SU_OK);
  308 }

Cache object: af89596c97db3a84f6d7c83fb23a37a8


[ 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.