diff options
author | Renzo Davoli <renzo@cs.unibo.it> | 2019-12-29 16:12:08 +0100 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2020-01-04 14:04:55 +0400 |
commit | b2199f4021c47359a81d46e9e4db3d93dcbb7232 (patch) | |
tree | 6035752ada8dc2556922db86bca8c989dc3cfcce | |
parent | 3d9118b4a0e8e12a9cffabcfa967a7d14eac0b6e (diff) | |
download | slirp-b2199f4021c47359a81d46e9e4db3d93dcbb7232.zip slirp-b2199f4021c47359a81d46e9e4db3d93dcbb7232.tar.gz slirp-b2199f4021c47359a81d46e9e4db3d93dcbb7232.tar.bz2 |
Add slirp_add_unix()
Add a new function to forward to a unix socket.
Signed-off-by: Renzo Davoli <renzo@cs.unibo.it>
[ Marc-André - a bunch of cleanups ]
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | src/libslirp.h | 4 | ||||
-rw-r--r-- | src/libslirp.map | 1 | ||||
-rw-r--r-- | src/misc.c | 52 | ||||
-rw-r--r-- | src/misc.h | 5 | ||||
-rw-r--r-- | src/slirp.c | 17 | ||||
-rw-r--r-- | src/tcp_subr.c | 5 |
7 files changed, 84 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5218a36..00d0ce2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added + - New API function `slirp_add_unix`: add a forward rule to a Unix socket. - New API function `slirp_remove_guestfwd`: remove a forward rule previously - added by `slirp_add_exec` or `slirp_add_guestfwd` + added by `slirp_add_exec`, `slirp_add_unix` or `slirp_add_guestfwd` ### Changed diff --git a/src/libslirp.h b/src/libslirp.h index 3c8baba..ad93edf 100644 --- a/src/libslirp.h +++ b/src/libslirp.h @@ -138,9 +138,11 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, int host_port); int slirp_add_exec(Slirp *slirp, const char *cmdline, struct in_addr *guest_addr, int guest_port); +int slirp_add_unix(Slirp *slirp, const char *unixsock, + struct in_addr *guest_addr, int guest_port); int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque, struct in_addr *guest_addr, int guest_port); -/* remove entries added by slirp_add_exec or slirp_add_guestfwd */ +/* remove entries added by slirp_add_exec, slirp_add_unix or slirp_add_guestfwd */ int slirp_remove_guestfwd(Slirp *slirp, struct in_addr guest_addr, int guest_port); diff --git a/src/libslirp.map b/src/libslirp.map index 20f9c8d..72aab91 100644 --- a/src/libslirp.map +++ b/src/libslirp.map @@ -25,5 +25,6 @@ SLIRP_4.1 { } SLIRP_4.0; SLIRP_4.2 { + slirp_add_unix; slirp_remove_guestfwd; } SLIRP_4.1; @@ -4,6 +4,9 @@ */ #include "slirp.h" +#ifdef G_OS_UNIX +#include <sys/un.h> +#endif inline void insque(void *a, void *b) { @@ -50,6 +53,16 @@ struct gfwd_list *add_exec(struct gfwd_list **ex_ptr, const char *cmdline, return f; } +struct gfwd_list *add_unix(struct gfwd_list **ex_ptr, const char *unixsock, + struct in_addr addr, int port) +{ + struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port); + + f->ex_unix = g_strdup(unixsock); + + return f; +} + int remove_guestfwd(struct gfwd_list **ex_ptr, struct in_addr addr, int port) { for (; *ex_ptr != NULL; ex_ptr = &((*ex_ptr)->ex_next)) { @@ -224,6 +237,45 @@ int fork_exec(struct socket *so, const char *ex) return 1; } +int open_unix(struct socket *so, const char *unixpath) +{ +#ifdef G_OS_UNIX + struct sockaddr_un sa; + int s; + + DEBUG_CALL("open_unix"); + DEBUG_ARG("so = %p", so); + DEBUG_ARG("unixpath = %s", unixpath); + + memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + if (g_strlcpy(sa.sun_path, unixpath, sizeof(sa.sun_path)) >= sizeof(sa.sun_path)) { + g_critical("Bad unix path: %s", unixpath); + return 0; + } + + s = slirp_socket(PF_UNIX, SOCK_STREAM, 0); + if (s < 0) { + g_critical("open_unix(): %s", strerror(errno)); + return 0; + } + + if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { + g_critical("open_unix(): %s", strerror(errno)); + closesocket(s); + return 0; + } + + so->s = s; + slirp_set_nonblock(so->s); + so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque); + + return 1; +#else + g_assert_not_reached(); +#endif +} + char *slirp_connection_info(Slirp *slirp) { GString *str = g_string_new(NULL); @@ -14,6 +14,7 @@ struct gfwd_list { struct in_addr ex_addr; /* Server address */ int ex_fport; /* Port to telnet to */ char *ex_exec; /* Command line of what to exec */ + char *ex_unix; /* unix socket */ struct gfwd_list *ex_next; }; @@ -53,6 +54,7 @@ struct slirp_quehead { void slirp_insque(void *, void *); void slirp_remque(void *); int fork_exec(struct socket *so, const char *ex); +int open_unix(struct socket *so, const char *unixsock); struct gfwd_list *add_guestfwd(struct gfwd_list **ex_ptr, SlirpWriteCb write_cb, void *opaque, struct in_addr addr, int port); @@ -60,6 +62,9 @@ struct gfwd_list *add_guestfwd(struct gfwd_list **ex_ptr, SlirpWriteCb write_cb, struct gfwd_list *add_exec(struct gfwd_list **ex_ptr, const char *cmdline, struct in_addr addr, int port); +struct gfwd_list *add_unix(struct gfwd_list **ex_ptr, const char *unixsock, + struct in_addr addr, int port); + int remove_guestfwd(struct gfwd_list **ex_ptr, struct in_addr addr, int port); #endif diff --git a/src/slirp.c b/src/slirp.c index 1abbce5..e82e7e8 100644 --- a/src/slirp.c +++ b/src/slirp.c @@ -368,6 +368,7 @@ void slirp_cleanup(Slirp *slirp) for (e = slirp->guestfwd_list; e; e = next) { next = e->ex_next; g_free(e->ex_exec); + g_free(e->ex_unix); g_free(e); } @@ -1049,6 +1050,22 @@ int slirp_add_exec(Slirp *slirp, const char *cmdline, return 0; } +int slirp_add_unix(Slirp *slirp, const char *unixsock, + struct in_addr *guest_addr, int guest_port) +{ +#ifdef G_OS_UNIX + if (!check_guestfwd(slirp, guest_addr, guest_port)) { + return -1; + } + + add_unix(&slirp->guestfwd_list, unixsock, *guest_addr, htons(guest_port)); + return 0; +#else + g_warn_if_reached(); + return -1; +#endif +} + int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque, struct in_addr *guest_addr, int guest_port) { diff --git a/src/tcp_subr.c b/src/tcp_subr.c index 3ccea96..382aa38 100644 --- a/src/tcp_subr.c +++ b/src/tcp_subr.c @@ -948,7 +948,10 @@ int tcp_ctl(struct socket *so) return 1; } DEBUG_MISC(" executing %s", ex_ptr->ex_exec); - return fork_exec(so, ex_ptr->ex_exec); + if (ex_ptr->ex_unix) + return open_unix(so, ex_ptr->ex_unix); + else + return fork_exec(so, ex_ptr->ex_exec); } } } |