Merge latest green inbound changeset and mozilla-central

This commit is contained in:
Ed Morley 2013-08-29 14:45:19 +01:00
commit 3562d328d5
45 changed files with 985 additions and 219 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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)

View File

@ -1,4 +1,4 @@
{
"revision": "f400eac8b28353050ea9ff87dcb7e780e3537a89",
"revision": "7db3c28d7056b880b3be261f7784b5cc3e96702b",
"repo_path": "/integration/gaia-central"
}

View File

@ -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.

View File

@ -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',

View File

@ -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

View File

@ -141,8 +141,6 @@ DOMCI_CLASS(BluetoothDevice)
DOMCI_CLASS(CameraCapabilities)
DOMCI_CLASS(DOMWindowResizeEventDetail)
DOMCI_CLASS(LockedFile)
DOMCI_CLASS(CSSFontFeatureValuesRule)

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -172,7 +172,6 @@ var interfaceNamesInGlobalScope =
"DOMStringMap",
"DOMTokenList",
"DOMTransactionEvent",
"DOMWindowResizeEventDetail",
"DragEvent",
"DynamicsCompressorNode",
"Element",

View File

@ -22,3 +22,8 @@ dictionary OpenWindowEventDetail {
DOMString features = "";
Node? frameElement = null;
};
dictionary DOMWindowResizeEventDetail {
long width = 0;
long height = 0;
};

View File

@ -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);
};

View File

@ -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()

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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);

View File

@ -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",

View File

@ -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);
}
}

View File

@ -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))

View File

@ -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){

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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)
{

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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)

View File

@ -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) {

View File

@ -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
"""