TUN-5659: Proxy UDP with zero-byte payload
This commit is contained in:
parent
10fc450ae5
commit
c196679bc7
|
@ -106,6 +106,7 @@ func (s *Session) waitForCloseCondition(ctx context.Context, closeAfterIdle time
|
||||||
func (s *Session) dstToTransport(buffer []byte) error {
|
func (s *Session) dstToTransport(buffer []byte) error {
|
||||||
n, err := s.dstConn.Read(buffer)
|
n, err := s.dstConn.Read(buffer)
|
||||||
s.markActive()
|
s.markActive()
|
||||||
|
// https://pkg.go.dev/io#Reader suggests caller should always process n > 0 bytes
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
if n <= int(s.transport.MTU()) {
|
if n <= int(s.transport.MTU()) {
|
||||||
err = s.transport.SendTo(s.ID, buffer[:n])
|
err = s.transport.SendTo(s.ID, buffer[:n])
|
||||||
|
@ -118,6 +119,10 @@ func (s *Session) dstToTransport(buffer []byte) error {
|
||||||
Msg("dropped packet exceeding MTU")
|
Msg("dropped packet exceeding MTU")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Some UDP application might send 0-size payload.
|
||||||
|
if err == nil && n == 0 {
|
||||||
|
err = s.transport.SendTo(s.ID, []byte{})
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,3 +195,40 @@ func TestMarkActiveNotBlocking(t *testing.T) {
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestZeroBytePayload(t *testing.T) {
|
||||||
|
sessionID := uuid.New()
|
||||||
|
cfdConn, originConn := net.Pipe()
|
||||||
|
transport := &mockQUICTransport{
|
||||||
|
reqChan: newDatagramChannel(1),
|
||||||
|
respChan: newDatagramChannel(1),
|
||||||
|
}
|
||||||
|
log := zerolog.Nop()
|
||||||
|
session := newSession(sessionID, transport, cfdConn, &log)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
errGroup, ctx := errgroup.WithContext(ctx)
|
||||||
|
errGroup.Go(func() error {
|
||||||
|
// Read from underlying conn and send to transport
|
||||||
|
closedByRemote, err := session.Serve(ctx, time.Minute*2)
|
||||||
|
require.Equal(t, context.Canceled, err)
|
||||||
|
require.False(t, closedByRemote)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
errGroup.Go(func() error {
|
||||||
|
// Write to underlying connection
|
||||||
|
n, err := originConn.Write([]byte{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 0, n)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
receivedSessionID, payload, err := transport.respChan.Receive(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, payload, 0)
|
||||||
|
require.Equal(t, sessionID, receivedSessionID)
|
||||||
|
|
||||||
|
cancel()
|
||||||
|
require.NoError(t, errGroup.Wait())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue