mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-08 06:47:23 -04:00
Unify IPv4 address parsing
This commit is contained in:
parent
651d80b27d
commit
cb0b2fb7cf
@ -127,7 +127,7 @@ typedef struct WSAData {
|
||||
CC_WINSOCK_FUNC int (WINAPI *_WSAStartup)(WORD versionRequested, WSADATA* wsaData);
|
||||
CC_WINSOCK_FUNC int (WINAPI *_WSACleanup)(void);
|
||||
CC_WINSOCK_FUNC int (WINAPI *_WSAGetLastError)(void);
|
||||
CC_WINSOCK_FUNC int (WINAPI *_WSAStringToAddressW)(LPWSTR addressString, INT addressFamily, LPVOID protocolInfo, LPVOID address, LPINT addressLength);
|
||||
CC_WINSOCK_FUNC int (WINAPI *_WSAStringToAddressA)(LPSTR addressString, INT addressFamily, LPVOID protocolInfo, LPVOID address, LPINT addressLength);
|
||||
|
||||
CC_WINSOCK_FUNC int (WINAPI *_socket)(int af, int type, int protocol);
|
||||
CC_WINSOCK_FUNC int (WINAPI *_closesocket)(SOCKET s);
|
||||
@ -148,7 +148,7 @@ CC_WINSOCK_FUNC void (WINAPI* _freeaddrinfo)(ADDRINFOA* addrInfo);
|
||||
static void Winsock_LoadDynamicFuncs(void) {
|
||||
static const struct DynamicLibSym funcs[] = {
|
||||
DynamicLib_ReqSym(WSAStartup), DynamicLib_ReqSym(WSACleanup),
|
||||
DynamicLib_ReqSym(WSAGetLastError), DynamicLib_OptSym(WSAStringToAddressW),
|
||||
DynamicLib_ReqSym(WSAGetLastError), DynamicLib_OptSym(WSAStringToAddressA),
|
||||
DynamicLib_ReqSym(socket), DynamicLib_ReqSym(closesocket),
|
||||
DynamicLib_ReqSym(connect), DynamicLib_ReqSym(shutdown),
|
||||
DynamicLib_ReqSym(ioctlsocket), DynamicLib_ReqSym(getsockopt),
|
||||
|
@ -275,26 +275,29 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char str[NATIVE_STR_LEN];
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(const 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 i = 0;
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)addrs[0].data;
|
||||
if (inet_aton(str, &addr4->sin_addr) > 0) {
|
||||
// TODO eliminate this path?
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(*addr4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hints.ai_family = AF_INET; // TODO: you need this, otherwise resolving dl.dropboxusercontent.com crashes in Citra. probably something to do with IPv6 addresses
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
@ -304,7 +307,7 @@ cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* a
|
||||
String_AppendInt(&portStr, port);
|
||||
portRaw[portStr.length] = '\0';
|
||||
|
||||
int res = getaddrinfo(str, portRaw, &hints, &result);
|
||||
int res = getaddrinfo(host, portRaw, &hints, &result);
|
||||
if (res == -NO_DATA) return SOCK_ERR_UNKNOWN_HOST;
|
||||
if (res) return res;
|
||||
|
||||
|
@ -526,17 +526,28 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char str[NATIVE_STR_LEN];
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(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;
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
@ -544,24 +555,12 @@ cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* a
|
||||
String_InitArray(portStr, portRaw);
|
||||
String_AppendInt(&portStr, port);
|
||||
portRaw[portStr.length] = '\0';
|
||||
|
||||
// getaddrinfo IP address resolution was only added in Nov 2023
|
||||
// https://github.com/KallistiOS/KallistiOS/pull/358
|
||||
// So include this special case for backwards compatibility
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)addrs[0].data;
|
||||
if (inet_pton(AF_INET, str, &addr4->sin_addr) > 0) {
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(struct sockaddr_in);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = getaddrinfo(str, portRaw, &hints, &result);
|
||||
int res = getaddrinfo(host, portRaw, &hints, &result);
|
||||
if (res == EAI_NONAME) return SOCK_ERR_UNKNOWN_HOST;
|
||||
if (res) return res;
|
||||
|
||||
int i = 0;
|
||||
for (cur = result; cur && i < SOCKET_MAX_ADDRS; cur = cur->ai_next, i++)
|
||||
{
|
||||
SocketAddr_Set(&addrs[i], cur->ai_addr, cur->ai_addrlen);
|
||||
|
@ -380,7 +380,24 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
#ifdef HW_RVL
|
||||
struct hostent* res = net_gethostbyname(host);
|
||||
struct sockaddr_in* addr4;
|
||||
@ -414,21 +431,6 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
|
||||
return ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 1;
|
||||
if (inet_aton(str, &addr4->sin_addr) > 0) {
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(*addr4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
||||
|
@ -391,12 +391,31 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
*#########################################################################################################################*/
|
||||
static cc_bool net_supported = true;
|
||||
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
|
||||
if (!net_supported) return false; // TODO still accept?
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct hostent* res = gethostbyname(host);
|
||||
struct sockaddr_in* addr4;
|
||||
char* src_addr;
|
||||
int i;
|
||||
|
||||
if (!net_supported) return ERR_NO_NETWORKING;
|
||||
// avoid confusion with SSL error codes
|
||||
// e.g. FFFF FFF7 > FF00 FFF7
|
||||
if (!res) return -0xFF0000 + errno;
|
||||
@ -407,7 +426,7 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
|
||||
|
||||
for (i = 0; i < SOCKET_MAX_ADDRS; i++)
|
||||
{
|
||||
src_addr = res->h_addr_list[i];
|
||||
char* src_addr = res->h_addr_list[i];
|
||||
if (!src_addr) break;
|
||||
addrs[i].size = sizeof(struct sockaddr_in);
|
||||
|
||||
@ -421,25 +440,6 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
|
||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||
}
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
String_EncodeUtf8(str, address);
|
||||
|
||||
if (!net_supported) return ERR_NO_NETWORKING;
|
||||
*numValidAddrs = 1;
|
||||
|
||||
if (inet_aton(str, &addr4->sin_addr) > 0) {
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(*addr4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
||||
if (!net_supported) { *s = -1; return ERR_NO_NETWORKING; }
|
||||
|
@ -488,20 +488,35 @@ static void Networking_LoadIOPModules(void) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
int lwip_shutdown(int s, int how);
|
||||
int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
|
||||
int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
|
||||
int lwip_close(int s);
|
||||
int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
|
||||
int lwip_recv(int s, void *mem, size_t len, int flags);
|
||||
int lwip_send(int s, const void *dataptr, size_t size, int flags);
|
||||
int lwip_socket(int domain, int type, int protocol);
|
||||
int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout);
|
||||
int lwip_ioctl(int s, long cmd, void *argp);
|
||||
|
||||
int lwip_shutdown(int s, int how);
|
||||
int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
|
||||
int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
|
||||
int lwip_close(int s);
|
||||
int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
|
||||
int lwip_recv(int s, void *mem, size_t len, int flags);
|
||||
int lwip_send(int s, const void *dataptr, size_t size, int flags);
|
||||
int lwip_socket(int domain, int type, int protocol);
|
||||
int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout);
|
||||
int lwip_ioctl(int s, long cmd, void *argp);
|
||||
int netconn_gethostbyname(const char *name, ip4_addr_t *addr);
|
||||
|
||||
int ip4addr_aton(const char *cp, ip4_addr_t *addr);
|
||||
int netconn_gethostbyname(const char *name, ip4_addr_t *addr);
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)addrs[0].data;
|
||||
@ -520,25 +535,6 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
|
||||
return 0;
|
||||
}
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
|
||||
if (ip4addr_aton(str, (ip4_addr_t*)&addr4->sin_addr) > 0) {
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(*addr4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
static cc_result GetSocketError(cc_socket s) {
|
||||
socklen_t resultSize = sizeof(socklen_t);
|
||||
cc_result res = 0;
|
||||
|
@ -335,10 +335,23 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
union SocketAddress {
|
||||
struct sockaddr raw;
|
||||
struct sockaddr_in v4;
|
||||
};
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct net_hostent* res = netGetHostByName(host);
|
||||
struct sockaddr_in* addr4;
|
||||
@ -350,41 +363,24 @@ static cc_result ParseHost(char* host, int port, cc_sockaddr* addrs, int* numVal
|
||||
|
||||
// each address pointer is only 4 bytes long
|
||||
u32* addr_list = (u32*)res->h_addr_list;
|
||||
char* src_addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SOCKET_MAX_ADDRS; i++)
|
||||
{
|
||||
src_addr = (char*)addr_list[i];
|
||||
char* src_addr = (char*)addr_list[i];
|
||||
if (!src_addr) break;
|
||||
addrs[i].size = sizeof(struct sockaddr_in);
|
||||
|
||||
addr4 = (struct sockaddr_in*)addrs[i].data;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
addr4->sin_addr = *(struct in_addr*)src_addr;
|
||||
}
|
||||
|
||||
*numValidAddrs = i;
|
||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||
}
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
|
||||
if (inet_aton(str, &addr4->sin_addr) > 0) {
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(*addr4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
||||
|
||||
|
@ -387,15 +387,36 @@ void Platform_LoadSysFonts(void) { }
|
||||
union SocketAddress {
|
||||
struct sockaddr raw;
|
||||
struct sockaddr_in v4;
|
||||
#ifdef AF_INET6
|
||||
struct sockaddr_in6 v6;
|
||||
struct sockaddr_storage total;
|
||||
#endif
|
||||
};
|
||||
/* Sanity check to ensure cc_sockaddr struct is large enough to contain all socket addresses supported by this platform */
|
||||
static char sockaddr_size_check[sizeof(union SocketAddress) < CC_SOCKETADDR_MAXSIZE ? 1 : -1];
|
||||
|
||||
#if SUPPORTS_GETADDRINFO
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
union SocketAddress* addr = (union SocketAddress*)dst->data;
|
||||
if (inet_pton(AF_INET6, ip, &addr->v6.sin6_addr) <= 0) return false;
|
||||
|
||||
addr->v6.sin6_family = AF_INET6;
|
||||
addr->v6.sin6_port = htons(port);
|
||||
|
||||
dst->size = sizeof(addr->v6);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char portRaw[32]; cc_string portStr;
|
||||
struct addrinfo hints = { 0 };
|
||||
@ -431,63 +452,6 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
|
||||
*numValidAddrs = i;
|
||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||
}
|
||||
#else
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct hostent* res = gethostbyname(host);
|
||||
struct sockaddr_in* addr4;
|
||||
char* src_addr;
|
||||
int i;
|
||||
|
||||
// Must have at least one IPv4 address
|
||||
if (res->h_addrtype != AF_INET) return ERR_INVALID_ARGUMENT;
|
||||
if (!res->h_addr_list) return ERR_INVALID_ARGUMENT;
|
||||
|
||||
for (i = 0; i < SOCKET_MAX_ADDRS; i++)
|
||||
{
|
||||
src_addr = res->h_addr_list[i];
|
||||
if (!src_addr) break;
|
||||
addrs[i].size = sizeof(struct sockaddr_in);
|
||||
|
||||
addr4 = (struct sockaddr_in*)addrs[i].data;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
addr4->sin_addr = *(struct in_addr*)src_addr;
|
||||
}
|
||||
|
||||
*numValidAddrs = i;
|
||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
union SocketAddress* addr = (union SocketAddress*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
|
||||
if (inet_pton(AF_INET, str, &addr->v4.sin_addr) > 0) {
|
||||
addr->v4.sin_family = AF_INET;
|
||||
addr->v4.sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(addr->v4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef AF_INET6
|
||||
if (inet_pton(AF_INET6, str, &addr->v6.sin6_addr) > 0) {
|
||||
addr->v6.sin6_family = AF_INET6;
|
||||
addr->v6.sin6_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(addr->v6);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
||||
|
@ -298,29 +298,41 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
char buf[1024];
|
||||
int rid, ret;
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 1;
|
||||
int rid;
|
||||
|
||||
if (sceNetInetInetPton(AF_INET, str, &addr4->sin_addr) <= 0) {
|
||||
/* Fallback to resolving as DNS name */
|
||||
if (sceNetResolverCreate(&rid, buf, sizeof(buf)) < 0)
|
||||
return ERR_INVALID_ARGUMENT;
|
||||
/* Fallback to resolving as DNS name */
|
||||
if (sceNetResolverCreate(&rid, buf, sizeof(buf)) < 0)
|
||||
return ERR_INVALID_ARGUMENT;
|
||||
|
||||
ret = sceNetResolverStartNtoA(rid, str, &addr4->sin_addr, 1 /* timeout */, 5 /* retries */);
|
||||
sceNetResolverDelete(rid);
|
||||
if (ret < 0) return ret;
|
||||
}
|
||||
int ret = sceNetResolverStartNtoA(rid, host, &addr4->sin_addr, 1 /* timeout */, 5 /* retries */);
|
||||
sceNetResolverDelete(rid);
|
||||
if (ret < 0) return ret;
|
||||
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(*addr4);
|
||||
addrs[0].size = sizeof(*addr4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -281,29 +281,40 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct SceNetSockaddrIn* addr4 = (struct SceNetSockaddrIn*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = SCE_NET_AF_INET;
|
||||
addr4->sin_port = sceNetHtons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct SceNetSockaddrIn* addr4 = (struct SceNetSockaddrIn*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
char buf[1024];
|
||||
int rid, ret;
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 1;
|
||||
/* Fallback to resolving as DNS name */
|
||||
int rid = sceNetResolverCreate("CC resolver", NULL, 0);
|
||||
if (rid < 0) return ERR_INVALID_ARGUMENT;
|
||||
|
||||
if (sceNetInetPton(SCE_NET_AF_INET, str, &addr4->sin_addr) <= 0) {
|
||||
/* Fallback to resolving as DNS name */
|
||||
rid = sceNetResolverCreate("CC resolver", NULL, 0);
|
||||
if (rid < 0) return ERR_INVALID_ARGUMENT;
|
||||
|
||||
ret = sceNetResolverStartNtoa(rid, str, &addr4->sin_addr, 0, 0, 0);
|
||||
sceNetResolverDestroy(rid);
|
||||
if (ret) return ret;
|
||||
}
|
||||
int ret = sceNetResolverStartNtoa(rid, host, &addr4->sin_addr, 0, 0, 0);
|
||||
sceNetResolverDestroy(rid);
|
||||
if (ret) return ret;
|
||||
|
||||
addr4->sin_family = SCE_NET_AF_INET;
|
||||
addr4->sin_port = sceNetHtons(port);
|
||||
|
||||
addrs[0].size = sizeof(*addr4);
|
||||
addrs[0].size = sizeof(*addr4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -667,6 +667,36 @@ union SocketAddress {
|
||||
/* Sanity check to ensure cc_sockaddr struct is large enough to contain all socket addresses supported by this platform */
|
||||
static char sockaddr_size_check[sizeof(union SocketAddress) < CC_SOCKETADDR_MAXSIZE ? 1 : -1];
|
||||
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef AF_INET6
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
union SocketAddress* addr = (union SocketAddress*)dst->data;
|
||||
if (inet_pton(AF_INET6, ip, &addr->v6.sin6_addr) <= 0) return false;
|
||||
|
||||
addr->v6.sin6_family = AF_INET6;
|
||||
addr->v6.sin6_port = htons(port);
|
||||
|
||||
dst->size = sizeof(addr->v6);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SUPPORTS_GETADDRINFO
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char portRaw[32]; cc_string portStr;
|
||||
@ -731,36 +761,6 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
|
||||
}
|
||||
#endif
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
union SocketAddress* addr = (union SocketAddress*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
|
||||
if (inet_pton(AF_INET, str, &addr->v4.sin_addr) > 0) {
|
||||
addr->v4.sin_family = AF_INET;
|
||||
addr->v4.sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(addr->v4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef AF_INET6
|
||||
if (inet_pton(AF_INET6, str, &addr->v6.sin6_addr) > 0) {
|
||||
addr->v6.sin6_family = AF_INET6;
|
||||
addr->v6.sin6_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(addr->v6);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
||||
|
||||
|
@ -367,6 +367,30 @@ union SocketAddress {
|
||||
struct sockaddr_storage total;
|
||||
};
|
||||
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
union SocketAddress* addr = (union SocketAddress*)dst->data;
|
||||
if (inet_pton(AF_INET6, ip, &addr->v6.sin6_addr) <= 0) return false;
|
||||
|
||||
addr->v6.sin6_family = AF_INET6;
|
||||
addr->v6.sin6_port = htons(port);
|
||||
|
||||
dst->size = sizeof(addr->v6);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char portRaw[32]; cc_string portStr;
|
||||
struct addrinfo hints = { 0 };
|
||||
@ -403,34 +427,6 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
|
||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||
}
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
union SocketAddress* addr = (union SocketAddress*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
|
||||
if (inet_pton(AF_INET, str, &addr->v4.sin_addr) > 0) {
|
||||
addr->v4.sin_family = AF_INET;
|
||||
addr->v4.sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(addr->v4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET6, str, &addr->v6.sin6_addr) > 0) {
|
||||
addr->v6.sin6_family = AF_INET6;
|
||||
addr->v6.sin6_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(addr->v6);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
||||
|
||||
|
@ -417,12 +417,22 @@ void Platform_LoadSysFonts(void) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
union SocketAddress {
|
||||
struct sockaddr raw;
|
||||
struct sockaddr_in v4;
|
||||
};
|
||||
/* Sanity check to ensure cc_sockaddr struct is large enough to contain all socket addresses supported by this platform */
|
||||
static char sockaddr_size_check[sizeof(union SocketAddress) < CC_SOCKETADDR_MAXSIZE ? 1 : -1];
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if SUPPORTS_GETADDRINFO
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
@ -488,25 +498,6 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
|
||||
}
|
||||
#endif
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
union SocketAddress* addr = (union SocketAddress*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
|
||||
if (inet_pton(AF_INET, str, &addr->v4.sin_addr) > 0) {
|
||||
addr->v4.sin_family = AF_INET;
|
||||
addr->v4.sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(addr->v4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
||||
|
||||
|
@ -313,6 +313,23 @@ union SocketAddress {
|
||||
struct sockaddr_storage total;
|
||||
};
|
||||
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char portRaw[32]; cc_string portStr;
|
||||
struct addrinfo hints = { 0 };
|
||||
@ -350,24 +367,6 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
|
||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||
}
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
union SocketAddress* addr = (union SocketAddress*)addrs[0].data;
|
||||
char str[NATIVE_STR_LEN];
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
|
||||
if (inet_pton(AF_INET, str, &addr->v4.sin_addr) > 0) {
|
||||
addr->v4.sin_family = AF_INET;
|
||||
addr->v4.sin_port = htons(port);
|
||||
|
||||
addrs[0].size = sizeof(addr->v4);
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
||||
|
||||
|
@ -545,27 +545,36 @@ void Platform_LoadSysFonts(void) {
|
||||
/* Sanity check to ensure cc_sockaddr struct is large enough to contain all socket addresses supported by this platform */
|
||||
static char sockaddr_size_check[sizeof(SOCKADDR_STORAGE) < CC_SOCKETADDR_MAXSIZE ? 1 : -1];
|
||||
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
SOCKADDR_IN* addr4 = (SOCKADDR_IN*)dst->data;
|
||||
cc_uint32 ip_addr;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
static INT WINAPI FallbackParseAddress(LPWSTR addressString, INT addressFamily, LPVOID protocolInfo, LPVOID address, LPINT addressLength) {
|
||||
SOCKADDR_IN* addr4 = (SOCKADDR_IN*)address;
|
||||
cc_uint8* addr = (cc_uint8*)&addr4->sin_addr;
|
||||
cc_string ip, parts[4 + 1];
|
||||
cc_winstring* addrStr = (cc_winstring*)addressString;
|
||||
|
||||
ip = String_FromReadonly(addrStr->ansi);
|
||||
/* 4+1 in case user tries '1.1.1.1.1' */
|
||||
if (String_UNSAFE_Split(&ip, '.', parts, 4 + 1) != 4)
|
||||
return ERR_INVALID_ARGUMENT;
|
||||
|
||||
if (!Convert_ParseUInt8(&parts[0], &addr[0]) || !Convert_ParseUInt8(&parts[1], &addr[1]) ||
|
||||
!Convert_ParseUInt8(&parts[2], &addr[2]) || !Convert_ParseUInt8(&parts[3], &addr[3]))
|
||||
return ERR_INVALID_ARGUMENT;
|
||||
|
||||
addr4->sin_family = AF_INET;
|
||||
return 0;
|
||||
addr4->sin_addr.S_un.S_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = _htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_result ParseHostOld(char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
#ifdef AF_INET6
|
||||
SOCKADDR_IN6* addr6 = (SOCKADDR_IN6*)dst->data;
|
||||
INT size = sizeof(*addr6);
|
||||
if (!_WSAStringToAddressA) return false;
|
||||
|
||||
if (!_WSAStringToAddressA(ip, AF_INET6, NULL, addr6, &size)) {
|
||||
addr6->sin6_port = _htons(port);
|
||||
|
||||
dst->size = size;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHostOld(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
struct hostent* res;
|
||||
cc_result wsa_res;
|
||||
SOCKADDR_IN* addr4;
|
||||
@ -602,7 +611,7 @@ static cc_result ParseHostOld(char* host, int port, cc_sockaddr* addrs, int* num
|
||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||
}
|
||||
|
||||
static cc_result ParseHostNew(char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
static cc_result ParseHostNew(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char portRaw[32]; cc_string portStr;
|
||||
struct addrinfo hints = { 0 };
|
||||
struct addrinfo* result;
|
||||
@ -638,39 +647,11 @@ static cc_result ParseHostNew(char* host, int port, cc_sockaddr* addrs, int* num
|
||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||
}
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
SOCKADDR_IN* addr4 = (SOCKADDR_IN* )addrs[0].data;
|
||||
SOCKADDR_IN6* addr6 = (SOCKADDR_IN6*)addrs[0].data;
|
||||
cc_winstring str;
|
||||
INT size;
|
||||
|
||||
*numValidAddrs = 0;
|
||||
Platform_EncodeString(&str, address);
|
||||
|
||||
size = sizeof(*addr4);
|
||||
if (!_WSAStringToAddressW(str.uni, AF_INET, NULL, addr4, &size)) {
|
||||
addr4->sin_port = _htons(port);
|
||||
|
||||
addrs[0].size = size;
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef AF_INET6
|
||||
size = sizeof(*addr6);
|
||||
if (!_WSAStringToAddressW(str.uni, AF_INET6, NULL, addr6, &size)) {
|
||||
addr6->sin6_port = _htons(port);
|
||||
|
||||
addrs[0].size = size;
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
if (_getaddrinfo) {
|
||||
return ParseHostNew(str.ansi, port, addrs, numValidAddrs);
|
||||
return ParseHostNew(host, port, addrs, numValidAddrs);
|
||||
} else {
|
||||
return ParseHostOld(str.ansi, port, addrs, numValidAddrs);
|
||||
return ParseHostOld(host, port, addrs, numValidAddrs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1040,9 +1021,7 @@ void Platform_Init(void) {
|
||||
if (conHandle == INVALID_HANDLE_VALUE) conHandle = NULL;
|
||||
|
||||
Winsock_LoadDynamicFuncs();
|
||||
/* Fallback for older OS versions which lack WSAStringToAddressW */
|
||||
if (!_WSAStringToAddressW) _WSAStringToAddressW = FallbackParseAddress;
|
||||
|
||||
|
||||
res = _WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (res) Logger_SysWarn(res, "starting WSA");
|
||||
}
|
||||
|
@ -314,16 +314,29 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char str[NATIVE_STR_LEN];
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst) {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)dst->data;
|
||||
cc_uint32 ip_addr = 0;
|
||||
if (!ParseIPv4Address(ip, &ip_addr)) return false;
|
||||
|
||||
addr4->sin_addr.s_addr = ip_addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
dst->size = sizeof(*addr4);
|
||||
return true;
|
||||
}
|
||||
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cc_result ParseHost(const 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 i = 0;
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
*numValidAddrs = 0;
|
||||
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
@ -332,7 +345,7 @@ cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* a
|
||||
String_AppendInt(&portStr, port);
|
||||
portRaw[portStr.length] = '\0';
|
||||
|
||||
int res = lwip_getaddrinfo(str, portRaw, &hints, &result);
|
||||
int res = lwip_getaddrinfo(host, portRaw, &hints, &result);
|
||||
if (res == EAI_FAIL) return SOCK_ERR_UNKNOWN_HOST;
|
||||
if (res) return res;
|
||||
|
||||
|
@ -285,3 +285,54 @@ cc_result Platform_Decrypt(const void* data, int len, cc_string* dst) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#ifdef CC_BUILD_NETWORKING
|
||||
/* Parses IPv4 addresses in the form a.b.c.d */
|
||||
static CC_INLINE cc_bool ParseIPv4Address(const cc_string* addr, cc_uint32* ip) {
|
||||
cc_string parts[5];
|
||||
int i;
|
||||
|
||||
union ipv4_addr_raw {
|
||||
cc_uint8 bytes[4];
|
||||
cc_uint32 value;
|
||||
} raw;
|
||||
|
||||
/* 4+1 in case user tries '1.1.1.1.1' */
|
||||
if (String_UNSAFE_Split(addr, '.', parts, 4 + 1) != 4) return false;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (!Convert_ParseUInt8(&parts[i], &raw.bytes[i])) return false;
|
||||
}
|
||||
|
||||
*ip = raw.value;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static cc_bool ParseIPv4(const cc_string* ip, int port, cc_sockaddr* dst);
|
||||
static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst);
|
||||
static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int* numValidAddrs);
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char str[NATIVE_STR_LEN];
|
||||
|
||||
if (ParseIPv4(address, port, &addrs[0])) {
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
String_EncodeUtf8(str, address);
|
||||
if (ParseIPv6(str, port, &addrs[0])) {
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*numValidAddrs = 0;
|
||||
return ParseHost(str, port, addrs, numValidAddrs);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user