diff --git a/include/SDL3_net/SDL_net.h b/include/SDL3_net/SDL_net.h index eefc96a..09ea6d6 100644 --- a/include/SDL3_net/SDL_net.h +++ b/include/SDL3_net/SDL_net.h @@ -61,6 +61,15 @@ extern "C" { (SDL_NET_MAJOR_VERSION > X || SDL_NET_MINOR_VERSION >= Y) && \ (SDL_NET_MAJOR_VERSION > X || SDL_NET_MINOR_VERSION > Y || SDL_NET_MICRO_VERSION >= Z)) +/** + * A variable setting the default IP value to "IPv4" or "IPv6" + * + * This hint should be set before creating a socket bound to a NULL address + * and before resolving a hostname. + * + * \since This hint is available since SDL_net 3.0.0 + */ +#define SDL_NET_HINT_IP_DEFAULT_VERSION "SDL_NET_HINT_IP_DEFAULT_VERSION" /** * This function gets the version of the dynamically linked SDL_net library. diff --git a/src/SDL_net.c b/src/SDL_net.c index 8d1bf36..a95de06 100644 --- a/src/SDL_net.c +++ b/src/SDL_net.c @@ -160,7 +160,7 @@ static char *CreateSocketErrorString(int rc) MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ msgbuf, SDL_arraysize(msgbuf), - NULL + NULL ); if (bw == 0) { return SDL_strdup("Unknown error"); @@ -220,8 +220,23 @@ static int ResolveAddress(SDLNet_Address *addr) struct addrinfo *ainfo = NULL; int rc; + struct addrinfo hints, *phints = &hints; + SDL_zero(hints); + + const char *hint = SDL_GetHint(SDL_NET_HINT_IP_DEFAULT_VERSION); + if (hint) { + if (SDL_strcasecmp(hint, "ipv4") == 0) { + hints.ai_family = AF_INET; + } else if (SDL_strcasecmp(hint, "ipv6") == 0) { + hints.ai_family = AF_INET6; + hints.ai_flags = AI_V4MAPPED; + } + } else { + phints = NULL; + } + //SDL_Log("getaddrinfo '%s'", addr->hostname); - rc = getaddrinfo(addr->hostname, NULL, NULL, &ainfo); + rc = getaddrinfo(addr->hostname, NULL, phints, &ainfo); //SDL_Log("rc=%d", rc); if (rc != 0) { addr->errstr = CreateGetAddrInfoErrorString(rc); @@ -279,7 +294,7 @@ static int SDLCALL ResolverThread(void *data) int outcome; if (!simulated_loss || (RandomNumberBetween(0, 100) > simulated_loss)) { - outcome = ResolveAddress(addr); + outcome = ResolveAddress(addr); } else { outcome = -1; addr->errstr = SDL_strdup("simulated failure"); @@ -779,6 +794,16 @@ static struct addrinfo *MakeAddrInfoWithPort(const SDLNet_Address *addr, const i //hints.ai_protocol = ainfo ? ainfo->ai_protocol : 0; hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | (!ainfo ? AI_PASSIVE : 0); + const char *hint = SDL_GetHint(SDL_NET_HINT_IP_DEFAULT_VERSION); + if (!addr && hint) { + if (SDL_strcasecmp(hint, "ipv4") == 0) { + hints.ai_family = AF_INET; + } else if (SDL_strcasecmp(hint, "ipv6") == 0) { + hints.ai_family = AF_INET6; + hints.ai_flags |= AI_V4MAPPED; + } + } + char service[16]; SDL_snprintf(service, sizeof (service), "%d", (int) port);