Home | History | Annotate | Line # | Download | only in libsockin
sockin_user.c revision 1.1.36.1
      1  1.1.36.1  christos /*	$NetBSD: sockin_user.c,v 1.1.36.1 2019/06/10 22:09:55 christos Exp $	*/
      2       1.1     pooka 
      3       1.1     pooka /*
      4       1.1     pooka  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
      5       1.1     pooka  *
      6       1.1     pooka  * Redistribution and use in source and binary forms, with or without
      7       1.1     pooka  * modification, are permitted provided that the following conditions
      8       1.1     pooka  * are met:
      9       1.1     pooka  * 1. Redistributions of source code must retain the above copyright
     10       1.1     pooka  *    notice, this list of conditions and the following disclaimer.
     11       1.1     pooka  * 2. Redistributions in binary form must reproduce the above copyright
     12       1.1     pooka  *    notice, this list of conditions and the following disclaimer in the
     13       1.1     pooka  *    documentation and/or other materials provided with the distribution.
     14       1.1     pooka  *
     15       1.1     pooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     16       1.1     pooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17       1.1     pooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18       1.1     pooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19       1.1     pooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20       1.1     pooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21       1.1     pooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22       1.1     pooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23       1.1     pooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24       1.1     pooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25       1.1     pooka  * SUCH DAMAGE.
     26       1.1     pooka  */
     27       1.1     pooka 
     28  1.1.36.1  christos #include <sys/cdefs.h>
     29  1.1.36.1  christos #ifdef __KERNEL_RCSID
     30  1.1.36.1  christos __KERNEL_RCSID(0, "$NetBSD: sockin_user.c,v 1.1.36.1 2019/06/10 22:09:55 christos Exp $");
     31  1.1.36.1  christos #endif
     32  1.1.36.1  christos 
     33       1.1     pooka /* for struct msghdr content visibility */
     34       1.1     pooka #define _XOPEN_SOURCE 4
     35       1.1     pooka #define _XOPEN_SOURCE_EXTENDED 1
     36       1.1     pooka 
     37       1.1     pooka #ifndef _KERNEL
     38       1.1     pooka #include <sys/types.h>
     39       1.1     pooka #include <sys/socket.h>
     40       1.1     pooka 
     41       1.1     pooka #include <errno.h>
     42       1.1     pooka #include <poll.h>
     43       1.1     pooka #include <stdlib.h>
     44       1.1     pooka #include <string.h>
     45       1.1     pooka #include <stdint.h>
     46       1.1     pooka 
     47       1.1     pooka #include <rump/rumpuser_component.h>
     48       1.1     pooka #include <rump/rumpdefs.h>
     49       1.1     pooka 
     50       1.1     pooka #include "sockin_user.h"
     51       1.1     pooka 
     52       1.1     pooka #define seterror(_v_) if ((_v_) == -1) rv = errno; else rv = 0;
     53       1.1     pooka 
     54       1.1     pooka #ifndef __arraycount
     55       1.1     pooka #define __arraycount(a) (sizeof(a) / sizeof(*a))
     56       1.1     pooka #endif
     57       1.1     pooka 
     58       1.1     pooka #ifndef __UNCONST
     59       1.1     pooka #define __UNCONST(a) ((void*)(const void*)a)
     60       1.1     pooka #endif
     61       1.1     pooka 
     62       1.1     pooka #include <netinet/in.h>
     63       1.1     pooka #include <netinet/tcp.h>
     64       1.1     pooka #include <netinet/udp.h>
     65       1.1     pooka 
     66       1.1     pooka 
     67       1.1     pooka static int translate_so_sockopt(int);
     68       1.1     pooka static int translate_ip_sockopt(int);
     69       1.1     pooka static int translate_tcp_sockopt(int);
     70       1.1     pooka static int translate_domain(int);
     71       1.1     pooka 
     72       1.1     pooka #define translate(_a_) case RUMP_##_a_: return _a_
     73       1.1     pooka static int
     74       1.1     pooka translate_so_sockopt(int lopt)
     75       1.1     pooka {
     76       1.1     pooka 
     77       1.1     pooka 	switch (lopt) {
     78       1.1     pooka 	translate(SO_DEBUG);
     79       1.1     pooka #ifndef SO_REUSEPORT
     80       1.1     pooka 	case RUMP_SO_REUSEPORT: return SO_REUSEADDR;
     81       1.1     pooka #else
     82       1.1     pooka 	translate(SO_REUSEPORT);
     83       1.1     pooka #endif
     84       1.1     pooka 	translate(SO_TYPE);
     85       1.1     pooka 	translate(SO_ERROR);
     86       1.1     pooka 	translate(SO_DONTROUTE);
     87       1.1     pooka 	translate(SO_BROADCAST);
     88       1.1     pooka 	translate(SO_SNDBUF);
     89       1.1     pooka 	translate(SO_RCVBUF);
     90       1.1     pooka 	translate(SO_KEEPALIVE);
     91       1.1     pooka 	translate(SO_OOBINLINE);
     92       1.1     pooka 	translate(SO_LINGER);
     93       1.1     pooka 	default: return -1;
     94       1.1     pooka 	}
     95       1.1     pooka }
     96       1.1     pooka 
     97       1.1     pooka static int
     98       1.1     pooka translate_ip_sockopt(int lopt)
     99       1.1     pooka {
    100       1.1     pooka 
    101       1.1     pooka 	switch (lopt) {
    102       1.1     pooka 	translate(IP_TOS);
    103       1.1     pooka 	translate(IP_TTL);
    104       1.1     pooka 	translate(IP_HDRINCL);
    105       1.1     pooka 	translate(IP_MULTICAST_TTL);
    106       1.1     pooka 	translate(IP_MULTICAST_LOOP);
    107       1.1     pooka 	translate(IP_MULTICAST_IF);
    108       1.1     pooka 	translate(IP_ADD_MEMBERSHIP);
    109       1.1     pooka 	translate(IP_DROP_MEMBERSHIP);
    110       1.1     pooka 	default: return -1;
    111       1.1     pooka 	}
    112       1.1     pooka }
    113       1.1     pooka 
    114       1.1     pooka static int
    115       1.1     pooka translate_tcp_sockopt(int lopt)
    116       1.1     pooka {
    117       1.1     pooka 
    118       1.1     pooka 	switch (lopt) {
    119       1.1     pooka 	translate(TCP_NODELAY);
    120       1.1     pooka 	translate(TCP_MAXSEG);
    121       1.1     pooka 	default: return -1;
    122       1.1     pooka 	}
    123       1.1     pooka }
    124       1.1     pooka 
    125       1.1     pooka static int
    126       1.1     pooka translate_domain(int domain)
    127       1.1     pooka {
    128       1.1     pooka 
    129       1.1     pooka 	switch (domain) {
    130       1.1     pooka 	translate(AF_INET);
    131       1.1     pooka 	translate(AF_INET6);
    132       1.1     pooka 	default: return AF_UNSPEC;
    133       1.1     pooka 	}
    134       1.1     pooka }
    135       1.1     pooka 
    136       1.1     pooka #undef translate
    137       1.1     pooka 
    138       1.1     pooka static void
    139       1.1     pooka translate_sockopt(int *levelp, int *namep)
    140       1.1     pooka {
    141       1.1     pooka 	int level, name;
    142       1.1     pooka 
    143       1.1     pooka 	level = *levelp;
    144       1.1     pooka 	name = *namep;
    145       1.1     pooka 
    146       1.1     pooka 	switch (level) {
    147       1.1     pooka 	case RUMP_SOL_SOCKET:
    148       1.1     pooka 		level = SOL_SOCKET;
    149       1.1     pooka 		name = translate_so_sockopt(name);
    150       1.1     pooka 		break;
    151       1.1     pooka 	case RUMP_IPPROTO_IP:
    152       1.1     pooka #ifdef SOL_IP
    153       1.1     pooka 		level = SOL_IP;
    154       1.1     pooka #else
    155       1.1     pooka 		level = IPPROTO_IP;
    156       1.1     pooka #endif
    157       1.1     pooka 		name = translate_ip_sockopt(name);
    158       1.1     pooka 		break;
    159       1.1     pooka 	case RUMP_IPPROTO_TCP:
    160       1.1     pooka #ifdef SOL_TCP
    161       1.1     pooka 		level = SOL_TCP;
    162       1.1     pooka #else
    163       1.1     pooka 		level = IPPROTO_TCP;
    164       1.1     pooka #endif
    165       1.1     pooka 		name = translate_tcp_sockopt(name);
    166       1.1     pooka 		break;
    167       1.1     pooka 	case RUMP_IPPROTO_UDP:
    168       1.1     pooka #ifdef SOL_UDP
    169       1.1     pooka 		level = SOL_UDP;
    170       1.1     pooka #else
    171       1.1     pooka 		level = IPPROTO_UDP;
    172       1.1     pooka #endif
    173       1.1     pooka 		name = -1;
    174       1.1     pooka 		break;
    175       1.1     pooka 	default:
    176       1.1     pooka 		level = -1;
    177       1.1     pooka 	}
    178       1.1     pooka 	*levelp = level;
    179       1.1     pooka 	*namep = name;
    180       1.1     pooka }
    181       1.1     pooka 
    182       1.1     pooka #ifndef __NetBSD__
    183       1.1     pooka static const struct {
    184       1.1     pooka 	int bfl;
    185       1.1     pooka 	int lfl;
    186       1.1     pooka } bsd_to_native_msg_flags_[] = {
    187       1.1     pooka 	{RUMP_MSG_OOB,		MSG_OOB},
    188       1.1     pooka 	{RUMP_MSG_PEEK,		MSG_PEEK},
    189       1.1     pooka 	{RUMP_MSG_DONTROUTE,	MSG_DONTROUTE},
    190       1.1     pooka 	{RUMP_MSG_EOR,		MSG_EOR},
    191       1.1     pooka 	{RUMP_MSG_TRUNC,	MSG_TRUNC},
    192       1.1     pooka 	{RUMP_MSG_CTRUNC,	MSG_CTRUNC},
    193       1.1     pooka 	{RUMP_MSG_WAITALL,	MSG_WAITALL},
    194       1.1     pooka 	{RUMP_MSG_DONTWAIT,	MSG_DONTWAIT},
    195       1.1     pooka 
    196       1.1     pooka 	/* might be better to always set NOSIGNAL ... */
    197       1.1     pooka #ifdef MSG_NOSIGNAL
    198       1.1     pooka 	{RUMP_MSG_NOSIGNAL,	MSG_NOSIGNAL},
    199       1.1     pooka #endif
    200       1.1     pooka };
    201       1.1     pooka 
    202       1.1     pooka static int native_to_bsd_msg_flags(int);
    203       1.1     pooka 
    204       1.1     pooka static int
    205       1.1     pooka native_to_bsd_msg_flags(int lflag)
    206       1.1     pooka {
    207       1.1     pooka 	unsigned int i;
    208       1.1     pooka 	int bfl, lfl;
    209       1.1     pooka 	int bflag = 0;
    210       1.1     pooka 
    211       1.1     pooka 	if (lflag == 0)
    212       1.1     pooka 		return (0);
    213       1.1     pooka 
    214       1.1     pooka 	for(i = 0; i < __arraycount(bsd_to_native_msg_flags_); i++) {
    215       1.1     pooka 		bfl = bsd_to_native_msg_flags_[i].bfl;
    216       1.1     pooka 		lfl = bsd_to_native_msg_flags_[i].lfl;
    217       1.1     pooka 
    218       1.1     pooka 		if (lflag & lfl) {
    219       1.1     pooka 			lflag ^= lfl;
    220       1.1     pooka 			bflag |= bfl;
    221       1.1     pooka 		}
    222       1.1     pooka 	}
    223       1.1     pooka 	if (lflag != 0)
    224       1.1     pooka 		return (-1);
    225       1.1     pooka 
    226       1.1     pooka 	return (bflag);
    227       1.1     pooka }
    228       1.1     pooka 
    229       1.1     pooka static int
    230       1.1     pooka bsd_to_native_msg_flags(int bflag)
    231       1.1     pooka {
    232       1.1     pooka 	unsigned int i;
    233       1.1     pooka 	int lflag = 0;
    234       1.1     pooka 
    235       1.1     pooka 	if (bflag == 0)
    236       1.1     pooka 		return (0);
    237       1.1     pooka 
    238       1.1     pooka 	for(i = 0; i < __arraycount(bsd_to_native_msg_flags_); i++) {
    239       1.1     pooka 		if (bflag & bsd_to_native_msg_flags_[i].bfl)
    240       1.1     pooka 			lflag |= bsd_to_native_msg_flags_[i].lfl;
    241       1.1     pooka 	}
    242       1.1     pooka 
    243       1.1     pooka 	return (lflag);
    244       1.1     pooka }
    245       1.1     pooka #endif
    246       1.1     pooka 
    247       1.1     pooka struct rump_sockaddr {
    248       1.1     pooka 	uint8_t	sa_len;	    /* total length */
    249       1.1     pooka 	uint8_t	sa_family;	/* address family */
    250       1.1     pooka 	char	sa_data[14];	/* actually longer; address value */
    251       1.1     pooka };
    252       1.1     pooka 
    253       1.1     pooka struct rump_msghdr {
    254       1.1     pooka 	void		*msg_name;	/* optional address */
    255       1.1     pooka 	uint32_t	msg_namelen;	/* size of address */
    256       1.1     pooka 	struct iovec	*msg_iov;	/* scatter/gather array */
    257       1.1     pooka 	int		msg_iovlen;	/* # elements in msg_iov */
    258       1.1     pooka 	void		*msg_control;	/* ancillary data, see below */
    259       1.1     pooka 	uint32_t	msg_controllen;	/* ancillary data buffer len */
    260       1.1     pooka 	int		msg_flags;	/* flags on received message */
    261       1.1     pooka };
    262       1.1     pooka 
    263       1.1     pooka static struct sockaddr *translate_sockaddr(const struct sockaddr *,
    264       1.1     pooka 		uint32_t);
    265       1.1     pooka static void translate_sockaddr_back(const struct sockaddr *,
    266       1.1     pooka 		struct rump_sockaddr *, uint32_t len);
    267       1.1     pooka static struct msghdr *translate_msghdr(const struct rump_msghdr *, int *);
    268       1.1     pooka static void translate_msghdr_back(const struct msghdr *, struct rump_msghdr *);
    269       1.1     pooka 
    270       1.1     pooka #if defined(__NetBSD__)
    271       1.1     pooka static struct sockaddr *
    272       1.1     pooka translate_sockaddr(const struct sockaddr *addr, uint32_t len)
    273       1.1     pooka {
    274       1.1     pooka 
    275       1.1     pooka 	return (struct sockaddr *)__UNCONST(addr);
    276       1.1     pooka }
    277       1.1     pooka 
    278       1.1     pooka static void
    279       1.1     pooka translate_sockaddr_back(const struct sockaddr *laddr,
    280       1.1     pooka 		struct rump_sockaddr *baddr, uint32_t len)
    281       1.1     pooka {
    282       1.1     pooka 
    283       1.1     pooka 	return;
    284       1.1     pooka }
    285       1.1     pooka 
    286       1.1     pooka static struct msghdr *
    287       1.1     pooka translate_msghdr(const struct rump_msghdr *bmsg, int *flags)
    288       1.1     pooka {
    289       1.1     pooka 
    290       1.1     pooka 	return (struct msghdr *)__UNCONST(bmsg);
    291       1.1     pooka }
    292       1.1     pooka 
    293       1.1     pooka static void
    294       1.1     pooka translate_msghdr_back(const struct msghdr *lmsg, struct rump_msghdr *bmsg)
    295       1.1     pooka {
    296       1.1     pooka 
    297       1.1     pooka 	return;
    298       1.1     pooka }
    299       1.1     pooka 
    300       1.1     pooka #else
    301       1.1     pooka static struct sockaddr *
    302       1.1     pooka translate_sockaddr(const struct sockaddr *addr, uint32_t len)
    303       1.1     pooka {
    304       1.1     pooka 	struct sockaddr *laddr;
    305       1.1     pooka 	const struct rump_sockaddr *baddr;
    306       1.1     pooka 
    307       1.1     pooka 	baddr = (const struct rump_sockaddr *)addr;
    308       1.1     pooka 	laddr = malloc(len);
    309       1.1     pooka 	if (laddr == NULL)
    310       1.1     pooka 		return NULL;
    311       1.1     pooka 	memcpy(laddr, baddr, len);
    312       1.1     pooka 	laddr->sa_family = translate_domain(baddr->sa_family);
    313       1.1     pooka 	/* No sa_len for Linux and SunOS */
    314       1.1     pooka #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
    315       1.1     pooka 	laddr->sa_len = len;
    316       1.1     pooka #endif
    317       1.1     pooka 	return laddr;
    318       1.1     pooka }
    319       1.1     pooka 
    320       1.1     pooka #define translate_back(_a_) case _a_: return RUMP_##_a_
    321       1.1     pooka static int translate_domain_back(int);
    322       1.1     pooka static int
    323       1.1     pooka translate_domain_back(int domain)
    324       1.1     pooka {
    325       1.1     pooka 
    326       1.1     pooka 	switch (domain) {
    327       1.1     pooka 	translate_back(AF_INET);
    328       1.1     pooka 	translate_back(AF_INET6);
    329       1.1     pooka 	default: return RUMP_AF_UNSPEC;
    330       1.1     pooka 	}
    331       1.1     pooka }
    332       1.1     pooka #undef translate_back
    333       1.1     pooka 
    334       1.1     pooka static void
    335       1.1     pooka translate_sockaddr_back(const struct sockaddr *laddr,
    336       1.1     pooka 		struct rump_sockaddr *baddr,
    337       1.1     pooka 		uint32_t len)
    338       1.1     pooka {
    339       1.1     pooka 
    340       1.1     pooka 	if (baddr != NULL) {
    341       1.1     pooka 		memcpy(baddr, laddr, len);
    342       1.1     pooka 		baddr->sa_family = translate_domain_back(laddr->sa_family);
    343       1.1     pooka 		baddr->sa_len = len;
    344       1.1     pooka 	}
    345       1.1     pooka 	free(__UNCONST(laddr));
    346       1.1     pooka }
    347       1.1     pooka 
    348       1.1     pooka static struct msghdr *
    349       1.1     pooka translate_msghdr(const struct rump_msghdr *bmsg, int *flags)
    350       1.1     pooka {
    351       1.1     pooka 	struct msghdr *rv;
    352       1.1     pooka 
    353       1.1     pooka 	*flags = bsd_to_native_msg_flags(*flags);
    354       1.1     pooka 	if (*flags < 0)
    355       1.1     pooka 		*flags = 0;
    356       1.1     pooka 
    357       1.1     pooka 	rv = malloc(sizeof(*rv));
    358       1.1     pooka 	rv->msg_namelen = bmsg->msg_namelen;
    359       1.1     pooka 	rv->msg_iov = bmsg->msg_iov;
    360       1.1     pooka 	rv->msg_iovlen = bmsg->msg_iovlen;
    361       1.1     pooka 	rv->msg_control = bmsg->msg_control;
    362       1.1     pooka 	rv->msg_controllen = bmsg->msg_controllen;
    363       1.1     pooka 	rv->msg_flags = 0;
    364       1.1     pooka 
    365       1.1     pooka 	if (bmsg->msg_name != NULL) {
    366       1.1     pooka 		rv->msg_name = translate_sockaddr(bmsg->msg_name,
    367       1.1     pooka 				bmsg->msg_namelen);
    368       1.1     pooka 		if (rv->msg_name == NULL) {
    369       1.1     pooka 			free(rv);
    370       1.1     pooka 			return NULL;
    371       1.1     pooka 		}
    372       1.1     pooka 	} else
    373       1.1     pooka 		rv->msg_name = NULL;
    374       1.1     pooka 	return rv;
    375       1.1     pooka }
    376       1.1     pooka 
    377       1.1     pooka static void
    378       1.1     pooka translate_msghdr_back(const struct msghdr *lmsg, struct rump_msghdr *bmsg)
    379       1.1     pooka {
    380       1.1     pooka 
    381       1.1     pooka 	if (bmsg == NULL) {
    382       1.1     pooka 		if (lmsg->msg_name != NULL)
    383       1.1     pooka 			free(lmsg->msg_name);
    384       1.1     pooka 		free(__UNCONST(lmsg));
    385       1.1     pooka 		return;
    386       1.1     pooka 	}
    387       1.1     pooka 	bmsg->msg_namelen = lmsg->msg_namelen;
    388       1.1     pooka 	bmsg->msg_iov = lmsg->msg_iov;
    389       1.1     pooka 	bmsg->msg_iovlen = lmsg->msg_iovlen;
    390       1.1     pooka 	bmsg->msg_control = lmsg->msg_control;
    391       1.1     pooka 	bmsg->msg_controllen = lmsg->msg_controllen;
    392       1.1     pooka 	bmsg->msg_flags = native_to_bsd_msg_flags(lmsg->msg_flags);
    393       1.1     pooka 
    394       1.1     pooka 	if (lmsg->msg_name != NULL)
    395       1.1     pooka 		translate_sockaddr_back(lmsg->msg_name, bmsg->msg_name,
    396       1.1     pooka 				bmsg->msg_namelen);
    397       1.1     pooka 	else
    398       1.1     pooka 		bmsg->msg_name = NULL;
    399       1.1     pooka 
    400       1.1     pooka 	free(__UNCONST(lmsg));
    401       1.1     pooka }
    402       1.1     pooka #endif
    403       1.1     pooka 
    404       1.1     pooka int
    405       1.1     pooka rumpcomp_sockin_socket(int domain, int type, int proto, int *s)
    406       1.1     pooka {
    407       1.1     pooka 	void *cookie;
    408       1.1     pooka 	int rv;
    409       1.1     pooka 
    410       1.1     pooka 	domain = translate_domain(domain);
    411       1.1     pooka 
    412       1.1     pooka 	cookie = rumpuser_component_unschedule();
    413       1.1     pooka 	*s = socket(domain, type, proto);
    414       1.1     pooka 	seterror(*s);
    415       1.1     pooka 	rumpuser_component_schedule(cookie);
    416       1.1     pooka 
    417       1.1     pooka 	return rumpuser_component_errtrans(rv);
    418       1.1     pooka }
    419       1.1     pooka 
    420       1.1     pooka int
    421       1.1     pooka rumpcomp_sockin_sendmsg(int s, const struct msghdr *msg, int flags, size_t *snd)
    422       1.1     pooka {
    423       1.1     pooka 	void *cookie;
    424       1.1     pooka 	ssize_t nn;
    425       1.1     pooka 	int rv;
    426       1.1     pooka 
    427       1.1     pooka 	msg = translate_msghdr((struct rump_msghdr *)msg, &flags);
    428       1.1     pooka 
    429       1.1     pooka 	cookie = rumpuser_component_unschedule();
    430       1.1     pooka 	nn = sendmsg(s, msg, flags);
    431       1.1     pooka 	seterror(nn);
    432       1.1     pooka 	*snd = (size_t)nn;
    433       1.1     pooka 	rumpuser_component_schedule(cookie);
    434       1.1     pooka 
    435       1.1     pooka 	translate_msghdr_back(msg, NULL);
    436       1.1     pooka 
    437       1.1     pooka 	return rumpuser_component_errtrans(rv);
    438       1.1     pooka }
    439       1.1     pooka 
    440       1.1     pooka int
    441       1.1     pooka rumpcomp_sockin_recvmsg(int s, struct msghdr *msg, int flags, size_t *rcv)
    442       1.1     pooka {
    443       1.1     pooka 	void *cookie;
    444       1.1     pooka 	ssize_t nn;
    445       1.1     pooka 	int rv;
    446       1.1     pooka 	struct rump_msghdr *saveptr;
    447       1.1     pooka 
    448       1.1     pooka 	saveptr = (struct rump_msghdr *)msg;
    449       1.1     pooka 	msg = translate_msghdr(saveptr, &flags);
    450       1.1     pooka 
    451       1.1     pooka 	cookie = rumpuser_component_unschedule();
    452       1.1     pooka 	nn = recvmsg(s, msg, flags);
    453       1.1     pooka 	seterror(nn);
    454       1.1     pooka 	*rcv = (size_t)nn;
    455       1.1     pooka 	rumpuser_component_schedule(cookie);
    456       1.1     pooka 
    457       1.1     pooka 	translate_msghdr_back(msg, saveptr);
    458       1.1     pooka 
    459       1.1     pooka 	return rumpuser_component_errtrans(rv);
    460       1.1     pooka }
    461       1.1     pooka 
    462       1.1     pooka int
    463       1.1     pooka rumpcomp_sockin_connect(int s, const struct sockaddr *name, int len)
    464       1.1     pooka {
    465       1.1     pooka 	void *cookie;
    466       1.1     pooka 	int rv;
    467       1.1     pooka 
    468       1.1     pooka 	name = translate_sockaddr(name, len);
    469       1.1     pooka 
    470       1.1     pooka 	cookie = rumpuser_component_unschedule();
    471       1.1     pooka 	rv = connect(s, name, (socklen_t)len);
    472       1.1     pooka 	seterror(rv);
    473       1.1     pooka 	rumpuser_component_schedule(cookie);
    474       1.1     pooka 
    475       1.1     pooka 	translate_sockaddr_back(name, NULL, len);
    476       1.1     pooka 
    477       1.1     pooka 	return rumpuser_component_errtrans(rv);
    478       1.1     pooka }
    479       1.1     pooka 
    480       1.1     pooka int
    481       1.1     pooka rumpcomp_sockin_bind(int s, const struct sockaddr *name, int len)
    482       1.1     pooka {
    483       1.1     pooka 	void *cookie;
    484       1.1     pooka 	int rv;
    485       1.1     pooka 
    486       1.1     pooka 	name = translate_sockaddr(name, len);
    487       1.1     pooka 
    488       1.1     pooka 	cookie = rumpuser_component_unschedule();
    489       1.1     pooka 	rv = bind(s, name, (socklen_t)len);
    490       1.1     pooka 	seterror(rv);
    491       1.1     pooka 	rumpuser_component_schedule(cookie);
    492       1.1     pooka 
    493       1.1     pooka 	translate_sockaddr_back(name, NULL, len);
    494       1.1     pooka 
    495       1.1     pooka 	return rumpuser_component_errtrans(rv);
    496       1.1     pooka }
    497       1.1     pooka 
    498       1.1     pooka int
    499       1.1     pooka rumpcomp_sockin_accept(int s, struct sockaddr *name, int *lenp, int *s2)
    500       1.1     pooka {
    501       1.1     pooka 	void *cookie;
    502       1.1     pooka 	int rv;
    503       1.1     pooka 	struct rump_sockaddr *saveptr;
    504       1.1     pooka 
    505       1.1     pooka 	saveptr = (struct rump_sockaddr *)name;
    506       1.1     pooka 	name = translate_sockaddr(name, *lenp);
    507       1.1     pooka 
    508       1.1     pooka 	cookie = rumpuser_component_unschedule();
    509       1.1     pooka 	*s2 = accept(s, name, (socklen_t *)lenp);
    510       1.1     pooka 	seterror(*s2);
    511       1.1     pooka 	rumpuser_component_schedule(cookie);
    512       1.1     pooka 
    513       1.1     pooka 	translate_sockaddr_back(name, saveptr, *lenp);
    514       1.1     pooka 
    515       1.1     pooka 	return rumpuser_component_errtrans(rv);
    516       1.1     pooka }
    517       1.1     pooka 
    518       1.1     pooka int
    519       1.1     pooka rumpcomp_sockin_listen(int s, int backlog)
    520       1.1     pooka {
    521       1.1     pooka 	void *cookie;
    522       1.1     pooka 	int rv;
    523       1.1     pooka 
    524       1.1     pooka 	cookie = rumpuser_component_unschedule();
    525       1.1     pooka 	rv = listen(s, backlog);
    526       1.1     pooka 	seterror(rv);
    527       1.1     pooka 	rumpuser_component_schedule(cookie);
    528       1.1     pooka 
    529       1.1     pooka 	return rumpuser_component_errtrans(rv);
    530       1.1     pooka }
    531       1.1     pooka 
    532       1.1     pooka int
    533       1.1     pooka rumpcomp_sockin_getname(int s, struct sockaddr *so, int *lenp,
    534       1.1     pooka 	enum rumpcomp_sockin_getnametype which)
    535       1.1     pooka {
    536       1.1     pooka 	socklen_t slen = *lenp;
    537       1.1     pooka 	int rv;
    538       1.1     pooka 	struct rump_sockaddr *saveptr;
    539       1.1     pooka 
    540       1.1     pooka 	saveptr = (struct rump_sockaddr *)so;
    541       1.1     pooka 	so = translate_sockaddr(so, *lenp);
    542       1.1     pooka 
    543       1.1     pooka 	if (which == RUMPCOMP_SOCKIN_SOCKNAME)
    544       1.1     pooka 		rv = getsockname(s, so, &slen);
    545       1.1     pooka 	else
    546       1.1     pooka 		rv = getpeername(s, so, &slen);
    547       1.1     pooka 
    548       1.1     pooka 	seterror(rv);
    549       1.1     pooka 	translate_sockaddr_back(so, saveptr, *lenp);
    550       1.1     pooka 
    551       1.1     pooka 	*lenp = slen;
    552       1.1     pooka 
    553       1.1     pooka 	return rumpuser_component_errtrans(rv);
    554       1.1     pooka }
    555       1.1     pooka 
    556       1.1     pooka int
    557       1.1     pooka rumpcomp_sockin_setsockopt(int s, int level, int name,
    558       1.1     pooka 	const void *data, int dlen)
    559       1.1     pooka {
    560       1.1     pooka 	socklen_t slen = dlen;
    561       1.1     pooka 	int rv;
    562       1.1     pooka 
    563       1.1     pooka 	translate_sockopt(&level, &name);
    564       1.1     pooka 	if (level == -1 || name == -1) {
    565       1.1     pooka #ifdef SETSOCKOPT_STRICT
    566       1.1     pooka 		errno = EINVAL;
    567       1.1     pooka 		rv = -1;
    568       1.1     pooka #else
    569       1.1     pooka 		rv = 0;
    570       1.1     pooka #endif
    571       1.1     pooka 	} else
    572       1.1     pooka 		rv = setsockopt(s, level, name, data, slen);
    573       1.1     pooka 
    574       1.1     pooka 	seterror(rv);
    575       1.1     pooka 
    576       1.1     pooka 	return rumpuser_component_errtrans(rv);
    577       1.1     pooka }
    578       1.1     pooka 
    579       1.1     pooka int
    580       1.1     pooka rumpcomp_sockin_poll(struct pollfd *fds, int nfds, int timeout, int *nready)
    581       1.1     pooka {
    582       1.1     pooka 	void *cookie;
    583       1.1     pooka 	int rv;
    584       1.1     pooka 
    585       1.1     pooka 	cookie = rumpuser_component_unschedule();
    586       1.1     pooka 	*nready = poll(fds, (nfds_t)nfds, timeout);
    587       1.1     pooka 	seterror(*nready);
    588       1.1     pooka 	rumpuser_component_schedule(cookie);
    589       1.1     pooka 
    590       1.1     pooka 	return rumpuser_component_errtrans(rv);
    591       1.1     pooka }
    592       1.1     pooka #endif
    593