Esempio n. 1
0
SVCXPRT *
svc_raw_ncreate(void)
{
	struct svc_raw_private *srp;

	/* VARIABLES PROTECTED BY svcraw_lock: svc_raw_private, srp */
	mutex_lock(&svcraw_lock);
	srp = svc_raw_private;
	if (srp == NULL) {
		srp = (struct svc_raw_private *)mem_alloc(sizeof(*srp));
		if (__rpc_rawcombuf == NULL)
			__rpc_rawcombuf = mem_alloc(UDPMSGSIZE * sizeof(char));
		srp->raw_buf = __rpc_rawcombuf;	/* Share it with the client */
		svc_raw_private = srp;
	}
	srp->server.xp_fd = FD_SETSIZE;
	srp->server.xp_port = 0;
	srp->server.xp_p3 = NULL;
	svc_raw_ops(&srp->server);
/* XXX check and or fixme */
#if 0
	srp->server.xp_verf.oa_base = srp->verf_body;
#endif
	xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
	xprt_register(&srp->server);
	mutex_unlock(&svcraw_lock);

	return (&srp->server);
}
Esempio n. 2
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1; //Default test result set to FAILED
	SVCXPRT *svcr = NULL;
	int fd = 0;

	//create a server
	svcr = svcfd_create(fd, 1024, 1024);

	//call routine
	xprt_register(svcr);

	//If we are here, xprt_register returned : test has passed
	test_status = 0;

	//clean up
	svc_destroy(svcr);

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
Esempio n. 3
0
/*
 * Usage:
 *      xprt = svcunix_create(sock, send_buf_size, recv_buf_size);
 *
 * Creates, registers, and returns a (rpc) unix based transporter.
 * Once *xprt is initialized, it is registered as a transporter
 * see (svc.h, xprt_register).  This routine returns
 * a NULL if a problem occurred.
 *
 * If sock<0 then a socket is created, else sock is used.
 * If the socket, sock is not bound to a port then svcunix_create
 * binds it to an arbitrary port.  The routine then starts a unix
 * listener on the socket's associated port.  In any (successful) case,
 * xprt->xp_sock is the registered socket number and xprt->xp_port is the
 * associated port number.
 *
 * Since unix streams do buffered io similar to stdio, the caller can specify
 * how big the send and receive buffers are via the second and third parms;
 * 0 => use the system default.
 */
