diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java
index 9e4f5d51d10e15e55dce2db7785d4d612f8784ac..f441e340c32834ae83eb122dec25b3c62afa3cbf 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java
@@ -23,6 +23,7 @@ import org.json.JSONObject;
 
 import java.util.ArrayList;
 
+import de.blinkt.openvpn.core.connection.Connection;
 import se.leap.bitmaskclient.base.models.Transport;
 import se.leap.bitmaskclient.base.utils.ConfigHelper;
 import se.leap.bitmaskclient.base.utils.ConfigHelper.ObfsVpnHelper;
@@ -77,23 +78,36 @@ public class ObfuscationProxyDialog extends AppCompatDialogFragment {
                     Transport transport = Transport.fromJson(jsonObject);
                     if (transport.getOptions() == null) {
                         errors.add("Missing Bridge Options");
-                    }
-                    if (transport.getOptions() != null &&
-                            (transport.getOptions().getEndpoints() == null || transport.getOptions().getEndpoints().length == 0)) {
-                        errors.add("Cert and IP is missing");
-                    }
-                    if (transport.getOptions() != null && transport.getOptions().getEndpoints() != null) {
-                        for (Transport.Endpoint endpoint : transport.getOptions().getEndpoints()) {
-                            if (endpoint.getIp() == null || endpoint.getIp().isEmpty()) {
-                                errors.add("IP is missing");
-                            } else if (!ConfigHelper.isIPv4(endpoint.getIp())) {
-                                errors.add("Invalid IPv4 address");
+                    } else {
+                        if (transport.getOptions().getEndpoints() == null ||
+                                transport.getOptions().getEndpoints().length == 0) {
+                            errors.add("Cert and IP is missing");
+                        }
+                        int iatMode;
+                        try {
+                            if (transport.getOptions().getIatMode() == null ||
+                                    transport.getOptions().getIatMode().isEmpty()) {
+                                errors.add("iat mode is missing");
+                            } else if ((iatMode = Integer.parseInt(transport.getOptions().getIatMode())) < 0 || (iatMode > 1)) {
+                                errors.add("invalid iat mode (0 or 1)");
                             }
-                            if (endpoint.getCert() == null || endpoint.getCert().isEmpty()) {
-                                errors.add("Cert is missing");
+                        } catch (NumberFormatException nfe) {
+                            errors.add("invalid iat mode (0 or 1)");
+                        }
+                        if (transport.getOptions().getEndpoints() != null) {
+                            for (Transport.Endpoint endpoint : transport.getOptions().getEndpoints()) {
+                                if (endpoint.getIp() == null || endpoint.getIp().isEmpty()) {
+                                    errors.add("IP is missing");
+                                } else if (!ConfigHelper.isIPv4(endpoint.getIp())) {
+                                    errors.add("Invalid IPv4 address");
+                                }
+                                if (endpoint.getCert() == null || endpoint.getCert().isEmpty()) {
+                                    errors.add("Cert is missing");
+                                }
                             }
                         }
                     }
+
                     if (transport.getProtocols() == null || transport.getProtocols().length == 0) {
                         errors.add("missing protocols");
                     }
@@ -105,10 +119,31 @@ public class ObfuscationProxyDialog extends AppCompatDialogFragment {
                     } catch (NullPointerException | IllegalArgumentException e) {}
                     if (!hasValidTransportType) {
                         errors.add("invalid bridge transport type");
-                    } else if (!hasPTAllowedProtocol(transport)) {
-                        errors.add("invalid protocol for transport " + transport.getType());
+                    } else {
+                        if (!hasPTAllowedProtocol(transport)) {
+                            errors.add("invalid protocol for transport " + transport.getType());
+                        }
+                        if (transport.getTransportType() != Connection.TransportType.OBFS4_HOP &&
+                                (transport.getPorts() == null || transport.getPorts().length == 0)) {
+                            errors.add("ports are missing");
+                        } else {
+                            for (String port: transport.getPorts()) {
+                                try {
+                                    int portNumber = Integer.parseInt(port);
+                                    if (portNumber < 1 || portNumber > 65535) {
+                                        errors.add("invalid port number (1-65535)");
+                                    }
+                                } catch (NumberFormatException e) {
+                                    if (port.isEmpty()) {
+                                        errors.add("bridge port value cannot be empty");
+                                    } else {
+                                        errors.add(port + " is an invalid value for bridge ports");
+                                    }
+                                }
+                            }
+                        }
                     }
-                } catch (IllegalStateException | JSONException e) {
+                } catch (Exception e) {
                     errors.add("invalid json format");
                 }
                 StringBuilder stringBuilder = new StringBuilder();
@@ -117,6 +152,7 @@ public class ObfuscationProxyDialog extends AppCompatDialogFragment {
                     int diff = 0;
                     if (i == 2 && (diff = errors.size() - 3) > 0) {
                         stringBuilder.append(diff + " more...");
+                        break;
                     }
                 }
                 validityCheck.setText(stringBuilder.toString());
@@ -124,20 +160,18 @@ public class ObfuscationProxyDialog extends AppCompatDialogFragment {
             }
         });
 
-
-        try {
-            Transport transport = Transport.fromJson(new JSONObject(PreferenceHelper.getObfuscationPinningTransport(getContext())));
+        Transport transport = PreferenceHelper.getObfuscationPinningTransport(getContext(), false);
+        if (transport != null) {
             bridgeConfig.setText(transport.toPrettyPrint());
-        } catch (Exception e) {
-            // eat me
         }
+
         saveButton.setOnClickListener(v -> {
             JSONObject jsonObject = null;
             try {
                 jsonObject = new JSONObject(bridgeConfig.getText().toString());
-                Transport transport = Transport.fromJson(jsonObject);
-                PreferenceHelper.setObfuscationPinningGatewayLocation(v.getContext(), gatewaysManager.getLocationNameForIP(transport.getOptions().getEndpoints()[0].getIp(), v.getContext()));
-                PreferenceHelper.setObufscationPinningTransport(v.getContext(), transport);
+                Transport t = Transport.fromJson(jsonObject);
+                PreferenceHelper.setObfuscationPinningGatewayLocation(v.getContext(), gatewaysManager.getLocationNameForIP(t.getIPFromEndpoints(), v.getContext()));
+                PreferenceHelper.setObfuscationPinningTransport(v.getContext(), t);
             } catch (JSONException | NullPointerException | ArrayIndexOutOfBoundsException e) {}
 
             dismiss();
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Transport.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Transport.java
index ddd75ddadfc48897c4de02769c3fab13c6a01135..1256277a32668310ce9a9c9200813bd209176691 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Transport.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Transport.java
@@ -64,6 +64,20 @@ public class Transport implements Serializable {
         return gson.toJson(this);
     }
 
+    public @Nullable String getIPFromEndpoints() {
+        if (options == null || options.endpoints == null || options.endpoints.length == 0) {
+            return null;
+        }
+        return options.endpoints[0].ip;
+    }
+
+    public @Nullable String getCertFromEndpoints() {
+        if (options == null || options.endpoints == null || options.endpoints.length == 0) {
+            return null;
+        }
+        return options.endpoints[0].cert;
+    }
+
     public static Transport fromJson(JSONObject json) {
         GsonBuilder builder = new GsonBuilder();
         return builder.
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java
index f08a98e0a7446288d12754ba5cbbc6dd3c30694f..0b278ed418b169780e9bace0fc197bfea75a2fd1 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java
@@ -37,7 +37,6 @@ import static se.leap.bitmaskclient.base.models.Constants.USE_SNOWFLAKE;
 
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.WorkerThread;
@@ -51,6 +50,7 @@ import java.util.HashSet;
 import java.util.Set;
 
 import de.blinkt.openvpn.VpnProfile;
+import de.blinkt.openvpn.core.connection.Connection;
 import se.leap.bitmaskclient.BuildConfig;
 import se.leap.bitmaskclient.base.models.Provider;
 import se.leap.bitmaskclient.base.models.Transport;
@@ -332,12 +332,29 @@ public class PreferenceHelper {
                 getObfuscationPinningTransport(context) != null;
     }
 
-    public static void setObufscationPinningTransport(Context context, Transport transport) {
+    public static void setObfuscationPinningTransport(Context context, Transport transport) {
         putString(context, OBFUSCATION_PINNING_TRANSPORT, transport.toString());
     }
 
-    public static String getObfuscationPinningTransport(Context context) {
-        return getString(context, OBFUSCATION_PINNING_TRANSPORT, null);
+    public static Transport getObfuscationPinningTransport(Context context) {
+        return getObfuscationPinningTransport(context, true);
+    }
+
+    public static Transport getObfuscationPinningTransport(Context context, boolean compatFix) {
+        try {
+            String transportString = getString(context, OBFUSCATION_PINNING_TRANSPORT, null);
+            if (transportString != null) {
+                Transport transport = Transport.fromJson(new JSONObject(getString(context, OBFUSCATION_PINNING_TRANSPORT, null)));
+                // compatibility hack...
+                if (compatFix && transport.getTransportType() == Connection.TransportType.OBFS4) {
+                    transport.getOptions().setCert(transport.getCertFromEndpoints());
+                }
+                return transport;
+            }
+        } catch (JSONException | NullPointerException e) {
+            e.printStackTrace();
+        }
+        return null;
     }
 
     public static void setObfuscationPinningIP(Context context, String ip) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
index 0ee1695cc51eef954fbe86fec2436de099e60362..92323d13387afd228a5f47915ca06da3d830eeac 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
@@ -16,7 +16,6 @@
  */
 package se.leap.bitmaskclient.eip;
 
-import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4;
 import static de.blinkt.openvpn.core.connection.Connection.TransportType.PT;
 import static se.leap.bitmaskclient.base.models.Constants.FULLNESS;
 import static se.leap.bitmaskclient.base.models.Constants.HOST;
@@ -30,11 +29,7 @@ import static se.leap.bitmaskclient.base.models.Constants.TIMEZONE;
 import static se.leap.bitmaskclient.base.models.Constants.VERSION;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.allowExperimentalTransports;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getExcludedApps;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningCert;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningGatewayLocation;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningIP;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningKCP;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningPort;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningTransport;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferUDP;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useObfuscationPinning;
@@ -116,10 +111,10 @@ public class Gateway {
         config.experimentalTransports = allowExperimentalTransports(context);
         config.excludedApps = getExcludedApps(context);
         config.useObfuscationPinning = useObfuscationPinning(context);
-                if (config.useObfuscationPinning) {
+        if (config.useObfuscationPinning) {
             try {
-                Transport transport = Transport.fromJson(new JSONObject(getObfuscationPinningTransport(context)));
-                config.remoteGatewayIP = transport.getOptions().getEndpoints()[0].getIp();
+                Transport transport = getObfuscationPinningTransport(context);
+                config.remoteGatewayIP = transport.getIPFromEndpoints();
                 config.obfuscationProxyTransport = transport;
                 config.profileName = getObfuscationPinningGatewayLocation(context);
             } catch (Exception e) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
index d114665b87006da79adf6ad619c0bdc6cdc548be..a867805931a15d812ed901c3e5d16b224c25f4b7 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
@@ -25,10 +25,7 @@ import static se.leap.bitmaskclient.base.models.Constants.HOST;
 import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY;
 import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
 import static se.leap.bitmaskclient.base.models.Constants.SORTED_GATEWAYS;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningCert;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningIP;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningKCP;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningPort;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningTransport;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferredCity;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges;
 
@@ -402,13 +399,10 @@ public class GatewaysManager {
 
              if (PreferenceHelper.useObfuscationPinning(context)) {
                  try {
-                     Transport[] transports = new Transport[]{
-                             new Transport(OBFS4.toString(),
-                                     new String[]{getObfuscationPinningKCP(context) ? "kcp" : "tcp"},
-                                     new String[]{getObfuscationPinningPort(context)},
-                                     getObfuscationPinningCert(context))};
+                     Transport transport = getObfuscationPinningTransport(context);
+                     Transport[] transports = new Transport[]{transport};
                      GatewayJson.Capabilities capabilities = new GatewayJson.Capabilities(false, false, false, transports, false);
-                     GatewayJson gatewayJson = new GatewayJson(context.getString(R.string.unknown_location), getObfuscationPinningIP(context), null, PINNED_OBFUSCATION_PROXY, capabilities);
+                     GatewayJson gatewayJson = new GatewayJson(context.getString(R.string.unknown_location), transport.getIPFromEndpoints(), null, PINNED_OBFUSCATION_PROXY, capabilities);
                      Gateway gateway = new Gateway(eipDefinition, secrets, new JSONObject(gatewayJson.toString()), this.context);
                      addGateway(gateway);
                  } catch (JSONException | ConfigParser.ConfigParseError | IOException e) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
index a5d9224ff0a22272c4ec3bac25dd8235a139e989..710980a80bd4c8bd4f302c995ed3cf5869d273db 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
@@ -22,7 +22,6 @@ import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN
 import static se.leap.bitmaskclient.base.models.Constants.CAPABILITIES;
 import static se.leap.bitmaskclient.base.models.Constants.IP_ADDRESS;
 import static se.leap.bitmaskclient.base.models.Constants.IP_ADDRESS6;
-import static se.leap.bitmaskclient.base.models.Constants.KCP;
 import static se.leap.bitmaskclient.base.models.Constants.PORTS;
 import static se.leap.bitmaskclient.base.models.Constants.PROTOCOLS;
 import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY;
@@ -69,12 +68,6 @@ public class VpnConfigGenerator {
     private final boolean preferUDP;
     private final boolean experimentalTransports;
     private final boolean useObfuscationPinning;
-
-    private final Transport obfuscationPinningTransport;
-  //  private final String obfuscationPinningIP;
-  //  private final String obfuscationPinningPort;
-  //  private final String obfuscationPinningCert;
-  //  private final boolean obfuscationPinningKCP;
     private final String remoteGatewayIP;
     private final String profileName;
     private final Set<String> excludedApps;
@@ -92,11 +85,6 @@ public class VpnConfigGenerator {
         Set<String> excludedApps = null;
 
         boolean useObfuscationPinning;
-  //      boolean obfuscationProxyKCP;
- //       String obfuscationProxyIP = "";
- //       String obfuscationProxyPort = "";
- //       String obfuscationProxyCert = "";
-
         Transport obfuscationProxyTransport;
     }
 
@@ -108,11 +96,14 @@ public class VpnConfigGenerator {
         this.preferUDP = config.preferUDP;
         this.experimentalTransports = config.experimentalTransports;
         this.useObfuscationPinning = config.useObfuscationPinning;
-        this.obfuscationPinningTransport = useObfuscationPinning ? config.obfuscationProxyTransport : null;
         this.remoteGatewayIP = config.remoteGatewayIP;
         this.profileName = config.profileName;
         this.excludedApps = config.excludedApps;
-        checkCapabilities();
+        if (useObfuscationPinning) {
+            transports.put(config.obfuscationProxyTransport.getTransportType(), config.obfuscationProxyTransport);
+        } else {
+            checkCapabilities();
+        }
     }
 
     public void checkCapabilities() throws ConfigParser.ConfigParseError {
@@ -197,18 +188,8 @@ public class VpnConfigGenerator {
     }
 
     private Obfs4Options getObfs4Options(TransportType transportType) throws JSONException {
-        String ip = gateway.getString(IP_ADDRESS);
-        Transport transport;
-        if (useObfuscationPinning) {
-            transport = obfuscationPinningTransport;
-            ip = obfuscationPinningTransport.getOptions().getEndpoints()[0].getIp();
-            // hack just for compatibility reasons for now
-            if (obfuscationPinningTransport.getTransportType() == OBFS4) {
-                obfuscationPinningTransport.getOptions().setCert(obfuscationPinningTransport.getOptions().getEndpoints()[0].getCert());
-            }
-        } else {
-            transport = transports.get(transportType);
-        }
+        Transport transport = transports.get(transportType);
+        String ip = useObfuscationPinning ? transport.getIPFromEndpoints() : gateway.getString(IP_ADDRESS);
         return new Obfs4Options(ip, transport);
     }
 
@@ -390,9 +371,6 @@ public class VpnConfigGenerator {
 
     public String getRemoteString(String ipAddress, Transport transport) {
         if (useObfsVpn()) {
-            if (useObfuscationPinning) {
-                return REMOTE + " " + obfuscationPinningTransport.getOptions().getEndpoints()[0].getIp() + " " + obfuscationPinningTransport.getProtocols()[0] + " tcp" + newLine;
-            }
             switch (transport.getTransportType()) {
                 case OBFS4:
                     return REMOTE + " " + ipAddress + " " + transport.getPorts()[0] + " tcp" + newLine;
@@ -416,9 +394,6 @@ public class VpnConfigGenerator {
     }
 
     public String getRouteString(String ipAddress, Transport transport) {
-        if (useObfuscationPinning) {
-            return "route " + remoteGatewayIP + " 255.255.255.255 net_gateway" + newLine;
-        }
         switch (transport.getTransportType()) {
             case OBFS4:
                 return "route " + ipAddress + " 255.255.255.255 net_gateway" + newLine;