| 520 | } |
| 521 | |
| 522 | std::unique_ptr<Sock> CreateSockOS(int domain, int type, int protocol) |
| 523 | { |
| 524 | // Not IPv4, IPv6 or UNIX |
| 525 | if (domain == AF_UNSPEC) return nullptr; |
| 526 | |
| 527 | // Create a socket in the specified address family. |
| 528 | SOCKET hSocket = socket(domain, type, protocol); |
| 529 | if (hSocket == INVALID_SOCKET) { |
| 530 | return nullptr; |
| 531 | } |
| 532 | |
| 533 | auto sock = std::make_unique<Sock>(hSocket); |
| 534 | |
| 535 | if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNIX) { |
| 536 | return sock; |
| 537 | } |
| 538 | |
| 539 | // Ensure that waiting for I/O on this socket won't result in undefined |
| 540 | // behavior. |
| 541 | if (!sock->IsSelectable()) { |
| 542 | LogInfo("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n"); |
| 543 | return nullptr; |
| 544 | } |
| 545 | |
| 546 | #ifdef SO_NOSIGPIPE |
| 547 | int set = 1; |
| 548 | // Set the no-sigpipe option on the socket for BSD systems, other UNIXes |
| 549 | // should use the MSG_NOSIGNAL flag for every send. |
| 550 | if (sock->SetSockOpt(SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(int)) == SOCKET_ERROR) { |
| 551 | LogInfo("Error setting SO_NOSIGPIPE on socket: %s, continuing anyway\n", |
| 552 | NetworkErrorString(WSAGetLastError())); |
| 553 | } |
| 554 | #endif |
| 555 | |
| 556 | // Set the non-blocking option on the socket. |
| 557 | if (!sock->SetNonBlocking()) { |
| 558 | LogInfo("Error setting socket to non-blocking: %s\n", NetworkErrorString(WSAGetLastError())); |
| 559 | return nullptr; |
| 560 | } |
| 561 | |
| 562 | #ifdef HAVE_SOCKADDR_UN |
| 563 | if (domain == AF_UNIX) return sock; |
| 564 | #endif |
| 565 | |
| 566 | if (protocol == IPPROTO_TCP) { |
| 567 | // Set the no-delay option (disable Nagle's algorithm) on the TCP socket. |
| 568 | const int on{1}; |
| 569 | if (sock->SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == SOCKET_ERROR) { |
| 570 | LogDebug(BCLog::NET, "Unable to set TCP_NODELAY on a newly created socket, continuing anyway\n"); |
| 571 | } |
| 572 | } |
| 573 | |
| 574 | return sock; |
| 575 | } |
| 576 | |
| 577 | std::function<std::unique_ptr<Sock>(int, int, int)> CreateSock = CreateSockOS; |
| 578 |
nothing calls this directly
no test coverage detected