added windows support for ipv6, cleaned up unix code
(cherry picked from commit 672225b710
)
This commit is contained in:
parent
904285f4b4
commit
d8b0070b8c
11 changed files with 175 additions and 122 deletions
|
@ -117,7 +117,9 @@ IP_Address IP::resolve_hostname(const String& p_hostname, IP_Address::AddrType p
|
|||
GLOBAL_LOCK_FUNCTION;
|
||||
|
||||
if (resolver->cache.has(p_hostname))
|
||||
return resolver->cache[p_hostname];
|
||||
if (resolver->cache[p_hostname].type & p_type != 0)
|
||||
return resolver->cache[p_hostname];
|
||||
// requested type is different from type in cache. continue resolution, if successful it'll overwrite cache
|
||||
|
||||
IP_Address res = _resolve_hostname(p_hostname, p_type);
|
||||
resolver->cache[p_hostname]=res;
|
||||
|
@ -137,7 +139,7 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname, IP_Addr
|
|||
|
||||
resolver->queue[id].hostname=p_hostname;
|
||||
resolver->queue[id].type = p_type;
|
||||
if (resolver->cache.has(p_hostname)) {
|
||||
if (resolver->cache.has(p_hostname) && (resolver->cache[p_hostname].type & p_type) != 0) {
|
||||
resolver->queue[id].response=resolver->cache[p_hostname];
|
||||
resolver->queue[id].status=IP::RESOLVER_STATUS_DONE;
|
||||
} else {
|
||||
|
@ -187,6 +189,14 @@ void IP::erase_resolve_item(ResolverID p_id) {
|
|||
|
||||
}
|
||||
|
||||
void IP::clear_cache(const String &p_hostname) {
|
||||
|
||||
if (p_hostname.empty()) {
|
||||
resolver->cache.clear();
|
||||
} else {
|
||||
resolver->cache.erase(p_hostname);
|
||||
}
|
||||
};
|
||||
|
||||
Array IP::_get_local_addresses() const {
|
||||
|
||||
|
@ -208,6 +218,7 @@ void IP::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("get_resolve_item_address","id"),&IP::get_resolve_item_address);
|
||||
ObjectTypeDB::bind_method(_MD("erase_resolve_item","id"),&IP::erase_resolve_item);
|
||||
ObjectTypeDB::bind_method(_MD("get_local_addresses"),&IP::_get_local_addresses);
|
||||
ObjectTypeDB::bind_method(_MD("clear_cache"),&IP::clear_cache, DEFVAL(""));
|
||||
|
||||
BIND_CONSTANT( RESOLVER_STATUS_NONE );
|
||||
BIND_CONSTANT( RESOLVER_STATUS_WAITING );
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
virtual void get_local_addresses(List<IP_Address> *r_addresses) const=0;
|
||||
void erase_resolve_item(ResolverID p_id);
|
||||
|
||||
void clear_cache(const String& p_hostname = "");
|
||||
|
||||
static IP* get_singleton();
|
||||
|
||||
static IP* create();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
66
drivers/unix/socket_helpers.h
Normal file
66
drivers/unix/socket_helpers.h
Normal file
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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_storage addr;
|
||||
_set_listen_sockaddr(&addr, p_port, p_type, p_accepted_hosts);
|
||||
|
||||
struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&addr;
|
||||
addr6->sin6_family = AF_INET6;
|
||||
addr6->sin6_port = htons(p_port);
|
||||
addr6->sin6_addr = in6addr_any;
|
||||
};
|
||||
// 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;
|
||||
int port;
|
||||
_set_ip_addr_port(ip, port, &their_addr);
|
||||
|
||||
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));
|
||||
|
||||
} 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;
|
||||
};
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include "packet_peer_udp_winsock.h"
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include "drivers/unix/socket_helpers.h"
|
||||
|
||||
int PacketPeerUDPWinsock::get_available_packet_count() const {
|
||||
|
||||
|
@ -48,7 +51,15 @@ Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer,int &r_buffer_si
|
|||
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);
|
||||
|
@ -60,13 +71,10 @@ Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer,int &r_buffer_si
|
|||
}
|
||||
Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer,int p_buffer_size){
|
||||
|
||||
int sock = _get_socket();
|
||||
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;
|
||||
_set_sockaddr(&addr, peer_addr, peer_port);
|
||||
|
||||
_set_blocking(true);
|
||||
|
||||
|
@ -104,16 +112,16 @@ void PacketPeerUDPWinsock::_set_blocking(bool p_blocking) {
|
|||
};
|
||||
}
|
||||
|
||||
Error PacketPeerUDPWinsock::listen(int p_port, int p_recv_buffer_size){
|
||||
Error PacketPeerUDPWinsock::listen(int p_port, IP_Address::AddrType p_address_type, int p_recv_buffer_size) {
|
||||
|
||||
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;
|
||||
|
||||
struct sockaddr_storage addr = {0};
|
||||
_set_listen_sockaddr(&addr, p_port, p_address_type, NULL);
|
||||
|
||||
if (bind(sock, (struct sockaddr*)&addr, sizeof(sockaddr_in)) == -1 ) {
|
||||
close();
|
||||
return ERR_UNAVAILABLE;
|
||||
|
@ -146,17 +154,41 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) {
|
|||
_set_blocking(p_wait);
|
||||
|
||||
|
||||
struct sockaddr_in from = {0};
|
||||
int len = sizeof(struct sockaddr_in);
|
||||
struct sockaddr_storage from = {0};
|
||||
int len = sizeof(struct sockaddr_storage);
|
||||
int ret;
|
||||
while ( (ret = recvfrom(sockfd, (char*)recv_buffer, MIN((int)sizeof(recv_buffer),MAX(rb.space_left()-12, 0)), 0, (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 = 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 = 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;
|
||||
};
|
||||
|
||||
|
@ -202,12 +234,14 @@ int PacketPeerUDPWinsock::get_packet_port() const{
|
|||
return packet_port;
|
||||
}
|
||||
|
||||
int PacketPeerUDPWinsock::_get_socket() {
|
||||
int PacketPeerUDPWinsock::_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);
|
||||
|
||||
|
|
|
@ -42,15 +42,15 @@ class PacketPeerUDPWinsock : public PacketPeerUDP {
|
|||
mutable RingBuffer<uint8_t> rb;
|
||||
uint8_t recv_buffer[PACKET_BUFFER_SIZE];
|
||||
mutable uint8_t packet_buffer[PACKET_BUFFER_SIZE];
|
||||
IP_Address packet_ip;
|
||||
int packet_port;
|
||||
mutable IP_Address packet_ip;
|
||||
mutable int packet_port;
|
||||
mutable int queue_count;
|
||||
int sockfd;
|
||||
|
||||
IP_Address peer_addr;
|
||||
int peer_port;
|
||||
|
||||
_FORCE_INLINE_ int _get_socket();
|
||||
_FORCE_INLINE_ int _get_socket(IP_Address::AddrType p_type);
|
||||
|
||||
static PacketPeerUDP* _create();
|
||||
|
||||
|
@ -67,7 +67,7 @@ public:
|
|||
|
||||
virtual int get_max_packet_size() const;
|
||||
|
||||
virtual Error listen(int p_port,int p_recv_buffer_size=65536);
|
||||
virtual Error listen(int p_port, IP_Address::AddrType p_address_type, int p_recv_buffer_size=65536);
|
||||
virtual void close();
|
||||
virtual Error wait();
|
||||
virtual bool is_listening() const;
|
||||
|
|
|
@ -31,17 +31,12 @@
|
|||
#include "stream_peer_winsock.h"
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include "drivers/unix/socket_helpers.h"
|
||||
|
||||
int winsock_refcount = 0;
|
||||
|
||||
static void set_addr_in(struct sockaddr_in& their_addr, const IP_Address& p_host, uint16_t p_port) {
|
||||
|
||||
their_addr.sin_family = AF_INET; // host byte order
|
||||
their_addr.sin_port = htons(p_port); // short, network byte order
|
||||
their_addr.sin_addr = *((struct in_addr*)&p_host.host);
|
||||
memset(&(their_addr.sin_zero), '\0', 8);
|
||||
};
|
||||
|
||||
StreamPeerTCP* StreamPeerWinsock::_create() {
|
||||
|
||||
return memnew(StreamPeerWinsock);
|
||||
|
@ -92,8 +87,8 @@ Error StreamPeerWinsock::_poll_connection(bool p_block) const {
|
|||
_block(sockfd, false, true);
|
||||
};
|
||||
|
||||
struct sockaddr_in their_addr;
|
||||
set_addr_in(their_addr, peer_host, peer_port);
|
||||
struct sockaddr_storage their_addr;
|
||||
_set_sockaddr(&their_addr, peer_host, peer_port);
|
||||
|
||||
if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) {
|
||||
|
||||
|
@ -299,9 +294,10 @@ void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port)
|
|||
|
||||
Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) {
|
||||
|
||||
ERR_FAIL_COND_V( p_host.host == 0, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V( p_host.type == IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER);
|
||||
|
||||
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
|
||||
int family = p_host.type == IP_Address::TYPE_IPV6 ? AF_INET6 : AF_INET;
|
||||
if ((sockfd = socket(family, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
|
||||
ERR_PRINT("Socket creation failed!");
|
||||
disconnect();
|
||||
//perror("socket");
|
||||
|
@ -315,8 +311,8 @@ Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) {
|
|||
return FAILED;
|
||||
};
|
||||
|
||||
struct sockaddr_in their_addr;
|
||||
set_addr_in(their_addr, p_host, p_port);
|
||||
struct sockaddr_storage their_addr;
|
||||
_set_sockaddr(&their_addr, p_host, p_port);
|
||||
|
||||
if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) {
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include "stream_peer_winsock.h"
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include "drivers/unix/socket_helpers.h"
|
||||
|
||||
extern int winsock_refcount;
|
||||
|
||||
|
@ -60,7 +63,7 @@ void TCPServerWinsock::cleanup() {
|
|||
};
|
||||
|
||||
|
||||
Error TCPServerWinsock::listen(uint16_t p_port,const List<String> *p_accepted_hosts) {
|
||||
Error TCPServerWinsock::listen(uint16_t p_port, IP_Address::AddrType p_type,const List<String> *p_accepted_hosts) {
|
||||
|
||||
int sockfd;
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
@ -73,11 +76,8 @@ Error TCPServerWinsock::listen(uint16_t p_port,const List<String> *p_accepted_ho
|
|||
return FAILED;
|
||||
};
|
||||
|
||||
struct sockaddr_in my_addr;
|
||||
my_addr.sin_family = AF_INET; // host byte order
|
||||
my_addr.sin_port = htons(p_port); // short, network byte order
|
||||
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP TODO: use p_accepted_hosts
|
||||
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
|
||||
struct sockaddr_storage my_addr;
|
||||
_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) {
|
||||
|
@ -140,16 +140,17 @@ Ref<StreamPeerTCP> TCPServerWinsock::take_connection() {
|
|||
return NULL;
|
||||
};
|
||||
|
||||
struct sockaddr_in their_addr;
|
||||
struct sockaddr_storage their_addr;
|
||||
int sin_size = sizeof(their_addr);
|
||||
int fd = accept(listen_sockfd, (struct sockaddr *)&their_addr, &sin_size);
|
||||
ERR_FAIL_COND_V(fd == INVALID_SOCKET, NULL);
|
||||
|
||||
Ref<StreamPeerWinsock> conn = memnew(StreamPeerWinsock);
|
||||
IP_Address ip;
|
||||
ip.host = (uint32_t)their_addr.sin_addr.s_addr;
|
||||
int port;
|
||||
_set_ip_addr_port(ip, port, &their_addr);
|
||||
|
||||
conn->set_socket(fd, ip, ntohs(their_addr.sin_port));
|
||||
conn->set_socket(fd, ip, port);
|
||||
|
||||
return conn;
|
||||
};
|
||||
|
|
|
@ -39,7 +39,7 @@ class TCPServerWinsock : public TCP_Server {
|
|||
|
||||
public:
|
||||
|
||||
virtual Error listen(uint16_t p_port,const List<String> *p_accepted_hosts=NULL);
|
||||
virtual Error listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_IPV4,const List<String> *p_accepted_hosts=NULL);
|
||||
virtual bool is_connection_available() const;
|
||||
virtual Ref<StreamPeerTCP> take_connection();
|
||||
|
||||
|
|
Loading…
Reference in a new issue