Error PacketPeerUDPWinsock::listen(int p_port, IP_Address p_bind_address, int p_recv_buffer_size) {

	ERR_FAIL_COND_V(sockfd != -1, ERR_ALREADY_IN_USE);
	ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);

	sock_type = IP::TYPE_ANY;

	if (p_bind_address.is_valid())
		sock_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;

	int sock = _get_socket();
	if (sock == -1)
		return ERR_CANT_CREATE;

	struct sockaddr_storage addr = { 0 };
	size_t addr_size = _set_listen_sockaddr(&addr, p_port, sock_type, IP_Address());

	if (bind(sock, (struct sockaddr *)&addr, addr_size) == -1) {
		close();
		return ERR_UNAVAILABLE;
	}

	blocking = true;

	printf("UDP Connection listening on port %i\n", p_port);
	rb.resize(nearest_shift(p_recv_buffer_size));
	return OK;
}
Error NetSocketPosix::recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) {
	ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);

	struct sockaddr_storage from;
	socklen_t len = sizeof(struct sockaddr_storage);
	memset(&from, 0, len);

	r_read = ::recvfrom(_sock, SOCK_BUF(p_buffer), p_len, 0, (struct sockaddr *)&from, &len);

	if (r_read < 0) {
		NetError err = _get_socket_error();
		if (err == ERR_NET_WOULD_BLOCK)
			return ERR_BUSY;

		return FAILED;
	}

	if (from.ss_family == AF_INET) {
		struct sockaddr_in *sin_from = (struct sockaddr_in *)&from;
		r_ip.set_ipv4((uint8_t *)&sin_from->sin_addr);
		r_port = ntohs(sin_from->sin_port);
	} else if (from.ss_family == AF_INET6) {
		struct sockaddr_in6 *s6_from = (struct sockaddr_in6 *)&from;
		r_ip.set_ipv6((uint8_t *)&s6_from->sin6_addr);
		r_port = ntohs(s6_from->sin6_port);
	} else {
		// Unsupported socket family, should never happen.
		ERR_FAIL_V(FAILED);
	}

	return OK;
}
Beispiel #3
0
void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const {

	ULONG buf_size = 1024;
	IP_ADAPTER_ADDRESSES *addrs;

	while (true) {

		addrs = (IP_ADAPTER_ADDRESSES *)memalloc(buf_size);
		int err = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST |
														  GAA_FLAG_SKIP_MULTICAST |
														  GAA_FLAG_SKIP_DNS_SERVER |
														  GAA_FLAG_SKIP_FRIENDLY_NAME,
				NULL, addrs, &buf_size);
		if (err == NO_ERROR) {
			break;
		};
		memfree(addrs);
		if (err == ERROR_BUFFER_OVERFLOW) {
			continue; // will go back and alloc the right size
		};

		ERR_EXPLAIN("Call to GetAdaptersAddresses failed with error " + itos(err));
		ERR_FAIL();
		return;
	};

	IP_ADAPTER_ADDRESSES *adapter = addrs;

	while (adapter != NULL) {

		IP_ADAPTER_UNICAST_ADDRESS *address = adapter->FirstUnicastAddress;
		while (address != NULL) {

			IP_Address ip;

			if (address->Address.lpSockaddr->sa_family == AF_INET) {

				SOCKADDR_IN *ipv4 = reinterpret_cast<SOCKADDR_IN *>(address->Address.lpSockaddr);

				ip.set_ipv4((uint8_t *)&(ipv4->sin_addr));
			} else { // ipv6

				SOCKADDR_IN6 *ipv6 = reinterpret_cast<SOCKADDR_IN6 *>(address->Address.lpSockaddr);

				ip.set_ipv6(ipv6->sin6_addr.s6_addr);
			};

			r_addresses->push_back(ip);

			address = address->Next;
		};
		adapter = adapter->Next;
	};

	memfree(addrs);
};
Beispiel #4
0
Error TCPServerPosix::listen(uint16_t p_port, const IP_Address p_bind_address) {

	ERR_FAIL_COND_V(listen_sockfd != -1, ERR_ALREADY_IN_USE);
	ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);

	int sockfd;
