Skip to content

Commit

Permalink
Merge pull request #2253 from meganz/hotfix/dns-server-ios
Browse files Browse the repository at this point in the history
SDK-1226. Do not use DNS server provided by iOS (release v3.7.3d)
  • Loading branch information
sergiohs84 authored Sep 30, 2020
2 parents 2337aca + 8ad262d commit 33d946d
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 102 deletions.
11 changes: 7 additions & 4 deletions include/mega/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ namespace mega {
#define APISSLEXPONENT "\x01\x00\x01"

#define MEGA_DNS_SERVERS "2001:678:25c:2215::554,89.44.169.136," \
"2001:67c:1998:2212::13,31.216.148.13," \
"2405:f900:3e6a:1::103,31.216.148.11," \
"2403:9800:c020::43,122.56.56.216"
"2001:678:25c:2215::559,89.44.169.141," \
"2a0b:e40:3::14,66.203.127.16," \
"2a0b:e40:3::16,66.203.127.14"

class MEGA_API SpeedController
{
Expand Down Expand Up @@ -180,7 +180,10 @@ struct MEGA_API HttpIO : public EventTrigger
virtual Proxy *getautoproxy();

// get alternative DNS servers
void getMEGADNSservers(string*, bool = true);
void getMEGADNSservers(string* dnsservers, bool getfromnetwork);

// get DNS servers as configured in the system
void getDNSserversFromIos(string &dnsServers);

// set max download speed
virtual bool setmaxdownloadspeed(m_off_t bpslimit);
Expand Down
54 changes: 54 additions & 0 deletions src/http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
#include "mega/osx/osxutils.h"
#endif

#if TARGET_OS_IPHONE
#include <resolv.h>
#endif

namespace mega {

// interval to calculate the mean speed (ds)
Expand Down Expand Up @@ -316,6 +320,56 @@ void HttpIO::getMEGADNSservers(string *dnsservers, bool getfromnetwork)
}
}

// this method allows to retrieve DNS servers as configured in the system. Note that, under Wifi connections,
// it usually returns the gateway (192.168.1.1 or similar), so the DNS requests done by c-ares represent a
// an access to the local network, which we aim to avoid since iOS 14 requires explicit permission given by the user.
void HttpIO::getDNSserversFromIos(string& dnsServers)
{
#if TARGET_OS_IPHONE
// Workaround to get the IP of valid DNS servers on iOS
__res_state res;
bool valid;
if (res_ninit(&res) == 0)
{
union res_sockaddr_union u[MAXNS];
int nscount = res_getservers(&res, u, MAXNS);

for (int i = 0; i < nscount; i++)
{
char straddr[INET6_ADDRSTRLEN];
straddr[0] = 0;
valid = false;

if (u[i].sin.sin_family == PF_INET)
{
valid = mega_inet_ntop(PF_INET, &u[i].sin.sin_addr, straddr, sizeof(straddr)) == straddr;
}

if (u[i].sin6.sin6_family == PF_INET6)
{
valid = mega_inet_ntop(PF_INET6, &u[i].sin6.sin6_addr, straddr, sizeof(straddr)) == straddr;
}

if (valid && straddr[0])
{
if (dnsServers.size())
{
dnsServers.append(",");
}
dnsServers.append(straddr);
}
}

res_ndestroy(&res);
}

if (!dnsServers.size())
{
LOG_warn << "Failed to get DNS servers from OS";
}
#endif
}

bool HttpIO::setmaxdownloadspeed(m_off_t)
{
return false;
Expand Down
99 changes: 1 addition & 98 deletions src/megaapi_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,6 @@
#ifdef __APPLE__
#include <xlocale.h>
#include <strings.h>

#if TARGET_OS_IPHONE
#include <netdb.h>
#include <resolv.h>
#include <arpa/inet.h>
#endif
#endif

#ifdef _WIN32
Expand Down Expand Up @@ -6205,60 +6199,17 @@ MegaProxy *MegaApiImpl::getAutoProxySettings()

void MegaApiImpl::loop()
{
#if defined(WINDOWS_PHONE) || TARGET_OS_IPHONE
#if defined(WINDOWS_PHONE)
// Workaround to get the IP of valid DNS servers on Windows Phone/iOS
string servers;

while (true)
{
#ifdef WINDOWS_PHONE
client->httpio->getMEGADNSservers(&servers, false);
#else
__res_state res;
bool valid;
if (res_ninit(&res) == 0)
{
union res_sockaddr_union u[MAXNS];
int nscount = res_getservers(&res, u, MAXNS);

for(int i = 0; i < nscount; i++)
{
char straddr[INET6_ADDRSTRLEN];
straddr[0] = 0;
valid = false;

if (u[i].sin.sin_family == PF_INET)
{
valid = mega_inet_ntop(PF_INET, &u[i].sin.sin_addr, straddr, sizeof(straddr)) == straddr;
}

if (u[i].sin6.sin6_family == PF_INET6)
{
valid = mega_inet_ntop(PF_INET6, &u[i].sin6.sin6_addr, straddr, sizeof(straddr)) == straddr;
}

if (valid && straddr[0])
{
if (servers.size())
{
servers.append(",");
}
servers.append(straddr);
}
}

res_ndestroy(&res);
}
#endif

if (servers.size())
break;

#ifdef WINDOWS_PHONE
std::this_thread::sleep_for(std::chrono::seconds(1));
#else
sleep(1);
#endif
}

LOG_debug << "Using DNS servers " << servers;
Expand Down Expand Up @@ -19854,54 +19805,6 @@ void MegaApiImpl::sendPendingRequests()
{
servers = dnsservers;
}
#if TARGET_OS_IPHONE
else
{
// Workaround to get the IP of valid DNS servers on iOS
__res_state res;
bool valid;
if (res_ninit(&res) == 0)
{
union res_sockaddr_union u[MAXNS];
int nscount = res_getservers(&res, u, MAXNS);

for (int i = 0; i < nscount; i++)
{
char straddr[INET6_ADDRSTRLEN];
straddr[0] = 0;
valid = false;

if (u[i].sin.sin_family == PF_INET)
{
valid = mega_inet_ntop(PF_INET, &u[i].sin.sin_addr, straddr, sizeof(straddr)) == straddr;
}

if (u[i].sin6.sin6_family == PF_INET6)
{
valid = mega_inet_ntop(PF_INET6, &u[i].sin6.sin6_addr, straddr, sizeof(straddr)) == straddr;
}

if (valid && straddr[0])
{
if (servers.size())
{
servers.append(",");
}
servers.append(straddr);
}
}

res_ndestroy(&res);
}

if (!servers.size())
{
LOG_warn << "Failed to get DNS servers at Retry Pending Connections";
e = API_EACCESS; // ie. when iOS has no Internet connection at all
break;
}
}
#endif
#ifndef __MINGW32__
if (servers.size())
{
Expand Down
24 changes: 24 additions & 0 deletions src/posix/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ CurlHttpIO::CurlHttpIO()
options.tries = 2;
ares_init_options(&ares, &options, ARES_OPT_TRIES);
arestimeout = -1;

filterDNSservers();

curl_multi_setopt(curlm[API], CURLMOPT_SOCKETFUNCTION, api_socket_callback);
Expand Down Expand Up @@ -384,6 +385,11 @@ bool CurlHttpIO::ipv6available()

void CurlHttpIO::filterDNSservers()
{
// in iOS, DNS resolution is done by cUrl directly (c-ares is not involved at all)
#ifdef TARGET_OS_IPHONE
return;
#endif

string newservers;
string serverlist;
set<string> serverset;
Expand Down Expand Up @@ -1399,6 +1405,8 @@ void CurlHttpIO::send_request(CurlHttpContext* httpctx)
httpctx->posturl.replace(httpctx->posturl.find(httpctx->hostname), httpctx->hostname.size(), httpctx->hostip);
httpctx->headers = curl_slist_append(httpctx->headers, httpctx->hostheader.c_str());
}

#ifndef TARGET_OS_IPHONE
else
{
LOG_err << "No IP nor proxy available";
Expand All @@ -1414,6 +1422,7 @@ void CurlHttpIO::send_request(CurlHttpContext* httpctx)
httpio->statechange = true;
return;
}
#endif

CURL* curl;
if ((curl = curl_easy_init()))
Expand Down Expand Up @@ -1590,7 +1599,11 @@ void CurlHttpIO::request_proxy_ip()
httpctx->httpio = this;
httpctx->hostname = proxyhost;
httpctx->ares_pending = 1;


#if TARGET_OS_IPHONE
send_request(httpctx);
#else
if (ipv6proxyenabled)
{
httpctx->ares_pending++;
Expand All @@ -1600,6 +1613,7 @@ void CurlHttpIO::request_proxy_ip()

LOG_debug << "Resolving IPv4 address for proxy: " << proxyhost;
ares_gethostbyname(ares, proxyhost.c_str(), PF_INET, proxy_ready_callback, httpctx);
#endif
}

bool CurlHttpIO::crackurl(string* url, string* scheme, string* hostname, int* port)
Expand Down Expand Up @@ -1907,6 +1921,9 @@ void CurlHttpIO::post(HttpReq* req, const char* data, unsigned len)
return;
}

#if TARGET_OS_IPHONE
send_request(httpctx);
#else
if (ipv6requestsenabled)
{
httpctx->ares_pending++;
Expand All @@ -1916,6 +1933,7 @@ void CurlHttpIO::post(HttpReq* req, const char* data, unsigned len)

LOG_debug << "Resolving IPv4 address for " << httpctx->hostname;
ares_gethostbyname(ares, httpctx->hostname.c_str(), PF_INET, ares_completed_callback, httpctx);
#endif
}

void CurlHttpIO::setproxy(Proxy* proxy)
Expand Down Expand Up @@ -2614,6 +2632,11 @@ int CurlHttpIO::sockopt_callback(void *clientp, curl_socket_t, curlsocktype)
{
httpio->dnscache[httpctx->hostname].mNeedsResolvingAgain = false;
httpctx->ares_pending = 1;


#if TARGET_OS_IPHONE
send_request(httpctx);
#else
if (httpio->ipv6requestsenabled)
{
httpctx->ares_pending++;
Expand All @@ -2623,6 +2646,7 @@ int CurlHttpIO::sockopt_callback(void *clientp, curl_socket_t, curlsocktype)

LOG_debug << "Resolving IPv4 address for " << httpctx->hostname << " during connection";
ares_gethostbyname(httpio->ares, httpctx->hostname.c_str(), PF_INET, ares_completed_callback, httpctx);
#endif
}

return CURL_SOCKOPT_OK;
Expand Down

0 comments on commit 33d946d

Please sign in to comment.