diff --git a/TunSafe.vcxproj b/TunSafe.vcxproj
index 94651a4..ea793d3 100644
--- a/TunSafe.vcxproj
+++ b/TunSafe.vcxproj
@@ -195,6 +195,7 @@
+
diff --git a/TunSafe.vcxproj.filters b/TunSafe.vcxproj.filters
index a035bde..77805db 100644
--- a/TunSafe.vcxproj.filters
+++ b/TunSafe.vcxproj.filters
@@ -123,6 +123,9 @@
Source Files
+
+ Source Files
+
diff --git a/tunsafe_dnsresolve.h b/tunsafe_dnsresolve.h
index f3a1ff4..5733057 100644
--- a/tunsafe_dnsresolve.h
+++ b/tunsafe_dnsresolve.h
@@ -8,12 +8,14 @@ class DnsBlocker;
class DnsResolverCanceller {
public:
- DnsResolverCanceller() : cancel_(false) {}
+ DnsResolverCanceller() : cancel_(false), cancel_sleep_once_(false) {}
void Cancel();
+ void CancelSleepOnce();
void Reset() { cancel_ = false; }
bool is_cancelled() { return cancel_; }
public:
bool cancel_;
+ bool cancel_sleep_once_;
ConditionVariable condvar_;
};
@@ -25,6 +27,7 @@ public:
bool Resolve(const char *hostname, IpAddr *result);
void ClearCache();
+ void RetryNow();
void Cancel() { token_.Cancel(); }
void ResetCancel() { token_.Reset(); }
private:
@@ -36,6 +39,7 @@ private:
std::vector cache_;
DnsBlocker *dns_blocker_;
DnsResolverCanceller token_;
+ int retry_attempt_;
};
#endif // TUNSAFE_DNSRESOLVE_H_
\ No newline at end of file
diff --git a/tunsafe_ipaddr.cpp b/tunsafe_ipaddr.cpp
index aed2abf..94b0809 100644
--- a/tunsafe_ipaddr.cpp
+++ b/tunsafe_ipaddr.cpp
@@ -140,6 +140,15 @@ void DnsResolverCanceller::Cancel() {
g_dns_mutex.Release();
}
+void DnsResolverCanceller::CancelSleepOnce() {
+ g_dns_mutex.Acquire();
+ cancel_sleep_once_ = true;
+ condvar_.Wake();
+ g_dns_mutex.Release();
+}
+
+
+
bool DnsResolverThread::Resolve(const char *hostname, IpAddr *result, DnsResolverCanceller *token) {
if (token->cancel_)
return false;
@@ -188,15 +197,23 @@ void DnsResolverThread::ThreadMain() {
struct addrinfo hints = {0};
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
+ // AI_V4MAPPED doesn't work on Android?!
+#if defined(OS_IOS)
hints.ai_flags = AI_DEFAULT;
+#else
+ hints.ai_flags = AI_ADDRCONFIG ;
+#endif
ai = NULL;
- if (getaddrinfo(e->hostname, NULL, &hints, &ai) != 0)
+ int r = getaddrinfo(e->hostname, NULL, &hints, &ai);
+ if (r != 0)
ai = NULL;
+// RINFO("r=%d errno=%d, %s", r, errno, gai_strerror(r));
// he = gethostbyname(e->hostname);
g_dns_mutex.Acquire();
if (e->state == Entry::CANCELLED) {
delete e;
} else {
+// RINFO("ai=%p, family=%d", ai, ai ? ai->ai_family : -1);
if (ai) {
e->result->sin.sin_family = ai->ai_family;
e->result->sin.sin_port = 0;
@@ -228,6 +245,11 @@ static bool InterruptibleSleep(int delay, DnsResolverCanceller *token) {
g_dns_mutex.Acquire();
uint32 time_at_start = (uint32)OsGetMilliseconds();
while (delay > 0 && !token->cancel_) {
+ if (token->cancel_sleep_once_) {
+ token->cancel_sleep_once_ = false;
+ delay = 0;
+ break;
+ }
token->condvar_.WaitTimed(&g_dns_mutex, delay);
uint32 now = (uint32)OsGetMilliseconds();
delay -= (now - time_at_start);
@@ -249,10 +271,11 @@ void DnsResolver::ClearCache() {
}
bool DnsResolver::Resolve(const char *hostname, IpAddr *result) {
- int attempt = 0;
- static const uint8 retry_delays[] = {1, 2, 3, 5, 10};
+ static const uint8 retry_delays[] = {1, 2, 3, 5, 10, 20, 40, 60, 120, 180, 255};
char buf[kSizeOfAddress];
+ retry_attempt_ = 0;
+
memset(result, 0, sizeof(IpAddr));
// First check cache
@@ -283,15 +306,20 @@ bool DnsResolver::Resolve(const char *hostname, IpAddr *result) {
if (token_.is_cancelled())
return false;
- RINFO("Unable to resolve %s. Trying again in %d second(s)", hostname, retry_delays[attempt]);
- if (!InterruptibleSleep(retry_delays[attempt] * 1000, &token_))
+ RINFO("Unable to resolve %s. Trying again in %d second(s)", hostname, retry_delays[retry_attempt_]);
+ if (!InterruptibleSleep(retry_delays[retry_attempt_] * 1000, &token_))
return false;
- if (attempt != ARRAY_SIZE(retry_delays) - 1)
- attempt++;
+ if (retry_attempt_ != ARRAY_SIZE(retry_delays) - 1)
+ retry_attempt_++;
}
}
+void DnsResolver::RetryNow() {
+ retry_attempt_ = 0;
+ token_.CancelSleepOnce();
+}
+
// Parse an IPV4 address into sin, doing NAT64 translation if applicable (on IOS)
static bool ParseIpv4WithNAT64Translation(const char *s, IpAddr *sin, int flags) {
// First verify it's actually a valid ipv4 address to prevent getaddrinfo from doing a slow resolve