From 672225b710815865449e7930255468d1c085b137 Mon Sep 17 00:00:00 2001 From: Ariel Manzur Date: Thu, 20 Oct 2016 07:04:10 -0300 Subject: added windows support for ipv6, cleaned up unix code --- drivers/unix/socket_helpers.h | 66 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 drivers/unix/socket_helpers.h (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h new file mode 100644 index 000000000..622b45c50 --- /dev/null +++ b/drivers/unix/socket_helpers.h @@ -0,0 +1,66 @@ +#ifndef SOCKET_HELPERS_H +#define SOCKET_HELPERS_H + +#include + +// helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this + +static void _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) { + + memset(p_addr, 0, sizeof(struct sockaddr_storage)); + if (p_ip.type == IP_Address::TYPE_IPV6) { + + struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(p_port); + copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16); + + } else { + + struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; + addr4->sin_family = AF_INET; // host byte order + addr4->sin_port = htons(p_port); // short, network byte order + addr4->sin_addr = *((struct in_addr*)&p_ip.field32[0]); + }; +}; + +static void _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP_Address::AddrType p_address_type, const List *p_accepted_hosts) { + + memset(p_addr, 0, sizeof(struct sockaddr_storage)); + if (p_address_type == IP_Address::TYPE_IPV4) { + struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; + addr4->sin_family = AF_INET; + addr4->sin_port = htons(p_port); + addr4->sin_addr.s_addr = INADDR_ANY; // TODO: use accepted hosts list + } else { + struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; + + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(p_port); + addr6->sin6_addr = in6addr_any; // TODO: use accepted hosts list + }; +}; + +static void _set_ip_addr_port(IP_Address& r_ip, int& r_port, struct sockaddr_storage* p_addr) { + + if (p_addr->ss_family == AF_INET) { + r_ip.type = IP_Address::TYPE_IPV4; + + struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; + r_ip.field32[0] = (uint32_t)addr4->sin_addr.s_addr; + + r_port = ntohs(addr4->sin_port); + + } else if (p_addr->ss_family == AF_INET6) { + + r_ip.type = IP_Address::TYPE_IPV6; + + struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; + copymem(&addr6->sin6_addr.s6_addr, r_ip.field8, 16); + + r_port = ntohs(addr6->sin6_port); + }; +}; + + +#endif -- cgit v1.2.3-70-g09d2 From 80e911647c5df21c5b6a06876f1d48e21cd1f5fc Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Sat, 22 Oct 2016 07:23:07 +0200 Subject: Pass correct address size (ipv4,ipv6) to socket connect, bind, sendto The address size passed to network system calls now reflects the the actual IP type (v4 or v6). Fix Windows and OSX ipv6 sockets --- drivers/unix/packet_peer_udp_posix.cpp | 8 ++++---- drivers/unix/socket_helpers.h | 8 ++++++-- drivers/unix/stream_peer_tcp_posix.cpp | 8 ++++---- drivers/unix/tcp_server_posix.cpp | 4 ++-- platform/windows/packet_peer_udp_winsock.cpp | 8 ++++---- platform/windows/stream_peer_winsock.cpp | 8 ++++---- platform/windows/tcp_server_winsock.cpp | 4 ++-- 7 files changed, 26 insertions(+), 22 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index cdc3bfce2..d6fc697c6 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -99,12 +99,12 @@ Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer,int p_buffer_size){ int sock = _get_socket(peer_addr.type); ERR_FAIL_COND_V( sock == -1, FAILED ); struct sockaddr_storage addr; - _set_sockaddr(&addr, peer_addr, peer_port); + size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port); errno = 0; int err; - while ( (err = sendto(sock, p_buffer, p_buffer_size, 0, (struct sockaddr*)&addr, sizeof(addr))) != p_buffer_size) { + while ( (err = sendto(sock, p_buffer, p_buffer_size, 0, (struct sockaddr*)&addr, addr_size)) != p_buffer_size) { if (errno != EAGAIN) { return FAILED; @@ -129,9 +129,9 @@ Error PacketPeerUDPPosix::listen(int p_port, IP_Address::AddrType p_address_type return ERR_CANT_CREATE; sockaddr_storage addr = {0}; - _set_listen_sockaddr(&addr, p_port, p_address_type, NULL); + size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_address_type, NULL); - if (bind(sock, (struct sockaddr*)&addr, sizeof(sockaddr_storage)) == -1 ) { + if (bind(sock, (struct sockaddr*)&addr, addr_size) == -1 ) { close(); return ERR_UNAVAILABLE; } diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 622b45c50..4ee40e3d3 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -5,7 +5,7 @@ // helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this -static void _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) { +static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); if (p_ip.type == IP_Address::TYPE_IPV6) { @@ -14,6 +14,7 @@ static void _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_i addr6->sin6_family = AF_INET6; addr6->sin6_port = htons(p_port); copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16); + return sizeof(sockaddr_in6); } else { @@ -21,10 +22,11 @@ static void _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_i addr4->sin_family = AF_INET; // host byte order addr4->sin_port = htons(p_port); // short, network byte order addr4->sin_addr = *((struct in_addr*)&p_ip.field32[0]); + return sizeof(sockaddr_in); }; }; -static void _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP_Address::AddrType p_address_type, const List *p_accepted_hosts) { +static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP_Address::AddrType p_address_type, const List *p_accepted_hosts) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); if (p_address_type == IP_Address::TYPE_IPV4) { @@ -32,12 +34,14 @@ static void _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP addr4->sin_family = AF_INET; addr4->sin_port = htons(p_port); addr4->sin_addr.s_addr = INADDR_ANY; // TODO: use accepted hosts list + return sizeof(sockaddr_in); } else { struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; addr6->sin6_family = AF_INET6; addr6->sin6_port = htons(p_port); addr6->sin6_addr = in6addr_any; // TODO: use accepted hosts list + return sizeof(sockaddr_in6); }; }; diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 5a63a512e..f2915b0a1 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -98,9 +98,9 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const { }; struct sockaddr_storage their_addr; - _set_sockaddr(&their_addr, peer_host, peer_port); + size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port); - if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(their_addr)) == -1) { + if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == -1) { if (errno == EISCONN) { status = STATUS_CONNECTED; @@ -153,10 +153,10 @@ Error StreamPeerTCPPosix::connect(const IP_Address& p_host, uint16_t p_port) { #endif struct sockaddr_storage their_addr; - _set_sockaddr(&their_addr, p_host, p_port); + size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port); errno = 0; - if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(their_addr)) == -1 && errno != EINPROGRESS) { + if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == -1 && errno != EINPROGRESS) { ERR_PRINT("Connection to remote host failed!"); disconnect(); diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index 27c561847..05b739804 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -87,11 +87,11 @@ Error TCPServerPosix::listen(uint16_t p_port, IP_Address::AddrType p_type, const } struct sockaddr_storage addr; - _set_listen_sockaddr(&addr, p_port, p_type, p_accepted_hosts); + size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_type, p_accepted_hosts); // automatically fill with my IP TODO: use p_accepted_hosts - if (bind(sockfd, (struct sockaddr *)&addr, sizeof addr) != -1) { + if (bind(sockfd, (struct sockaddr *)&addr, addr_size) != -1) { if (::listen(sockfd, 1) == -1) { diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index cd4e85fd8..0408a303f 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -74,13 +74,13 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer,int p_buffer_size int sock = _get_socket(peer_addr.type); ERR_FAIL_COND_V( sock == -1, FAILED ); struct sockaddr_storage addr; - _set_sockaddr(&addr, peer_addr, peer_port); + size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port); _set_blocking(true); errno = 0; int err; - while ( (err = sendto(sock, (const char*)p_buffer, p_buffer_size, 0, (struct sockaddr*)&addr, sizeof(addr))) != p_buffer_size) { + while ( (err = sendto(sock, (const char*)p_buffer, p_buffer_size, 0, (struct sockaddr*)&addr, addr_size)) != p_buffer_size) { if (WSAGetLastError() != WSAEWOULDBLOCK) { return FAILED; @@ -120,9 +120,9 @@ Error PacketPeerUDPWinsock::listen(int p_port, IP_Address::AddrType p_address_ty return ERR_CANT_CREATE; struct sockaddr_storage addr = {0}; - _set_listen_sockaddr(&addr, p_port, p_address_type, NULL); + size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_address_type, NULL); - if (bind(sock, (struct sockaddr*)&addr, sizeof(sockaddr_in)) == -1 ) { + if (bind(sock, (struct sockaddr*)&addr, addr_size) == -1 ) { close(); return ERR_UNAVAILABLE; } diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index cd9cc9902..b511e38ec 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -88,9 +88,9 @@ Error StreamPeerWinsock::_poll_connection(bool p_block) const { }; struct sockaddr_storage their_addr; - _set_sockaddr(&their_addr, peer_host, peer_port); + size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port); - if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) { + if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == SOCKET_ERROR) { int err = WSAGetLastError(); if (err == WSAEISCONN) { @@ -312,9 +312,9 @@ Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) { }; struct sockaddr_storage their_addr; - _set_sockaddr(&their_addr, p_host, p_port); + size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port); - if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) { + if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { ERR_PRINT("Connection to remote host failed!"); diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp index 049e609d6..1aedc52bb 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -77,7 +77,7 @@ Error TCPServerWinsock::listen(uint16_t p_port, IP_Address::AddrType p_type,cons }; struct sockaddr_storage my_addr; - _set_listen_sockaddr(&my_addr, p_port, p_type, p_accepted_hosts); + size_t addr_size = _set_listen_sockaddr(&my_addr, p_port, p_type, p_accepted_hosts); int reuse=1; if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) { @@ -86,7 +86,7 @@ Error TCPServerWinsock::listen(uint16_t p_port, IP_Address::AddrType p_type,cons } - if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) != SOCKET_ERROR) { + if (bind(sockfd, (struct sockaddr *)&my_addr, addr_size) != SOCKET_ERROR) { if (::listen(sockfd, SOMAXCONN) == SOCKET_ERROR) { -- cgit v1.2.3-70-g09d2