fix SocketConnect for IPv6

This commit is contained in:
Adam Higerd 2022-08-07 23:31:42 -05:00 committed by Vicki Pfau
parent 902c7aade4
commit 519968d37e
1 changed files with 38 additions and 13 deletions

View File

@ -39,6 +39,10 @@ typedef SOCKET Socket;
typedef int Socket; typedef int Socket;
#endif #endif
#if !defined(__3DS__) && !defined(GEKKO)
#define HAS_IPV6
#endif
enum IP { enum IP {
IPV4, IPV4,
IPV6 IPV6
@ -152,12 +156,36 @@ static inline int SocketClose(Socket socket) {
#endif #endif
} }
static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress) { static inline void SocketCloseQuiet(Socket socket) {
#ifdef GEKKO int savedErrno = SocketError();
Socket sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); SocketClose(socket);
#ifdef _WIN32
WSASetLastError(savedErrno);
#else #else
Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); errno = savedErrno;
#endif #endif
}
static inline Socket SocketCreate(bool useIPv6, int protocol) {
if (useIPv6) {
#ifdef HAS_IPV6
return socket(AF_INET6, SOCK_STREAM, protocol);
#else
errno = EAFNOSUPPORT;
return INVALID_SOCKET;
#endif
} else {
#ifdef GEKKO
return net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
#else
return socket(AF_INET, SOCK_STREAM, protocol);
#endif
}
}
static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress) {
bool useIPv6 = bindAddress && (bindAddress->version == IPV6);
Socket sock = SocketCreate(useIPv6, IPPROTO_TCP);
if (SOCKET_FAILED(sock)) { if (SOCKET_FAILED(sock)) {
return sock; return sock;
} }
@ -178,7 +206,7 @@ static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress)
#else #else
err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif #endif
} else if (bindAddress->version == IPV4) { } else if (!useIPv6) {
struct sockaddr_in bindInfo; struct sockaddr_in bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo)); memset(&bindInfo, 0, sizeof(bindInfo));
bindInfo.sin_family = AF_INET; bindInfo.sin_family = AF_INET;
@ -200,18 +228,15 @@ static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress)
#endif #endif
} }
if (err) { if (err) {
SocketClose(sock); SocketCloseQuiet(sock);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
return sock; return sock;
} }
static inline Socket SocketConnectTCP(int port, const struct Address* destinationAddress) { static inline Socket SocketConnectTCP(int port, const struct Address* destinationAddress) {
#ifdef GEKKO bool useIPv6 = destinationAddress && (destinationAddress->version == IPV6);
Socket sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); Socket sock = SocketCreate(useIPv6, IPPROTO_TCP);
#else
Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#endif
if (SOCKET_FAILED(sock)) { if (SOCKET_FAILED(sock)) {
return sock; return sock;
} }
@ -238,7 +263,7 @@ static inline Socket SocketConnectTCP(int port, const struct Address* destinatio
#else #else
err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif #endif
#if !defined(__3DS__) && !defined(GEKKO) #ifdef HAS_IPV6
} else { } else {
struct sockaddr_in6 bindInfo; struct sockaddr_in6 bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo)); memset(&bindInfo, 0, sizeof(bindInfo));
@ -250,7 +275,7 @@ static inline Socket SocketConnectTCP(int port, const struct Address* destinatio
} }
if (err) { if (err) {
SocketClose(sock); SocketCloseQuiet(sock);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
return sock; return sock;