| 
									
										
										
										
											2016-06-18 14:46:12 +02:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  packet_peer_udp.cpp                                                  */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2016-06-18 14:46:12 +02:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2022-01-03 21:27:34 +01:00
										 |  |  | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2016-06-18 14:46:12 +02:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | #include "packet_peer_udp.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "core/io/ip.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | #include "core/io/udp_server.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-08 17:14:01 +01:00
										 |  |  | void PacketPeerUDP::set_blocking_mode(bool p_enable) { | 
					
						
							|  |  |  | 	blocking = p_enable; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-25 17:36:09 +01:00
										 |  |  | void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) { | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 	ERR_FAIL_COND(udp_server); | 
					
						
							| 
									
										
										
										
											2019-11-25 17:36:09 +01:00
										 |  |  | 	broadcast = p_enabled; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (_sock.is_valid() && _sock->is_open()) { | 
					
						
							| 
									
										
										
										
											2019-11-25 17:36:09 +01:00
										 |  |  | 		_sock->set_broadcasting_enabled(p_enabled); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-25 17:36:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | Error PacketPeerUDP::join_multicast_group(IPAddress p_multi_address, String p_if_name) { | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V(udp_server, ERR_LOCKED); | 
					
						
							| 
									
										
										
										
											2019-06-20 11:36:32 +02:00
										 |  |  | 	ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!p_multi_address.is_valid(), ERR_INVALID_PARAMETER); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!_sock->is_open()) { | 
					
						
							|  |  |  | 		IP::Type ip_type = p_multi_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; | 
					
						
							|  |  |  | 		Error err = _sock->open(NetSocket::TYPE_UDP, ip_type); | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(err != OK, err); | 
					
						
							|  |  |  | 		_sock->set_blocking_enabled(false); | 
					
						
							| 
									
										
										
										
											2019-11-25 17:36:09 +01:00
										 |  |  | 		_sock->set_broadcasting_enabled(broadcast); | 
					
						
							| 
									
										
										
										
											2019-06-20 11:36:32 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return _sock->join_multicast_group(p_multi_address, p_if_name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | Error PacketPeerUDP::leave_multicast_group(IPAddress p_multi_address, String p_if_name) { | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V(udp_server, ERR_LOCKED); | 
					
						
							| 
									
										
										
										
											2019-06-20 11:36:32 +02:00
										 |  |  | 	ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!_sock->is_open(), ERR_UNCONFIGURED); | 
					
						
							|  |  |  | 	return _sock->leave_multicast_group(p_multi_address, p_if_name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | String PacketPeerUDP::_get_packet_ip() const { | 
					
						
							|  |  |  | 	return get_packet_address(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 00:54:21 -03:00
										 |  |  | Error PacketPeerUDP::_set_dest_address(const String &p_address, int p_port) { | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | 	IPAddress ip; | 
					
						
							| 
									
										
										
										
											2014-11-13 00:53:12 -03:00
										 |  |  | 	if (p_address.is_valid_ip_address()) { | 
					
						
							|  |  |  | 		ip = p_address; | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2017-01-18 12:47:12 +01:00
										 |  |  | 		ip = IP::get_singleton()->resolve_hostname(p_address); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (!ip.is_valid()) { | 
					
						
							| 
									
										
										
										
											2014-11-13 00:53:12 -03:00
										 |  |  | 			return ERR_CANT_RESOLVE; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-11-13 00:53:12 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 00:54:21 -03:00
										 |  |  | 	set_dest_address(ip, p_port); | 
					
						
							| 
									
										
										
										
											2014-11-13 00:53:12 -03:00
										 |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | int PacketPeerUDP::get_available_packet_count() const { | 
					
						
							|  |  |  | 	// TODO we should deprecate this, and expose poll instead!
 | 
					
						
							|  |  |  | 	Error err = const_cast<PacketPeerUDP *>(this)->_poll(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (err != OK) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return queue_count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { | 
					
						
							|  |  |  | 	Error err = _poll(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (err != OK) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 		return err; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (queue_count == 0) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 		return ERR_UNAVAILABLE; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	uint32_t size = 0; | 
					
						
							|  |  |  | 	uint8_t ipv6[16]; | 
					
						
							|  |  |  | 	rb.read(ipv6, 16, true); | 
					
						
							|  |  |  | 	packet_ip.set_ipv6(ipv6); | 
					
						
							|  |  |  | 	rb.read((uint8_t *)&packet_port, 4, true); | 
					
						
							|  |  |  | 	rb.read((uint8_t *)&size, 4, true); | 
					
						
							|  |  |  | 	rb.read(packet_buffer, size, true); | 
					
						
							|  |  |  | 	--queue_count; | 
					
						
							|  |  |  | 	*r_buffer = packet_buffer; | 
					
						
							|  |  |  | 	r_buffer_size = size; | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!peer_addr.is_valid(), ERR_UNCONFIGURED); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Error err; | 
					
						
							|  |  |  | 	int sent = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!_sock->is_open()) { | 
					
						
							|  |  |  | 		IP::Type ip_type = peer_addr.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; | 
					
						
							|  |  |  | 		err = _sock->open(NetSocket::TYPE_UDP, ip_type); | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(err != OK, err); | 
					
						
							|  |  |  | 		_sock->set_blocking_enabled(false); | 
					
						
							| 
									
										
										
										
											2019-11-25 17:36:09 +01:00
										 |  |  | 		_sock->set_broadcasting_enabled(broadcast); | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do { | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 		if (connected && !udp_server) { | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 			err = _sock->send(p_buffer, p_buffer_size, sent); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 		if (err != OK) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (err != ERR_BUSY) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 				return FAILED; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} else if (!blocking) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 				return ERR_BUSY; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 			// Keep trying to send full packet
 | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return OK; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} while (sent != p_buffer_size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PacketPeerUDP::get_max_packet_size() const { | 
					
						
							|  |  |  | 	return 512; // uhm maybe not
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | Error PacketPeerUDP::bind(int p_port, const IPAddress &p_bind_address, int p_recv_buffer_size) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2021-03-21 10:15:30 +00:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The local port number must be between 0 and 65535 (inclusive)."); | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Error err; | 
					
						
							|  |  |  | 	IP::Type ip_type = IP::TYPE_ANY; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (p_bind_address.is_valid()) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 		ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	err = _sock->open(NetSocket::TYPE_UDP, ip_type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (err != OK) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 		return ERR_CANT_CREATE; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	_sock->set_blocking_enabled(false); | 
					
						
							| 
									
										
										
										
											2019-11-25 17:36:09 +01:00
										 |  |  | 	_sock->set_broadcasting_enabled(broadcast); | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	err = _sock->bind(p_bind_address, p_port); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (err != OK) { | 
					
						
							|  |  |  | 		_sock->close(); | 
					
						
							|  |  |  | 		return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rb.resize(nearest_shift(p_recv_buffer_size)); | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | Error PacketPeerUDP::connect_shared_socket(Ref<NetSocket> p_sock, IPAddress p_ip, uint16_t p_port, UDPServer *p_server) { | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 	udp_server = p_server; | 
					
						
							|  |  |  | 	connected = true; | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 	_sock = p_sock; | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 	peer_addr = p_ip; | 
					
						
							|  |  |  | 	peer_port = p_port; | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 	packet_ip = peer_addr; | 
					
						
							|  |  |  | 	packet_port = peer_port; | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | void PacketPeerUDP::disconnect_shared_socket() { | 
					
						
							|  |  |  | 	udp_server = nullptr; | 
					
						
							|  |  |  | 	_sock = Ref<NetSocket>(NetSocket::create()); | 
					
						
							|  |  |  | 	close(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | Error PacketPeerUDP::connect_to_host(const IPAddress &p_host, int p_port) { | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V(udp_server, ERR_LOCKED); | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 	ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER); | 
					
						
							| 
									
										
										
										
											2021-03-21 10:15:30 +00:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(p_port < 1 || p_port > 65535, ERR_INVALID_PARAMETER, "The remote port number must be between 1 and 65535 (inclusive)."); | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Error err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!_sock->is_open()) { | 
					
						
							|  |  |  | 		IP::Type ip_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; | 
					
						
							|  |  |  | 		err = _sock->open(NetSocket::TYPE_UDP, ip_type); | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(err != OK, ERR_CANT_OPEN); | 
					
						
							|  |  |  | 		_sock->set_blocking_enabled(false); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = _sock->connect_to_host(p_host, p_port); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// I see no reason why we should get ERR_BUSY (wouldblock/eagain) here.
 | 
					
						
							|  |  |  | 	// This is UDP, so connect is only used to tell the OS to which socket
 | 
					
						
							| 
									
										
										
										
											2021-03-12 19:05:16 +05:30
										 |  |  | 	// it should deliver packets when multiple are bound on the same address/port.
 | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 	if (err != OK) { | 
					
						
							|  |  |  | 		close(); | 
					
						
							|  |  |  | 		ERR_FAIL_V_MSG(FAILED, "Unable to connect"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	connected = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	peer_addr = p_host; | 
					
						
							|  |  |  | 	peer_port = p_port; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Flush any packet we might still have in queue.
 | 
					
						
							|  |  |  | 	rb.clear(); | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-27 16:31:56 +02:00
										 |  |  | bool PacketPeerUDP::is_socket_connected() const { | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 	return connected; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | void PacketPeerUDP::close() { | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 	if (udp_server) { | 
					
						
							|  |  |  | 		udp_server->remove_peer(peer_addr, peer_port); | 
					
						
							|  |  |  | 		udp_server = nullptr; | 
					
						
							|  |  |  | 		_sock = Ref<NetSocket>(NetSocket::create()); | 
					
						
							|  |  |  | 	} else if (_sock.is_valid()) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 		_sock->close(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	rb.resize(16); | 
					
						
							|  |  |  | 	queue_count = 0; | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 	connected = false; | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error PacketPeerUDP::wait() { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); | 
					
						
							|  |  |  | 	return _sock->poll(NetSocket::POLL_TYPE_IN, -1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error PacketPeerUDP::_poll() { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!_sock->is_open()) { | 
					
						
							|  |  |  | 		return FAILED; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 	if (udp_server) { | 
					
						
							|  |  |  | 		return OK; // Handled by UDPServer.
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Error err; | 
					
						
							|  |  |  | 	int read; | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | 	IPAddress ip; | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	uint16_t port; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (true) { | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 		if (connected) { | 
					
						
							|  |  |  | 			err = _sock->recv(recv_buffer, sizeof(recv_buffer), read); | 
					
						
							|  |  |  | 			ip = peer_addr; | 
					
						
							|  |  |  | 			port = peer_port; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			err = _sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, ip, port); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (err != OK) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (err == ERR_BUSY) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 			return FAILED; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 		err = store_packet(ip, port, recv_buffer, read); | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 		if (err != OK) { | 
					
						
							| 
									
										
										
										
											2019-11-07 09:44:15 +01:00
										 |  |  | 			WARN_PRINT("Buffer full, dropping packets!"); | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | Error PacketPeerUDP::store_packet(IPAddress p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size) { | 
					
						
							| 
									
										
										
										
											2020-06-25 15:32:50 +02:00
										 |  |  | 	if (rb.space_left() < p_buf_size + 24) { | 
					
						
							|  |  |  | 		return ERR_OUT_OF_MEMORY; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rb.write(p_ip.get_ipv6(), 16); | 
					
						
							|  |  |  | 	rb.write((uint8_t *)&p_port, 4); | 
					
						
							|  |  |  | 	rb.write((uint8_t *)&p_buf_size, 4); | 
					
						
							|  |  |  | 	rb.write(p_buf, p_buf_size); | 
					
						
							|  |  |  | 	++queue_count; | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-26 17:56:08 +01:00
										 |  |  | bool PacketPeerUDP::is_bound() const { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	return _sock.is_valid() && _sock->is_open(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | IPAddress PacketPeerUDP::get_packet_address() const { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	return packet_ip; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PacketPeerUDP::get_packet_port() const { | 
					
						
							|  |  |  | 	return packet_port; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-21 10:15:30 +00:00
										 |  |  | int PacketPeerUDP::get_local_port() const { | 
					
						
							|  |  |  | 	uint16_t local_port; | 
					
						
							|  |  |  | 	_sock->get_socket_address(nullptr, &local_port); | 
					
						
							|  |  |  | 	return local_port; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 02:48:18 +02:00
										 |  |  | void PacketPeerUDP::set_dest_address(const IPAddress &p_address, int p_port) { | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(connected, "Destination address cannot be set for connected sockets"); | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	peer_addr = p_address; | 
					
						
							|  |  |  | 	peer_port = p_port; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | void PacketPeerUDP::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2021-03-26 17:56:08 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("bind", "port", "bind_address", "recv_buf_size"), &PacketPeerUDP::bind, DEFVAL("*"), DEFVAL(65536)); | 
					
						
							| 
									
										
										
										
											2017-02-13 12:47:24 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("close"), &PacketPeerUDP::close); | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("wait"), &PacketPeerUDP::wait); | 
					
						
							| 
									
										
										
										
											2021-03-26 17:56:08 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("is_bound"), &PacketPeerUDP::is_bound); | 
					
						
							| 
									
										
										
										
											2019-08-22 19:03:35 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port"), &PacketPeerUDP::connect_to_host); | 
					
						
							| 
									
										
										
										
											2022-03-27 16:31:56 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("is_socket_connected"), &PacketPeerUDP::is_socket_connected); | 
					
						
							| 
									
										
										
										
											2017-02-13 12:47:24 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_packet_ip"), &PacketPeerUDP::_get_packet_ip); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_packet_port"), &PacketPeerUDP::get_packet_port); | 
					
						
							| 
									
										
										
										
											2021-03-21 10:15:30 +00:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_local_port"), &PacketPeerUDP::get_local_port); | 
					
						
							| 
									
										
										
										
											2017-02-13 12:47:24 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_dest_address", "host", "port"), &PacketPeerUDP::_set_dest_address); | 
					
						
							| 
									
										
										
										
											2019-11-25 17:36:09 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_broadcast_enabled", "enabled"), &PacketPeerUDP::set_broadcast_enabled); | 
					
						
							| 
									
										
										
										
											2019-06-20 11:36:32 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("join_multicast_group", "multicast_address", "interface_name"), &PacketPeerUDP::join_multicast_group); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("leave_multicast_group", "multicast_address", "interface_name"), &PacketPeerUDP::leave_multicast_group); | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-08 15:07:33 -05:00
										 |  |  | PacketPeerUDP::PacketPeerUDP() : | 
					
						
							|  |  |  | 		_sock(Ref<NetSocket>(NetSocket::create())) { | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | 	rb.resize(16); | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-02 05:32:12 +02:00
										 |  |  | PacketPeerUDP::~PacketPeerUDP() { | 
					
						
							|  |  |  | 	close(); | 
					
						
							| 
									
										
										
										
											2014-11-12 11:23:23 -03:00
										 |  |  | } |