#ifdef __OpenBSD__
	sock_type = IP::TYPE_IPV4; // OpenBSD does not support dual stacking, fallback to IPv4 only.
#else
	sock_type = IP::TYPE_ANY;
#endif

	// If the bind address is valid use its type as the socket type
	if (p_bind_address.is_valid())
		sock_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;

	sockfd = _socket_create(sock_type, SOCK_STREAM, IPPROTO_TCP);

	ERR_FAIL_COND_V(sockfd == -1, FAILED);

#ifndef NO_FCNTL
	fcntl(sockfd, F_SETFL, O_NONBLOCK);
#else
	int bval = 1;
	ioctl(sockfd, FIONBIO, &bval);
#endif

	int reuse = 1;
	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) {
		WARN_PRINT("REUSEADDR failed!")
	}

	struct sockaddr_storage addr;
	size_t addr_size = _set_listen_sockaddr(&addr, p_port, sock_type, p_bind_address);

	if (bind(sockfd, (struct sockaddr *)&addr, addr_size) != -1) {

		if (::listen(sockfd, 1) == -1) {

			close(sockfd);
			ERR_FAIL_V(FAILED);
		};
	} else {
		return ERR_ALREADY_IN_USE;
	};

	if (listen_sockfd != -1) {
		stop();
	};

	listen_sockfd = sockfd;

	return OK;
};
Beispiel #5
0
static IP_Address _sockaddr2ip(struct sockaddr *p_addr) {

	IP_Address ip;
	if (p_addr->sa_family == AF_INET) {
		struct sockaddr_in *addr = (struct sockaddr_in *)p_addr;
		ip.set_ipv4((uint8_t *)&(addr->sin_addr));
	} else {
		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr;
		ip.set_ipv6(addr6->sin6_addr.s6_addr);
	};

	return ip;
};
size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const IP_Address &p_ip, uint16_t p_port, IP::Type p_ip_type) {

	memset(p_addr, 0, sizeof(struct sockaddr_storage));
	if (p_ip_type == IP::TYPE_IPV6 || p_ip_type == IP::TYPE_ANY) { // IPv6 socket

		// IPv6 only socket with IPv4 address
		ERR_FAIL_COND_V(!p_ip.is_wildcard() && p_ip_type == IP::TYPE_IPV6 && p_ip.is_ipv4(), 0);

		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr;
		addr6->sin6_family = AF_INET6;
		addr6->sin6_port = htons(p_port);
		if (p_ip.is_valid()) {
			copymem(&addr6->sin6_addr.s6_addr, p_ip.get_ipv6(), 16);
		} else {
			addr6->sin6_addr = in6addr_any;
		}
		return sizeof(sockaddr_in6);
	} else { // IPv4 socket

		// IPv4 socket with IPv6 address
		ERR_FAIL_COND_V(!p_ip.is_wildcard() && !p_ip.is_ipv4(), 0);

		struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr;
		addr4->sin_family = AF_INET;
		addr4->sin_port = htons(p_port); // short, network byte order

		if (p_ip.is_valid()) {
			copymem(&addr4->sin_addr.s_addr, p_ip.get_ipv4(), 4);
		} else {
			addr4->sin_addr.s_addr = INADDR_ANY;
		}

		return sizeof(sockaddr_in);
	}
}
bool NetSocketPosix::_can_use_ip(const IP_Address p_ip, const bool p_for_bind) const {

	if (p_for_bind && !(p_ip.is_valid() || p_ip.is_wildcard())) {
		return false;
	} else if (!p_for_bind && !p_ip.is_valid()) {
		return false;
	}
	// Check if socket support this IP type.
	IP::Type type = p_ip.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
	if (_ip_type != IP::TYPE_ANY && !p_ip.is_wildcard() && _ip_type != type) {
		return false;
	}
	return true;
}
Beispiel #8
0
Error PacketPeerUDP::_set_dest_address(const String &p_address, int p_port) {

	IP_Address ip;
	if (p_address.is_valid_ip_address()) {
		ip = p_address;
	} else {
		ip = IP::get_singleton()->resolve_hostname(p_address);
		if (!ip.is_valid())
			return ERR_CANT_RESOLVE;
	}

	set_dest_address(ip, p_port);
	return OK;
}
Beispiel #9
0
Error StreamPeerTCP::_connect(const String &p_address, int p_port) {

	IP_Address ip;
	if (p_address.is_valid_ip_address()) {
		ip = p_address;
	} else {
		ip = IP::get_singleton()->resolve_hostname(p_address);
		if (!ip.is_valid())
			return ERR_CANT_RESOLVE;
	}

	connect_to_host(ip, p_port);
	return OK;
}
Beispiel #10
0
void NetSocketPosix::_set_ip_port(struct sockaddr_storage *p_addr, IP_Address &r_ip, uint16_t &r_port) {

	if (p_addr->ss_family == AF_INET) {

		struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr;
		r_ip.set_ipv4((uint8_t *)&(addr4->sin_addr.s_addr));

		r_port = ntohs(addr4->sin_port);

	} else if (p_addr->ss_family == AF_INET6) {

		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr;
		r_ip.set_ipv6(addr6->sin6_addr.s6_addr);

		r_port = ntohs(addr6->sin6_port);
	};
}
int findIndex(IP_Address host){
	int index = -1;
	list<IP_Address>:: iterator iterator;
	for(iterator = nodesList.begin(),index=0;iterator!=nodesList.end();++iterator,++index){
		string node = *iterator;
		if(host.compare(node)==0){
			return index;
		}
	}
	return index;
}
Beispiel #12
0
Error StreamPeerWinsock::connect_to_host(const IP_Address &p_host, uint16_t p_port) {

	ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER);

	sock_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
	sockfd = _socket_create(sock_type, SOCK_STREAM, IPPROTO_TCP);
	if (sockfd == INVALID_SOCKET) {
		ERR_PRINT("Socket creation failed!");
		disconnect_from_host();
		//perror("socket");
		return FAILED;
	};

	unsigned long par = 1;
	if (ioctlsocket(sockfd, FIONBIO, &par)) {
		perror("setting non-block mode");
		disconnect_from_host();
		return FAILED;
	};

	struct sockaddr_storage their_addr;
	size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port, sock_type);

	if (::connect(sockfd, (struct sockaddr *)&their_addr, addr_size) == SOCKET_ERROR) {

		if (WSAGetLastError() != WSAEWOULDBLOCK) {
			ERR_PRINT("Connection to remote host failed!");
			disconnect_from_host();
			return FAILED;
		};
		status = STATUS_CONNECTING;
	} else {
		status = STATUS_CONNECTED;
	};

	peer_host = p_host;
	peer_port = p_port;

	return OK;
};
Beispiel #13
0
Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) {

	ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
	ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
	ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);

	Error err;
	IP::Type ip_type = IP::TYPE_ANY;

	// If the bind address is valid use its type as the socket type
	if (p_bind_address.is_valid())
		ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;

	err = _sock->open(NetSocket::TYPE_TCP, ip_type);

	ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);

	_sock->set_blocking_enabled(false);
	_sock->set_reuse_address_enabled(true);

	err = _sock->bind(p_bind_address, p_port);

	if (err != OK) {

		_sock->close();
		return ERR_ALREADY_IN_USE;
	}

	err = _sock->listen(MAX_PENDING_CONNECTIONS);

	if (err != OK) {
		_sock->close();
		return FAILED;
	}
	return OK;
}
Beispiel #14
0
Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) {

	ERR_FAIL_COND_V(context != NULL, FAILED);

	IP_Address addr;

	if (!p_host.is_valid_ip_address()) {
		addr = IP::get_singleton()->resolve_hostname(p_host);
	} else {
		addr = p_host;
	}

	ERR_FAIL_COND_V(!addr.is_valid(), ERR_INVALID_PARAMETER);

	// Prepare protocols
	_lws_make_protocols(this, &LWSClient::_lws_gd_callback, p_protocols, &_lws_ref);

	// Init lws client
	struct lws_context_creation_info info;
	struct lws_client_connect_info i;

	memset(&i, 0, sizeof i);
	memset(&info, 0, sizeof info);

	info.port = CONTEXT_PORT_NO_LISTEN;
	info.protocols = _lws_ref->lws_structs;
	info.gid = -1;
	info.uid = -1;
	//info.ws_ping_pong_interval = 5;
	info.user = _lws_ref;
#if defined(LWS_OPENSSL_SUPPORT)
	info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
#endif
	context = lws_create_context(&info);

	if (context == NULL) {
		_lws_free_ref(_lws_ref);
		_lws_ref = NULL;
		ERR_EXPLAIN("Unable to create lws context");
		ERR_FAIL_V(FAILED);
	}

	i.context = context;
	if (p_protocols.size() > 0)
		i.protocol = _lws_ref->lws_names;
	else
		i.protocol = NULL;

	if (p_ssl) {
		i.ssl_connection = LCCSCF_USE_SSL;
		if (!verify_ssl)
			i.ssl_connection |= LCCSCF_ALLOW_SELFSIGNED;
	} else {
		i.ssl_connection = 0;
	}

	// These CharStrings needs to survive till we call lws_client_connect_via_info
	CharString addr_ch = ((String)addr).ascii();
	CharString host_ch = p_host.utf8();
	CharString path_ch = p_path.utf8();
	i.address = addr_ch.get_data();
	i.host = host_ch.get_data();
	i.path = path_ch.get_data();
	i.port = p_port;

	lws_client_connect_via_info(&i);

	return OK;
};
Beispiel #15
0
Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) {

	ERR_FAIL_COND_V(context != NULL, FAILED);

	IP_Address addr;

	if (!p_host.is_valid_ip_address()) {
		addr = IP::get_singleton()->resolve_hostname(p_host);
	} else {
		addr = p_host;
	}

	ERR_FAIL_COND_V(!addr.is_valid(), ERR_INVALID_PARAMETER);

	// prepare protocols
	if (p_protocols.size() == 0) // default to binary protocol
		p_protocols.append("binary");
	_lws_make_protocols(this, &LWSClient::_lws_gd_callback, p_protocols, &_lws_ref);

	// init lws client
	struct lws_context_creation_info info;
	struct lws_client_connect_info i;

	memset(&i, 0, sizeof i);
	memset(&info, 0, sizeof info);

	info.port = CONTEXT_PORT_NO_LISTEN;
	info.protocols = _lws_ref->lws_structs;
	info.gid = -1;
	info.uid = -1;
	//info.ws_ping_pong_interval = 5;
	info.user = _lws_ref;
#if defined(LWS_OPENSSL_SUPPORT)
	info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
#endif
	context = lws_create_context(&info);

	if (context == NULL) {
		_lws_free_ref(_lws_ref);
		_lws_ref = NULL;
		ERR_EXPLAIN("Unable to create lws context");
		ERR_FAIL_V(FAILED);
	}

	char abuf[1024];
	char hbuf[1024];
	char pbuf[2048];
	String addr_str = (String)addr;
	strncpy(abuf, addr_str.ascii().get_data(), 1024);
	strncpy(hbuf, p_host.utf8().get_data(), 1024);
	strncpy(pbuf, p_path.utf8().get_data(), 2048);

	i.context = context;
	i.protocol = _lws_ref->lws_names;
	i.address = abuf;
	i.host = hbuf;
	i.path = pbuf;
	i.port = p_port;

	if (p_ssl) {
		i.ssl_connection = LCCSCF_USE_SSL;
		if (!verify_ssl)
			i.ssl_connection |= LCCSCF_ALLOW_SELFSIGNED;
	} else {
		i.ssl_connection = 0;
	}

	lws_client_connect_via_info(&i);
	return OK;
};