Skip to content

Commit f5dc9ab

Browse files
OkamiWgvisor-bot
authored andcommitted
Allow not handled packets for UDP Forwarder
For TCP forwarder, we can reset the connection with r.Complete(true). For UDP forwarder, there was no way to reset the connection. gVisor already sends ICMP port unreachable for unhandled packets, but udp.Forwarder.HandlePacket always returns true. So we change the handler's function signature to return a bool type value, indicating whether the packet was handled or not. Thus allowing us to send ICMP port unreachable for failed UDP connections. FUTURE_COPYBARA_INTEGRATE_REVIEW=#11850 from OkamiW:udp-forwarder-not-handled-packets 496c218 PiperOrigin-RevId: 777960633
1 parent bb08e96 commit f5dc9ab

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

pkg/tcpip/adapters/gonet/gonet_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ func TestUDPForwarder(t *testing.T) {
480480
}
481481

482482
done := make(chan struct{})
483-
fwd := udp.NewForwarder(s, func(r *udp.ForwarderRequest) {
483+
fwd := udp.NewForwarder(s, func(r *udp.ForwarderRequest) bool {
484484
defer close(done)
485485

486486
var wq waiter.Queue
@@ -496,11 +496,15 @@ func TestUDPForwarder(t *testing.T) {
496496
n, e := c.Read(buf)
497497
if e != nil {
498498
t.Errorf("c.Read() = %v", e)
499+
return true
499500
}
500501

501502
if _, e := c.Write(buf[:n]); e != nil {
502503
t.Errorf("c.Write() = %v", e)
504+
return true
503505
}
506+
507+
return true
504508
})
505509
s.SetTransportProtocolHandler(udp.ProtocolNumber, fwd.HandlePacket)
506510

pkg/tcpip/transport/udp/forwarder.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,24 @@ import (
2020
"gvisor.dev/gvisor/pkg/waiter"
2121
)
2222

23+
// ForwarderHandler handles incoming requests. Returning true marks the
24+
// request as handled, returning false marks the request as unhandled.
25+
// Stack may send an ICMP port unreachable message for unhandled requests.
26+
type ForwarderHandler func(*ForwarderRequest) (handled bool)
27+
2328
// Forwarder is a session request forwarder, which allows clients to decide
2429
// what to do with a session request, for example: ignore it, or process it.
2530
//
2631
// The canonical way of using it is to pass the Forwarder.HandlePacket function
2732
// to stack.SetTransportProtocolHandler.
2833
type Forwarder struct {
29-
handler func(*ForwarderRequest)
34+
handler ForwarderHandler
3035

3136
stack *stack.Stack
3237
}
3338

3439
// NewForwarder allocates and initializes a new forwarder.
35-
func NewForwarder(s *stack.Stack, handler func(*ForwarderRequest)) *Forwarder {
40+
func NewForwarder(s *stack.Stack, handler ForwarderHandler) *Forwarder {
3641
return &Forwarder{
3742
stack: s,
3843
handler: handler,
@@ -44,13 +49,11 @@ func NewForwarder(s *stack.Stack, handler func(*ForwarderRequest)) *Forwarder {
4449
// This function is expected to be passed as an argument to the
4550
// stack.SetTransportProtocolHandler function.
4651
func (f *Forwarder) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
47-
f.handler(&ForwarderRequest{
52+
return f.handler(&ForwarderRequest{
4853
stack: f.stack,
4954
id: id,
5055
pkt: pkt.Clone(),
5156
})
52-
53-
return true
5457
}
5558

5659
// ForwarderRequest represents a session request received by the forwarder and

0 commit comments

Comments
 (0)