aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2020-03-16 19:47:26 +0100
committerMarc-André Lureau <marcandre.lureau@redhat.com>2020-03-16 23:45:28 +0100
commitf9c56fed8ef0bae4ac81a7335c5d262e1e1f4c21 (patch)
tree37e0e93129823411a1e7e90d07055a695e469442
parent8a18a76855f1d67fd6d4cdff30b669d235249a7a (diff)
downloadslirp-f9c56fed8ef0bae4ac81a7335c5d262e1e1f4c21.zip
slirp-f9c56fed8ef0bae4ac81a7335c5d262e1e1f4c21.tar.gz
slirp-f9c56fed8ef0bae4ac81a7335c5d262e1e1f4c21.tar.bz2
socket: do not fallback on loopback addr for addresses in our mask/prefix
Currently, any address within the subnetwork will fallback on loopback. It seems it has always been like that, but it seems wrong, and I don't see a good reason to keep it this way. Fortunately, lack of ARP reply made this unusable in practice, so we shouldn't break much existing users. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
-rw-r--r--src/socket.c28
1 files changed, 12 insertions, 16 deletions
diff --git a/src/socket.c b/src/socket.c
index cb1684a..6ad9c30 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -821,19 +821,17 @@ void sofwdrain(struct socket *so)
static bool sotranslate_out4(Slirp *s, struct socket *so, struct sockaddr_in *sin)
{
- if ((so->so_faddr.s_addr & s->vnetwork_mask.s_addr) ==
- s->vnetwork_addr.s_addr) {
- if (so->so_faddr.s_addr == s->vnameserver_addr.s_addr) {
- return get_dns_addr(&sin->sin_addr) >= 0;
- }
+ if (so->so_faddr.s_addr == s->vnameserver_addr.s_addr) {
+ return get_dns_addr(&sin->sin_addr) >= 0;
+ }
+
+ if (so->so_faddr.s_addr == s->vhost_addr.s_addr ||
+ so->so_faddr.s_addr == 0xffffffff) {
if (s->disable_host_loopback) {
return false;
}
sin->sin_addr = loopback_addr;
- } else if (!s->disable_host_loopback && so->so_faddr.s_addr == 0xffffffff) {
- /* Receive broadcast as well */
- sin->sin_addr = loopback_addr;
}
return true;
@@ -841,19 +839,17 @@ static bool sotranslate_out4(Slirp *s, struct socket *so, struct sockaddr_in *si
static bool sotranslate_out6(Slirp *s, struct socket *so, struct sockaddr_in6 *sin)
{
- if (in6_equal_net(&so->so_faddr6, &s->vprefix_addr6, s->vprefix_len)) {
- if (in6_equal(&so->so_faddr6, &s->vnameserver_addr6)) {
- return get_dns6_addr(&sin->sin6_addr, &sin->sin6_scope_id) >= 0;
- }
+ if (in6_equal(&so->so_faddr6, &s->vnameserver_addr6)) {
+ return get_dns6_addr(&sin->sin6_addr, &sin->sin6_scope_id) >= 0;
+ }
+
+ if (in6_equal_net(&so->so_faddr6, &s->vprefix_addr6, s->vprefix_len) ||
+ in6_equal(&so->so_faddr6, &(struct in6_addr)ALLNODES_MULTICAST)) {
if (s->disable_host_loopback) {
return false;
}
sin->sin6_addr = in6addr_loopback;
- } else if (!s->disable_host_loopback &&
- in6_equal(&so->so_faddr6,
- &(struct in6_addr)ALLNODES_MULTICAST)) {
- sin->sin6_addr = in6addr_loopback;
}
return true;