SVCXPRT *
svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
{
  bool_t madesock = FALSE;
  SVCXPRT *xprt;
  struct unix_rendezvous *r;
  struct sockaddr_un addr;
  socklen_t len = sizeof (struct sockaddr_in);

  if (sock == RPC_ANYSOCK)
    {
      if ((sock = __socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
	{
	  perror (_("svc_unix.c - AF_UNIX socket creation problem"));
	  return (SVCXPRT *) NULL;
	}
      madesock = TRUE;
    }
  memset (&addr, '\0', sizeof (addr));
  addr.sun_family = AF_UNIX;
  len = strlen (path) + 1;
  memcpy (addr.sun_path, path, len);
  len += sizeof (addr.sun_family);

  bind (sock, (struct sockaddr *) &addr, len);

  if (getsockname (sock, (struct sockaddr *) &addr, &len) != 0
      || listen (sock, 2) != 0)
    {
      perror (_("svc_unix.c - cannot getsockname or listen"));
      if (madesock)
	__close (sock);
      return (SVCXPRT *) NULL;
    }

  r = (struct unix_rendezvous *) mem_alloc (sizeof (*r));
  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
  if (r == NULL || xprt == NULL)
    {
#ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
	__fwprintf (stderr, L"%s", _("svcunix_create: out of memory\n"));
      else
#endif
	fputs (_("svcunix_create: out of memory\n"), stderr);
      mem_free (r, sizeof (*r));
      mem_free (xprt, sizeof (SVCXPRT));
      return NULL;
    }
  r->sendsize = sendsize;
  r->recvsize = recvsize;
  xprt->xp_p2 = NULL;
  xprt->xp_p1 = (caddr_t) r;
  xprt->xp_verf = _null_auth;
  xprt->xp_ops = &svcunix_rendezvous_op;
  xprt->xp_port = -1;
  xprt->xp_sock = sock;
  xprt_register (xprt);
  return xprt;
}
Esempio n. 4
0
internal_function
makefd_xprt (int fd, u_int sendsize, u_int recvsize)
{
  SVCXPRT *xprt;
  struct tcp_conn *cd;

  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
  cd = (struct tcp_conn *) mem_alloc (sizeof (struct tcp_conn));
  if (xprt == (SVCXPRT *) NULL || cd == NULL)
    {
#ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
	(void) __fwprintf (stderr, L"%s",
			   _("svc_tcp: makefd_xprt: out of memory\n"));
      else
#endif
	(void) fputs (_("svc_tcp: makefd_xprt: out of memory\n"), stderr);
      mem_free (xprt, sizeof (SVCXPRT));
      mem_free (cd, sizeof (struct tcp_conn));
      return NULL;
    }
  cd->strm_stat = XPRT_IDLE;
  xdrrec_create (&(cd->xdrs), sendsize, recvsize,
		 (caddr_t) xprt, readtcp, writetcp);
  xprt->xp_p2 = NULL;
  xprt->xp_p1 = (caddr_t) cd;
  xprt->xp_verf.oa_base = cd->verf_body;
  xprt->xp_addrlen = 0;
  xprt->xp_ops = &svctcp_op;	/* truly deals with calls */
  xprt->xp_port = 0;		/* this is a connection, not a rendezvouser */
  xprt->xp_sock = fd;
  xprt_register (xprt);
  return xprt;
}
internal_function
makefd_xprt (int fd, u_int sendsize, u_int recvsize)
{
  SVCXPRT *xprt;
  struct tcp_conn *cd;

  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
  cd = (struct tcp_conn *) mem_alloc (sizeof (struct tcp_conn));
  if (xprt == (SVCXPRT *) NULL || cd == NULL)
    {
      (void) __fxprintf (NULL, "%s: %s", "svc_tcp: makefd_xprt",
			 _("out of memory\n"));
      mem_free (xprt, sizeof (SVCXPRT));
      mem_free (cd, sizeof (struct tcp_conn));
      return NULL;
    }
  cd->strm_stat = XPRT_IDLE;
  INTUSE(xdrrec_create) (&(cd->xdrs), sendsize, recvsize,
			 (caddr_t) xprt, readtcp, writetcp);
  xprt->xp_p2 = NULL;
  xprt->xp_p1 = (caddr_t) cd;
  xprt->xp_verf.oa_base = cd->verf_body;
  xprt->xp_addrlen = 0;
  xprt->xp_ops = &svctcp_op;	/* truly deals with calls */
  xprt->xp_port = 0;		/* this is a connection, not a rendezvouser */
  xprt->xp_sock = fd;
  xprt_register (xprt);
  return xprt;
}
Esempio n. 6
0
SVCXPRT *
svc_raw_create()
{
	struct svc_raw_private *srp;
/* VARIABLES PROTECTED BY svcraw_lock: svc_raw_private, srp */

	mutex_lock(&svcraw_lock);
	srp = svc_raw_private;
	if (srp == NULL) {
		srp = calloc(1, sizeof(*srp));
		if (srp == NULL)
			goto out;
		if (__rpc_rawcombuf == NULL)
			__rpc_rawcombuf = malloc(UDPMSGSIZE);
		if (__rpc_rawcombuf == NULL)
			goto out;
		srp->raw_buf = __rpc_rawcombuf; /* Share it with the client */
		svc_raw_private = srp;
	}
	srp->server.xp_fd = FD_SETSIZE;
	srp->server.xp_port = 0;
	srp->server.xp_p3 = NULL;
	svc_raw_ops(&srp->server);
	srp->server.xp_verf.oa_base = srp->verf_body;
	xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
	xprt_register(&srp->server);
	mutex_unlock(&svcraw_lock);
	return (&srp->server);
out:
	if (srp != NULL)
		free(srp);
	mutex_unlock(&svcraw_lock);
	return (NULL);
}
Esempio n. 7
0
/*
 * Usage:
 *      xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
 *
 * Creates, registers, and returns a (rpc) tcp based transporter.
 * Once *xprt is initialized, it is registered as a transporter
 * see (svc.h, xprt_register).  This routine returns
 * a NULL if a problem occurred.
 *
 * If sock<0 then a socket is created, else sock is used.
 * If the socket, sock is not bound to a port then svctcp_create
 * binds it to an arbitrary port.  The routine then starts a tcp
 * listener on the socket's associated port.  In any (successful) case,
 * xprt->xp_sock is the registered socket number and xprt->xp_port is the
 * associated port number.
 *
 * Since tcp streams do buffered io similar to stdio, the caller can specify
 * how big the send and receive buffers are via the second and third parms;
 * 0 => use the system default.
 */
SVCXPRT *
svctcp_create (int sock, u_int sendsize, u_int recvsize)
{
  bool_t madesock = FALSE;
  SVCXPRT *xprt;
  struct tcp_rendezvous *r;
  struct sockaddr_in addr;
  socklen_t len = sizeof (struct sockaddr_in);

  if (sock == RPC_ANYSOCK)
    {
      if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
	{
	  perror (_("svc_tcp.c - tcp 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) ||
      (listen (sock, 2) != 0))
    {
      perror (_("svc_tcp.c - cannot getsockname or listen"));
      if (madesock)
	(void) close (sock);
      return (SVCXPRT *) NULL;
    }
  r = (struct tcp_rendezvous *) mem_alloc (sizeof (*r));
  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
  if (r == NULL || xprt == NULL)
    {
#ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
	(void) __fwprintf (stderr, L"%s", _("svctcp_create: out of memory\n"));
      else
#endif
	(void) fputs (_("svctcp_create: out of memory\n"), stderr);
      mem_free (r, sizeof (*r));
      mem_free (xprt, sizeof (SVCXPRT));
      return NULL;
    }
  r->sendsize = sendsize;
  r->recvsize = recvsize;
  xprt->xp_p2 = NULL;
  xprt->xp_p1 = (caddr_t) r;
  xprt->xp_verf = _null_auth;
  xprt->xp_ops = &svctcp_rendezvous_op;
  xprt->xp_port = ntohs (addr.sin_port);
  xprt->xp_sock = sock;
  xprt_register (xprt);
  return xprt;
}
Esempio n. 8
0
/*
 * Usage:
 *	xprt = svc_vc_create(sock, send_buf_size, recv_buf_size);
 *
 * Creates, registers, and returns a (rpc) tcp based transporter.
 * Once *xprt is initialized, it is registered as a transporter
 * see (svc.h, xprt_register).  This routine returns
 * a NULL if a problem occurred.
 *
 * The filedescriptor passed in is expected to refer to a bound, but
 * not yet connected socket.
 *
 * Since streams do buffered io similar to stdio, the caller can specify
 * how big the send and receive buffers are via the second and third parms;
 * 0 => use the system default.
 */
SVCXPRT *
svc_vc_create(int fd, u_int sendsize, u_int recvsize)
{
	SVCXPRT *xprt = NULL;
	struct cf_rendezvous *r = NULL;
	struct __rpc_sockinfo si;
	struct sockaddr_storage sslocal;
	socklen_t slen;

	if (!__rpc_fd2sockinfo(fd, &si))
		return NULL;

	r = mem_alloc(sizeof(*r));
	if (r == NULL) {
		warnx("svc_vc_create: out of memory");
		goto cleanup_svc_vc_create;
	}
	r->sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
	r->recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
	r->maxrec = __svc_maxrec;
	xprt = mem_alloc(sizeof(SVCXPRT));
	if (xprt == NULL) {
		warnx("svc_vc_create: out of memory");
		goto cleanup_svc_vc_create;
	}
	xprt->xp_tp = NULL;
	xprt->xp_p1 = r;
	xprt->xp_p2 = NULL;
	xprt->xp_p3 = NULL;
	xprt->xp_verf = _null_auth;
	svc_vc_rendezvous_ops(xprt);
	xprt->xp_port = (u_short)-1;	/* It is the rendezvouser */
	xprt->xp_fd = fd;

	slen = sizeof (struct sockaddr_storage);
	if (_getsockname(fd, (struct sockaddr *)(void *)&sslocal, &slen) < 0) {
		warnx("svc_vc_create: could not retrieve local addr");
		goto cleanup_svc_vc_create;
	}

	xprt->xp_ltaddr.maxlen = xprt->xp_ltaddr.len = sslocal.ss_len;
	xprt->xp_ltaddr.buf = mem_alloc((size_t)sslocal.ss_len);
	if (xprt->xp_ltaddr.buf == NULL) {
		warnx("svc_vc_create: no mem for local addr");
		goto cleanup_svc_vc_create;
	}
	memcpy(xprt->xp_ltaddr.buf, &sslocal, (size_t)sslocal.ss_len);

	xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage);
	xprt_register(xprt);
	return (xprt);
cleanup_svc_vc_create:
	if (xprt)
		mem_free(xprt, sizeof(*xprt));
	if (r != NULL)
		mem_free(r, sizeof(*r));
	return (NULL);
}
Esempio n. 9
0
/*
 * Usage:
 *	xprt = svc_vc_create(sock, send_buf_size, recv_buf_size);
 *
 * Creates, registers, and returns a (rpc) tcp based transporter.
 * Once *xprt is initialized, it is registered as a transporter
 * see (svc.h, xprt_register).  This routine returns
 * a NULL if a problem occurred.
 *
 * The filedescriptor passed in is expected to refer to a bound, but
 * not yet connected socket.
 *
 * Since streams do buffered io similar to stdio, the caller can specify
 * how big the send and receive buffers are via the second and third parms;
 * 0 => use the system default.
 */
SVCXPRT *
svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
    size_t recvsize)
{
	SVCXPRT *xprt = NULL;
	struct sockaddr* sa;
	int error;

	SOCK_LOCK(so);
	if (so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED)) {
		SOCK_UNLOCK(so);
		CURVNET_SET(so->so_vnet);
		error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
		CURVNET_RESTORE();
		if (error)
			return (NULL);
		xprt = svc_vc_create_conn(pool, so, sa);
		free(sa, M_SONAME);
		return (xprt);
	}
	SOCK_UNLOCK(so);

	xprt = svc_xprt_alloc();
	sx_init(&xprt->xp_lock, "xprt->xp_lock");
	xprt->xp_pool = pool;
	xprt->xp_socket = so;
	xprt->xp_p1 = NULL;
	xprt->xp_p2 = NULL;
	xprt->xp_ops = &svc_vc_rendezvous_ops;

	CURVNET_SET(so->so_vnet);
	error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
	CURVNET_RESTORE();
	if (error) {
		goto cleanup_svc_vc_create;
	}

	memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
	free(sa, M_SONAME);

	xprt_register(xprt);

	solisten(so, -1, curthread);

	SOCKBUF_LOCK(&so->so_rcv);
	xprt->xp_upcallset = 1;
	soupcall_set(so, SO_RCV, svc_vc_soupcall, xprt);
	SOCKBUF_UNLOCK(&so->so_rcv);

	return (xprt);
cleanup_svc_vc_create:
	if (xprt) {
		sx_destroy(&xprt->xp_lock);
		svc_xprt_free(xprt);
	}
	return (NULL);
}
Esempio n. 10
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);
}
Esempio n. 11
0
SVCXPRT *
svc_dg_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
    size_t recvsize)
{
	SVCXPRT *xprt;
	struct __rpc_sockinfo si;
	struct sockaddr* sa;
	int error;

	if (!__rpc_socket2sockinfo(so, &si)) {
		printf(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)) {
		printf(svc_dg_str, svc_dg_err2);
		return (NULL);
	}

	xprt = svc_xprt_alloc();
	sx_init(&xprt->xp_lock, "xprt->xp_lock");
	xprt->xp_pool = pool;
	xprt->xp_socket = so;
	xprt->xp_p1 = NULL;
	xprt->xp_p2 = NULL;
	xprt->xp_ops = &svc_dg_ops;

	CURVNET_SET(so->so_vnet);
	error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
	CURVNET_RESTORE();
	if (error)
		goto freedata;

	memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
	free(sa, M_SONAME);

	xprt_register(xprt);

	SOCKBUF_LOCK(&so->so_rcv);
	soupcall_set(so, SO_RCV, svc_dg_soupcall, xprt);
	SOCKBUF_UNLOCK(&so->so_rcv);

	return (xprt);
freedata:
	(void) printf(svc_dg_str, __no_mem_str);
	if (xprt) {
		svc_xprt_free(xprt);
	}
	return (NULL);
}
Esempio n. 12
0
/*
 * Usage:
 *	xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
 *
 * Creates, registers, and returns a (rpc) tcp based transporter.
 * Once *xprt is initialized, it is registered as a transporter
 * see (svc.h, xprt_register).  This routine returns
 * a NULL if a problem occurred.
 *
 * If sock<0 then a socket is created, else sock is used.
 * If the socket, sock is not bound to a port then svctcp_create
 * binds it to an arbitrary port.  The routine then starts a tcp
 * listener on the socket's associated port.  In any (successful) case,
 * xprt->xp_sock is the registered socket number and xprt->xp_port is the
 * associated port number.
 *
 * Since tcp streams do buffered io similar to stdio, the caller can specify
 * how big the send and receive buffers are via the second and third parms;
 * 0 => use the system default.
 */
