From 20451db88cdc9d91454e3747f37777ae805d3fda Mon Sep 17 00:00:00 2001 From: "Else, Someone" Date: Fri, 7 Nov 2025 19:04:58 +0200 Subject: [PATCH] ch-proxy: support normal vsock --- pkgs/ch-proxy/proxy.c | 89 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/pkgs/ch-proxy/proxy.c b/pkgs/ch-proxy/proxy.c index 78bfefd..ed1dea0 100644 --- a/pkgs/ch-proxy/proxy.c +++ b/pkgs/ch-proxy/proxy.c @@ -7,6 +7,8 @@ #include #include +#include + struct msghdr mk_msghdr(); int ch_connect(const char*, const char*); ssize_t send_fd(int, int); @@ -18,7 +20,8 @@ void print_usage() { "Usage:\n" "\tch-proxy uvm/$USER_VM_NAME [PORT]\n" "\tch-proxy uuvm/$VM_NAME [PORT]\n" - "\tch-proxy vsock-mux%$PATH [PORT]\n"); + "\tch-proxy vsock-mux%$PATH [PORT]\n" + "\tch-proxy vsock/cid[:port]\n"); } char *extract_vsock_mux(const char *host_string) { @@ -67,6 +70,50 @@ char *extract_muvm(const char *host_string) { return result; } +int extract_cid(const char *host, int *cid, int *port) { + if (errno != 0) { + perror("extract_cid(...): errno unclean"); + exit(EXIT_FAILURE); + } + + const char PREFIX[] = "vsock/"; + const ssize_t PREFIX_LEN = sizeof(PREFIX) - 1; + + if (strncmp(host, PREFIX, PREFIX_LEN) != 0) { + return 1; + } + + char *in = NULL; + const char *end = host + strlen(host); + const char *sCid = host + PREFIX_LEN; + + long x; + x = strtol(sCid, &in, 10); + if (errno != 0) { + perror("strtol(cid, ...)"); + exit(EXIT_FAILURE); + } + *cid = (int) x; + + if (in == end) { + *port = 22; + return 0; + } else if (in[0] != ':') { + perror("extract_cid(...): expected a string of the form cid[:port]"); + perror(host); + exit(EXIT_FAILURE); + } + + const char *sPort = in + 1; + x = strtol(sPort, &in, 10); + if (errno != 0) { + perror("strtol(port, ...)"); + exit(EXIT_FAILURE); + } + *port = (int) x; + return 0; +} + int main(int argc, char** argv) { if (!(2 <= argc && argc <= 3)) { fprintf(stderr, "%s: Wrong # of arguments: %d\n", argv[0], argc); @@ -79,21 +126,47 @@ int main(int argc, char** argv) { const char *ssh_host = argv[1]; const char *port_string = argc == 3 ? argv[2] : PORT_DEFAULT; - char *path_un; + int cid = -1, port = -1; + char *path_un = NULL; if ((path_un = extract_uvm(ssh_host)) != NULL) { } else if ((path_un = extract_muvm(ssh_host)) != NULL) { } else if ((path_un = extract_vsock_mux(ssh_host)) != NULL) { + } else if (extract_cid(ssh_host, &cid, &port) == 0) { } else { - fprintf(stderr, "ch-proxy/main: unexpected host stirng format: %s\n", ssh_host); + fprintf(stderr, "ch-proxy/main: unexpected host string format: %s\n", ssh_host); print_usage(); return EXIT_FAILURE; } - const int s = ch_connect(path_un, port_string); - if (s == -1) { - perror("ssh-vsock-proxy/main/ch_connect"); - return EXIT_FAILURE; - }; + int s = -1; + + if (path_un != NULL) { + s = ch_connect(path_un, port_string); + if (s == -1) { + perror("ssh-vsock-proxy/main/ch_connect"); + return EXIT_FAILURE; + }; + } else if (cid != -1 && port != -1) { + struct sockaddr_vm sa = { + .svm_family = AF_VSOCK, + .svm_reserved1 = 0, + .svm_port = port, + .svm_cid = cid, + }; + memset(sa.svm_zero, 0, sizeof(sa.svm_zero)); + s = socket(AF_VSOCK, SOCK_STREAM, 0); + if (s == -1) { + perror("socket(AF_VSOCK, ...)"); + exit(EXIT_FAILURE); + } + if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) != 0) { + perror("connect(socket(AF_VSOCK, ...), ...)"); + exit(EXIT_FAILURE); + } + } else { + perror("Couldn't parse neither uuvm/ strings nor vsock/cid[:port]"); + exit(EXIT_FAILURE); + } if (send_fd(1, s) == -1) { perror("ssh-vsock-proxy/main/send_fd");