udp: Don't use separate sockets to listen for spliced packets
Currently, when ports are forwarded inbound in pasta mode, we open two sockets for incoming traffic: one listens on the public IP address and will forward packets to the tuntap interface. The other listens on localhost and forwards via "splicing" (resending directly via sockets in the ns). Now that we've improved the logic about whether we "splice" any individual packet, we don't need this. Instead we can have a single socket bound to 0.0.0.0 or ::, marked as able to splice and udp_sock_handler() will deal with each packet as appropriate. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
8d503e825f
commit
b93d025d50
1 changed files with 13 additions and 40 deletions
53
udp.c
53
udp.c
|
@ -1124,7 +1124,6 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
|
||||||
const void *addr, const char *ifname, in_port_t port)
|
const void *addr, const char *ifname, in_port_t port)
|
||||||
{
|
{
|
||||||
union udp_epoll_ref uref = { .u32 = 0 };
|
union udp_epoll_ref uref = { .u32 = 0 };
|
||||||
const void *bind_addr;
|
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
if (ns) {
|
if (ns) {
|
||||||
|
@ -1136,67 +1135,41 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((af == AF_INET || af == AF_UNSPEC) && c->ifi4) {
|
if ((af == AF_INET || af == AF_UNSPEC) && c->ifi4) {
|
||||||
if (!addr && c->mode == MODE_PASTA)
|
|
||||||
bind_addr = &c->ip4.addr;
|
|
||||||
else
|
|
||||||
bind_addr = addr;
|
|
||||||
|
|
||||||
uref.udp.v6 = 0;
|
uref.udp.v6 = 0;
|
||||||
|
uref.udp.splice = (c->mode == MODE_PASTA);
|
||||||
|
uref.udp.orig = true;
|
||||||
|
|
||||||
if (!ns) {
|
if (!ns) {
|
||||||
uref.udp.splice = 0;
|
s = sock_l4(c, AF_INET, IPPROTO_UDP, addr, ifname,
|
||||||
s = sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, ifname,
|
|
||||||
port, uref.u32);
|
port, uref.u32);
|
||||||
|
|
||||||
udp_tap_map[V4][uref.udp.port].sock = s;
|
udp_tap_map[V4][uref.udp.port].sock = s;
|
||||||
|
udp_splice_init[V4][port].sock = s;
|
||||||
if (c->mode == MODE_PASTA) {
|
|
||||||
bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) };
|
|
||||||
uref.udp.splice = uref.udp.orig = true;
|
|
||||||
|
|
||||||
s = sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr,
|
|
||||||
ifname, port, uref.u32);
|
|
||||||
udp_splice_init[V4][port].sock = s;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
uref.udp.splice = uref.udp.orig = uref.udp.ns = true;
|
struct in_addr loopback = { htonl(INADDR_LOOPBACK) };
|
||||||
|
uref.udp.ns = true;
|
||||||
|
|
||||||
bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) };
|
s = sock_l4(c, AF_INET, IPPROTO_UDP, &loopback,
|
||||||
|
|
||||||
s = sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr,
|
|
||||||
ifname, port, uref.u32);
|
ifname, port, uref.u32);
|
||||||
udp_splice_ns[V4][port].sock = s;
|
udp_splice_ns[V4][port].sock = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) {
|
if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) {
|
||||||
if (!addr && c->mode == MODE_PASTA)
|
|
||||||
bind_addr = &c->ip6.addr;
|
|
||||||
else
|
|
||||||
bind_addr = addr;
|
|
||||||
|
|
||||||
uref.udp.v6 = 1;
|
uref.udp.v6 = 1;
|
||||||
|
uref.udp.splice = (c->mode == MODE_PASTA);
|
||||||
|
uref.udp.orig = true;
|
||||||
|
|
||||||
if (!ns) {
|
if (!ns) {
|
||||||
uref.udp.splice = 0;
|
s = sock_l4(c, AF_INET6, IPPROTO_UDP, addr, ifname,
|
||||||
s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, ifname,
|
|
||||||
port, uref.u32);
|
port, uref.u32);
|
||||||
|
|
||||||
udp_tap_map[V6][uref.udp.port].sock = s;
|
udp_tap_map[V6][uref.udp.port].sock = s;
|
||||||
|
udp_splice_init[V6][port].sock = s;
|
||||||
if (c->mode == MODE_PASTA) {
|
|
||||||
bind_addr = &in6addr_loopback;
|
|
||||||
uref.udp.splice = uref.udp.orig = true;
|
|
||||||
|
|
||||||
s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr,
|
|
||||||
ifname, port, uref.u32);
|
|
||||||
udp_splice_init[V6][port].sock = s;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
bind_addr = &in6addr_loopback;
|
uref.udp.ns = true;
|
||||||
uref.udp.splice = uref.udp.orig = uref.udp.ns = true;
|
|
||||||
|
|
||||||
s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr,
|
s = sock_l4(c, AF_INET6, IPPROTO_UDP, &in6addr_loopback,
|
||||||
ifname, port, uref.u32);
|
ifname, port, uref.u32);
|
||||||
udp_splice_ns[V6][port].sock = s;
|
udp_splice_ns[V6][port].sock = s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue