udp: Update UDP "connection" timestamps in both directions
A UDP pseudo-connection between port A in the init namespace and port B in the pasta guest namespace involves two sockets: udp_splice_init[v6][B] and udp_splice_ns[v6][A]. The socket which originated this "connection" will be permanent but the other one will be closed on a timeout. When we get a packet from the originating socket, we update the timeout on the other socket, but we don't do the same when we get a reply packet from the other socket. However any activity on the "connection" probably indicates that it's still in use. Without this we could incorrectly time out a "connection" if it's using a protocol which involves a single initiating packet, but which then gets continuing replies from the target. Correct this by updating the timeout on both sockets for a packet in either direction. This also updates the timestamps for the permanent originating sockets which is unnecessary, but harmless. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
7610034fef
commit
71d2595a8f
1 changed files with 17 additions and 2 deletions
19
udp.c
19
udp.c
|
@ -55,12 +55,15 @@
|
||||||
* - bind in namespace to 127.0.0.1:5000
|
* - bind in namespace to 127.0.0.1:5000
|
||||||
* - add to epoll with reference: index = 5000, splice = 1, orig = 0,
|
* - add to epoll with reference: index = 5000, splice = 1, orig = 0,
|
||||||
* ns = 1
|
* ns = 1
|
||||||
* - update udp_splice_ns[V4][5000].ts with current time
|
* - update udp_splice_init[V4][80].ts and udp_splice_ns[V4][5000].ts with
|
||||||
|
* current time
|
||||||
*
|
*
|
||||||
* - reverse direction: 127.0.0.1:80 -> 127.0.0.1:5000 in namespace socket s,
|
* - reverse direction: 127.0.0.1:80 -> 127.0.0.1:5000 in namespace socket s,
|
||||||
* having epoll reference: index = 5000, splice = 1, orig = 0, ns = 1
|
* having epoll reference: index = 5000, splice = 1, orig = 0, ns = 1
|
||||||
* - if udp_splice_init[V4][80].sock:
|
* - if udp_splice_init[V4][80].sock:
|
||||||
* - send to udp_splice_init[V4][80].sock, with destination port 5000
|
* - send to udp_splice_init[V4][80].sock, with destination port 5000
|
||||||
|
* - update udp_splice_init[V4][80].ts and udp_splice_ns[V4][5000].ts with
|
||||||
|
* current time
|
||||||
* - otherwise, discard
|
* - otherwise, discard
|
||||||
*
|
*
|
||||||
* - from namespace to init:
|
* - from namespace to init:
|
||||||
|
@ -75,12 +78,15 @@
|
||||||
* - bind in init to 127.0.0.1:2000
|
* - bind in init to 127.0.0.1:2000
|
||||||
* - add to epoll with reference: index = 2000, splice = 1, orig = 0,
|
* - add to epoll with reference: index = 2000, splice = 1, orig = 0,
|
||||||
* ns = 0
|
* ns = 0
|
||||||
* - update udp_splice_init[V4][2000].ts with current time
|
* - update udp_splice_ns[V4][22].ts and udp_splice_init[V4][2000].ts with
|
||||||
|
* current time
|
||||||
*
|
*
|
||||||
* - reverse direction: 127.0.0.1:22 -> 127.0.0.1:2000 in init from socket s,
|
* - reverse direction: 127.0.0.1:22 -> 127.0.0.1:2000 in init from socket s,
|
||||||
* having epoll reference: index = 2000, splice = 1, orig = 0, ns = 0
|
* having epoll reference: index = 2000, splice = 1, orig = 0, ns = 0
|
||||||
* - if udp_splice_ns[V4][22].sock:
|
* - if udp_splice_ns[V4][22].sock:
|
||||||
* - send to udp_splice_ns[V4][22].sock, with destination port 2000
|
* - send to udp_splice_ns[V4][22].sock, with destination port 2000
|
||||||
|
* - update udp_splice_ns[V4][22].ts and udp_splice_init[V4][2000].ts with
|
||||||
|
* current time
|
||||||
* - otherwise, discard
|
* - otherwise, discard
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -539,12 +545,16 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
udp_splice_init[v6][dst].ts = now->tv_sec;
|
||||||
udp_splice_ns[v6][src].ts = now->tv_sec;
|
udp_splice_ns[v6][src].ts = now->tv_sec;
|
||||||
} else if (!ref.r.p.udp.udp.orig && ref.r.p.udp.udp.ns) {
|
} else if (!ref.r.p.udp.udp.orig && ref.r.p.udp.udp.ns) {
|
||||||
src += c->udp.fwd_in.rdelta[src];
|
src += c->udp.fwd_in.rdelta[src];
|
||||||
|
|
||||||
if (!(s = udp_splice_init[v6][src].sock))
|
if (!(s = udp_splice_init[v6][src].sock))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
udp_splice_ns[v6][dst].ts = now->tv_sec;
|
||||||
|
udp_splice_init[v6][src].ts = now->tv_sec;
|
||||||
} else if (ref.r.p.udp.udp.orig && ref.r.p.udp.udp.ns) {
|
} else if (ref.r.p.udp.udp.orig && ref.r.p.udp.udp.ns) {
|
||||||
src += c->udp.fwd_in.rdelta[src];
|
src += c->udp.fwd_in.rdelta[src];
|
||||||
|
|
||||||
|
@ -553,12 +563,17 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref,
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
udp_splice_ns[v6][dst].ts = now->tv_sec;
|
||||||
udp_splice_init[v6][src].ts = now->tv_sec;
|
udp_splice_init[v6][src].ts = now->tv_sec;
|
||||||
} else if (!ref.r.p.udp.udp.orig && !ref.r.p.udp.udp.ns) {
|
} else if (!ref.r.p.udp.udp.orig && !ref.r.p.udp.udp.ns) {
|
||||||
src += c->udp.fwd_out.rdelta[src];
|
src += c->udp.fwd_out.rdelta[src];
|
||||||
|
|
||||||
if (!(s = udp_splice_ns[v6][src].sock))
|
if (!(s = udp_splice_ns[v6][src].sock))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
udp_splice_init[v6][dst].ts = now->tv_sec;
|
||||||
|
udp_splice_ns[v6][src].ts = now->tv_sec;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue