Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) { ERR_FAIL_COND_V(is_open(), ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(ip_type > IP::TYPE_ANY || ip_type < IP::TYPE_NONE, ERR_INVALID_PARAMETER); #if defined(__OpenBSD__) // OpenBSD does not support dual stacking, fallback to IPv4 only. if (ip_type == IP::TYPE_ANY) ip_type = IP::TYPE_IPV4; #endif int family = ip_type == IP::TYPE_IPV4 ? AF_INET : AF_INET6; int protocol = p_sock_type == TYPE_TCP ? IPPROTO_TCP : IPPROTO_UDP; int type = p_sock_type == TYPE_TCP ? SOCK_STREAM : SOCK_DGRAM; _sock = socket(family, type, protocol); if (_sock == SOCK_EMPTY && ip_type == IP::TYPE_ANY) { // Careful here, changing the referenced parameter so the caller knows that we are using an IPv4 socket // in place of a dual stack one, and further calls to _set_sock_addr will work as expected. ip_type = IP::TYPE_IPV4; family = AF_INET; _sock = socket(family, type, protocol); } ERR_FAIL_COND_V(_sock == SOCK_EMPTY, FAILED); _ip_type = ip_type; if (family == AF_INET6) { // Select IPv4 over IPv6 mapping set_ipv6_only_enabled(ip_type != IP::TYPE_ANY); } if (protocol == IPPROTO_UDP && ip_type != IP::TYPE_IPV6) { // Enable broadcasting for UDP sockets if it's not IPv6 only (IPv6 has no broadcast option). set_broadcasting_enabled(true); } _is_stream = p_sock_type == TYPE_TCP; #if defined(WINDOWS_ENABLED) if (!_is_stream) { // Disable windows feature/bug reporting WSAECONNRESET/WSAENETRESET when // recv/recvfrom and an ICMP reply was received from a previous send/sendto. unsigned long disable = 0; if (ioctlsocket(_sock, SIO_UDP_CONNRESET, &disable) == SOCKET_ERROR) { print_verbose("Unable to turn off UDP WSAECONNRESET behaviour on Windows"); } if (ioctlsocket(_sock, SIO_UDP_NETRESET, &disable) == SOCKET_ERROR) { // This feature seems not to be supported on wine. print_verbose("Unable to turn off UDP WSAENETRESET behaviour on Windows"); } } #endif return OK; }
Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) { ERR_FAIL_COND_V(is_open(), ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(ip_type > IP::TYPE_ANY || ip_type < IP::TYPE_NONE, ERR_INVALID_PARAMETER); #if defined(__OpenBSD__) // OpenBSD does not support dual stacking, fallback to IPv4 only. if (ip_type == IP::TYPE_ANY) ip_type = IP::TYPE_IPV4; #endif int family = ip_type == IP::TYPE_IPV4 ? AF_INET : AF_INET6; int protocol = p_sock_type == TYPE_TCP ? IPPROTO_TCP : IPPROTO_UDP; int type = p_sock_type == TYPE_TCP ? SOCK_STREAM : SOCK_DGRAM; _sock = socket(family, type, protocol); if (_sock == SOCK_EMPTY && ip_type == IP::TYPE_ANY) { // Careful here, changing the referenced parameter so the caller knows that we are using an IPv4 socket // in place of a dual stack one, and further calls to _set_sock_addr will work as expected. ip_type = IP::TYPE_IPV4; family = AF_INET; _sock = socket(family, type, protocol); } ERR_FAIL_COND_V(_sock == SOCK_EMPTY, FAILED); _ip_type = ip_type; if (family == AF_INET6) { // Select IPv4 over IPv6 mapping set_ipv6_only_enabled(ip_type != IP::TYPE_ANY); } if (protocol == IPPROTO_UDP && ip_type != IP::TYPE_IPV6) { // Enable broadcasting for UDP sockets if it's not IPv6 only (IPv6 has no broadcast option). set_broadcasting_enabled(true); } _is_stream = p_sock_type == TYPE_TCP; return OK; }