From 1502f0cdcb8c8b1a5f11ee3da83ef8fe27816427 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 26 Dec 2020 22:46:36 +0100 Subject: [PATCH] Added VSOCK stream addresses --- CHANGES | 3 + EXAMPLES | 14 +++++ Makefile.in | 4 +- config.h.in | 4 ++ configure.ac | 23 ++++++++ doc/socat.yo | 81 +++++++++++++++++++++++++- socat.c | 5 ++ sysincludes.h | 3 + sysutils.c | 41 +++++++++++++ sysutils.h | 8 +++ test.sh | 57 ++++++++++++++++++ xio-ip.c | 11 ++++ xio-listen.c | 12 ++++ xio-vsock.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++ xio-vsock.h | 11 ++++ xiomodes.h | 1 + xioopen.c | 6 ++ xioopts.c | 5 +- 18 files changed, 442 insertions(+), 4 deletions(-) create mode 100644 xio-vsock.c create mode 100644 xio-vsock.h diff --git a/CHANGES b/CHANGES index 0fc1d95..3c728c6 100644 --- a/CHANGES +++ b/CHANGES @@ -170,6 +170,9 @@ New features: Test: PROXYAUTHFILE Thanks to Charles Stephens for sending an initial patch. + Added AF_VSOCK support with VSOCK-CONNECT and VSOCK-LISTEN addresses. + Developed by Stefano Garzarella. + ####################### V 1.7.3.4: Corrections: diff --git a/EXAMPLES b/EXAMPLES index e5160bc..83d38de 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -232,6 +232,20 @@ $ socat -d -d tcp:localhost:25,crlf,nodelay exec:'/usr/sbin/chat -v -s "\"220 \" # socat readline TCP6:[::1]:21 # if your inetd/ftp is listening on ip6 +////////////////////////////////////////////////////////////////////////////// +// VSOCK +# start a linux VM with cid=21 +# qemu-system-x86_64 -m 1G -smp 2 -cpu host -M accel=kvm \ +# -drive if=virtio,file=/path/to/fedora.img,format=qcow2 \ +# -device vhost-vsock-pci,guest-cid=21 + +# guest listens on port 1234 and host connects to it +guest$ socat - vsock-listen:1234 +host$ socat - vsock-connect:21:1234 + +# host (well know CID_HOST = 2) listens on port 4321 and guest connects to it +host$ socat - vsock-listen:4321 +guest$ socat - vsock-connect:2:4321 /////////////////////////////////////////////////////////////////////////////// // application server solutions diff --git a/Makefile.in b/Makefile.in index 2b89684..5c7c66b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -45,7 +45,7 @@ XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ - xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c xio-vsock.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ @@ -63,7 +63,7 @@ HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes. xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ - xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h xio-vsock.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ diff --git a/config.h.in b/config.h.in index c523df1..08ec477 100644 --- a/config.h.in +++ b/config.h.in @@ -279,6 +279,9 @@ /* Define if you have the header file. */ #undef HAVE_LINUX_IF_TUN_H +/* Define if you have the header file. */ +#undef HAVE_LINUX_VM_SOCKETS_H + /* Define if you have the header file. */ #undef HAVE_NETPACKET_PACKET_H @@ -660,6 +663,7 @@ #undef WITH_LISTEN #undef WITH_SOCKS4 #undef WITH_SOCKS4A +#undef WITH_VSOCK #undef WITH_PROXY #undef WITH_EXEC #undef WITH_SYSTEM diff --git a/configure.ac b/configure.ac index 461e586..3312b5f 100644 --- a/configure.ac +++ b/configure.ac @@ -349,6 +349,29 @@ else fi fi +AC_MSG_CHECKING(whether to include vsock support) +AC_ARG_ENABLE(vsock, [ --disable-vsock disable vsock support], + [case "$enableval" in + no) AC_MSG_RESULT(no); WITH_VSOCK= ;; + *) AC_MSG_RESULT(yes); WITH_VSOCK=1 ;; + esac], + [AC_MSG_RESULT(yes); WITH_VSOCK=1 ]) +if test "$WITH_VSOCK"; then + AC_CHECK_HEADER(linux/vm_sockets.h, + AC_DEFINE(HAVE_LINUX_VM_SOCKETS_H), + [WITH_VSOCK=; + AC_MSG_WARN([include file linux/vm_sockets.h not found, disabling vsock])], + [AC_INCLUDES_DEFAULT + #if HAVE_SYS_SOCKET_H + #include + #endif + ] + ) +fi +if test "$WITH_VSOCK"; then + AC_DEFINE(WITH_VSOCK) +fi + AC_MSG_CHECKING(whether to include listen support) AC_ARG_ENABLE(listen, [ --disable-listen disable listen support], [case "$enableval" in diff --git a/doc/socat.yo b/doc/socat.yo index 5bbab58..d8f2ab0 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1352,6 +1352,37 @@ label(ADDRESS_UNIX_CLIENT)dit(bf(tt(UNIX-CLIENT:))) link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO), link(GOPEN)(ADDRESS_GOPEN) +label(ADDRESS_VSOCK_CONNECT)dit(bf(tt(VSOCK-CONNECT::))) + Establishes a VSOCK stream connection to the specified [link(VSOCK + cid)(TYPE_VSOCK_ADDRESS)] and [link(VSOCK port)(TYPE_VSOCK_PORT)].nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl() + Useful options: + link(bind)(OPTION_BIND), + link(pf)(OPTION_PROTOCOL_FAMILY), + link(connect-timeout)(OPTION_CONNECT_TIMEOUT), + link(retry)(OPTION_RETRY), + link(readbytes)(OPTION_READBYTES)nl() + See also: + link(VSOCK-LISTEN)(ADDRESS_VSOCK_LISTEN), + +label(ADDRESS_VSOCK_LISTEN)dit(bf(tt(VSOCK-LISTEN:))) + Listens on [link(VSOCK port)(TYPE_VSOCK_PORT)] and accepts a + VSOCK connection. + Note that opening this address usually blocks until a client connects.nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl() + Useful options: + link(fork)(OPTION_FORK), + link(bind)(OPTION_BIND), + link(pf)(OPTION_PROTOCOL_FAMILY), + link(max-children)(OPTION_MAX_CHILDREN), + link(backlog)(OPTION_BACKLOG), + link(su)(OPTION_SUBSTUSER), + link(reuseaddr)(OPTION_REUSEADDR), + link(retry)(OPTION_RETRY), + link(cool-write)(OPTION_COOL_WRITE)nl() + See also: + link(VSOCK-CONNECT)(ADDRESS_VSOCK_CONNECT) + dit(bf(tt(ABSTRACT-CONNECT:))) dit(bf(tt(ABSTRACT-LISTEN:))) dit(bf(tt(ABSTRACT-SENDTO:))) @@ -1885,7 +1916,8 @@ label(OPTION_BIND)dit(bf(tt(bind=))) Binds the socket to the given socket address using the code(bind()) system call. The form of is socket domain dependent: IP4 and IP6 allow the form [hostname|hostaddress][:(service|port)] (link(example)(EXAMPLE_OPTION_BIND_TCP4)), - unixdomain() sockets require link()(TYPE_FILENAME). + unixdomain() sockets require link()(TYPE_FILENAME), + VSOCK allow the form [cid][:(port)]. label(OPTION_CONNECT_TIMEOUT)dit(bf(tt(connect-timeout=))) Abort the connection attempt after [link(timeval)(TYPE_TIMEVAL)] with error status. @@ -3041,6 +3073,14 @@ label(TYPE_USER)dit(user) If the first character is a decimal digit, the value is read with code(strtoul()) as unsigned integer specifying a user id. Otherwise, it must be an existing user name. +label(TYPE_VSOCK_ADDRESS)dit(VSOCK cid) + A uint32_t (32 bit unsigned number) specifying a VSOCK Context Identifier + (CID), read with code(strtoul()). + There are several special addresses: VMADDR_CID_ANY (-1U) means any address + for binding; VMADDR_CID_HOST (2) is the well-known address of the host. +label(TYPE_VSOCK_PORT)dit(VSOCK port) + A uint32_t (32 bit unsigned number) specifying a VSOCK port, read + with code(strtoul()). enddit() @@ -3444,6 +3484,45 @@ streaming eg. via TCP or SSL does not guarantee to retain packet boundaries and may thus cause packet loss. +label(EXAMPLE_ADDRESS_VSOCK) +dit(bf(tt(socat - VSOCK-CONNECT:2:1234))) + +establishes a VSOCK connection with the host (host is always reachable with +the well-know CID=2) on 1234 port. + + +dit(bf(tt(socat - VSOCK-LISTEN:1234))) + +listens for a VSOCK connection on 1234 port. + + +dit(bf(tt(socat - VSOCK-CONNECT:31:4321,bind:5555))) + +establishes a VSOCK connection with the guest that have CID=31 on 1234 port, +binding the local socket to the 5555 port. + + +dit(bf(tt(socat VSOCK-LISTEN:3333,reuseaddr,fork VSOCK-CONNECT:42,3333))) + +starts a forwarder that accepts VSOCK connections on port 3333, and directs +them to the guest with CID=42 on the same port. + + +dit(bf(tt(socat VSOCK-LISTEN:22,reuseaddr,fork TCP:localhost:22))) + +forwards VSOCK connections from 22 port to the local SSH server. +Running this in a VM allows you to connect via SSH from the host using VSOCK, +as in the example below. + + +dit(bf(tt(socat TCP4-LISTEN:22222,reuseaddr,fork VSOCK-CONNECT:33:22))) + +forwards TCP connections from 22222 port to the guest with CID=33 listening on +VSOCK port 22. +Running this in the host, allows you to connect via SSH running +"ssh -p 22222 user@localhost", if the guest runs the example above. + + label(EXAMPLE_INTERFACE) dit(bf(tt(socat PTY,link=/var/run/ppp,rawer INTERFACE:hdlc0))) diff --git a/socat.c b/socat.c index 320d41c..b1a70aa 100644 --- a/socat.c +++ b/socat.c @@ -528,6 +528,11 @@ void socat_version(FILE *fd) { #else fputs(" #undef WITH_SOCKS4A\n", fd); #endif +#ifdef WITH_VSOCK + fprintf(fd, " #define WITH_VSOCK %d\n", WITH_VSOCK); +#else + fputs(" #undef WITH_VSOCK\n", fd); +#endif #ifdef WITH_PROXY fprintf(fd, " #define WITH_PROXY %d\n", WITH_PROXY); #else diff --git a/sysincludes.h b/sysincludes.h index d33c21c..4a63cc4 100644 --- a/sysincludes.h +++ b/sysincludes.h @@ -185,5 +185,8 @@ #include #include #endif +#if HAVE_LINUX_VM_SOCKETS_H +#include +#endif #endif /* !defined(__sysincludes_h_included) */ diff --git a/sysutils.c b/sysutils.c index 05b8206..db95840 100644 --- a/sysutils.c +++ b/sysutils.c @@ -204,6 +204,10 @@ char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size #if WITH_IP6 case AF_INET6: sockaddr_inet6_info(&sau->ip6, cp, blen); break; +#endif +#if WITH_VSOCK + case AF_VSOCK: sockaddr_vm_info(&sau->vm, cp, blen); + break; #endif default: n = xio_snprintf(cp, blen, "AF=%d ", sa->sa_family); @@ -297,6 +301,43 @@ char *sockaddr_inet4_info(const struct sockaddr_in *sa, char *buff, size_t blen) } #endif /* WITH_IP4 */ +#if WITH_VSOCK +char *sockaddr_vm_info(const struct sockaddr_vm *sa, char *buff, size_t blen) { + if (xio_snprintf(buff, blen, "cid:%u port:%u", sa->svm_cid, sa->svm_port) >= blen) { + Warn("sockaddr_vm_info(): buffer too short"); + buff[blen-1] = '\0'; + } + return buff; +} + +int sockaddr_vm_parse(struct sockaddr_vm *sa, const char *cid_str, + const char *port_str) +{ + char *garbage = NULL; + if (!cid_str) { + sa->svm_cid = VMADDR_CID_ANY; + } else { + sa->svm_cid = strtoul(cid_str, &garbage, 0); + if (*garbage != '\0') { + Error1("sockaddr_vm - garbage in cid: \"%s\"", garbage); + return -EINVAL; + } + } + + if (!port_str) { + sa->svm_port = VMADDR_PORT_ANY; + } else { + sa->svm_port = strtoul(port_str, &garbage, 0); + if (*garbage != '\0') { + Error1("sockaddr_vm - garbage in port: \"%s\"", garbage); + return -EINVAL; + } + } + + return 0; +} +#endif /* WITH_IP4 */ + #if !HAVE_INET_NTOP /* http://www.opengroup.org/onlinepubs/000095399/functions/inet_ntop.html */ const char *inet_ntop(int pf, const void *binaddr, diff --git a/sysutils.h b/sysutils.h index 6a37e3f..48c24b5 100644 --- a/sysutils.h +++ b/sysutils.h @@ -27,6 +27,9 @@ union sockaddr_union { #if WITH_IP6 struct sockaddr_in6 ip6; #endif /* WITH_IP6 */ +#if WITH_VSOCK + struct sockaddr_vm vm; +#endif /* WITH_IP6 */ #if WITH_INTERFACE struct sockaddr_ll ll; #endif @@ -68,6 +71,11 @@ extern char *sockaddr_inet4_info(const struct sockaddr_in *sa, char *buff, size_ #if WITH_IP6 extern char *sockaddr_inet6_info(const struct sockaddr_in6 *sa, char *buff, size_t blen); #endif /* WITH_IP6 */ +#if WITH_VSOCK +extern char *sockaddr_vm_info(const struct sockaddr_vm *sa, char *buff, size_t blen); +extern int sockaddr_vm_parse(struct sockaddr_vm *sa, const char *cid_str, + const char *port_str); +#endif /* WITH_VSOCK */ #if !HAVE_INET_NTOP extern const char *inet_ntop(int pf, const void *binaddr, char *addrtext, socklen_t textlen); diff --git a/test.sh b/test.sh index 9cfa9e3..0b97f19 100755 --- a/test.sh +++ b/test.sh @@ -35,6 +35,7 @@ done opt_t="-t $val_t" UNAME=`uname` +UNAME_R=`uname -r` #MICROS=100000 case "X$val_t" in @@ -14588,6 +14589,62 @@ PORT=$((PORT+1)) N=$((N+1)) +# Test communication via vsock loopback socket +NAME=VSOCK_ECHO +case "$TESTS" in +*%$N%*|*%functions%*|*%vsock%*|*%socket%*|*%$NAME%*) +TEST="$NAME: test communication via vsock loopback socket" +# Start a listening echo server +# Connect with a client, send data and compare reply with original data +if ! eval $NUMCOND; then :; else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="test$N $(date) $RANDOM" +CMD0="$TRACE $SOCAT $opts VSOCK-LISTEN:$PORT PIPE" +CMD1="$TRACE $SOCAT $opts - VSOCK-CONNECT:1:$PORT" +printf "test $F_n $TEST... " $N +$CMD0 >/dev/null 2>"${te}0" & +pid0=$! +sleep 1 +echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" +rc1=$? +kill $pid0 2>/dev/null; wait +if [ $rc1 -ne 0 ] && [ "$UNAME" != Linux ]; then + $PRINTF "${YELLOW}works only on Linux?${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! [[ $UNAME_R =~ ^[6-9]\.* ]] && ! [[ $UNAME_R =~ ^5\.[6-]\.* ]] && ! [[ $UNAME_R =~ ^5\.[1-9][0-9].* ]]; then + $PRINTF "${YELLOW}works only on Linux from 5.6${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +elif [ $rc1 -ne 0 ]; then + $PRINTF "$FAILED\n" + echo "$CMD0 &" >&2 + cat "${te}0" >&2 + echo "$CMD1" >&2 + cat "${te}1" >&2 + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" +elif echo "$da" |diff - ${tf}1 >${tfdiff}$N; then + $PRINTF "$OK\n" + numOK=$((numOK+1)) +else + $PRINTF "$FAILED\n" + echo "$CMD0 &" >&2 + cat "${te}0" >&2 + echo "$CMD1" >&2 + cat "${te}1" >&2 + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" +fi +fi # NUMCOND + ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + + ################################################################################## #================================================================================= # here come tests that might affect your systems integrity. Put normal tests diff --git a/xio-ip.c b/xio-ip.c index ee572e1..9ad642c 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -167,6 +167,17 @@ int xiogetaddrinfo(const char *node, const char *service, if (service && service[0]=='\0') { Error("empty port/service"); } + +#ifdef WITH_VSOCK + if (family == AF_VSOCK) { + error_num = sockaddr_vm_parse(&sau->vm, node, service); + if (error_num < 0) + return STAT_NORETRY; + + return STAT_OK; + } +#endif /* WITH_VSOCK */ + /* if service is numeric we don't want to have a lookup (might take long with NIS), so we handle this specially */ if (service && isdigit(service[0]&0xff)) { diff --git a/xio-listen.c b/xio-listen.c index c06335e..73f4041 100644 --- a/xio-listen.c +++ b/xio-listen.c @@ -152,6 +152,18 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl applyopts_offset(xfd, opts); applyopts_cloexec(xfd->fd, opts); +#if defined(WITH_VSOCK) && defined(IOCTL_VM_SOCKETS_GET_LOCAL_CID) + { + unsigned int cid; + if (Ioctl(xfd->fd, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid) < 0) { + Warn2("ioctl(%d, IOCTL_VM_SOCKETS_GET_LOCAL_CID, ...): %s", + xfd->fd, strerror(errno)); + } else { + Notice1("VSOCK CID=%u", cid); + } + } +#endif + applyopts(xfd->fd, opts, PH_PREBIND); applyopts(xfd->fd, opts, PH_BIND); if (Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) { diff --git a/xio-vsock.c b/xio-vsock.c new file mode 100644 index 0000000..0720b2e --- /dev/null +++ b/xio-vsock.c @@ -0,0 +1,157 @@ +/* source: xio-vsock.c */ +/* Copyright Gerhard Rieger and contributors (see file CHANGES) */ +/* Author: Stefano Garzarella :") }; +#if WITH_LISTEN +const struct addrdesc addr_vsock_listen = { "vsock-listen", 1 + XIO_RDWR, + xioopen_vsock_listen, + GROUP_FD|GROUP_SOCKET|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, + 0, 0, 0 HELP(":") }; +#endif /* WITH_LISTEN */ + +static int vsock_addr_init(struct sockaddr_vm *sa, const char *cid_str, + const char *port_str) { + int ret; + + memset(sa, 0, sizeof(*sa)); + + sa->svm_family = AF_VSOCK; + ret = sockaddr_vm_parse(sa, cid_str, port_str); + if (ret < 0) + return STAT_NORETRY; + + return STAT_OK; +} + +static int vsock_init(struct opt *opts, struct single *xfd) { + + xfd->howtoend = END_SHUTDOWN; + + if (applyopts_single(xfd, opts, PH_INIT) < 0) + return STAT_NORETRY; + + applyopts(-1, opts, PH_INIT); + applyopts(-1, opts, PH_EARLY); + + xfd->dtype = XIODATA_STREAM; + + return STAT_OK; +} + +static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xxfd, unsigned groups, + int abstract, int dummy2, int dummy3) { + /* we expect the form :cid:port */ + struct single *xfd = &xxfd->stream; + struct sockaddr_vm sa, sa_local; + socklen_t sa_len = sizeof(sa); + bool needbind = false; + int socktype = SOCK_STREAM; + int pf = PF_VSOCK; + int protocol = 0; + int ret; + + if (argc != 3) { + Error2("%s: wrong number of parameters (%d instead of 2)", + argv[0], argc-1); + return STAT_NORETRY; + } + + ret = vsock_addr_init(&sa, argv[1], argv[2]); + if (ret) { + return ret; + } + + ret = vsock_init(opts, xfd); + if (ret) { + return ret; + } + + ret = retropt_bind(opts, pf, socktype, protocol, + (struct sockaddr *)&sa_local, &sa_len, 3, 0, 0); + if (ret == STAT_NORETRY) + return ret; + if (ret == STAT_OK) + needbind = true; + + ret = xioopen_connect(xfd, needbind ? (union sockaddr_union *)&sa_local : NULL, + sa_len, (struct sockaddr *)&sa, sizeof(sa), + opts, pf, socktype, protocol, false); + if (ret) + return ret; + + ret = _xio_openlate(xfd, opts); + if (ret < 0) + return ret; + + return STAT_OK; +} + +#if WITH_LISTEN +static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, + int dummy2, int dummy3) { + /* we expect the form :port */ + struct single *xfd = &xxfd->stream; + struct sockaddr_vm sa, sa_bind; + socklen_t sa_len = sizeof(sa_bind); + struct opt *opts0; + int socktype = SOCK_STREAM; + int pf = PF_VSOCK; + int protocol = 0; + int ret; + + if (argc != 2) { + Error2("%s: wrong number of parameters (%d instead of 1)", + argv[0], argc-1); + return STAT_NORETRY; + } + + ret = vsock_addr_init(&sa, NULL, argv[1]); + if (ret) { + return ret; + } + + ret = vsock_init(opts, xfd); + if (ret) { + return ret; + } + + opts0 = copyopts(opts, GROUP_ALL); + + ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_bind, + &sa_len, 1, 0, 0); + if (ret == STAT_NORETRY) + return ret; + if (ret == STAT_OK) + sa.svm_cid = sa_bind.svm_cid; + + /* this may fork() */ + return xioopen_listen(xfd, xioflags, (struct sockaddr *)&sa, sizeof(sa), + opts, opts0, pf, socktype, protocol); +} + +#endif /* WITH_LISTEN */ +#endif /* WITH_VSOCK */ diff --git a/xio-vsock.h b/xio-vsock.h new file mode 100644 index 0000000..20e36a4 --- /dev/null +++ b/xio-vsock.h @@ -0,0 +1,11 @@ +/* source: xio-vsock.h */ +/* Copyright Gerhard Rieger and contributors (see file CHANGES) */ +/* Author: Stefano Garzarella