示例#1
0
static bool_t Svcudp_recv(register SVCXPRT * xprt, struct rpc_msg *msg)
{
  register struct Svcudp_data *su = Su_data(xprt);
  register XDR *xdrs = &(su->su_xdrs);
  register int rlen;

 again:
  xprt->xp_addrlen = sizeof(struct sockaddr_in);
#ifdef _FREEBSD
  rlen = recvfrom(xprt->xp_fd, rpc_buffer(xprt), (int)su->su_iosz,
                  0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
#else
  rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int)su->su_iosz,
                  0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
#endif

  if(rlen == -1 && errno == EINTR)
    goto again;

  if(rlen == -1 || rlen < 4 * sizeof(u_int32_t))
    return (FALSE);

  xdrs->x_op = XDR_DECODE;

  XDR_SETPOS(xdrs, 0);

  if(!xdr_callmsg(xdrs, msg))
    return (FALSE);

  su->su_xid = msg->rm_xid;

  return (TRUE);
}
示例#2
0
/*
 * Usage:
 *	xprt = svcudp_create(sock);
 *
 * If sock<0 then a socket is created, else sock is used.
 * If the socket, sock is not bound to a port then svcudp_create
 * binds it to an arbitrary port.  In any (successful) case,
 * xprt->xp_sock is the registered socket number and xprt->xp_port is the
 * associated port number.
 * Once *xprt is initialized, it is registered as a transporter;
 * see (svc.h, xprt_register).
 * The routines returns NULL if a problem occurred.
 */
SVCXPRT *
svcudp_bufcreate(
	register int sock,
	unsigned sendsz,
	unsigned recvsz)
{
	bool_t madesock = FALSE;
	register SVCXPRT *xprt;
	register struct svcudp_data *su;
	struct sockaddr_in addr;
	socklen_t len = sizeof(struct sockaddr_in);

	if (sock == RPC_ANYSOCK) {
		if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
			perror("svcudp_create: socket creation problem");
			return ((SVCXPRT *)NULL);
		}
		madesock = TRUE;
	}
	bzero((char *)&addr, sizeof (addr));
	addr.sin_family = AF_INET;
	if (bindresvport(sock, &addr)) {
		addr.sin_port = 0;
		(void)bind(sock, (struct sockaddr *)&addr, len);
	}
	if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
		perror("svcudp_create - cannot getsockname");
		if (madesock)
			(void)close(sock);
		return ((SVCXPRT *)NULL);
	}
	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
	if (xprt == NULL) {
		(void)fprintf(stderr, "svcudp_create: out of memory\n");
		return (NULL);
	}
	su = (struct svcudp_data *)mem_alloc(sizeof(*su));
	if (su == NULL) {
		(void)fprintf(stderr, "svcudp_create: out of memory\n");
		return (NULL);
	}
	su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
	if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
		(void)fprintf(stderr, "svcudp_create: out of memory\n");
		return (NULL);
	}
	xdrmem_create(
	    &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
	su->su_cache = NULL;
	xprt->xp_p2 = (char*)su;
	xprt->xp_verf.oa_base = su->su_verfbody;
	xprt->xp_ops = &svcudp_op;
	xprt->xp_port = ntohs(addr.sin_port);
	xprt->xp_sock = sock;
	xprt_register(xprt);
	return (xprt);
}
示例#3
0
/*
 * Set an entry in the cache
 */
static void
cache_set(SVCXPRT *xprt, u_long replylen)
{
	cache_ptr victim;	
	cache_ptr *vicp;
	struct svcudp_data *su = su_data(xprt);
	struct udp_cache *uc = (struct udp_cache *) su->su_cache;
	u_int loc;
	char *newbuf;

	/*
 	 * Find space for the new entry, either by
	 * reusing an old entry, or by mallocing a new one
	 */
	victim = uc->uc_fifo[uc->uc_nextvictim];
	if (victim != NULL) {
		loc = CACHE_LOC(xprt, victim->cache_xid);
		for (vicp = &uc->uc_entries[loc]; 
		  *vicp != NULL && *vicp != victim; 
		  vicp = &(*vicp)->cache_next) 
				;
		if (*vicp == NULL) {
			return;
		}
		*vicp = victim->cache_next;	/* remote from cache */
		newbuf = victim->cache_reply;
	} else {
		victim = malloc(sizeof(struct cache_node));
		if (victim == NULL) {
			return;
		}
		newbuf = malloc(su->su_iosz);
		if (newbuf == NULL) {
			free(victim);
			return;
		}
	}

	/*
	 * Store it away
	 */
	victim->cache_replylen = replylen;
	victim->cache_reply = rpc_buffer(xprt);
	rpc_buffer(xprt) = newbuf;
	xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE);
	victim->cache_xid = su->su_xid;
	victim->cache_proc = uc->uc_proc;
	victim->cache_vers = uc->uc_vers;
	victim->cache_prog = uc->uc_prog;
	victim->cache_addr = uc->uc_addr;
	loc = CACHE_LOC(xprt, victim->cache_xid);
	victim->cache_next = uc->uc_entries[loc];	
	uc->uc_entries[loc] = victim;
	uc->uc_fifo[uc->uc_nextvictim++] = victim;
	uc->uc_nextvictim %= uc->uc_size;
}
示例#4
0
文件: svc_udp.c 项目: PADL/krb5
static bool_t
svcudp_recv(
	SVCXPRT *xprt,
	struct rpc_msg *msg)
{
        struct msghdr dummy;
	struct iovec dummy_iov[1];
	struct svcudp_data *su = su_data(xprt);
	XDR *xdrs = &su->su_xdrs;
	int rlen;
	char *reply;
	uint32_t replylen;
	socklen_t addrlen;

    again:
	memset(&dummy, 0, sizeof(dummy));
	dummy_iov[0].iov_base = rpc_buffer(xprt);
	dummy_iov[0].iov_len = (int) su->su_iosz;
	dummy.msg_iov = dummy_iov;
	dummy.msg_iovlen = 1;
	dummy.msg_namelen = xprt->xp_laddrlen = sizeof(struct sockaddr_in);
	dummy.msg_name = (char *) &xprt->xp_laddr;
	rlen = recvmsg(xprt->xp_sock, &dummy, MSG_PEEK);
	if (rlen == -1) {
	     if (errno == EINTR)
		  goto again;
	     else
		  return (FALSE);
	}

	addrlen = sizeof(struct sockaddr_in);
	rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz,
	    0, (struct sockaddr *)&(xprt->xp_raddr), &addrlen);
	if (rlen == -1 && errno == EINTR)
		goto again;
	if (rlen < (int) (4*sizeof(uint32_t)))
		return (FALSE);
	xprt->xp_addrlen = addrlen;
	xdrs->x_op = XDR_DECODE;
	XDR_SETPOS(xdrs, 0);
	if (! xdr_callmsg(xdrs, msg))
		return (FALSE);
	su->su_xid = msg->rm_xid;
	if (su->su_cache != NULL) {
		if (cache_get(xprt, msg, &reply, &replylen)) {
			(void) sendto(xprt->xp_sock, reply, (int) replylen, 0,
			  (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen);
			return (TRUE);
		}
	}
	return (TRUE);
}
示例#5
0
文件: svc_udp.c 项目: khallock/LDM
static bool_t
svcudp_reply(
	register SVCXPRT *xprt, 
	struct rpc_msg *msg) 
{
	register struct svcudp_data *su = su_data(xprt);
	register XDR *xdrs = &(su->su_xdrs);
	register int slen;
	register bool_t stat = FALSE;

	xdrs->x_op = XDR_ENCODE;
	XDR_SETPOS(xdrs, 0);
	msg->rm_xid = su->su_xid;
	if (xdr_replymsg(xdrs, msg)) {
		slen = (int)XDR_GETPOS(xdrs);
		if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
		    (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
		    == (ssize_t)slen) {
			stat = TRUE;
			if (su->su_cache) {
				cache_set(xprt, (unsigned long) slen);
			}
		}
	}
	return (stat);
}
示例#6
0
文件: svc_udp.c 项目: khallock/LDM
static bool_t
svcudp_recv(
	register SVCXPRT *xprt,
	struct rpc_msg *msg)
{
	register struct svcudp_data *su = su_data(xprt);
	register XDR *xdrs = &(su->su_xdrs);
	register ssize_t rlen;
	char *reply;
	unsigned long replylen;
	socklen_t len;

