mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-01 04:47:31 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
e235eb81c6
40 changed files with 516 additions and 78 deletions
|
|
@ -588,7 +588,7 @@ RTCPeerConnection.prototype = {
|
||||||
throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme,
|
throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme,
|
||||||
"SyntaxError");
|
"SyntaxError");
|
||||||
}
|
}
|
||||||
if (url.scheme in { stuns:1, turns:1 }) {
|
if (url.scheme in { stuns:1 }) {
|
||||||
this.logWarning(url.scheme.toUpperCase() + " is not yet supported.");
|
this.logWarning(url.scheme.toUpperCase() + " is not yet supported.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
26
dom/media/tests/mochitest/addTurnsSelfsignedCert.js
Normal file
26
dom/media/tests/mochitest/addTurnsSelfsignedCert.js
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||||
|
|
||||||
|
// This is only usable from the parent process, even for doing simple stuff like
|
||||||
|
// serializing a cert.
|
||||||
|
var gCertMaker = Cc["@mozilla.org/security/x509certdb;1"].
|
||||||
|
getService(Ci.nsIX509CertDB);
|
||||||
|
|
||||||
|
var gCertOverrides = Cc["@mozilla.org/security/certoverride;1"].
|
||||||
|
getService(Ci.nsICertOverrideService);
|
||||||
|
|
||||||
|
|
||||||
|
addMessageListener('add-turns-certs', certs => {
|
||||||
|
var port = 5349;
|
||||||
|
certs.forEach(certDescription => {
|
||||||
|
var cert = gCertMaker.constructX509FromBase64(certDescription.cert);
|
||||||
|
gCertOverrides.rememberValidityOverride(certDescription.hostname, port,
|
||||||
|
cert, Ci.nsICertOverrideService.ERROR_UNTRUSTED, false);
|
||||||
|
});
|
||||||
|
sendAsyncMessage('certs-added');
|
||||||
|
});
|
||||||
|
|
@ -13,6 +13,7 @@ support-files =
|
||||||
blacksilence.js
|
blacksilence.js
|
||||||
turnConfig.js
|
turnConfig.js
|
||||||
sdpUtils.js
|
sdpUtils.js
|
||||||
|
addTurnsSelfsignedCert.js
|
||||||
!/dom/canvas/test/captureStream_common.js
|
!/dom/canvas/test/captureStream_common.js
|
||||||
!/dom/canvas/test/webgl-mochitest/webgl-util.js
|
!/dom/canvas/test/webgl-mochitest/webgl-util.js
|
||||||
!/dom/media/test/manifest.js
|
!/dom/media/test/manifest.js
|
||||||
|
|
@ -97,6 +98,8 @@ skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
|
||||||
skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
|
skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
|
||||||
[test_peerConnection_basicAudioNATRelayTCP.html]
|
[test_peerConnection_basicAudioNATRelayTCP.html]
|
||||||
skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
|
skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
|
||||||
|
[test_peerConnection_basicAudioNATRelayTLS.html]
|
||||||
|
skip-if = true # need pyopenssl on builders, see bug 1323439
|
||||||
[test_peerConnection_basicAudioRequireEOC.html]
|
[test_peerConnection_basicAudioRequireEOC.html]
|
||||||
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
|
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
|
||||||
[test_peerConnection_basicAudioPcmaPcmuOnly.html]
|
[test_peerConnection_basicAudioPcmaPcmuOnly.html]
|
||||||
|
|
|
||||||
|
|
@ -1869,6 +1869,33 @@ function createHTML(options) {
|
||||||
var iceServerWebsocket;
|
var iceServerWebsocket;
|
||||||
var iceServersArray = [];
|
var iceServersArray = [];
|
||||||
|
|
||||||
|
var addTurnsSelfsignedCerts = () => {
|
||||||
|
var gUrl = SimpleTest.getTestFileURL('addTurnsSelfsignedCert.js');
|
||||||
|
var gScript = SpecialPowers.loadChromeScript(gUrl);
|
||||||
|
var certs = [];
|
||||||
|
// If the ICE server is running TURNS, and includes a "cert" attribute in
|
||||||
|
// its JSON, we set up an override that will forgive things like
|
||||||
|
// self-signed for it.
|
||||||
|
iceServersArray.forEach(iceServer => {
|
||||||
|
if (iceServer.hasOwnProperty("cert")) {
|
||||||
|
iceServer.urls.forEach(url => {
|
||||||
|
if (url.startsWith("turns:")) {
|
||||||
|
// Assumes no port or params!
|
||||||
|
certs.push({"cert": iceServer.cert, "hostname": url.substr(6)});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
gScript.addMessageListener('certs-added', () => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.sendAsyncMessage('add-turns-certs', certs);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var setupIceServerConfig = useIceServer => {
|
var setupIceServerConfig = useIceServer => {
|
||||||
// We disable ICE support for HTTP proxy when using a TURN server, because
|
// We disable ICE support for HTTP proxy when using a TURN server, because
|
||||||
// mochitest uses a fake HTTP proxy to serve content, which will eat our STUN
|
// mochitest uses a fake HTTP proxy to serve content, which will eat our STUN
|
||||||
|
|
@ -1910,7 +1937,8 @@ var setupIceServerConfig = useIceServer => {
|
||||||
|
|
||||||
return enableHttpProxy(false)
|
return enableHttpProxy(false)
|
||||||
.then(spawnIceServer)
|
.then(spawnIceServer)
|
||||||
.then(iceServersStr => { iceServersArray = JSON.parse(iceServersStr); });
|
.then(iceServersStr => { iceServersArray = JSON.parse(iceServersStr); })
|
||||||
|
.then(addTurnsSelfsignedCerts);
|
||||||
};
|
};
|
||||||
|
|
||||||
function runNetworkTest(testFunction, fixtureOptions) {
|
function runNetworkTest(testFunction, fixtureOptions) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script type="application/javascript" src="pc.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre id="test">
|
||||||
|
<script type="application/javascript">
|
||||||
|
createHTML({
|
||||||
|
bug: "1231975",
|
||||||
|
title: "Basic audio-only peer connection with port dependent NAT that blocks STUN"
|
||||||
|
});
|
||||||
|
|
||||||
|
var test;
|
||||||
|
runNetworkTest(options => {
|
||||||
|
SpecialPowers.pushPrefEnv(
|
||||||
|
{
|
||||||
|
'set': [
|
||||||
|
['media.peerconnection.nat_simulator.filtering_type', 'PORT_DEPENDENT'],
|
||||||
|
['media.peerconnection.nat_simulator.mapping_type', 'PORT_DEPENDENT'],
|
||||||
|
['media.peerconnection.nat_simulator.block_udp', true],
|
||||||
|
['media.peerconnection.nat_simulator.block_tcp', true]
|
||||||
|
]
|
||||||
|
}, function (options) {
|
||||||
|
options = options || {};
|
||||||
|
options.expectedLocalCandidateType = "relayed-tcp";
|
||||||
|
options.expectedRemoteCandidateType = "relayed-tcp";
|
||||||
|
// No reason to wait for gathering to complete like the other NAT tests,
|
||||||
|
// since relayed-tcp is the only thing that can work.
|
||||||
|
test = new PeerConnectionTest(options);
|
||||||
|
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||||
|
test.run();
|
||||||
|
})
|
||||||
|
}, { useIceServer: true });
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2011 Google Inc. All rights reserved.
|
* Copyright (C) 2011 Google Inc.
|
||||||
|
* Copyright (C) 2022 Moonchild Productions.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|
@ -104,7 +105,7 @@ protected:
|
||||||
float m_lastAnchor;
|
float m_lastAnchor;
|
||||||
float m_lastFilterStageGain;
|
float m_lastFilterStageGain;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct ZeroPoleFilterPack4 {
|
||||||
ZeroPole filters[4];
|
ZeroPole filters[4];
|
||||||
size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,8 @@ parent:
|
||||||
// address specified in |localAddr| and |localPort|.
|
// address specified in |localAddr| and |localPort|.
|
||||||
async OpenBind(nsCString host, uint16_t port,
|
async OpenBind(nsCString host, uint16_t port,
|
||||||
nsCString localAddr, uint16_t localPort,
|
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
|
// When child's send() is called, this message requrests parent to send
|
||||||
// data and update it's trackingNumber.
|
// data and update it's trackingNumber.
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ void
|
||||||
TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
|
TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
|
||||||
const nsACString& aRemoteHost, uint16_t aRemotePort,
|
const nsACString& aRemoteHost, uint16_t aRemotePort,
|
||||||
const nsACString& aLocalHost, uint16_t aLocalPort,
|
const nsACString& aLocalHost, uint16_t aLocalPort,
|
||||||
bool aUseSSL)
|
bool aUseSSL, bool aReuseAddrPort)
|
||||||
{
|
{
|
||||||
mSocket = aSocket;
|
mSocket = aSocket;
|
||||||
AddIPDLReference();
|
AddIPDLReference();
|
||||||
|
|
@ -117,7 +117,8 @@ TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
|
||||||
aRemotePort);
|
aRemotePort);
|
||||||
PTCPSocketChild::SendOpenBind(nsCString(aRemoteHost), aRemotePort,
|
PTCPSocketChild::SendOpenBind(nsCString(aRemoteHost), aRemotePort,
|
||||||
nsCString(aLocalHost), aLocalPort,
|
nsCString(aLocalHost), aLocalPort,
|
||||||
aUseSSL, true, mFilterName);
|
aUseSSL, aReuseAddrPort,
|
||||||
|
true, mFilterName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ public:
|
||||||
void SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
|
void SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
|
||||||
const nsACString& aRemoteHost, uint16_t aRemotePort,
|
const nsACString& aRemoteHost, uint16_t aRemotePort,
|
||||||
const nsACString& aLocalHost, uint16_t aLocalPort,
|
const nsACString& aLocalHost, uint16_t aLocalPort,
|
||||||
bool aUseSSL);
|
bool aUseSSL, bool aUseRealtimeOptions);
|
||||||
NS_IMETHOD SendSendArray(nsTArray<uint8_t>& aArray,
|
NS_IMETHOD SendSendArray(nsTArray<uint8_t>& aArray,
|
||||||
uint32_t aTrackingNumber);
|
uint32_t aTrackingNumber);
|
||||||
void SendSend(const nsACString& aData, uint32_t aTrackingNumber);
|
void SendSend(const nsACString& aData, uint32_t aTrackingNumber);
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,7 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
|
||||||
const nsCString& aLocalAddr,
|
const nsCString& aLocalAddr,
|
||||||
const uint16_t& aLocalPort,
|
const uint16_t& aLocalPort,
|
||||||
const bool& aUseSSL,
|
const bool& aUseSSL,
|
||||||
|
const bool& aReuseAddrPort,
|
||||||
const bool& aUseArrayBuffers,
|
const bool& aUseArrayBuffers,
|
||||||
const nsCString& aFilter)
|
const nsCString& aFilter)
|
||||||
{
|
{
|
||||||
|
|
@ -167,14 +168,27 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsISocketTransport> socketTransport;
|
nsCOMPtr<nsISocketTransport> socketTransport;
|
||||||
rv = sts->CreateTransport(nullptr, 0,
|
if (aUseSSL) {
|
||||||
aRemoteHost, aRemotePort,
|
const char* socketTypes[1];
|
||||||
nullptr, getter_AddRefs(socketTransport));
|
socketTypes[0] = "ssl";
|
||||||
|
rv = sts->CreateTransport(socketTypes, 1,
|
||||||
|
aRemoteHost, aRemotePort,
|
||||||
|
nullptr, getter_AddRefs(socketTransport));
|
||||||
|
} else {
|
||||||
|
rv = sts->CreateTransport(nullptr, 0,
|
||||||
|
aRemoteHost, aRemotePort,
|
||||||
|
nullptr, getter_AddRefs(socketTransport));
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
FireInteralError(this, __LINE__);
|
FireInteralError(this, __LINE__);
|
||||||
return true;
|
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;
|
PRNetAddr prAddr;
|
||||||
if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) {
|
if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) {
|
||||||
FireInteralError(this, __LINE__);
|
FireInteralError(this, __LINE__);
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ public:
|
||||||
const nsCString& aLocalAddr,
|
const nsCString& aLocalAddr,
|
||||||
const uint16_t& aLocalPort,
|
const uint16_t& aLocalPort,
|
||||||
const bool& aUseSSL,
|
const bool& aUseSSL,
|
||||||
|
const bool& aReuseAddrPort,
|
||||||
const bool& aUseArrayBuffers,
|
const bool& aUseArrayBuffers,
|
||||||
const nsCString& aFilter) override;
|
const nsCString& aFilter) override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,7 @@ public:
|
||||||
Display* display,
|
Display* display,
|
||||||
GLXDrawable drawable,
|
GLXDrawable drawable,
|
||||||
GLXFBConfig cfg,
|
GLXFBConfig cfg,
|
||||||
bool deleteDrawable,
|
Drawable ownedPixmap = X11None,
|
||||||
gfxXlibSurface* pixmap = nullptr,
|
|
||||||
ContextProfile profile = ContextProfile::OpenGLCompatibility);
|
ContextProfile profile = ContextProfile::OpenGLCompatibility);
|
||||||
|
|
||||||
// Finds a GLXFBConfig compatible with the provided window.
|
// Finds a GLXFBConfig compatible with the provided window.
|
||||||
|
|
@ -77,25 +76,26 @@ private:
|
||||||
Display* aDisplay,
|
Display* aDisplay,
|
||||||
GLXDrawable aDrawable,
|
GLXDrawable aDrawable,
|
||||||
GLXContext aContext,
|
GLXContext aContext,
|
||||||
bool aDeleteDrawable,
|
|
||||||
bool aDoubleBuffered,
|
bool aDoubleBuffered,
|
||||||
gfxXlibSurface* aPixmap,
|
ContextProfile profile,
|
||||||
ContextProfile profile);
|
Drawable aOwnedPixmap = X11None);
|
||||||
|
|
||||||
GLXContext mContext;
|
GLXContext mContext;
|
||||||
Display* mDisplay;
|
Display* mDisplay;
|
||||||
GLXDrawable mDrawable;
|
GLXDrawable mDrawable;
|
||||||
Maybe<GLXDrawable> mOverrideDrawable;
|
Maybe<GLXDrawable> mOverrideDrawable;
|
||||||
bool mDeleteDrawable;
|
// The X pixmap associated with the GLX pixmap. If this is provided, then
|
||||||
|
// this class assumes responsibility for freeing both. Otherwise, the
|
||||||
|
// user of this class is responsibile for freeing the drawables.
|
||||||
|
const Drawable mOwnedPixmap;
|
||||||
bool mDoubleBuffered;
|
bool mDoubleBuffered;
|
||||||
|
|
||||||
GLXLibrary* mGLX;
|
GLXLibrary* mGLX;
|
||||||
|
|
||||||
RefPtr<gfxXlibSurface> mPixmap;
|
|
||||||
bool mOwnsContext;
|
bool mOwnsContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace gl
|
||||||
}
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // GLCONTEXTGLX_H_
|
#endif // GLCONTEXTGLX_H_
|
||||||
|
|
|
||||||
|
|
@ -327,7 +327,7 @@ GLXLibrary::CreatePixmap(gfxASurface* aSurface)
|
||||||
X11None };
|
X11None };
|
||||||
|
|
||||||
int numConfigs = 0;
|
int numConfigs = 0;
|
||||||
Display* display = xs->XDisplay();
|
Display *display = xs->XDisplay();
|
||||||
int xscreen = DefaultScreen(display);
|
int xscreen = DefaultScreen(display);
|
||||||
|
|
||||||
ScopedXFree<GLXFBConfig> cfgs(xChooseFBConfig(display,
|
ScopedXFree<GLXFBConfig> cfgs(xChooseFBConfig(display,
|
||||||
|
|
@ -800,7 +800,7 @@ already_AddRefed<GLContextGLX>
|
||||||
GLContextGLX::CreateGLContext(CreateContextFlags flags, const SurfaceCaps& caps,
|
GLContextGLX::CreateGLContext(CreateContextFlags flags, const SurfaceCaps& caps,
|
||||||
GLContextGLX* shareContext, bool isOffscreen,
|
GLContextGLX* shareContext, bool isOffscreen,
|
||||||
Display* display, GLXDrawable drawable, GLXFBConfig cfg,
|
Display* display, GLXDrawable drawable, GLXFBConfig cfg,
|
||||||
bool deleteDrawable, gfxXlibSurface* pixmap,
|
Drawable ownedPixmap,
|
||||||
ContextProfile profile)
|
ContextProfile profile)
|
||||||
{
|
{
|
||||||
GLXLibrary& glx = sGLXLibrary;
|
GLXLibrary& glx = sGLXLibrary;
|
||||||
|
|
@ -860,8 +860,7 @@ GLContextGLX::CreateGLContext(CreateContextFlags flags, const SurfaceCaps& caps,
|
||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
glContext = new GLContextGLX(flags, caps, shareContext, isOffscreen, display,
|
glContext = new GLContextGLX(flags, caps, shareContext, isOffscreen, display,
|
||||||
drawable, context, deleteDrawable, db, pixmap,
|
drawable, context, db, profile, ownedPixmap);
|
||||||
profile);
|
|
||||||
if (!glContext->Init())
|
if (!glContext->Init())
|
||||||
error = true;
|
error = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -896,8 +895,9 @@ GLContextGLX::~GLContextGLX()
|
||||||
|
|
||||||
mGLX->xDestroyContext(mDisplay, mContext);
|
mGLX->xDestroyContext(mDisplay, mContext);
|
||||||
|
|
||||||
if (mDeleteDrawable) {
|
if (mOwnedPixmap) {
|
||||||
mGLX->xDestroyPixmap(mDisplay, mDrawable);
|
mGLX->xDestroyPixmap(mDisplay, mDrawable);
|
||||||
|
XFreePixmap(mDisplay, mOwnedPixmap);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(!mOverrideDrawable);
|
MOZ_ASSERT(!mOverrideDrawable);
|
||||||
}
|
}
|
||||||
|
|
@ -1035,18 +1035,16 @@ GLContextGLX::GLContextGLX(
|
||||||
Display* aDisplay,
|
Display* aDisplay,
|
||||||
GLXDrawable aDrawable,
|
GLXDrawable aDrawable,
|
||||||
GLXContext aContext,
|
GLXContext aContext,
|
||||||
bool aDeleteDrawable,
|
|
||||||
bool aDoubleBuffered,
|
bool aDoubleBuffered,
|
||||||
gfxXlibSurface* aPixmap,
|
ContextProfile profile,
|
||||||
ContextProfile profile)
|
Drawable aOwnedPixmap)
|
||||||
: GLContext(flags, caps, shareContext, isOffscreen),
|
: GLContext(flags, caps, shareContext, isOffscreen),
|
||||||
mContext(aContext),
|
mContext(aContext),
|
||||||
mDisplay(aDisplay),
|
mDisplay(aDisplay),
|
||||||
mDrawable(aDrawable),
|
mDrawable(aDrawable),
|
||||||
mDeleteDrawable(aDeleteDrawable),
|
mOwnedPixmap(aOwnedPixmap),
|
||||||
mDoubleBuffered(aDoubleBuffered),
|
mDoubleBuffered(aDoubleBuffered),
|
||||||
mGLX(&sGLXLibrary),
|
mGLX(&sGLXLibrary),
|
||||||
mPixmap(aPixmap),
|
|
||||||
mOwnsContext(true)
|
mOwnsContext(true)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mGLX);
|
MOZ_ASSERT(mGLX);
|
||||||
|
|
@ -1098,10 +1096,9 @@ GLContextProviderGLX::CreateWrappingExisting(void* aContext, void* aSurface)
|
||||||
false, // Offscreen
|
false, // Offscreen
|
||||||
(Display*)DefaultXDisplay(), // Display
|
(Display*)DefaultXDisplay(), // Display
|
||||||
(GLXDrawable)aSurface, (GLXContext)aContext,
|
(GLXDrawable)aSurface, (GLXContext)aContext,
|
||||||
false, // aDeleteDrawable,
|
|
||||||
true,
|
true,
|
||||||
(gfxXlibSurface*)nullptr,
|
ContextProfile::OpenGLCompatibility,
|
||||||
ContextProfile::OpenGLCompatibility);
|
(Drawable)nullptr);
|
||||||
|
|
||||||
glContext->mOwnsContext = false;
|
glContext->mOwnsContext = false;
|
||||||
gGlobalContext = glContext;
|
gGlobalContext = glContext;
|
||||||
|
|
@ -1146,8 +1143,7 @@ CreateForWidget(Display* aXDisplay, Window aXWindow, bool aForceAccelerated)
|
||||||
GLContextGLX* shareContext = GetGlobalContextGLX();
|
GLContextGLX* shareContext = GetGlobalContextGLX();
|
||||||
RefPtr<GLContextGLX> gl = GLContextGLX::CreateGLContext(CreateContextFlags::NONE,
|
RefPtr<GLContextGLX> gl = GLContextGLX::CreateGLContext(CreateContextFlags::NONE,
|
||||||
caps, shareContext, false,
|
caps, shareContext, false,
|
||||||
aXDisplay, aXWindow, config,
|
aXDisplay, aXWindow, config);
|
||||||
false);
|
|
||||||
return gl.forget();
|
return gl.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1326,24 +1322,20 @@ CreateOffscreenPixmapContext(CreateContextFlags flags, const IntSize& size,
|
||||||
FindVisualAndDepth(display, visid, &visual, &depth);
|
FindVisualAndDepth(display, visid, &visual, &depth);
|
||||||
|
|
||||||
OffMainThreadScopedXErrorHandler xErrorHandler;
|
OffMainThreadScopedXErrorHandler xErrorHandler;
|
||||||
bool error = false;
|
|
||||||
|
|
||||||
Drawable drawable;
|
|
||||||
GLXPixmap pixmap = 0;
|
GLXPixmap pixmap = 0;
|
||||||
|
|
||||||
gfx::IntSize dummySize(16, 16);
|
gfx::IntSize dummySize(16, 16);
|
||||||
RefPtr<gfxXlibSurface> surface = gfxXlibSurface::Create(DefaultScreenOfDisplay(display),
|
const auto drawable =
|
||||||
visual,
|
XCreatePixmap(display, DefaultRootWindow(display),
|
||||||
dummySize);
|
dummySize.width, dummySize.height, depth);
|
||||||
if (surface->CairoStatus() != 0) {
|
if (!drawable) {
|
||||||
mozilla::Unused << xErrorHandler.SyncAndGetError(display);
|
mozilla::Unused << xErrorHandler.SyncAndGetError(display);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle slightly different signature between glXCreatePixmap and
|
// Handle slightly different signature between glXCreatePixmap and
|
||||||
// its pre-GLX-1.3 extension equivalent (though given the ABI, we
|
// its pre-GLX-1.3 extension equivalent (though given the ABI, we
|
||||||
// might not need to).
|
// might not need to).
|
||||||
drawable = surface->XDrawable();
|
|
||||||
if (glx->GLXVersionCheck(1, 3)) {
|
if (glx->GLXVersionCheck(1, 3)) {
|
||||||
pixmap = glx->xCreatePixmap(display, config, drawable, nullptr);
|
pixmap = glx->xCreatePixmap(display, config, drawable, nullptr);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1351,16 +1343,17 @@ CreateOffscreenPixmapContext(CreateContextFlags flags, const IntSize& size,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pixmap == 0) {
|
if (pixmap == 0) {
|
||||||
error = true;
|
XFreePixmap(display, drawable);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serverError = xErrorHandler.SyncAndGetError(display);
|
bool serverError = xErrorHandler.SyncAndGetError(display);
|
||||||
if (error || serverError)
|
if (serverError)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
GLContextGLX* shareContext = GetGlobalContextGLX();
|
GLContextGLX* shareContext = GetGlobalContextGLX();
|
||||||
return GLContextGLX::CreateGLContext(flags, minCaps, shareContext, true, display,
|
return GLContextGLX::CreateGLContext(flags, minCaps, shareContext, true, display,
|
||||||
pixmap, config, true, surface, profile);
|
pixmap, config, drawable, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ already_AddRefed<GLContext>
|
/*static*/ already_AddRefed<GLContext>
|
||||||
|
|
|
||||||
|
|
@ -731,8 +731,7 @@ public:
|
||||||
false,
|
false,
|
||||||
mXDisplay,
|
mXDisplay,
|
||||||
root,
|
root,
|
||||||
config,
|
config);
|
||||||
false);
|
|
||||||
|
|
||||||
if (!mGLContext) {
|
if (!mGLContext) {
|
||||||
lock.NotifyAll();
|
lock.NotifyAll();
|
||||||
|
|
|
||||||
|
|
@ -833,7 +833,7 @@ function ArrayFrom(items, mapfn=undefined, thisArg=undefined) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 7.
|
// Step 7.
|
||||||
assert(usingIterator === undefined, "`items` can't be an Iterable after step 6.g.iv");
|
assert(usingIterator === undefined, "`items` cannot be an Iterable after step 6.g.iv");
|
||||||
|
|
||||||
// Steps 8-9.
|
// Steps 8-9.
|
||||||
var arrayLike = ToObject(items);
|
var arrayLike = ToObject(items);
|
||||||
|
|
@ -1181,6 +1181,35 @@ function FlattenIntoArray(target, source, sourceLen, start, depth, mapperFunctio
|
||||||
return targetIndex;
|
return targetIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ES2022 at() method on the built-in indexables
|
||||||
|
// Array.prototype.at(index)
|
||||||
|
function ArrayAt(index) {
|
||||||
|
// Step 1.
|
||||||
|
var O = ToObject(this);
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
var len = ToLength(O.length);
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
var relativeIndex = ToInteger(index);
|
||||||
|
|
||||||
|
// Steps 4-5.
|
||||||
|
var k;
|
||||||
|
if (relativeIndex >= 0) {
|
||||||
|
k = relativeIndex;
|
||||||
|
} else {
|
||||||
|
k = len + relativeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 6.
|
||||||
|
if (k < 0 || k >= len) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 7.
|
||||||
|
return O[k];
|
||||||
|
}
|
||||||
|
|
||||||
function ArrayStaticConcat(arr, arg1) {
|
function ArrayStaticConcat(arr, arg1) {
|
||||||
if (arguments.length < 1)
|
if (arguments.length < 1)
|
||||||
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.concat');
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.concat');
|
||||||
|
|
|
||||||
|
|
@ -784,6 +784,39 @@ function String_static_raw(callSite, ...substitutions) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ES2022 at() method on the built-in indexables
|
||||||
|
// String.prototype.at(index)
|
||||||
|
function String_at(index) {
|
||||||
|
// Step 1.
|
||||||
|
if (this === undefined || this === null)
|
||||||
|
ThrowIncompatibleMethod("at", this);
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
var string = ToString(this);
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
var len = string.length;
|
||||||
|
|
||||||
|
// Step 4.
|
||||||
|
var relativeIndex = ToInteger(index);
|
||||||
|
|
||||||
|
// Steps 5-6.
|
||||||
|
var k;
|
||||||
|
if (relativeIndex >= 0) {
|
||||||
|
k = relativeIndex;
|
||||||
|
} else {
|
||||||
|
k = len + relativeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 7.
|
||||||
|
if (k < 0 || k >= len) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 8.
|
||||||
|
return string[k];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare String str1 against String str2, using the locale and collation
|
* Compare String str1 against String str2, using the locale and collation
|
||||||
* options provided.
|
* options provided.
|
||||||
|
|
|
||||||
|
|
@ -1308,6 +1308,45 @@ function TypedArraySubarray(begin, end) {
|
||||||
return TypedArraySpeciesCreateWithBuffer(obj, buffer, beginByteOffset, newLength);
|
return TypedArraySpeciesCreateWithBuffer(obj, buffer, beginByteOffset, newLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ES2022 at() method on the built-in indexables
|
||||||
|
// %TypedArray%.prototype.at(index)
|
||||||
|
function TypedArrayAt(index) {
|
||||||
|
// Step 1.
|
||||||
|
var obj = this;
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
// This function is not generic.
|
||||||
|
if (!IsObject(obj) || !IsTypedArray(obj)) {
|
||||||
|
return callFunction(CallTypedArrayMethodIfWrapped, obj, index,
|
||||||
|
"TypedArrayAt");
|
||||||
|
}
|
||||||
|
GetAttachedArrayBuffer(obj);
|
||||||
|
|
||||||
|
// If we got here, `this` is either a typed array or a wrapper for one.
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
var len = TypedArrayLength(obj);
|
||||||
|
|
||||||
|
// Step 4.
|
||||||
|
var relativeIndex = ToInteger(index);
|
||||||
|
|
||||||
|
// Steps 5-6.
|
||||||
|
var k;
|
||||||
|
if (relativeIndex >= 0) {
|
||||||
|
k = relativeIndex;
|
||||||
|
} else {
|
||||||
|
k = len + relativeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 7.
|
||||||
|
if (k < 0 || k >= len) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 8.
|
||||||
|
return obj[k];
|
||||||
|
}
|
||||||
|
|
||||||
// ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
|
// ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
|
||||||
function TypedArrayValues() {
|
function TypedArrayValues() {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,7 @@ class StoreBuffer
|
||||||
|
|
||||||
explicit operator bool() const { return objectAndKind_ != 0; }
|
explicit operator bool() const { return objectAndKind_ != 0; }
|
||||||
|
|
||||||
typedef struct {
|
typedef struct Hasher {
|
||||||
typedef SlotsEdge Lookup;
|
typedef SlotsEdge Lookup;
|
||||||
static HashNumber hash(const Lookup& l) { return l.objectAndKind_ ^ l.start_ ^ l.count_; }
|
static HashNumber hash(const Lookup& l) { return l.objectAndKind_ ^ l.start_ ^ l.count_; }
|
||||||
static bool match(const SlotsEdge& k, const Lookup& l) { return k == l; }
|
static bool match(const SlotsEdge& k, const Lookup& l) { return k == l; }
|
||||||
|
|
|
||||||
|
|
@ -3189,6 +3189,9 @@ static const JSFunctionSpec array_methods[] = {
|
||||||
JS_SELF_HOSTED_FN("flat", "ArrayFlat", 0,0),
|
JS_SELF_HOSTED_FN("flat", "ArrayFlat", 0,0),
|
||||||
JS_SELF_HOSTED_FN("flatMap", "ArrayFlatMap", 1,0),
|
JS_SELF_HOSTED_FN("flatMap", "ArrayFlatMap", 1,0),
|
||||||
|
|
||||||
|
/* ES2022 additions */
|
||||||
|
JS_SELF_HOSTED_FN("at", "ArrayAt", 1,0),
|
||||||
|
|
||||||
JS_FS_END
|
JS_FS_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2847,6 +2847,9 @@ static const JSFunctionSpec string_methods[] = {
|
||||||
/* Python-esque sequence methods. */
|
/* Python-esque sequence methods. */
|
||||||
JS_FN("concat", str_concat, 1,0),
|
JS_FN("concat", str_concat, 1,0),
|
||||||
JS_SELF_HOSTED_FN("slice", "String_slice", 2,0),
|
JS_SELF_HOSTED_FN("slice", "String_slice", 2,0),
|
||||||
|
|
||||||
|
/* ES2022 additions */
|
||||||
|
JS_SELF_HOSTED_FN("at", "String_at", 1,0),
|
||||||
|
|
||||||
/* HTML string methods. */
|
/* HTML string methods. */
|
||||||
JS_SELF_HOSTED_FN("bold", "String_bold", 0,0),
|
JS_SELF_HOSTED_FN("bold", "String_bold", 0,0),
|
||||||
|
|
|
||||||
|
|
@ -1538,6 +1538,10 @@ TypedArrayObject::protoFunctions[] = {
|
||||||
JS_SELF_HOSTED_FN("includes", "TypedArrayIncludes", 2, 0),
|
JS_SELF_HOSTED_FN("includes", "TypedArrayIncludes", 2, 0),
|
||||||
JS_SELF_HOSTED_FN("toString", "ArrayToString", 0, 0),
|
JS_SELF_HOSTED_FN("toString", "ArrayToString", 0, 0),
|
||||||
JS_SELF_HOSTED_FN("toLocaleString", "TypedArrayToLocaleString", 2, 0),
|
JS_SELF_HOSTED_FN("toLocaleString", "TypedArrayToLocaleString", 2, 0),
|
||||||
|
|
||||||
|
/* ES2022 additions */
|
||||||
|
JS_SELF_HOSTED_FN("at", "TypedArrayAt", 1, 0),
|
||||||
|
|
||||||
JS_FS_END
|
JS_FS_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -858,6 +858,10 @@ int NrSocket::connect(nr_transport_addr *addr) {
|
||||||
PRNetAddr naddr;
|
PRNetAddr naddr;
|
||||||
int32_t connect_status, getsockname_status;
|
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)))
|
if ((r=nr_transport_addr_to_praddr(addr, &naddr)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
|
|
@ -1840,7 +1844,7 @@ void NrTcpSocketIpc::close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int NrTcpSocketIpc::connect(nr_transport_addr *addr) {
|
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;
|
int32_t remote_port, local_port;
|
||||||
int r, _status;
|
int r, _status;
|
||||||
if ((r=nr_transport_addr_get_addrstring_and_port(addr,
|
if ((r=nr_transport_addr_get_addrstring_and_port(addr,
|
||||||
|
|
@ -1856,6 +1860,8 @@ int NrTcpSocketIpc::connect(nr_transport_addr *addr) {
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tls_host = addr->tls_host;
|
||||||
|
|
||||||
state_ = mirror_state_ = NR_CONNECTING;
|
state_ = mirror_state_ = NR_CONNECTING;
|
||||||
RUN_ON_THREAD(io_thread_,
|
RUN_ON_THREAD(io_thread_,
|
||||||
mozilla::WrapRunnable(RefPtr<NrTcpSocketIpc>(this),
|
mozilla::WrapRunnable(RefPtr<NrTcpSocketIpc>(this),
|
||||||
|
|
@ -1863,7 +1869,8 @@ int NrTcpSocketIpc::connect(nr_transport_addr *addr) {
|
||||||
remote_addr,
|
remote_addr,
|
||||||
static_cast<uint16_t>(remote_port),
|
static_cast<uint16_t>(remote_port),
|
||||||
local_addr,
|
local_addr,
|
||||||
static_cast<uint16_t>(local_port)),
|
static_cast<uint16_t>(local_port),
|
||||||
|
tls_host),
|
||||||
NS_DISPATCH_NORMAL);
|
NS_DISPATCH_NORMAL);
|
||||||
|
|
||||||
// Make caller wait for ready to write.
|
// 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,
|
void NrTcpSocketIpc::connect_i(const nsACString &remote_addr,
|
||||||
uint16_t remote_port,
|
uint16_t remote_port,
|
||||||
const nsACString &local_addr,
|
const nsACString &local_addr,
|
||||||
uint16_t local_port) {
|
uint16_t local_port,
|
||||||
|
const nsACString &tls_host) {
|
||||||
ASSERT_ON_THREAD(io_thread_);
|
ASSERT_ON_THREAD(io_thread_);
|
||||||
mirror_state_ = NR_CONNECTING;
|
mirror_state_ = NR_CONNECTING;
|
||||||
|
|
||||||
|
|
@ -1948,11 +1956,21 @@ void NrTcpSocketIpc::connect_i(const nsACString &remote_addr,
|
||||||
|
|
||||||
// Bug 1285330: put filtering back in here
|
// Bug 1285330: put filtering back in here
|
||||||
|
|
||||||
// XXX remove remote!
|
if (tls_host.IsEmpty()) {
|
||||||
socket_child_->SendWindowlessOpenBind(this,
|
// XXX remove remote!
|
||||||
remote_addr, remote_port,
|
socket_child_->SendWindowlessOpenBind(this,
|
||||||
local_addr, local_port,
|
remote_addr, remote_port,
|
||||||
/* use ssl */ false);
|
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,
|
void NrTcpSocketIpc::write_i(nsAutoPtr<InfallibleTArray<uint8_t>> arr,
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,8 @@ private:
|
||||||
void connect_i(const nsACString &remote_addr,
|
void connect_i(const nsACString &remote_addr,
|
||||||
uint16_t remote_port,
|
uint16_t remote_port,
|
||||||
const nsACString &local_addr,
|
const nsACString &local_addr,
|
||||||
uint16_t local_port);
|
uint16_t local_port,
|
||||||
|
const nsACString &tls_host);
|
||||||
void write_i(nsAutoPtr<InfallibleTArray<uint8_t>> buf,
|
void write_i(nsAutoPtr<InfallibleTArray<uint8_t>> buf,
|
||||||
uint32_t tracking_number);
|
uint32_t tracking_number);
|
||||||
void close_i();
|
void close_i();
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ MOZ_MTLOG_MODULE("mtransport")
|
||||||
|
|
||||||
const char kNrIceTransportUdp[] = "udp";
|
const char kNrIceTransportUdp[] = "udp";
|
||||||
const char kNrIceTransportTcp[] = "tcp";
|
const char kNrIceTransportTcp[] = "tcp";
|
||||||
|
const char kNrIceTransportTls[] = "tls";
|
||||||
|
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
|
|
||||||
|
|
@ -210,6 +211,9 @@ nsresult NrIceStunServer::ToNicerStunStruct(nr_ice_stun_server *server) const {
|
||||||
server->transport = IPPROTO_UDP;
|
server->transport = IPPROTO_UDP;
|
||||||
} else if (transport_ == kNrIceTransportTcp) {
|
} else if (transport_ == kNrIceTransportTcp) {
|
||||||
server->transport = IPPROTO_TCP;
|
server->transport = IPPROTO_TCP;
|
||||||
|
} else if (transport_ == kNrIceTransportTls) {
|
||||||
|
server->transport = IPPROTO_TCP;
|
||||||
|
server->tls = 1;
|
||||||
} else {
|
} else {
|
||||||
MOZ_MTLOG(ML_ERROR, "Unsupported STUN server transport: " << transport_);
|
MOZ_MTLOG(ML_ERROR, "Unsupported STUN server transport: " << transport_);
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
@ -586,6 +590,7 @@ NrIceCtx::Initialize(const std::string& ufrag,
|
||||||
nsCString mapping_type;
|
nsCString mapping_type;
|
||||||
nsCString filtering_type;
|
nsCString filtering_type;
|
||||||
bool block_udp = false;
|
bool block_udp = false;
|
||||||
|
bool block_tcp = false;
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIPrefService> pref_service =
|
nsCOMPtr<nsIPrefService> pref_service =
|
||||||
|
|
@ -604,6 +609,9 @@ NrIceCtx::Initialize(const std::string& ufrag,
|
||||||
rv = pref_branch->GetBoolPref(
|
rv = pref_branch->GetBoolPref(
|
||||||
"media.peerconnection.nat_simulator.block_udp",
|
"media.peerconnection.nat_simulator.block_udp",
|
||||||
&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->filtering_type_ = TestNat::ToNatBehavior(filtering_type.get());
|
||||||
test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type.get());
|
test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type.get());
|
||||||
test_nat->block_udp_ = block_udp;
|
test_nat->block_udp_ = block_udp;
|
||||||
|
test_nat->block_tcp_ = block_tcp;
|
||||||
test_nat->enabled_ = true;
|
test_nat->enabled_ = true;
|
||||||
SetNat(test_nat);
|
SetNat(test_nat);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ class NrIceMediaStream;
|
||||||
|
|
||||||
extern const char kNrIceTransportUdp[];
|
extern const char kNrIceTransportUdp[];
|
||||||
extern const char kNrIceTransportTcp[];
|
extern const char kNrIceTransportTcp[];
|
||||||
|
extern const char kNrIceTransportTls[];
|
||||||
|
|
||||||
class NrIceStunServer {
|
class NrIceStunServer {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,7 @@ int TestNat::create_socket_factory(nr_socket_factory **factorypp) {
|
||||||
|
|
||||||
TestNrSocket::TestNrSocket(TestNat *nat)
|
TestNrSocket::TestNrSocket(TestNat *nat)
|
||||||
: nat_(nat),
|
: nat_(nat),
|
||||||
|
tls_(false),
|
||||||
timer_handle_(nullptr) {
|
timer_handle_(nullptr) {
|
||||||
nat_->insert_socket(this);
|
nat_->insert_socket(this);
|
||||||
}
|
}
|
||||||
|
|
@ -473,6 +474,10 @@ int TestNrSocket::connect(nr_transport_addr *addr) {
|
||||||
return R_INTERNAL;
|
return R_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr->tls_host[0] != '\0') {
|
||||||
|
tls_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!nat_->enabled_
|
if (!nat_->enabled_
|
||||||
|| addr->protocol==IPPROTO_UDP // Horrible hack to allow default address
|
|| addr->protocol==IPPROTO_UDP // Horrible hack to allow default address
|
||||||
// discovery to work. Only works because
|
// 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) {
|
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()) {
|
if (port_mappings_.empty()) {
|
||||||
// The no-nat case, just pass call through.
|
// 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 {
|
} else {
|
||||||
destroy_stale_port_mappings();
|
destroy_stale_port_mappings();
|
||||||
if (port_mappings_.empty()) {
|
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
|
// This is TCP only
|
||||||
MOZ_ASSERT(port_mappings_.size() == 1);
|
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 TestNrSocket::read(void *buf, size_t maxlen, size_t *len) {
|
||||||
|
int r;
|
||||||
|
|
||||||
if (port_mappings_.empty()) {
|
if (port_mappings_.empty()) {
|
||||||
return internal_socket_->read(buf, maxlen, len);
|
r = internal_socket_->read(buf, maxlen, len);
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(port_mappings_.size() == 1);
|
MOZ_ASSERT(port_mappings_.size() == 1);
|
||||||
int bytesRead =
|
r = port_mappings_.front()->external_socket_->read(buf, maxlen, len);
|
||||||
port_mappings_.front()->external_socket_->read(buf, maxlen, len);
|
if (!r && nat_->refresh_on_ingress_) {
|
||||||
if (bytesRead > 0 && nat_->refresh_on_ingress_) {
|
|
||||||
port_mappings_.front()->last_used_ = PR_IntervalNow();
|
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,
|
int TestNrSocket::async_wait(int how, NR_async_cb cb, void *cb_arg,
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ class TestNat {
|
||||||
refresh_on_ingress_(false),
|
refresh_on_ingress_(false),
|
||||||
block_udp_(false),
|
block_udp_(false),
|
||||||
block_stun_(false),
|
block_stun_(false),
|
||||||
|
block_tcp_(false),
|
||||||
delay_stun_resp_ms_(0),
|
delay_stun_resp_ms_(0),
|
||||||
sockets_() {}
|
sockets_() {}
|
||||||
|
|
||||||
|
|
@ -168,6 +169,7 @@ class TestNat {
|
||||||
bool refresh_on_ingress_;
|
bool refresh_on_ingress_;
|
||||||
bool block_udp_;
|
bool block_udp_;
|
||||||
bool block_stun_;
|
bool block_stun_;
|
||||||
|
bool block_tcp_;
|
||||||
/* Note: this can only delay a single response so far (bug 1253657) */
|
/* Note: this can only delay a single response so far (bug 1253657) */
|
||||||
uint32_t delay_stun_resp_ms_;
|
uint32_t delay_stun_resp_ms_;
|
||||||
|
|
||||||
|
|
@ -319,6 +321,7 @@ class TestNrSocket : public NrSocketBase {
|
||||||
// same nat.
|
// same nat.
|
||||||
RefPtr<NrSocketBase> internal_socket_;
|
RefPtr<NrSocketBase> internal_socket_;
|
||||||
RefPtr<TestNat> nat_;
|
RefPtr<TestNat> nat_;
|
||||||
|
bool tls_;
|
||||||
// Since our comparison logic is different depending on what kind of NAT
|
// 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
|
// 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
|
// comparison function at runtime, and these lists are going to be very
|
||||||
|
|
|
||||||
|
|
@ -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))
|
if(r=nr_transport_addr_copy(&cand->stun_server_addr,addr))
|
||||||
ABORT(r);
|
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 (cand->tcp_type == TCP_TYPE_PASSIVE || cand->tcp_type == TCP_TYPE_SO){
|
||||||
if (r=nr_socket_multi_tcp_stun_server_connect(cand->osock, addr))
|
if (r=nr_socket_multi_tcp_stun_server_connect(cand->osock, addr))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ typedef struct nr_ice_stun_server_ {
|
||||||
} u;
|
} u;
|
||||||
int id;
|
int id;
|
||||||
int transport;
|
int transport;
|
||||||
|
int tls; /* Whether to use TLS or not */
|
||||||
} nr_ice_stun_server;
|
} nr_ice_stun_server;
|
||||||
|
|
||||||
typedef struct nr_ice_turn_server_ {
|
typedef struct nr_ice_turn_server_ {
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ typedef struct nr_transport_addr_ {
|
||||||
/* A string version.
|
/* A string version.
|
||||||
56 = 5 ("IP6:[") + 39 (ipv6 address) + 2 ("]:") + 5 (port) + 4 (/UDP) + 1 (null) */
|
56 = 5 ("IP6:[") + 39 (ipv6 address) + 2 ("]:") + 5 (port) + 4 (/UDP) + 1 (null) */
|
||||||
char as_string[56];
|
char as_string[56];
|
||||||
|
char tls_host[256];
|
||||||
} nr_transport_addr;
|
} nr_transport_addr;
|
||||||
|
|
||||||
typedef struct nr_transport_addr_mask_ {
|
typedef struct nr_transport_addr_mask_ {
|
||||||
|
|
|
||||||
|
|
@ -335,6 +335,7 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
|
||||||
, mSTSThread(nullptr)
|
, mSTSThread(nullptr)
|
||||||
, mAllowIceLoopback(false)
|
, mAllowIceLoopback(false)
|
||||||
, mAllowIceLinkLocal(false)
|
, mAllowIceLinkLocal(false)
|
||||||
|
, mForceIceTcp(false)
|
||||||
, mMedia(nullptr)
|
, mMedia(nullptr)
|
||||||
, mUuidGen(MakeUnique<PCUuidGenerator>())
|
, mUuidGen(MakeUnique<PCUuidGenerator>())
|
||||||
, mNumAudioStreams(0)
|
, mNumAudioStreams(0)
|
||||||
|
|
@ -365,6 +366,8 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
|
||||||
"media.peerconnection.ice.loopback", false);
|
"media.peerconnection.ice.loopback", false);
|
||||||
mAllowIceLinkLocal = Preferences::GetBool(
|
mAllowIceLinkLocal = Preferences::GetBool(
|
||||||
"media.peerconnection.ice.link_local", false);
|
"media.peerconnection.ice.link_local", false);
|
||||||
|
mForceIceTcp = Preferences::GetBool(
|
||||||
|
"media.peerconnection.ice.force_ice_tcp", false);
|
||||||
#endif
|
#endif
|
||||||
memset(mMaxReceiving, 0, sizeof(mMaxReceiving));
|
memset(mMaxReceiving, 0, sizeof(mMaxReceiving));
|
||||||
memset(mMaxSending, 0, sizeof(mMaxSending));
|
memset(mMaxSending, 0, sizeof(mMaxSending));
|
||||||
|
|
@ -527,8 +530,8 @@ PeerConnectionConfiguration::AddIceServer(const RTCIceServer &aServer)
|
||||||
if (!(isStun || isStuns || isTurn || isTurns)) {
|
if (!(isStun || isStuns || isTurn || isTurns)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
if (isTurns || isStuns) {
|
if (isStuns) {
|
||||||
continue; // TODO: Support TURNS and STUNS (Bug 1056934)
|
continue; // TODO: Support STUNS (Bug 1056934)
|
||||||
}
|
}
|
||||||
nsAutoCString spec;
|
nsAutoCString spec;
|
||||||
rv = url->GetSpec(spec);
|
rv = url->GetSpec(spec);
|
||||||
|
|
@ -577,6 +580,11 @@ PeerConnectionConfiguration::AddIceServer(const RTCIceServer &aServer)
|
||||||
if (port == -1)
|
if (port == -1)
|
||||||
port = (isStuns || isTurns)? 5349 : 3478;
|
port = (isStuns || isTurns)? 5349 : 3478;
|
||||||
|
|
||||||
|
if (isStuns || isTurns) {
|
||||||
|
// Should we barf if transport is set to udp or something?
|
||||||
|
transport = "tls";
|
||||||
|
}
|
||||||
|
|
||||||
// First check the known good ports for webrtc
|
// First check the known good ports for webrtc
|
||||||
bool knownGoodPort = false;
|
bool knownGoodPort = false;
|
||||||
for (int i = 0; !knownGoodPort && gGoodWebrtcPortList[i]; i++) {
|
for (int i = 0; !knownGoodPort && gGoodWebrtcPortList[i]; i++) {
|
||||||
|
|
@ -2256,6 +2264,11 @@ NS_IMETHODIMP
|
||||||
PeerConnectionImpl::AddIceCandidate(const char* aCandidate, const char* aMid, unsigned short aLevel) {
|
PeerConnectionImpl::AddIceCandidate(const char* aCandidate, const char* aMid, unsigned short aLevel) {
|
||||||
PC_AUTO_ENTER_API_CALL(true);
|
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;
|
JSErrorResult rv;
|
||||||
RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
|
RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
|
||||||
if (!pco) {
|
if (!pco) {
|
||||||
|
|
@ -3111,7 +3124,7 @@ PeerConnectionImpl::SetSignalingState_m(PCImplSignalingState aSignalingState,
|
||||||
mNegotiationNeeded = false;
|
mNegotiationNeeded = false;
|
||||||
// If we're rolling back a local offer, we might need to remove some
|
// If we're rolling back a local offer, we might need to remove some
|
||||||
// transports, but nothing further needs to be done.
|
// transports, but nothing further needs to be done.
|
||||||
mMedia->ActivateOrRemoveTransports(*mJsepSession);
|
mMedia->ActivateOrRemoveTransports(*mJsepSession, mForceIceTcp);
|
||||||
if (!rollback) {
|
if (!rollback) {
|
||||||
if (NS_FAILED(mMedia->UpdateMediaPipelines(*mJsepSession))) {
|
if (NS_FAILED(mMedia->UpdateMediaPipelines(*mJsepSession))) {
|
||||||
CSFLogError(logTag, "Error Updating MediaPipelines");
|
CSFLogError(logTag, "Error Updating MediaPipelines");
|
||||||
|
|
@ -3277,6 +3290,11 @@ PeerConnectionImpl::CandidateReady(const std::string& candidate,
|
||||||
uint16_t level) {
|
uint16_t level) {
|
||||||
PC_AUTO_ENTER_API_CALL_VOID_RETURN(false);
|
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;
|
std::string mid;
|
||||||
bool skipped = false;
|
bool skipped = false;
|
||||||
nsresult res = mJsepSession->AddLocalIceCandidate(candidate,
|
nsresult res = mJsepSession->AddLocalIceCandidate(candidate,
|
||||||
|
|
|
||||||
|
|
@ -803,6 +803,7 @@ private:
|
||||||
|
|
||||||
bool mAllowIceLoopback;
|
bool mAllowIceLoopback;
|
||||||
bool mAllowIceLinkLocal;
|
bool mAllowIceLinkLocal;
|
||||||
|
bool mForceIceTcp;
|
||||||
RefPtr<PeerConnectionMedia> mMedia;
|
RefPtr<PeerConnectionMedia> mMedia;
|
||||||
|
|
||||||
// The JSEP negotiation session.
|
// The JSEP negotiation session.
|
||||||
|
|
|
||||||
|
|
@ -468,7 +468,8 @@ PeerConnectionMedia::EnsureTransport_s(size_t aLevel, size_t aComponentCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession)
|
PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession,
|
||||||
|
const bool forceIceTcp)
|
||||||
{
|
{
|
||||||
auto transports = aSession.GetTransports();
|
auto transports = aSession.GetTransports();
|
||||||
for (size_t i = 0; i < transports.size(); ++i) {
|
for (size_t i = 0; i < transports.size(); ++i) {
|
||||||
|
|
@ -491,6 +492,14 @@ PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession)
|
||||||
RemoveTransportFlow(i, true);
|
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(
|
RUN_ON_THREAD(
|
||||||
GetSTSThread(),
|
GetSTSThread(),
|
||||||
WrapRunnable(RefPtr<PeerConnectionMedia>(this),
|
WrapRunnable(RefPtr<PeerConnectionMedia>(this),
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,8 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||||
|
|
||||||
// Activate or remove ICE transports at the conclusion of offer/answer,
|
// Activate or remove ICE transports at the conclusion of offer/answer,
|
||||||
// or when rollback occurs.
|
// or when rollback occurs.
|
||||||
void ActivateOrRemoveTransports(const JsepSession& aSession);
|
void ActivateOrRemoveTransports(const JsepSession& aSession,
|
||||||
|
const bool forceIceTcp);
|
||||||
|
|
||||||
// Start ICE checks.
|
// Start ICE checks.
|
||||||
void StartIceChecks(const JsepSession& session);
|
void StartIceChecks(const JsepSession& session);
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,11 @@ interface nsISocketTransport : nsITransport
|
||||||
unsigned long getTimeout(in unsigned long aType);
|
unsigned long getTimeout(in unsigned long aType);
|
||||||
void setTimeout(in unsigned long aType, in unsigned long aValue);
|
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.
|
* Values for the aType parameter passed to get/setTimeout.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -738,6 +738,7 @@ nsSocketTransport::nsSocketTransport()
|
||||||
, mProxyTransparentResolvesHost(false)
|
, mProxyTransparentResolvesHost(false)
|
||||||
, mHttpsProxy(false)
|
, mHttpsProxy(false)
|
||||||
, mConnectionFlags(0)
|
, mConnectionFlags(0)
|
||||||
|
, mReuseAddrPort(false)
|
||||||
, mState(STATE_CLOSED)
|
, mState(STATE_CLOSED)
|
||||||
, mAttached(false)
|
, mAttached(false)
|
||||||
, mInputClosed(true)
|
, mInputClosed(true)
|
||||||
|
|
@ -1355,6 +1356,32 @@ nsSocketTransport::InitiateSocket()
|
||||||
status = PR_SetSocketOption(fd, &opt);
|
status = PR_SetSocketOption(fd, &opt);
|
||||||
NS_ASSERTION(status == PR_SUCCESS, "unable to make socket non-blocking");
|
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
|
// 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
|
// full packets the final packet of a multi segment POST/PUT or pipeline
|
||||||
// sequence is delayed a full rtt
|
// sequence is delayed a full rtt
|
||||||
|
|
@ -2484,6 +2511,13 @@ nsSocketTransport::SetTimeout(uint32_t type, uint32_t value)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSocketTransport::SetReuseAddrPort(bool reuseAddrPort)
|
||||||
|
{
|
||||||
|
mReuseAddrPort = reuseAddrPort;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSocketTransport::SetQoSBits(uint8_t aQoSBits)
|
nsSocketTransport::SetQoSBits(uint8_t aQoSBits)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,7 @@ private:
|
||||||
bool mProxyTransparentResolvesHost;
|
bool mProxyTransparentResolvesHost;
|
||||||
bool mHttpsProxy;
|
bool mHttpsProxy;
|
||||||
uint32_t mConnectionFlags;
|
uint32_t mConnectionFlags;
|
||||||
|
bool mReuseAddrPort;
|
||||||
|
|
||||||
// The origin attributes are used to create sockets. The first party domain
|
// 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
|
// will eventually be used to isolate OCSP cache and is only non-empty when
|
||||||
|
|
|
||||||
|
|
@ -1685,6 +1685,12 @@ SocketTransportShim::SetTimeout(uint32_t aType, uint32_t aValue)
|
||||||
return mWrapped->SetTimeout(aType, aValue);
|
return mWrapped->SetTimeout(aType, aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
SocketTransportShim::SetReuseAddrPort(bool aReuseAddrPort)
|
||||||
|
{
|
||||||
|
return mWrapped->SetReuseAddrPort(aReuseAddrPort);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
SocketTransportShim::GetQoSBits(uint8_t *aQoSBits)
|
SocketTransportShim::GetQoSBits(uint8_t *aQoSBits)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1346,7 +1346,7 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, sy
|
||||||
raise
|
raise
|
||||||
|
|
||||||
# Resign the executable, since install_name_tool invalidates the signature
|
# Resign the executable, since install_name_tool invalidates the signature
|
||||||
call_subprocess(["codesign", "-s", "-", py_executable])
|
call_subprocess(["codesign", "-fs", "-", py_executable])
|
||||||
|
|
||||||
if not is_win:
|
if not is_win:
|
||||||
# Ensure that 'python', 'pythonX' and 'pythonX.Y' all exist
|
# Ensure that 'python', 'pythonX' and 'pythonX.Y' all exist
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ import passlib.utils # for saslprep
|
||||||
import copy
|
import copy
|
||||||
import random
|
import random
|
||||||
import operator
|
import operator
|
||||||
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import string
|
||||||
import time
|
import time
|
||||||
from string import Template
|
from string import Template
|
||||||
from twisted.internet import reactor, protocol
|
from twisted.internet import reactor, protocol
|
||||||
|
|
@ -715,6 +717,38 @@ def prune_allocations():
|
||||||
del allocations[key]
|
del allocations[key]
|
||||||
allocation.close()
|
allocation.close()
|
||||||
|
|
||||||
|
CERT_FILE = "selfsigned.crt"
|
||||||
|
KEY_FILE = "private.key"
|
||||||
|
|
||||||
|
def create_self_signed_cert(name):
|
||||||
|
from OpenSSL import crypto
|
||||||
|
if os.path.isfile(CERT_FILE) and os.path.isfile(KEY_FILE):
|
||||||
|
return
|
||||||
|
|
||||||
|
# create a key pair
|
||||||
|
k = crypto.PKey()
|
||||||
|
k.generate_key(crypto.TYPE_RSA, 1024)
|
||||||
|
|
||||||
|
# create a self-signed cert
|
||||||
|
cert = crypto.X509()
|
||||||
|
cert.get_subject().C = "US"
|
||||||
|
cert.get_subject().ST = "TX"
|
||||||
|
cert.get_subject().L = "Dallas"
|
||||||
|
cert.get_subject().O = "Mozilla test iceserver"
|
||||||
|
cert.get_subject().OU = "Mozilla test iceserver"
|
||||||
|
cert.get_subject().CN = name
|
||||||
|
cert.set_serial_number(1000)
|
||||||
|
cert.gmtime_adj_notBefore(0)
|
||||||
|
cert.gmtime_adj_notAfter(10*365*24*60*60)
|
||||||
|
cert.set_issuer(cert.get_subject())
|
||||||
|
cert.set_pubkey(k)
|
||||||
|
cert.sign(k, 'sha1')
|
||||||
|
|
||||||
|
open(CERT_FILE, "wt").write(
|
||||||
|
crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
|
||||||
|
open(KEY_FILE, "wt").write(
|
||||||
|
crypto.dump_privatekey(crypto.FILETYPE_PEM, k))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
random.seed()
|
random.seed()
|
||||||
|
|
||||||
|
|
@ -739,20 +773,48 @@ if __name__ == "__main__":
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
from twisted.internet import ssl
|
||||||
|
from OpenSSL import SSL
|
||||||
|
create_self_signed_cert(hostname)
|
||||||
|
tls_context_factory = ssl.DefaultOpenSSLContextFactory(KEY_FILE, CERT_FILE, SSL.TLSv1_2_METHOD)
|
||||||
|
reactor.listenSSL(5349, TcpStunHandlerFactory(), tls_context_factory, interface=interface_4)
|
||||||
|
|
||||||
|
try:
|
||||||
|
reactor.listenSSL(5349, TcpStunHandlerFactory(), tls_context_factory, interface=interface_6)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
f = open(CERT_FILE, 'r');
|
||||||
|
lines = f.readlines();
|
||||||
|
lines.pop(0); # Remove BEGIN CERTIFICATE
|
||||||
|
lines.pop(); # Remove END CERTIFICATE
|
||||||
|
lines = map(string.strip, lines);
|
||||||
|
certbase64 = string.join(lines, '');
|
||||||
|
|
||||||
|
turns_url = ', "turns:' + hostname + '"'
|
||||||
|
cert_prop = ', "cert":"' + certbase64 + '"'
|
||||||
|
except:
|
||||||
|
turns_url = ''
|
||||||
|
cert_prop = ''
|
||||||
|
pass
|
||||||
|
|
||||||
allocation_pruner = LoopingCall(prune_allocations)
|
allocation_pruner = LoopingCall(prune_allocations)
|
||||||
allocation_pruner.start(1)
|
allocation_pruner.start(1)
|
||||||
|
|
||||||
template = Template(
|
template = Template(
|
||||||
'[\
|
'[\
|
||||||
{"url":"stun:$hostname"}, \
|
{"urls":["stun:$hostname", "stun:$hostname?transport=tcp"]}, \
|
||||||
{"url":"stun:$hostname?transport=tcp"}, \
|
{"username":"$user","credential":"$pwd","urls": \
|
||||||
{"username":"$user","credential":"$pwd","url":"turn:$hostname"}, \
|
["turn:$hostname", "turn:$hostname?transport=tcp" $turns_url] \
|
||||||
{"username":"$user","credential":"$pwd","url":"turn:$hostname?transport=tcp"}]'
|
$cert_prop}]' # Hack to make it easier to override cert checks
|
||||||
)
|
)
|
||||||
|
|
||||||
print(template.substitute(user=turn_user,
|
print(template.substitute(user=turn_user,
|
||||||
pwd=turn_pass,
|
pwd=turn_pass,
|
||||||
hostname=hostname))
|
hostname=hostname,
|
||||||
|
turns_url=turns_url,
|
||||||
|
cert_prop=cert_prop))
|
||||||
|
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue