summaryrefslogtreecommitdiff
path: root/drivers/unix
diff options
context:
space:
mode:
authorAriel Manzur <ariel@godotengine.org>2016-10-20 07:04:10 -0300
committerAriel Manzur <ariel@godotengine.org>2016-10-20 07:04:10 -0300
commit672225b710815865449e7930255468d1c085b137 (patch)
tree995f4e845e0d908fd27a2dcc583a5a2bd3dbb672 /drivers/unix
parent1c2ac490cf157402cac7f9dbc2a293d0c922def8 (diff)
added windows support for ipv6, cleaned up unix code
Diffstat (limited to 'drivers/unix')
-rw-r--r--drivers/unix/packet_peer_udp_posix.cpp29
-rw-r--r--drivers/unix/socket_helpers.h66
-rw-r--r--drivers/unix/stream_peer_tcp_posix.cpp24
-rw-r--r--drivers/unix/tcp_server_posix.cpp36
4 files changed, 82 insertions, 73 deletions
diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp
index cab2b2bbb9..cdc3bfce28 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 {
@@ -98,17 +99,7 @@ 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;
- if (peer_addr.type == IP_Address::TYPE_IPV4) {
- struct sockaddr_in* addr_in = (struct sockaddr_in*)&addr;
- addr_in->sin_family = AF_INET;
- addr_in->sin_port = htons(peer_port);
- addr_in->sin_addr = *((struct in_addr*)&peer_addr.field32[0]);
- } else {
- struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*)&addr;
- addr_in6->sin6_family = AF_INET;
- addr_in6->sin6_port = htons(peer_port);
- copymem(&addr_in6->sin6_addr.s6_addr, peer_addr.field8, 16);
- };
+ _set_sockaddr(&addr, peer_addr, peer_port);
errno = 0;
int err;
@@ -138,20 +129,7 @@ Error PacketPeerUDPPosix::listen(int p_port, IP_Address::AddrType p_address_type
return ERR_CANT_CREATE;
sockaddr_storage addr = {0};
-
- if (p_address_type == IP_Address::TYPE_IPV4) {
- struct sockaddr_in* addr4 = (struct sockaddr_in*)&addr;
- addr4->sin_family = AF_INET;
- addr4->sin_port = htons(p_port);
- addr4->sin_addr.s_addr = INADDR_ANY;
- } else {
-
- struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&addr;
-
- addr6->sin6_family = AF_INET6;
- addr6->sin6_port = htons(p_port);
- addr6->sin6_addr = in6addr_any;
- };
+ _set_listen_sockaddr(&addr, p_port, p_address_type, NULL);
if (bind(sock, (struct sockaddr*)&addr, sizeof(sockaddr_storage)) == -1 ) {
close();
@@ -212,6 +190,7 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) {
rb.write((uint8_t*)&ret, 4);
rb.write(recv_buffer, ret);
+ len = sizeof(struct sockaddr_storage);
++queue_count;
};
diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h
new file mode 100644
index 0000000000..622b45c500
--- /dev/null
+++ b/drivers/unix/socket_helpers.h
@@ -0,0 +1,66 @@
+#ifndef SOCKET_HELPERS_H
+#define SOCKET_HELPERS_H
+
+#include <string.h>
+
+// 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<String> *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
diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp
index bb672cef31..5a63a512e4 100644
--- a/drivers/unix/stream_peer_tcp_posix.cpp
+++ b/drivers/unix/stream_peer_tcp_posix.cpp
@@ -61,24 +61,7 @@
#define MSG_NOSIGNAL SO_NOSIGPIPE
#endif
-static void set_addr_in(struct sockaddr_storage& their_addr, const IP_Address& p_host, uint16_t p_port) {
-
- memset(&their_addr, 0, sizeof(struct sockaddr_storage));
- if (p_host.type == IP_Address::TYPE_IPV6) {
-
- struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&their_addr;
- addr6->sin6_family = AF_INET6;
- addr6->sin6_port = htons(p_port);
- copymem(&addr6->sin6_addr.s6_addr, p_host.field8, 16);
-
- } else {
-
- struct sockaddr_in* addr4 = (struct sockaddr_in*)&their_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_host.field32[0]);
- };
-};
+#include "drivers/unix/socket_helpers.h"
StreamPeerTCP* StreamPeerTCPPosix::_create() {
@@ -115,7 +98,8 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const {
};
struct sockaddr_storage their_addr;
- set_addr_in(their_addr, peer_host, peer_port);
+ _set_sockaddr(&their_addr, peer_host, peer_port);
+
if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(their_addr)) == -1) {
if (errno == EISCONN) {
@@ -169,7 +153,7 @@ Error StreamPeerTCPPosix::connect(const IP_Address& p_host, uint16_t p_port) {
#endif
struct sockaddr_storage their_addr;
- set_addr_in(their_addr, p_host, p_port);
+ _set_sockaddr(&their_addr, p_host, p_port);
errno = 0;
if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(their_addr)) == -1 && errno != EINPROGRESS) {
diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp
index 03312a7538..27c5618479 100644
--- a/drivers/unix/tcp_server_posix.cpp
+++ b/drivers/unix/tcp_server_posix.cpp
@@ -56,6 +56,8 @@
#include <sys/socket.h>
#include <assert.h>
+#include "drivers/unix/socket_helpers.h"
+
TCP_Server* TCPServerPosix::_create() {
return memnew(TCPServerPosix);
@@ -84,19 +86,9 @@ Error TCPServerPosix::listen(uint16_t p_port, IP_Address::AddrType p_type, const
WARN_PRINT("REUSEADDR failed!")
}
- sockaddr_storage addr = {0};
- if (p_type == IP_Address::TYPE_IPV4) {
- struct sockaddr_in* addr4 = (struct sockaddr_in*)&addr;
- addr4->sin_family = AF_INET;
- addr4->sin_port = htons(p_port);
- addr4->sin_addr.s_addr = INADDR_ANY;
- } else {
-
- struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&addr;
- addr6->sin6_family = AF_INET6;
- addr6->sin6_port = htons(p_port);
- addr6->sin6_addr = in6addr_any;
- };
+ struct sockaddr_storage addr;
+ _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) {
@@ -161,22 +153,10 @@ Ref<StreamPeerTCP> TCPServerPosix::take_connection() {
Ref<StreamPeerTCPPosix> conn = memnew(StreamPeerTCPPosix);
IP_Address ip;
- if (their_addr.ss_family == AF_INET) {
- ip.type = IP_Address::TYPE_IPV4;
-
- struct sockaddr_in* addr4 = (struct sockaddr_in*)&their_addr;
- ip.field32[0] = (uint32_t)addr4->sin_addr.s_addr;
- conn->set_socket(fd, ip, ntohs(addr4->sin_port));
+ int port;
+ _set_ip_addr_port(ip, port, &their_addr);
- } else if (their_addr.ss_family == AF_INET6) {
-
- ip.type = IP_Address::TYPE_IPV6;
-
- struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&their_addr;
- copymem(&addr6->sin6_addr.s6_addr, ip.field8, 16);
-
- conn->set_socket(fd, ip, ntohs(addr6->sin6_port));
- };
+ conn->set_socket(fd, ip, port);
return conn;
};