Black Lives Matter. Support the Equal Justice Initiative.

Source file src/net/addrselect_test.go

Documentation: net

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
     6  // +build darwin dragonfly freebsd linux netbsd openbsd solaris
     7  
     8  package net
     9  
    10  import (
    11  	"reflect"
    12  	"testing"
    13  )
    14  
    15  func TestSortByRFC6724(t *testing.T) {
    16  	tests := []struct {
    17  		in      []IPAddr
    18  		srcs    []IP
    19  		want    []IPAddr
    20  		reverse bool // also test it starting backwards
    21  	}{
    22  		// Examples from RFC 6724 section 10.2:
    23  
    24  		// Prefer matching scope.
    25  		{
    26  			in: []IPAddr{
    27  				{IP: ParseIP("2001:db8:1::1")},
    28  				{IP: ParseIP("198.51.100.121")},
    29  			},
    30  			srcs: []IP{
    31  				ParseIP("2001:db8:1::2"),
    32  				ParseIP("169.254.13.78"),
    33  			},
    34  			want: []IPAddr{
    35  				{IP: ParseIP("2001:db8:1::1")},
    36  				{IP: ParseIP("198.51.100.121")},
    37  			},
    38  			reverse: true,
    39  		},
    40  
    41  		// Prefer matching scope.
    42  		{
    43  			in: []IPAddr{
    44  				{IP: ParseIP("2001:db8:1::1")},
    45  				{IP: ParseIP("198.51.100.121")},
    46  			},
    47  			srcs: []IP{
    48  				ParseIP("fe80::1"),
    49  				ParseIP("198.51.100.117"),
    50  			},
    51  			want: []IPAddr{
    52  				{IP: ParseIP("198.51.100.121")},
    53  				{IP: ParseIP("2001:db8:1::1")},
    54  			},
    55  			reverse: true,
    56  		},
    57  
    58  		// Prefer higher precedence.
    59  		{
    60  			in: []IPAddr{
    61  				{IP: ParseIP("2001:db8:1::1")},
    62  				{IP: ParseIP("10.1.2.3")},
    63  			},
    64  			srcs: []IP{
    65  				ParseIP("2001:db8:1::2"),
    66  				ParseIP("10.1.2.4"),
    67  			},
    68  			want: []IPAddr{
    69  				{IP: ParseIP("2001:db8:1::1")},
    70  				{IP: ParseIP("10.1.2.3")},
    71  			},
    72  			reverse: true,
    73  		},
    74  
    75  		// Prefer smaller scope.
    76  		{
    77  			in: []IPAddr{
    78  				{IP: ParseIP("2001:db8:1::1")},
    79  				{IP: ParseIP("fe80::1")},
    80  			},
    81  			srcs: []IP{
    82  				ParseIP("2001:db8:1::2"),
    83  				ParseIP("fe80::2"),
    84  			},
    85  			want: []IPAddr{
    86  				{IP: ParseIP("fe80::1")},
    87  				{IP: ParseIP("2001:db8:1::1")},
    88  			},
    89  			reverse: true,
    90  		},
    91  
    92  		// Issue 13283.  Having a 10/8 source address does not
    93  		// mean we should prefer 23/8 destination addresses.
    94  		{
    95  			in: []IPAddr{
    96  				{IP: ParseIP("54.83.193.112")},
    97  				{IP: ParseIP("184.72.238.214")},
    98  				{IP: ParseIP("23.23.172.185")},
    99  				{IP: ParseIP("75.101.148.21")},
   100  				{IP: ParseIP("23.23.134.56")},
   101  				{IP: ParseIP("23.21.50.150")},
   102  			},
   103  			srcs: []IP{
   104  				ParseIP("10.2.3.4"),
   105  				ParseIP("10.2.3.4"),
   106  				ParseIP("10.2.3.4"),
   107  				ParseIP("10.2.3.4"),
   108  				ParseIP("10.2.3.4"),
   109  				ParseIP("10.2.3.4"),
   110  			},
   111  			want: []IPAddr{
   112  				{IP: ParseIP("54.83.193.112")},
   113  				{IP: ParseIP("184.72.238.214")},
   114  				{IP: ParseIP("23.23.172.185")},
   115  				{IP: ParseIP("75.101.148.21")},
   116  				{IP: ParseIP("23.23.134.56")},
   117  				{IP: ParseIP("23.21.50.150")},
   118  			},
   119  			reverse: false,
   120  		},
   121  	}
   122  	for i, tt := range tests {
   123  		inCopy := make([]IPAddr, len(tt.in))
   124  		copy(inCopy, tt.in)
   125  		srcCopy := make([]IP, len(tt.in))
   126  		copy(srcCopy, tt.srcs)
   127  		sortByRFC6724withSrcs(inCopy, srcCopy)
   128  		if !reflect.DeepEqual(inCopy, tt.want) {
   129  			t.Errorf("test %d:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want)
   130  		}
   131  		if tt.reverse {
   132  			copy(inCopy, tt.in)
   133  			copy(srcCopy, tt.srcs)
   134  			for j := 0; j < len(inCopy)/2; j++ {
   135  				k := len(inCopy) - j - 1
   136  				inCopy[j], inCopy[k] = inCopy[k], inCopy[j]
   137  				srcCopy[j], srcCopy[k] = srcCopy[k], srcCopy[j]
   138  			}
   139  			sortByRFC6724withSrcs(inCopy, srcCopy)
   140  			if !reflect.DeepEqual(inCopy, tt.want) {
   141  				t.Errorf("test %d, starting backwards:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want)
   142  			}
   143  		}
   144  
   145  	}
   146  
   147  }
   148  
   149  func TestRFC6724PolicyTableClassify(t *testing.T) {
   150  	tests := []struct {
   151  		ip   IP
   152  		want policyTableEntry
   153  	}{
   154  		{
   155  			ip: ParseIP("127.0.0.1"),
   156  			want: policyTableEntry{
   157  				Prefix:     &IPNet{IP: ParseIP("::ffff:0:0"), Mask: CIDRMask(96, 128)},
   158  				Precedence: 35,
   159  				Label:      4,
   160  			},
   161  		},
   162  		{
   163  			ip: ParseIP("2601:645:8002:a500:986f:1db8:c836:bd65"),
   164  			want: policyTableEntry{
   165  				Prefix:     &IPNet{IP: ParseIP("::"), Mask: CIDRMask(0, 128)},
   166  				Precedence: 40,
   167  				Label:      1,
   168  			},
   169  		},
   170  		{
   171  			ip: ParseIP("::1"),
   172  			want: policyTableEntry{
   173  				Prefix:     &IPNet{IP: ParseIP("::1"), Mask: CIDRMask(128, 128)},
   174  				Precedence: 50,
   175  				Label:      0,
   176  			},
   177  		},
   178  		{
   179  			ip: ParseIP("2002::ab12"),
   180  			want: policyTableEntry{
   181  				Prefix:     &IPNet{IP: ParseIP("2002::"), Mask: CIDRMask(16, 128)},
   182  				Precedence: 30,
   183  				Label:      2,
   184  			},
   185  		},
   186  	}
   187  	for i, tt := range tests {
   188  		got := rfc6724policyTable.Classify(tt.ip)
   189  		if !reflect.DeepEqual(got, tt.want) {
   190  			t.Errorf("%d. Classify(%s) = %v; want %v", i, tt.ip, got, tt.want)
   191  		}
   192  	}
   193  }
   194  
   195  func TestRFC6724ClassifyScope(t *testing.T) {
   196  	tests := []struct {
   197  		ip   IP
   198  		want scope
   199  	}{
   200  		{ParseIP("127.0.0.1"), scopeLinkLocal},   // rfc6724#section-3.2
   201  		{ParseIP("::1"), scopeLinkLocal},         // rfc4007#section-4
   202  		{ParseIP("169.254.1.2"), scopeLinkLocal}, // rfc6724#section-3.2
   203  		{ParseIP("fec0::1"), scopeSiteLocal},
   204  		{ParseIP("8.8.8.8"), scopeGlobal},
   205  
   206  		{ParseIP("ff02::"), scopeLinkLocal},  // IPv6 multicast
   207  		{ParseIP("ff05::"), scopeSiteLocal},  // IPv6 multicast
   208  		{ParseIP("ff04::"), scopeAdminLocal}, // IPv6 multicast
   209  		{ParseIP("ff0e::"), scopeGlobal},     // IPv6 multicast
   210  
   211  		{IPv4(0xe0, 0, 0, 0), scopeGlobal},       // IPv4 link-local multicast as 16 bytes
   212  		{IPv4(0xe0, 2, 2, 2), scopeGlobal},       // IPv4 global multicast as 16 bytes
   213  		{IPv4(0xe0, 0, 0, 0).To4(), scopeGlobal}, // IPv4 link-local multicast as 4 bytes
   214  		{IPv4(0xe0, 2, 2, 2).To4(), scopeGlobal}, // IPv4 global multicast as 4 bytes
   215  	}
   216  	for i, tt := range tests {
   217  		got := classifyScope(tt.ip)
   218  		if got != tt.want {
   219  			t.Errorf("%d. classifyScope(%s) = %x; want %x", i, tt.ip, got, tt.want)
   220  		}
   221  	}
   222  }
   223  
   224  func TestRFC6724CommonPrefixLength(t *testing.T) {
   225  	tests := []struct {
   226  		a, b IP
   227  		want int
   228  	}{
   229  		{ParseIP("fe80::1"), ParseIP("fe80::2"), 64},
   230  		{ParseIP("fe81::1"), ParseIP("fe80::2"), 15},
   231  		{ParseIP("127.0.0.1"), ParseIP("fe80::1"), 0}, // diff size
   232  		{IPv4(1, 2, 3, 4), IP{1, 2, 3, 4}, 32},
   233  		{IP{1, 2, 255, 255}, IP{1, 2, 0, 0}, 16},
   234  		{IP{1, 2, 127, 255}, IP{1, 2, 0, 0}, 17},
   235  		{IP{1, 2, 63, 255}, IP{1, 2, 0, 0}, 18},
   236  		{IP{1, 2, 31, 255}, IP{1, 2, 0, 0}, 19},
   237  		{IP{1, 2, 15, 255}, IP{1, 2, 0, 0}, 20},
   238  		{IP{1, 2, 7, 255}, IP{1, 2, 0, 0}, 21},
   239  		{IP{1, 2, 3, 255}, IP{1, 2, 0, 0}, 22},
   240  		{IP{1, 2, 1, 255}, IP{1, 2, 0, 0}, 23},
   241  		{IP{1, 2, 0, 255}, IP{1, 2, 0, 0}, 24},
   242  	}
   243  	for i, tt := range tests {
   244  		got := commonPrefixLen(tt.a, tt.b)
   245  		if got != tt.want {
   246  			t.Errorf("%d. commonPrefixLen(%s, %s) = %d; want %d", i, tt.a, tt.b, got, tt.want)
   247  		}
   248  	}
   249  
   250  }
   251  

View as plain text