summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dom/network/PTCPSocket.ipdl3
-rw-r--r--dom/network/TCPSocketChild.cpp5
-rw-r--r--dom/network/TCPSocketChild.h2
-rw-r--r--dom/network/TCPSocketParent.cpp5
-rw-r--r--dom/network/TCPSocketParent.h1
-rw-r--r--media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp15
-rw-r--r--media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h1
-rw-r--r--media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp11
-rw-r--r--media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h3
-rw-r--r--netwerk/base/nsISocketTransport.idl5
-rw-r--r--netwerk/base/nsSocketTransport2.cpp34
-rw-r--r--netwerk/base/nsSocketTransport2.h1
-rw-r--r--netwerk/protocol/http/TunnelUtils.cpp6
13 files changed, 85 insertions, 7 deletions
diff --git a/dom/network/PTCPSocket.ipdl b/dom/network/PTCPSocket.ipdl
index aa7c51e45f..ea00856029 100644
--- a/dom/network/PTCPSocket.ipdl
+++ b/dom/network/PTCPSocket.ipdl
@@ -44,7 +44,8 @@ parent:
// address specified in |localAddr| and |localPort|.
async OpenBind(nsCString host, uint16_t port,
nsCString localAddr, uint16_t localPort,
- bool useSSL, bool aUseArrayBuffers, nsCString aFilter);
+ bool useSSL, bool reuseAddrPort,
+ bool aUseArrayBuffers, nsCString aFilter);
// When child's send() is called, this message requrests parent to send
// data and update it's trackingNumber.
diff --git a/dom/network/TCPSocketChild.cpp b/dom/network/TCPSocketChild.cpp
index 9e1dce2769..b2b8db78a3 100644
--- a/dom/network/TCPSocketChild.cpp
+++ b/dom/network/TCPSocketChild.cpp
@@ -108,7 +108,7 @@ void
TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
const nsACString& aRemoteHost, uint16_t aRemotePort,
const nsACString& aLocalHost, uint16_t aLocalPort,
- bool aUseSSL)
+ bool aUseSSL, bool aReuseAddrPort)
{
mSocket = aSocket;
AddIPDLReference();
@@ -117,7 +117,8 @@ TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
aRemotePort);
PTCPSocketChild::SendOpenBind(nsCString(aRemoteHost), aRemotePort,
nsCString(aLocalHost), aLocalPort,
- aUseSSL, true, mFilterName);
+ aUseSSL, aReuseAddrPort,
+ true, mFilterName);
}
void
diff --git a/dom/network/TCPSocketChild.h b/dom/network/TCPSocketChild.h
index 7e9b59e8b5..46e9b0a90f 100644
--- a/dom/network/TCPSocketChild.h
+++ b/dom/network/TCPSocketChild.h
@@ -55,7 +55,7 @@ public:
void SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
const nsACString& aRemoteHost, uint16_t aRemotePort,
const nsACString& aLocalHost, uint16_t aLocalPort,
- bool aUseSSL);
+ bool aUseSSL, bool aUseRealtimeOptions);
NS_IMETHOD SendSendArray(nsTArray<uint8_t>& aArray,
uint32_t aTrackingNumber);
void SendSend(const nsACString& aData, uint32_t aTrackingNumber);
diff --git a/dom/network/TCPSocketParent.cpp b/dom/network/TCPSocketParent.cpp
index 27d4d057e7..96eab44510 100644
--- a/dom/network/TCPSocketParent.cpp
+++ b/dom/network/TCPSocketParent.cpp
@@ -149,6 +149,7 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
const nsCString& aLocalAddr,
const uint16_t& aLocalPort,
const bool& aUseSSL,
+ const bool& aReuseAddrPort,
const bool& aUseArrayBuffers,
const nsCString& aFilter)
{
@@ -184,6 +185,10 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
return true;
}
+ // in most cases aReuseAddrPort is false, but ICE TCP needs
+ // sockets options set that allow addr/port reuse
+ socketTransport->SetReuseAddrPort(aReuseAddrPort);
+
PRNetAddr prAddr;
if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) {
FireInteralError(this, __LINE__);
diff --git a/dom/network/TCPSocketParent.h b/dom/network/TCPSocketParent.h
index 07112f1e2d..e0f987b17f 100644
--- a/dom/network/TCPSocketParent.h
+++ b/dom/network/TCPSocketParent.h
@@ -54,6 +54,7 @@ public:
const nsCString& aLocalAddr,
const uint16_t& aLocalPort,
const bool& aUseSSL,
+ const bool& aReuseAddrPort,
const bool& aUseArrayBuffers,
const nsCString& aFilter) override;
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
index 7f3bb90d44..ad87fa1f91 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -335,6 +335,7 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
, mSTSThread(nullptr)
, mAllowIceLoopback(false)
, mAllowIceLinkLocal(false)
+ , mForceIceTcp(false)
, mMedia(nullptr)
, mUuidGen(MakeUnique<PCUuidGenerator>())
, mNumAudioStreams(0)
@@ -365,6 +366,8 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
"media.peerconnection.ice.loopback", false);
mAllowIceLinkLocal = Preferences::GetBool(
"media.peerconnection.ice.link_local", false);
+ mForceIceTcp = Preferences::GetBool(
+ "media.peerconnection.ice.force_ice_tcp", false);
#endif
memset(mMaxReceiving, 0, sizeof(mMaxReceiving));
memset(mMaxSending, 0, sizeof(mMaxSending));
@@ -2260,6 +2263,11 @@ NS_IMETHODIMP
PeerConnectionImpl::AddIceCandidate(const char* aCandidate, const char* aMid, unsigned short aLevel) {
PC_AUTO_ENTER_API_CALL(true);
+ if (mForceIceTcp && std::string::npos != std::string(aCandidate).find(" UDP ")) {
+ CSFLogError(logTag, "Blocking remote UDP candidate: %s", aCandidate);
+ return NS_OK;
+ }
+
JSErrorResult rv;
RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
if (!pco) {
@@ -3111,7 +3119,7 @@ PeerConnectionImpl::SetSignalingState_m(PCImplSignalingState aSignalingState,
mNegotiationNeeded = false;
// If we're rolling back a local offer, we might need to remove some
// transports, but nothing further needs to be done.
- mMedia->ActivateOrRemoveTransports(*mJsepSession);
+ mMedia->ActivateOrRemoveTransports(*mJsepSession, mForceIceTcp);
if (!rollback) {
mMedia->UpdateMediaPipelines(*mJsepSession);
InitializeDataChannel();
@@ -3273,6 +3281,11 @@ PeerConnectionImpl::CandidateReady(const std::string& candidate,
uint16_t level) {
PC_AUTO_ENTER_API_CALL_VOID_RETURN(false);
+ if (mForceIceTcp && std::string::npos != candidate.find(" UDP ")) {
+ CSFLogError(logTag, "Blocking local UDP candidate: %s", candidate.c_str());
+ return;
+ }
+
std::string mid;
bool skipped = false;
nsresult res = mJsepSession->AddLocalIceCandidate(candidate,
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
index 7b53ea1160..098b34249a 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -803,6 +803,7 @@ private:
bool mAllowIceLoopback;
bool mAllowIceLinkLocal;
+ bool mForceIceTcp;
RefPtr<PeerConnectionMedia> mMedia;
// The JSEP negotiation session.
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
index 0d388a8f49..0306b57904 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -457,7 +457,8 @@ PeerConnectionMedia::EnsureTransport_s(size_t aLevel, size_t aComponentCount)
}
void
-PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession)
+PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession,
+ const bool forceIceTcp)
{
auto transports = aSession.GetTransports();
for (size_t i = 0; i < transports.size(); ++i) {
@@ -480,6 +481,14 @@ PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession)
RemoveTransportFlow(i, true);
}
+ if (forceIceTcp) {
+ candidates.erase(std::remove_if(candidates.begin(),
+ candidates.end(),
+ [](const std::string & s) {
+ return s.find(" UDP "); }),
+ candidates.end());
+ }
+
RUN_ON_THREAD(
GetSTSThread(),
WrapRunnable(RefPtr<PeerConnectionMedia>(this),
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
index c0001a5e54..8908e51546 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -270,7 +270,8 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
// Activate or remove ICE transports at the conclusion of offer/answer,
// or when rollback occurs.
- void ActivateOrRemoveTransports(const JsepSession& aSession);
+ void ActivateOrRemoveTransports(const JsepSession& aSession,
+ const bool forceIceTcp);
// Start ICE checks.
void StartIceChecks(const JsepSession& session);
diff --git a/netwerk/base/nsISocketTransport.idl b/netwerk/base/nsISocketTransport.idl
index 9b5bc23fb7..3525aad5d9 100644
--- a/netwerk/base/nsISocketTransport.idl
+++ b/netwerk/base/nsISocketTransport.idl
@@ -130,6 +130,11 @@ interface nsISocketTransport : nsITransport
void setTimeout(in unsigned long aType, in unsigned long aValue);
/**
+ * True to set addr and port reuse socket options.
+ */
+ void setReuseAddrPort(in bool reuseAddrPort);
+
+ /**
* Values for the aType parameter passed to get/setTimeout.
*/
const unsigned long TIMEOUT_CONNECT = 0;
diff --git a/netwerk/base/nsSocketTransport2.cpp b/netwerk/base/nsSocketTransport2.cpp
index ff5fc3070d..ab20737443 100644
--- a/netwerk/base/nsSocketTransport2.cpp
+++ b/netwerk/base/nsSocketTransport2.cpp
@@ -737,6 +737,7 @@ nsSocketTransport::nsSocketTransport()
, mProxyTransparentResolvesHost(false)
, mHttpsProxy(false)
, mConnectionFlags(0)
+ , mReuseAddrPort(false)
, mState(STATE_CLOSED)
, mAttached(false)
, mInputClosed(true)
@@ -1354,6 +1355,32 @@ nsSocketTransport::InitiateSocket()
status = PR_SetSocketOption(fd, &opt);
NS_ASSERTION(status == PR_SUCCESS, "unable to make socket non-blocking");
+ if (mReuseAddrPort) {
+ SOCKET_LOG((" Setting port/addr reuse socket options\n"));
+
+ // Set ReuseAddr for TCP sockets to enable having several
+ // sockets bound to same local IP and port
+ PRSocketOptionData opt_reuseaddr;
+ opt_reuseaddr.option = PR_SockOpt_Reuseaddr;
+ opt_reuseaddr.value.reuse_addr = PR_TRUE;
+ status = PR_SetSocketOption(fd, &opt_reuseaddr);
+ if (status != PR_SUCCESS) {
+ SOCKET_LOG((" Couldn't set reuse addr socket option: %d\n",
+ status));
+ }
+
+ // And also set ReusePort for platforms supporting this socket option
+ PRSocketOptionData opt_reuseport;
+ opt_reuseport.option = PR_SockOpt_Reuseport;
+ opt_reuseport.value.reuse_port = PR_TRUE;
+ status = PR_SetSocketOption(fd, &opt_reuseport);
+ if (status != PR_SUCCESS
+ && PR_GetError() != PR_OPERATION_NOT_SUPPORTED_ERROR) {
+ SOCKET_LOG((" Couldn't set reuse port socket option: %d\n",
+ status));
+ }
+ }
+
// disable the nagle algorithm - if we rely on it to coalesce writes into
// full packets the final packet of a multi segment POST/PUT or pipeline
// sequence is delayed a full rtt
@@ -2469,6 +2496,13 @@ nsSocketTransport::SetTimeout(uint32_t type, uint32_t value)
}
NS_IMETHODIMP
+nsSocketTransport::SetReuseAddrPort(bool reuseAddrPort)
+{
+ mReuseAddrPort = reuseAddrPort;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsSocketTransport::SetQoSBits(uint8_t aQoSBits)
{
// Don't do any checking here of bits. Why? Because as of RFC-4594
diff --git a/netwerk/base/nsSocketTransport2.h b/netwerk/base/nsSocketTransport2.h
index 89b75efa57..a61e432b48 100644
--- a/netwerk/base/nsSocketTransport2.h
+++ b/netwerk/base/nsSocketTransport2.h
@@ -295,6 +295,7 @@ private:
bool mProxyTransparentResolvesHost;
bool mHttpsProxy;
uint32_t mConnectionFlags;
+ bool mReuseAddrPort;
// The origin attributes are used to create sockets. The first party domain
// will eventually be used to isolate OCSP cache and is only non-empty when
diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp
index eeaf57f55c..01075d2c0c 100644
--- a/netwerk/protocol/http/TunnelUtils.cpp
+++ b/netwerk/protocol/http/TunnelUtils.cpp
@@ -1686,6 +1686,12 @@ SocketTransportShim::SetTimeout(uint32_t aType, uint32_t aValue)
}
NS_IMETHODIMP
+SocketTransportShim::SetReuseAddrPort(bool aReuseAddrPort)
+{
+ return mWrapped->SetReuseAddrPort(aReuseAddrPort);
+}
+
+NS_IMETHODIMP
SocketTransportShim::GetQoSBits(uint8_t *aQoSBits)
{
return mWrapped->GetQoSBits(aQoSBits);