Corrected VSOCK CID query; minor VSOCK features

This commit is contained in:
Gerhard Rieger 2023-06-12 08:37:49 +02:00
parent b05b360320
commit 10a741eb60
6 changed files with 88 additions and 21 deletions

10
CHANGES
View file

@ -18,7 +18,7 @@ Corrections:
Filan: Corrected some syntax error messages 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 TCP/UDP on options -s, -S
Test: FILAN_SHORT_TCP Test: FILAN_SHORT_TCP
@ -28,6 +28,14 @@ Corrections:
Filan: Fixed diag_set() call in filan_main.c, bug popped up with C23. 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. 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: Coding:
New Environment variable SOCAT_TRANSFER_WAIT that Socat sleep before New Environment variable SOCAT_TRANSFER_WAIT that Socat sleep before
starting the data transfer loop. Useful, e.g., to accumulate multiple starting the data transfer loop. Useful, e.g., to accumulate multiple

View file

@ -1365,7 +1365,6 @@ label(ADDRESS_VSOCK_CONNECT)dit(bf(tt(VSOCK-CONNECT:<cid>:<port>)))
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl()
Useful options: Useful options:
link(bind)(OPTION_BIND), link(bind)(OPTION_BIND),
link(pf)(OPTION_PROTOCOL_FAMILY),
link(connect-timeout)(OPTION_CONNECT_TIMEOUT), link(connect-timeout)(OPTION_CONNECT_TIMEOUT),
link(retry)(OPTION_RETRY), link(retry)(OPTION_RETRY),
link(readbytes)(OPTION_READBYTES)nl() link(readbytes)(OPTION_READBYTES)nl()
@ -1380,7 +1379,6 @@ label(ADDRESS_VSOCK_LISTEN)dit(bf(tt(VSOCK-LISTEN:<port>)))
Useful options: Useful options:
link(fork)(OPTION_FORK), link(fork)(OPTION_FORK),
link(bind)(OPTION_BIND), link(bind)(OPTION_BIND),
link(pf)(OPTION_PROTOCOL_FAMILY),
link(max-children)(OPTION_MAX_CHILDREN), link(max-children)(OPTION_MAX_CHILDREN),
link(backlog)(OPTION_BACKLOG), link(backlog)(OPTION_BACKLOG),
link(su)(OPTION_SUBSTUSER), link(su)(OPTION_SUBSTUSER),

View file

@ -19,6 +19,8 @@
static int iffan(FILE *outfile); static int iffan(FILE *outfile);
static int vsockan(FILE *outfile);
int hostan(FILE *outfile) { int hostan(FILE *outfile) {
fprintf(outfile, "\nC TYPE SIZES\n"); fprintf(outfile, "\nC TYPE SIZES\n");
@ -40,6 +42,9 @@ int hostan(FILE *outfile) {
#if _WITH_SOCKET && (_WITH_IP4 || _WITH_IP6) #if _WITH_SOCKET && (_WITH_IP4 || _WITH_IP6)
fprintf(outfile, "\nIP INTERFACES\n"); fprintf(outfile, "\nIP INTERFACES\n");
iffan(outfile); iffan(outfile);
#endif
#if WITH_VSOCK
vsockan(outfile);
#endif #endif
return 0; return 0;
} }
@ -101,3 +106,24 @@ static int iffan(FILE *outfile) {
return 0; return 0;
} }
#endif /* _WITH_SOCKET */ #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 */

View file

