Use CURL_IPRESOLVE_V4 option only as fallback for advertising

This commit is contained in:
Michał Janiszewski 2018-02-11 21:51:46 +01:00 committed by Michał Janiszewski
parent 759171186c
commit 2e19e6cf0e
3 changed files with 23 additions and 5 deletions

View File

@ -44,6 +44,7 @@ struct HttpRequest2
std::string Method;
std::string Url;
http_data_type Type;
bool ForceIPv4 = false;
size_t Size = 0;
union
{
@ -59,6 +60,7 @@ struct HttpRequest2
Method = request.Method;
Url = request.Url;
Type = request.Type;
ForceIPv4 = request.ForceIPv4;
Size = request.Size;
if (request.Type == HTTP_DATA_JSON)
{
@ -77,6 +79,7 @@ struct HttpRequest2
Method = std::string(request->method);
Url = std::string(request->url);
Type = request->type;
ForceIPv4 = request->forceIPv4;
Size = request->size;
if (request->type == HTTP_DATA_JSON)
{
@ -198,8 +201,11 @@ static http_response_t *http_request(const HttpRequest2 &request)
curl_easy_setopt(curl, CURLOPT_URL, request.Url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &writeBuffer);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_request_write_func);
// Force resolving to IPv4 to fix issues where advertising over IPv6 does not work
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
if (request.ForceIPv4)
{
// Force resolving to IPv4 to fix issues where advertising over IPv6 does not work
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
}
curlResult = curl_easy_perform(curl);

View File

@ -61,6 +61,9 @@ private:
// Key received from the master server
std::string _key;
// See https://github.com/OpenRCT2/OpenRCT2/issues/6277 and 4953
bool _forceIPv4 = false;
public:
explicit NetworkServerAdvertiser(uint16 port)
{
@ -79,7 +82,7 @@ public:
case ADVERTISE_STATUS::UNREGISTERED:
if (_lastAdvertiseTime == 0 || platform_get_ticks() > _lastAdvertiseTime + MASTER_SERVER_REGISTER_TIME)
{
SendRegistration();
SendRegistration(_forceIPv4);
}
break;
case ADVERTISE_STATUS::REGISTERED:
@ -95,7 +98,7 @@ public:
}
private:
void SendRegistration()
void SendRegistration(bool forceIPv4)
{
_lastAdvertiseTime = platform_get_ticks();
@ -104,6 +107,7 @@ private:
request.tag = this;
request.url = GetMasterServerUrl();
request.method = HTTP_METHOD_POST;
request.forceIPv4 = forceIPv4;
json_t *body = json_object();
json_object_set_new(body, "key", json_string(_key.c_str()));
@ -180,7 +184,14 @@ private:
{
message = json_string_value(jsonMessage);
}
Console::Error::WriteLine("Unable to advertise: %s", message);
Console::Error::WriteLine("Unable to advertise (%d): %s", status, message);
// Hack for https://github.com/OpenRCT2/OpenRCT2/issues/6277
// Master server may not reply correctly if using IPv6, retry forcing IPv4
if (!_forceIPv4 && status == 500)
{
_forceIPv4 = true;
log_info("Retry with ipv4 only");
}
}
}
}

View File

@ -33,6 +33,7 @@ typedef struct http_request_t {
std::string method;
std::string url;
http_data_type type = HTTP_DATA_NONE;
bool forceIPv4;
size_t size;
union {
const json_t *root;