Browse Source

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
Fabio Alessandrelli 8 years ago
parent
commit
80e911647c

+ 4 - 4
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);
 	int sock = _get_socket(peer_addr.type);
 	ERR_FAIL_COND_V( sock == -1, FAILED );
 	ERR_FAIL_COND_V( sock == -1, FAILED );
 	struct sockaddr_storage addr;
 	struct sockaddr_storage addr;
-	_set_sockaddr(&addr, peer_addr, peer_port);
+	size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port);
 
 
 	errno = 0;
 	errno = 0;
 	int err;
 	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) {
 		if (errno != EAGAIN) {
 			return FAILED;
 			return FAILED;
@@ -129,9 +129,9 @@ Error PacketPeerUDPPosix::listen(int p_port, IP_Address::AddrType p_address_type
 		return ERR_CANT_CREATE;
 		return ERR_CANT_CREATE;
 
 
 	sockaddr_storage addr = {0};
 	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();
 		close();
 		return ERR_UNAVAILABLE;
 		return ERR_UNAVAILABLE;
 	}
 	}

+ 6 - 2
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
 // 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));
 	memset(p_addr, 0, sizeof(struct sockaddr_storage));
 	if (p_ip.type == IP_Address::TYPE_IPV6) {
 	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_family = AF_INET6;
 		addr6->sin6_port = htons(p_port);
 		addr6->sin6_port = htons(p_port);
 		copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16);
 		copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16);
+		return sizeof(sockaddr_in6);
 
 
 	} else {
 	} 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_family = AF_INET;    // host byte order
 		addr4->sin_port = htons(p_port);  // short, network byte order
 		addr4->sin_port = htons(p_port);  // short, network byte order
 		addr4->sin_addr = *((struct in_addr*)&p_ip.field32[0]);
 		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<String> *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<String> *p_accepted_hosts) {
 
 
 	memset(p_addr, 0, sizeof(struct sockaddr_storage));
 	memset(p_addr, 0, sizeof(struct sockaddr_storage));
 	if (p_address_type == IP_Address::TYPE_IPV4) {
 	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_family = AF_INET;
 		addr4->sin_port = htons(p_port);
 		addr4->sin_port = htons(p_port);
 		addr4->sin_addr.s_addr = INADDR_ANY; // TODO: use accepted hosts list
 		addr4->sin_addr.s_addr = INADDR_ANY; // TODO: use accepted hosts list
+		return sizeof(sockaddr_in);
 	} else {
 	} else {
 		struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr;
 		struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr;
 
 
 		addr6->sin6_family = AF_INET6;
 		addr6->sin6_family = AF_INET6;
 		addr6->sin6_port = htons(p_port);
 		addr6->sin6_port = htons(p_port);
 		addr6->sin6_addr = in6addr_any; // TODO: use accepted hosts list
 		addr6->sin6_addr = in6addr_any; // TODO: use accepted hosts list
+		return sizeof(sockaddr_in6);
 	};
 	};
 };
 };
 
 

+ 4 - 4
drivers/unix/stream_peer_tcp_posix.cpp

@@ -98,9 +98,9 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const {
 	};
 	};
 
 
 	struct sockaddr_storage their_addr;
 	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) {
 		if (errno == EISCONN) {
 			status = STATUS_CONNECTED;
 			status = STATUS_CONNECTED;
@@ -153,10 +153,10 @@ Error StreamPeerTCPPosix::connect(const IP_Address& p_host, uint16_t p_port) {
 #endif
 #endif
 
 
 	struct sockaddr_storage their_addr;
 	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;
 	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!");
 		ERR_PRINT("Connection to remote host failed!");
 		disconnect();
 		disconnect();

+ 2 - 2
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;
 	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
 	// 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) {
 		if (::listen(sockfd, 1) == -1) {
 
 

+ 4 - 4
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);
 	int sock = _get_socket(peer_addr.type);
 	ERR_FAIL_COND_V( sock == -1, FAILED );
 	ERR_FAIL_COND_V( sock == -1, FAILED );
 	struct sockaddr_storage addr;
 	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);
 	_set_blocking(true);
 
 
 	errno = 0;
 	errno = 0;
 	int err;
 	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) {
 		if (WSAGetLastError() != WSAEWOULDBLOCK) {
 			return FAILED;
 			return FAILED;
@@ -120,9 +120,9 @@ Error PacketPeerUDPWinsock::listen(int p_port, IP_Address::AddrType p_address_ty
 		return ERR_CANT_CREATE;
 		return ERR_CANT_CREATE;
 
 
 	struct sockaddr_storage addr = {0};
 	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();
 		close();
 		return ERR_UNAVAILABLE;
 		return ERR_UNAVAILABLE;
 	}
 	}

+ 4 - 4
platform/windows/stream_peer_winsock.cpp

@@ -88,9 +88,9 @@ Error StreamPeerWinsock::_poll_connection(bool p_block) const {
 	};
 	};
 
 
 	struct sockaddr_storage their_addr;
 	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();
 		int err = WSAGetLastError();
 		if (err == WSAEISCONN) {
 		if (err == WSAEISCONN) {
@@ -312,9 +312,9 @@ Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) {
 	};
 	};
 
 
 	struct sockaddr_storage their_addr;
 	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) {
 		if (WSAGetLastError() != WSAEWOULDBLOCK) {
 			ERR_PRINT("Connection to remote host failed!");
 			ERR_PRINT("Connection to remote host failed!");

+ 2 - 2
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;
 	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;
 	int reuse=1;
 	if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) {
 	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) {
 		if (::listen(sockfd, SOMAXCONN) == SOCKET_ERROR) {