SVCXPRT *
svctcp_create(
	register int sock,
	unsigned sendsize,
	unsigned recvsize)
{
	bool_t madesock = FALSE;
	register SVCXPRT *xprt;
	register struct tcp_rendezvous *r;
	struct sockaddr_in addr;
	socklen_t len = (socklen_t)sizeof(struct sockaddr_in);

	if (sock == RPC_ANYSOCK) {
		if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
			perror("svctcp_.c - udp 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)  ||
	    (listen(sock, 2) != 0)) {
		perror("svctcp_.c - cannot getsockname or listen");
		if (madesock)
		       (void)close(sock);
		return ((SVCXPRT *)NULL);
	}
	r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
	if (r == NULL) {
		(void) fprintf(stderr, "svctcp_create: out of memory\n");
		return (NULL);
	}
	r->sendsize = sendsize;
	r->recvsize = recvsize;
	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
	if (xprt == NULL) {
		(void) fprintf(stderr, "svctcp_create: out of memory\n");
		return (NULL);
	}
	xprt->xp_p2 = NULL;
	xprt->xp_p1 = (char*)r;
	xprt->xp_verf = _null_auth;
	xprt->xp_ops = &svctcp_rendezvous_op;
	xprt->xp_port = ntohs(addr.sin_port);
	xprt->xp_sock = sock;
	xprt_register(xprt);
	return (xprt);
}
Esempio n. 13
0
SVCXPRT *
svc_raw_create(void)
{
	struct svc_raw_private *srp;
	bool_t flag1 = FALSE, flag2 = FALSE;

/* VARIABLES PROTECTED BY svcraw_lock: svc_raw_private, srp */
	(void) mutex_lock(&svcraw_lock);
	srp = svc_raw_private;
	if (srp == NULL) {
		srp = calloc(1, sizeof (*srp));
		if (srp == NULL) {
			syslog(LOG_ERR, "svc_raw_create: out of memory");
			(void) mutex_unlock(&svcraw_lock);
			return (NULL);
		}
		flag1 = TRUE;
		if (_rawcombuf == NULL) {
			_rawcombuf = calloc(UDPMSGSIZE, sizeof (char));
			if (_rawcombuf == NULL) {
				free(srp);
				syslog(LOG_ERR, "svc_raw_create: "
					"out of memory");
				(void) mutex_unlock(&svcraw_lock);
				return (NULL);
			}
			flag2 = TRUE;
		}
		srp->raw_buf = _rawcombuf; /* Share it with the client */
		svc_raw_private = srp;
	}
	if ((srp->server = svc_xprt_alloc()) == NULL) {
		if (flag2)
			free(svc_raw_private->raw_buf);
		if (flag1)
			free(svc_raw_private);
		(void) mutex_unlock(&svcraw_lock);
		return (NULL);
	}
	/*
	 * By convention, using FD_SETSIZE as the psuedo file descriptor
	 */
	srp->server->xp_fd = FD_SETSIZE;
	srp->server->xp_port = 0;
	srp->server->xp_ops = svc_raw_ops();
	srp->server->xp_verf.oa_base = srp->verf_body;
	xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
	xprt_register(srp->server);
	(void) mutex_unlock(&svcraw_lock);
	return (srp->server);
}
int loc_apicb_app_init(void)
{

  /* Register a callback server to use the loc_apicbprog_* function  */
  if (svrPort == NULL) {
        svrPort = svcrtr_create();
  }
  if (!svrPort) return -1;

  xprt_register(svrPort);
  if(svc_register(svrPort, LOC_APICBPROG, LOC_APICBVERS_0001, RPC_CB_FUNC_VERS(loc_apicbprog_,LOC_APICBVERS_0001),0))
  {
     return 0;
  }
  else
  {
    return -1;
  }
}
Esempio n. 15
0
SVCXPRT *
svc_raw_create()
{
	struct svc_raw_private *srp;
/* VARIABLES PROTECTED BY svcraw_lock: svc_raw_private, srp */

	mutex_lock(&svcraw_lock);
	srp = svc_raw_private;
	if (srp == NULL) {
		srp = (struct svc_raw_private *)calloc(1, sizeof (*srp));
		if (srp == NULL) {
			mutex_unlock(&svcraw_lock);
			return (NULL);
		}
		if (__rpc_rawcombuf == NULL) {
			__rpc_rawcombuf = calloc(UDPMSGSIZE, sizeof (char));
			if (__rpc_rawcombuf == NULL) {
				free(srp);
				mutex_unlock(&svcraw_lock);
				return (NULL);
			}
		}
		srp->raw_buf = __rpc_rawcombuf; /* Share it with the client */
		srp->server = svc_xprt_alloc();
		if (srp->server == NULL) {
			free(__rpc_rawcombuf);
			free(srp);
			mutex_unlock(&svcraw_lock);
			return (NULL);
		}
		svc_raw_private = srp;
	}
	srp->server->xp_fd = FD_SETSIZE;
	srp->server->xp_port = 0;
	svc_raw_ops(srp->server);
	srp->server->xp_verf.oa_base = srp->verf_body;
	xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
	xprt_register(srp->server);
	mutex_unlock(&svcraw_lock);
	return (srp->server);
}
Esempio n. 16
0
static SVCXPRT *
makefd_xprt(int fd, u_int sendsize, u_int recvsize)
{
	SVCXPRT *xprt;
	struct cf_conn *cd;
	const char *netid;
	struct __rpc_sockinfo si;

	assert(fd != -1);

	xprt = mem_alloc(sizeof(SVCXPRT));
	if (xprt == NULL) {
		warnx("svc_vc: makefd_xprt: out of memory");
		goto done;
	}
	memset(xprt, 0, sizeof *xprt);
	cd = mem_alloc(sizeof(struct cf_conn));
	if (cd == NULL) {
		warnx("svc_tcp: makefd_xprt: out of memory");
		mem_free(xprt, sizeof(SVCXPRT));
		xprt = NULL;
		goto done;
	}
	cd->strm_stat = XPRT_IDLE;
	xdrrec_create(&(cd->xdrs), sendsize, recvsize,
	    xprt, read_vc, write_vc);
	xprt->xp_p1 = cd;
	xprt->xp_verf.oa_base = cd->verf_body;
	svc_vc_ops(xprt);  /* truely deals with calls */
	xprt->xp_port = 0;  /* this is a connection, not a rendezvouser */
	xprt->xp_fd = fd;
        if (__rpc_fd2sockinfo(fd, &si) && __rpc_sockinfo2netid(&si, &netid))
		xprt->xp_netid = strdup(netid);

	xprt_register(xprt);
done:
	return (xprt);
}
Esempio n. 17
0
static SVCXPRT *
makefd_xprt(
	int fd,
	unsigned sendsize,
	unsigned recvsize)
{
	register SVCXPRT *xprt;
	register struct tcp_conn *cd;
 
	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
	if (xprt == (SVCXPRT *)NULL) {
		(void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
		goto done;
	}
	cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn));
	if (cd == (struct tcp_conn *)NULL) {
		(void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
		mem_free((char *) xprt, sizeof(SVCXPRT));
		xprt = (SVCXPRT *)NULL;
		goto done;
	}
	cd->strm_stat = XPRT_IDLE;
	xdrrec_create(&(cd->xdrs), sendsize, recvsize, (char*)xprt,
	    (int(*)(void*, char*, int))readtcp,
	    (int(*)(void*, char*, int))writetcp);
	xprt->xp_p2 = NULL;
	xprt->xp_p1 = (char*)cd;
	xprt->xp_verf.oa_base = cd->verf_body;
	xprt->xp_addrlen = 0;
	xprt->xp_ops = &svctcp_op;  /* truely deals with calls */
	xprt->xp_port = 0;  /* this is a connection, not a rendezvouser */
	xprt->xp_sock = fd;
	xprt_register(xprt);
    done:
	return (xprt);
}
Esempio n. 18
0
/*
 * CLNT_CONTROL() on the client returned by clnt_reconnect_create() must
 * always be called before CLNT_CALL_MBUF() by a single thread only.
 */
static bool_t
clnt_reconnect_control(CLIENT *cl, u_int request, void *info)
{
	struct rc_data *rc = (struct rc_data *)cl->cl_private;
	SVCXPRT *xprt;

	if (info == NULL) {
		return (FALSE);
	}
	switch (request) {
	case CLSET_TIMEOUT:
		rc->rc_timeout = *(struct timeval *)info;
		if (rc->rc_client)
			CLNT_CONTROL(rc->rc_client, request, info);
		break;

	case CLGET_TIMEOUT:
		*(struct timeval *)info = rc->rc_timeout;
		break;

	case CLSET_RETRY_TIMEOUT:
		rc->rc_retry = *(struct timeval *)info;
		if (rc->rc_client)
			CLNT_CONTROL(rc->rc_client, request, info);
		break;

	case CLGET_RETRY_TIMEOUT:
		*(struct timeval *)info = rc->rc_retry;
		break;

	case CLGET_VERS:
		*(uint32_t *)info = rc->rc_vers;
		break;

	case CLSET_VERS:
		rc->rc_vers = *(uint32_t *) info;
		if (rc->rc_client)
			CLNT_CONTROL(rc->rc_client, CLSET_VERS, info);
		break;

	case CLGET_PROG:
		*(uint32_t *)info = rc->rc_prog;
		break;

	case CLSET_PROG:
		rc->rc_prog = *(uint32_t *) info;
		if (rc->rc_client)
			CLNT_CONTROL(rc->rc_client, request, info);
		break;

	case CLSET_WAITCHAN:
		rc->rc_waitchan = (char *)info;
		if (rc->rc_client)
			CLNT_CONTROL(rc->rc_client, request, info);
		break;

	case CLGET_WAITCHAN:
		*(const char **) info = rc->rc_waitchan;
		break;

	case CLSET_INTERRUPTIBLE:
		rc->rc_intr = *(int *) info;
		if (rc->rc_client)
			CLNT_CONTROL(rc->rc_client, request, info);
		break;

	case CLGET_INTERRUPTIBLE:
		*(int *) info = rc->rc_intr;
		break;

	case CLSET_RETRIES:
		rc->rc_retries = *(int *) info;
		break;

	case CLGET_RETRIES:
		*(int *) info = rc->rc_retries;
		break;

	case CLSET_PRIVPORT:
		rc->rc_privport = *(int *) info;
		break;

	case CLGET_PRIVPORT:
		*(int *) info = rc->rc_privport;
		break;

	case CLSET_BACKCHANNEL:
		xprt = (SVCXPRT *)info;
		SVC_ACQUIRE(xprt);
		xprt_register(xprt);
		rc->rc_backchannel = info;
		break;

	default:
		return (FALSE);
	}

	return (TRUE);
}
Esempio n. 19
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);
  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;
}
Esempio n. 20
0
File: svc_udp.c Progetto: 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);
}
Esempio n. 21
0
/*
 * Usage:
 *      xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
 *
 * Creates, registers, and returns a (rpc) tcp based transporter.
 * Once *xprt is initialized, it is registered as a transporter
 * see (svc.h, xprt_register).  This routine returns
 * a NULL if a problem occurred.
 *
 * If sock<0 then a socket is created, else sock is used.
 * If the socket, @var{sock}, is not bound to a port then svctcp_create
 * binds it to an arbitrary port.  The routine then starts a tcp
 * listener on the socket's associated port.  In any (successful) case,
 * xprt->xp_sock is the registered socket number and xprt->xp_port is the
 * associated port number.
 *
 * Since tcp streams do buffered io similar to stdio, the caller can specify
 * how big the send and receive buffers are via the second and third parms;
 * 0 => use the system default.
 */
