From 10a741eb6046c100a97c206ad8bf1af97b9694b9 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 12 Jun 2023 08:37:49 +0200 Subject: [PATCH] Corrected VSOCK CID query; minor VSOCK features --- CHANGES | 10 ++++++++- doc/socat.yo | 2 -- hostan.c | 26 +++++++++++++++++++++++ xio-socket.c | 2 +- xio-vsock.c | 60 +++++++++++++++++++++++++++++++++++++++------------- xio-vsock.h | 9 ++++++-- 6 files changed, 88 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index 8a0a3b3..c33b4e4 100644 --- a/CHANGES +++ b/CHANGES @@ -18,7 +18,7 @@ Corrections: Filan: Corrected some syntax error messages - Filan: Fixed a bug introduces in 1.7.4.4 that broke displaying + Filan: Fixed a bug introduced in 1.7.4.4 that broke displaying TCP/UDP on options -s, -S Test: FILAN_SHORT_TCP @@ -28,6 +28,14 @@ Corrections: Filan: Fixed diag_set() call in filan_main.c, bug popped up with C23. Thanks to Cristian Rodríguez from openSUSE for reporting this issue. + Querying the vsock Context Identifier (CID) requires an FD from opening + /dev/vsock. + Thanks to Volker Simonis for sending a patch. + +Features: + VSOCK, VSOCK-L support options pf, socktype, prototype (currently + useless) + Coding: New Environment variable SOCAT_TRANSFER_WAIT that Socat sleep before starting the data transfer loop. Useful, e.g., to accumulate multiple diff --git a/doc/socat.yo b/doc/socat.yo index 4f40ddb..e898986 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1365,7 +1365,6 @@ label(ADDRESS_VSOCK_CONNECT)dit(bf(tt(VSOCK-CONNECT::))) 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() @@ -1380,7 +1379,6 @@ label(ADDRESS_VSOCK_LISTEN)dit(bf(tt(VSOCK-LISTEN:))) 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), diff --git a/hostan.c b/hostan.c index 3a7dc97..dfa1b2e 100644 --- a/hostan.c +++ b/hostan.c @@ -19,6 +19,8 @@ static int iffan(FILE *outfile); +static int vsockan(FILE *outfile); + int hostan(FILE *outfile) { fprintf(outfile, "\nC TYPE SIZES\n"); @@ -40,6 +42,9 @@ int hostan(FILE *outfile) { #if _WITH_SOCKET && (_WITH_IP4 || _WITH_IP6) fprintf(outfile, "\nIP INTERFACES\n"); iffan(outfile); +#endif +#if WITH_VSOCK + vsockan(outfile); #endif return 0; } @@ -101,3 +106,24 @@ static int iffan(FILE *outfile) { return 0; } #endif /* _WITH_SOCKET */ + + +#if WITH_VSOCK +static int vsockan(FILE *outfile) { + unsigned int cid; + int vsock; + if ((vsock = Open("/dev/vsock", O_RDONLY, 0)) < 0 ) { + Warn1("open(\"/dev/vsock\", ...): %s", strerror(errno)); + } else if (Ioctl(vsock, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid) < 0) { + Warn2("ioctl(%d, IOCTL_VM_SOCKETS_GET_LOCAL_CID, ...): %s", + vsock, strerror(errno)); + } else { + Notice1("VSOCK CID=%u", cid); + fprintf(outfile, "\nVSOCK_CID = %u\n", cid); + } + if (vsock >= 0) { + Close(vsock); + } + return 0; +} +#endif /* WITH_VSOCK */ diff --git a/xio-socket.c b/xio-socket.c index 1af7ca7..d8c5d47 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -2090,7 +2090,7 @@ int xiosetsockaddrenv(const char *lr, xiosetenv(namebuff, valuebuff, 1, NULL); namebuff[strlen(lr)] = '\0'; ++idx; } while (result > 0); - break; + break; #endif /* WITH_VSOCK */ #if LATER case PF_PACKET: diff --git a/xio-vsock.c b/xio-vsock.c index 957707a..37fed61 100644 --- a/xio-vsock.c +++ b/xio-vsock.c @@ -20,6 +20,8 @@ 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); +static void xiolog_vsock_cid(void); + const struct addrdesc addr_vsock_connect = { "vsock-connect", 1 + XIO_RDWR, xioopen_vsock_connect, GROUP_FD|GROUP_SOCKET|GROUP_CHILD|GROUP_RETRY, @@ -31,13 +33,15 @@ const struct addrdesc addr_vsock_listen = { "vsock-listen", 1 + XIO_RDWR, 0, 0, 0 HELP(":") }; #endif /* WITH_LISTEN */ + +/* Initializes a sockaddr of type VSOCK */ static int vsock_addr_init(struct sockaddr_vm *sa, const char *cid_str, - const char *port_str) { + const char *port_str, int pf) { int ret; memset(sa, 0, sizeof(*sa)); - sa->svm_family = AF_VSOCK; + sa->svm_family = pf; ret = sockaddr_vm_parse(sa, cid_str, port_str); if (ret < 0) return STAT_NORETRY; @@ -45,6 +49,8 @@ static int vsock_addr_init(struct sockaddr_vm *sa, const char *cid_str, return STAT_OK; } + +/* Performs a few steps during opening an address of type VSOCK */ static int vsock_init(struct opt *opts, struct single *xfd) { xfd->howtoend = END_SHUTDOWN; @@ -79,7 +85,11 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, return STAT_NORETRY; } - ret = vsock_addr_init(&sa, argv[1], argv[2]); + retropt_socket_pf(opts, &pf); + retropt_int(opts, OPT_SO_TYPE, &socktype); + retropt_int(opts, OPT_SO_PROTOTYPE, &protocol); + + ret = vsock_addr_init(&sa, argv[1], argv[2], pf); if (ret) { return ret; } @@ -89,6 +99,8 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, return ret; } + xiolog_vsock_cid(); + ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_local, &sa_len, 3, 0, 0); if (ret == STAT_NORETRY) @@ -109,6 +121,7 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, 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, @@ -129,7 +142,11 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, return STAT_NORETRY; } - ret = vsock_addr_init(&sa, NULL, argv[1]); + retropt_socket_pf(opts, &pf); + retropt_int(opts, OPT_SO_TYPE, &socktype); + retropt_int(opts, OPT_SO_PROTOTYPE, &protocol); + + ret = vsock_addr_init(&sa, NULL, argv[1], pf); if (ret) { return ret; } @@ -139,16 +156,6 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, return ret; } - { - 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); - } - } - opts0 = copyopts(opts, GROUP_ALL); ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_bind, @@ -158,13 +165,36 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, if (ret == STAT_OK) sa.svm_cid = sa_bind.svm_cid; + xiolog_vsock_cid(); + /* this may fork() */ return xioopen_listen(xfd, xioflags, (struct sockaddr *)&sa, sizeof(sa), opts, opts0, pf, socktype, protocol); } - #endif /* WITH_LISTEN */ + +/* Just tries to query and log the VSOCK CID */ +static void xiolog_vsock_cid(void) { + int vsock; + unsigned int cid; +#ifdef IOCTL_VM_SOCKETS_GET_LOCAL_CID + if ((vsock = Open("/dev/vsock", O_RDONLY, 0)) < 0 ) { + Warn1("open(\"/dev/vsock\", ...): %s", strerror(errno)); + } else if (Ioctl(vsock, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid) < 0) { + Warn2("ioctl(%d, IOCTL_VM_SOCKETS_GET_LOCAL_CID, ...): %s", + vsock, strerror(errno)); + } else { + Notice1("VSOCK CID=%u", cid); + } + if (vsock >= 0) { + Close(vsock); + } +#endif /* IOCTL_VM_SOCKETS_GET_LOCAL_CID */ + return; +} + + /* Returns information that can be used for constructing an environment variable describing the socket address. if idx is 0, this function writes "ADDR" into namebuff and the CID address diff --git a/xio-vsock.h b/xio-vsock.h index 0e88036..8d3dc14 100644 --- a/xio-vsock.h +++ b/xio-vsock.h @@ -2,14 +2,19 @@ /* Copyright Gerhard Rieger and contributors (see file CHANGES) */ /* Author: Stefano Garzarella