mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-10 07:49:57 -04:00
Add support for resolving domains to IPv6 addresses on Windows, also support IPV6 addresses for host component of a URL in HttpClient http backend
This commit is contained in:
parent
fefc2c5ff4
commit
c82ec9e4b9
@ -512,6 +512,21 @@ struct HttpConnection {
|
|||||||
cc_bool valid;
|
cc_bool valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void ExtractHostPort(const struct HttpUrl* url, cc_string* host, cc_string* port) {
|
||||||
|
/* address can have the form of either "host" or "host:port" */
|
||||||
|
/* Slightly more complicated because IPv6 hosts can be e.g. [::1] */
|
||||||
|
cc_string* str = &url->address;
|
||||||
|
int idx = String_LastIndexOf(str, ':');
|
||||||
|
|
||||||
|
if (idx == -1) {
|
||||||
|
*host = *str;
|
||||||
|
*port = String_Empty;
|
||||||
|
} else {
|
||||||
|
*host = String_UNSAFE_Substring(str, 0, idx);
|
||||||
|
*port = String_UNSAFE_SubstringAt(str, idx + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct HttpUrl* url) {
|
static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct HttpUrl* url) {
|
||||||
cc_string host, port;
|
cc_string host, port;
|
||||||
cc_uint16 portNum;
|
cc_uint16 portNum;
|
||||||
@ -519,8 +534,7 @@ static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct H
|
|||||||
cc_sockaddr addrs[SOCKET_MAX_ADDRS];
|
cc_sockaddr addrs[SOCKET_MAX_ADDRS];
|
||||||
int numValidAddrs;
|
int numValidAddrs;
|
||||||
|
|
||||||
/* address can be either "host" or "host:port" */
|
ExtractHostPort(url, &host, &port);
|
||||||
String_UNSAFE_Separate(&url->address, ':', &host, &port);
|
|
||||||
if (!Convert_ParseUInt16(&port, &portNum)) {
|
if (!Convert_ParseUInt16(&port, &portNum)) {
|
||||||
portNum = url->https ? 443 : 80;
|
portNum = url->https ? 443 : 80;
|
||||||
}
|
}
|
||||||
|
@ -416,6 +416,9 @@ static int (WSAAPI *_select)(int nfds, fd_set* readfds, fd_set* writefds, fd_set
|
|||||||
|
|
||||||
static struct hostent* (WSAAPI *_gethostbyname)(const char* name);
|
static struct hostent* (WSAAPI *_gethostbyname)(const char* name);
|
||||||
static unsigned short (WSAAPI *_htons)(u_short hostshort);
|
static unsigned short (WSAAPI *_htons)(u_short hostshort);
|
||||||
|
static int (WSAAPI *_getaddrinfo )(PCSTR nodeName, PCSTR serviceName, const ADDRINFOA* hints, PADDRINFOA* result);
|
||||||
|
static void (WSAAPI* _freeaddrinfo)(PADDRINFOA addrInfo);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static INT WSAAPI FallbackParseAddress(LPWSTR addressString, INT addressFamily, LPVOID protocolInfo, LPVOID address, LPINT addressLength) {
|
static INT WSAAPI FallbackParseAddress(LPWSTR addressString, INT addressFamily, LPVOID protocolInfo, LPVOID address, LPINT addressLength) {
|
||||||
@ -445,6 +448,7 @@ static void LoadWinsockFuncs(void) {
|
|||||||
DynamicLib_Sym(connect), DynamicLib_Sym(shutdown),
|
DynamicLib_Sym(connect), DynamicLib_Sym(shutdown),
|
||||||
DynamicLib_Sym(ioctlsocket), DynamicLib_Sym(getsockopt),
|
DynamicLib_Sym(ioctlsocket), DynamicLib_Sym(getsockopt),
|
||||||
DynamicLib_Sym(gethostbyname), DynamicLib_Sym(htons),
|
DynamicLib_Sym(gethostbyname), DynamicLib_Sym(htons),
|
||||||
|
DynamicLib_Sym(getaddrinfo), DynamicLib_Sym(freeaddrinfo),
|
||||||
DynamicLib_Sym(recv), DynamicLib_Sym(send), DynamicLib_Sym(select)
|
DynamicLib_Sym(recv), DynamicLib_Sym(send), DynamicLib_Sym(select)
|
||||||
};
|
};
|
||||||
static const cc_string winsock1 = String_FromConst("wsock32.DLL");
|
static const cc_string winsock1 = String_FromConst("wsock32.DLL");
|
||||||
@ -459,7 +463,7 @@ static void LoadWinsockFuncs(void) {
|
|||||||
if (!_WSAStringToAddressW) _WSAStringToAddressW = FallbackParseAddress;
|
if (!_WSAStringToAddressW) _WSAStringToAddressW = FallbackParseAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cc_result ParseHost(char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
static cc_result ParseHostOld(char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||||
struct hostent* res;
|
struct hostent* res;
|
||||||
cc_result wsa_res;
|
cc_result wsa_res;
|
||||||
SOCKADDR_IN* addr4;
|
SOCKADDR_IN* addr4;
|
||||||
@ -496,6 +500,44 @@ static cc_result ParseHost(char* host, int port, cc_sockaddr* addrs, int* numVal
|
|||||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cc_result ParseHostNew(char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||||
|
char portRaw[32]; cc_string portStr;
|
||||||
|
struct addrinfo hints = { 0 };
|
||||||
|
struct addrinfo* result;
|
||||||
|
struct addrinfo* cur;
|
||||||
|
int res, i = 0;
|
||||||
|
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
String_InitArray(portStr, portRaw);
|
||||||
|
String_AppendInt(&portStr, port);
|
||||||
|
portRaw[portStr.length] = '\0';
|
||||||
|
|
||||||
|
res = _getaddrinfo(host, portRaw, &hints, &result);
|
||||||
|
if (res == EAI_NONAME) return SOCK_ERR_UNKNOWN_HOST;
|
||||||
|
if (res) return res;
|
||||||
|
|
||||||
|
/* Prefer IPv4 addresses first */
|
||||||
|
for (cur = result; cur && i < SOCKET_MAX_ADDRS; cur = cur->ai_next)
|
||||||
|
{
|
||||||
|
if (cur->ai_family != AF_INET) continue;
|
||||||
|
Mem_Copy(addrs[i].data, cur->ai_addr, cur->ai_addrlen);
|
||||||
|
addrs[i].size = cur->ai_addrlen; i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cur = result; cur && i < SOCKET_MAX_ADDRS; cur = cur->ai_next)
|
||||||
|
{
|
||||||
|
if (cur->ai_family == AF_INET) continue;
|
||||||
|
Mem_Copy(addrs[i].data, cur->ai_addr, cur->ai_addrlen);
|
||||||
|
addrs[i].size = cur->ai_addrlen; i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_freeaddrinfo(result);
|
||||||
|
*numValidAddrs = i;
|
||||||
|
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||||
SOCKADDR_IN* addr4 = (SOCKADDR_IN* )addrs[0].data;
|
SOCKADDR_IN* addr4 = (SOCKADDR_IN* )addrs[0].data;
|
||||||
SOCKADDR_IN6* addr6 = (SOCKADDR_IN6*)addrs[0].data;
|
SOCKADDR_IN6* addr6 = (SOCKADDR_IN6*)addrs[0].data;
|
||||||
@ -523,7 +565,11 @@ cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* a
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseHost(str.ansi, port, addrs, numValidAddrs);
|
if (_getaddrinfo) {
|
||||||
|
return ParseHostNew(str.ansi, port, addrs, numValidAddrs);
|
||||||
|
} else {
|
||||||
|
return ParseHostOld(str.ansi, port, addrs, numValidAddrs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result Socket_Connect(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
cc_result Socket_Connect(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user