    again:
	len = xprt->xp_addrlen = sizeof(struct sockaddr_in);
	rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz,
	    0, (struct sockaddr *)&(xprt->xp_raddr), &len);
	if (rlen == -1 && errno == EINTR)
		goto again;
	if (rlen < 4*sizeof(uint32_t))
		return (FALSE);
	xprt->xp_addrlen = len;
	xdrs->x_op = XDR_DECODE;
	XDR_SETPOS(xdrs, 0);
	if (! xdr_callmsg(xdrs, msg))
		return (FALSE);
	su->su_xid = msg->rm_xid;
	if (su->su_cache != NULL) {
		if (cache_get(xprt, msg, &reply, &replylen)) {
			(void) sendto(xprt->xp_sock, reply, replylen, 0,
			  (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen);
			return (TRUE);
		}
	}
	return (TRUE);
}
示例#7
0
static bool_t
svc_dg_reply(SVCXPRT *xprt, struct rpc_msg *msg)
{
	struct svc_dg_data *su;
	XDR *xdrs;
	bool_t stat = FALSE;
	size_t slen;

	_DIAGASSERT(xprt != NULL);
	_DIAGASSERT(msg != NULL);

	su = su_data(xprt);
	xdrs = &(su->su_xdrs);

	xdrs->x_op = XDR_ENCODE;
	XDR_SETPOS(xdrs, 0);
	msg->rm_xid = su->su_xid;
	if (xdr_replymsg(xdrs, msg)) {
		slen = XDR_GETPOS(xdrs);
		if (sendto(xprt->xp_fd, rpc_buffer(xprt), slen, 0,
		    (struct sockaddr *)xprt->xp_rtaddr.buf,
		    (socklen_t)xprt->xp_rtaddr.len) == (ssize_t) slen) {
			stat = TRUE;
			if (su->su_cache)
				cache_set(xprt, slen);
		}
	}
	return (stat);
}
示例#8
0
void Svcudp_soft_destroy(register SVCXPRT * xprt)
{
  register struct Svcudp_data *su = Su_data(xprt);

  //XDR_DESTROY(&(su->su_xdrs));
  Mem_Free(rpc_buffer(xprt));
  Mem_Free((caddr_t) su);
  Mem_Free((caddr_t) xprt);
}
示例#9
0
static void Svcudp_destroy(register SVCXPRT * xprt)
{
  register struct Svcudp_data *su = Su_data(xprt);

  Xprt_unregister(xprt);
  (void)close(xprt->XP_SOCK);
  XDR_DESTROY(&(su->su_xdrs));
  Mem_Free(rpc_buffer(xprt));
  Mem_Free((caddr_t) su);
  Mem_Free((caddr_t) xprt);

}
示例#10
0
static bool_t
svc_dg_recv(SVCXPRT *xprt, struct rpc_msg *msg)
{
	struct svc_dg_data *su;
	XDR *xdrs;
	char *reply;
	struct sockaddr_storage ss;
	socklen_t alen;
	size_t replylen;
	ssize_t rlen;

	_DIAGASSERT(xprt != NULL);
	_DIAGASSERT(msg != NULL);

	su = su_data(xprt);
	xdrs = &(su->su_xdrs);

again:
	alen = sizeof (struct sockaddr_storage);
	rlen = recvfrom(xprt->xp_fd, rpc_buffer(xprt), su->su_iosz, 0,
	    (struct sockaddr *)(void *)&ss, &alen);
	if (rlen == -1 && errno == EINTR)
		goto again;
	if (rlen == -1 || (rlen < (ssize_t)(4 * sizeof (u_int32_t))))
		return (FALSE);
	if (xprt->xp_rtaddr.len < alen) {
		if (xprt->xp_rtaddr.len != 0)
			mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.len);
		xprt->xp_rtaddr.buf = mem_alloc(alen);
		xprt->xp_rtaddr.len = alen;
	}
	memcpy(xprt->xp_rtaddr.buf, &ss, alen);
#ifdef PORTMAP
	if (ss.ss_family == AF_INET) {
		xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf;
		xprt->xp_addrlen = sizeof (struct sockaddr_in);
	}
#endif
	xdrs->x_op = XDR_DECODE;
	XDR_SETPOS(xdrs, 0);
	if (! xdr_callmsg(xdrs, msg)) {
		return (FALSE);
	}
	su->su_xid = msg->rm_xid;
	if (su->su_cache != NULL) {
		if (cache_get(xprt, msg, &reply, &replylen)) {
			(void)sendto(xprt->xp_fd, reply, replylen, 0,
			    (struct sockaddr *)(void *)&ss, alen);
			return (FALSE);
		}
	}
	return (TRUE);
}
示例#11
0
文件: svc_udp.c 项目: khallock/LDM
static void
svcudp_destroy(
	register SVCXPRT *xprt)
{
	register struct svcudp_data *su = su_data(xprt);

	xprt_unregister(xprt);
	(void)close(xprt->xp_sock);
	XDR_DESTROY(&(su->su_xdrs));
	mem_free(rpc_buffer(xprt), su->su_iosz);
	mem_free((char*)su, sizeof(struct svcudp_data));
	mem_free((char*)xprt, sizeof(SVCXPRT));
}
示例#12
0
static void
svcudp_destroy(SVCXPRT *xprt)
{
	struct svcudp_data *su = su_data(xprt);

	xprt_unregister(xprt);
	if (xprt->xp_sock != -1)
		(void)close(xprt->xp_sock);
	xprt->xp_sock = -1;
	XDR_DESTROY(&(su->su_xdrs));
	mem_free(rpc_buffer(xprt), su->su_iosz);
	mem_free((caddr_t)su, sizeof(struct svcudp_data));
	mem_free((caddr_t)xprt, sizeof(SVCXPRT));
}
示例#13
0
static void Svcudp_destroy(register SVCXPRT * xprt)
{
  register struct Svcudp_data *su = Su_data(xprt);

  Xprt_unregister(xprt);
#ifdef _FREEBSD
  (void)close(xprt->xp_fd);
#else
  (void)close(xprt->xp_sock);
#endif
  XDR_DESTROY(&(su->su_xdrs));
  Mem_Free(rpc_buffer(xprt));
  Mem_Free((caddr_t) su);
  Mem_Free((caddr_t) xprt);

}
示例#14
0
static void
svcudp_destroy(register SVCXPRT *xprt)
{
    register struct svcudp_data *su = su_data(xprt);

    xprt_unregister(xprt);
    if (xprt->xp_sock != INVALID_SOCKET)
        (void)closesocket(xprt->xp_sock);
    xprt->xp_sock = INVALID_SOCKET;
    if (xprt->xp_auth != NULL) {
        SVCAUTH_DESTROY(xprt->xp_auth);
        xprt->xp_auth = NULL;
    }
    XDR_DESTROY(&(su->su_xdrs));
    mem_free(rpc_buffer(xprt), su->su_iosz);
    mem_free((caddr_t)su, sizeof(struct svcudp_data));
    mem_free((caddr_t)xprt, sizeof(SVCXPRT));
}
示例#15
0
static bool_t svcudp_reply(
    register SVCXPRT *xprt,
    struct rpc_msg *msg)
{
    register struct svcudp_data *su = su_data(xprt);
    register XDR *xdrs = &(su->su_xdrs);
    register int slen;
    register bool_t stat = FALSE;

