tunnel: retry DNS resolution for 10 seconds
This has several problems: 1) it blocks the main thread; 2) it doesn't distinguish between a permanent error and a transient one; 3) the 10 seconds is hard coded; 4) there's no way for the user to cancel it. We'll have to improve this. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
24ded8070f
commit
fe61522f2a
@ -55,6 +55,7 @@ public final class BackendException extends Exception {
|
|||||||
VPN_NOT_AUTHORIZED,
|
VPN_NOT_AUTHORIZED,
|
||||||
UNABLE_TO_START_VPN,
|
UNABLE_TO_START_VPN,
|
||||||
TUN_CREATION_ERROR,
|
TUN_CREATION_ERROR,
|
||||||
GO_ACTIVATION_ERROR_CODE
|
GO_ACTIVATION_ERROR_CODE,
|
||||||
|
DNS_RESOLUTION_FAILURE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import com.wireguard.android.backend.BackendException.Reason;
|
|||||||
import com.wireguard.android.backend.Tunnel.State;
|
import com.wireguard.android.backend.Tunnel.State;
|
||||||
import com.wireguard.android.util.SharedLibraryLoader;
|
import com.wireguard.android.util.SharedLibraryLoader;
|
||||||
import com.wireguard.config.Config;
|
import com.wireguard.config.Config;
|
||||||
|
import com.wireguard.config.InetEndpoint;
|
||||||
import com.wireguard.config.InetNetwork;
|
import com.wireguard.config.InetNetwork;
|
||||||
import com.wireguard.config.Peer;
|
import com.wireguard.config.Peer;
|
||||||
import com.wireguard.crypto.Key;
|
import com.wireguard.crypto.Key;
|
||||||
@ -40,6 +41,7 @@ import androidx.collection.ArraySet;
|
|||||||
*/
|
*/
|
||||||
@NonNullForAll
|
@NonNullForAll
|
||||||
public final class GoBackend implements Backend {
|
public final class GoBackend implements Backend {
|
||||||
|
private static final int DNS_RESOLUTION_RETRIES = 10;
|
||||||
private static final String TAG = "WireGuard/GoBackend";
|
private static final String TAG = "WireGuard/GoBackend";
|
||||||
@Nullable private static AlwaysOnCallback alwaysOnCallback;
|
@Nullable private static AlwaysOnCallback alwaysOnCallback;
|
||||||
private static GhettoCompletableFuture<VpnService> vpnService = new GhettoCompletableFuture<>();
|
private static GhettoCompletableFuture<VpnService> vpnService = new GhettoCompletableFuture<>();
|
||||||
@ -234,6 +236,25 @@ public final class GoBackend implements Backend {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dnsRetry: for (int i = 0; i < DNS_RESOLUTION_RETRIES; ++i) {
|
||||||
|
// Pre-resolve IPs so they're cached when building the userspace string
|
||||||
|
for (final Peer peer : config.getPeers()) {
|
||||||
|
final InetEndpoint ep = peer.getEndpoint().orElse(null);
|
||||||
|
if (ep == null)
|
||||||
|
continue;
|
||||||
|
if (ep.getResolved().orElse(null) == null) {
|
||||||
|
if (i < DNS_RESOLUTION_RETRIES - 1) {
|
||||||
|
Log.w(TAG, "DNS host \"" + ep.getHost() + "\" failed to resolve; trying again");
|
||||||
|
Thread.sleep(1000);
|
||||||
|
continue dnsRetry;
|
||||||
|
} else
|
||||||
|
throw new BackendException(Reason.DNS_RESOLUTION_FAILURE, ep.getHost());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Build config
|
// Build config
|
||||||
final String goConfig = config.toWgUserspaceString();
|
final String goConfig = config.toWgUserspaceString();
|
||||||
|
|
||||||
|
@ -36,7 +36,8 @@ object ErrorMessages {
|
|||||||
BackendException.Reason.VPN_NOT_AUTHORIZED to R.string.vpn_not_authorized_error,
|
BackendException.Reason.VPN_NOT_AUTHORIZED to R.string.vpn_not_authorized_error,
|
||||||
BackendException.Reason.UNABLE_TO_START_VPN to R.string.vpn_start_error,
|
BackendException.Reason.UNABLE_TO_START_VPN to R.string.vpn_start_error,
|
||||||
BackendException.Reason.TUN_CREATION_ERROR to R.string.tun_create_error,
|
BackendException.Reason.TUN_CREATION_ERROR to R.string.tun_create_error,
|
||||||
BackendException.Reason.GO_ACTIVATION_ERROR_CODE to R.string.tunnel_on_error
|
BackendException.Reason.GO_ACTIVATION_ERROR_CODE to R.string.tunnel_on_error,
|
||||||
|
BackendException.Reason.DNS_RESOLUTION_FAILURE to R.string.tunnel_dns_failure
|
||||||
)
|
)
|
||||||
private val KFE_FORMAT_MAP = mapOf(
|
private val KFE_FORMAT_MAP = mapOf(
|
||||||
Key.Format.BASE64 to R.string.key_length_explanation_base64,
|
Key.Format.BASE64 to R.string.key_length_explanation_base64,
|
||||||
|
@ -214,6 +214,7 @@
|
|||||||
<string name="tunnel_list_placeholder">Add a tunnel using the blue button</string>
|
<string name="tunnel_list_placeholder">Add a tunnel using the blue button</string>
|
||||||
<string name="tunnel_name">Tunnel Name</string>
|
<string name="tunnel_name">Tunnel Name</string>
|
||||||
<string name="tunnel_on_error">Unable to turn tunnel on (wgTurnOn returned %d)</string>
|
<string name="tunnel_on_error">Unable to turn tunnel on (wgTurnOn returned %d)</string>
|
||||||
|
<string name="tunnel_dns_failure">Unable to resolve DNS hostname: “%s”</string>
|
||||||
<string name="tunnel_rename_error">Unable to rename tunnel: %s</string>
|
<string name="tunnel_rename_error">Unable to rename tunnel: %s</string>
|
||||||
<string name="tunnel_rename_success">Successfully renamed tunnel to “%s”</string>
|
<string name="tunnel_rename_success">Successfully renamed tunnel to “%s”</string>
|
||||||
<string name="type_name_go_userspace">Go userspace</string>
|
<string name="type_name_go_userspace">Go userspace</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user