mirror of
https://github.com/tailscale/tailscale.git
synced 2025-09-21 21:51:21 +02:00
wgengine/magicsock: send a valid payload in TestNetworkDownSendErrors
This test ostensibly checks whether we record an error metric if a packet is dropped because the network is down, but the network connectivity is irrelevant -- the send error is actually because the arguments to Send() are invalid: RebindingUDPConn.WriteWireGuardBatchTo: [unexpected] offset (0) != Geneve header length (8) This patch changes the test so we try to send a valid packet, and we verify this by sending it once before taking the network down. The new error is: magicsock: network down which is what we're trying to test. We then test sending an invalid payload as a separate test case. Updates tailscale/corp#22075 Signed-off-by: Alex Chan <alexc@tailscale.com>
This commit is contained in:
parent
998a667cd5
commit
5c24f0ed80
@ -3131,34 +3131,89 @@ func TestMaybeRebindOnError(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNetworkDownSendErrors(t *testing.T) {
|
func newTestConnAndRegistry(t *testing.T) (*Conn, *usermetric.Registry, func()) {
|
||||||
|
t.Helper()
|
||||||
bus := eventbus.New()
|
bus := eventbus.New()
|
||||||
defer bus.Close()
|
|
||||||
|
|
||||||
netMon := must.Get(netmon.New(bus, t.Logf))
|
netMon := must.Get(netmon.New(bus, t.Logf))
|
||||||
defer netMon.Close()
|
|
||||||
|
|
||||||
reg := new(usermetric.Registry)
|
reg := new(usermetric.Registry)
|
||||||
|
|
||||||
conn := must.Get(NewConn(Options{
|
conn := must.Get(NewConn(Options{
|
||||||
DisablePortMapper: true,
|
DisablePortMapper: true,
|
||||||
Logf: t.Logf,
|
Logf: t.Logf,
|
||||||
NetMon: netMon,
|
NetMon: netMon,
|
||||||
Metrics: reg,
|
|
||||||
EventBus: bus,
|
EventBus: bus,
|
||||||
|
Metrics: reg,
|
||||||
}))
|
}))
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
conn.SetNetworkUp(false)
|
return conn, reg, func() {
|
||||||
if err := conn.Send([][]byte{{00}}, &lazyEndpoint{}, 0); err == nil {
|
bus.Close()
|
||||||
t.Error("expected error, got nil")
|
netMon.Close()
|
||||||
}
|
conn.Close()
|
||||||
resp := httptest.NewRecorder()
|
|
||||||
reg.Handler(resp, new(http.Request))
|
|
||||||
if !strings.Contains(resp.Body.String(), `tailscaled_outbound_dropped_packets_total{reason="error"} 1`) {
|
|
||||||
t.Errorf("expected NetworkDown to increment packet dropped metric; got %q", resp.Body.String())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNetworkSendErrors(t *testing.T) {
|
||||||
|
t.Run("network-down", func(t *testing.T) {
|
||||||
|
// TODO(alexc): This test case fails on Windows because it never
|
||||||
|
// successfully sends the first packet:
|
||||||
|
//
|
||||||
|
// expected successful Send, got err: "write udp4 0.0.0.0:57516->127.0.0.1:9999:
|
||||||
|
// wsasendto: The requested address is not valid in its context."
|
||||||
|
//
|
||||||
|
// It would be nice to run this test on Windows, but I was already
|
||||||
|
// on a side quest and it was unclear if this test has ever worked
|
||||||
|
// correctly on Windows.
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
t.Skipf("skipping on %s", runtime.GOOS)
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, reg, close := newTestConnAndRegistry(t)
|
||||||
|
defer close()
|
||||||
|
|
||||||
|
buffs := [][]byte{{00, 00, 00, 00, 00, 00, 00, 00}}
|
||||||
|
ep := &lazyEndpoint{
|
||||||
|
src: epAddr{ap: netip.MustParseAddrPort("127.0.0.1:9999")},
|
||||||
|
}
|
||||||
|
offset := 8
|
||||||
|
|
||||||
|
// Check this is a valid payload to send when the network is up
|
||||||
|
conn.SetNetworkUp(true)
|
||||||
|
if err := conn.Send(buffs, ep, offset); err != nil {
|
||||||
|
t.Errorf("expected successful Send, got err: %q", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we know the payload would be sent if the network is up,
|
||||||
|
// send it again when the network is down
|
||||||
|
conn.SetNetworkUp(false)
|
||||||
|
err := conn.Send(buffs, ep, offset)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected error, got nil")
|
||||||
|
}
|
||||||
|
resp := httptest.NewRecorder()
|
||||||
|
reg.Handler(resp, new(http.Request))
|
||||||
|
if !strings.Contains(resp.Body.String(), `tailscaled_outbound_dropped_packets_total{reason="error"} 1`) {
|
||||||
|
t.Errorf("expected NetworkDown to increment packet dropped metric; got %q", resp.Body.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("invalid-payload", func(t *testing.T) {
|
||||||
|
conn, reg, close := newTestConnAndRegistry(t)
|
||||||
|
defer close()
|
||||||
|
|
||||||
|
conn.SetNetworkUp(false)
|
||||||
|
err := conn.Send([][]byte{{00}}, &lazyEndpoint{}, 0)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected error, got nil")
|
||||||
|
}
|
||||||
|
resp := httptest.NewRecorder()
|
||||||
|
reg.Handler(resp, new(http.Request))
|
||||||
|
if !strings.Contains(resp.Body.String(), `tailscaled_outbound_dropped_packets_total{reason="error"} 1`) {
|
||||||
|
t.Errorf("expected invalid payload to increment packet dropped metric; got %q", resp.Body.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func Test_packetLooksLike(t *testing.T) {
|
func Test_packetLooksLike(t *testing.T) {
|
||||||
discoPub := key.DiscoPublicFromRaw32(mem.B([]byte{1: 1, 30: 30, 31: 31}))
|
discoPub := key.DiscoPublicFromRaw32(mem.B([]byte{1: 1, 30: 30, 31: 31}))
|
||||||
nakedDisco := make([]byte, 0, 512)
|
nakedDisco := make([]byte, 0, 512)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user