    xdrproc_t xdr_results;
    caddr_t xdr_location;
    bool_t has_args;

    if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
            msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
        has_args = TRUE;
        xdr_results = msg->acpted_rply.ar_results.proc;
        xdr_location = msg->acpted_rply.ar_results.where;

        msg->acpted_rply.ar_results.proc = xdr_void;
        msg->acpted_rply.ar_results.where = NULL;
    } else
        has_args = FALSE;

    xdrs->x_op = XDR_ENCODE;
    XDR_SETPOS(xdrs, 0);
    msg->rm_xid = su->su_xid;
    if (xdr_replymsg(xdrs, msg) &&
            (!has_args ||
             (SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) {
        slen = (int)XDR_GETPOS(xdrs);
        if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
                   (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
                == slen) {
            stat = TRUE;
            if (su->su_cache && slen >= 0) {
                cache_set(xprt, (uint32_t) slen);
            }
        }
    }
    return (stat);
}
示例#16
0
static bool_t Svcudp_reply(register SVCXPRT * xprt, struct rpc_msg *msg)
{
  register struct Svcudp_data *su = Su_data(xprt);
  register XDR *xdrs = &(su->su_xdrs);
  register int slen;
  xdrproc_t xdr_proc;
  caddr_t xdr_where;

  xdrs->x_op = XDR_ENCODE;
  XDR_SETPOS(xdrs, 0);
  msg->rm_xid = su->su_xid;

  if(msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS)
    {
      xdr_proc = msg->acpted_rply.ar_results.proc;
      xdr_where = msg->acpted_rply.ar_results.where;
      msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
      msg->acpted_rply.ar_results.where = NULL;

      if(!xdr_replymsg(xdrs, msg) ||
         !SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_proc, xdr_where))
        return (FALSE);
    }
  else if(!xdr_replymsg(xdrs, msg))
    {
      return (FALSE);
    }
  slen = (int)XDR_GETPOS(xdrs);

#ifdef _FREEBSD
  if(sendto(xprt->xp_fd,
#else
  if(sendto(xprt->xp_sock,
#endif
            rpc_buffer(xprt),
            slen, 0, (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) != slen)
    {
      return (FALSE);
    }
  return (TRUE);
}
示例#17
0
static bool_t Svcudp_reply(register SVCXPRT * xprt, struct rpc_msg *msg)
{
  register struct Svcudp_data *su = Su_data(xprt);
  register XDR *xdrs = &(su->su_xdrs);
  register int slen;
  xdrproc_t xdr_proc;
  caddr_t xdr_where;

  xdrs->x_op = XDR_ENCODE;
  XDR_SETPOS(xdrs, 0);
  msg->rm_xid = su->su_xid;

  if(msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS)
    {
      xdr_proc = msg->acpted_rply.ar_results.proc;
      xdr_where = msg->acpted_rply.ar_results.where;
      msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
      msg->acpted_rply.ar_results.where = NULL;

      if(!xdr_replymsg(xdrs, msg) ||
         !SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_proc, xdr_where))
        return (FALSE);
    }
  else if(!xdr_replymsg(xdrs, msg))
    {
      return (FALSE);
    }
  slen = (int)XDR_GETPOS(xdrs);

  if(sendto(xprt->XP_SOCK,
            rpc_buffer(xprt),
            slen, 0, (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) != slen)
    {
      LogInfo(COMPONENT_DISPATCH, "EAGAIN indicates UDP buffer is full and not"
               " allowed to block. sendto() returned %s", strerror(errno));
      return (FALSE);
    }
  return (TRUE);
}
示例#18
0
static void
svc_dg_destroy(SVCXPRT *xprt)
{
	struct svc_dg_data *su;

	_DIAGASSERT(xprt != NULL);

	su = su_data(xprt);

	xprt_unregister(xprt);
	if (xprt->xp_fd != -1)
		(void)close(xprt->xp_fd);
	XDR_DESTROY(&(su->su_xdrs));
	(void) mem_free(rpc_buffer(xprt), su->su_iosz);
	(void) mem_free(su, sizeof (*su));
	if (xprt->xp_rtaddr.buf)
		(void) mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.maxlen);
	if (xprt->xp_ltaddr.buf)
		(void) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen);
	if (xprt->xp_tp)
		(void) free(xprt->xp_tp);
	(void) mem_free(xprt, sizeof (SVCXPRT));
}
示例#19
0
void FreeXprt(SVCXPRT *xprt)
{
  if(!xprt)
    {
      LogFullDebug(COMPONENT_RPC,
                   "Attempt to free NULL xprt");
      return;
      
    }

  LogFullDebug(COMPONENT_RPC,
               "FreeXprt xprt=%p", xprt);
  if(xprt->xp_ops == &Svcudp_op)
    {
      xp_free(Su_data(xprt));
      xp_free(rpc_buffer(xprt));
    }
  else if (xprt->xp_ops == &Svctcp_op)
    {
      struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1;
      XDR_DESTROY(&(cd->xdrs));
      xp_free(xprt->xp_p1); /* cd */
    }
  else if (xprt->xp_ops == &Svctcp_rendezvous_op)
    {
      xp_free(xprt->xp_p1); /* r */
    }
  else
    {
      LogCrit(COMPONENT_RPC,
              "Attempt to free unknown xprt %p",
              xprt);
      return;
    }

  Mem_Free(xprt);
}
示例#20
0
SVCXPRT *
svc_dg_ncreate(int fd, u_int sendsize, u_int recvsize)
{
    SVCXPRT *xprt;
    struct svc_dg_data *su = NULL;
    struct __rpc_sockinfo si;
    struct sockaddr_storage ss;
    socklen_t slen;
    uint32_t oflags;

    if (!__rpc_fd2sockinfo(fd, &si)) {
        __warnx(TIRPC_DEBUG_FLAG_SVC_DG,
                svc_dg_str, svc_dg_err1);
        return (NULL);
    }
    /*
     * Find the receive and the send size
     */
    sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
    recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
    if ((sendsize == 0) || (recvsize == 0)) {
        __warnx(TIRPC_DEBUG_FLAG_SVC_DG,
                svc_dg_str, svc_dg_err2);
        return (NULL);
    }

    xprt = mem_alloc(sizeof (SVCXPRT));
    if (xprt == NULL)
        goto freedata;
    memset(xprt, 0, sizeof (SVCXPRT));

    /* Init SVCXPRT locks, etc */
    mutex_init(&xprt->xp_lock, NULL);
    mutex_init(&xprt->xp_auth_lock, NULL);

    su = mem_alloc(sizeof (*su));
    if (su == NULL)
        goto freedata;
    su->su_iosz = ((MAX(sendsize, recvsize) + 3) / 4) * 4;
    if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL)
        goto freedata;
    xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz,
                  XDR_DECODE);

    su->su_cache = NULL;
    xprt->xp_flags = SVC_XPRT_FLAG_NONE;
    xprt->xp_refcnt = 1;
    xprt->xp_fd = fd;
    xprt->xp_p2 = su;
    svc_dg_ops(xprt);
    xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage);

    slen = sizeof ss;
    if (getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0)
        goto freedata;

    __rpc_set_netbuf(&xprt->xp_ltaddr, &ss, slen);

    switch (ss.ss_family) {
    case AF_INET:
        xprt->xp_port = ntohs(((struct sockaddr_in *) &ss)->sin_port);
        break;
#ifdef INET6
    case AF_INET6:
        xprt->xp_port = ntohs(((struct sockaddr_in6 *) &ss)->sin6_port);
        break;
#endif
    case AF_LOCAL:
        /* no port */
        break;
    default:
        break;
    }

    /* Enable reception of IP*_PKTINFO control msgs */
    svc_dg_enable_pktinfo(fd, &si);

    /* Make reachable */
    xprt->xp_p5 = rpc_dplx_lookup_rec(xprt->xp_fd,
                                      RPC_DPLX_FLAG_NONE, &oflags); /* ref+1 */
    svc_rqst_init_xprt(xprt);

    /* Conditional xprt_register */
    if (! (__svc_params->flags & SVC_FLAG_NOREG_XPRTS))
        xprt_register(xprt);

    return (xprt);
freedata:
    __warnx(TIRPC_DEBUG_FLAG_SVC_DG,
            svc_dg_str, __no_mem_str);
    if (xprt) {
        if (su)
            (void) mem_free(su, sizeof (*su));
        svc_rqst_finalize_xprt(xprt, SVC_RQST_FLAG_NONE);
        (void) mem_free(xprt, sizeof (SVCXPRT));
    }
    return (NULL);
}
示例#21
0
SVCXPRT *Svcudp_bufcreate(register int sock, u_int sendsz, u_int recvsz)
{
  bool_t madesock = FALSE;
  register SVCXPRT *xprt;
  register struct Svcudp_data *su;
  struct sockaddr_in addr;
  unsigned long len = sizeof(struct sockaddr_in);

  if(sock == RPC_ANYSOCK)
    {
      if((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
        {
          perror("Svcudp_create: socket creation problem");
          return ((SVCXPRT *) NULL);
        }
      madesock = TRUE;
    }

  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  if(bindresvport(sock, &addr))
    {
      addr.sin_port = 0;
      (void)bind(sock, (struct sockaddr *)&addr, len);
    }

  if(getsockname(sock, (struct sockaddr *)&addr, (socklen_t *) & len) != 0)
    {
      perror("Svcudp_create - cannot getsockname");
      if(madesock)
        (void)close(sock);
      return ((SVCXPRT *) NULL);
    }

  xprt = (SVCXPRT *) Mem_Alloc(sizeof(SVCXPRT));
  if(xprt == NULL)
    {
      return (NULL);
    }

  su = (struct Svcudp_data *)Mem_Alloc(sizeof(*su));

  if(su == NULL)
    {
      return (NULL);
    }
  su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
  if((rpc_buffer(xprt) = Mem_Alloc(su->su_iosz)) == NULL)
    {
      return (NULL);
    }

  xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
  xprt->xp_p2 = (caddr_t) su;
  xprt->xp_verf.oa_base = su->su_verfbody;
  xprt->xp_ops = &Svcudp_op;
  xprt->xp_port = ntohs(addr.sin_port);
#ifdef _FREEBSD
  xprt->xp_fd = sock;
#else
  xprt->xp_sock = sock;
#endif

  Xprt_register(xprt);

  return (xprt);
}
示例#22
0
/*
 * Usage:
 *	xprt = svcudp_create(sock);
 *
 * If sock<0 then a socket is created, else sock is used.
 * If the socket, sock is not bound to a port then svcudp_create
 * binds it to an arbitrary port.  In any (successful) case,
 * xprt->xp_sock is the registered socket number and xprt->xp_port is the
 * associated port number.
 * Once *xprt is initialized, it is registered as a transporter;
 * see (svc.h, xprt_register).
 * The routines returns NULL if a problem occurred.
 */
SVCXPRT *
svcudp_bufcreate(int sock, u_int sendsz, u_int recvsz)
{
	bool_t madesock = FALSE;
	SVCXPRT *xprt;
	struct svcudp_data *su;
	struct sockaddr_in addr;
	socklen_t len = sizeof(struct sockaddr_in);

	if (sock == RPC_ANYSOCK) {
		if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
			return (NULL);
		madesock = TRUE;
	}
	memset(&addr, 0, sizeof (addr));
	addr.sin_len = sizeof(struct sockaddr_in);
	addr.sin_family = AF_INET;
	if (bindresvport(sock, &addr)) {
		addr.sin_port = 0;
		(void)bind(sock, (struct sockaddr *)&addr, len);
	}
	if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
		if (madesock)
			(void)close(sock);
		return (NULL);
	}
	xprt = malloc(sizeof(SVCXPRT));
	if (xprt == NULL) {
		if (madesock)
			(void)close(sock);
		return (NULL);
	}
	su = malloc(sizeof(*su));
	if (su == NULL) {
		if (madesock)
			(void)close(sock);
		free(xprt);
		return (NULL);
	}
	su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
	if ((rpc_buffer(xprt) = malloc(su->su_iosz)) == NULL) {
		if (madesock)
			(void)close(sock);
		free(xprt);
		free(su);
		return (NULL);
	}
	xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz,
	    XDR_DECODE);
	su->su_cache = NULL;
	xprt->xp_p2 = (caddr_t)su;
	xprt->xp_verf.oa_base = su->su_verfbody;
	xprt->xp_ops = &svcudp_op;
	xprt->xp_port = ntohs(addr.sin_port);
	xprt->xp_sock = sock;
	if (__xprt_register(xprt) == 0) {
		if (madesock)
			(void)close(sock);
		free(rpc_buffer(xprt));
		free(xprt);
		free(su);
		return (NULL);
	}
	return (xprt);
}
示例#23
0
文件: svc_udp.c 项目: 16rd/rt-n56u
/*
 * Usage:
 *      xprt = svcudp_create(sock);
 *
 * If sock<0 then a socket is created, else sock is used.
 * If the socket, sock is not bound to a port then svcudp_create
 * binds it to an arbitrary port.  In any (successful) case,
 * xprt->xp_sock is the registered socket number and xprt->xp_port is the
 * associated port number.
 * Once *xprt is initialized, it is registered as a transporter;
 * see (svc.h, xprt_register).
 * The routines returns NULL if a problem occurred.
 */
SVCXPRT *
svcudp_bufcreate (int sock, u_int sendsz, u_int recvsz)
{
  bool_t madesock = FALSE;
  SVCXPRT *xprt;
  struct svcudp_data *su;
  struct sockaddr_in addr;
  socklen_t len = sizeof (struct sockaddr_in);
  int pad;
  void *buf;

  if (sock == RPC_ANYSOCK)
    {
      if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
	{
	  perror (_("svcudp_create: socket creation problem"));
	  return (SVCXPRT *) NULL;
	}
      madesock = TRUE;
    }
  memset ((char *) &addr, 0, sizeof (addr));
  addr.sin_family = AF_INET;
  if (bindresvport (sock, &addr))
    {
      addr.sin_port = 0;
      (void) bind (sock, (struct sockaddr *) &addr, len);
    }
  if (getsockname (sock, (struct sockaddr *) &addr, &len) != 0)
    {
      perror (_("svcudp_create - cannot getsockname"));
      if (madesock)
	(void) close (sock);
      return (SVCXPRT *) NULL;
    }
  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
  su = (struct svcudp_data *) mem_alloc (sizeof (*su));
  buf = mem_alloc (((MAX (sendsz, recvsz) + 3) / 4) * 4);
  if (xprt == NULL || su == NULL || buf == NULL)
    {
#ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
	(void) fwprintf (stderr, L"%s", _("svcudp_create: out of memory\n"));
      else
#endif
	(void) fputs (_("svcudp_create: out of memory\n"), stderr);
      mem_free (xprt, sizeof (SVCXPRT));
      mem_free (su, sizeof (*su));
      mem_free (buf, ((MAX (sendsz, recvsz) + 3) / 4) * 4);
      return NULL;
    }
  su->su_iosz = ((MAX (sendsz, recvsz) + 3) / 4) * 4;
  rpc_buffer (xprt) = buf;
  xdrmem_create (&(su->su_xdrs), rpc_buffer (xprt), su->su_iosz, XDR_DECODE);
  su->su_cache = NULL;
  xprt->xp_p2 = (caddr_t) su;
  xprt->xp_verf.oa_base = su->su_verfbody;
  xprt->xp_ops = &svcudp_op;
  xprt->xp_port = ntohs (addr.sin_port);
  xprt->xp_sock = sock;

#ifdef IP_PKTINFO
  if ((sizeof (struct iovec) + sizeof (struct msghdr)
       + sizeof(struct cmsghdr) + sizeof (struct in_pktinfo))
      > sizeof (xprt->xp_pad))
    {
# ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
	(void) fwprintf (stderr, L"%s",
			   _("svcudp_create: xp_pad is too small for IP_PKTINFO\n"));
      else
# endif
	(void) fputs (_("svcudp_create: xp_pad is too small for IP_PKTINFO\n"),
		      stderr);
      return NULL;
    }
  pad = 1;
  if (setsockopt (sock, SOL_IP, IP_PKTINFO, (void *) &pad,
		  sizeof (pad)) == 0)
    /* Set the padding to all 1s. */
    pad = 0xff;
  else
#endif
    /* Clear the padding. */
    pad = 0;
  memset (&xprt->xp_pad [0], pad, sizeof (xprt->xp_pad));

  xprt_register (xprt);
  return xprt;
}
示例#24
0
文件: svc_udp.c 项目: PADL/krb5
/*
 * Usage:
 *	xprt = svcudp_create(sock);
 *
 * If sock<0 then a socket is created, else sock is used.
 * If the socket, sock is not bound to a port then svcudp_create
 * binds it to an arbitrary port.  In any (successful) case,
 * xprt->xp_sock is the registered socket number and xprt->xp_port is the
 * associated port number.
 * Once *xprt is initialized, it is registered as a transporter;
 * see (svc.h, xprt_register).
 * The routines returns NULL if a problem occurred.
 */
