зеркало из https://github.com/mozilla/gecko-dev.git
Merge latest green inbound changeset and mozilla-central
This commit is contained in:
Коммит
90b1996255
|
@ -4,7 +4,7 @@
|
|||
|
||||
#filter substitution
|
||||
|
||||
pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.xul");
|
||||
pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.html");
|
||||
pref("browser.chromeURL", "chrome://browser/content/");
|
||||
|
||||
// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
|
||||
|
|
|
@ -11,7 +11,7 @@ window.addEventListener('ContentStart', function() {
|
|||
let shell = document.getElementById('shell');
|
||||
|
||||
// The <browser> element inside it
|
||||
let browser = document.getElementById('homescreen');
|
||||
let browser = document.getElementById('systemapp');
|
||||
|
||||
// Figure out the native resolution of the screen
|
||||
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- 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/. -->
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
id="shell"
|
||||
windowtype="navigator:browser"
|
||||
#ifdef ANDROID
|
||||
sizemode="fullscreen"
|
||||
#endif
|
||||
style="background: black; overflow: hidden; width:100%; height:100%; padding: 0px !important"
|
||||
onunload="shell.stop();">
|
||||
|
||||
<head>
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://browser/content/settings.js"> </script>
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://browser/content/shell.js"> </script>
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
<!-- this script handles the screen argument for desktop builds -->
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://browser/content/screen.js"> </script>
|
||||
<!-- this script handles the "runapp" argument for desktop builds -->
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://browser/content/runapp.js"> </script>
|
||||
#endif
|
||||
</head>
|
||||
<body id="container" style="margin: 0px; width:100%; height:100%;">
|
||||
<!-- The html:iframe containing the UI is created here. -->
|
||||
</body>
|
||||
</html>
|
|
@ -186,7 +186,7 @@ var shell = {
|
|||
|
||||
get contentBrowser() {
|
||||
delete this.contentBrowser;
|
||||
return this.contentBrowser = document.getElementById('homescreen');
|
||||
return this.contentBrowser = document.getElementById('systemapp');
|
||||
},
|
||||
|
||||
get homeURL() {
|
||||
|
@ -269,25 +269,25 @@ var shell = {
|
|||
}
|
||||
|
||||
let manifestURL = this.manifestURL;
|
||||
// <html:iframe id="homescreen"
|
||||
// <html:iframe id="systemapp"
|
||||
// mozbrowser="true" allowfullscreen="true"
|
||||
// style="overflow: hidden; -moz-box-flex: 1; border: none;"
|
||||
// style="overflow: hidden; height: 100%; width: 100%; border: none;"
|
||||
// src="data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;'>"/>
|
||||
let browserFrame =
|
||||
let systemAppFrame =
|
||||
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
|
||||
browserFrame.setAttribute('id', 'homescreen');
|
||||
browserFrame.setAttribute('mozbrowser', 'true');
|
||||
browserFrame.setAttribute('mozapp', manifestURL);
|
||||
browserFrame.setAttribute('allowfullscreen', 'true');
|
||||
browserFrame.setAttribute('style', "overflow: hidden; -moz-box-flex: 1; border: none;");
|
||||
browserFrame.setAttribute('src', "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;");
|
||||
document.getElementById('shell').appendChild(browserFrame);
|
||||
systemAppFrame.setAttribute('id', 'systemapp');
|
||||
systemAppFrame.setAttribute('mozbrowser', 'true');
|
||||
systemAppFrame.setAttribute('mozapp', manifestURL);
|
||||
systemAppFrame.setAttribute('allowfullscreen', 'true');
|
||||
systemAppFrame.setAttribute('style', "overflow: hidden; height: 100%; width: 100%; border: none;");
|
||||
systemAppFrame.setAttribute('src', "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;");
|
||||
document.getElementById('container').appendChild(systemAppFrame);
|
||||
|
||||
browserFrame.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
|
||||
.createInstance(Ci.nsISHistory);
|
||||
systemAppFrame.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
|
||||
.createInstance(Ci.nsISHistory);
|
||||
|
||||
// Capture all key events so we can filter out hardware buttons
|
||||
// And send them to Gaia via mozChromeEvents.
|
||||
|
@ -1239,3 +1239,50 @@ Services.obs.addObserver(function(aSubject, aTopic, aData) {
|
|||
Services.prefs.setIntPref("browser.cache.disk.capacity", size);
|
||||
}) ()
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
let SensorsListener = {
|
||||
sensorsListenerDevices: ['crespo'],
|
||||
device: libcutils.property_get("ro.product.device"),
|
||||
|
||||
deviceNeedsWorkaround: function SensorsListener_deviceNeedsWorkaround() {
|
||||
return (this.sensorsListenerDevices.indexOf(this.device) != -1);
|
||||
},
|
||||
|
||||
handleEvent: function SensorsListener_handleEvent(evt) {
|
||||
switch(evt.type) {
|
||||
case 'devicemotion':
|
||||
// Listener that does nothing, we need this to have the sensor being
|
||||
// able to report correct values, as explained in bug 753245, comment 6
|
||||
// and in bug 871916
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
observe: function SensorsListener_observe(subject, topic, data) {
|
||||
// We remove the listener when the screen is off, otherwise sensor will
|
||||
// continue to bother us with data and we won't be able to get the
|
||||
// system into suspend state, thus draining battery.
|
||||
if (data === 'on') {
|
||||
window.addEventListener('devicemotion', this);
|
||||
} else {
|
||||
window.removeEventListener('devicemotion', this);
|
||||
}
|
||||
},
|
||||
|
||||
init: function SensorsListener_init() {
|
||||
if (this.deviceNeedsWorkaround()) {
|
||||
// On boot, enable the listener, screen will be on.
|
||||
window.addEventListener('devicemotion', this);
|
||||
|
||||
// Then listen for further screen state changes
|
||||
Services.obs.addObserver(this, 'screen-state-changed', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SensorsListener.init();
|
||||
#endif
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="shell"
|
||||
windowtype="navigator:browser"
|
||||
#ifdef ANDROID
|
||||
sizemode="fullscreen"
|
||||
#endif
|
||||
style="background: black; overflow: hidden; width:320px; height:480px"
|
||||
onunload="shell.stop();">
|
||||
|
||||
<script type="application/javascript" src="chrome://browser/content/settings.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/shell.js"/>
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
<!-- this script handles the screen argument for desktop builds -->
|
||||
<script type="application/javascript" src="chrome://browser/content/screen.js"/>
|
||||
<!-- this script handles the "runapp" argument for desktop builds -->
|
||||
<script type="application/javascript" src="chrome://browser/content/runapp.js"/>
|
||||
#endif
|
||||
<!-- The html:iframe containing the UI is created here. -->
|
||||
</window>
|
|
@ -12,7 +12,7 @@ chrome.jar:
|
|||
* content/dbg-browser-actors.js (content/dbg-browser-actors.js)
|
||||
content/forms.js (content/forms.js)
|
||||
* content/settings.js (content/settings.js)
|
||||
* content/shell.xul (content/shell.xul)
|
||||
* content/shell.html (content/shell.html)
|
||||
* content/shell.js (content/shell.js)
|
||||
#ifndef ANDROID
|
||||
content/screen.js (content/screen.js)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"revision": "f400eac8b28353050ea9ff87dcb7e780e3537a89",
|
||||
"revision": "7db3c28d7056b880b3be261f7784b5cc3e96702b",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ Cu.import("resource://gre/modules/OfflineCacheInstaller.jsm");
|
|||
Cu.import("resource://gre/modules/SystemMessagePermissionsChecker.jsm");
|
||||
Cu.import("resource://gre/modules/AppDownloadManager.jsm");
|
||||
Cu.import("resource://gre/modules/WebappOSUtils.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
XPCOMUtils.defineLazyGetter(this, "libcutils", function() {
|
||||
|
@ -1327,7 +1328,6 @@ this.DOMApplicationRegistry = {
|
|||
|
||||
// Returns the MD5 hash of a file, doing async IO off the main thread.
|
||||
computeFileHash: function computeFileHash(aFile, aCallback) {
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
const CHUNK_SIZE = 16384;
|
||||
|
||||
// Return the two-digit hexadecimal code for a byte.
|
||||
|
|
|
@ -9,7 +9,6 @@ TEST_DIRS += ['test']
|
|||
XPIDL_SOURCES += [
|
||||
'nsIDOMDOMCursor.idl',
|
||||
'nsIDOMDOMRequest.idl',
|
||||
'nsIDOMDOMWindowResizeEventDetail.idl',
|
||||
'nsIEntropyCollector.idl',
|
||||
'nsIScriptChannel.idl',
|
||||
'nsISiteSpecificUserAgent.idl',
|
||||
|
@ -74,7 +73,6 @@ CPP_SOURCES += [
|
|||
'nsDOMNavigationTiming.cpp',
|
||||
'nsDOMScriptObjectFactory.cpp',
|
||||
'nsDOMWindowList.cpp',
|
||||
'nsDOMWindowResizeEventDetail.cpp',
|
||||
'nsDOMWindowUtils.cpp',
|
||||
'nsFocusManager.cpp',
|
||||
'nsGlobalWindow.cpp',
|
||||
|
|
|
@ -184,7 +184,6 @@
|
|||
#endif
|
||||
|
||||
#include "nsIDOMCameraManager.h"
|
||||
#include "nsIDOMDOMWindowResizeEventDetail.h"
|
||||
#include "nsIDOMGlobalObjectConstructor.h"
|
||||
#include "nsIDOMLockedFile.h"
|
||||
#include "nsDebug.h"
|
||||
|
@ -554,9 +553,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
NS_DEFINE_CLASSINFO_DATA(CameraCapabilities, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(DOMWindowResizeEventDetail, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(LockedFile, nsEventTargetSH,
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(CSSFontFeatureValuesRule, nsDOMGenericSH,
|
||||
|
@ -1429,10 +1425,6 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_MAP_ENTRY(nsICameraCapabilities)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(DOMWindowResizeEventDetail, nsIDOMDOMWindowResizeEventDetail)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMWindowResizeEventDetail)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(LockedFile, nsIDOMLockedFile)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMLockedFile)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
|
|
@ -141,8 +141,6 @@ DOMCI_CLASS(BluetoothDevice)
|
|||
|
||||
DOMCI_CLASS(CameraCapabilities)
|
||||
|
||||
DOMCI_CLASS(DOMWindowResizeEventDetail)
|
||||
|
||||
DOMCI_CLASS(LockedFile)
|
||||
|
||||
DOMCI_CLASS(CSSFontFeatureValuesRule)
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
#include "nsDOMWindowResizeEventDetail.h"
|
||||
#include "nsDOMClassInfoID.h" // DOMCI_DATA
|
||||
|
||||
DOMCI_DATA(DOMWindowResizeEventDetail, nsDOMWindowResizeEventDetail)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMWindowResizeEventDetail)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDOMWindowResizeEventDetail)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMWindowResizeEventDetail)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF(nsDOMWindowResizeEventDetail)
|
||||
NS_IMPL_RELEASE(nsDOMWindowResizeEventDetail)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowResizeEventDetail::GetWidth(int32_t* aOut)
|
||||
{
|
||||
*aOut = mSize.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowResizeEventDetail::GetHeight(int32_t* aOut)
|
||||
{
|
||||
*aOut = mSize.height;
|
||||
return NS_OK;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
#include "nsIDOMDOMWindowResizeEventDetail.h"
|
||||
#include "nsSize.h"
|
||||
|
||||
class nsDOMWindowResizeEventDetail : public nsIDOMDOMWindowResizeEventDetail
|
||||
{
|
||||
public:
|
||||
nsDOMWindowResizeEventDetail(const nsIntSize& aSize)
|
||||
: mSize(aSize)
|
||||
{}
|
||||
|
||||
virtual ~nsDOMWindowResizeEventDetail() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMDOMWINDOWRESIZEEVENTDETAIL
|
||||
|
||||
private:
|
||||
const nsIntSize mSize;
|
||||
};
|
|
@ -34,7 +34,6 @@
|
|||
#include "nsIPermissionManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptTimeoutHandler.h"
|
||||
#include "nsDOMWindowResizeEventDetail.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Thanks so much, Microsoft! :(
|
||||
|
@ -179,6 +178,7 @@
|
|||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
#include "GeneratedEvents.h"
|
||||
#include "GeneratedEventClasses.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
|
@ -209,6 +209,7 @@
|
|||
#include "nsSandboxFlags.h"
|
||||
#include "TimeChangeObserver.h"
|
||||
#include "mozilla/dom/AudioContext.h"
|
||||
#include "mozilla/dom/BrowserElementDictionariesBinding.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
|
||||
|
@ -4956,31 +4957,40 @@ nsGlobalWindow::DispatchCustomEvent(const char *aEventName)
|
|||
bool
|
||||
nsGlobalWindow::DispatchResizeEvent(const nsIntSize& aSize)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDoc);
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsresult rv = domDoc->CreateEvent(NS_LITERAL_STRING("CustomEvent"),
|
||||
getter_AddRefs(event));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
ErrorResult res;
|
||||
nsRefPtr<nsDOMEvent> domEvent =
|
||||
mDoc->CreateEvent(NS_LITERAL_STRING("CustomEvent"), res);
|
||||
if (res.Failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWritableVariant> detailVariant = new nsVariant();
|
||||
nsCOMPtr<nsIDOMDOMWindowResizeEventDetail> detail =
|
||||
new nsDOMWindowResizeEventDetail(aSize);
|
||||
rv = detailVariant->SetAsISupports(detail);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoCompartment ac(cx, mJSObject);
|
||||
DOMWindowResizeEventDetailInitializer detail;
|
||||
detail.mWidth = aSize.width;
|
||||
detail.mHeight = aSize.height;
|
||||
JS::Rooted<JS::Value> detailValue(cx);
|
||||
detail.ToObject(cx, JS::NullPtr(), &detailValue);
|
||||
|
||||
nsCOMPtr<nsIDOMCustomEvent> customEvent = do_QueryInterface(event);
|
||||
customEvent->InitCustomEvent(NS_LITERAL_STRING("DOMWindowResize"),
|
||||
CustomEvent* customEvent = static_cast<CustomEvent*>(domEvent.get());
|
||||
customEvent->InitCustomEvent(cx,
|
||||
NS_LITERAL_STRING("DOMWindowResize"),
|
||||
/* bubbles = */ true,
|
||||
/* cancelable = */ true,
|
||||
detailVariant);
|
||||
customEvent->SetTrusted(true);
|
||||
customEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
|
||||
detailValue,
|
||||
res);
|
||||
if (res.Failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
domEvent->SetTrusted(true);
|
||||
domEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
|
||||
|
||||
nsCOMPtr<EventTarget> target = do_QueryInterface(GetOuterWindow());
|
||||
customEvent->SetTarget(target);
|
||||
domEvent->SetTarget(target);
|
||||
|
||||
bool defaultActionEnabled = true;
|
||||
target->DispatchEvent(event, &defaultActionEnabled);
|
||||
target->DispatchEvent(domEvent, &defaultActionEnabled);
|
||||
|
||||
return defaultActionEnabled;
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(166fa8f4-ff40-4150-ab31-272e8246e362)]
|
||||
interface nsIDOMDOMWindowResizeEventDetail : nsISupports
|
||||
{
|
||||
readonly attribute long width;
|
||||
readonly attribute long height;
|
||||
};
|
|
@ -172,7 +172,6 @@ var interfaceNamesInGlobalScope =
|
|||
"DOMStringMap",
|
||||
"DOMTokenList",
|
||||
"DOMTransactionEvent",
|
||||
"DOMWindowResizeEventDetail",
|
||||
"DragEvent",
|
||||
"DynamicsCompressorNode",
|
||||
"Element",
|
||||
|
|
|
@ -22,3 +22,8 @@ dictionary OpenWindowEventDetail {
|
|||
DOMString features = "";
|
||||
Node? frameElement = null;
|
||||
};
|
||||
|
||||
dictionary DOMWindowResizeEventDetail {
|
||||
long width = 0;
|
||||
long height = 0;
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ interface DummyInterface {
|
|||
void MmsAttachment(optional MmsAttachment arg);
|
||||
void AsyncScrollEventDetail(optional AsyncScrollEventDetail arg);
|
||||
void OpenWindowEventDetail(optional OpenWindowEventDetail arg);
|
||||
void DOMWindowResizeEventDetail(optional DOMWindowResizeEventDetail arg);
|
||||
void WifiOptions(optional WifiCommandOptions arg1,
|
||||
optional WifiResultOptions arg2);
|
||||
};
|
||||
|
|
|
@ -120,7 +120,7 @@ class ControlRunnable : public nsRunnable
|
|||
{
|
||||
public:
|
||||
ControlRunnable(CommandOptions aOptions) : mOptions(aOptions) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
|
|
|
@ -255,7 +255,7 @@ this.OnRefTestLoad = function OnRefTestLoad(win)
|
|||
|
||||
#if BOOTSTRAP
|
||||
#if REFTEST_B2G
|
||||
var doc = gContainingWindow.document.getElementsByTagName("window")[0];
|
||||
var doc = gContainingWindow.document.getElementsByTagName("html")[0];
|
||||
#else
|
||||
var doc = gContainingWindow.document.getElementById('main-window');
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,8 @@ namespace {
|
|||
struct NetworkInterface {
|
||||
struct sockaddr_in addr;
|
||||
std::string name;
|
||||
// See NR_INTERFACE_TYPE_* in nICEr/src/net/local_addrs.h
|
||||
int type;
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
@ -74,6 +76,19 @@ GetInterfaces(std::vector<NetworkInterface>* aInterfaces)
|
|||
}
|
||||
interface.name = NS_ConvertUTF16toUTF8(ifaceName).get();
|
||||
|
||||
int32_t type;
|
||||
if (NS_FAILED(iface->GetType(&type))) {
|
||||
continue;
|
||||
}
|
||||
switch (type) {
|
||||
case nsINetworkInterface::NETWORK_TYPE_WIFI:
|
||||
interface.type = NR_INTERFACE_TYPE_WIFI;
|
||||
break;
|
||||
case nsINetworkInterface::NETWORK_TYPE_MOBILE:
|
||||
interface.type = NR_INTERFACE_TYPE_MOBILE;
|
||||
break;
|
||||
}
|
||||
|
||||
aInterfaces->push_back(interface);
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -81,7 +96,7 @@ GetInterfaces(std::vector<NetworkInterface>* aInterfaces)
|
|||
} // anonymous namespace
|
||||
|
||||
int
|
||||
nr_stun_get_addrs(nr_transport_addr aAddrs[], int aMaxAddrs,
|
||||
nr_stun_get_addrs(nr_local_addr aAddrs[], int aMaxAddrs,
|
||||
int aDropLoopback, int* aCount)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -106,11 +121,14 @@ nr_stun_get_addrs(nr_transport_addr aAddrs[], int aMaxAddrs,
|
|||
NetworkInterface &interface = interfaces[i];
|
||||
if (nr_sockaddr_to_transport_addr((sockaddr*)&(interface.addr),
|
||||
sizeof(struct sockaddr_in),
|
||||
IPPROTO_UDP, 0, &(aAddrs[n]))) {
|
||||
IPPROTO_UDP, 0, &(aAddrs[n].addr))) {
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "Problem transforming address");
|
||||
return R_FAILED;
|
||||
}
|
||||
strlcpy(aAddrs[n].ifname, interface.name.c_str(), sizeof(aAddrs[n].ifname));
|
||||
strlcpy(aAddrs[n].addr.ifname, interface.name.c_str(),
|
||||
sizeof(aAddrs[n].addr.ifname));
|
||||
aAddrs[n].interface.type = interface.type;
|
||||
aAddrs[n].interface.estimated_speed = 0;
|
||||
n++;
|
||||
}
|
||||
|
||||
|
@ -121,8 +139,10 @@ nr_stun_get_addrs(nr_transport_addr aAddrs[], int aMaxAddrs,
|
|||
}
|
||||
|
||||
for (int i = 0; i < *aCount; ++i) {
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s", i,
|
||||
aAddrs[i].as_string, aAddrs[i].ifname);
|
||||
char typestr[100];
|
||||
nr_local_addr_fmt_info_string(aAddrs + i, typestr, sizeof(typestr));
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s, type: %s\n",
|
||||
i, aAddrs[i].addr.as_string, aAddrs[i].addr.ifname, typestr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -82,6 +82,7 @@ extern "C" {
|
|||
#include "nricectx.h"
|
||||
#include "nricemediastream.h"
|
||||
#include "nr_socket_prsock.h"
|
||||
#include "nrinterfaceprioritizer.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -368,6 +369,20 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef USE_INTERFACE_PRIORITIZER
|
||||
nr_interface_prioritizer *prioritizer = CreateInterfacePrioritizer();
|
||||
if (!prioritizer) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Couldn't create interface prioritizer.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
r = nr_ice_ctx_set_interface_prioritizer(ctx->ctx_, prioritizer);
|
||||
if (r) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Couldn't set interface prioritizer.");
|
||||
return nullptr;
|
||||
}
|
||||
#endif // USE_INTERFACE_PRIORITIZER
|
||||
|
||||
// Create the handler objects
|
||||
ctx->ice_handler_vtbl_ = new nr_ice_handler_vtbl();
|
||||
ctx->ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair;
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
/* 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/. */
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "logging.h"
|
||||
#include "nrinterfaceprioritizer.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
namespace {
|
||||
|
||||
class LocalAddress {
|
||||
public:
|
||||
LocalAddress()
|
||||
: key_(),
|
||||
is_vpn_(-1),
|
||||
estimated_speed_(-1),
|
||||
type_preference_(-1) {}
|
||||
|
||||
bool Init(const nr_local_addr& local_addr) {
|
||||
char buf[MAXIFNAME + 41];
|
||||
int r = nr_transport_addr_fmt_ifname_addr_string(&local_addr.addr, buf, sizeof(buf));
|
||||
if (r) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Error formatting interface address string.");
|
||||
return false;
|
||||
}
|
||||
key_ = buf;
|
||||
is_vpn_ = (local_addr.interface.type & NR_INTERFACE_TYPE_VPN) != 0 ? 1 : 0;
|
||||
estimated_speed_ = local_addr.interface.estimated_speed;
|
||||
type_preference_ = GetNetworkTypePreference(local_addr.interface.type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator<(const LocalAddress& rhs) const {
|
||||
// Interface that is "less" here is preferred.
|
||||
// If type preferences are different, we should simply sort by
|
||||
// |type_preference_|.
|
||||
if (type_preference_ != rhs.type_preference_) {
|
||||
return type_preference_ < rhs.type_preference_;
|
||||
}
|
||||
|
||||
// If type preferences are the same, the next thing we use to sort is vpn.
|
||||
// If two LocalAddress are different in |is_vpn_|, the LocalAddress that is
|
||||
// not in vpn gets priority.
|
||||
if (is_vpn_ != rhs.is_vpn_) {
|
||||
return is_vpn_ < rhs.is_vpn_;
|
||||
}
|
||||
|
||||
// Compare estimated speed.
|
||||
if (estimated_speed_ != rhs.estimated_speed_) {
|
||||
return estimated_speed_ > rhs.estimated_speed_;
|
||||
}
|
||||
|
||||
// All things above are the same, we can at least sort with key.
|
||||
return key_ < rhs.key_;
|
||||
}
|
||||
|
||||
const std::string& GetKey() const {
|
||||
return key_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Getting the preference corresponding to a type. Getting lower number here
|
||||
// means the type of network is preferred.
|
||||
static inline int GetNetworkTypePreference(int type) {
|
||||
if (type & NR_INTERFACE_TYPE_WIRED) {
|
||||
return 1;
|
||||
}
|
||||
if (type & NR_INTERFACE_TYPE_WIFI) {
|
||||
return 2;
|
||||
}
|
||||
if (type & NR_INTERFACE_TYPE_MOBILE) {
|
||||
return 3;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
std::string key_;
|
||||
int is_vpn_;
|
||||
int estimated_speed_;
|
||||
int type_preference_;
|
||||
};
|
||||
|
||||
class InterfacePrioritizer {
|
||||
public:
|
||||
InterfacePrioritizer()
|
||||
: local_addrs_(),
|
||||
preference_map_(),
|
||||
sorted_(false) {}
|
||||
|
||||
int add(const nr_local_addr *iface) {
|
||||
LocalAddress addr;
|
||||
if (!addr.Init(*iface)) {
|
||||
return R_FAILED;
|
||||
}
|
||||
std::pair<std::set<LocalAddress>::iterator, bool> r =
|
||||
local_addrs_.insert(addr);
|
||||
if (!r.second) {
|
||||
return R_ALREADY; // This address is already in the set.
|
||||
}
|
||||
sorted_ = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sort() {
|
||||
UCHAR tmp_pref = 127;
|
||||
preference_map_.clear();
|
||||
for (std::set<LocalAddress>::iterator i = local_addrs_.begin();
|
||||
i != local_addrs_.end(); ++i) {
|
||||
if (tmp_pref == 0) {
|
||||
return R_FAILED;
|
||||
}
|
||||
preference_map_.insert(make_pair(i->GetKey(), tmp_pref--));
|
||||
}
|
||||
sorted_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getPreference(const char *key, UCHAR *pref) {
|
||||
if (!sorted_) {
|
||||
return R_FAILED;
|
||||
}
|
||||
std::map<std::string, UCHAR>::iterator i = preference_map_.find(key);
|
||||
if (i == preference_map_.end()) {
|
||||
return R_NOT_FOUND;
|
||||
}
|
||||
*pref = i->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<LocalAddress> local_addrs_;
|
||||
std::map<std::string, UCHAR> preference_map_;
|
||||
bool sorted_;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
static int add_interface(void *obj, nr_local_addr *iface) {
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(obj);
|
||||
return ip->add(iface);
|
||||
}
|
||||
|
||||
static int get_priority(void *obj, const char *key, UCHAR *pref) {
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(obj);
|
||||
return ip->getPreference(key, pref);
|
||||
}
|
||||
|
||||
static int sort_preference(void *obj) {
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(obj);
|
||||
return ip->sort();
|
||||
}
|
||||
|
||||
static int destroy(void **objp) {
|
||||
if (!objp || !*objp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(*objp);
|
||||
*objp = 0;
|
||||
delete ip;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nr_interface_prioritizer_vtbl priorizer_vtbl = {
|
||||
add_interface,
|
||||
get_priority,
|
||||
sort_preference,
|
||||
destroy
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nr_interface_prioritizer* CreateInterfacePrioritizer() {
|
||||
nr_interface_prioritizer *ip;
|
||||
int r = nr_interface_prioritizer_create_int(new InterfacePrioritizer(),
|
||||
&priorizer_vtbl,
|
||||
&ip);
|
||||
if (r != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,18 @@
|
|||
/* 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/. */
|
||||
#ifndef nrinterfacepriority_h__
|
||||
#define nrinterfacepriority_h__
|
||||
|
||||
extern "C" {
|
||||
#include "nr_api.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nr_interface_prioritizer* CreateInterfacePrioritizer();
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -40,7 +40,7 @@ LOCAL_INCLUDES += \
|
|||
-I$(topsrcdir)/media/mtransport/third_party/nrappkit/src/port/linux/include \
|
||||
-I$(topsrcdir)/media/mtransport/third_party/nrappkit/src/port/generic/include \
|
||||
$(NULL)
|
||||
DEFINES += -DLINUX
|
||||
DEFINES += -DLINUX -DUSE_INTERFACE_PRIORITIZER
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET), Android)
|
||||
|
@ -71,6 +71,7 @@ MTRANSPORT_LCPPSRCS = \
|
|||
nricemediastream.cpp \
|
||||
nriceresolverfake.cpp \
|
||||
nriceresolver.cpp \
|
||||
nrinterfaceprioritizer.cpp \
|
||||
nr_socket_prsock.cpp \
|
||||
nr_timer.cpp \
|
||||
transportflow.cpp \
|
||||
|
@ -86,6 +87,7 @@ ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
|
|||
MTRANSPORT_LCPPSRCS += \
|
||||
gonk_addrs.cpp \
|
||||
$(NULL)
|
||||
DEFINES += -DUSE_INTERFACE_PRIORITIZER
|
||||
endif
|
||||
|
||||
MTRANSPORT_CPPSRCS = $(addprefix $(topsrcdir)/media/mtransport/, $(MTRANSPORT_LCPPSRCS))
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "nricemediastream.h"
|
||||
#include "nriceresolverfake.h"
|
||||
#include "nriceresolver.h"
|
||||
#include "nrinterfaceprioritizer.h"
|
||||
#include "mtransport_test_utils.h"
|
||||
#include "runnable_utils.h"
|
||||
|
||||
|
@ -485,6 +486,54 @@ class IceConnectTest : public ::testing::Test {
|
|||
mozilla::ScopedDeletePtr<IceTestPeer> p2_;
|
||||
};
|
||||
|
||||
class PrioritizerTest : public ::testing::Test {
|
||||
public:
|
||||
PrioritizerTest():
|
||||
prioritizer_(nullptr) {}
|
||||
|
||||
~PrioritizerTest() {
|
||||
if (prioritizer_) {
|
||||
nr_interface_prioritizer_destroy(&prioritizer_);
|
||||
}
|
||||
}
|
||||
|
||||
void SetPriorizer(nr_interface_prioritizer *prioritizer) {
|
||||
prioritizer_ = prioritizer;
|
||||
}
|
||||
|
||||
void AddInterface(const std::string& num, int type, int estimated_speed) {
|
||||
std::string str_addr = "10.0.0." + num;
|
||||
std::string ifname = "eth" + num;
|
||||
nr_local_addr local_addr;
|
||||
local_addr.interface.type = type;
|
||||
local_addr.interface.estimated_speed = estimated_speed;
|
||||
|
||||
int r = nr_ip4_str_port_to_transport_addr(str_addr.c_str(), 0,
|
||||
IPPROTO_UDP, &(local_addr.addr));
|
||||
ASSERT_EQ(0, r);
|
||||
strncpy(local_addr.addr.ifname, ifname.c_str(), MAXIFNAME);
|
||||
|
||||
r = nr_interface_prioritizer_add_interface(prioritizer_, &local_addr);
|
||||
ASSERT_EQ(0, r);
|
||||
r = nr_interface_prioritizer_sort_preference(prioritizer_);
|
||||
ASSERT_EQ(0, r);
|
||||
}
|
||||
|
||||
void HasLowerPreference(const std::string& num1, const std::string& num2) {
|
||||
std::string key1 = "eth" + num1 + ":10.0.0." + num1;
|
||||
std::string key2 = "eth" + num2 + ":10.0.0." + num2;
|
||||
UCHAR pref1, pref2;
|
||||
int r = nr_interface_prioritizer_get_priority(prioritizer_, key1.c_str(), &pref1);
|
||||
ASSERT_EQ(0, r);
|
||||
r = nr_interface_prioritizer_get_priority(prioritizer_, key2.c_str(), &pref2);
|
||||
ASSERT_EQ(0, r);
|
||||
ASSERT_LE(pref1, pref2);
|
||||
}
|
||||
|
||||
private:
|
||||
nr_interface_prioritizer *prioritizer_;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
|
||||
|
@ -673,6 +722,37 @@ TEST_F(IceConnectTest, TestConnectShutdownOneSide) {
|
|||
ConnectThenDelete();
|
||||
}
|
||||
|
||||
TEST_F(PrioritizerTest, TestPrioritizer) {
|
||||
SetPriorizer(::mozilla::CreateInterfacePrioritizer());
|
||||
|
||||
AddInterface("0", NR_INTERFACE_TYPE_VPN, 100); // unknown vpn
|
||||
AddInterface("1", NR_INTERFACE_TYPE_VPN | NR_INTERFACE_TYPE_WIRED, 100); // wired vpn
|
||||
AddInterface("2", NR_INTERFACE_TYPE_VPN | NR_INTERFACE_TYPE_WIFI, 100); // wifi vpn
|
||||
AddInterface("3", NR_INTERFACE_TYPE_VPN | NR_INTERFACE_TYPE_MOBILE, 100); // wifi vpn
|
||||
AddInterface("4", NR_INTERFACE_TYPE_WIRED, 1000); // wired, high speed
|
||||
AddInterface("5", NR_INTERFACE_TYPE_WIRED, 10); // wired, low speed
|
||||
AddInterface("6", NR_INTERFACE_TYPE_WIFI, 10); // wifi, low speed
|
||||
AddInterface("7", NR_INTERFACE_TYPE_WIFI, 1000); // wifi, high speed
|
||||
AddInterface("8", NR_INTERFACE_TYPE_MOBILE, 10); // mobile, low speed
|
||||
AddInterface("9", NR_INTERFACE_TYPE_MOBILE, 1000); // mobile, high speed
|
||||
AddInterface("10", NR_INTERFACE_TYPE_UNKNOWN, 10); // unknown, low speed
|
||||
AddInterface("11", NR_INTERFACE_TYPE_UNKNOWN, 1000); // unknown, high speed
|
||||
|
||||
// expected preference "4" > "5" > "1" > "7" > "6" > "2" > "9" > "8" > "3" > "11" > "10" > "0"
|
||||
|
||||
HasLowerPreference("0", "10");
|
||||
HasLowerPreference("10", "11");
|
||||
HasLowerPreference("11", "3");
|
||||
HasLowerPreference("3", "8");
|
||||
HasLowerPreference("8", "9");
|
||||
HasLowerPreference("9", "2");
|
||||
HasLowerPreference("2", "6");
|
||||
HasLowerPreference("6", "7");
|
||||
HasLowerPreference("7", "1");
|
||||
HasLowerPreference("1", "5");
|
||||
HasLowerPreference("5", "4");
|
||||
}
|
||||
|
||||
static std::string get_environment(const char *name) {
|
||||
char *value = getenv(name);
|
||||
|
||||
|
|
|
@ -76,6 +76,10 @@
|
|||
"./src/net/transport_addr.h",
|
||||
"./src/net/transport_addr_reg.c",
|
||||
"./src/net/transport_addr_reg.h",
|
||||
"./src/net/local_addr.c",
|
||||
"./src/net/local_addr.h",
|
||||
"./src/net/nr_interface_prioritizer.c",
|
||||
"./src/net/nr_interface_prioritizer.h",
|
||||
|
||||
# STUN
|
||||
"./src/stun/addrs.c",
|
||||
|
|
|
@ -358,23 +358,37 @@ int nr_ice_candidate_compute_priority(nr_ice_candidate *cand)
|
|||
if(type_preference > 126)
|
||||
r_log(LOG_ICE,LOG_ERR,"Illegal type preference %d",type_preference);
|
||||
|
||||
|
||||
if(r=NR_reg_get2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,
|
||||
&interface_preference)) {
|
||||
if (r==R_NOT_FOUND) {
|
||||
if (next_automatic_preference == 1) {
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Out of preference values. Can't assign one for interface %s",cand->base.ifname);
|
||||
ABORT(R_NOT_FOUND);
|
||||
if(!cand->ctx->interface_prioritizer) {
|
||||
/* Prioritizer is not set, read from registry */
|
||||
if(r=NR_reg_get2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,
|
||||
&interface_preference)) {
|
||||
if (r==R_NOT_FOUND) {
|
||||
if (next_automatic_preference == 1) {
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Out of preference values. Can't assign one for interface %s",cand->base.ifname);
|
||||
ABORT(R_NOT_FOUND);
|
||||
}
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Automatically assigning preference for interface %s->%d",cand->base.ifname,
|
||||
next_automatic_preference);
|
||||
if (r=NR_reg_set2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,next_automatic_preference)){
|
||||
ABORT(r);
|
||||
}
|
||||
interface_preference=next_automatic_preference;
|
||||
next_automatic_preference--;
|
||||
}
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Automatically assigning preference for interface %s->%d",cand->base.ifname,
|
||||
next_automatic_preference);
|
||||
if (r=NR_reg_set2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,next_automatic_preference)){
|
||||
else {
|
||||
ABORT(r);
|
||||
}
|
||||
interface_preference=next_automatic_preference;
|
||||
next_automatic_preference--;
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
char key_of_interface[MAXIFNAME + 41];
|
||||
|
||||
if(r=nr_transport_addr_fmt_ifname_addr_string(&cand->base,key_of_interface,
|
||||
sizeof(key_of_interface))) {
|
||||
ABORT(r);
|
||||
}
|
||||
if(r=nr_interface_prioritizer_get_priority(cand->ctx->interface_prioritizer,
|
||||
key_of_interface,&interface_preference)) {
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,31 +170,24 @@ int nr_ice_component_destroy(nr_ice_component **componentp)
|
|||
return(0);
|
||||
}
|
||||
|
||||
#define MAXADDRS 100 // Ridiculously high
|
||||
/* Make all the candidates we can make at the beginning */
|
||||
int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *component)
|
||||
{
|
||||
int r,_status;
|
||||
nr_transport_addr addrs[MAXADDRS];
|
||||
nr_local_addr *addrs=ctx->local_addrs;
|
||||
nr_socket *sock;
|
||||
nr_ice_socket *isock=0;
|
||||
nr_ice_candidate *cand=0;
|
||||
char *lufrag;
|
||||
char *lpwd;
|
||||
Data pwd;
|
||||
int addr_ct;
|
||||
int addr_ct=ctx->local_addr_ct;
|
||||
int i;
|
||||
int j;
|
||||
char label[256];
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): initializing component with id %d",ctx->label,component->component_id);
|
||||
|
||||
/* First, gather all the local addresses we have */
|
||||
if(r=nr_stun_find_local_addresses(addrs,MAXADDRS,&addr_ct)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to find local addresses",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if(addr_ct==0){
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): no local addresses available",ctx->label);
|
||||
ABORT(R_NOT_FOUND);
|
||||
|
@ -204,7 +197,7 @@ int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *compon
|
|||
for(i=0;i<addr_ct;i++){
|
||||
char suppress;
|
||||
|
||||
if(r=NR_reg_get2_char(NR_ICE_REG_SUPPRESS_INTERFACE_PRFX,addrs[i].ifname,&suppress)){
|
||||
if(r=NR_reg_get2_char(NR_ICE_REG_SUPPRESS_INTERFACE_PRFX,addrs[i].addr.ifname,&suppress)){
|
||||
if(r!=R_NOT_FOUND)
|
||||
ABORT(r);
|
||||
}
|
||||
|
@ -214,9 +207,9 @@ int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *compon
|
|||
}
|
||||
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): host address %s",ctx->label,addrs[i].as_string);
|
||||
if(r=nr_socket_local_create(&addrs[i],&sock)){
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): couldn't create socket for address %s",ctx->label,addrs[i].as_string);
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): host address %s",ctx->label,addrs[i].addr.as_string);
|
||||
if(r=nr_socket_local_create(&addrs[i].addr,&sock)){
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): couldn't create socket for address %s",ctx->label,addrs[i].addr.as_string);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -279,7 +272,7 @@ int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *compon
|
|||
#endif /* USE_TURN */
|
||||
|
||||
/* Create a STUN server context for this socket */
|
||||
snprintf(label, sizeof(label), "server(%s)", addrs[i].as_string);
|
||||
snprintf(label, sizeof(label), "server(%s)", addrs[i].addr.as_string);
|
||||
if(r=nr_stun_server_ctx_create(label,sock,&isock->stun_server))
|
||||
ABORT(r);
|
||||
if(r=nr_ice_socket_register_stun_server(isock,isock->stun_server,&isock->stun_server_handle))
|
||||
|
|
|
@ -156,6 +156,33 @@ int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers,int
|
|||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_local_addrs(nr_ice_ctx *ctx,nr_local_addr *addrs,int ct)
|
||||
{
|
||||
int _status,i,r;
|
||||
|
||||
if(ctx->local_addrs) {
|
||||
RFREE(ctx->local_addrs);
|
||||
ctx->local_addr_ct=0;
|
||||
ctx->local_addrs=0;
|
||||
}
|
||||
|
||||
if (ct) {
|
||||
if(!(ctx->local_addrs=RCALLOC(sizeof(nr_local_addr)*ct)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
for (i=0;i<ct;++i) {
|
||||
if (r=nr_local_addr_copy(ctx->local_addrs+i,addrs+i)) {
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
ctx->local_addr_ct = ct;
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver)
|
||||
{
|
||||
int _status;
|
||||
|
@ -171,6 +198,20 @@ int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver)
|
|||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *ip)
|
||||
{
|
||||
int _status;
|
||||
|
||||
if (ctx->interface_prioritizer) {
|
||||
ABORT(R_ALREADY);
|
||||
}
|
||||
|
||||
ctx->interface_prioritizer = ip;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
#ifdef USE_TURN
|
||||
int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out)
|
||||
|
@ -301,6 +342,9 @@ int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp)
|
|||
ctx->turn_server_ct=0;
|
||||
#endif /* USE_TURN */
|
||||
|
||||
ctx->local_addrs=0;
|
||||
ctx->local_addr_ct=0;
|
||||
|
||||
/* 255 is the max for our priority algorithm */
|
||||
if((ctx->stun_server_ct+ctx->turn_server_ct)>255){
|
||||
r_log(LOG_ICE,LOG_WARNING,"Too many STUN/TURN servers specified: max=255");
|
||||
|
@ -348,6 +392,8 @@ static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
|||
|
||||
RFREE(ctx->stun_servers);
|
||||
|
||||
RFREE(ctx->local_addrs);
|
||||
|
||||
for (i = 0; i < ctx->turn_server_ct; i++) {
|
||||
RFREE(ctx->turn_servers[i].username);
|
||||
r_data_destroy(&ctx->turn_servers[i].password);
|
||||
|
@ -374,6 +420,7 @@ static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
|||
}
|
||||
|
||||
nr_resolver_destroy(&ctx->resolver);
|
||||
nr_interface_prioritizer_destroy(&ctx->interface_prioritizer);
|
||||
|
||||
RFREE(ctx);
|
||||
}
|
||||
|
@ -416,10 +463,13 @@ void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg)
|
|||
}
|
||||
}
|
||||
|
||||
#define MAXADDRS 100 // Ridiculously high
|
||||
int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg)
|
||||
{
|
||||
int r,_status;
|
||||
nr_ice_media_stream *stream;
|
||||
nr_local_addr addrs[MAXADDRS];
|
||||
int i,addr_ct;
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Initializing candidates",ctx->label);
|
||||
ctx->state=NR_ICE_STATE_INITIALIZING;
|
||||
|
@ -431,6 +481,30 @@ int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg)
|
|||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
|
||||
/* First, gather all the local addresses we have */
|
||||
if(r=nr_stun_find_local_addresses(addrs,MAXADDRS,&addr_ct)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to find local addresses",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
/* Sort interfaces by preference */
|
||||
if(ctx->interface_prioritizer) {
|
||||
for(i=0;i<addr_ct;i++){
|
||||
if(r=nr_interface_prioritizer_add_interface(ctx->interface_prioritizer,addrs+i)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to add interface ",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
if(r=nr_interface_prioritizer_sort_preference(ctx->interface_prioritizer)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to sort interface by preference",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (r=nr_ice_ctx_set_local_addrs(ctx,addrs,addr_ct)) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
/* Initialize all the media stream/component pairs */
|
||||
stream=STAILQ_FIRST(&ctx->streams);
|
||||
while(stream){
|
||||
|
|
|
@ -43,6 +43,7 @@ extern "C" {
|
|||
#include "transport_addr.h"
|
||||
#include "nr_socket.h"
|
||||
#include "nr_resolver.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
#include "stun_client_ctx.h"
|
||||
#include "stun_server_ctx.h"
|
||||
#include "turn_client_ctx.h"
|
||||
|
@ -122,8 +123,11 @@ struct nr_ice_ctx_ {
|
|||
int stun_server_ct;
|
||||
nr_ice_turn_server *turn_servers; /* The list of turn servers */
|
||||
int turn_server_ct;
|
||||
nr_local_addr *local_addrs; /* The list of available local addresses and corresponding interface information */
|
||||
int local_addr_ct;
|
||||
|
||||
nr_resolver *resolver; /* The resolver to use */
|
||||
nr_interface_prioritizer *interface_prioritizer; /* Priority decision logic */
|
||||
|
||||
nr_ice_foundation_head foundations;
|
||||
|
||||
|
@ -161,6 +165,7 @@ int nr_ice_ctx_finalize(nr_ice_ctx *ctx, nr_ice_peer_ctx *pctx);
|
|||
int nr_ice_ctx_set_stun_servers(nr_ice_ctx *ctx,nr_ice_stun_server *servers, int ct);
|
||||
int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers, int ct);
|
||||
int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver);
|
||||
int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *prioritizer);
|
||||
|
||||
extern int LOG_ICE;
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <nr_api.h>
|
||||
#include <string.h>
|
||||
#include "local_addr.h"
|
||||
|
||||
int nr_local_addr_copy(nr_local_addr *to, nr_local_addr *from)
|
||||
{
|
||||
nr_transport_addr_copy(&(to->addr), &(from->addr));
|
||||
to->interface = from->interface;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_local_addr_fmt_info_string(nr_local_addr *addr, char *buf, int len)
|
||||
{
|
||||
int addr_type = addr->interface.type;
|
||||
const char *vpn = (addr_type & NR_INTERFACE_TYPE_VPN) ? "VPN on " : "";
|
||||
|
||||
const char *type = (addr_type & NR_INTERFACE_TYPE_WIRED) ? "wired" :
|
||||
(addr_type & NR_INTERFACE_TYPE_WIFI) ? "wifi" :
|
||||
(addr_type & NR_INTERFACE_TYPE_MOBILE) ? "mobile" :
|
||||
"unknown";
|
||||
|
||||
snprintf(buf, len, "%s%s, estimated speed: %d kbps",
|
||||
vpn, type, addr->interface.estimated_speed);
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _local_addr_h
|
||||
#define _local_addr_h
|
||||
|
||||
#include "transport_addr.h"
|
||||
|
||||
typedef struct nr_interface_ {
|
||||
int type;
|
||||
#define NR_INTERFACE_TYPE_UNKNOWN 0x0
|
||||
#define NR_INTERFACE_TYPE_WIRED 0x1
|
||||
#define NR_INTERFACE_TYPE_WIFI 0x2
|
||||
#define NR_INTERFACE_TYPE_MOBILE 0x4
|
||||
#define NR_INTERFACE_TYPE_VPN 0x8
|
||||
int estimated_speed; /* Speed in kbps */
|
||||
} nr_interface;
|
||||
|
||||
typedef struct nr_local_addr_ {
|
||||
nr_transport_addr addr;
|
||||
nr_interface interface;
|
||||
} nr_local_addr;
|
||||
|
||||
int nr_local_addr_copy(nr_local_addr *to, nr_local_addr *from);
|
||||
int nr_local_addr_fmt_info_string(nr_local_addr *addr, char *buf, int len);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "nr_api.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
#include "transport_addr.h"
|
||||
|
||||
int nr_interface_prioritizer_create_int(void *obj,
|
||||
nr_interface_prioritizer_vtbl *vtbl,nr_interface_prioritizer **ifpp)
|
||||
{
|
||||
int _status;
|
||||
nr_interface_prioritizer *ifp=0;
|
||||
|
||||
if(!(ifp=RCALLOC(sizeof(nr_interface_prioritizer))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
ifp->obj = obj;
|
||||
ifp->vtbl = vtbl;
|
||||
|
||||
*ifpp = ifp;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_destroy(nr_interface_prioritizer **ifpp)
|
||||
{
|
||||
nr_interface_prioritizer *ifp;
|
||||
|
||||
if (!ifpp || !*ifpp)
|
||||
return(0);
|
||||
|
||||
ifp = *ifpp;
|
||||
*ifpp = 0;
|
||||
ifp->vtbl->destroy(&ifp->obj);
|
||||
RFREE(ifp);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_add_interface(nr_interface_prioritizer *ifp,
|
||||
nr_local_addr *addr)
|
||||
{
|
||||
return ifp->vtbl->add_interface(ifp->obj, addr);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_get_priority(nr_interface_prioritizer *ifp,
|
||||
const char *key, UCHAR *interface_preference)
|
||||
{
|
||||
return ifp->vtbl->get_priority(ifp->obj,key,interface_preference);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_sort_preference(nr_interface_prioritizer *ifp)
|
||||
{
|
||||
return ifp->vtbl->sort_preference(ifp->obj);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _nr_interface_prioritizer
|
||||
#define _nr_interface_prioritizer
|
||||
|
||||
#include "transport_addr.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
typedef struct nr_interface_prioritizer_vtbl_ {
|
||||
int (*add_interface)(void *obj, nr_local_addr *iface);
|
||||
int (*get_priority)(void *obj, const char *key, UCHAR *pref);
|
||||
int (*sort_preference)(void *obj);
|
||||
int (*destroy)(void **obj);
|
||||
} nr_interface_prioritizer_vtbl;
|
||||
|
||||
typedef struct nr_interface_prioritizer_ {
|
||||
void *obj;
|
||||
nr_interface_prioritizer_vtbl *vtbl;
|
||||
} nr_interface_prioritizer;
|
||||
|
||||
int nr_interface_prioritizer_create_int(void *obj, nr_interface_prioritizer_vtbl *vtbl,
|
||||
nr_interface_prioritizer **prioritizer);
|
||||
|
||||
int nr_interface_prioritizer_destroy(nr_interface_prioritizer **prioritizer);
|
||||
|
||||
int nr_interface_prioritizer_add_interface(nr_interface_prioritizer *prioritizer,
|
||||
nr_local_addr *addr);
|
||||
|
||||
int nr_interface_prioritizer_get_priority(nr_interface_prioritizer *prioritizer,
|
||||
const char *key, UCHAR *interface_preference);
|
||||
|
||||
int nr_interface_prioritizer_sort_preference(nr_interface_prioritizer *prioritizer);
|
||||
#endif
|
|
@ -37,6 +37,7 @@ static char *RCSSTRING __UNUSED__="$Id: nr_socket.c,v 1.2 2008/04/28 17:59:02 ek
|
|||
#include <assert.h>
|
||||
#include <nr_api.h>
|
||||
#include "nr_socket.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
int nr_socket_create_int(void *obj, nr_socket_vtbl *vtbl, nr_socket **sockp)
|
||||
{
|
||||
|
|
|
@ -78,6 +78,27 @@ int nr_transport_addr_fmt_addr_string(nr_transport_addr *addr)
|
|||
return(_status);
|
||||
}
|
||||
|
||||
int nr_transport_addr_fmt_ifname_addr_string(const nr_transport_addr *addr, char *buf, int len)
|
||||
{
|
||||
int _status;
|
||||
char buffer[40];
|
||||
|
||||
switch(addr->ip_version){
|
||||
case NR_IPV4:
|
||||
if (!inet_ntop(AF_INET, &addr->u.addr4.sin_addr,buffer,sizeof(buffer))) {
|
||||
strncpy(buffer, "[error]", len);
|
||||
}
|
||||
snprintf(buf,len,"%s:%s",addr->ifname,buffer);
|
||||
break;
|
||||
default:
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_sockaddr_to_transport_addr(struct sockaddr *saddr, int saddr_len, int protocol, int keep, nr_transport_addr *addr)
|
||||
{
|
||||
int r,_status;
|
||||
|
|
|
@ -91,6 +91,7 @@ int nr_transport_addr_is_loopback(nr_transport_addr *addr);
|
|||
int nr_transport_addr_copy(nr_transport_addr *to, nr_transport_addr *from);
|
||||
int nr_transport_addr_copy_keep_ifname(nr_transport_addr *to, nr_transport_addr *from);
|
||||
int nr_transport_addr_fmt_addr_string(nr_transport_addr *addr);
|
||||
int nr_transport_addr_fmt_ifname_addr_string(const nr_transport_addr *addr, char *buf, int len);
|
||||
int nr_transport_addr_set_port(nr_transport_addr *addr, int port);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,7 +62,13 @@ static char *RCSSTRING __UNUSED__="$Id: addrs.c,v 1.2 2008/04/28 18:21:30 ekr Ex
|
|||
#include <net/if_types.h>
|
||||
#include <sys/sockio.h>
|
||||
#else
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/wireless.h>
|
||||
#ifndef ANDROID
|
||||
#include <linux/ethtool.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <net/route.h>
|
||||
|
||||
|
@ -120,9 +126,9 @@ static char *RCSSTRING __UNUSED__="$Id: addrs.c,v 1.2 2008/04/28 18:21:30 ekr Ex
|
|||
static void stun_rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
|
||||
static int stun_grab_addrs(char *name, int addrcount,
|
||||
struct ifa_msghdr *ifam,
|
||||
nr_transport_addr addrs[], int maxaddrs, int *count);
|
||||
nr_local_addr addrs[], int maxaddrs, int *count);
|
||||
static int
|
||||
nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_addr *addr);
|
||||
nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -151,7 +157,7 @@ stun_rt_xaddrs(cp, cplim, rtinfo)
|
|||
}
|
||||
|
||||
static int
|
||||
stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
int s = -1;
|
||||
|
@ -172,15 +178,18 @@ stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_transport
|
|||
|
||||
/* Expand the compacted addresses */
|
||||
stun_rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, &info);
|
||||
addrs[*count].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[*count].interface.estimated_speed = 0;
|
||||
/* TODO (Bug 895790) Get interface properties for Darwin */
|
||||
|
||||
switch (info.rti_info[RTAX_IFA]->sa_family) {
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)info.rti_info[RTAX_IFA];
|
||||
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sin, sizeof(*sin), IPPROTO_UDP, 0, &(addrs[*count]))))
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sin, sizeof(*sin), IPPROTO_UDP, 0, &(addrs[*count].addr))))
|
||||
ABORT(r);
|
||||
|
||||
strlcpy(addrs[*count].ifname, name, sizeof(addrs[*count].ifname));
|
||||
strlcpy(addrs[*count].addr.ifname, name, sizeof(addrs[*count].addr.ifname));
|
||||
|
||||
++*count;
|
||||
break;
|
||||
|
@ -206,7 +215,7 @@ stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_transport
|
|||
}
|
||||
|
||||
static int
|
||||
stun_get_mib_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_mib_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int _status;
|
||||
char name[32];
|
||||
|
@ -353,7 +362,7 @@ abort:
|
|||
|
||||
|
||||
static int
|
||||
stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
|
@ -424,24 +433,30 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
|||
|
||||
for (pAddrString = &(pAdapter->IpAddressList); pAddrString != NULL; pAddrString = pAddrString->Next) {
|
||||
unsigned long this_addr = inet_addr(pAddrString->IpAddress.String);
|
||||
nr_transport_addr *addr = &(addrs[n].addr);
|
||||
|
||||
if (this_addr == 0)
|
||||
continue;
|
||||
|
||||
r_log(NR_LOG_STUN, LOG_INFO, "Adapter %s address: %s", munged_ifname, pAddrString->IpAddress.String);
|
||||
|
||||
addrs[n].ip_version=NR_IPV4;
|
||||
addrs[n].protocol = IPPROTO_UDP;
|
||||
addr->ip_version=NR_IPV4;
|
||||
addr->protocol = IPPROTO_UDP;
|
||||
|
||||
addrs[n].u.addr4.sin_family=PF_INET;
|
||||
addrs[n].u.addr4.sin_port=0;
|
||||
addrs[n].u.addr4.sin_addr.s_addr=this_addr;
|
||||
addrs[n].addr=(struct sockaddr *)&(addrs[n].u.addr4);
|
||||
addrs[n].addr_len=sizeof(struct sockaddr_in);
|
||||
addr->u.addr4.sin_family=PF_INET;
|
||||
addr->u.addr4.sin_port=0;
|
||||
addr->u.addr4.sin_addr.s_addr=this_addr;
|
||||
addr->addr=(struct sockaddr *)&(addr->u.addr4);
|
||||
addr->addr_len=sizeof(struct sockaddr_in);
|
||||
|
||||
strlcpy(addrs[n].ifname, munged_ifname, sizeof(addrs[n].ifname));
|
||||
snprintf(addrs[n].as_string,40,"IP4:%s:%d",inet_ntoa(addrs[n].u.addr4.sin_addr),
|
||||
ntohs(addrs[n].u.addr4.sin_port));
|
||||
strlcpy(addr->ifname, munged_ifname, sizeof(addr->ifname));
|
||||
snprintf(addr->as_string,40,"IP4:%s:%d",
|
||||
inet_ntoa(addr->u.addr4.sin_addr),
|
||||
ntohs(addr->u.addr4.sin_port));
|
||||
|
||||
/* TODO: (Bug 895793) Getting interface properties for Windows */
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[n].interface.estimated_speed = 0;
|
||||
|
||||
if (++n >= maxaddrs)
|
||||
goto done;
|
||||
|
@ -465,7 +480,7 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
|||
* isn't supported on Win2000.
|
||||
*/
|
||||
static int
|
||||
stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL, tmpAddress = NULL;
|
||||
|
@ -531,7 +546,7 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
|||
|
||||
if ((sa_addr->lpSockaddr->sa_family == AF_INET) ||
|
||||
(sa_addr->lpSockaddr->sa_family == AF_INET6)) {
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, sizeof(*sa_addr->lpSockaddr), IPPROTO_UDP, 0, &(addrs[n]))))
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, sizeof(*sa_addr->lpSockaddr), IPPROTO_UDP, 0, &(addrs[n].addr))))
|
||||
ABORT(r);
|
||||
}
|
||||
else {
|
||||
|
@ -539,7 +554,10 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
|||
continue;
|
||||
}
|
||||
|
||||
strlcpy(addrs[n].ifname, munged_ifname, sizeof(addrs[n].ifname));
|
||||
strlcpy(addrs[n].addr.ifname, munged_ifname, sizeof(addrs[n].addr.ifname));
|
||||
/* TODO: (Bug 895793) Getting interface properties for Windows */
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[n].interface.estimated_speed = 0;
|
||||
if (++n >= maxaddrs)
|
||||
goto done;
|
||||
}
|
||||
|
@ -559,7 +577,7 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
|||
#elif defined(__sparc__)
|
||||
|
||||
static int
|
||||
stun_get_sparc_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_sparc_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
*count = 0;
|
||||
UNIMPLEMENTED; /*TODO !nn! - sparc */
|
||||
|
@ -569,7 +587,7 @@ stun_get_sparc_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
|||
#else
|
||||
|
||||
static int
|
||||
stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_siocgifconf_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
struct ifconf ifc;
|
||||
int _status;
|
||||
|
@ -598,6 +616,10 @@ stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
|||
|
||||
#ifdef LINUX
|
||||
int si = sizeof(struct ifreq);
|
||||
#ifndef ANDROID
|
||||
struct ethtool_cmd ecmd;
|
||||
struct iwreq wrq;
|
||||
#endif
|
||||
#else
|
||||
int si = sizeof(ifr->ifr_name) + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr));
|
||||
#endif
|
||||
|
@ -614,11 +636,46 @@ stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
|||
|
||||
//r_log(NR_LOG_STUN, LOG_ERR, "ioctl addr e = %d",e);
|
||||
|
||||
if ((r=nr_sockaddr_to_transport_addr(&ifr2.ifr_addr, sizeof(ifr2.ifr_addr), IPPROTO_UDP, 0, &(addrs[n])))) {
|
||||
if ((r=nr_sockaddr_to_transport_addr(&ifr2.ifr_addr, sizeof(ifr2.ifr_addr), IPPROTO_UDP, 0, &(addrs[n].addr)))) {
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "Problem transforming address");
|
||||
}
|
||||
else {
|
||||
strlcpy(addrs[n].ifname, ifr->ifr_name, sizeof(addrs[n].ifname));
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[n].interface.estimated_speed = 0;
|
||||
#if defined(LINUX) && !defined(ANDROID)
|
||||
/* TODO (Bug 896851): interface property for Android */
|
||||
/* Getting ethtool for ethernet information. */
|
||||
ecmd.cmd = ETHTOOL_GSET;
|
||||
ifr2.ifr_data = (void*)&ecmd;
|
||||
e = ioctl(s, SIOCETHTOOL, &ifr2);
|
||||
if (e == 0)
|
||||
{
|
||||
/* For wireless network, we won't get ethtool, it's a wired
|
||||
connection */
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_WIRED;
|
||||
addrs[n].interface.estimated_speed = ((ecmd.speed_hi << 16) | ecmd.speed) * 1000;
|
||||
}
|
||||
|
||||
strncpy(wrq.ifr_name, ifr->ifr_name, sizeof(wrq.ifr_name));
|
||||
e = ioctl(s, SIOCGIWRATE, &wrq);
|
||||
if (e == 0)
|
||||
{
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_WIFI;
|
||||
addrs[n].interface.estimated_speed = wrq.u.bitrate.value / 1000;
|
||||
}
|
||||
|
||||
ifr2 = *ifr;
|
||||
e = ioctl(s, SIOCGIFFLAGS, &ifr2);
|
||||
if (e == 0)
|
||||
{
|
||||
if (ifr2.ifr_flags & IFF_POINTOPOINT)
|
||||
{
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN | NR_INTERFACE_TYPE_VPN;
|
||||
/* TODO (Bug 896913): find backend network type of this VPN */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
strlcpy(addrs[n].addr.ifname, ifr->ifr_name, sizeof(addrs[n].addr.ifname));
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
@ -633,13 +690,14 @@ stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
|||
#endif
|
||||
|
||||
static int
|
||||
nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_addr *addr)
|
||||
nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr)
|
||||
{
|
||||
int i;
|
||||
int different;
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
different = nr_transport_addr_cmp(&addrs[i], addr, NR_TRANSPORT_ADDR_CMP_MODE_ALL);
|
||||
different = nr_transport_addr_cmp(&addrs[i].addr, &(addr->addr),
|
||||
NR_TRANSPORT_ADDR_CMP_MODE_ALL);
|
||||
if (!different)
|
||||
return 1; /* duplicate */
|
||||
}
|
||||
|
@ -648,10 +706,10 @@ nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_add
|
|||
}
|
||||
|
||||
int
|
||||
nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback, int *count)
|
||||
nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback, int *count)
|
||||
{
|
||||
int r, _status;
|
||||
nr_transport_addr *tmp = 0;
|
||||
nr_local_addr *tmp = 0;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
|
@ -664,12 +722,12 @@ nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback, i
|
|||
if (nr_stun_is_duplicate_addr(tmp, n, &addrs[i])) {
|
||||
/* skip addrs[i], it's a duplicate */
|
||||
}
|
||||
else if (remove_loopback && nr_transport_addr_is_loopback(&addrs[i])) {
|
||||
else if (remove_loopback && nr_transport_addr_is_loopback(&addrs[i].addr)) {
|
||||
/* skip addrs[i], it's a loopback */
|
||||
}
|
||||
else {
|
||||
/* otherwise, copy it to the temporary array */
|
||||
if ((r=nr_transport_addr_copy(&tmp[n], &addrs[i])))
|
||||
if ((r=nr_local_addr_copy(&tmp[n], &addrs[i])))
|
||||
ABORT(r);
|
||||
++n;
|
||||
}
|
||||
|
@ -679,7 +737,7 @@ nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback, i
|
|||
|
||||
/* copy temporary array into passed in/out array */
|
||||
for (i = 0; i < *count; ++i) {
|
||||
if ((r=nr_transport_addr_copy(&addrs[i], &tmp[i])))
|
||||
if ((r=nr_local_addr_copy(&addrs[i], &tmp[i])))
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
|
@ -692,10 +750,11 @@ nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback, i
|
|||
#ifndef USE_PLATFORM_NR_STUN_GET_ADDRS
|
||||
|
||||
int
|
||||
nr_stun_get_addrs(nr_transport_addr addrs[], int maxaddrs, int drop_loopback, int *count)
|
||||
nr_stun_get_addrs(nr_local_addr addrs[], int maxaddrs, int drop_loopback, int *count)
|
||||
{
|
||||
int _status=0;
|
||||
int i;
|
||||
char typestr[100];
|
||||
|
||||
#if defined(BSD) || defined(DARWIN)
|
||||
_status = stun_get_mib_addrs(addrs, maxaddrs, count);
|
||||
|
@ -710,7 +769,9 @@ nr_stun_get_addrs(nr_transport_addr addrs[], int maxaddrs, int drop_loopback, in
|
|||
nr_stun_remove_duplicate_addrs(addrs, drop_loopback, count);
|
||||
|
||||
for (i = 0; i < *count; ++i) {
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s", i, addrs[i].as_string, addrs[i].ifname);
|
||||
nr_local_addr_fmt_info_string(addrs+i,typestr,sizeof(typestr));
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s, type: %s\n",
|
||||
i,addrs[i].addr.as_string,addrs[i].addr.ifname,typestr);
|
||||
}
|
||||
|
||||
return _status;
|
||||
|
|
|
@ -35,8 +35,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define _addrs_h_
|
||||
|
||||
#include "transport_addr.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
int nr_stun_get_addrs(nr_transport_addr addrs[], int maxaddrs, int remove_loopback, int *count);
|
||||
int nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback,int *count);
|
||||
int nr_stun_get_addrs(nr_local_addr addrs[], int maxaddrs, int remove_loopback, int *count);
|
||||
int nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback,int *count);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -98,7 +98,7 @@ nr_stun_xor_mapped_address(UINT4 magicCookie, nr_transport_addr *from, nr_transp
|
|||
}
|
||||
|
||||
int
|
||||
nr_stun_find_local_addresses(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
nr_stun_find_local_addresses(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
NR_registry *children = 0;
|
||||
|
@ -137,7 +137,7 @@ nr_stun_find_local_addresses(nr_transport_addr addrs[], int maxaddrs, int *count
|
|||
ABORT(r);
|
||||
|
||||
for (i = 0; i < *count; ++i) {
|
||||
if ((r=nr_reg_get_transport_addr(children[i], 0, &addrs[i])))
|
||||
if ((r=nr_reg_get_transport_addr(children[i], 0, &addrs[i].addr)))
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define _stun_util_h
|
||||
|
||||
#include "stun.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
extern int NR_LOG_STUN;
|
||||
|
||||
|
@ -43,7 +44,7 @@ int nr_stun_startup(void);
|
|||
|
||||
int nr_stun_xor_mapped_address(UINT4 magicCookie, nr_transport_addr *from, nr_transport_addr *to);
|
||||
|
||||
int nr_stun_find_local_addresses(nr_transport_addr addrs[], int maxaddrs, int *count);
|
||||
int nr_stun_find_local_addresses(nr_local_addr addrs[], int maxaddrs, int *count);
|
||||
|
||||
int nr_stun_different_transaction(UCHAR *msg, int len, nr_stun_message *req);
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ class testElementTouch(MarionetteTestCase):
|
|||
button.tap()
|
||||
expected = "button1-touchstart-touchend-mousemove-mousedown-mouseup-click"
|
||||
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
|
||||
button.tap(0, 300)
|
||||
button = self.marionette.find_element("id", "button2")
|
||||
button.tap()
|
||||
expected = "button2-touchstart-touchend-mousemove-mousedown-mouseup-click"
|
||||
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button2').innerHTML;") == expected)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ const CHILD_SCRIPT = "chrome://specialpowers/content/specialpowers.js";
|
|||
const CHILD_SCRIPT_API = "chrome://specialpowers/content/specialpowersAPI.js";
|
||||
const CHILD_LOGGER_SCRIPT = "chrome://specialpowers/content/MozillaLogger.js";
|
||||
|
||||
let homescreen = document.getElementById('homescreen');
|
||||
let homescreen = document.getElementById('systemapp');
|
||||
let container = homescreen.contentWindow.document.getElementById('test-container');
|
||||
|
||||
function openWindow(aEvent) {
|
||||
|
|
|
@ -409,7 +409,7 @@ toolbar#nav-bar {
|
|||
if options.browserChrome or options.chrome or options.a11y or options.webapprtChrome:
|
||||
chrome += """
|
||||
overlay chrome://browser/content/browser.xul chrome://mochikit/content/browser-test-overlay.xul
|
||||
overlay chrome://browser/content/shell.xul chrome://mochikit/content/browser-test-overlay.xul
|
||||
overlay chrome://browser/content/shell.xhtml chrome://mochikit/content/browser-test-overlay.xul
|
||||
overlay chrome://navigator/content/navigator.xul chrome://mochikit/content/browser-test-overlay.xul
|
||||
overlay chrome://webapprt/content/webapp.xul chrome://mochikit/content/browser-test-overlay.xul
|
||||
"""
|
||||
|
|
Загрузка…
Ссылка в новой задаче