diff options
Diffstat (limited to 'drivers/unix/packet_peer_udp_posix.cpp')
| -rw-r--r-- | drivers/unix/packet_peer_udp_posix.cpp | 80 | 
1 files changed, 59 insertions, 21 deletions
diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 0201a85651..0b172b6a51 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -54,6 +54,7 @@  #include <arpa/inet.h>  #endif +#include "drivers/unix/socket_helpers.h"  int PacketPeerUDPPosix::get_available_packet_count() const { @@ -73,7 +74,15 @@ Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer,int &r_buffer_size  		return ERR_UNAVAILABLE;  	uint32_t size; -	rb.read((uint8_t*)&packet_ip.host,4,true); +	uint8_t type; +	rb.read(&type, 1, true); +	if (type == IP_Address::TYPE_IPV4) { +		rb.read((uint8_t*)&packet_ip.field8,4,true); +		packet_ip.type = IP_Address::TYPE_IPV4; +	} else { +		rb.read((uint8_t*)&packet_ip.field8,16,true); +		packet_ip.type = IP_Address::TYPE_IPV6; +	};  	rb.read((uint8_t*)&packet_port,4,true);  	rb.read((uint8_t*)&size,4,true);  	rb.read(packet_buffer,size,true); @@ -85,17 +94,17 @@ Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer,int &r_buffer_size  }  Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer,int p_buffer_size){ -	int sock = _get_socket(); +	ERR_FAIL_COND_V(peer_addr.type == IP_Address::TYPE_NONE, ERR_UNCONFIGURED); + +	int sock = _get_socket(peer_addr.type);  	ERR_FAIL_COND_V( sock == -1, FAILED ); -	struct sockaddr_in addr; -	addr.sin_family = AF_INET; -	addr.sin_port = htons(peer_port); -	addr.sin_addr = *((struct in_addr*)&peer_addr.host); +	struct sockaddr_storage addr; +	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; @@ -110,17 +119,19 @@ int PacketPeerUDPPosix::get_max_packet_size() const{  	return 512; // uhm maybe not  } -Error PacketPeerUDPPosix::listen(int p_port, int p_recv_buffer_size){ +Error PacketPeerUDPPosix::listen(int p_port, IP_Address::AddrType p_address_type, int p_recv_buffer_size) { + +	ERR_FAIL_COND_V(p_address_type != IP_Address::TYPE_IPV4 && p_address_type != IP_Address::TYPE_IPV6, ERR_INVALID_PARAMETER);  	close(); -	int sock = _get_socket(); +	int sock = _get_socket(p_address_type);  	if (sock == -1 )  		return ERR_CANT_CREATE; -	sockaddr_in addr = {0}; -	addr.sin_family = AF_INET; -	addr.sin_port = htons(p_port); -	addr.sin_addr.s_addr = INADDR_ANY; -	if (bind(sock, (struct sockaddr*)&addr, sizeof(sockaddr_in)) == -1 ) { + +	sockaddr_storage addr = {0}; +	size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_address_type, NULL); + +	if (bind(sock, (struct sockaddr*)&addr, addr_size) == -1 ) {  		close();  		return ERR_UNAVAILABLE;  	} @@ -145,16 +156,41 @@ Error PacketPeerUDPPosix::wait() {  Error PacketPeerUDPPosix::_poll(bool p_wait) { -	struct sockaddr_in from = {0}; -	socklen_t len = sizeof(struct sockaddr_in); +	struct sockaddr_storage from = {0}; +	socklen_t len = sizeof(struct sockaddr_storage);  	int ret;  	while ( (ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer),MAX(rb.space_left()-12, 0)), p_wait?0:MSG_DONTWAIT, (struct sockaddr*)&from, &len)) > 0) { -		rb.write((uint8_t*)&from.sin_addr, 4); -		uint32_t port = ntohs(from.sin_port); + +		uint32_t port = 0; + +		if (from.ss_family == AF_INET) { +			uint8_t type = (uint8_t)IP_Address::TYPE_IPV4; +			rb.write(&type, 1); +			struct sockaddr_in* sin_from = (struct sockaddr_in*)&from; +			rb.write((uint8_t*)&sin_from->sin_addr, 4); +			port = ntohs(sin_from->sin_port); + +		} else if (from.ss_family == AF_INET6) { + +			uint8_t type = (uint8_t)IP_Address::TYPE_IPV6; +			rb.write(&type, 1); + +			struct sockaddr_in6* s6_from = (struct sockaddr_in6*)&from; +			rb.write((uint8_t*)&s6_from->sin6_addr, 16); + +			port = ntohs(s6_from->sin6_port); + +		} else { +			// WARN_PRINT("Ignoring packet with unknown address family"); +			uint8_t type = (uint8_t)IP_Address::TYPE_NONE; +			rb.write(&type, 1); +		}; +  		rb.write((uint8_t*)&port, 4);  		rb.write((uint8_t*)&ret, 4);  		rb.write(recv_buffer, ret); -		len = sizeof(struct sockaddr_in); + +		len = sizeof(struct sockaddr_storage);  		++queue_count;  	}; @@ -182,12 +218,14 @@ int PacketPeerUDPPosix::get_packet_port() const{  	return packet_port;  } -int PacketPeerUDPPosix::_get_socket() { +int PacketPeerUDPPosix::_get_socket(IP_Address::AddrType p_type) {  	if (sockfd != -1)  		return sockfd; -	sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); +	int family = p_type == IP_Address::TYPE_IPV6 ? AF_INET6 : AF_INET; + +	sockfd = socket(family, SOCK_DGRAM, IPPROTO_UDP);  	ERR_FAIL_COND_V( sockfd == -1, -1 );  	//fcntl(sockfd, F_SETFL, O_NONBLOCK);  |