Hello, I wanted to remind you about my patch. Do I need to make any
further changes?


вс, 10 авг. 2025 г. в 14:35, Samuel Thibault <[email protected]>:
>
> Viktor Kurilko, le ven. 08 août 2025 21:29:25 +0700, a ecrit:
> > This patch adds the ability to map a host unix socket to a guest tcp socket 
> > when
> > using the slirp backend. This feature was added in libslirp version 4.7.0.
> >
> > A new syntax for unix socket: -hostfwd=unix:hostpath-[guestaddr]:guestport
> >
> > Signed-off-by: Viktor Kurilko <[email protected]>
>
> Reviewed-by: Samuel Thibault <[email protected]>
>
> Thanks!
>
> > ---
> > Separator parsing has been moved to protocol-specific blocks.
> > Fixed overwriting of sin_addr.
> > `
> >  docs/system/devices/net.rst |   2 +-
> >  hmp-commands.hx             |   4 +-
> >  net/slirp.c                 | 110 +++++++++++++++++++++++++++---------
> >  qapi/net.json               |   2 +-
> >  qemu-options.hx             |  11 +++-
> >  5 files changed, 97 insertions(+), 32 deletions(-)
> >
> > diff --git a/docs/system/devices/net.rst b/docs/system/devices/net.rst
> > index 7d76fe88c4..13199a44fd 100644
> > --- a/docs/system/devices/net.rst
> > +++ b/docs/system/devices/net.rst
> > @@ -79,7 +79,7 @@ those sockets. To allow ping for GID 100 (usually users 
> > group)::
> >
> >  When using the built-in TFTP server, the router is also the TFTP server.
> >
> > -When using the ``'-netdev user,hostfwd=...'`` option, TCP or UDP
> > +When using the ``'-netdev user,hostfwd=...'`` option, TCP, UDP or UNIX
> >  connections can be redirected from the host to the guest. It allows for
> >  example to redirect X11, telnet or SSH connections.
> >
> > diff --git a/hmp-commands.hx b/hmp-commands.hx
> > index d0e4f35a30..64a463b15b 100644
> > --- a/hmp-commands.hx
> > +++ b/hmp-commands.hx
> > @@ -1357,8 +1357,8 @@ ERST
> >      {
> >          .name       = "hostfwd_add",
> >          .args_type  = "arg1:s,arg2:s?",
> > -        .params     = "[netdev_id] 
> > [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
> > -        .help       = "redirect TCP or UDP connections from host to guest 
> > (requires -net user)",
> > +        .params     = "[netdev_id] 
> > [tcp|udp|unix]:[[hostaddr]:hostport|hostpath]-[guestaddr]:guestport",
> > +        .help       = "redirect TCP, UDP or UNIX connections from host to 
> > guest (requires -net user)",
> >          .cmd        = hmp_hostfwd_add,
> >      },
> >  #endif
> > diff --git a/net/slirp.c b/net/slirp.c
> > index 9657e86a84..1b5e67f9d1 100644
> > --- a/net/slirp.c
> > +++ b/net/slirp.c
> > @@ -795,12 +795,13 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict 
> > *qdict)
> >
> >  static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error 
> > **errp)
> >  {
> > -    struct sockaddr_in host_addr = {
> > -        .sin_family = AF_INET,
> > -        .sin_addr = {
> > -            .s_addr = INADDR_ANY,
> > -        },
> > -    };
> > +    union {
> > +        struct sockaddr_in in;
> > +#if !defined(WIN32) && SLIRP_CHECK_VERSION(4, 7, 0)
> > +        struct sockaddr_un un;
> > +#endif
> > +    } host_addr = {0};
> > +
> >      struct sockaddr_in guest_addr = {
> >          .sin_family = AF_INET,
> >          .sin_addr = {
> > @@ -811,9 +812,13 @@ static int slirp_hostfwd(SlirpState *s, const char 
> > *redir_str, Error **errp)
> >      int host_port, guest_port;
> >      const char *p;
> >      char buf[256];
> > -    int is_udp;
> > +    int is_udp = 0;
> > +#if !defined(WIN32) && SLIRP_CHECK_VERSION(4, 7, 0)
> > +    int is_unix = 0;
> > +#endif
> >      const char *end;
> >      const char *fail_reason = "Unknown reason";
> > +    socklen_t host_addr_size;
> >
> >      p = redir_str;
> >      if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
> > @@ -824,30 +829,83 @@ static int slirp_hostfwd(SlirpState *s, const char 
> > *redir_str, Error **errp)
> >          is_udp = 0;
> >      } else if (!strcmp(buf, "udp")) {
> >          is_udp = 1;
> > -    } else {
> > -        fail_reason = "Bad protocol name";
> > -        goto fail_syntax;
> >      }
> > -
> > -    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
> > -        fail_reason = "Missing : separator";
> > -        goto fail_syntax;
> > +#if !defined(WIN32) && SLIRP_CHECK_VERSION(4, 7, 0)
> > +    else if (!strcmp(buf, "unix")) {
> > +        is_unix = 1;
> >      }
> > -    if (buf[0] != '\0' && !inet_aton(buf, &host_addr.sin_addr)) {
> > -        fail_reason = "Bad host address";
> > +#endif
> > +    else {
> > +        fail_reason = "Bad protocol name";
> >          goto fail_syntax;
> >      }
> >
> > -    if (get_str_sep(buf, sizeof(buf), &p, '-') < 0) {
> > -        fail_reason = "Bad host port separator";
> > -        goto fail_syntax;
> > -    }
> > -    err = qemu_strtoi(buf, &end, 0, &host_port);
> > -    if (err || host_port < 0 || host_port > 65535) {
> > -        fail_reason = "Bad host port";
> > -        goto fail_syntax;
> > +#if !defined(WIN32) && SLIRP_CHECK_VERSION(4, 7, 0)
> > +    if (is_unix) {
> > +        if (get_str_sep(buf, sizeof(buf), &p, '-') < 0) {
> > +            fail_reason = "Missing - separator";
> > +            goto fail_syntax;
> > +        }
> > +        if (buf[0] == '\0') {
> > +            fail_reason = "Missing unix socket path";
> > +            goto fail_syntax;
> > +        }
> > +        if (buf[0] != '/') {
> > +            fail_reason = "unix socket path must be absolute";
> > +            goto fail_syntax;
> > +        }
> > +
> > +        size_t path_len = strlen(buf);
> > +        if (path_len > sizeof(host_addr.un.sun_path) - 1) {
> > +            fail_reason = "Unix socket path is too long";
> > +            goto fail_syntax;
> > +        }
> > +
> > +        struct stat st;
> > +        if (stat(buf, &st) == 0) {
> > +            if (!S_ISSOCK(st.st_mode)) {
> > +                fail_reason = "file exists and it's not unix socket";
> > +                goto fail_syntax;
> > +            }
> > +
> > +            if (unlink(buf) < 0) {
> > +                error_setg_errno(errp, errno, "Failed to unlink '%s'", 
> > buf);
> > +                goto fail_syntax;
> > +            }
> > +        }
> > +        host_addr.un.sun_family = AF_UNIX;
> > +        memcpy(host_addr.un.sun_path, buf, path_len);
> > +        host_addr_size = sizeof(host_addr.un);
> > +    } else
> > +#endif
> > +    {
> > +        host_addr.in.sin_family = AF_INET;
> > +        host_addr.in.sin_addr.s_addr = INADDR_ANY;
> > +
> > +        if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
> > +            fail_reason = "Missing : separator";
> > +            goto fail_syntax;
> > +        }
> > +
> > +        if (buf[0] != '\0' && !inet_aton(buf, &host_addr.in.sin_addr)) {
> > +            fail_reason = "Bad host address";
> > +            goto fail_syntax;
> > +        }
> > +
> > +        if (get_str_sep(buf, sizeof(buf), &p, '-') < 0) {
> > +            fail_reason = "Bad host port separator";
> > +            goto fail_syntax;
> > +        }
> > +
> > +        err = qemu_strtoi(buf, &end, 0, &host_port);
> > +        if (err || host_port < 0 || host_port > 65535) {
> > +            fail_reason = "Bad host port";
> > +            goto fail_syntax;
> > +        }
> > +
> > +        host_addr.in.sin_port = htons(host_port);
> > +        host_addr_size = sizeof(host_addr.in);
> >      }
> > -    host_addr.sin_port = htons(host_port);
> >
> >      if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
> >          fail_reason = "Missing guest address";
> > @@ -867,7 +925,7 @@ static int slirp_hostfwd(SlirpState *s, const char 
> > *redir_str, Error **errp)
> >
> >  #if SLIRP_CHECK_VERSION(4, 5, 0)
> >      err = slirp_add_hostxfwd(s->slirp,
> > -            (struct sockaddr *) &host_addr, sizeof(host_addr),
> > +            (struct sockaddr *) &host_addr, host_addr_size,
> >              (struct sockaddr *) &guest_addr, sizeof(guest_addr),
> >              is_udp ? SLIRP_HOSTFWD_UDP : 0);
> >  #else
> > diff --git a/qapi/net.json b/qapi/net.json
> > index 78bcc9871e..60d196afe5 100644
> > --- a/qapi/net.json
> > +++ b/qapi/net.json
> > @@ -281,7 +281,7 @@
> >  #
> >  # @smbserver: IP address of the built-in SMB server
> >  #
> > -# @hostfwd: redirect incoming TCP or UDP host connections to guest
> > +# @hostfwd: redirect incoming TCP, UDP or UNIX host connections to guest
> >  #     endpoints
> >  #
> >  # @guestfwd: forward guest TCP connections
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index ab23f14d21..86a70e0315 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -3317,8 +3317,8 @@ SRST
> >
> >          Note that a SAMBA server must be installed on the host OS.
> >
> > -    ``hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport``
> > -        Redirect incoming TCP or UDP connections to the host port
> > +    
> > ``hostfwd=[tcp|udp|unix]:[[hostaddr]:hostport|hostpath]-[guestaddr]:guestport``
> > +        Redirect incoming TCP, UDP or UNIX connections to the host port
> >          hostport to the guest IP address guestaddr on guest port
> >          guestport. If guestaddr is not specified, its value is x.x.x.15
> >          (default first address given by the built-in DHCP server). By
> > @@ -3348,6 +3348,13 @@ SRST
> >          Then when you use on the host ``telnet localhost 5555``, you
> >          connect to the guest telnet server.
> >
> > +        To redirect host unix socket /tmp/vm to guest tcp socket 23 use
> > +        following:
> > +
> > +        .. parsed-literal::
> > +            # on the host
> > +            |qemu_system| -nic user,hostfwd=unix:/tmp/vm-:23
> > +
> >      ``guestfwd=[tcp]:server:port-dev``; \ 
> > ``guestfwd=[tcp]:server:port-cmd:command``
> >          Forward guest TCP connections to the IP address server on port
> >          port to the character device dev or to a program executed by
> > --
> > 2.50.1
> >
>
> --
> Samuel
> <i8b4uUnderground> d-_-b
> <BonyNoMore> how u make that inverted b?
> <BonyNoMore> wait
> <BonyNoMore> never mind

Reply via email to