SVCXPRT *
svcudp_bufcreate(
	int sock,
	u_int sendsz,
	u_int recvsz)
{
	bool_t madesock = FALSE;
	SVCXPRT *xprt;
	struct svcudp_data *su;
	struct sockaddr_storage ss;
	struct sockaddr *sa = (struct sockaddr *)&ss;
	socklen_t len;

	if (sock == RPC_ANYSOCK) {
		if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
			perror("svcudp_create: socket creation problem");
			return ((SVCXPRT *)NULL);
		}
		set_cloexec_fd(sock);
		madesock = TRUE;
		memset(&ss, 0, sizeof(ss));
		sa->sa_family = AF_INET;
	} else {
		len = sizeof(struct sockaddr_storage);
		if (getsockname(sock, sa, &len) < 0) {
			perror("svcudp_create - cannot getsockname");
			return ((SVCXPRT *)NULL);
		}
	}

	if (bindresvport_sa(sock, sa)) {
		sa_setport(sa, 0);
		(void)bind(sock, sa, sa_socklen(sa));
	}
	len = sizeof(struct sockaddr_storage);
	if (getsockname(sock, sa, &len) != 0) {
		perror("svcudp_create - cannot getsockname");
		if (madesock)
			(void)close(sock);
		return ((SVCXPRT *)NULL);
	}
	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
	if (xprt == NULL) {
		(void)fprintf(stderr, "svcudp_create: out of memory\n");
		return (NULL);
	}
	su = (struct svcudp_data *)mem_alloc(sizeof(*su));
	if (su == NULL) {
		(void)fprintf(stderr, "svcudp_create: out of memory\n");
		return (NULL);
	}
	su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
	if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
		(void)fprintf(stderr, "svcudp_create: out of memory\n");
		return (NULL);
	}
	xdrmem_create(
	    &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
	su->su_cache = NULL;
	xprt->xp_p2 = (caddr_t)su;
	xprt->xp_auth = NULL;
	xprt->xp_verf.oa_base = su->su_verfbody;
	xprt->xp_ops = &svcudp_op;
	xprt->xp_port = sa_getport(sa);
	xprt->xp_sock = sock;
	xprt_register(xprt);
	return (xprt);
}
示例#25
0
/*
 * Duplicate xprt from original to copy.
 */
