diff options
author | Basilisk-Dev <basiliskdev@protonmail.com> | 2022-08-20 14:21:43 -0400 |
---|---|---|
committer | Basilisk-Dev <basiliskdev@protonmail.com> | 2022-08-20 14:21:43 -0400 |
commit | d49569ca0d6869de9e60026efa893c45770c86ae (patch) | |
tree | 1f2340890a8ff7a5d15fd9b0e6090c5d987cd01d /media/mtransport | |
parent | 544366e3010ea16601ff363a2f41df5f84f77d47 (diff) | |
download | uxp-d49569ca0d6869de9e60026efa893c45770c86ae.tar.gz |
Issue #1991 - Support TURN TLS Support in WebRTC
Backport of Mozilla bug 1056934
Diffstat (limited to 'media/mtransport')
-rw-r--r-- | media/mtransport/nr_socket_prsock.cpp | 34 | ||||
-rw-r--r-- | media/mtransport/nr_socket_prsock.h | 3 | ||||
-rw-r--r-- | media/mtransport/nricectx.cpp | 9 | ||||
-rw-r--r-- | media/mtransport/nricectx.h | 1 | ||||
-rw-r--r-- | media/mtransport/test_nr_socket.cpp | 55 | ||||
-rw-r--r-- | media/mtransport/test_nr_socket.h | 3 | ||||
-rw-r--r-- | media/mtransport/third_party/nICEr/src/ice/ice_candidate.c | 8 | ||||
-rw-r--r-- | media/mtransport/third_party/nICEr/src/ice/ice_ctx.h | 1 | ||||
-rw-r--r-- | media/mtransport/third_party/nICEr/src/net/transport_addr.h | 1 |
9 files changed, 100 insertions, 15 deletions
diff --git a/media/mtransport/nr_socket_prsock.cpp b/media/mtransport/nr_socket_prsock.cpp index 80e5ef51e4..3fd223349c 100644 --- a/media/mtransport/nr_socket_prsock.cpp +++ b/media/mtransport/nr_socket_prsock.cpp @@ -858,6 +858,10 @@ int NrSocket::connect(nr_transport_addr *addr) { PRNetAddr naddr; int32_t connect_status, getsockname_status; + // TODO: Add TLS layer with nsISocketProviderService? + if (addr->tls_host[0] != '\0') + ABORT(R_INTERNAL); + if ((r=nr_transport_addr_to_praddr(addr, &naddr))) ABORT(r); @@ -1840,7 +1844,7 @@ void NrTcpSocketIpc::close() { } int NrTcpSocketIpc::connect(nr_transport_addr *addr) { - nsCString remote_addr, local_addr; + nsCString remote_addr, local_addr, tls_host; int32_t remote_port, local_port; int r, _status; if ((r=nr_transport_addr_get_addrstring_and_port(addr, @@ -1856,6 +1860,8 @@ int NrTcpSocketIpc::connect(nr_transport_addr *addr) { ABORT(r); } + tls_host = addr->tls_host; + state_ = mirror_state_ = NR_CONNECTING; RUN_ON_THREAD(io_thread_, mozilla::WrapRunnable(RefPtr<NrTcpSocketIpc>(this), @@ -1863,7 +1869,8 @@ int NrTcpSocketIpc::connect(nr_transport_addr *addr) { remote_addr, static_cast<uint16_t>(remote_port), local_addr, - static_cast<uint16_t>(local_port)), + static_cast<uint16_t>(local_port), + tls_host), NS_DISPATCH_NORMAL); // Make caller wait for ready to write. @@ -1939,7 +1946,8 @@ int NrTcpSocketIpc::accept(nr_transport_addr *addrp, nr_socket **sockp) { void NrTcpSocketIpc::connect_i(const nsACString &remote_addr, uint16_t remote_port, const nsACString &local_addr, - uint16_t local_port) { + uint16_t local_port, + const nsACString &tls_host) { ASSERT_ON_THREAD(io_thread_); mirror_state_ = NR_CONNECTING; @@ -1948,11 +1956,21 @@ void NrTcpSocketIpc::connect_i(const nsACString &remote_addr, // Bug 1285330: put filtering back in here - // XXX remove remote! - socket_child_->SendWindowlessOpenBind(this, - remote_addr, remote_port, - local_addr, local_port, - /* use ssl */ false); + if (tls_host.IsEmpty()) { + // XXX remove remote! + socket_child_->SendWindowlessOpenBind(this, + remote_addr, remote_port, + local_addr, local_port, + /* use ssl */ false, + /* reuse addr port */ true); + } else { + // XXX remove remote! + socket_child_->SendWindowlessOpenBind(this, + tls_host, remote_port, + local_addr, local_port, + /* use ssl */ true, + /* reuse addr port */ true); + } } void NrTcpSocketIpc::write_i(nsAutoPtr<InfallibleTArray<uint8_t>> arr, diff --git a/media/mtransport/nr_socket_prsock.h b/media/mtransport/nr_socket_prsock.h index 5ed9a6a219..7d372ccb16 100644 --- a/media/mtransport/nr_socket_prsock.h +++ b/media/mtransport/nr_socket_prsock.h @@ -369,7 +369,8 @@ private: void connect_i(const nsACString &remote_addr, uint16_t remote_port, const nsACString &local_addr, - uint16_t local_port); + uint16_t local_port, + const nsACString &tls_host); void write_i(nsAutoPtr<InfallibleTArray<uint8_t>> buf, uint32_t tracking_number); void close_i(); diff --git a/media/mtransport/nricectx.cpp b/media/mtransport/nricectx.cpp index be50f50169..75d3d2519d 100644 --- a/media/mtransport/nricectx.cpp +++ b/media/mtransport/nricectx.cpp @@ -108,6 +108,7 @@ MOZ_MTLOG_MODULE("mtransport") const char kNrIceTransportUdp[] = "udp"; const char kNrIceTransportTcp[] = "tcp"; +const char kNrIceTransportTls[] = "tls"; static bool initialized = false; @@ -210,6 +211,9 @@ nsresult NrIceStunServer::ToNicerStunStruct(nr_ice_stun_server *server) const { server->transport = IPPROTO_UDP; } else if (transport_ == kNrIceTransportTcp) { server->transport = IPPROTO_TCP; + } else if (transport_ == kNrIceTransportTls) { + server->transport = IPPROTO_TCP; + server->tls = 1; } else { MOZ_MTLOG(ML_ERROR, "Unsupported STUN server transport: " << transport_); return NS_ERROR_FAILURE; @@ -586,6 +590,7 @@ NrIceCtx::Initialize(const std::string& ufrag, nsCString mapping_type; nsCString filtering_type; bool block_udp = false; + bool block_tcp = false; nsresult rv; nsCOMPtr<nsIPrefService> pref_service = @@ -604,6 +609,9 @@ NrIceCtx::Initialize(const std::string& ufrag, rv = pref_branch->GetBoolPref( "media.peerconnection.nat_simulator.block_udp", &block_udp); + rv = pref_branch->GetBoolPref( + "media.peerconnection.nat_simulator.block_tcp", + &block_tcp); } } @@ -614,6 +622,7 @@ NrIceCtx::Initialize(const std::string& ufrag, test_nat->filtering_type_ = TestNat::ToNatBehavior(filtering_type.get()); test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type.get()); test_nat->block_udp_ = block_udp; + test_nat->block_tcp_ = block_tcp; test_nat->enabled_ = true; SetNat(test_nat); } diff --git a/media/mtransport/nricectx.h b/media/mtransport/nricectx.h index ce104ac317..87122121e5 100644 --- a/media/mtransport/nricectx.h +++ b/media/mtransport/nricectx.h @@ -90,6 +90,7 @@ class NrIceMediaStream; extern const char kNrIceTransportUdp[]; extern const char kNrIceTransportTcp[]; +extern const char kNrIceTransportTls[]; class NrIceStunServer { public: diff --git a/media/mtransport/test_nr_socket.cpp b/media/mtransport/test_nr_socket.cpp index e7dad79cd1..fb2de3096e 100644 --- a/media/mtransport/test_nr_socket.cpp +++ b/media/mtransport/test_nr_socket.cpp @@ -200,6 +200,7 @@ int TestNat::create_socket_factory(nr_socket_factory **factorypp) { TestNrSocket::TestNrSocket(TestNat *nat) : nat_(nat), + tls_(false), timer_handle_(nullptr) { nat_->insert_socket(this); } @@ -473,6 +474,10 @@ int TestNrSocket::connect(nr_transport_addr *addr) { return R_INTERNAL; } + if (addr->tls_host[0] != '\0') { + tls_ = true; + } + if (!nat_->enabled_ || addr->protocol==IPPROTO_UDP // Horrible hack to allow default address // discovery to work. Only works because @@ -508,6 +513,24 @@ int TestNrSocket::connect(nr_transport_addr *addr) { } int TestNrSocket::write(const void *msg, size_t len, size_t *written) { + UCHAR *buf = static_cast<UCHAR*>(const_cast<void*>(msg)); + if (nat_->block_stun_ && nr_is_stun_message(buf, len)) { + // Should cause this socket to be abandoned + r_log(LOG_GENERIC, LOG_DEBUG, + "TestNrSocket %s dropping outgoing TCP " + "because it is configured to drop STUN", + my_addr().as_string); + return R_INTERNAL; + } + + if (nat_->block_tcp_ && !tls_) { + // Should cause this socket to be abandoned + r_log(LOG_GENERIC, LOG_DEBUG, + "TestNrSocket %s dropping outgoing TCP " + "because it is configured to drop TCP", + my_addr().as_string); + return R_INTERNAL; + } if (port_mappings_.empty()) { // The no-nat case, just pass call through. @@ -518,7 +541,11 @@ int TestNrSocket::write(const void *msg, size_t len, size_t *written) { } else { destroy_stale_port_mappings(); if (port_mappings_.empty()) { - return -1; + r_log(LOG_GENERIC, LOG_DEBUG, + "TestNrSocket %s dropping outgoing TCP " + "because the port mapping was stale", + my_addr().as_string); + return R_INTERNAL; } // This is TCP only MOZ_ASSERT(port_mappings_.size() == 1); @@ -533,18 +560,34 @@ int TestNrSocket::write(const void *msg, size_t len, size_t *written) { } int TestNrSocket::read(void *buf, size_t maxlen, size_t *len) { + int r; if (port_mappings_.empty()) { - return internal_socket_->read(buf, maxlen, len); + r = internal_socket_->read(buf, maxlen, len); } else { MOZ_ASSERT(port_mappings_.size() == 1); - int bytesRead = - port_mappings_.front()->external_socket_->read(buf, maxlen, len); - if (bytesRead > 0 && nat_->refresh_on_ingress_) { + r = port_mappings_.front()->external_socket_->read(buf, maxlen, len); + if (!r && nat_->refresh_on_ingress_) { port_mappings_.front()->last_used_ = PR_IntervalNow(); } - return bytesRead; } + + if (r) { + return r; + } + + if (nat_->block_tcp_ && !tls_) { + // Should cause this socket to be abandoned + return R_INTERNAL; + } + + UCHAR *cbuf = static_cast<UCHAR*>(const_cast<void*>(buf)); + if (nat_->block_stun_ && nr_is_stun_message(cbuf, *len)) { + // Should cause this socket to be abandoned + return R_INTERNAL; + } + + return r; } int TestNrSocket::async_wait(int how, NR_async_cb cb, void *cb_arg, diff --git a/media/mtransport/test_nr_socket.h b/media/mtransport/test_nr_socket.h index 91c9030f17..a47a88beb9 100644 --- a/media/mtransport/test_nr_socket.h +++ b/media/mtransport/test_nr_socket.h @@ -137,6 +137,7 @@ class TestNat { refresh_on_ingress_(false), block_udp_(false), block_stun_(false), + block_tcp_(false), delay_stun_resp_ms_(0), sockets_() {} @@ -168,6 +169,7 @@ class TestNat { bool refresh_on_ingress_; bool block_udp_; bool block_stun_; + bool block_tcp_; /* Note: this can only delay a single response so far (bug 1253657) */ uint32_t delay_stun_resp_ms_; @@ -319,6 +321,7 @@ class TestNrSocket : public NrSocketBase { // same nat. RefPtr<NrSocketBase> internal_socket_; RefPtr<TestNat> nat_; + bool tls_; // Since our comparison logic is different depending on what kind of NAT // we simulate, and the STL does not make it very easy to switch out the // comparison function at runtime, and these lists are going to be very diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c b/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c index e48b7b5e1a..879b77933e 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c @@ -666,6 +666,14 @@ static int nr_ice_candidate_resolved_cb(void *cb_arg, nr_transport_addr *addr) if(r=nr_transport_addr_copy(&cand->stun_server_addr,addr)) ABORT(r); + if (cand->stun_server->tls) { + /* Copy over the DNS name; needed for TLS. There is already a null at the + * end of the buffer, leave it there. */ + strncpy(cand->stun_server_addr.tls_host, + cand->stun_server->u.dnsname.host, + sizeof(cand->stun_server_addr.tls_host) - 1); + } + if (cand->tcp_type == TCP_TYPE_PASSIVE || cand->tcp_type == TCP_TYPE_SO){ if (r=nr_socket_multi_tcp_stun_server_connect(cand->osock, addr)) ABORT(r); diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h index cc79304f08..1e815ac2ac 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h +++ b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h @@ -63,6 +63,7 @@ typedef struct nr_ice_stun_server_ { } u; int id; int transport; + int tls; /* Whether to use TLS or not */ } nr_ice_stun_server; typedef struct nr_ice_turn_server_ { diff --git a/media/mtransport/third_party/nICEr/src/net/transport_addr.h b/media/mtransport/third_party/nICEr/src/net/transport_addr.h index dfec633291..06c8b8c9c5 100644 --- a/media/mtransport/third_party/nICEr/src/net/transport_addr.h +++ b/media/mtransport/third_party/nICEr/src/net/transport_addr.h @@ -66,6 +66,7 @@ typedef struct nr_transport_addr_ { /* A string version. 56 = 5 ("IP6:[") + 39 (ipv6 address) + 2 ("]:") + 5 (port) + 4 (/UDP) + 1 (null) */ char as_string[56]; + char tls_host[256]; } nr_transport_addr; typedef struct nr_transport_addr_mask_ { |