github.com/xingly-cn/shorturl-go@v0.0.0-20220110130535-e21de4659f74/pkg/mod/golang.org/x/sys@v0.0.0-20200323222414-85ca7c5b95cd/unix/syscall_internal_linux_test.go (about)

     1  // Copyright 2019 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  // +build linux
     6  
     7  package unix
     8  
     9  import (
    10  	"reflect"
    11  	"testing"
    12  	"unsafe"
    13  )
    14  
    15  // as per socket(2)
    16  type SocketSpec struct {
    17  	domain   int
    18  	typ      int
    19  	protocol int
    20  }
    21  
    22  func Test_anyToSockaddr(t *testing.T) {
    23  	tests := []struct {
    24  		name string
    25  		rsa  *RawSockaddrAny
    26  		sa   Sockaddr
    27  		err  error
    28  		skt  SocketSpec
    29  	}{
    30  		{
    31  			name: "AF_TIPC bad addrtype",
    32  			rsa: &RawSockaddrAny{
    33  				Addr: RawSockaddr{
    34  					Family: AF_TIPC,
    35  				},
    36  			},
    37  			err: EINVAL,
    38  		},
    39  		{
    40  			name: "AF_TIPC NameSeq",
    41  			rsa: sockaddrTIPCToAny(RawSockaddrTIPC{
    42  				Family:   AF_TIPC,
    43  				Addrtype: TIPC_SERVICE_RANGE,
    44  				Scope:    1,
    45  				Addr: (&TIPCServiceRange{
    46  					Type:  1,
    47  					Lower: 2,
    48  					Upper: 3,
    49  				}).tipcAddr(),
    50  			}),
    51  			sa: &SockaddrTIPC{
    52  				Scope: 1,
    53  				Addr: &TIPCServiceRange{
    54  					Type:  1,
    55  					Lower: 2,
    56  					Upper: 3,
    57  				},
    58  			},
    59  		},
    60  		{
    61  			name: "AF_TIPC Name",
    62  			rsa: sockaddrTIPCToAny(RawSockaddrTIPC{
    63  				Family:   AF_TIPC,
    64  				Addrtype: TIPC_SERVICE_ADDR,
    65  				Scope:    2,
    66  				Addr: (&TIPCServiceName{
    67  					Type:     1,
    68  					Instance: 2,
    69  					Domain:   3,
    70  				}).tipcAddr(),
    71  			}),
    72  			sa: &SockaddrTIPC{
    73  				Scope: 2,
    74  				Addr: &TIPCServiceName{
    75  					Type:     1,
    76  					Instance: 2,
    77  					Domain:   3,
    78  				},
    79  			},
    80  		},
    81  		{
    82  			name: "AF_TIPC ID",
    83  			rsa: sockaddrTIPCToAny(RawSockaddrTIPC{
    84  				Family:   AF_TIPC,
    85  				Addrtype: TIPC_SOCKET_ADDR,
    86  				Scope:    3,
    87  				Addr: (&TIPCSocketAddr{
    88  					Ref:  1,
    89  					Node: 2,
    90  				}).tipcAddr(),
    91  			}),
    92  			sa: &SockaddrTIPC{
    93  				Scope: 3,
    94  				Addr: &TIPCSocketAddr{
    95  					Ref:  1,
    96  					Node: 2,
    97  				},
    98  			},
    99  		},
   100  		{
   101  			name: "AF_INET IPPROTO_L2TP",
   102  			rsa: sockaddrL2TPIPToAny(RawSockaddrL2TPIP{
   103  				Family:  AF_INET,
   104  				Addr:    [4]byte{0xef, 0x10, 0x5b, 0xa2},
   105  				Conn_id: 0x1234abcd,
   106  			}),
   107  			sa: &SockaddrL2TPIP{
   108  				Addr:   [4]byte{0xef, 0x10, 0x5b, 0xa2},
   109  				ConnId: 0x1234abcd,
   110  			},
   111  			skt: SocketSpec{domain: AF_INET, typ: SOCK_DGRAM, protocol: IPPROTO_L2TP},
   112  		},
   113  		{
   114  			name: "AF_INET6 IPPROTO_L2TP",
   115  			rsa: sockaddrL2TPIP6ToAny(RawSockaddrL2TPIP6{
   116  				Family:   AF_INET6,
   117  				Flowinfo: 42,
   118  				Addr: [16]byte{
   119  					0x20, 0x01, 0x0d, 0xb8,
   120  					0x85, 0xa3, 0x00, 0x00,
   121  					0x00, 0x00, 0x8a, 0x2e,
   122  					0x03, 0x70, 0x73, 0x34,
   123  				},
   124  				Scope_id: 90210,
   125  				Conn_id:  0x1234abcd,
   126  			}),
   127  			sa: &SockaddrL2TPIP6{
   128  				Addr: [16]byte{
   129  					0x20, 0x01, 0x0d, 0xb8,
   130  					0x85, 0xa3, 0x00, 0x00,
   131  					0x00, 0x00, 0x8a, 0x2e,
   132  					0x03, 0x70, 0x73, 0x34,
   133  				},
   134  				ZoneId: 90210,
   135  				ConnId: 0x1234abcd,
   136  			},
   137  			skt: SocketSpec{domain: AF_INET6, typ: SOCK_DGRAM, protocol: IPPROTO_L2TP},
   138  		},
   139  		{
   140  			name: "AF_MAX EAFNOSUPPORT",
   141  			rsa: &RawSockaddrAny{
   142  				Addr: RawSockaddr{
   143  					Family: AF_MAX,
   144  				},
   145  			},
   146  			err: EAFNOSUPPORT,
   147  		},
   148  		// TODO: expand to support other families.
   149  	}
   150  
   151  	for _, tt := range tests {
   152  		t.Run(tt.name, func(t *testing.T) {
   153  			fd := int(0)
   154  			var err error
   155  			if tt.skt.domain != 0 {
   156  				fd, err = Socket(tt.skt.domain, tt.skt.typ, tt.skt.protocol)
   157  				// Some sockaddr types need specific kernel modules running: if these
   158  				// are not present we'll get EPROTONOSUPPORT back when trying to create
   159  				// the socket.  Skip the test in this situation.
   160  				if err == EPROTONOSUPPORT {
   161  					t.Skip("socket family/protocol not supported by kernel")
   162  				} else if err != nil {
   163  					t.Fatalf("socket(%v): %v", tt.skt, err)
   164  				}
   165  				defer Close(fd)
   166  			}
   167  			sa, err := anyToSockaddr(fd, tt.rsa)
   168  			if err != tt.err {
   169  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   170  			}
   171  
   172  			if !reflect.DeepEqual(sa, tt.sa) {
   173  				t.Fatalf("unexpected Sockaddr:\n got: %#v\nwant: %#v", sa, tt.sa)
   174  			}
   175  		})
   176  	}
   177  }
   178  
   179  func TestSockaddrTIPC_sockaddr(t *testing.T) {
   180  	tests := []struct {
   181  		name string
   182  		sa   *SockaddrTIPC
   183  		raw  *RawSockaddrTIPC
   184  		err  error
   185  	}{
   186  		{
   187  			name: "no fields set",
   188  			sa:   &SockaddrTIPC{},
   189  			err:  EINVAL,
   190  		},
   191  		{
   192  			name: "ID",
   193  			sa: &SockaddrTIPC{
   194  				Scope: 1,
   195  				Addr: &TIPCSocketAddr{
   196  					Ref:  1,
   197  					Node: 2,
   198  				},
   199  			},
   200  			raw: &RawSockaddrTIPC{
   201  				Family:   AF_TIPC,
   202  				Addrtype: TIPC_SOCKET_ADDR,
   203  				Scope:    1,
   204  				Addr: (&TIPCSocketAddr{
   205  					Ref:  1,
   206  					Node: 2,
   207  				}).tipcAddr(),
   208  			},
   209  		},
   210  		{
   211  			name: "NameSeq",
   212  			sa: &SockaddrTIPC{
   213  				Scope: 2,
   214  				Addr: &TIPCServiceRange{
   215  					Type:  1,
   216  					Lower: 2,
   217  					Upper: 3,
   218  				},
   219  			},
   220  			raw: &RawSockaddrTIPC{
   221  				Family:   AF_TIPC,
   222  				Addrtype: TIPC_SERVICE_RANGE,
   223  				Scope:    2,
   224  				Addr: (&TIPCServiceRange{
   225  					Type:  1,
   226  					Lower: 2,
   227  					Upper: 3,
   228  				}).tipcAddr(),
   229  			},
   230  		},
   231  		{
   232  			name: "Name",
   233  			sa: &SockaddrTIPC{
   234  				Scope: 3,
   235  				Addr: &TIPCServiceName{
   236  					Type:     1,
   237  					Instance: 2,
   238  					Domain:   3,
   239  				},
   240  			},
   241  			raw: &RawSockaddrTIPC{
   242  				Family:   AF_TIPC,
   243  				Addrtype: TIPC_SERVICE_ADDR,
   244  				Scope:    3,
   245  				Addr: (&TIPCServiceName{
   246  					Type:     1,
   247  					Instance: 2,
   248  					Domain:   3,
   249  				}).tipcAddr(),
   250  			},
   251  		},
   252  	}
   253  
   254  	for _, tt := range tests {
   255  		t.Run(tt.name, func(t *testing.T) {
   256  			out, l, err := tt.sa.sockaddr()
   257  			if err != tt.err {
   258  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   259  			}
   260  
   261  			// Must be 0 on error or a fixed size otherwise.
   262  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrTIPC) {
   263  				t.Fatalf("unexpected Socklen: %d", l)
   264  			}
   265  			if out == nil {
   266  				// No pointer to cast, return early.
   267  				return
   268  			}
   269  
   270  			raw := (*RawSockaddrTIPC)(out)
   271  			if !reflect.DeepEqual(raw, tt.raw) {
   272  				t.Fatalf("unexpected RawSockaddrTIPC:\n got: %#v\nwant: %#v", raw, tt.raw)
   273  			}
   274  		})
   275  	}
   276  }
   277  
   278  func TestSockaddrL2TPIP_sockaddr(t *testing.T) {
   279  	tests := []struct {
   280  		name string
   281  		sa   *SockaddrL2TPIP
   282  		raw  *RawSockaddrL2TPIP
   283  		err  error
   284  	}{
   285  		{
   286  			name: "L2TPIP",
   287  			sa: &SockaddrL2TPIP{
   288  				Addr:   [4]byte{0xef, 0x10, 0x5b, 0xa2},
   289  				ConnId: 0x1234abcd,
   290  			},
   291  			raw: &RawSockaddrL2TPIP{
   292  				Family:  AF_INET,
   293  				Addr:    [4]byte{0xef, 0x10, 0x5b, 0xa2},
   294  				Conn_id: 0x1234abcd,
   295  			},
   296  		},
   297  	}
   298  
   299  	for _, tt := range tests {
   300  		t.Run(tt.name, func(t *testing.T) {
   301  			out, l, err := tt.sa.sockaddr()
   302  			if err != tt.err {
   303  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   304  			}
   305  
   306  			// Must be 0 on error or a fixed size otherwise.
   307  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrL2TPIP) {
   308  				t.Fatalf("unexpected Socklen: %d", l)
   309  			}
   310  
   311  			if out != nil {
   312  				raw := (*RawSockaddrL2TPIP)(out)
   313  				if !reflect.DeepEqual(raw, tt.raw) {
   314  					t.Fatalf("unexpected RawSockaddrL2TPIP:\n got: %#v\nwant: %#v", raw, tt.raw)
   315  				}
   316  			}
   317  		})
   318  	}
   319  }
   320  
   321  func TestSockaddrL2TPIP6_sockaddr(t *testing.T) {
   322  	tests := []struct {
   323  		name string
   324  		sa   *SockaddrL2TPIP6
   325  		raw  *RawSockaddrL2TPIP6
   326  		err  error
   327  	}{
   328  		{
   329  			name: "L2TPIP6",
   330  			sa: &SockaddrL2TPIP6{
   331  				Addr: [16]byte{
   332  					0x20, 0x01, 0x0d, 0xb8,
   333  					0x85, 0xa3, 0x00, 0x00,
   334  					0x00, 0x00, 0x8a, 0x2e,
   335  					0x03, 0x70, 0x73, 0x34,
   336  				},
   337  				ZoneId: 90210,
   338  				ConnId: 0x1234abcd,
   339  			},
   340  			raw: &RawSockaddrL2TPIP6{
   341  				Family: AF_INET6,
   342  				Addr: [16]byte{
   343  					0x20, 0x01, 0x0d, 0xb8,
   344  					0x85, 0xa3, 0x00, 0x00,
   345  					0x00, 0x00, 0x8a, 0x2e,
   346  					0x03, 0x70, 0x73, 0x34,
   347  				},
   348  				Scope_id: 90210,
   349  				Conn_id:  0x1234abcd,
   350  			},
   351  		},
   352  	}
   353  
   354  	for _, tt := range tests {
   355  		t.Run(tt.name, func(t *testing.T) {
   356  			out, l, err := tt.sa.sockaddr()
   357  			if err != tt.err {
   358  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   359  			}
   360  
   361  			// Must be 0 on error or a fixed size otherwise.
   362  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrL2TPIP6) {
   363  				t.Fatalf("unexpected Socklen: %d", l)
   364  			}
   365  
   366  			if out != nil {
   367  				raw := (*RawSockaddrL2TPIP6)(out)
   368  				if !reflect.DeepEqual(raw, tt.raw) {
   369  					t.Fatalf("unexpected RawSockaddrL2TPIP6:\n got: %#v\nwant: %#v", raw, tt.raw)
   370  				}
   371  			}
   372  		})
   373  	}
   374  }
   375  
   376  // These helpers explicitly copy the contents of in into out to produce
   377  // the correct sockaddr structure, without relying on unsafe casting to
   378  // a type of a larger size.
   379  func sockaddrTIPCToAny(in RawSockaddrTIPC) *RawSockaddrAny {
   380  	var out RawSockaddrAny
   381  	copy(
   382  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   383  		(*(*[SizeofSockaddrTIPC]byte)(unsafe.Pointer(&in)))[:],
   384  	)
   385  	return &out
   386  }
   387  
   388  func sockaddrL2TPIPToAny(in RawSockaddrL2TPIP) *RawSockaddrAny {
   389  	var out RawSockaddrAny
   390  	copy(
   391  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   392  		(*(*[SizeofSockaddrL2TPIP]byte)(unsafe.Pointer(&in)))[:],
   393  	)
   394  	return &out
   395  }
   396  
   397  func sockaddrL2TPIP6ToAny(in RawSockaddrL2TPIP6) *RawSockaddrAny {
   398  	var out RawSockaddrAny
   399  	copy(
   400  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   401  		(*(*[SizeofSockaddrL2TPIP6]byte)(unsafe.Pointer(&in)))[:],
   402  	)
   403  	return &out
   404  }