mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-31 00:01:40 +01:00 
			
		
		
		
	This adds a PCP test to the IGD test server, by hardcoding in a few observed packets from Denton's box. Signed-off-by: julianknodt <julianknodt@gmail.com>
		
			
				
	
	
		
			63 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			63 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| package portmapper
 | |
| 
 | |
| import (
 | |
| 	"encoding/binary"
 | |
| 	"testing"
 | |
| 
 | |
| 	"inet.af/netaddr"
 | |
| )
 | |
| 
 | |
| var examplePCPMapResponse = []byte{2, 129, 0, 0, 0, 0, 28, 32, 0, 2, 155, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 112, 9, 24, 241, 208, 251, 45, 157, 76, 10, 188, 17, 0, 0, 0, 4, 210, 4, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 135, 180, 175, 246}
 | |
| 
 | |
| func TestParsePCPMapResponse(t *testing.T) {
 | |
| 	mapping, err := parsePCPMapResponse(examplePCPMapResponse)
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("failed to parse PCP Map Response: %v", err)
 | |
| 	}
 | |
| 	if mapping == nil {
 | |
| 		t.Fatalf("got nil mapping when expected non-nil")
 | |
| 	}
 | |
| 	expectedAddr := netaddr.MustParseIPPort("135.180.175.246:1234")
 | |
| 	if mapping.external != expectedAddr {
 | |
| 		t.Errorf("mismatched external address, got: %v, want: %v", mapping.external, expectedAddr)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	serverResponseBit = 1 << 7
 | |
| 	fakeLifetimeSec   = 1<<31 - 1
 | |
| )
 | |
| 
 | |
| func buildPCPDiscoResponse(req []byte) []byte {
 | |
| 	out := make([]byte, 24)
 | |
| 	out[0] = pcpVersion
 | |
| 	out[1] = req[1] | serverResponseBit
 | |
| 	out[3] = 0
 | |
| 	// Do not put an epoch time in 8:12, when we start using it, tests that use it should fail.
 | |
| 	return out
 | |
| }
 | |
| 
 | |
| func buildPCPMapResponse(req []byte) []byte {
 | |
| 	out := make([]byte, 24+36)
 | |
| 	out[0] = pcpVersion
 | |
| 	out[1] = req[1] | serverResponseBit
 | |
| 	out[3] = 0
 | |
| 	binary.BigEndian.PutUint32(out[4:8], 1<<30)
 | |
| 	// Do not put an epoch time in 8:12, when we start using it, tests that use it should fail.
 | |
| 	mapResp := out[24:]
 | |
| 	mapReq := req[24:]
 | |
| 	// copy nonce, protocol and internal port
 | |
| 	copy(mapResp[:13], mapReq[:13])
 | |
| 	copy(mapResp[16:18], mapReq[16:18])
 | |
| 	// assign external port
 | |
| 	binary.BigEndian.PutUint16(mapResp[18:20], 4242)
 | |
| 	assignedIP := netaddr.IPv4(127, 0, 0, 1)
 | |
| 	assignedIP16 := assignedIP.As16()
 | |
| 	copy(mapResp[20:36], assignedIP16[:])
 | |
| 	return out
 | |
| }
 |