mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			335 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			335 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Go
		
	
	
	
// Copyright 2015 The Go Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 | 
						|
 | 
						|
package net
 | 
						|
 | 
						|
import (
 | 
						|
	"reflect"
 | 
						|
	"testing"
 | 
						|
)
 | 
						|
 | 
						|
func TestSortByRFC6724(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		in      []IPAddr
 | 
						|
		srcs    []IP
 | 
						|
		want    []IPAddr
 | 
						|
		reverse bool // also test it starting backwards
 | 
						|
	}{
 | 
						|
		// Examples from RFC 6724 section 10.2:
 | 
						|
 | 
						|
		// Prefer matching scope.
 | 
						|
		{
 | 
						|
			in: []IPAddr{
 | 
						|
				{IP: ParseIP("2001:db8:1::1")},
 | 
						|
				{IP: ParseIP("198.51.100.121")},
 | 
						|
			},
 | 
						|
			srcs: []IP{
 | 
						|
				ParseIP("2001:db8:1::2"),
 | 
						|
				ParseIP("169.254.13.78"),
 | 
						|
			},
 | 
						|
			want: []IPAddr{
 | 
						|
				{IP: ParseIP("2001:db8:1::1")},
 | 
						|
				{IP: ParseIP("198.51.100.121")},
 | 
						|
			},
 | 
						|
			reverse: true,
 | 
						|
		},
 | 
						|
 | 
						|
		// Prefer matching scope.
 | 
						|
		{
 | 
						|
			in: []IPAddr{
 | 
						|
				{IP: ParseIP("2001:db8:1::1")},
 | 
						|
				{IP: ParseIP("198.51.100.121")},
 | 
						|
			},
 | 
						|
			srcs: []IP{
 | 
						|
				ParseIP("fe80::1"),
 | 
						|
				ParseIP("198.51.100.117"),
 | 
						|
			},
 | 
						|
			want: []IPAddr{
 | 
						|
				{IP: ParseIP("198.51.100.121")},
 | 
						|
				{IP: ParseIP("2001:db8:1::1")},
 | 
						|
			},
 | 
						|
			reverse: true,
 | 
						|
		},
 | 
						|
 | 
						|
		// Prefer higher precedence.
 | 
						|
		{
 | 
						|
			in: []IPAddr{
 | 
						|
				{IP: ParseIP("2001:db8:1::1")},
 | 
						|
				{IP: ParseIP("10.1.2.3")},
 | 
						|
			},
 | 
						|
			srcs: []IP{
 | 
						|
				ParseIP("2001:db8:1::2"),
 | 
						|
				ParseIP("10.1.2.4"),
 | 
						|
			},
 | 
						|
			want: []IPAddr{
 | 
						|
				{IP: ParseIP("2001:db8:1::1")},
 | 
						|
				{IP: ParseIP("10.1.2.3")},
 | 
						|
			},
 | 
						|
			reverse: true,
 | 
						|
		},
 | 
						|
 | 
						|
		// Prefer smaller scope.
 | 
						|
		{
 | 
						|
			in: []IPAddr{
 | 
						|
				{IP: ParseIP("2001:db8:1::1")},
 | 
						|
				{IP: ParseIP("fe80::1")},
 | 
						|
			},
 | 
						|
			srcs: []IP{
 | 
						|
				ParseIP("2001:db8:1::2"),
 | 
						|
				ParseIP("fe80::2"),
 | 
						|
			},
 | 
						|
			want: []IPAddr{
 | 
						|
				{IP: ParseIP("fe80::1")},
 | 
						|
				{IP: ParseIP("2001:db8:1::1")},
 | 
						|
			},
 | 
						|
			reverse: true,
 | 
						|
		},
 | 
						|
 | 
						|
		// Issue 13283.  Having a 10/8 source address does not
 | 
						|
		// mean we should prefer 23/8 destination addresses.
 | 
						|
		{
 | 
						|
			in: []IPAddr{
 | 
						|
				{IP: ParseIP("54.83.193.112")},
 | 
						|
				{IP: ParseIP("184.72.238.214")},
 | 
						|
				{IP: ParseIP("23.23.172.185")},
 | 
						|
				{IP: ParseIP("75.101.148.21")},
 | 
						|
				{IP: ParseIP("23.23.134.56")},
 | 
						|
				{IP: ParseIP("23.21.50.150")},
 | 
						|
			},
 | 
						|
			srcs: []IP{
 | 
						|
				ParseIP("10.2.3.4"),
 | 
						|
				ParseIP("10.2.3.4"),
 | 
						|
				ParseIP("10.2.3.4"),
 | 
						|
				ParseIP("10.2.3.4"),
 | 
						|
				ParseIP("10.2.3.4"),
 | 
						|
				ParseIP("10.2.3.4"),
 | 
						|
			},
 | 
						|
			want: []IPAddr{
 | 
						|
				{IP: ParseIP("54.83.193.112")},
 | 
						|
				{IP: ParseIP("184.72.238.214")},
 | 
						|
				{IP: ParseIP("23.23.172.185")},
 | 
						|
				{IP: ParseIP("75.101.148.21")},
 | 
						|
				{IP: ParseIP("23.23.134.56")},
 | 
						|
				{IP: ParseIP("23.21.50.150")},
 | 
						|
			},
 | 
						|
			reverse: false,
 | 
						|
		},
 | 
						|
 | 
						|
		// Prefer longer common prefixes, but only for IPv4 address
 | 
						|
		// pairs in the same special-purpose block.
 | 
						|
		{
 | 
						|
			in: []IPAddr{
 | 
						|
				{IP: ParseIP("1.2.3.4")},
 | 
						|
				{IP: ParseIP("10.55.0.1")},
 | 
						|
				{IP: ParseIP("10.66.0.1")},
 | 
						|
			},
 | 
						|
			srcs: []IP{
 | 
						|
				ParseIP("1.2.3.5"),
 | 
						|
				ParseIP("10.66.1.2"),
 | 
						|
				ParseIP("10.66.1.2"),
 | 
						|
			},
 | 
						|
			want: []IPAddr{
 | 
						|
				{IP: ParseIP("10.66.0.1")},
 | 
						|
				{IP: ParseIP("10.55.0.1")},
 | 
						|
				{IP: ParseIP("1.2.3.4")},
 | 
						|
			},
 | 
						|
			reverse: true,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i, tt := range tests {
 | 
						|
		inCopy := make([]IPAddr, len(tt.in))
 | 
						|
		copy(inCopy, tt.in)
 | 
						|
		srcCopy := make([]IP, len(tt.in))
 | 
						|
		copy(srcCopy, tt.srcs)
 | 
						|
		sortByRFC6724withSrcs(inCopy, srcCopy)
 | 
						|
		if !reflect.DeepEqual(inCopy, tt.want) {
 | 
						|
			t.Errorf("test %d:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want)
 | 
						|
		}
 | 
						|
		if tt.reverse {
 | 
						|
			copy(inCopy, tt.in)
 | 
						|
			copy(srcCopy, tt.srcs)
 | 
						|
			for j := 0; j < len(inCopy)/2; j++ {
 | 
						|
				k := len(inCopy) - j - 1
 | 
						|
				inCopy[j], inCopy[k] = inCopy[k], inCopy[j]
 | 
						|
				srcCopy[j], srcCopy[k] = srcCopy[k], srcCopy[j]
 | 
						|
			}
 | 
						|
			sortByRFC6724withSrcs(inCopy, srcCopy)
 | 
						|
			if !reflect.DeepEqual(inCopy, tt.want) {
 | 
						|
				t.Errorf("test %d, starting backwards:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want)
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
func TestRFC6724PolicyTableClassify(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		ip   IP
 | 
						|
		want policyTableEntry
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			ip: ParseIP("127.0.0.1"),
 | 
						|
			want: policyTableEntry{
 | 
						|
				Prefix:     &IPNet{IP: ParseIP("::ffff:0:0"), Mask: CIDRMask(96, 128)},
 | 
						|
				Precedence: 35,
 | 
						|
				Label:      4,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			ip: ParseIP("2601:645:8002:a500:986f:1db8:c836:bd65"),
 | 
						|
			want: policyTableEntry{
 | 
						|
				Prefix:     &IPNet{IP: ParseIP("::"), Mask: CIDRMask(0, 128)},
 | 
						|
				Precedence: 40,
 | 
						|
				Label:      1,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			ip: ParseIP("::1"),
 | 
						|
			want: policyTableEntry{
 | 
						|
				Prefix:     &IPNet{IP: ParseIP("::1"), Mask: CIDRMask(128, 128)},
 | 
						|
				Precedence: 50,
 | 
						|
				Label:      0,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			ip: ParseIP("2002::ab12"),
 | 
						|
			want: policyTableEntry{
 | 
						|
				Prefix:     &IPNet{IP: ParseIP("2002::"), Mask: CIDRMask(16, 128)},
 | 
						|
				Precedence: 30,
 | 
						|
				Label:      2,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i, tt := range tests {
 | 
						|
		got := rfc6724policyTable.Classify(tt.ip)
 | 
						|
		if !reflect.DeepEqual(got, tt.want) {
 | 
						|
			t.Errorf("%d. Classify(%s) = %v; want %v", i, tt.ip, got, tt.want)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestRFC6724ClassifyScope(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		ip   IP
 | 
						|
		want scope
 | 
						|
	}{
 | 
						|
		{ParseIP("127.0.0.1"), scopeLinkLocal},   // rfc6724#section-3.2
 | 
						|
		{ParseIP("::1"), scopeLinkLocal},         // rfc4007#section-4
 | 
						|
		{ParseIP("169.254.1.2"), scopeLinkLocal}, // rfc6724#section-3.2
 | 
						|
		{ParseIP("fec0::1"), scopeSiteLocal},
 | 
						|
		{ParseIP("8.8.8.8"), scopeGlobal},
 | 
						|
 | 
						|
		{ParseIP("ff02::"), scopeLinkLocal},  // IPv6 multicast
 | 
						|
		{ParseIP("ff05::"), scopeSiteLocal},  // IPv6 multicast
 | 
						|
		{ParseIP("ff04::"), scopeAdminLocal}, // IPv6 multicast
 | 
						|
		{ParseIP("ff0e::"), scopeGlobal},     // IPv6 multicast
 | 
						|
 | 
						|
		{IPv4(0xe0, 0, 0, 0), scopeGlobal},       // IPv4 link-local multicast as 16 bytes
 | 
						|
		{IPv4(0xe0, 2, 2, 2), scopeGlobal},       // IPv4 global multicast as 16 bytes
 | 
						|
		{IPv4(0xe0, 0, 0, 0).To4(), scopeGlobal}, // IPv4 link-local multicast as 4 bytes
 | 
						|
		{IPv4(0xe0, 2, 2, 2).To4(), scopeGlobal}, // IPv4 global multicast as 4 bytes
 | 
						|
	}
 | 
						|
	for i, tt := range tests {
 | 
						|
		got := classifyScope(tt.ip)
 | 
						|
		if got != tt.want {
 | 
						|
			t.Errorf("%d. classifyScope(%s) = %x; want %x", i, tt.ip, got, tt.want)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestRFC6724CommonPrefixLength(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		a, b IP
 | 
						|
		want int
 | 
						|
	}{
 | 
						|
		{ParseIP("fe80::1"), ParseIP("fe80::2"), 64},
 | 
						|
		{ParseIP("fe81::1"), ParseIP("fe80::2"), 15},
 | 
						|
		{ParseIP("127.0.0.1"), ParseIP("fe80::1"), 0}, // diff size
 | 
						|
		{IPv4(1, 2, 3, 4), IP{1, 2, 3, 4}, 32},
 | 
						|
		{IP{1, 2, 255, 255}, IP{1, 2, 0, 0}, 16},
 | 
						|
		{IP{1, 2, 127, 255}, IP{1, 2, 0, 0}, 17},
 | 
						|
		{IP{1, 2, 63, 255}, IP{1, 2, 0, 0}, 18},
 | 
						|
		{IP{1, 2, 31, 255}, IP{1, 2, 0, 0}, 19},
 | 
						|
		{IP{1, 2, 15, 255}, IP{1, 2, 0, 0}, 20},
 | 
						|
		{IP{1, 2, 7, 255}, IP{1, 2, 0, 0}, 21},
 | 
						|
		{IP{1, 2, 3, 255}, IP{1, 2, 0, 0}, 22},
 | 
						|
		{IP{1, 2, 1, 255}, IP{1, 2, 0, 0}, 23},
 | 
						|
		{IP{1, 2, 0, 255}, IP{1, 2, 0, 0}, 24},
 | 
						|
	}
 | 
						|
	for i, tt := range tests {
 | 
						|
		got := commonPrefixLen(tt.a, tt.b)
 | 
						|
		if got != tt.want {
 | 
						|
			t.Errorf("%d. commonPrefixLen(%s, %s) = %d; want %d", i, tt.a, tt.b, got, tt.want)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
func mustParseCIDRs(t *testing.T, blocks ...string) []*IPNet {
 | 
						|
	res := make([]*IPNet, len(blocks))
 | 
						|
	for i, block := range blocks {
 | 
						|
		var err error
 | 
						|
		_, res[i], err = ParseCIDR(block)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatalf("ParseCIDR(%s) failed: %v", block, err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return res
 | 
						|
}
 | 
						|
 | 
						|
func TestSameIPv4SpecialPurposeBlock(t *testing.T) {
 | 
						|
	blocks := mustParseCIDRs(t,
 | 
						|
		"10.0.0.0/8",
 | 
						|
		"127.0.0.0/8",
 | 
						|
		"169.254.0.0/16",
 | 
						|
		"172.16.0.0/12",
 | 
						|
		"192.168.0.0/16",
 | 
						|
	)
 | 
						|
 | 
						|
	addrs := []struct {
 | 
						|
		ip    IP
 | 
						|
		block int // index or -1
 | 
						|
	}{
 | 
						|
		{IP{1, 2, 3, 4}, -1},
 | 
						|
		{IP{2, 3, 4, 5}, -1},
 | 
						|
		{IP{10, 2, 3, 4}, 0},
 | 
						|
		{IP{10, 6, 7, 8}, 0},
 | 
						|
		{IP{127, 0, 0, 1}, 1},
 | 
						|
		{IP{127, 255, 255, 255}, 1},
 | 
						|
		{IP{169, 254, 77, 99}, 2},
 | 
						|
		{IP{169, 254, 44, 22}, 2},
 | 
						|
		{IP{169, 255, 0, 1}, -1},
 | 
						|
		{IP{172, 15, 5, 6}, -1},
 | 
						|
		{IP{172, 16, 32, 41}, 3},
 | 
						|
		{IP{172, 31, 128, 9}, 3},
 | 
						|
		{IP{172, 32, 88, 100}, -1},
 | 
						|
		{IP{192, 168, 1, 1}, 4},
 | 
						|
		{IP{192, 168, 128, 42}, 4},
 | 
						|
		{IP{192, 169, 1, 1}, -1},
 | 
						|
	}
 | 
						|
 | 
						|
	for i, addr := range addrs {
 | 
						|
		for j, block := range blocks {
 | 
						|
			got := block.Contains(addr.ip)
 | 
						|
			want := addr.block == j
 | 
						|
			if got != want {
 | 
						|
				t.Errorf("%d/%d. %s.Contains(%s): got %v, want %v", i, j, block, addr.ip, got, want)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	for i, addr1 := range addrs {
 | 
						|
		for j, addr2 := range addrs {
 | 
						|
			got := sameIPv4SpecialPurposeBlock(addr1.ip, addr2.ip)
 | 
						|
			want := addr1.block >= 0 && addr1.block == addr2.block
 | 
						|
			if got != want {
 | 
						|
				t.Errorf("%d/%d. sameIPv4SpecialPurposeBlock(%s, %s): got %v, want %v", i, j, addr1.ip, addr2.ip, got, want)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |