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 }