Force rawrtc to load ice candidates on ports 5800-5810

For forcing chrome (on Windows) to do a similar limit, see
https://getadmx.com/?Category=Chrome&Policy=Google.Policies.Chrome::WebRtcUdpPortRange
wherein you set the Software\Policies\Google\Chrome\WebRtcUdpPortRange
registry setting to "5800-5810"

Change-Id: I943b75b83eb93b4931f2b0cde799d82dcaac2b84
Signed-off-by: James Kuszmaul <jabukuszmaul@gmail.com>
diff --git a/aos/network/rawrtc.cc b/aos/network/rawrtc.cc
index a92b408..89141db 100644
--- a/aos/network/rawrtc.cc
+++ b/aos/network/rawrtc.cc
@@ -12,6 +12,11 @@
 #include "flatbuffers/flatbuffers.h"
 #include "glog/logging.h"
 
+DEFINE_int32(min_ice_port, -1,
+             "Minimum port number to use for ICE candidates.");
+DEFINE_int32(max_ice_port, -1,
+             "Maximum port number to use for ICE candidates.");
+
 namespace aos {
 namespace web_proxy {
 namespace {
@@ -186,6 +191,13 @@
   CHECK_RAWRTC(rawrtc_peer_connection_configuration_set_sctp_buffer_length(
       configuration, TRANSPORT_BUFFER_LENGTH, TRANSPORT_BUFFER_LENGTH));
 
+  if (FLAGS_min_ice_port >= 0 && FLAGS_max_ice_port >= 0) {
+    CHECK_LT(FLAGS_min_ice_port, FLAGS_max_ice_port);
+    // Set the port range to use for ICE candidates.
+    CHECK_RAWRTC(rawrtc_peer_connection_configuration_set_ice_udp_port_range(
+        configuration, FLAGS_min_ice_port, FLAGS_max_ice_port));
+  }
+
   // Create peer connection
   CHECK_RAWRTC(rawrtc_peer_connection_create(
       &connection_, configuration, StaticNegotiationNeededHandler,
diff --git a/third_party/rawrtc/rawrtc/include/rawrtc/ice_gather_options.h b/third_party/rawrtc/rawrtc/include/rawrtc/ice_gather_options.h
index e676947..d30613b 100644
--- a/third_party/rawrtc/rawrtc/include/rawrtc/ice_gather_options.h
+++ b/third_party/rawrtc/rawrtc/include/rawrtc/ice_gather_options.h
@@ -34,6 +34,14 @@
     enum rawrtc_ice_gather_policy const gather_policy);
 
 /*
+ * Force ICE candidates to be generated within a specific range of UDP ports.
+ */
+enum rawrtc_code rawrtc_ice_gather_options_set_udp_port_range(
+    struct rawrtc_ice_gather_options* const options,
+    uint16_t min_udp_port,
+    uint16_t max_udp_port);
+
+/*
  * Add an ICE server to the gather options.
  */
 enum rawrtc_code rawrtc_ice_gather_options_add_server(
diff --git a/third_party/rawrtc/rawrtc/include/rawrtc/peer_connection_configuration.h b/third_party/rawrtc/rawrtc/include/rawrtc/peer_connection_configuration.h
index 6d92d20..c331211 100644
--- a/third_party/rawrtc/rawrtc/include/rawrtc/peer_connection_configuration.h
+++ b/third_party/rawrtc/rawrtc/include/rawrtc/peer_connection_configuration.h
@@ -94,3 +94,11 @@
  */
 enum rawrtc_code rawrtc_peer_connection_configuration_set_sctp_mtu_discovery(
     struct rawrtc_peer_connection_configuration* configuration, bool on);
+
+/*
+ * Force local ICE candidate generation to use the specified local UDP ports.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_set_ice_udp_port_range(
+    struct rawrtc_peer_connection_configuration* configuration,
+    uint16_t min_port,
+    uint16_t max_port);
diff --git a/third_party/rawrtc/rawrtc/src/ice_gather_options/options.c b/third_party/rawrtc/rawrtc/src/ice_gather_options/options.c
index 92dbb06..24005ce 100644
--- a/third_party/rawrtc/rawrtc/src/ice_gather_options/options.c
+++ b/third_party/rawrtc/rawrtc/src/ice_gather_options/options.c
@@ -43,6 +43,25 @@
     return RAWRTC_CODE_SUCCESS;
 }
 
+enum rawrtc_code rawrtc_ice_gather_options_set_udp_port_range(
+    struct rawrtc_ice_gather_options* const options,
+    uint16_t min_udp_port,
+    uint16_t max_udp_port) {
+
+    if (!options) {
+        return RAWRTC_CODE_INVALID_ARGUMENT;
+    }
+
+    if (max_udp_port <= min_udp_port) {
+        return RAWRTC_CODE_INVALID_ARGUMENT;
+    }
+
+    options->udp_port_range.min = min_udp_port;
+    options->udp_port_range.max = max_udp_port;
+
+    return RAWRTC_CODE_SUCCESS;
+}
+
 /*
  * Add an ICE server instance to the gather options.
  */
diff --git a/third_party/rawrtc/rawrtc/src/ice_gather_options/options.h b/third_party/rawrtc/rawrtc/src/ice_gather_options/options.h
index c43b9c8..28a8474 100644
--- a/third_party/rawrtc/rawrtc/src/ice_gather_options/options.h
+++ b/third_party/rawrtc/rawrtc/src/ice_gather_options/options.h
@@ -7,6 +7,10 @@
 struct rawrtc_ice_gather_options {
     enum rawrtc_ice_gather_policy gather_policy;
     struct list ice_servers;
+    struct {
+        uint16_t min;
+        uint16_t max;
+    } udp_port_range;
 };
 
 enum rawrtc_code rawrtc_ice_gather_options_add_server_internal(
diff --git a/third_party/rawrtc/rawrtc/src/ice_gatherer/gatherer.c b/third_party/rawrtc/rawrtc/src/ice_gatherer/gatherer.c
index 51002fe..6a06338 100644
--- a/third_party/rawrtc/rawrtc/src/ice_gatherer/gatherer.c
+++ b/third_party/rawrtc/rawrtc/src/ice_gatherer/gatherer.c
@@ -106,6 +106,12 @@
         goto out;
     }
 
+    err = trice_set_port_range(gatherer->ice, options->udp_port_range.min, options->udp_port_range.max);
+    if (err) {
+        DEBUG_WARNING("Unable to set trickle ICE port range, reason: %m\n", err);
+        goto out;
+    }
+
     // Get local DNS servers
     err = dns_srv_get(NULL, 0, dns_servers, &n_dns_servers);
     if (err) {
diff --git a/third_party/rawrtc/rawrtc/src/peer_connection/connection.c b/third_party/rawrtc/rawrtc/src/peer_connection/connection.c
index ceb1a43..c3730b0 100644
--- a/third_party/rawrtc/rawrtc/src/peer_connection/connection.c
+++ b/third_party/rawrtc/rawrtc/src/peer_connection/connection.c
@@ -520,6 +520,13 @@
         return error;
     }
 
+    error = rawrtc_ice_gather_options_set_udp_port_range(
+        options, connection->configuration->ice_udp_port_range.min,
+        connection->configuration->ice_udp_port_range.max);
+    if (error) {
+        return error;
+    }
+
     // Add ICE servers to gather options
     for (le = list_head(&connection->configuration->ice_servers); le != NULL; le = le->next) {
         struct rawrtc_ice_server* const source_server = le->data;
diff --git a/third_party/rawrtc/rawrtc/src/peer_connection_configuration/configuration.c b/third_party/rawrtc/rawrtc/src/peer_connection_configuration/configuration.c
index ebf16f2..48fb719 100644
--- a/third_party/rawrtc/rawrtc/src/peer_connection_configuration/configuration.c
+++ b/third_party/rawrtc/rawrtc/src/peer_connection_configuration/configuration.c
@@ -258,3 +258,18 @@
     configuration->sctp.mtu_discovery = on;
     return RAWRTC_CODE_SUCCESS;
 }
+
+enum rawrtc_code rawrtc_peer_connection_configuration_set_ice_udp_port_range(
+    struct rawrtc_peer_connection_configuration* configuration,
+    uint16_t min_port,
+    uint16_t max_port) {
+    if (!configuration) {
+        return RAWRTC_CODE_INVALID_ARGUMENT;
+    }
+    if (max_port <= min_port) {
+        return RAWRTC_CODE_INVALID_ARGUMENT;
+    }
+    configuration->ice_udp_port_range.min = min_port;
+    configuration->ice_udp_port_range.max = max_port;
+    return RAWRTC_CODE_SUCCESS;
+}
diff --git a/third_party/rawrtc/rawrtc/src/peer_connection_configuration/configuration.h b/third_party/rawrtc/rawrtc/src/peer_connection_configuration/configuration.h
index 34fd7c1..f89e7b4 100644
--- a/third_party/rawrtc/rawrtc/src/peer_connection_configuration/configuration.h
+++ b/third_party/rawrtc/rawrtc/src/peer_connection_configuration/configuration.h
@@ -17,6 +17,10 @@
         uint32_t mtu;
         bool mtu_discovery;
     } sctp;
+    struct {
+        uint16_t min;
+        uint16_t max;
+    } ice_udp_port_range;
 };
 
 enum rawrtc_code rawrtc_peer_connection_configuration_add_ice_server_internal(
diff --git a/y2020/y2020_roborio.json b/y2020/y2020_roborio.json
index 505eb1c..a082d99 100644
--- a/y2020/y2020_roborio.json
+++ b/y2020/y2020_roborio.json
@@ -405,6 +405,7 @@
     {
       "name": "web_proxy",
       "executable_name": "web_proxy_main",
+      "args": ["--min_ice_port=5800", "--max_ice_port=5810"],
       "nodes": [
         "roborio"
       ]