| 550 | } |
| 551 | |
| 552 | SOCKET createSocket(Protocol protocol) |
| 553 | { |
| 554 | auto family = protocolToFamily(protocol); |
| 555 | if (protocol == Protocol::any) |
| 556 | { |
| 557 | family = AF_INET6; |
| 558 | } |
| 559 | |
| 560 | auto sock = socket(family, SOCK_DGRAM, IPPROTO_UDP); |
| 561 | if (sock == INVALID_SOCKET) |
| 562 | { |
| 563 | throw SocketException("Unable to create socket."); |
| 564 | } |
| 565 | |
| 566 | // Enable send and receiving of broadcast messages |
| 567 | // if (!setOption(sock, SOL_SOCKET, SO_BROADCAST, true)) |
| 568 | // { |
| 569 | // Console::logVerbose("setsockopt(socket, SO_BROADCAST) failed: %d", LAST_SOCKET_ERROR()); |
| 570 | // } |
| 571 | |
| 572 | if (protocol == Protocol::any) |
| 573 | { |
| 574 | // Turn off IPV6_V6ONLY so we can accept both v4 and v6 connections |
| 575 | // Incoming IPv4 addresses will be mapped to IPv6 addresses |
| 576 | if (!setOption(sock, IPPROTO_IPV6, IPV6_V6ONLY, false)) |
| 577 | { |
| 578 | Logging::warn("setsockopt(socket, IPV6_V6ONLY) failed: {}", LAST_SOCKET_ERROR()); |
| 579 | } |
| 580 | } |
| 581 | else if (protocol == Protocol::ipv6) |
| 582 | { |
| 583 | // Turn on IPV6_V6ONLY so we only accept both v6 connections |
| 584 | if (!setOption(sock, IPPROTO_IPV6, IPV6_V6ONLY, true)) |
| 585 | { |
| 586 | Logging::warn("setsockopt(socket, IPV6_V6ONLY) failed: {}", LAST_SOCKET_ERROR()); |
| 587 | } |
| 588 | } |
| 589 | |
| 590 | if (!setOption(sock, SOL_SOCKET, SO_REUSEADDR, true)) |
| 591 | { |
| 592 | Logging::warn("setsockopt(socket, SO_REUSEADDR) failed: {}", LAST_SOCKET_ERROR()); |
| 593 | } |
| 594 | |
| 595 | if (!setNonBlocking(sock, true)) |
| 596 | { |
| 597 | throw SocketException("Failed to set non-blocking mode."); |
| 598 | } |
| 599 | |
| 600 | return sock; |
| 601 | } |
| 602 | |
| 603 | void closeSocket() |
| 604 | { |
nothing calls this directly
no test coverage detected