Try other resolved IPs if one fails to connect
This commit is contained in:
parent
9d38ebdc3c
commit
fd52e18d19
|
@ -45,6 +45,8 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
|
||||||
conn_port = p_port;
|
conn_port = p_port;
|
||||||
conn_host = p_host;
|
conn_host = p_host;
|
||||||
|
|
||||||
|
ip_candidates.clear();
|
||||||
|
|
||||||
ssl = p_ssl;
|
ssl = p_ssl;
|
||||||
ssl_verify_host = p_verify_host;
|
ssl_verify_host = p_verify_host;
|
||||||
|
|
||||||
|
@ -234,6 +236,7 @@ void HTTPClientTCP::close() {
|
||||||
resolving = IP::RESOLVER_INVALID_ID;
|
resolving = IP::RESOLVER_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ip_candidates.clear();
|
||||||
response_headers.clear();
|
response_headers.clear();
|
||||||
response_str.clear();
|
response_str.clear();
|
||||||
body_size = -1;
|
body_size = -1;
|
||||||
|
@ -256,10 +259,17 @@ Error HTTPClientTCP::poll() {
|
||||||
return OK; // Still resolving
|
return OK; // Still resolving
|
||||||
|
|
||||||
case IP::RESOLVER_STATUS_DONE: {
|
case IP::RESOLVER_STATUS_DONE: {
|
||||||
IPAddress host = IP::get_singleton()->get_resolve_item_address(resolving);
|
ip_candidates = IP::get_singleton()->get_resolve_item_addresses(resolving);
|
||||||
Error err = tcp_connection->connect_to_host(host, conn_port);
|
|
||||||
IP::get_singleton()->erase_resolve_item(resolving);
|
IP::get_singleton()->erase_resolve_item(resolving);
|
||||||
resolving = IP::RESOLVER_INVALID_ID;
|
resolving = IP::RESOLVER_INVALID_ID;
|
||||||
|
|
||||||
|
Error err = ERR_BUG; // Should be at least one entry.
|
||||||
|
while (ip_candidates.size() > 0) {
|
||||||
|
err = tcp_connection->connect_to_host(ip_candidates.front(), conn_port);
|
||||||
|
if (err == OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
status = STATUS_CANT_CONNECT;
|
status = STATUS_CANT_CONNECT;
|
||||||
return err;
|
return err;
|
||||||
|
@ -313,6 +323,7 @@ Error HTTPClientTCP::poll() {
|
||||||
if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
|
if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
|
||||||
// Handshake has been successful
|
// Handshake has been successful
|
||||||
handshaking = false;
|
handshaking = false;
|
||||||
|
ip_candidates.clear();
|
||||||
status = STATUS_CONNECTED;
|
status = STATUS_CONNECTED;
|
||||||
return OK;
|
return OK;
|
||||||
} else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) {
|
} else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) {
|
||||||
|
@ -323,15 +334,24 @@ Error HTTPClientTCP::poll() {
|
||||||
}
|
}
|
||||||
// ... we will need to poll more for handshake to finish
|
// ... we will need to poll more for handshake to finish
|
||||||
} else {
|
} else {
|
||||||
|
ip_candidates.clear();
|
||||||
status = STATUS_CONNECTED;
|
status = STATUS_CONNECTED;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
} break;
|
} break;
|
||||||
case StreamPeerTCP::STATUS_ERROR:
|
case StreamPeerTCP::STATUS_ERROR:
|
||||||
case StreamPeerTCP::STATUS_NONE: {
|
case StreamPeerTCP::STATUS_NONE: {
|
||||||
|
Error err = ERR_CANT_CONNECT;
|
||||||
|
while (ip_candidates.size() > 0) {
|
||||||
|
tcp_connection->disconnect_from_host();
|
||||||
|
err = tcp_connection->connect_to_host(ip_candidates.pop_front(), conn_port);
|
||||||
|
if (err == OK) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
close();
|
close();
|
||||||
status = STATUS_CANT_CONNECT;
|
status = STATUS_CANT_CONNECT;
|
||||||
return ERR_CANT_CONNECT;
|
return err;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -37,6 +37,7 @@ class HTTPClientTCP : public HTTPClient {
|
||||||
private:
|
private:
|
||||||
Status status = STATUS_DISCONNECTED;
|
Status status = STATUS_DISCONNECTED;
|
||||||
IP::ResolverID resolving = IP::RESOLVER_INVALID_ID;
|
IP::ResolverID resolving = IP::RESOLVER_INVALID_ID;
|
||||||
|
Array ip_candidates;
|
||||||
int conn_port = -1;
|
int conn_port = -1;
|
||||||
String conn_host;
|
String conn_host;
|
||||||
bool ssl = false;
|
bool ssl = false;
|
||||||
|
|
|
@ -161,22 +161,28 @@ Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
|
||||||
ERR_FAIL_COND_V(p_path.is_empty(), ERR_INVALID_PARAMETER);
|
ERR_FAIL_COND_V(p_path.is_empty(), ERR_INVALID_PARAMETER);
|
||||||
|
|
||||||
_peer = Ref<WSLPeer>(memnew(WSLPeer));
|
_peer = Ref<WSLPeer>(memnew(WSLPeer));
|
||||||
IPAddress addr;
|
|
||||||
|
|
||||||
if (!p_host.is_valid_ip_address()) {
|
if (p_host.is_valid_ip_address()) {
|
||||||
addr = IP::get_singleton()->resolve_hostname(p_host);
|
ip_candidates.clear();
|
||||||
|
ip_candidates.push_back(IPAddress(p_host));
|
||||||
} else {
|
} else {
|
||||||
addr = p_host;
|
ip_candidates = IP::get_singleton()->resolve_hostname_addresses(p_host);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!addr.is_valid(), ERR_INVALID_PARAMETER);
|
ERR_FAIL_COND_V(ip_candidates.is_empty(), ERR_INVALID_PARAMETER);
|
||||||
|
|
||||||
String port = "";
|
String port = "";
|
||||||
if ((p_port != 80 && !p_ssl) || (p_port != 443 && p_ssl)) {
|
if ((p_port != 80 && !p_ssl) || (p_port != 443 && p_ssl)) {
|
||||||
port = ":" + itos(p_port);
|
port = ":" + itos(p_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
Error err = _tcp->connect_to_host(addr, p_port);
|
Error err = ERR_BUG; // Should be at least one entry.
|
||||||
|
while (ip_candidates.size() > 0) {
|
||||||
|
err = _tcp->connect_to_host(ip_candidates.pop_front(), p_port);
|
||||||
|
if (err == OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
_tcp->disconnect_from_host();
|
_tcp->disconnect_from_host();
|
||||||
_on_error();
|
_on_error();
|
||||||
|
@ -185,6 +191,7 @@ Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
|
||||||
_connection = _tcp;
|
_connection = _tcp;
|
||||||
_use_ssl = p_ssl;
|
_use_ssl = p_ssl;
|
||||||
_host = p_host;
|
_host = p_host;
|
||||||
|
_port = p_port;
|
||||||
// Strip edges from protocols.
|
// Strip edges from protocols.
|
||||||
_protocols.resize(p_protocols.size());
|
_protocols.resize(p_protocols.size());
|
||||||
String *pw = _protocols.ptrw();
|
String *pw = _protocols.ptrw();
|
||||||
|
@ -244,6 +251,7 @@ void WSLClient::poll() {
|
||||||
_on_error();
|
_on_error();
|
||||||
break;
|
break;
|
||||||
case StreamPeerTCP::STATUS_CONNECTED: {
|
case StreamPeerTCP::STATUS_CONNECTED: {
|
||||||
|
ip_candidates.clear();
|
||||||
Ref<StreamPeerSSL> ssl;
|
Ref<StreamPeerSSL> ssl;
|
||||||
if (_use_ssl) {
|
if (_use_ssl) {
|
||||||
if (_connection == _tcp) {
|
if (_connection == _tcp) {
|
||||||
|
@ -274,6 +282,12 @@ void WSLClient::poll() {
|
||||||
_do_handshake();
|
_do_handshake();
|
||||||
} break;
|
} break;
|
||||||
case StreamPeerTCP::STATUS_ERROR:
|
case StreamPeerTCP::STATUS_ERROR:
|
||||||
|
while (ip_candidates.size() > 0) {
|
||||||
|
_tcp->disconnect_from_host();
|
||||||
|
if (_tcp->connect_to_host(ip_candidates.pop_front(), _port) == OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
disconnect_from_host();
|
disconnect_from_host();
|
||||||
_on_error();
|
_on_error();
|
||||||
break;
|
break;
|
||||||
|
@ -315,6 +329,8 @@ void WSLClient::disconnect_from_host(int p_code, String p_reason) {
|
||||||
|
|
||||||
memset(_resp_buf, 0, sizeof(_resp_buf));
|
memset(_resp_buf, 0, sizeof(_resp_buf));
|
||||||
_resp_pos = 0;
|
_resp_pos = 0;
|
||||||
|
|
||||||
|
ip_candidates.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
IPAddress WSLClient::get_connected_host() const {
|
IPAddress WSLClient::get_connected_host() const {
|
||||||
|
|
|
@ -63,6 +63,8 @@ private:
|
||||||
|
|
||||||
String _key;
|
String _key;
|
||||||
String _host;
|
String _host;
|
||||||
|
int _port;
|
||||||
|
Array ip_candidates;
|
||||||
Vector<String> _protocols;
|
Vector<String> _protocols;
|
||||||
bool _use_ssl = false;
|
bool _use_ssl = false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue