(bufs [][]byte, endpoint Endpoint)
| 339 | } |
| 340 | |
| 341 | func (s *StdNetBind) Send(bufs [][]byte, endpoint Endpoint) error { |
| 342 | s.mu.Lock() |
| 343 | blackhole := s.blackhole4 |
| 344 | conn := s.ipv4 |
| 345 | offload := s.ipv4TxOffload |
| 346 | br := batchWriter(s.ipv4PC) |
| 347 | is6 := false |
| 348 | if endpoint.DstIP().Is6() { |
| 349 | blackhole = s.blackhole6 |
| 350 | conn = s.ipv6 |
| 351 | br = s.ipv6PC |
| 352 | is6 = true |
| 353 | offload = s.ipv6TxOffload |
| 354 | } |
| 355 | s.mu.Unlock() |
| 356 | |
| 357 | if blackhole { |
| 358 | return nil |
| 359 | } |
| 360 | if conn == nil { |
| 361 | return syscall.EAFNOSUPPORT |
| 362 | } |
| 363 | |
| 364 | msgs := s.getMessages() |
| 365 | defer s.putMessages(msgs) |
| 366 | ua := s.udpAddrPool.Get().(*net.UDPAddr) |
| 367 | defer s.udpAddrPool.Put(ua) |
| 368 | if is6 { |
| 369 | as16 := endpoint.DstIP().As16() |
| 370 | copy(ua.IP, as16[:]) |
| 371 | ua.IP = ua.IP[:16] |
| 372 | } else { |
| 373 | as4 := endpoint.DstIP().As4() |
| 374 | copy(ua.IP, as4[:]) |
| 375 | ua.IP = ua.IP[:4] |
| 376 | } |
| 377 | ua.Port = int(endpoint.(*StdNetEndpoint).Port()) |
| 378 | var ( |
| 379 | retried bool |
| 380 | err error |
| 381 | ) |
| 382 | retry: |
| 383 | if offload { |
| 384 | n := coalesceMessages(ua, endpoint.(*StdNetEndpoint), bufs, *msgs, setGSOSize) |
| 385 | err = s.send(conn, br, (*msgs)[:n]) |
| 386 | if err != nil && offload && errShouldDisableUDPGSO(err) { |
| 387 | offload = false |
| 388 | s.mu.Lock() |
| 389 | if is6 { |
| 390 | s.ipv6TxOffload = false |
| 391 | } else { |
| 392 | s.ipv4TxOffload = false |
| 393 | } |
| 394 | s.mu.Unlock() |
| 395 | retried = true |
| 396 | goto retry |
| 397 | } |
| 398 | } else { |
nothing calls this directly
no test coverage detected