github.com/database64128/shadowsocks-go@v1.10.2-0.20240315062903-143a773533f1/ss2022/udp_test.go (about)

     1  package ss2022
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"crypto/rand"
     7  	"errors"
     8  	"net/netip"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/database64128/shadowsocks-go/conn"
    13  )
    14  
    15  const (
    16  	name       = "test"
    17  	mtu        = 1500
    18  	packetSize = 1452
    19  	payloadLen = 1280
    20  	fwmark     = 10240
    21  )
    22  
    23  // UDP jumbograms.
    24  const (
    25  	jumboMTU        = 128 * 1024
    26  	jumboPacketSize = 128*1024 - 40 - 8 - 8
    27  	jumboPayloadLen = 127 * 1024
    28  )
    29  
    30  var (
    31  	targetAddr           = conn.AddrFromIPPort(targetAddrPort)
    32  	serverAddr           = conn.AddrFromIPPort(serverAddrPort)
    33  	targetAddrPort       = netip.AddrPortFrom(netip.IPv6Unspecified(), 53)
    34  	serverAddrPort       = netip.AddrPortFrom(netip.IPv6Unspecified(), 1080)
    35  	clientAddrPort       = netip.AddrPortFrom(netip.IPv6Unspecified(), 10800)
    36  	replayClientAddrPort = netip.AddrPortFrom(netip.IPv6Unspecified(), 10801)
    37  	replayServerAddrPort = netip.AddrPortFrom(netip.IPv6Unspecified(), 10802)
    38  )
    39  
    40  func testUDPClientServer(t *testing.T, ctx context.Context, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap, clientShouldPad, serverShouldPad PaddingPolicy, mtu, packetSize, payloadLen int) {
    41  	c := NewUDPClient(name, "ip", serverAddr, mtu, conn.DefaultUDPClientListenConfig, DefaultSlidingWindowFilterSize, clientCipherConfig, clientShouldPad)
    42  	s := NewUDPServer(DefaultSlidingWindowFilterSize, userCipherConfig, identityCipherConfig, serverShouldPad)
    43  	s.ReplaceUserLookupMap(userLookupMap)
    44  
    45  	clientInfo := c.Info()
    46  	if clientInfo.Name != name {
    47  		t.Errorf("Fixed name mismatch: in: %s, out: %s", name, clientInfo.Name)
    48  	}
    49  
    50  	_, clientSession, err := c.NewSession(ctx)
    51  	if err != nil {
    52  		t.Fatal(err)
    53  	}
    54  	defer clientSession.Close()
    55  
    56  	if clientSession.MaxPacketSize != packetSize {
    57  		t.Errorf("Fixed MTU mismatch: in: %d, out: %d", mtu, clientSession.MaxPacketSize)
    58  	}
    59  
    60  	frontHeadroom := clientInfo.PackerHeadroom.Front + 8 // Compensate for server message overhead.
    61  	rearHeadroom := clientInfo.PackerHeadroom.Rear
    62  	b := make([]byte, frontHeadroom+payloadLen+rearHeadroom)
    63  	payload := b[frontHeadroom : frontHeadroom+payloadLen]
    64  
    65  	// Fill random payload.
    66  	_, err = rand.Read(payload)
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  
    71  	// Backup payload.
    72  	payloadBackup := make([]byte, len(payload))
    73  	copy(payloadBackup, payload)
    74  
    75  	// Client packs.
    76  	dap, pkts, pktl, err := clientSession.Packer.PackInPlace(ctx, b, targetAddr, frontHeadroom, payloadLen)
    77  	if err != nil {
    78  		t.Fatal(err)
    79  	}
    80  	if dap != serverAddrPort {
    81  		t.Errorf("Expected packed client packet destAddrPort %s, got %s", serverAddrPort, dap)
    82  	}
    83  	p := b[pkts : pkts+pktl]
    84  
    85  	// Server unpacks.
    86  	csid, err := s.SessionInfo(p)
    87  	if err != nil {
    88  		t.Fatal(err)
    89  	}
    90  	serverUnpacker, _, err := s.NewUnpacker(p, csid)
    91  	if err != nil {
    92  		t.Fatal(err)
    93  	}
    94  	ta, ps, pl, err := serverUnpacker.UnpackInPlace(b, clientAddrPort, pkts, pktl)
    95  	if err != nil {
    96  		t.Error(err)
    97  	}
    98  
    99  	// Check target address.
   100  	if !ta.Equals(targetAddr) {
   101  		t.Errorf("Target address mismatch: c: %s, s: %s", targetAddr, ta)
   102  	}
   103  
   104  	// Check payload.
   105  	p = b[ps : ps+pl]
   106  	if !bytes.Equal(payloadBackup, p) {
   107  		t.Errorf("Payload mismatch: c: %v, s: %v", payloadBackup, p)
   108  	}
   109  
   110  	// Fill random again.
   111  	_, err = rand.Read(payload)
   112  	if err != nil {
   113  		t.Fatal(err)
   114  	}
   115  	copy(payloadBackup, payload)
   116  
   117  	// Server packs.
   118  	serverPacker, err := serverUnpacker.NewPacker()
   119  	if err != nil {
   120  		t.Fatal(err)
   121  	}
   122  	pkts, pktl, err = serverPacker.PackInPlace(b, targetAddrPort, frontHeadroom, payloadLen, packetSize)
   123  	if err != nil {
   124  		t.Fatal(err)
   125  	}
   126  
   127  	// Client unpacks.
   128  	tap, ps, pl, err := clientSession.Unpacker.UnpackInPlace(b, serverAddrPort, pkts, pktl)
   129  	if err != nil {
   130  		t.Error(err)
   131  	}
   132  
   133  	// Check target address.
   134  	if tap != targetAddrPort {
   135  		t.Errorf("Target address mismatch: s: %s, c: %s", targetAddrPort, tap)
   136  	}
   137  
   138  	// Check payload.
   139  	p = b[ps : ps+pl]
   140  	if !bytes.Equal(payloadBackup, p) {
   141  		t.Errorf("Payload mismatch: s: %v, c: %v", payloadBackup, p)
   142  	}
   143  }
   144  
   145  func testUDPClientServerSessionChangeAndReplay(t *testing.T, ctx context.Context, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap) {
   146  	shouldPad, err := ParsePaddingPolicy("")
   147  	if err != nil {
   148  		t.Fatal(err)
   149  	}
   150  
   151  	c := NewUDPClient(name, "ip", serverAddr, mtu, conn.DefaultUDPClientListenConfig, DefaultSlidingWindowFilterSize, clientCipherConfig, shouldPad)
   152  	s := NewUDPServer(DefaultSlidingWindowFilterSize, userCipherConfig, identityCipherConfig, shouldPad)
   153  	s.ReplaceUserLookupMap(userLookupMap)
   154  
   155  	clientInfo, clientSession, err := c.NewSession(ctx)
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  	defer clientSession.Close()
   160  
   161  	frontHeadroom := clientInfo.PackerHeadroom.Front + 8 // Compensate for server message overhead.
   162  	rearHeadroom := clientInfo.PackerHeadroom.Rear
   163  	b := make([]byte, frontHeadroom+payloadLen+rearHeadroom)
   164  
   165  	// Client packs.
   166  	dap, pkts, pktl, err := clientSession.Packer.PackInPlace(ctx, b, targetAddr, frontHeadroom, payloadLen)
   167  	if err != nil {
   168  		t.Fatal(err)
   169  	}
   170  	if dap != serverAddrPort {
   171  		t.Errorf("Expected packed client packet destAddrPort %s, got %s", serverAddrPort, dap)
   172  	}
   173  	p := b[pkts : pkts+pktl]
   174  
   175  	// Server processes client packet.
   176  	csid, err := s.SessionInfo(p)
   177  	if err != nil {
   178  		t.Fatal(err)
   179  	}
   180  	serverUnpacker, _, err := s.NewUnpacker(p, csid)
   181  	if err != nil {
   182  		t.Fatal(err)
   183  	}
   184  
   185  	// Backup processed client packet.
   186  	pb := make([]byte, pktl)
   187  	copy(pb, p)
   188  
   189  	// Server unpacks.
   190  	_, _, _, err = serverUnpacker.UnpackInPlace(b, clientAddrPort, pkts, pktl)
   191  	if err != nil {
   192  		t.Error(err)
   193  	}
   194  
   195  	// Server unpacks the same packet again.
   196  	_, _, _, err = serverUnpacker.UnpackInPlace(pb, replayClientAddrPort, 0, pktl)
   197  	var sprErr *ShadowPacketReplayError
   198  	if !errors.As(err, &sprErr) {
   199  		t.Errorf("Expected ShadowPacketReplayError, got %T", err)
   200  	}
   201  	if sprErr.srcAddr != replayClientAddrPort {
   202  		t.Errorf("Expected ShadowPacketReplayError srcAddr %s, got %s", replayClientAddrPort, sprErr.srcAddr)
   203  	}
   204  	if sprErr.sid != csid {
   205  		t.Errorf("Expected ShadowPacketReplayError sid %d, got %d", csid, sprErr.sid)
   206  	}
   207  	if sprErr.pid != 0 {
   208  		t.Errorf("Expected ShadowPacketReplayError pid 0, got %d", sprErr.pid)
   209  	}
   210  
   211  	// Server packs.
   212  	serverPacker, err := serverUnpacker.NewPacker()
   213  	if err != nil {
   214  		t.Fatal(err)
   215  	}
   216  	pkts, pktl, err = serverPacker.PackInPlace(b, targetAddrPort, frontHeadroom, payloadLen, packetSize)
   217  	if err != nil {
   218  		t.Fatal(err)
   219  	}
   220  	ssid0 := serverPacker.(*ShadowPacketServerPacker).ssid
   221  
   222  	// Backup packed server packet.
   223  	pb0 := make([]byte, pktl)
   224  	copy(pb0, b[pkts:pkts+pktl])
   225  
   226  	// Client unpacks.
   227  	_, _, _, err = clientSession.Unpacker.UnpackInPlace(b, serverAddrPort, pkts, pktl)
   228  	if err != nil {
   229  		t.Error(err)
   230  	}
   231  
   232  	// Refresh server session.
   233  	serverPacker, err = serverUnpacker.NewPacker()
   234  	if err != nil {
   235  		t.Fatal(err)
   236  	}
   237  	pkts, pktl, err = serverPacker.PackInPlace(b, targetAddrPort, frontHeadroom, payloadLen, packetSize)
   238  	if err != nil {
   239  		t.Fatal(err)
   240  	}
   241  	ssid1 := serverPacker.(*ShadowPacketServerPacker).ssid
   242  
   243  	// Backup packed server packet.
   244  	pb1 := make([]byte, pktl)
   245  	copy(pb1, b[pkts:pkts+pktl])
   246  
   247  	// Trick client into accepting refreshed server session.
   248  	spcu := clientSession.Unpacker.(*ShadowPacketClientUnpacker)
   249  	spcu.oldServerSessionLastSeenTime = spcu.oldServerSessionLastSeenTime.Add(-time.Minute - time.Nanosecond)
   250  
   251  	// Client unpacks.
   252  	_, _, _, err = clientSession.Unpacker.UnpackInPlace(b, serverAddrPort, pkts, pktl)
   253  	if err != nil {
   254  		t.Error(err)
   255  	}
   256  
   257  	// Refresh server session again. No tricks this time!
   258  	serverPacker, err = serverUnpacker.NewPacker()
   259  	if err != nil {
   260  		t.Fatal(err)
   261  	}
   262  	pkts, pktl, err = serverPacker.PackInPlace(b, targetAddrPort, frontHeadroom, payloadLen, packetSize)
   263  	if err != nil {
   264  		t.Fatal(err)
   265  	}
   266  
   267  	// Client unpacks.
   268  	_, _, _, err = clientSession.Unpacker.UnpackInPlace(b, serverAddrPort, pkts, pktl)
   269  	if err != ErrTooManyServerSessions {
   270  		t.Errorf("Expected ErrTooManyServerSessions, got %v", err)
   271  	}
   272  
   273  	// Client unpacks pb0.
   274  	_, _, _, err = clientSession.Unpacker.UnpackInPlace(pb0, replayServerAddrPort, 0, len(pb0))
   275  	if !errors.As(err, &sprErr) {
   276  		t.Errorf("Expected ShadowPacketReplayError, got %T", err)
   277  	}
   278  	if sprErr.srcAddr != replayServerAddrPort {
   279  		t.Errorf("Expected ShadowPacketReplayError srcAddr %s, got %s", replayServerAddrPort, sprErr.srcAddr)
   280  	}
   281  	if sprErr.sid != ssid0 {
   282  		t.Errorf("Expected ShadowPacketReplayError sid %d, got %d", ssid0, sprErr.sid)
   283  	}
   284  	if sprErr.pid != 0 {
   285  		t.Errorf("Expected ShadowPacketReplayError pid 0, got %d", sprErr.pid)
   286  	}
   287  
   288  	// Client unpacks pb1.
   289  	_, _, _, err = clientSession.Unpacker.UnpackInPlace(pb1, replayServerAddrPort, 0, len(pb1))
   290  	if !errors.As(err, &sprErr) {
   291  		t.Errorf("Expected ShadowPacketReplayError, got %T", err)
   292  	}
   293  	if sprErr.srcAddr != replayServerAddrPort {
   294  		t.Errorf("Expected ShadowPacketReplayError srcAddr %s, got %s", replayServerAddrPort, sprErr.srcAddr)
   295  	}
   296  	if sprErr.sid != ssid1 {
   297  		t.Errorf("Expected ShadowPacketReplayError sid %d, got %d", ssid1, sprErr.sid)
   298  	}
   299  	if sprErr.pid != 0 {
   300  		t.Errorf("Expected ShadowPacketReplayError pid 0, got %d", sprErr.pid)
   301  	}
   302  }
   303  
   304  func testUDPClientServerPaddingPolicy(t *testing.T, ctx context.Context, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap, mtu, packetSize, payloadLen int) {
   305  	t.Run("NoPadding", func(t *testing.T) {
   306  		testUDPClientServer(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, NoPadding, NoPadding, mtu, packetSize, payloadLen)
   307  	})
   308  	t.Run("PadPlainDNS", func(t *testing.T) {
   309  		testUDPClientServer(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, PadPlainDNS, PadPlainDNS, mtu, packetSize, payloadLen)
   310  	})
   311  	t.Run("PadAll", func(t *testing.T) {
   312  		testUDPClientServer(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, PadAll, PadAll, mtu, packetSize, payloadLen)
   313  	})
   314  }
   315  
   316  func testUDPClientServerWithCipher(t *testing.T, ctx context.Context, clientCipherConfig *ClientCipherConfig, userCipherConfig UserCipherConfig, identityCipherConfig ServerIdentityCipherConfig, userLookupMap UserLookupMap) {
   317  	t.Run("Typical", func(t *testing.T) {
   318  		testUDPClientServerPaddingPolicy(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, mtu, packetSize, payloadLen)
   319  	})
   320  	t.Run("EmptyPayload", func(t *testing.T) {
   321  		testUDPClientServerPaddingPolicy(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, mtu, packetSize, 0)
   322  	})
   323  	t.Run("Jumbogram", func(t *testing.T) {
   324  		testUDPClientServerPaddingPolicy(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap, jumboMTU, jumboPacketSize, jumboPayloadLen)
   325  	})
   326  	t.Run("SessionChangeAndReplay", func(t *testing.T) {
   327  		testUDPClientServerSessionChangeAndReplay(t, ctx, clientCipherConfig, userCipherConfig, identityCipherConfig, userLookupMap)
   328  	})
   329  }
   330  
   331  func TestUDPClientServerNoEIH(t *testing.T) {
   332  	ctx := context.Background()
   333  	clientCipherConfig128, userCipherConfig128, err := newRandomCipherConfigTupleNoEIH("2022-blake3-aes-128-gcm", true)
   334  	if err != nil {
   335  		t.Fatal(err)
   336  	}
   337  	clientCipherConfig256, userCipherConfig256, err := newRandomCipherConfigTupleNoEIH("2022-blake3-aes-256-gcm", true)
   338  	if err != nil {
   339  		t.Fatal(err)
   340  	}
   341  
   342  	t.Run("128", func(t *testing.T) {
   343  		testUDPClientServerWithCipher(t, ctx, clientCipherConfig128, userCipherConfig128, ServerIdentityCipherConfig{}, nil)
   344  	})
   345  	t.Run("256", func(t *testing.T) {
   346  		testUDPClientServerWithCipher(t, ctx, clientCipherConfig256, userCipherConfig256, ServerIdentityCipherConfig{}, nil)
   347  	})
   348  }
   349  
   350  func TestUDPClientServerWithEIH(t *testing.T) {
   351  	ctx := context.Background()
   352  	clientCipherConfig128, identityCipherConfig128, userLookupMap128, err := newRandomCipherConfigTupleWithEIH("2022-blake3-aes-128-gcm", true)
   353  	if err != nil {
   354  		t.Fatal(err)
   355  	}
   356  	clientCipherConfig256, identityCipherConfig256, userLookupMap256, err := newRandomCipherConfigTupleWithEIH("2022-blake3-aes-256-gcm", true)
   357  	if err != nil {
   358  		t.Fatal(err)
   359  	}
   360  
   361  	t.Run("128", func(t *testing.T) {
   362  		testUDPClientServerWithCipher(t, ctx, clientCipherConfig128, UserCipherConfig{}, identityCipherConfig128, userLookupMap128)
   363  	})
   364  	t.Run("256", func(t *testing.T) {
   365  		testUDPClientServerWithCipher(t, ctx, clientCipherConfig256, UserCipherConfig{}, identityCipherConfig256, userLookupMap256)
   366  	})
   367  }