@ -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 xioflags, xiofile_t *xxfd, unsigned groups, int abstract,
int dummy2, int dummy3); int dummy2, int dummy3);
static void xiolog_vsock_cid(void);
const struct addrdesc addr_vsock_connect = { "vsock-connect", 1 + XIO_RDWR, const struct addrdesc addr_vsock_connect = { "vsock-connect", 1 + XIO_RDWR,
xioopen_vsock_connect, xioopen_vsock_connect,
GROUP_FD|GROUP_SOCKET|GROUP_CHILD|GROUP_RETRY, 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(":<port>") }; 0, 0, 0 HELP(":<port>") };
#endif /* WITH_LISTEN */ #endif /* WITH_LISTEN */
/* Initializes a sockaddr of type VSOCK */
static int vsock_addr_init(struct sockaddr_vm *sa, const char *cid_str, 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; int ret;
memset(sa, 0, sizeof(*sa)); memset(sa, 0, sizeof(*sa));
sa->svm_family = AF_VSOCK; sa->svm_family = pf;
ret = sockaddr_vm_parse(sa, cid_str, port_str); ret = sockaddr_vm_parse(sa, cid_str, port_str);
if (ret < 0) if (ret < 0)
return STAT_NORETRY; return STAT_NORETRY;
@ -45,6 +49,8 @@ static int vsock_addr_init(struct sockaddr_vm *sa, const char *cid_str,
return STAT_OK; return STAT_OK;
} }
/* Performs a few steps during opening an address of type VSOCK */
static int vsock_init(struct opt *opts, struct single *xfd) { static int vsock_init(struct opt *opts, struct single *xfd) {
xfd->howtoend = END_SHUTDOWN; xfd->howtoend = END_SHUTDOWN;
@ -79,7 +85,11 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
return STAT_NORETRY; 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) { if (ret) {
return ret; return ret;
} }
@ -89,6 +99,8 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
return ret; return ret;
} }
xiolog_vsock_cid();
ret = retropt_bind(opts, pf, socktype, protocol, ret = retropt_bind(opts, pf, socktype, protocol,
(struct sockaddr *)&sa_local, &sa_len, 3, 0, 0); (struct sockaddr *)&sa_local, &sa_len, 3, 0, 0);
if (ret == STAT_NORETRY) if (ret == STAT_NORETRY)
@ -109,6 +121,7 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
return STAT_OK; return STAT_OK;
} }
#if WITH_LISTEN #if WITH_LISTEN
static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, 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; 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) { if (ret) {
return ret; return ret;
} }
@ -139,16 +156,6 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
return ret; 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); opts0 = copyopts(opts, GROUP_ALL);
ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_bind, 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) if (ret == STAT_OK)
sa.svm_cid = sa_bind.svm_cid; sa.svm_cid = sa_bind.svm_cid;
xiolog_vsock_cid();
/* this may fork() */ /* this may fork() */
return xioopen_listen(xfd, xioflags, (struct sockaddr *)&sa, sizeof(sa), return xioopen_listen(xfd, xioflags, (struct sockaddr *)&sa, sizeof(sa),
opts, opts0, pf, socktype, protocol); opts, opts0, pf, socktype, protocol);
} }
#endif /* WITH_LISTEN */ #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 /* Returns information that can be used for constructing an environment
variable describing the socket address. variable describing the socket address.
if idx is 0, this function writes "ADDR" into namebuff and the CID address if idx is 0, this function writes "ADDR" into namebuff and the CID address

View file

@ -2,14 +2,19 @@
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */ /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
/* Author: Stefano Garzarella <sgarzare@redhat.com */ /* Author: Stefano Garzarella <sgarzare@redhat.com */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
#ifndef __xio_vsock_h_included #ifndef __xio_vsock_h_included
#define __xio_vsock_h_included 1 #define __xio_vsock_h_included 1
#if WITH_VSOCK
extern const struct addrdesc addr_vsock_connect; extern const struct addrdesc addr_vsock_connect;
extern const struct addrdesc addr_vsock_listen; extern const struct addrdesc addr_vsock_listen;
extern int xiosetsockaddrenv_vsock(int idx, char *namebuff, size_t namelen, extern int xiosetsockaddrenv_vsock(int idx, char *namebuff, size_t namelen,
char *valuebuff, size_t valuelen, char *valuebuff, size_t valuelen,
struct sockaddr_vm *sa, int ipproto); struct sockaddr_vm *sa, int ipproto);
#endif /* WITH_VSOCK */
#endif /* !defined(__xio_vsock_h_included) */ #endif /* !defined(__xio_vsock_h_included) */