Merge branch 'listen_v6only' into 'master'
Listen v6only
See merge request slirp/libslirp!77
diff --git a/src/debug.h b/src/debug.h
index 47712bd..0f9f3ef 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -10,6 +10,7 @@
#define DBG_MISC (1 << 1)
#define DBG_ERROR (1 << 2)
#define DBG_TFTP (1 << 3)
+#define DBG_VERBOSE_CALL (1 << 4)
extern int slirp_debug;
@@ -20,6 +21,13 @@
} \
} while (0)
+#define DEBUG_VERBOSE_CALL(fmt, ...) \
+ do { \
+ if (G_UNLIKELY(slirp_debug & DBG_VERBOSE_CALL)) { \
+ g_debug(fmt "...", ##__VA_ARGS__); \
+ } \
+ } while (0)
+
#define DEBUG_ARG(fmt, ...) \
do { \
if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \
diff --git a/src/if.c b/src/if.c
index 23190b5..83dcae3 100644
--- a/src/if.c
+++ b/src/if.c
@@ -143,7 +143,7 @@
bool from_batchq = false;
struct mbuf *ifm, *ifm_next, *ifqt;
- DEBUG_CALL("if_start");
+ DEBUG_VERBOSE_CALL("if_start");
if (slirp->if_start_busy) {
return;
diff --git a/src/libslirp.h b/src/libslirp.h
index 7049e5b..aac182e 100644
--- a/src/libslirp.h
+++ b/src/libslirp.h
@@ -178,12 +178,6 @@
const struct sockaddr *haddr, socklen_t haddrlen,
int flags);
-int slirp_add_ipv6_hostfwd(Slirp *slirp, int is_udp,
- struct in6_addr host_addr, int host_port,
- struct in6_addr guest_addr, int guest_port);
-int slirp_remove_ipv6_hostfwd(Slirp *slirp, int is_udp,
- struct in6_addr host_addr, int host_port);
-
/* Set up port forwarding between a port in the guest network and a
* command running on the host */
int slirp_add_exec(Slirp *slirp, const char *cmdline,
diff --git a/src/libslirp.map b/src/libslirp.map
index cae6cf8..792b0a9 100644
--- a/src/libslirp.map
+++ b/src/libslirp.map
@@ -32,7 +32,5 @@
SLIRP_4.5 {
slirp_add_hostxfwd;
slirp_remove_hostxfwd;
- slirp_add_ipv6_hostfwd;
- slirp_remove_ipv6_hostfwd;
slirp_neighbor_info;
} SLIRP_4.2;
diff --git a/src/slirp.c b/src/slirp.c
index b1539af..ba41843 100644
--- a/src/slirp.c
+++ b/src/slirp.c
@@ -362,6 +362,7 @@
{ "misc", DBG_MISC },
{ "error", DBG_ERROR },
{ "tftp", DBG_TFTP },
+ { "verbose_call", DBG_VERBOSE_CALL },
};
slirp_debug = g_parse_debug_string(debug, keys, G_N_ELEMENTS(keys));
}
@@ -1179,8 +1180,10 @@
if (gaddr->sa_family == AF_INET) {
const struct sockaddr_in *gaddr_in = (const struct sockaddr_in *) gaddr;
- if (gaddrlen < sizeof(struct sockaddr_in))
+ if (gaddrlen < sizeof(struct sockaddr_in)) {
+ errno = EINVAL;
return -1;
+ }
if (!gaddr_in->sin_addr.s_addr) {
gdhcp_addr = *gaddr_in;
@@ -1191,8 +1194,10 @@
} else {
const struct sockaddr_in6 *gaddr_in6 = (const struct sockaddr_in6 *) gaddr;
- if (gaddrlen < sizeof(struct sockaddr_in6))
+ if (gaddrlen < sizeof(struct sockaddr_in6)) {
+ errno = EINVAL;
return -1;
+ }
if (in6_zero(&gaddr_in6->sin6_addr)) {
/*
@@ -1200,6 +1205,7 @@
* we can't translate "addr-any" to the guest. Instead, for now,
* reject it.
*/
+ errno = EINVAL;
return -1;
}
}
@@ -1218,58 +1224,6 @@
return 0;
}
-int slirp_remove_ipv6_hostfwd(Slirp *slirp, int is_udp,
- struct in6_addr host_addr, int host_port)
-{
- struct socket *so;
- struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
- struct sockaddr_in6 addr;
- int port = htons(host_port);
- socklen_t addr_len;
-
- for (so = head->so_next; so != head; so = so->so_next) {
- addr_len = sizeof(addr);
- if ((so->so_state & SS_HOSTFWD) &&
- getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
- addr_len == sizeof(addr) &&
- addr.sin6_family == AF_INET6 &&
- !memcmp(&addr.sin6_addr, &host_addr, sizeof(host_addr)) &&
- addr.sin6_port == port) {
- so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);
- closesocket(so->s);
- sofree(so);
- return 0;
- }
- }
-
- return -1;
-}
-
-int slirp_add_ipv6_hostfwd(Slirp *slirp, int is_udp,
- struct in6_addr host_addr, int host_port,
- struct in6_addr guest_addr, int guest_port)
-{
- /*
- * Libslirp currently only provides a stateless DHCPv6 server, thus we
- * can't translate "addr-any" to the guest. Instead, for now, reject it.
- */
- if (in6_zero(&guest_addr)) {
- return -1;
- }
-
- if (is_udp) {
- if (!udp6_listen(slirp, host_addr, htons(host_port),
- guest_addr, htons(guest_port), SS_HOSTFWD))
- return -1;
- } else {
- if (!tcp6_listen(slirp, host_addr, htons(host_port),
- guest_addr, htons(guest_port), SS_HOSTFWD))
- return -1;
- }
-
- return 0;
-}
-
/* TODO: IPv6 */
static bool check_guestfwd(Slirp *slirp, struct in_addr *guest_addr,
int guest_port)
diff --git a/src/socket.c b/src/socket.c
index 40c32a5..bf50058 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -735,6 +735,7 @@
/*
* Listen for incoming TCP connections
+ * On failure errno contains the reason.
*/
struct socket *tcpx_listen(Slirp *slirp,
const struct sockaddr *haddr, socklen_t haddrlen,
@@ -763,10 +764,7 @@
so = socreate(slirp);
/* Don't tcp_attach... we don't need so_snd nor so_rcv */
- if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
- g_free(so);
- return NULL;
- }
+ so->so_tcpcb = tcp_newtcpcb(so);
insque(so, &slirp->tcb);
/*
@@ -828,25 +826,6 @@
return tcpx_listen(slirp, (const struct sockaddr *) &hsa, sizeof(hsa), (struct sockaddr *) &lsa, sizeof(lsa), flags);
}
-struct socket *
-tcp6_listen(Slirp *slirp, struct in6_addr haddr, u_int hport,
- struct in6_addr laddr, u_int lport, int flags)
-{
- struct sockaddr_in6 hsa, lsa;
-
- memset(&hsa, 0, sizeof(hsa));
- hsa.sin6_family = AF_INET6;
- hsa.sin6_addr = haddr;
- hsa.sin6_port = hport;
-
- memset(&lsa, 0, sizeof(lsa));
- lsa.sin6_family = AF_INET6;
- lsa.sin6_addr = laddr;
- lsa.sin6_port = lport;
-
- return tcpx_listen(slirp, (const struct sockaddr *) &hsa, sizeof(hsa), (struct sockaddr*) &lsa, sizeof(lsa), flags);
-}
-
/*
* Various session state calls
* XXX Should be #define's
diff --git a/src/socket.h b/src/socket.h
index 5ea3cf6..932f391 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -166,8 +166,6 @@
void sorecvfrom(struct socket *);
int sosendto(struct socket *, struct mbuf *);
struct socket *tcp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned, int);
-struct socket *tcp6_listen(Slirp *, struct in6_addr, u_int,
- struct in6_addr, u_int, int);
struct socket *tcpx_listen(Slirp *slirp,
const struct sockaddr *haddr, socklen_t haddrlen,
const struct sockaddr *laddr, socklen_t laddrlen,
diff --git a/src/udp.c b/src/udp.c
index aa44bc3..b9694c2 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -360,11 +360,14 @@
{
struct socket *so;
socklen_t addrlen;
+ int save_errno;
so = socreate(slirp);
so->s = slirp_socket(haddr->sa_family, SOCK_DGRAM, 0);
if (so->s < 0) {
+ save_errno = errno;
sofree(so);
+ errno = save_errno;
return NULL;
}
if (haddr->sa_family == AF_INET6)
@@ -373,7 +376,9 @@
insque(so, &slirp->udb);
if (bind(so->s, haddr, haddrlen) < 0) {
+ save_errno = errno;
udp_detach(so);
+ errno = save_errno;
return NULL;
}
slirp_socket_set_fast_reuse(so->s);
@@ -409,22 +414,3 @@
return udpx_listen(slirp, (const struct sockaddr *) &hsa, sizeof(hsa), (struct sockaddr *) &lsa, sizeof(lsa), flags);
}
-
-struct socket *
-udp6_listen(Slirp *slirp, struct in6_addr haddr, u_int hport,
- struct in6_addr laddr, u_int lport, int flags)
-{
- struct sockaddr_in6 hsa, lsa;
-
- memset(&hsa, 0, sizeof(hsa));
- hsa.sin6_family = AF_INET6;
- hsa.sin6_addr = haddr;
- hsa.sin6_port = hport;
-
- memset(&lsa, 0, sizeof(lsa));
- lsa.sin6_family = AF_INET6;
- lsa.sin6_addr = laddr;
- lsa.sin6_port = lport;
-
- return udpx_listen(slirp, (const struct sockaddr *) &hsa, sizeof(hsa), (struct sockaddr *) &lsa, sizeof(lsa), flags);
-}
diff --git a/src/udp.h b/src/udp.h
index 0e92b48..47f4ed3 100644
--- a/src/udp.h
+++ b/src/udp.h
@@ -82,8 +82,6 @@
int udp_attach(struct socket *, unsigned short af);
void udp_detach(struct socket *);
struct socket *udp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned, int);
-struct socket *udp6_listen(Slirp *slirp, struct in6_addr, u_int,
- struct in6_addr, u_int, int);
struct socket *udpx_listen(Slirp *,
const struct sockaddr *haddr, socklen_t haddrlen,
const struct sockaddr *laddr, socklen_t laddrlen,
diff --git a/src/util.c b/src/util.c
index 67ef667..e6bccbe 100644
--- a/src/util.c
+++ b/src/util.c
@@ -71,6 +71,7 @@
/*
* Opens a socket with FD_CLOEXEC set
+ * On failure errno contains the reason.
*/
int slirp_socket(int domain, int type, int protocol)
{