SVCXPRT *
svctcp_create_with_lock(int sock, u_int sendsize, u_int recvsize)
{
    bool_t madesock;
    SVCXPRT *xprt;
    mtxprt_t *mtxprt;
    struct tcp_rendezvous *r;
    struct sockaddr_in addr;
    socklen_t len;
    int ret;
    int err;

#ifdef DEBUG_BUFSIZE_8K
    if (sendsize == 0) {
        sendsize = 8192;        // Magic number.  For debugging only.
    }
    if (recvsize == 0) {
        recvsize = 8192;        // Magic number.  For debugging only.
    }
#endif /* DEBUG_BUFSIZE_8K */

    tprintf(2, "sock=%d, sendsize=%u, recvsize=%u\n",
        sock, sendsize, recvsize);
    madesock = FALSE;
    len = sizeof (struct sockaddr_in);

    if (sock == RPC_ANYSOCK) {
        sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        tprintf(2, "socket() => %d\n", sock);
        if (sock < 0) {
            svc_perror(errno, "svc_tcp.c - tcp 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);
    }

    ret = getsockname(sock, (struct sockaddr *)&addr, &len);
    if (ret != 0) {
        err = errno;
        svc_perror(err, "svc_tcp.c - getsockname(...) failed");
    }
    else {
        ret = listen(sock, SOMAXCONN);
        if (ret != 0) {
            err = errno;
            svc_perror(err, "svc_tcp.c - listen() failed");
        }
    }

    if (ret != 0) {
        if (madesock) {
            (void) close(sock);
        }
        return ((SVCXPRT *)NULL);
    }

    r = (struct tcp_rendezvous *)guard_malloc(sizeof (*r));
    xprt = alloc_xprt();

    /*
     * Constructor for @type{SVCXPRT}, including the additional @type{mtxprt_t}
     * Order of construction is important.
     * We want to create a lock for each @type{SVCXPRT}.
     * The rest of the contructor should all be done while the lock is held.
     * Even if it is not _really_ necessary, it will keep Valgrind/Helgrind
     * happy.  And they are our friends.
     * Second step is to initialize the "magic" value, so that other
     * helper functions that validate it will be happy.
     */

    mtxprt = xprt_to_mtxprt_nocheck(xprt);

    if (pthread_mutex_init(&(mtxprt->mtxp_lock), NULL) != 0) {
        abort();
    }

    if (pthread_mutex_init(&(mtxprt->mtxp_progress_lock), NULL) != 0) {
        abort();
    }

    if (pthread_mutex_init(&(mtxprt->mtxp_mtready), NULL) != 0) {
        abort();
    }

    // Start off locked.  svctcp_getargs() will unlock it.
    if (pthread_mutex_lock(&(mtxprt->mtxp_mtready)) != 0) {
        abort();
    }

    /*
     * Do not use xprt_lock(xprt) here.
     * The constructor has not progressed far enough, yet.
     */
    if (pthread_mutex_lock(&(mtxprt->mtxp_lock)) != 0) {
        abort();
    }

    /*
     * Set "magic", right away.
     * Other functions validate it.  Keep them happy.
     */
    mtxprt->mtxp_magic = MTXPRT_MAGIC;

    r->sendsize = sendsize;
    r->recvsize = recvsize;
    mtxprt->mtxp_progress = 0;
    mtxprt->mtxp_busy = 0;
    xprt->xp_p2 = NULL;
    xprt->xp_p1 = (caddr_t)r;
    xprt->xp_verf = _null_auth;
    xprt->xp_ops = &svctcp_rendezvous_op;
    xprt->xp_port = ntohs(addr.sin_port);
    xprt->xp_sock = sock;

    mtxprt->mtxp_creator = pthread_self();
    mtxprt->mtxp_id = XPRT_ID_INVALID;
    mtxprt->mtxp_clone  = NULL;
    mtxprt->mtxp_parent = NO_PARENT;
    mtxprt->mtxp_refcnt = 0;
#ifdef CHECK_CREDENTIALS
    memset(mtxprt->mtxp_cred, 0, sizeof (mtxprt->mtxp_cred));
#endif
    memcpy(mtxprt->mtxp_guard, MTXPRT_GUARD, sizeof (mtxprt->mtxp_guard));
    xprt_unlock(xprt);
    xprt_register(xprt);
    return (xprt);
}
Esempio n. 22
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);
}
Esempio n. 23
0
static SVCXPRT *
makefd_xprt_with_lock(int fd, u_int sendsize, u_int recvsize)
{
    SVCXPRT *xprt;
    mtxprt_t *mtxprt;
    struct tcp_conn *cd;

    tprintf(2, "fd=%d, sendsize=%u, recvsize=%u\n", fd, sendsize, recvsize);
    xprt = alloc_xprt();
    cd = (struct tcp_conn *)guard_malloc(sizeof (struct tcp_conn));
    cd->strm_stat = XPRT_IDLE;
    xdrrec_create(&(cd->xdrs), sendsize, recvsize, (caddr_t)xprt, readtcp, writetcp);

    /*
     * Constructor for @type{SVCXPRT}, including the additional @type{mtxprt_t}
     * Order of construction is important.
     * We want to create a lock for each @type{SVCXPRT}.
     * The rest of the contructor should all be done while the lock is held.
     * Even if it is not _really_ necessary, it will keep Valgrind/Helgrind
     * happy.  And they are our friends.
     * Second step is to initialize the "magic" value, so that other
     * helper functions that validate it will be happy.
     */

    mtxprt = xprt_to_mtxprt_nocheck(xprt);

    if (pthread_mutex_init(&(mtxprt->mtxp_lock), NULL) != 0) {
        abort();
    }

    if (pthread_mutex_init(&(mtxprt->mtxp_progress_lock), NULL) != 0) {
        abort();
    }

    if (pthread_mutex_init(&(mtxprt->mtxp_mtready), NULL) != 0) {
        abort();
    }

    // Start off locked.  svctcp_getargs() will unlock it.
    if (pthread_mutex_lock(&(mtxprt->mtxp_mtready)) != 0) {
        abort();
    }

    /*
     * Do not use xprt_lock(xprt) here.
     * The constructor has not progressed far enough, yet.
     */
    if (pthread_mutex_lock(&(mtxprt->mtxp_lock)) != 0) {
        abort();
    }
    mtxprt->mtxp_progress = 0;
    mtxprt->mtxp_busy = 0;
    xprt->xp_p2 = NULL;
    xprt->xp_p1 = (caddr_t)cd;
    xprt->xp_verf.oa_base = cd->verf_body;
    xprt->xp_addrlen = 0;
    xprt->xp_ops = &svctcp_op;  /* truly deals with calls */
    xprt->xp_port = 0;          /* this is a connection, not a rendezvouser */
    xprt->xp_sock = fd;

#if 0
    XDR *xdrs;
    xdrs = &(cd->xdrs);
    xdrs->x_op = XDR_DECODE;
#endif

    /*
     * Set "magic", right away.
     * Other functions validate it.  Keep them happy.
     */
    mtxprt->mtxp_magic = MTXPRT_MAGIC;
    mtxprt->mtxp_creator = pthread_self();
    mtxprt->mtxp_id = XPRT_ID_INVALID;
    mtxprt->mtxp_clone  = NULL;
    mtxprt->mtxp_parent = NO_PARENT;
    mtxprt->mtxp_refcnt = 0;
#ifdef CHECK_CREDENTIALS
    memset(mtxprt->mtxp_cred, 0, sizeof (mtxprt->mtxp_cred));
#endif
    memcpy(mtxprt->mtxp_guard, MTXPRT_GUARD, sizeof (mtxprt->mtxp_guard));
    xprt_unlock(xprt);
    xprt_register(xprt);
    return (xprt);
}
Esempio n. 24
0
/*
 * Create a new transport for a socket optained via soaccept().
 */
SVCXPRT *
svc_vc_create_conn(SVCPOOL *pool, struct socket *so, struct sockaddr *raddr)
{
	SVCXPRT *xprt = NULL;
	struct cf_conn *cd = NULL;
	struct sockaddr* sa = NULL;
	struct sockopt opt;
	int one = 1;
	int error;

	bzero(&opt, sizeof(struct sockopt));
	opt.sopt_dir = SOPT_SET;
	opt.sopt_level = SOL_SOCKET;
	opt.sopt_name = SO_KEEPALIVE;
	opt.sopt_val = &one;
	opt.sopt_valsize = sizeof(one);
	CURVNET_SET(so->so_vnet);
	error = sosetopt(so, &opt);
	if (error) {
		CURVNET_RESTORE();
		return (NULL);
	}

	if (so->so_proto->pr_protocol == IPPROTO_TCP) {
		bzero(&opt, sizeof(struct sockopt));
		opt.sopt_dir = SOPT_SET;
		opt.sopt_level = IPPROTO_TCP;
		opt.sopt_name = TCP_NODELAY;
		opt.sopt_val = &one;
		opt.sopt_valsize = sizeof(one);
		error = sosetopt(so, &opt);
		if (error) {
			CURVNET_RESTORE();
			return (NULL);
		}
	}
	CURVNET_RESTORE();

	cd = mem_alloc(sizeof(*cd));
	cd->strm_stat = XPRT_IDLE;

	xprt = svc_xprt_alloc();
	sx_init(&xprt->xp_lock, "xprt->xp_lock");
	xprt->xp_pool = pool;
	xprt->xp_socket = so;
	xprt->xp_p1 = cd;
	xprt->xp_p2 = NULL;
	xprt->xp_ops = &svc_vc_ops;

	/*
	 * See http://www.connectathon.org/talks96/nfstcp.pdf - client
	 * has a 5 minute timer, server has a 6 minute timer.
	 */
	xprt->xp_idletimeout = 6 * 60;

	memcpy(&xprt->xp_rtaddr, raddr, raddr->sa_len);

	error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
	if (error)
		goto cleanup_svc_vc_create;

	memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
	free(sa, M_SONAME);

	xprt_register(xprt);

	SOCKBUF_LOCK(&so->so_rcv);
	xprt->xp_upcallset = 1;
	soupcall_set(so, SO_RCV, svc_vc_soupcall, xprt);
	SOCKBUF_UNLOCK(&so->so_rcv);

	/*
	 * Throw the transport into the active list in case it already
	 * has some data buffered.
	 */
	sx_xlock(&xprt->xp_lock);
	xprt_active(xprt);
	sx_xunlock(&xprt->xp_lock);

	return (xprt);
cleanup_svc_vc_create:
	if (xprt) {
		mem_free(xprt, sizeof(*xprt));
	}
	if (cd)
		mem_free(cd, sizeof(*cd));
	return (NULL);
}
Esempio n. 25
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);
}