SVCXPRT *Svcxprt_copy(SVCXPRT *xprt_copy, SVCXPRT *xprt_orig)
{
  if(xprt_copy)
    FreeXprt(xprt_copy);

  xprt_copy = (SVCXPRT *) Mem_Alloc(sizeof(SVCXPRT));
  if(xprt_copy == NULL)
    goto fail_no_xprt;

  LogFullDebug(COMPONENT_RPC,
               "Svcxprt_copy copying xprt_orig=%p to xprt_copy=%p",
               xprt_orig, xprt_copy);
  memcpy(xprt_copy, xprt_orig, sizeof(SVCXPRT));
  xprt_copy->xp_p1 = NULL;
  xprt_copy->xp_p2 = NULL;

  if(xprt_orig->xp_ops == &Svcudp_op)
    {
      if(Su_data(xprt_orig))
        {
          struct Svcudp_data *su_o = Su_data(xprt_orig), *su_c;
          su_c = (struct Svcudp_data *) Mem_Alloc(sizeof(*su_c));
          if(!su_c)
            goto fail;
          Su_data_set(xprt_copy) = (void *) su_c;
          memcpy(su_c, su_o, sizeof(*su_c));

          rpc_buffer(xprt_copy) = Mem_Alloc_Label(su_c->su_iosz, "UDP IO Buffer");
          if(!rpc_buffer(xprt_copy))
            goto fail;
          xdrmem_create(&(su_c->su_xdrs), rpc_buffer(xprt_copy), su_c->su_iosz, XDR_DECODE);
          if(xprt_orig->xp_verf.oa_base == su_o->su_verfbody)
            xprt_copy->xp_verf.oa_base = su_c->su_verfbody;
          else
            xprt_copy->xp_verf.oa_base = xprt_orig->xp_verf.oa_base;
          xprt_copy->xp_verf.oa_flavor = xprt_orig->xp_verf.oa_flavor;
          xprt_copy->xp_verf.oa_length = xprt_orig->xp_verf.oa_length;
        }
      else
        goto fail;
    }
  else if (xprt_orig->xp_ops == &Svctcp_op)
    {
      struct tcp_conn *cd_o = (struct tcp_conn *)xprt_orig->xp_p1, *cd_c;
      cd_c = (struct tcp_conn *) Mem_Alloc(sizeof(*cd_c));
      if(!cd_c)
        goto fail;
      memcpy(cd_c, cd_o, sizeof(*cd_c));
      xprt_copy->xp_p1 = (void *) cd_c;
      xdrrec_create(&(cd_c->xdrs), 32768, 32768, (caddr_t) xprt_copy, Readtcp, Writetcp);
      if(xprt_orig->xp_verf.oa_base == cd_o->verf_body)
        xprt_copy->xp_verf.oa_base = cd_c->verf_body;
      else
        xprt_copy->xp_verf.oa_base = xprt_orig->xp_verf.oa_base;
      xprt_copy->xp_verf.oa_flavor = xprt_orig->xp_verf.oa_flavor;
      xprt_copy->xp_verf.oa_length = xprt_orig->xp_verf.oa_length;
    }
  else if (xprt_orig->xp_ops == &Svctcp_rendezvous_op)
    {
      goto fail;
    }
  else
    {
      LogDebug(COMPONENT_RPC,
               "Attempt to copy unknown xprt %p",
               xprt_orig);
      Mem_Free(xprt_copy);
      goto fail_no_xprt;
    }

  return xprt_copy;

 fail:
  FreeXprt(xprt_copy);
 fail_no_xprt:
  /* Let caller know about failure */
  LogCrit(COMPONENT_RPC,
          "Failed to copy xprt");
  svcerr_systemerr(xprt_orig);
  return NULL;
}
示例#26
0
SVCXPRT *
svc_dg_create(int fd, u_int sendsize, u_int recvsize)
{
	SVCXPRT *xprt;
	struct svc_dg_data *su = NULL;
	struct __rpc_sockinfo si;
	struct sockaddr_storage ss;
	socklen_t slen;

	if (!__rpc_fd2sockinfo(fd, &si)) {
		warnx(svc_dg_str, svc_dg_err1);
		return (NULL);
	}
	/*
	 * Find the receive and the send size
	 */
	sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
	recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
	if ((sendsize == 0) || (recvsize == 0)) {
		warnx(svc_dg_str, svc_dg_err2);
		return (NULL);
	}

	xprt = mem_alloc(sizeof (SVCXPRT));
	if (xprt == NULL)
		goto freedata;
	memset(xprt, 0, sizeof (SVCXPRT));

	su = mem_alloc(sizeof (*su));
	if (su == NULL)
		goto freedata;
	su->su_iosz = ((MAX(sendsize, recvsize) + 3) / 4) * 4;
	if ((rpc_buffer(xprt) = malloc(su->su_iosz)) == NULL)
		goto freedata;
	_DIAGASSERT(__type_fit(u_int, su->su_iosz));
	xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), (u_int)su->su_iosz,
		XDR_DECODE);
	su->su_cache = NULL;
	xprt->xp_fd = fd;
	xprt->xp_p2 = (caddr_t)(void *)su;
	xprt->xp_verf.oa_base = su->su_verfbody;
	svc_dg_ops(xprt);
	xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage);

	slen = sizeof ss;
	if (getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0)
		goto freedata;
	xprt->xp_ltaddr.buf = mem_alloc(sizeof (struct sockaddr_storage));
	xprt->xp_ltaddr.maxlen = sizeof (struct sockaddr_storage);
	xprt->xp_ltaddr.len = slen;
	memcpy(xprt->xp_ltaddr.buf, &ss, slen);

	xprt_register(xprt);
	return (xprt);
freedata:
	(void) warnx(svc_dg_str, __no_mem_str);
	if (xprt) {
		if (su)
			(void) mem_free(su, sizeof (*su));
		(void) mem_free(xprt, sizeof (SVCXPRT));
	}
	return (NULL);
}