aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRenzo Davoli <renzo@cs.unibo.it>2019-12-29 16:12:08 +0100
committerMarc-André Lureau <marcandre.lureau@redhat.com>2020-01-04 14:04:55 +0400
commitb2199f4021c47359a81d46e9e4db3d93dcbb7232 (patch)
tree6035752ada8dc2556922db86bca8c989dc3cfcce
parent3d9118b4a0e8e12a9cffabcfa967a7d14eac0b6e (diff)
downloadslirp-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.md3
-rw-r--r--src/libslirp.h4
-rw-r--r--src/libslirp.map1
-rw-r--r--src/misc.c52
-rw-r--r--src/misc.h5
-rw-r--r--src/slirp.c17
-rw-r--r--src/tcp_subr.c5
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;
diff --git a/src/misc.c b/src/misc.c
index 924eb0d..fa65b6d 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -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);
diff --git a/src/misc.h b/src/misc.h
index 6ff7f54..841b0a7 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -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);
}
}
}