зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central a=merge
This commit is contained in:
Коммит
a4b709fedc
|
@ -352,7 +352,7 @@ AudioStream::Init(uint32_t aNumChannels,
|
||||||
params.channels = mOutChannels;
|
params.channels = mOutChannels;
|
||||||
params.layout = static_cast<uint32_t>(aChannelMap);
|
params.layout = static_cast<uint32_t>(aChannelMap);
|
||||||
params.format = ToCubebFormat<AUDIO_OUTPUT_FORMAT>::value;
|
params.format = ToCubebFormat<AUDIO_OUTPUT_FORMAT>::value;
|
||||||
params.prefs = CUBEB_STREAM_PREF_NONE;
|
params.prefs = CubebUtils::GetDefaultStreamPrefs();
|
||||||
|
|
||||||
mAudioClock.Init(aRate);
|
mAudioClock.Init(aRate);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#define PREF_CUBEB_LOGGING_LEVEL "media.cubeb.logging_level"
|
#define PREF_CUBEB_LOGGING_LEVEL "media.cubeb.logging_level"
|
||||||
// Hidden pref used by tests to force failure to obtain cubeb context
|
// Hidden pref used by tests to force failure to obtain cubeb context
|
||||||
#define PREF_CUBEB_FORCE_NULL_CONTEXT "media.cubeb.force_null_context"
|
#define PREF_CUBEB_FORCE_NULL_CONTEXT "media.cubeb.force_null_context"
|
||||||
|
// Hidden pref to disable BMO 1427011 experiment; can be removed once proven.
|
||||||
|
#define PREF_CUBEB_DISABLE_DEVICE_SWITCHING "media.cubeb.disable_device_switching"
|
||||||
#define PREF_CUBEB_SANDBOX "media.cubeb.sandbox"
|
#define PREF_CUBEB_SANDBOX "media.cubeb.sandbox"
|
||||||
#define PREF_AUDIOIPC_POOL_SIZE "media.audioipc.pool_size"
|
#define PREF_AUDIOIPC_POOL_SIZE "media.audioipc.pool_size"
|
||||||
#define PREF_AUDIOIPC_STACK_SIZE "media.audioipc.stack_size"
|
#define PREF_AUDIOIPC_STACK_SIZE "media.audioipc.stack_size"
|
||||||
|
@ -130,6 +132,7 @@ bool sCubebPlaybackLatencyPrefSet = false;
|
||||||
bool sCubebMSGLatencyPrefSet = false;
|
bool sCubebMSGLatencyPrefSet = false;
|
||||||
bool sAudioStreamInitEverSucceeded = false;
|
bool sAudioStreamInitEverSucceeded = false;
|
||||||
bool sCubebForceNullContext = false;
|
bool sCubebForceNullContext = false;
|
||||||
|
bool sCubebDisableDeviceSwitching = true;
|
||||||
#ifdef MOZ_CUBEB_REMOTING
|
#ifdef MOZ_CUBEB_REMOTING
|
||||||
bool sCubebSandbox = false;
|
bool sCubebSandbox = false;
|
||||||
size_t sAudioIPCPoolSize;
|
size_t sAudioIPCPoolSize;
|
||||||
|
@ -243,7 +246,12 @@ void PrefChanged(const char* aPref, void* aClosure)
|
||||||
sCubebForceNullContext = Preferences::GetBool(aPref, false);
|
sCubebForceNullContext = Preferences::GetBool(aPref, false);
|
||||||
MOZ_LOG(gCubebLog, LogLevel::Verbose,
|
MOZ_LOG(gCubebLog, LogLevel::Verbose,
|
||||||
("%s: %s", PREF_CUBEB_FORCE_NULL_CONTEXT, sCubebForceNullContext ? "true" : "false"));
|
("%s: %s", PREF_CUBEB_FORCE_NULL_CONTEXT, sCubebForceNullContext ? "true" : "false"));
|
||||||
}
|
} else if (strcmp(aPref, PREF_CUBEB_DISABLE_DEVICE_SWITCHING) == 0) {
|
||||||
|
StaticMutexAutoLock lock(sMutex);
|
||||||
|
sCubebDisableDeviceSwitching = Preferences::GetBool(aPref, true);
|
||||||
|
MOZ_LOG(gCubebLog, LogLevel::Verbose,
|
||||||
|
("%s: %s", PREF_CUBEB_DISABLE_DEVICE_SWITCHING, sCubebDisableDeviceSwitching ? "true" : "false"));
|
||||||
|
}
|
||||||
#ifdef MOZ_CUBEB_REMOTING
|
#ifdef MOZ_CUBEB_REMOTING
|
||||||
else if (strcmp(aPref, PREF_CUBEB_SANDBOX) == 0) {
|
else if (strcmp(aPref, PREF_CUBEB_SANDBOX) == 0) {
|
||||||
StaticMutexAutoLock lock(sMutex);
|
StaticMutexAutoLock lock(sMutex);
|
||||||
|
@ -694,6 +702,19 @@ void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cubeb_stream_prefs GetDefaultStreamPrefs()
|
||||||
|
{
|
||||||
|
#ifdef XP_WIN
|
||||||
|
// Investigation for bug 1427011 - if we're in E10S mode, rely on the
|
||||||
|
// AudioNotification IPC to detect device changes.
|
||||||
|
if (sCubebDisableDeviceSwitching &&
|
||||||
|
(XRE_IsE10sParentProcess() || XRE_IsContentProcess())) {
|
||||||
|
return CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return CUBEB_STREAM_PREF_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
uint32_t AndroidGetAudioOutputSampleRate()
|
uint32_t AndroidGetAudioOutputSampleRate()
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,6 +46,7 @@ bool CubebLatencyPrefSet();
|
||||||
void GetCurrentBackend(nsAString& aBackend);
|
void GetCurrentBackend(nsAString& aBackend);
|
||||||
void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos,
|
void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos,
|
||||||
Side aSide);
|
Side aSide);
|
||||||
|
cubeb_stream_prefs GetDefaultStreamPrefs();
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
uint32_t AndroidGetAudioOutputSampleRate();
|
uint32_t AndroidGetAudioOutputSampleRate();
|
||||||
|
|
|
@ -627,7 +627,7 @@ AudioCallbackDriver::Init()
|
||||||
|
|
||||||
output.channels = mOutputChannels;
|
output.channels = mOutputChannels;
|
||||||
output.layout = CUBEB_LAYOUT_UNDEFINED;
|
output.layout = CUBEB_LAYOUT_UNDEFINED;
|
||||||
output.prefs = CUBEB_STREAM_PREF_NONE;
|
output.prefs = CubebUtils::GetDefaultStreamPrefs();
|
||||||
|
|
||||||
uint32_t latency_frames = CubebUtils::GetCubebMSGLatencyInFrames(&output);
|
uint32_t latency_frames = CubebUtils::GetCubebMSGLatencyInFrames(&output);
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
inline void
|
inline void
|
||||||
js::gc::Arena::init(JS::Zone* zoneArg, AllocKind kind, const AutoLockGC& lock)
|
js::gc::Arena::init(JS::Zone* zoneArg, AllocKind kind, const AutoLockGC& lock)
|
||||||
{
|
{
|
||||||
MOZ_MAKE_MEM_UNDEFINED(this, ArenaSize);
|
|
||||||
|
|
||||||
MOZ_ASSERT(firstFreeSpan.isEmpty());
|
MOZ_ASSERT(firstFreeSpan.isEmpty());
|
||||||
MOZ_ASSERT(!zone);
|
MOZ_ASSERT(!zone);
|
||||||
MOZ_ASSERT(!allocated());
|
MOZ_ASSERT(!allocated());
|
||||||
|
@ -24,13 +22,19 @@ js::gc::Arena::init(JS::Zone* zoneArg, AllocKind kind, const AutoLockGC& lock)
|
||||||
MOZ_ASSERT(!markOverflow);
|
MOZ_ASSERT(!markOverflow);
|
||||||
MOZ_ASSERT(!auxNextLink);
|
MOZ_ASSERT(!auxNextLink);
|
||||||
|
|
||||||
|
MOZ_MAKE_MEM_UNDEFINED(this, ArenaSize);
|
||||||
|
|
||||||
zone = zoneArg;
|
zone = zoneArg;
|
||||||
allocKind = size_t(kind);
|
allocKind = size_t(kind);
|
||||||
setAsFullyUnused();
|
hasDelayedMarking = 0;
|
||||||
|
markOverflow = 0;
|
||||||
|
auxNextLink = 0;
|
||||||
if (zone->isAtomsZone())
|
if (zone->isAtomsZone())
|
||||||
zone->runtimeFromAnyThread()->gc.atomMarking.registerArena(this, lock);
|
zone->runtimeFromAnyThread()->gc.atomMarking.registerArena(this, lock);
|
||||||
else
|
else
|
||||||
bufferedCells() = &ArenaCellSet::Empty;
|
bufferedCells() = &ArenaCellSet::Empty;
|
||||||
|
|
||||||
|
setAsFullyUnused();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
|
|
@ -539,12 +539,12 @@ GCRuntime::markBufferedGrayRoots(JS::Zone* zone)
|
||||||
if (roots.empty())
|
if (roots.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check for and remove canary value.
|
// Check for canary value but don't remove it.
|
||||||
MOZ_RELEASE_ASSERT(roots.length() > 1);
|
MOZ_RELEASE_ASSERT(roots.length() > 1);
|
||||||
MOZ_RELEASE_ASSERT(roots.back() == GrayBufferCanary);
|
MOZ_RELEASE_ASSERT(roots.back() == GrayBufferCanary);
|
||||||
roots.popBack();
|
|
||||||
|
|
||||||
for (auto cell : zone->gcGrayRoots()) {
|
for (size_t i = 0; i < roots.length() - 1; i++) {
|
||||||
|
Cell* cell = roots[i];
|
||||||
MOZ_ASSERT(IsCellPointerValid(cell));
|
MOZ_ASSERT(IsCellPointerValid(cell));
|
||||||
TraceManuallyBarrieredGenericPointerEdge(&marker, &cell, "buffered gray root");
|
TraceManuallyBarrieredGenericPointerEdge(&marker, &cell, "buffered gray root");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
// |jit-test| error: ReferenceError
|
||||||
|
gczeal(11, 5);
|
||||||
|
gczeal(22, 9);
|
||||||
|
grayRoot().map = wm;
|
|
@ -1669,7 +1669,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void
|
||||||
if (!script) {
|
if (!script) {
|
||||||
// No error was reported, but no script produced. Assume we hit out of
|
// No error was reported, but no script produced. Assume we hit out of
|
||||||
// memory.
|
// memory.
|
||||||
MOZ_DIAGNOSTIC_ASSERT(false);
|
MOZ_ASSERT(false, "Expected script");
|
||||||
ReportOutOfMemory(cx);
|
ReportOutOfMemory(cx);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1706,7 +1706,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void
|
||||||
if (scripts.length() != expectedLength) {
|
if (scripts.length() != expectedLength) {
|
||||||
// No error was reported, but fewer scripts produced than expected.
|
// No error was reported, but fewer scripts produced than expected.
|
||||||
// Assume we hit out of memory.
|
// Assume we hit out of memory.
|
||||||
MOZ_DIAGNOSTIC_ASSERT(false);
|
MOZ_ASSERT(false, "Expected more scripts");
|
||||||
ReportOutOfMemory(cx);
|
ReportOutOfMemory(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
diff --git a/media/libcubeb/include/cubeb.h b/media/libcubeb/include/cubeb.h
|
||||||
|
--- a/media/libcubeb/include/cubeb.h
|
||||||
|
+++ b/media/libcubeb/include/cubeb.h
|
||||||
|
@@ -216,20 +216,23 @@ enum {
|
||||||
|
CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
|
||||||
|
CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
|
||||||
|
CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Miscellaneous stream preferences. */
|
||||||
|
typedef enum {
|
||||||
|
CUBEB_STREAM_PREF_NONE = 0x00, /**< No stream preferences are requested. */
|
||||||
|
- CUBEB_STREAM_PREF_LOOPBACK = 0x01 /**< Request a loopback stream. Should be
|
||||||
|
- specified on the input params and an
|
||||||
|
- output device to loopback from should
|
||||||
|
- be passed in place of an input device. */
|
||||||
|
+ CUBEB_STREAM_PREF_LOOPBACK = 0x01, /**< Request a loopback stream. Should be
|
||||||
|
+ specified on the input params and an
|
||||||
|
+ output device to loopback from should
|
||||||
|
+ be passed in place of an input device. */
|
||||||
|
+ CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING = 0x02, /**< Disable switching
|
||||||
|
+ default device on OS
|
||||||
|
+ changes. */
|
||||||
|
} cubeb_stream_prefs;
|
||||||
|
|
||||||
|
/** Stream format initialization parameters. */
|
||||||
|
typedef struct {
|
||||||
|
cubeb_sample_format format; /**< Requested sample format. One of
|
||||||
|
#cubeb_sample_format. */
|
||||||
|
uint32_t rate; /**< Requested sample rate. Valid range is [1000, 192000]. */
|
||||||
|
uint32_t channels; /**< Requested channel count. Valid range is [1, 8]. */
|
||||||
|
diff --git a/media/libcubeb/src/cubeb_wasapi.cpp b/media/libcubeb/src/cubeb_wasapi.cpp
|
||||||
|
--- a/media/libcubeb/src/cubeb_wasapi.cpp
|
||||||
|
+++ b/media/libcubeb/src/cubeb_wasapi.cpp
|
||||||
|
@@ -1829,21 +1829,26 @@ wasapi_stream_init(cubeb * context, cube
|
||||||
|
assert that the lock is held in the function. */
|
||||||
|
auto_lock lock(stm->stream_reset_lock);
|
||||||
|
rv = setup_wasapi_stream(stm.get());
|
||||||
|
}
|
||||||
|
if (rv != CUBEB_OK) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
- HRESULT hr = register_notification_client(stm.get());
|
||||||
|
- if (FAILED(hr)) {
|
||||||
|
- /* this is not fatal, we can still play audio, but we won't be able
|
||||||
|
- to keep using the default audio endpoint if it changes. */
|
||||||
|
- LOG("failed to register notification client, %lx", hr);
|
||||||
|
+ if (!((input_stream_params ?
|
||||||
|
+ (input_stream_params->prefs & CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING) : 0) ||
|
||||||
|
+ (output_stream_params ?
|
||||||
|
+ (output_stream_params->prefs & CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING) : 0))) {
|
||||||
|
+ HRESULT hr = register_notification_client(stm.get());
|
||||||
|
+ if (FAILED(hr)) {
|
||||||
|
+ /* this is not fatal, we can still play audio, but we won't be able
|
||||||
|
+ to keep using the default audio endpoint if it changes. */
|
||||||
|
+ LOG("failed to register notification client, %lx", hr);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
*stream = stm.release();
|
||||||
|
|
||||||
|
LOG("Stream init succesfull (%p)", *stream);
|
||||||
|
return CUBEB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1879,17 +1884,19 @@ void wasapi_stream_destroy(cubeb_stream
|
||||||
|
// Only free stm->emergency_bailout if we could join the thread.
|
||||||
|
// If we could not join the thread, stm->emergency_bailout is true
|
||||||
|
// and is still alive until the thread wakes up and exits cleanly.
|
||||||
|
if (stop_and_join_render_thread(stm)) {
|
||||||
|
delete stm->emergency_bailout.load();
|
||||||
|
stm->emergency_bailout = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
- unregister_notification_client(stm);
|
||||||
|
+ if (stm->notification_client) {
|
||||||
|
+ unregister_notification_client(stm);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
CloseHandle(stm->reconfigure_event);
|
||||||
|
CloseHandle(stm->refill_event);
|
||||||
|
CloseHandle(stm->input_available_event);
|
||||||
|
|
||||||
|
// The variables intialized in wasapi_stream_init,
|
||||||
|
// must be destroyed in wasapi_stream_destroy.
|
||||||
|
stm->linear_input_buffer.reset();
|
|
@ -221,10 +221,13 @@ enum {
|
||||||
/** Miscellaneous stream preferences. */
|
/** Miscellaneous stream preferences. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CUBEB_STREAM_PREF_NONE = 0x00, /**< No stream preferences are requested. */
|
CUBEB_STREAM_PREF_NONE = 0x00, /**< No stream preferences are requested. */
|
||||||
CUBEB_STREAM_PREF_LOOPBACK = 0x01 /**< Request a loopback stream. Should be
|
CUBEB_STREAM_PREF_LOOPBACK = 0x01, /**< Request a loopback stream. Should be
|
||||||
specified on the input params and an
|
specified on the input params and an
|
||||||
output device to loopback from should
|
output device to loopback from should
|
||||||
be passed in place of an input device. */
|
be passed in place of an input device. */
|
||||||
|
CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING = 0x02, /**< Disable switching
|
||||||
|
default device on OS
|
||||||
|
changes. */
|
||||||
} cubeb_stream_prefs;
|
} cubeb_stream_prefs;
|
||||||
|
|
||||||
/** Stream format initialization parameters. */
|
/** Stream format initialization parameters. */
|
||||||
|
|
|
@ -1834,11 +1834,16 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = register_notification_client(stm.get());
|
if (!((input_stream_params ?
|
||||||
if (FAILED(hr)) {
|
(input_stream_params->prefs & CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING) : 0) ||
|
||||||
/* this is not fatal, we can still play audio, but we won't be able
|
(output_stream_params ?
|
||||||
to keep using the default audio endpoint if it changes. */
|
(output_stream_params->prefs & CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING) : 0))) {
|
||||||
LOG("failed to register notification client, %lx", hr);
|
HRESULT hr = register_notification_client(stm.get());
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
/* this is not fatal, we can still play audio, but we won't be able
|
||||||
|
to keep using the default audio endpoint if it changes. */
|
||||||
|
LOG("failed to register notification client, %lx", hr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*stream = stm.release();
|
*stream = stm.release();
|
||||||
|
@ -1884,7 +1889,9 @@ void wasapi_stream_destroy(cubeb_stream * stm)
|
||||||
stm->emergency_bailout = nullptr;
|
stm->emergency_bailout = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
unregister_notification_client(stm);
|
if (stm->notification_client) {
|
||||||
|
unregister_notification_client(stm);
|
||||||
|
}
|
||||||
|
|
||||||
CloseHandle(stm->reconfigure_event);
|
CloseHandle(stm->reconfigure_event);
|
||||||
CloseHandle(stm->refill_event);
|
CloseHandle(stm->refill_event);
|
||||||
|
|
|
@ -79,3 +79,7 @@ patch -p3 < disable-assert.patch
|
||||||
|
|
||||||
echo "Applying prefer-pulse-rust.patch on top of $rev"
|
echo "Applying prefer-pulse-rust.patch on top of $rev"
|
||||||
patch -p3 < prefer-pulse-rust.patch
|
patch -p3 < prefer-pulse-rust.patch
|
||||||
|
|
||||||
|
echo "Applying disable-device-switching.patch on top of $rev"
|
||||||
|
patch -p3 < disable-device-switching.patch
|
||||||
|
|
||||||
|
|
|
@ -415,13 +415,14 @@ private:
|
||||||
LinkedListElement<T> sentinel;
|
LinkedListElement<T> sentinel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
template <typename Type>
|
||||||
class Iterator {
|
class Iterator {
|
||||||
RawType mCurrent;
|
Type mCurrent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Iterator(RawType aCurrent) : mCurrent(aCurrent) {}
|
explicit Iterator(Type aCurrent) : mCurrent(aCurrent) {}
|
||||||
|
|
||||||
RawType operator *() const {
|
Type operator *() const {
|
||||||
return mCurrent;
|
return mCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +431,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(Iterator& aOther) const {
|
bool operator!=(const Iterator<Type>& aOther) const {
|
||||||
return mCurrent != aOther.mCurrent;
|
return mCurrent != aOther.mCurrent;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -535,11 +536,17 @@ public:
|
||||||
*
|
*
|
||||||
* for (MyElementType* elt : myList) { ... }
|
* for (MyElementType* elt : myList) { ... }
|
||||||
*/
|
*/
|
||||||
Iterator begin() {
|
Iterator<RawType> begin() {
|
||||||
return Iterator(getFirst());
|
return Iterator<RawType>(getFirst());
|
||||||
}
|
}
|
||||||
Iterator end() {
|
Iterator<ConstRawType> begin() const {
|
||||||
return Iterator(nullptr);
|
return Iterator<ConstRawType>(getFirst());
|
||||||
|
}
|
||||||
|
Iterator<RawType> end() {
|
||||||
|
return Iterator<RawType>(nullptr);
|
||||||
|
}
|
||||||
|
Iterator<ConstRawType> end() const {
|
||||||
|
return Iterator<ConstRawType>(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -115,6 +115,11 @@ TestList()
|
||||||
MOZ_RELEASE_ASSERT(list.getLast() == &three);
|
MOZ_RELEASE_ASSERT(list.getLast() == &three);
|
||||||
MOZ_RELEASE_ASSERT(list.getFirst()->mValue == 3);
|
MOZ_RELEASE_ASSERT(list.getFirst()->mValue == 3);
|
||||||
MOZ_RELEASE_ASSERT(list.getLast()->mValue == 4);
|
MOZ_RELEASE_ASSERT(list.getLast()->mValue == 4);
|
||||||
|
|
||||||
|
const LinkedList<SomeClass>& constList = list;
|
||||||
|
for (const SomeClass* x : constList) {
|
||||||
|
MOZ_RELEASE_ASSERT(x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -2171,7 +2171,6 @@ pref("network.cookie.lifetimePolicy", 0); // 0-accept, 1-dontUse 2-acceptF
|
||||||
pref("network.cookie.prefsMigrated", false);
|
pref("network.cookie.prefsMigrated", false);
|
||||||
pref("network.cookie.lifetime.days", 90); // Ignored unless network.cookie.lifetimePolicy is 3.
|
pref("network.cookie.lifetime.days", 90); // Ignored unless network.cookie.lifetimePolicy is 3.
|
||||||
|
|
||||||
pref("network.proxy.enable_wpad_over_dhcp", true);
|
|
||||||
// The PAC file to load. Ignored unless network.proxy.type is 2.
|
// The PAC file to load. Ignored unless network.proxy.type is 2.
|
||||||
pref("network.proxy.autoconfig_url", "");
|
pref("network.proxy.autoconfig_url", "");
|
||||||
// Strip off paths when sending URLs to PAC scripts
|
// Strip off paths when sending URLs to PAC scripts
|
||||||
|
|
|
@ -38,7 +38,6 @@ XPIDL_SOURCES += [
|
||||||
'nsIDashboard.idl',
|
'nsIDashboard.idl',
|
||||||
'nsIDashboardEventNotifier.idl',
|
'nsIDashboardEventNotifier.idl',
|
||||||
'nsIDeprecationWarner.idl',
|
'nsIDeprecationWarner.idl',
|
||||||
'nsIDHCPClient.idl',
|
|
||||||
'nsIDivertableChannel.idl',
|
'nsIDivertableChannel.idl',
|
||||||
'nsIDownloader.idl',
|
'nsIDownloader.idl',
|
||||||
'nsIEncodedChannel.idl',
|
'nsIEncodedChannel.idl',
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
/* 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"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface allows the proxy code to access the DHCP Options in a platform-specific way
|
|
||||||
*/
|
|
||||||
[scriptable, uuid(aee75dc0-be1a-46b9-9e0c-31a6899c175c)]
|
|
||||||
interface nsIDHCPClient : nsISupports
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the DHCP Option designated by the option parameter
|
|
||||||
*/
|
|
||||||
ACString getOption(in uint8_t option);
|
|
||||||
};
|
|
|
@ -5,20 +5,17 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "nsPACMan.h"
|
#include "nsPACMan.h"
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
#include "mozilla/Preferences.h"
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
|
||||||
#include "nsIAuthPrompt.h"
|
#include "nsIAuthPrompt.h"
|
||||||
#include "nsIDHCPClient.h"
|
#include "nsIPromptFactory.h"
|
||||||
#include "nsIHttpChannel.h"
|
#include "nsIHttpChannel.h"
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
#include "nsIPrefBranch.h"
|
#include "nsIPrefBranch.h"
|
||||||
#include "nsIPromptFactory.h"
|
|
||||||
#include "nsIProtocolProxyService.h"
|
|
||||||
#include "nsISystemProxySettings.h"
|
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||||
|
#include "nsISystemProxySettings.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "mozilla/Preferences.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -29,8 +26,6 @@ LazyLogModule gProxyLog("proxy");
|
||||||
|
|
||||||
#undef LOG
|
#undef LOG
|
||||||
#define LOG(args) MOZ_LOG(gProxyLog, LogLevel::Debug, args)
|
#define LOG(args) MOZ_LOG(gProxyLog, LogLevel::Debug, args)
|
||||||
#define MOZ_WPAD_URL "http://wpad/wpad.dat"
|
|
||||||
#define MOZ_DHCP_WPAD_OPTION 252
|
|
||||||
|
|
||||||
// The PAC thread does evaluations of both PAC files and
|
// The PAC thread does evaluations of both PAC files and
|
||||||
// nsISystemProxySettings because they can both block the calling thread and we
|
// nsISystemProxySettings because they can both block the calling thread and we
|
||||||
|
@ -80,26 +75,6 @@ GetExtraJSContextHeapSize()
|
||||||
return extraSize < 0 ? 0 : extraSize;
|
return extraSize < 0 ? 0 : extraSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read network proxy type from preference
|
|
||||||
// Used to verify that the preference is WPAD in nsPACMan::ConfigureWPAD
|
|
||||||
nsresult
|
|
||||||
GetNetworkProxyTypeFromPref(int32_t* type)
|
|
||||||
{
|
|
||||||
*type = 0;
|
|
||||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
|
||||||
|
|
||||||
if (!prefs) {
|
|
||||||
LOG(("Failed to get a preference service object"));
|
|
||||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
|
||||||
}
|
|
||||||
nsresult rv = prefs->GetIntPref("network.proxy.type", type);
|
|
||||||
if (!NS_SUCCEEDED(rv)) {
|
|
||||||
LOG(("Failed to retrieve network.proxy.type from prefs"));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
LOG(("network.proxy.type pref retrieved: %d\n", *type));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -117,12 +92,12 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPACString(const nsACString &pacString)
|
void SetPACString(const nsCString &pacString)
|
||||||
{
|
{
|
||||||
mPACString = pacString;
|
mPACString = pacString;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPACURL(const nsACString &pacURL)
|
void SetPACURL(const nsCString &pacURL)
|
||||||
{
|
{
|
||||||
mPACURL = pacURL;
|
mPACURL = pacURL;
|
||||||
}
|
}
|
||||||
|
@ -216,43 +191,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<nsPACMan> mPACMan;
|
RefPtr<nsPACMan> mPACMan;
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// ConfigureWPADComplete allows the PAC thread to tell the main thread that
|
|
||||||
// the URL for the PAC file has been found
|
|
||||||
class ConfigureWPADComplete final : public Runnable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ConfigureWPADComplete(nsPACMan *aPACMan, const nsACString &aPACURISpec)
|
|
||||||
: Runnable("net::ConfigureWPADComplete"),
|
|
||||||
mPACMan(aPACMan),
|
|
||||||
mPACURISpec(aPACURISpec)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHOD Run() override
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
|
||||||
mPACMan->AssignPACURISpec(mPACURISpec);
|
|
||||||
mPACMan->ContinueLoadingAfterPACUriKnown();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
RefPtr<nsPACMan> mPACMan;
|
|
||||||
nsCString mPACURISpec;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// ExecutePACThreadAction is used to proxy actions from the main
|
// ExecutePACThreadAction is used to proxy actions from the main
|
||||||
// thread onto the PAC thread. There are 4 options: process the queue,
|
// thread onto the PAC thread. There are 3 options: process the queue,
|
||||||
// cancel the queue, query DHCP for the PAC option
|
// cancel the queue, and setup the javascript context with a new PAC file
|
||||||
// and setup the javascript context with a new PAC file
|
|
||||||
|
|
||||||
class ExecutePACThreadAction final : public Runnable
|
class ExecutePACThreadAction final : public Runnable
|
||||||
{
|
{
|
||||||
|
@ -265,7 +211,6 @@ public:
|
||||||
, mCancelStatus(NS_OK)
|
, mCancelStatus(NS_OK)
|
||||||
, mSetupPAC(false)
|
, mSetupPAC(false)
|
||||||
, mExtraHeapSize(0)
|
, mExtraHeapSize(0)
|
||||||
, mConfigureWPAD(false)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void CancelQueue (nsresult status)
|
void CancelQueue (nsresult status)
|
||||||
|
@ -276,7 +221,7 @@ public:
|
||||||
|
|
||||||
void SetupPAC (const char *text,
|
void SetupPAC (const char *text,
|
||||||
uint32_t datalen,
|
uint32_t datalen,
|
||||||
const nsACString &pacURI,
|
nsCString &pacURI,
|
||||||
uint32_t extraHeapSize)
|
uint32_t extraHeapSize)
|
||||||
{
|
{
|
||||||
mSetupPAC = true;
|
mSetupPAC = true;
|
||||||
|
@ -285,11 +230,6 @@ public:
|
||||||
mExtraHeapSize = extraHeapSize;
|
mExtraHeapSize = extraHeapSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWPAD()
|
|
||||||
{
|
|
||||||
mConfigureWPAD = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHOD Run() override
|
NS_IMETHOD Run() override
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread(), "wrong thread");
|
MOZ_ASSERT(!NS_IsMainThread(), "wrong thread");
|
||||||
|
@ -314,15 +254,6 @@ public:
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mConfigureWPAD) {
|
|
||||||
nsAutoCString spec;
|
|
||||||
mConfigureWPAD = false;
|
|
||||||
mPACMan->ConfigureWPAD(spec);
|
|
||||||
RefPtr<ConfigureWPADComplete> runnable = new ConfigureWPADComplete(mPACMan, spec);
|
|
||||||
NS_DispatchToMainThread(runnable);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
mPACMan->ProcessPendingQ();
|
mPACMan->ProcessPendingQ();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -335,9 +266,8 @@ private:
|
||||||
|
|
||||||
bool mSetupPAC;
|
bool mSetupPAC;
|
||||||
uint32_t mExtraHeapSize;
|
uint32_t mExtraHeapSize;
|
||||||
nsCString mSetupPACData;
|
nsCString mSetupPACData;
|
||||||
nsCString mSetupPACURI;
|
nsCString mSetupPACURI;
|
||||||
bool mConfigureWPAD;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -358,7 +288,7 @@ PendingPACQuery::PendingPACQuery(nsPACMan* pacMan,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PendingPACQuery::Complete(nsresult status, const nsACString &pacString)
|
PendingPACQuery::Complete(nsresult status, const nsCString &pacString)
|
||||||
{
|
{
|
||||||
if (!mCallback)
|
if (!mCallback)
|
||||||
return;
|
return;
|
||||||
|
@ -371,7 +301,7 @@ PendingPACQuery::Complete(nsresult status, const nsACString &pacString)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PendingPACQuery::UseAlternatePACFile(const nsACString &pacURL)
|
PendingPACQuery::UseAlternatePACFile(const nsCString &pacURL)
|
||||||
{
|
{
|
||||||
if (!mCallback)
|
if (!mCallback)
|
||||||
return;
|
return;
|
||||||
|
@ -406,9 +336,6 @@ nsPACMan::nsPACMan(nsIEventTarget *mainThreadEventTarget)
|
||||||
, mShutdown(false)
|
, mShutdown(false)
|
||||||
, mLoadFailureCount(0)
|
, mLoadFailureCount(0)
|
||||||
, mInProgress(false)
|
, mInProgress(false)
|
||||||
, mAutoDetect(false)
|
|
||||||
, mWPADOverDHCPEnabled(false)
|
|
||||||
, mProxyConfigType(0)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "pacman must be created on main thread");
|
MOZ_ASSERT(NS_IsMainThread(), "pacman must be created on main thread");
|
||||||
if (!sThreadLocalSetup){
|
if (!sThreadLocalSetup){
|
||||||
|
@ -468,7 +395,7 @@ nsPACMan::AsyncGetProxyForURI(nsIURI *uri,
|
||||||
TimeStamp::Now() > mScheduledReload) {
|
TimeStamp::Now() > mScheduledReload) {
|
||||||
LOG(("nsPACMan::AsyncGetProxyForURI reload as scheduled\n"));
|
LOG(("nsPACMan::AsyncGetProxyForURI reload as scheduled\n"));
|
||||||
|
|
||||||
LoadPACFromURI(EmptyCString(), true);
|
LoadPACFromURI(EmptyCString());
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<PendingPACQuery> query =
|
RefPtr<PendingPACQuery> query =
|
||||||
|
@ -501,15 +428,16 @@ nsPACMan::PostQuery(PendingPACQuery *query)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsPACMan::LoadPACFromURI(const nsACString &aSpec, bool aIsScheduledReload)
|
nsPACMan::LoadPACFromURI(const nsCString &spec)
|
||||||
{
|
{
|
||||||
NS_ENSURE_STATE(!mShutdown);
|
NS_ENSURE_STATE(!mShutdown);
|
||||||
|
NS_ENSURE_ARG(!spec.IsEmpty() || !mPACURISpec.IsEmpty());
|
||||||
|
|
||||||
nsCOMPtr<nsIStreamLoader> loader =
|
nsCOMPtr<nsIStreamLoader> loader =
|
||||||
do_CreateInstance(NS_STREAMLOADER_CONTRACTID);
|
do_CreateInstance(NS_STREAMLOADER_CONTRACTID);
|
||||||
NS_ENSURE_STATE(loader);
|
NS_ENSURE_STATE(loader);
|
||||||
|
|
||||||
LOG(("nsPACMan::LoadPACFromURI aSpec: %s, aIsScheduledReload:%s\n", aSpec.BeginReading(), aIsScheduledReload? "true" : "false"));
|
LOG(("nsPACMan::LoadPACFromURI %s\n", spec.get()));
|
||||||
// Since we might get called from nsProtocolProxyService::Init, we need to
|
// Since we might get called from nsProtocolProxyService::Init, we need to
|
||||||
// post an event back to the main thread before we try to use the IO service.
|
// post an event back to the main thread before we try to use the IO service.
|
||||||
//
|
//
|
||||||
|
@ -530,12 +458,11 @@ nsPACMan::LoadPACFromURI(const nsACString &aSpec, bool aIsScheduledReload)
|
||||||
CancelExistingLoad();
|
CancelExistingLoad();
|
||||||
|
|
||||||
mLoader = loader;
|
mLoader = loader;
|
||||||
if (!aIsScheduledReload) {
|
if (!spec.IsEmpty()) {
|
||||||
|
mPACURISpec = spec;
|
||||||
mPACURIRedirectSpec.Truncate();
|
mPACURIRedirectSpec.Truncate();
|
||||||
mNormalPACURISpec.Truncate(); // set at load time
|
mNormalPACURISpec.Truncate(); // set at load time
|
||||||
mLoadFailureCount = 0; // reset
|
mLoadFailureCount = 0; // reset
|
||||||
mAutoDetect = aSpec.IsEmpty();
|
|
||||||
mPACURISpec.Assign(aSpec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset to Null
|
// reset to Null
|
||||||
|
@ -543,56 +470,6 @@ nsPACMan::LoadPACFromURI(const nsACString &aSpec, bool aIsScheduledReload)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsPACMan::GetPACFromDHCP(nsACString &aSpec)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!NS_IsMainThread(), "wrong thread");
|
|
||||||
if (!mDHCPClient) {
|
|
||||||
LOG(("nsPACMan::GetPACFromDHCP DHCP option %d query failed because there is no DHCP client available\n", MOZ_DHCP_WPAD_OPTION));
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
nsresult rv;
|
|
||||||
rv = mDHCPClient->GetOption(MOZ_DHCP_WPAD_OPTION, aSpec);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
LOG(("nsPACMan::GetPACFromDHCP DHCP option %d query failed with result %d\n", MOZ_DHCP_WPAD_OPTION, (uint32_t)rv));
|
|
||||||
} else {
|
|
||||||
LOG(("nsPACMan::GetPACFromDHCP DHCP option %d query succeeded, finding PAC URL %s\n", MOZ_DHCP_WPAD_OPTION, aSpec.BeginReading()));
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsPACMan::ConfigureWPAD(nsACString &aSpec)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!NS_IsMainThread(), "wrong thread");
|
|
||||||
|
|
||||||
MOZ_RELEASE_ASSERT(mProxyConfigType == nsIProtocolProxyService::PROXYCONFIG_WPAD,
|
|
||||||
"WPAD is being executed when not selected by user");
|
|
||||||
|
|
||||||
aSpec.Truncate();
|
|
||||||
if (mWPADOverDHCPEnabled) {
|
|
||||||
GetPACFromDHCP(aSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aSpec.IsEmpty()) {
|
|
||||||
// We diverge from the WPAD spec here in that we don't walk the
|
|
||||||
// hosts's FQDN, stripping components until we hit a TLD. Doing so
|
|
||||||
// is dangerous in the face of an incomplete list of TLDs, and TLDs
|
|
||||||
// get added over time. We could consider doing only a single
|
|
||||||
// substitution of the first component, if that proves to help
|
|
||||||
// compatibility.
|
|
||||||
aSpec.AssignLiteral(MOZ_WPAD_URL);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsPACMan::AssignPACURISpec(const nsACString &aSpec)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
|
||||||
mPACURISpec.Assign(aSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsPACMan::StartLoading()
|
nsPACMan::StartLoading()
|
||||||
{
|
{
|
||||||
|
@ -605,29 +482,6 @@ nsPACMan::StartLoading()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mAutoDetect) {
|
|
||||||
GetNetworkProxyTypeFromPref(&mProxyConfigType);
|
|
||||||
RefPtr<ExecutePACThreadAction> wpadConfigurer =
|
|
||||||
new ExecutePACThreadAction(this);
|
|
||||||
wpadConfigurer->ConfigureWPAD();
|
|
||||||
if (mPACThread) {
|
|
||||||
mPACThread->Dispatch(wpadConfigurer, nsIEventTarget::DISPATCH_NORMAL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ContinueLoadingAfterPACUriKnown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsPACMan::ContinueLoadingAfterPACUriKnown()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
|
||||||
|
|
||||||
// CancelExistingLoad was called...
|
|
||||||
if (!mLoader) {
|
|
||||||
PostCancelPendingQ(NS_ERROR_ABORT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (NS_SUCCEEDED(mLoader->Init(this, nullptr))) {
|
if (NS_SUCCEEDED(mLoader->Init(this, nullptr))) {
|
||||||
// Always hit the origin server when loading PAC.
|
// Always hit the origin server when loading PAC.
|
||||||
nsCOMPtr<nsIIOService> ios = do_GetIOService();
|
nsCOMPtr<nsIIOService> ios = do_GetIOService();
|
||||||
|
@ -945,8 +799,6 @@ nsresult
|
||||||
nsPACMan::Init(nsISystemProxySettings *systemProxySettings)
|
nsPACMan::Init(nsISystemProxySettings *systemProxySettings)
|
||||||
{
|
{
|
||||||
mSystemProxySettings = systemProxySettings;
|
mSystemProxySettings = systemProxySettings;
|
||||||
mDHCPClient = do_GetService(NS_DHCPCLIENT_CONTRACTID);
|
|
||||||
|
|
||||||
|
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
NS_NewNamedThread("ProxyResolution", getter_AddRefs(mPACThread));
|
NS_NewNamedThread("ProxyResolution", getter_AddRefs(mPACThread));
|
||||||
|
|
|
@ -7,24 +7,23 @@
|
||||||
#ifndef nsPACMan_h__
|
#ifndef nsPACMan_h__
|
||||||
#define nsPACMan_h__
|
#define nsPACMan_h__
|
||||||
|
|
||||||
#include "mozilla/Atomics.h"
|
|
||||||
#include "mozilla/Attributes.h"
|
|
||||||
#include "mozilla/LinkedList.h"
|
|
||||||
#include "mozilla/Logging.h"
|
|
||||||
#include "mozilla/net/NeckoTargetHolder.h"
|
|
||||||
#include "mozilla/TimeStamp.h"
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "nsIChannelEventSink.h"
|
|
||||||
#include "nsIInterfaceRequestor.h"
|
|
||||||
#include "nsIStreamLoader.h"
|
#include "nsIStreamLoader.h"
|
||||||
|
#include "nsIInterfaceRequestor.h"
|
||||||
|
#include "nsIChannelEventSink.h"
|
||||||
|
#include "ProxyAutoConfig.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "ProxyAutoConfig.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/LinkedList.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "mozilla/TimeStamp.h"
|
||||||
|
#include "mozilla/Logging.h"
|
||||||
|
#include "mozilla/Atomics.h"
|
||||||
|
#include "mozilla/net/NeckoTargetHolder.h"
|
||||||
|
|
||||||
class nsISystemProxySettings;
|
class nsISystemProxySettings;
|
||||||
class nsIDHCPClient;
|
|
||||||
class nsIThread;
|
class nsIThread;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
@ -53,8 +52,8 @@ public:
|
||||||
* newPACURL should be 0 length.
|
* newPACURL should be 0 length.
|
||||||
*/
|
*/
|
||||||
virtual void OnQueryComplete(nsresult status,
|
virtual void OnQueryComplete(nsresult status,
|
||||||
const nsACString &pacString,
|
const nsCString &pacString,
|
||||||
const nsACString &newPACURL) = 0;
|
const nsCString &newPACURL) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PendingPACQuery final : public Runnable,
|
class PendingPACQuery final : public Runnable,
|
||||||
|
@ -66,8 +65,8 @@ public:
|
||||||
bool mainThreadResponse);
|
bool mainThreadResponse);
|
||||||
|
|
||||||
// can be called from either thread
|
// can be called from either thread
|
||||||
void Complete(nsresult status, const nsACString &pacString);
|
void Complete(nsresult status, const nsCString &pacString);
|
||||||
void UseAlternatePACFile(const nsACString &pacURL);
|
void UseAlternatePACFile(const nsCString &pacURL);
|
||||||
|
|
||||||
nsCString mSpec;
|
nsCString mSpec;
|
||||||
nsCString mScheme;
|
nsCString mScheme;
|
||||||
|
@ -132,7 +131,7 @@ public:
|
||||||
* The non normalized uri spec of this URI used for comparison with
|
* The non normalized uri spec of this URI used for comparison with
|
||||||
* system proxy settings to determine if the PAC uri has changed.
|
* system proxy settings to determine if the PAC uri has changed.
|
||||||
*/
|
*/
|
||||||
nsresult LoadPACFromURI(const nsACString &aSpec, bool aIsScheduledReload = false);
|
nsresult LoadPACFromURI(const nsCString &pacSpec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if we are currently loading the PAC file.
|
* Returns true if we are currently loading the PAC file.
|
||||||
|
@ -167,10 +166,6 @@ public:
|
||||||
return IsPACURI(tmp);
|
return IsPACURI(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsUsingWPAD() {
|
|
||||||
return mAutoDetect;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult Init(nsISystemProxySettings *);
|
nsresult Init(nsISystemProxySettings *);
|
||||||
static nsPACMan *sInstance;
|
static nsPACMan *sInstance;
|
||||||
|
|
||||||
|
@ -178,8 +173,6 @@ public:
|
||||||
void ProcessPendingQ();
|
void ProcessPendingQ();
|
||||||
void CancelPendingQ(nsresult);
|
void CancelPendingQ(nsresult);
|
||||||
|
|
||||||
void SetWPADOverDHCPEnabled(bool aValue) { mWPADOverDHCPEnabled = aValue; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NS_DECL_NSISTREAMLOADEROBSERVER
|
NS_DECL_NSISTREAMLOADEROBSERVER
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
NS_DECL_NSIINTERFACEREQUESTOR
|
||||||
|
@ -187,10 +180,8 @@ private:
|
||||||
|
|
||||||
friend class PendingPACQuery;
|
friend class PendingPACQuery;
|
||||||
friend class PACLoadComplete;
|
friend class PACLoadComplete;
|
||||||
friend class ConfigureWPADComplete;
|
|
||||||
friend class ExecutePACThreadAction;
|
friend class ExecutePACThreadAction;
|
||||||
friend class WaitForThreadShutdown;
|
friend class WaitForThreadShutdown;
|
||||||
friend class TestPACMan;
|
|
||||||
|
|
||||||
~nsPACMan();
|
~nsPACMan();
|
||||||
|
|
||||||
|
@ -204,11 +195,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void StartLoading();
|
void StartLoading();
|
||||||
|
|
||||||
/**
|
|
||||||
* Continue loading the PAC file.
|
|
||||||
*/
|
|
||||||
void ContinueLoadingAfterPACUriKnown();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload the PAC file if there is reason to.
|
* Reload the PAC file if there is reason to.
|
||||||
*/
|
*/
|
||||||
|
@ -226,22 +212,15 @@ private:
|
||||||
*/
|
*/
|
||||||
nsresult PostQuery(PendingPACQuery *query);
|
nsresult PostQuery(PendingPACQuery *query);
|
||||||
|
|
||||||
// Having found the PAC URI on the PAC thread, copy it to a string which
|
|
||||||
// can be altered on the main thread.
|
|
||||||
void AssignPACURISpec(const nsACString &aSpec);
|
|
||||||
|
|
||||||
// PAC thread operations only
|
// PAC thread operations only
|
||||||
void PostProcessPendingQ();
|
void PostProcessPendingQ();
|
||||||
void PostCancelPendingQ(nsresult);
|
void PostCancelPendingQ(nsresult);
|
||||||
bool ProcessPending();
|
bool ProcessPending();
|
||||||
nsresult GetPACFromDHCP(nsACString &aSpec);
|
|
||||||
nsresult ConfigureWPAD(nsACString &aSpec);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProxyAutoConfig mPAC;
|
ProxyAutoConfig mPAC;
|
||||||
nsCOMPtr<nsIThread> mPACThread;
|
nsCOMPtr<nsIThread> mPACThread;
|
||||||
nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
|
nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
|
||||||
nsCOMPtr<nsIDHCPClient> mDHCPClient;
|
|
||||||
|
|
||||||
LinkedList<PendingPACQuery> mPendingQ; /* pac thread only */
|
LinkedList<PendingPACQuery> mPendingQ; /* pac thread only */
|
||||||
|
|
||||||
|
@ -260,9 +239,6 @@ private:
|
||||||
|
|
||||||
bool mInProgress;
|
bool mInProgress;
|
||||||
bool mIncludePath;
|
bool mIncludePath;
|
||||||
bool mAutoDetect;
|
|
||||||
bool mWPADOverDHCPEnabled;
|
|
||||||
int32_t mProxyConfigType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern LazyLogModule gProxyLog;
|
extern LazyLogModule gProxyLog;
|
||||||
|
|
|
@ -62,6 +62,7 @@ namespace net {
|
||||||
#define PROXY_PREF_BRANCH "network.proxy"
|
#define PROXY_PREF_BRANCH "network.proxy"
|
||||||
#define PROXY_PREF(x) PROXY_PREF_BRANCH "." x
|
#define PROXY_PREF(x) PROXY_PREF_BRANCH "." x
|
||||||
|
|
||||||
|
#define WPAD_URL "http://wpad/wpad.dat"
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -310,8 +311,8 @@ private:
|
||||||
// Called asynchronously, so we do not need to post another PLEvent
|
// Called asynchronously, so we do not need to post another PLEvent
|
||||||
// before calling DoCallback.
|
// before calling DoCallback.
|
||||||
void OnQueryComplete(nsresult status,
|
void OnQueryComplete(nsresult status,
|
||||||
const nsACString &pacString,
|
const nsCString &pacString,
|
||||||
const nsACString &newPACURL) override
|
const nsCString &newPACURL) override
|
||||||
{
|
{
|
||||||
// If we've already called DoCallback then, nothing more to do.
|
// If we've already called DoCallback then, nothing more to do.
|
||||||
if (!mCallback)
|
if (!mCallback)
|
||||||
|
@ -820,7 +821,6 @@ nsProtocolProxyService::nsProtocolProxyService()
|
||||||
, mSOCKSProxyVersion(4)
|
, mSOCKSProxyVersion(4)
|
||||||
, mSOCKSProxyRemoteDNS(false)
|
, mSOCKSProxyRemoteDNS(false)
|
||||||
, mProxyOverTLS(true)
|
, mProxyOverTLS(true)
|
||||||
, mWPADOverDHCPEnabled(false)
|
|
||||||
, mPACMan(nullptr)
|
, mPACMan(nullptr)
|
||||||
, mSessionStart(PR_Now())
|
, mSessionStart(PR_Now())
|
||||||
, mFailedProxyTimeout(30 * 60) // 30 minute default
|
, mFailedProxyTimeout(30 * 60) // 30 minute default
|
||||||
|
@ -1087,12 +1087,6 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
|
||||||
mProxyOverTLS);
|
mProxyOverTLS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pref || !strcmp(pref, PROXY_PREF("enable_wpad_over_dhcp"))) {
|
|
||||||
proxy_GetBoolPref(prefBranch, PROXY_PREF("enable_wpad_over_dhcp"),
|
|
||||||
mWPADOverDHCPEnabled);
|
|
||||||
reloadPAC = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pref || !strcmp(pref, PROXY_PREF("failover_timeout")))
|
if (!pref || !strcmp(pref, PROXY_PREF("failover_timeout")))
|
||||||
proxy_GetIntPref(prefBranch, PROXY_PREF("failover_timeout"),
|
proxy_GetIntPref(prefBranch, PROXY_PREF("failover_timeout"),
|
||||||
mFailedProxyTimeout);
|
mFailedProxyTimeout);
|
||||||
|
@ -1125,15 +1119,19 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
|
||||||
ResetPACThread();
|
ResetPACThread();
|
||||||
}
|
}
|
||||||
} else if (mProxyConfig == PROXYCONFIG_WPAD) {
|
} else if (mProxyConfig == PROXYCONFIG_WPAD) {
|
||||||
LOG(("Auto-detecting proxy - Reset Pac Thread"));
|
// We diverge from the WPAD spec here in that we don't walk the
|
||||||
ResetPACThread();
|
// hosts's FQDN, stripping components until we hit a TLD. Doing so
|
||||||
|
// is dangerous in the face of an incomplete list of TLDs, and TLDs
|
||||||
|
// get added over time. We could consider doing only a single
|
||||||
|
// substitution of the first component, if that proves to help
|
||||||
|
// compatibility.
|
||||||
|
tempString.AssignLiteral(WPAD_URL);
|
||||||
} else if (mSystemProxySettings) {
|
} else if (mSystemProxySettings) {
|
||||||
// Get System Proxy settings if available
|
// Get System Proxy settings if available
|
||||||
AsyncConfigureFromPAC(false, false);
|
AsyncConfigureFromPAC(false, false);
|
||||||
}
|
}
|
||||||
if (!tempString.IsEmpty() || mProxyConfig == PROXYCONFIG_WPAD) {
|
if (!tempString.IsEmpty())
|
||||||
ConfigureFromPAC(tempString, true);
|
ConfigureFromPAC(tempString, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1484,7 +1482,9 @@ nsProtocolProxyService::SetupPACThread(nsIEventTarget *mainThreadEventTarget)
|
||||||
else {
|
else {
|
||||||
rv = mPACMan->Init(nullptr);
|
rv = mPACMan->Init(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
mPACMan->Shutdown();
|
||||||
mPACMan = nullptr;
|
mPACMan = nullptr;
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1508,15 +1508,11 @@ nsProtocolProxyService::ConfigureFromPAC(const nsCString &spec,
|
||||||
nsresult rv = SetupPACThread();
|
nsresult rv = SetupPACThread();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
bool autodetect = spec.IsEmpty();
|
if (mPACMan->IsPACURI(spec) && !forceReload)
|
||||||
if (!forceReload && ((!autodetect && mPACMan->IsPACURI(spec)) ||
|
|
||||||
(autodetect && mPACMan->IsUsingWPAD()))) {
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
|
||||||
|
|
||||||
mFailedProxies.Clear();
|
mFailedProxies.Clear();
|
||||||
|
|
||||||
mPACMan->SetWPADOverDHCPEnabled(mWPADOverDHCPEnabled);
|
|
||||||
return mPACMan->LoadPACFromURI(spec);
|
return mPACMan->LoadPACFromURI(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1569,6 +1565,8 @@ nsProtocolProxyService::ReloadPAC()
|
||||||
nsAutoCString pacSpec;
|
nsAutoCString pacSpec;
|
||||||
if (type == PROXYCONFIG_PAC)
|
if (type == PROXYCONFIG_PAC)
|
||||||
prefs->GetCharPref(PROXY_PREF("autoconfig_url"), pacSpec);
|
prefs->GetCharPref(PROXY_PREF("autoconfig_url"), pacSpec);
|
||||||
|
else if (type == PROXYCONFIG_WPAD)
|
||||||
|
pacSpec.AssignLiteral(WPAD_URL);
|
||||||
else if (type == PROXYCONFIG_SYSTEM) {
|
else if (type == PROXYCONFIG_SYSTEM) {
|
||||||
if (mSystemProxySettings) {
|
if (mSystemProxySettings) {
|
||||||
AsyncConfigureFromPAC(true, true);
|
AsyncConfigureFromPAC(true, true);
|
||||||
|
@ -1577,7 +1575,7 @@ nsProtocolProxyService::ReloadPAC()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pacSpec.IsEmpty() || type == PROXYCONFIG_WPAD)
|
if (!pacSpec.IsEmpty())
|
||||||
ConfigureFromPAC(pacSpec, true);
|
ConfigureFromPAC(pacSpec, true);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1601,8 +1599,8 @@ class nsAsyncBridgeRequest final : public nsPACManCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnQueryComplete(nsresult status,
|
void OnQueryComplete(nsresult status,
|
||||||
const nsACString &pacString,
|
const nsCString &pacString,
|
||||||
const nsACString &newPACURL) override
|
const nsCString &newPACURL) override
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
mCompleted = true;
|
mCompleted = true;
|
||||||
|
|
|
@ -400,7 +400,6 @@ protected:
|
||||||
int32_t mSOCKSProxyVersion;
|
int32_t mSOCKSProxyVersion;
|
||||||
bool mSOCKSProxyRemoteDNS;
|
bool mSOCKSProxyRemoteDNS;
|
||||||
bool mProxyOverTLS;
|
bool mProxyOverTLS;
|
||||||
bool mWPADOverDHCPEnabled;
|
|
||||||
|
|
||||||
RefPtr<nsPACMan> mPACMan; // non-null if we are using PAC
|
RefPtr<nsPACMan> mPACMan; // non-null if we are using PAC
|
||||||
nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
|
nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
|
||||||
|
|
|
@ -335,10 +335,6 @@
|
||||||
#define NS_SYSTEMPROXYSETTINGS_CONTRACTID \
|
#define NS_SYSTEMPROXYSETTINGS_CONTRACTID \
|
||||||
"@mozilla.org/system-proxy-settings;1"
|
"@mozilla.org/system-proxy-settings;1"
|
||||||
|
|
||||||
// component implementing nsIDHCPClient.
|
|
||||||
#define NS_DHCPCLIENT_CONTRACTID \
|
|
||||||
"@mozilla.org/dhcp-client;1"
|
|
||||||
|
|
||||||
// service implementing nsIStreamTransportService
|
// service implementing nsIStreamTransportService
|
||||||
#define NS_STREAMTRANSPORTSERVICE_CONTRACTID \
|
#define NS_STREAMTRANSPORTSERVICE_CONTRACTID \
|
||||||
"@mozilla.org/network/stream-transport-service;1"
|
"@mozilla.org/network/stream-transport-service;1"
|
||||||
|
|
|
@ -1,322 +0,0 @@
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include "nsServiceManagerUtils.h"
|
|
||||||
#include "../../../xpcom/threads/nsThreadManager.h"
|
|
||||||
#include "nsIDHCPClient.h"
|
|
||||||
#include "nsIPrefBranch.h"
|
|
||||||
#include "nsComponentManager.h"
|
|
||||||
#include "mozilla/ModuleUtils.h"
|
|
||||||
#include "../../base/nsPACMan.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define TEST_WPAD_DHCP_OPTION "http://pac/pac.dat"
|
|
||||||
#define TEST_ASSIGNED_PAC_URL "http://assignedpac/pac.dat"
|
|
||||||
#define WPAD_PREF 4
|
|
||||||
#define NETWORK_PROXY_TYPE_PREF_NAME "network.proxy.type"
|
|
||||||
#define GETTING_NETWORK_PROXY_TYPE_FAILED -1
|
|
||||||
|
|
||||||
nsCString WPADOptionResult;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace net {
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
SetNetworkProxyType(int32_t pref)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
|
||||||
|
|
||||||
if (!prefs) {
|
|
||||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
|
||||||
}
|
|
||||||
return prefs->SetIntPref(NETWORK_PROXY_TYPE_PREF_NAME, pref);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
GetNetworkProxyType(int32_t* pref)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
|
||||||
|
|
||||||
if (!prefs) {
|
|
||||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
|
||||||
}
|
|
||||||
return prefs->GetIntPref(NETWORK_PROXY_TYPE_PREF_NAME, pref);
|
|
||||||
}
|
|
||||||
|
|
||||||
class nsTestDHCPClient final : public nsIDHCPClient
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
NS_DECL_NSIDHCPCLIENT
|
|
||||||
|
|
||||||
nsTestDHCPClient() {};
|
|
||||||
nsresult Init(){
|
|
||||||
return NS_OK;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
~nsTestDHCPClient() {};
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsTestDHCPClient::GetOption(uint8_t option, nsACString & _retval)
|
|
||||||
{
|
|
||||||
_retval.Assign(WPADOptionResult);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(nsTestDHCPClient, nsIDHCPClient)
|
|
||||||
|
|
||||||
|
|
||||||
#define NS_TESTDHCPCLIENTSERVICE_CID /* {FEBF1D69-4D7D-4891-9524-045AD18B5592} */\
|
|
||||||
{ 0xFEBF1D69, 0x4D7D, 0x4891, \
|
|
||||||
{0x95, 0x24, 0x04, 0x5a, 0xd1, 0x8b, 0x55, 0x92 } }
|
|
||||||
|
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsTestDHCPClient, Init)
|
|
||||||
NS_DEFINE_NAMED_CID(NS_TESTDHCPCLIENTSERVICE_CID);
|
|
||||||
|
|
||||||
static const mozilla::Module::CIDEntry kSysDHCPClientCIDs[] = {
|
|
||||||
{ &kNS_TESTDHCPCLIENTSERVICE_CID, false, nullptr, nsTestDHCPClientConstructor },
|
|
||||||
{ nullptr }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const mozilla::Module::ContractIDEntry kSysDHCPClientContracts[] = {
|
|
||||||
{ NS_DHCPCLIENT_CONTRACTID, &kNS_TESTDHCPCLIENTSERVICE_CID },
|
|
||||||
{ nullptr }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const mozilla::Module kSysDHCPClientModule = {
|
|
||||||
mozilla::Module::kVersion,
|
|
||||||
kSysDHCPClientCIDs,
|
|
||||||
kSysDHCPClientContracts
|
|
||||||
};
|
|
||||||
|
|
||||||
NSMODULE_DEFN(nsDHCPClientModule) = &kSysDHCPClientModule;
|
|
||||||
|
|
||||||
void
|
|
||||||
SetOptionResult(const char* result)
|
|
||||||
{
|
|
||||||
WPADOptionResult.Assign(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ProcessPendingEventsAction final : public Runnable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// by default we just process the queue
|
|
||||||
ProcessPendingEventsAction()
|
|
||||||
: Runnable("net::ProcessPendingEventsAction")
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHOD
|
|
||||||
Run() override
|
|
||||||
{
|
|
||||||
if (NS_HasPendingEvents(nullptr)) {
|
|
||||||
NS_WARNING("Found pending requests on PAC thread");
|
|
||||||
nsresult rv;
|
|
||||||
rv = NS_ProcessPendingEvents(nullptr);
|
|
||||||
EXPECT_EQ(NS_OK, rv);
|
|
||||||
}
|
|
||||||
NS_WARNING("No pending requests on PAC thread");
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class TestPACMan : public ::testing::Test {
|
|
||||||
protected:
|
|
||||||
|
|
||||||
RefPtr<nsPACMan> mPACMan;
|
|
||||||
|
|
||||||
void
|
|
||||||
ProcessAllEvents()
|
|
||||||
{
|
|
||||||
ProcessPendingEventsOnPACThread();
|
|
||||||
nsresult rv;
|
|
||||||
while (NS_HasPendingEvents(nullptr)) {
|
|
||||||
NS_WARNING("Pending events on main thread");
|
|
||||||
rv = NS_ProcessPendingEvents(nullptr);
|
|
||||||
ASSERT_EQ(NS_OK, rv);
|
|
||||||
ProcessPendingEventsOnPACThread();
|
|
||||||
}
|
|
||||||
NS_WARNING("End of pending events on main thread");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// This method is used to ensure that all pending events on the main thread
|
|
||||||
// and the Proxy thread are processsed.
|
|
||||||
// It iterates over ProcessAllEvents because simply calling ProcessAllEvents once
|
|
||||||
// did not reliably process the events on both threads on all platforms.
|
|
||||||
void
|
|
||||||
ProcessAllEventsTenTimes(){
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
ProcessAllEvents();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
SetUp()
|
|
||||||
{
|
|
||||||
ASSERT_EQ(NS_OK, GetNetworkProxyType(&originalNetworkProxyTypePref));
|
|
||||||
nsFactoryEntry* factoryEntry = nsComponentManagerImpl::gComponentManager
|
|
||||||
->GetFactoryEntry(kNS_TESTDHCPCLIENTSERVICE_CID);
|
|
||||||
if (factoryEntry) {
|
|
||||||
nsresult rv = nsComponentManagerImpl::gComponentManager->UnregisterFactory(kNS_TESTDHCPCLIENTSERVICE_CID, factoryEntry->mFactory);
|
|
||||||
ASSERT_EQ(NS_OK, rv);
|
|
||||||
}
|
|
||||||
nsComponentManagerImpl::gComponentManager->RegisterModule(&kSysDHCPClientModule, nullptr);
|
|
||||||
|
|
||||||
mPACMan = new nsPACMan(nullptr);
|
|
||||||
mPACMan->SetWPADOverDHCPEnabled(true);
|
|
||||||
mPACMan->Init(nullptr);
|
|
||||||
ASSERT_EQ(NS_OK, SetNetworkProxyType(WPAD_PREF));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
TearDown()
|
|
||||||
{
|
|
||||||
|
|
||||||
mPACMan->Shutdown();
|
|
||||||
if (originalNetworkProxyTypePref != GETTING_NETWORK_PROXY_TYPE_FAILED) {
|
|
||||||
ASSERT_EQ(NS_OK, SetNetworkProxyType(originalNetworkProxyTypePref));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDHCPClient>
|
|
||||||
GetPACManDHCPCient()
|
|
||||||
{
|
|
||||||
return mPACMan->mDHCPClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetPACManDHCPCient(nsCOMPtr<nsIDHCPClient> aValue)
|
|
||||||
{
|
|
||||||
mPACMan->mDHCPClient = aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AssertPACSpecEqualTo(const char* aExpected)
|
|
||||||
{
|
|
||||||
ASSERT_STREQ(aExpected, mPACMan->mPACURISpec.Data());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
int32_t originalNetworkProxyTypePref = GETTING_NETWORK_PROXY_TYPE_FAILED;
|
|
||||||
|
|
||||||
void ProcessPendingEventsOnPACThread(){
|
|
||||||
RefPtr<ProcessPendingEventsAction> action =
|
|
||||||
new ProcessPendingEventsAction();
|
|
||||||
|
|
||||||
mPACMan->mPACThread->Dispatch(action, nsIEventTarget::DISPATCH_SYNC);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TEST_F(TestPACMan, TestCreateDHCPClientAndGetOption) {
|
|
||||||
|
|
||||||
SetOptionResult(TEST_WPAD_DHCP_OPTION);
|
|
||||||
nsCString spec;
|
|
||||||
GetPACManDHCPCient()->GetOption(252, spec);
|
|
||||||
ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, spec.Data());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestPACMan, TestCreateDHCPClientAndGetEmptyOption) {
|
|
||||||
SetOptionResult("");
|
|
||||||
nsCString spec;
|
|
||||||
spec.AssignLiteral(TEST_ASSIGNED_PAC_URL);
|
|
||||||
GetPACManDHCPCient()->GetOption(252, spec);
|
|
||||||
ASSERT_TRUE(spec.IsEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestPACMan, WhenTheDHCPClientExistsAndDHCPIsNonEmptyDHCPOptionIsUsedAsPACUri) {
|
|
||||||
|
|
||||||
SetOptionResult(TEST_WPAD_DHCP_OPTION);
|
|
||||||
|
|
||||||
mPACMan->LoadPACFromURI(EmptyCString());
|
|
||||||
|
|
||||||
ProcessAllEventsTenTimes();
|
|
||||||
|
|
||||||
ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, WPADOptionResult.Data());
|
|
||||||
AssertPACSpecEqualTo(TEST_WPAD_DHCP_OPTION);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestPACMan, WhenTheDHCPResponseIsEmptyWPADDefaultsToStandardURL) {
|
|
||||||
|
|
||||||
SetOptionResult(EmptyCString().Data());
|
|
||||||
|
|
||||||
mPACMan->LoadPACFromURI(EmptyCString());
|
|
||||||
ASSERT_TRUE(NS_HasPendingEvents(nullptr));
|
|
||||||
|
|
||||||
ProcessAllEventsTenTimes();
|
|
||||||
|
|
||||||
ASSERT_STREQ("", WPADOptionResult.Data());
|
|
||||||
AssertPACSpecEqualTo("http://wpad/wpad.dat");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestPACMan, WhenThereIsNoDHCPClientWPADDefaultsToStandardURL) {
|
|
||||||
|
|
||||||
SetOptionResult(TEST_WPAD_DHCP_OPTION);
|
|
||||||
|
|
||||||
SetPACManDHCPCient(nullptr);
|
|
||||||
|
|
||||||
mPACMan->LoadPACFromURI(EmptyCString());
|
|
||||||
|
|
||||||
ProcessAllEventsTenTimes();
|
|
||||||
|
|
||||||
ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, WPADOptionResult.Data());
|
|
||||||
AssertPACSpecEqualTo("http://wpad/wpad.dat");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestPACMan, WhenWPADOverDHCPIsPreffedOffWPADDefaultsToStandardURL) {
|
|
||||||
|
|
||||||
SetOptionResult(TEST_WPAD_DHCP_OPTION);
|
|
||||||
|
|
||||||
mPACMan->SetWPADOverDHCPEnabled(false);
|
|
||||||
mPACMan->LoadPACFromURI(EmptyCString());
|
|
||||||
|
|
||||||
ProcessAllEventsTenTimes();
|
|
||||||
|
|
||||||
ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, WPADOptionResult.Data());
|
|
||||||
AssertPACSpecEqualTo("http://wpad/wpad.dat");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestPACMan, WhenPACUriIsSetDirectlyItIsUsedRatherThanWPAD) {
|
|
||||||
|
|
||||||
SetOptionResult(TEST_WPAD_DHCP_OPTION);
|
|
||||||
|
|
||||||
nsCString spec;
|
|
||||||
spec.AssignLiteral(TEST_ASSIGNED_PAC_URL);
|
|
||||||
|
|
||||||
mPACMan->LoadPACFromURI(spec);
|
|
||||||
|
|
||||||
ProcessAllEventsTenTimes();
|
|
||||||
|
|
||||||
AssertPACSpecEqualTo(TEST_ASSIGNED_PAC_URL);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestPACMan, WhenAScheduledReloadOfAssignedPACHappensTheAssignedPACSpecStaysRatherThanReadingFromDHCP) {
|
|
||||||
|
|
||||||
SetOptionResult(TEST_WPAD_DHCP_OPTION);
|
|
||||||
nsCString spec;
|
|
||||||
spec.AssignLiteral(TEST_ASSIGNED_PAC_URL);
|
|
||||||
mPACMan->LoadPACFromURI(spec);
|
|
||||||
|
|
||||||
ProcessAllEventsTenTimes();
|
|
||||||
|
|
||||||
mPACMan->LoadPACFromURI(EmptyCString(), true);
|
|
||||||
|
|
||||||
ProcessAllEventsTenTimes();
|
|
||||||
|
|
||||||
AssertPACSpecEqualTo(TEST_ASSIGNED_PAC_URL);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace net
|
|
||||||
} // namespace mozilla
|
|
|
@ -9,7 +9,6 @@ UNIFIED_SOURCES += [
|
||||||
'TestHeaders.cpp',
|
'TestHeaders.cpp',
|
||||||
'TestHttpAuthUtils.cpp',
|
'TestHttpAuthUtils.cpp',
|
||||||
'TestMozURL.cpp',
|
'TestMozURL.cpp',
|
||||||
'TestPACMan.cpp',
|
|
||||||
'TestPartiallySeekableInputStream.cpp',
|
'TestPartiallySeekableInputStream.cpp',
|
||||||
'TestProtocolProxyService.cpp',
|
'TestProtocolProxyService.cpp',
|
||||||
'TestReadStreamToString.cpp',
|
'TestReadStreamToString.cpp',
|
||||||
|
@ -30,8 +29,3 @@ LOCAL_INCLUDES += [
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul-gtest'
|
FINAL_LIBRARY = 'xul-gtest'
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
|
||||||
'!/xpcom',
|
|
||||||
'/xpcom/components'
|
|
||||||
]
|
|
||||||
|
|
|
@ -1163,4 +1163,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
||||||
|
|
||||||
static const int32_t kUnknownId = -1;
|
static const int32_t kUnknownId = -1;
|
||||||
|
|
||||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1533204274991000);
|
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1533550046602000);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
const PRTime gPreloadListExpirationTime = INT64_C(1535623417693000);
|
const PRTime gPreloadListExpirationTime = INT64_C(1535969034685000);
|
||||||
%%
|
%%
|
||||||
0-1.party, 1
|
0-1.party, 1
|
||||||
0.me.uk, 1
|
0.me.uk, 1
|
||||||
|
|
|
@ -8,7 +8,7 @@ import sys
|
||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
PACKAGE_NAME = 'mozrunner'
|
PACKAGE_NAME = 'mozrunner'
|
||||||
PACKAGE_VERSION = '7.0.0'
|
PACKAGE_VERSION = '7.0.1'
|
||||||
|
|
||||||
desc = """Reliable start/stop/configuration of Mozilla Applications (Firefox, Thunderbird, etc.)"""
|
desc = """Reliable start/stop/configuration of Mozilla Applications (Firefox, Thunderbird, etc.)"""
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
|
||||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||||
DIRS += ['system/osxproxy']
|
DIRS += ['system/osxproxy']
|
||||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||||
DIRS += ['system/windowsproxy',
|
DIRS += ['system/windowsproxy']
|
||||||
'system/windowsDHCPClient']
|
|
||||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||||
DIRS += ['system/androidproxy']
|
DIRS += ['system/androidproxy']
|
||||||
|
|
||||||
|
|
|
@ -1,256 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* 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 "DHCPUtils.h"
|
|
||||||
#include <vector>
|
|
||||||
#include "mozilla\Logging.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define MOZ_WORKING_BUFFER_SIZE_NETWORK_ADAPTERS 15000
|
|
||||||
#define MOZ_WORKING_BUFFER_SIZE_DHCP_PARAMS 1000
|
|
||||||
#define MOZ_MAX_TRIES 3
|
|
||||||
namespace mozilla {
|
|
||||||
namespace toolkit {
|
|
||||||
namespace system {
|
|
||||||
namespace windowsDHCPClient {
|
|
||||||
|
|
||||||
//
|
|
||||||
// The comments on this page reference the following Microsoft documentation pages (both retrieved 2017-06-27)
|
|
||||||
// [1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx
|
|
||||||
// [2] https://msdn.microsoft.com/en-us/library/windows/desktop/aa363298(v=vs.85).aspx
|
|
||||||
mozilla::LazyLogModule gDhcpUtilsLog("dhcpUtils");
|
|
||||||
|
|
||||||
#undef LOG
|
|
||||||
#define LOG(args) MOZ_LOG(gDhcpUtilsLog, LogLevel::Debug, args)
|
|
||||||
|
|
||||||
bool
|
|
||||||
IsCurrentAndHasDHCP(PIP_ADAPTER_ADDRESSES aAddresses)
|
|
||||||
{
|
|
||||||
return aAddresses->OperStatus == 1 &&
|
|
||||||
(aAddresses->Dhcpv4Server.iSockaddrLength ||
|
|
||||||
aAddresses->Dhcpv6Server.iSockaddrLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
GetActiveDHCPNetworkAdapterName(nsACString& aNetworkAdapterName,
|
|
||||||
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper)
|
|
||||||
{
|
|
||||||
/* Declare and initialize variables */
|
|
||||||
|
|
||||||
uint32_t dwSize = 0;
|
|
||||||
uint32_t dwRetVal = 0;
|
|
||||||
nsresult rv = NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
// Set the flags to pass to GetAdaptersAddresses
|
|
||||||
uint32_t flags = GAA_FLAG_INCLUDE_PREFIX;
|
|
||||||
|
|
||||||
// default to unspecified address family (both)
|
|
||||||
uint32_t family = AF_UNSPEC;
|
|
||||||
|
|
||||||
// Allocate a 15 KB buffer to start with.
|
|
||||||
uint32_t outBufLen = MOZ_WORKING_BUFFER_SIZE_NETWORK_ADAPTERS;
|
|
||||||
uint32_t iterations = 0;
|
|
||||||
|
|
||||||
aNetworkAdapterName.Truncate();
|
|
||||||
|
|
||||||
// Now we try calling the GetAdaptersAddresses method until the return value
|
|
||||||
// is not ERROR_BUFFER_OVERFLOW. According to [1]
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// > When the return value is ERROR_BUFFER_OVERFLOW, the SizePointer parameter returned
|
|
||||||
// > points to the required size of the buffer to hold the adapter information.
|
|
||||||
// > Note that it is possible for the buffer size required for the IP_ADAPTER_ADDRESSES
|
|
||||||
// > structures pointed to by the AdapterAddresses parameter to change between
|
|
||||||
// > subsequent calls to the GetAdaptersAddresses function if an adapter address
|
|
||||||
// > is added or removed. However, this method of using the GetAdaptersAddresses
|
|
||||||
// > function is strongly discouraged. This method requires calling the
|
|
||||||
// > GetAdaptersAddresses function multiple times.
|
|
||||||
// >
|
|
||||||
// > The recommended method of calling the GetAdaptersAddresses function is
|
|
||||||
// > to pre-allocate a 15KB working buffer pointed to by the AdapterAddresses parameter.
|
|
||||||
// > On typical computers, this dramatically reduces the chances that the
|
|
||||||
// > GetAdaptersAddresses function returns ERROR_BUFFER_OVERFLOW, which would require
|
|
||||||
// > calling GetAdaptersAddresses function multiple times.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// The possibility of the buffer size changing between calls to
|
|
||||||
// GetAdaptersAddresses is why we allow the following code to be called several times,
|
|
||||||
// rather than just the two that would be neccessary if we could rely on the
|
|
||||||
// value returned in outBufLen being the true size needed.
|
|
||||||
|
|
||||||
std::vector<IP_ADAPTER_ADDRESSES> pAddresses;
|
|
||||||
do {
|
|
||||||
pAddresses.resize(outBufLen/sizeof(IP_ADAPTER_ADDRESSES));
|
|
||||||
|
|
||||||
dwRetVal =
|
|
||||||
aWindowsNetworkFunctionsWrapper->GetAdaptersAddressesWrapped(
|
|
||||||
family, flags, nullptr, pAddresses.data(), (PULONG)&outBufLen);
|
|
||||||
|
|
||||||
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
|
|
||||||
iterations++;
|
|
||||||
}
|
|
||||||
} while (dwRetVal == ERROR_BUFFER_OVERFLOW && iterations < MOZ_MAX_TRIES);
|
|
||||||
|
|
||||||
switch(dwRetVal) {
|
|
||||||
case NO_ERROR:
|
|
||||||
{
|
|
||||||
// set default return value if we don't find a suitable network adapter
|
|
||||||
rv = NS_ERROR_NOT_AVAILABLE;
|
|
||||||
PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses.data();
|
|
||||||
while (pCurrAddresses) {
|
|
||||||
if (IsCurrentAndHasDHCP(pCurrAddresses)) {
|
|
||||||
rv = NS_OK;
|
|
||||||
aNetworkAdapterName.Assign(pCurrAddresses->AdapterName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pCurrAddresses = pCurrAddresses->Next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ERROR_NO_DATA:
|
|
||||||
rv = NS_ERROR_NOT_AVAILABLE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_LOG(gDhcpUtilsLog, mozilla::LogLevel::Warning,
|
|
||||||
("GetAdaptersAddresses returned %d", dwRetVal));
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
IterateDHCPInformRequestsUntilBufferLargeEnough(
|
|
||||||
DHCPCAPI_PARAMS& aDhcpRequestedOptionParams,
|
|
||||||
wchar_t* aWideNetworkAdapterName,
|
|
||||||
std::vector<char>& aBuffer,
|
|
||||||
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper)
|
|
||||||
{
|
|
||||||
uint32_t iterations = 0;
|
|
||||||
uint32_t outBufLen = MOZ_WORKING_BUFFER_SIZE_DHCP_PARAMS;
|
|
||||||
|
|
||||||
DHCPCAPI_PARAMS_ARRAY RequestParams = {
|
|
||||||
1, // only one option to request
|
|
||||||
&aDhcpRequestedOptionParams
|
|
||||||
};
|
|
||||||
|
|
||||||
// According to [2],
|
|
||||||
// the following is for 'Optional data to be requested,
|
|
||||||
// in addition to the data requested in the RecdParams array.'
|
|
||||||
// We are not requesting anything in addition, so this is empty.
|
|
||||||
DHCPCAPI_PARAMS_ARRAY SendParams = {
|
|
||||||
0,
|
|
||||||
nullptr
|
|
||||||
};
|
|
||||||
|
|
||||||
DWORD winAPIResponse;
|
|
||||||
// Now we try calling the DHCPRequestParams method until the return value
|
|
||||||
// is not ERROR_MORE_DATA. According to [2]:
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// > Note that the required size of Buffer may increase during the time that elapses
|
|
||||||
// > between the initial function call's return and a subsequent call;
|
|
||||||
// > therefore, the required size of Buffer (indicated in pSize)
|
|
||||||
// > provides an indication of the approximate size required of Buffer,
|
|
||||||
// > rather than guaranteeing that subsequent calls will return successfully
|
|
||||||
// > if Buffer is set to the size indicated in pSize.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// This is why we allow this DHCPRequestParams to be called several times,
|
|
||||||
// rather than just the two that would be neccessary if we could rely on the
|
|
||||||
// value returned in outBufLen being the true size needed.
|
|
||||||
do {
|
|
||||||
aBuffer.resize(outBufLen);
|
|
||||||
|
|
||||||
winAPIResponse = aWindowsNetworkFunctionsWrapper->DhcpRequestParamsWrapped(
|
|
||||||
DHCPCAPI_REQUEST_SYNCHRONOUS, // Flags
|
|
||||||
nullptr, // Reserved
|
|
||||||
aWideNetworkAdapterName, // Adapter Name
|
|
||||||
nullptr, // not using class id
|
|
||||||
SendParams, // sent parameters
|
|
||||||
RequestParams, // requesting params
|
|
||||||
(PBYTE)aBuffer.data(), // buffer for the output of RequestParams
|
|
||||||
(PULONG)&outBufLen, // buffer size
|
|
||||||
nullptr // Request ID for persistent requests - not needed here
|
|
||||||
);
|
|
||||||
|
|
||||||
if (winAPIResponse == ERROR_MORE_DATA) {
|
|
||||||
iterations++;
|
|
||||||
}
|
|
||||||
} while (winAPIResponse == ERROR_MORE_DATA && iterations < MOZ_MAX_TRIES);
|
|
||||||
return winAPIResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
RetrieveOption(
|
|
||||||
const nsACString& aAdapterName,
|
|
||||||
uint8_t aOption,
|
|
||||||
std::vector<char>& aOptionValueBuf,
|
|
||||||
uint32_t* aOptionSize,
|
|
||||||
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper)
|
|
||||||
{
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
nsAutoString wideNetworkAdapterName = NS_ConvertUTF8toUTF16(aAdapterName);
|
|
||||||
|
|
||||||
DHCPCAPI_PARAMS DhcpRequestedOptionParams = {
|
|
||||||
0, // Flags - Reserved, must be set to zero [2]
|
|
||||||
aOption, // OptionId
|
|
||||||
false, // whether this is vendor specific - let's assume not
|
|
||||||
nullptr, // data filled in on return
|
|
||||||
0 // nBytes used by return data
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<char> tmpBuffer(MOZ_WORKING_BUFFER_SIZE_DHCP_PARAMS); // a buffer for the DHCP response object
|
|
||||||
DWORD winAPIResponse = IterateDHCPInformRequestsUntilBufferLargeEnough(DhcpRequestedOptionParams,
|
|
||||||
wideNetworkAdapterName.get(),
|
|
||||||
tmpBuffer,
|
|
||||||
aWindowsNetworkFunctionsWrapper);
|
|
||||||
|
|
||||||
switch (winAPIResponse){
|
|
||||||
case NO_ERROR:
|
|
||||||
{
|
|
||||||
if (DhcpRequestedOptionParams.nBytesData == 0) {
|
|
||||||
*aOptionSize = 0;
|
|
||||||
rv = NS_ERROR_NOT_AVAILABLE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*aOptionSize >= DhcpRequestedOptionParams.nBytesData) {
|
|
||||||
rv = NS_OK;
|
|
||||||
} else {
|
|
||||||
rv = NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t actualSizeReturned =
|
|
||||||
*aOptionSize > DhcpRequestedOptionParams.nBytesData?
|
|
||||||
DhcpRequestedOptionParams.nBytesData: *aOptionSize;
|
|
||||||
|
|
||||||
memcpy(aOptionValueBuf.data(),
|
|
||||||
DhcpRequestedOptionParams.Data, actualSizeReturned);
|
|
||||||
*aOptionSize = DhcpRequestedOptionParams.nBytesData;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ERROR_INVALID_PARAMETER:
|
|
||||||
MOZ_LOG(gDhcpUtilsLog, mozilla::LogLevel::Warning,
|
|
||||||
("RetrieveOption returned %d (ERROR_INVALID_PARAMETER) when option %d requested",
|
|
||||||
winAPIResponse, aOption));
|
|
||||||
rv = NS_ERROR_INVALID_ARG;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_LOG(gDhcpUtilsLog, mozilla::LogLevel::Warning,
|
|
||||||
("RetrieveOption returned %d when option %d requested", winAPIResponse, aOption));
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace windowsDHCPClient
|
|
||||||
} // namespace system
|
|
||||||
} // namespace toolkit
|
|
||||||
} // namespace mozilla
|
|
|
@ -1,34 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* 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 mozilla_toolkit_system_windowsDHCPClient_DHCPUtils_h
|
|
||||||
#define mozilla_toolkit_system_windowsDHCPClient_DHCPUtils_h
|
|
||||||
|
|
||||||
#include "WindowsNetworkFunctionsWrapper.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace toolkit {
|
|
||||||
namespace system {
|
|
||||||
namespace windowsDHCPClient {
|
|
||||||
|
|
||||||
nsresult GetActiveDHCPNetworkAdapterName(
|
|
||||||
nsACString& aNetworkAdapterName,
|
|
||||||
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper);
|
|
||||||
|
|
||||||
nsresult RetrieveOption(
|
|
||||||
const nsACString& aAdapterName,
|
|
||||||
uint8_t aOption,
|
|
||||||
std::vector<char>& aOptionValueBuf,
|
|
||||||
uint32_t* aOptionSize,
|
|
||||||
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper
|
|
||||||
);
|
|
||||||
|
|
||||||
} // namespace windowsDHCPClient
|
|
||||||
} // namespace system
|
|
||||||
} // namespace toolkit
|
|
||||||
} // namespace mozilla
|
|
||||||
#endif // mozilla_toolkit_system_windowsDHCPClient_DHCPUtils_h
|
|
|
@ -1,46 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* 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 "WindowsNetworkFunctionsWrapper.h"
|
|
||||||
|
|
||||||
|
|
||||||
#pragma comment(lib, "IPHLPAPI.lib")
|
|
||||||
#pragma comment(lib, "dhcpcsvc.lib" )
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace toolkit {
|
|
||||||
namespace system {
|
|
||||||
namespace windowsDHCPClient {
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(WindowsNetworkFunctionsWrapper, nsISupports)
|
|
||||||
|
|
||||||
ULONG WindowsNetworkFunctionsWrapper::GetAdaptersAddressesWrapped(
|
|
||||||
_In_ ULONG aFamily,
|
|
||||||
_In_ ULONG aFlags,
|
|
||||||
_In_ PVOID aReserved,
|
|
||||||
_Inout_ PIP_ADAPTER_ADDRESSES aAdapterAddresses,
|
|
||||||
_Inout_ PULONG aSizePointer)
|
|
||||||
{
|
|
||||||
return GetAdaptersAddresses(aFamily, aFlags, aReserved, aAdapterAddresses, aSizePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WindowsNetworkFunctionsWrapper::DhcpRequestParamsWrapped(
|
|
||||||
_In_ DWORD aFlags,
|
|
||||||
_In_ LPVOID aReserved,
|
|
||||||
_In_ LPWSTR aAdapterName,
|
|
||||||
_In_ LPDHCPCAPI_CLASSID aClassId,
|
|
||||||
_In_ DHCPCAPI_PARAMS_ARRAY aSendParams,
|
|
||||||
_Inout_ DHCPCAPI_PARAMS_ARRAY aRecdParams,
|
|
||||||
_In_ LPBYTE aBuffer,
|
|
||||||
_Inout_ LPDWORD apSize,
|
|
||||||
_In_ LPWSTR aRequestIdStr)
|
|
||||||
{
|
|
||||||
return DhcpRequestParams(aFlags, aReserved, aAdapterName, aClassId, aSendParams, aRecdParams, aBuffer, apSize, aRequestIdStr);
|
|
||||||
}
|
|
||||||
} // namespace windowsDHCPClient
|
|
||||||
} // namespace system
|
|
||||||
} // namespace toolkit
|
|
||||||
} // namespace mozilla
|
|
|
@ -1,60 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* 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 mozilla_toolkit_system_windowsDHCPClient_windowsNetworkFunctionsWrapper_h
|
|
||||||
#define mozilla_toolkit_system_windowsDHCPClient_windowsNetworkFunctionsWrapper_h
|
|
||||||
|
|
||||||
#include <Winsock2.h> // there is a compilation error if Winsock.h is not
|
|
||||||
// declared before dhcpcsdk.h
|
|
||||||
#include <dhcpcsdk.h>
|
|
||||||
#include <iphlpapi.h>
|
|
||||||
|
|
||||||
#include "nsISupports.h"
|
|
||||||
|
|
||||||
// Thin wrapper around low-level network functions needed for DHCP querying for web proxy
|
|
||||||
namespace mozilla {
|
|
||||||
namespace toolkit {
|
|
||||||
namespace system {
|
|
||||||
namespace windowsDHCPClient {
|
|
||||||
|
|
||||||
class WindowsNetworkFunctionsWrapper : nsISupports
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
WindowsNetworkFunctionsWrapper(){};
|
|
||||||
|
|
||||||
virtual ULONG GetAdaptersAddressesWrapped(
|
|
||||||
_In_ ULONG aFamily,
|
|
||||||
_In_ ULONG aFlags,
|
|
||||||
_In_ PVOID aReserved,
|
|
||||||
_Inout_ PIP_ADAPTER_ADDRESSES aAdapterAddresses,
|
|
||||||
_Inout_ PULONG aSizePointer
|
|
||||||
);
|
|
||||||
|
|
||||||
virtual DWORD DhcpRequestParamsWrapped(
|
|
||||||
_In_ DWORD aFlags,
|
|
||||||
_In_ LPVOID aReserved,
|
|
||||||
_In_ LPWSTR aAdapterName,
|
|
||||||
_In_ LPDHCPCAPI_CLASSID aClassId,
|
|
||||||
_In_ DHCPCAPI_PARAMS_ARRAY aSendParams,
|
|
||||||
_Inout_ DHCPCAPI_PARAMS_ARRAY aRecdParams,
|
|
||||||
_In_ LPBYTE aBuffer,
|
|
||||||
_Inout_ LPDWORD apSize,
|
|
||||||
_In_ LPWSTR aRequestIdStr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
~WindowsNetworkFunctionsWrapper(){};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace windowsDHCPClient
|
|
||||||
} // namespace system
|
|
||||||
} // namespace toolkit
|
|
||||||
} // namespace mozilla
|
|
||||||
#endif //mozilla_toolkit_system_windowsDHCPClient_windowsNetworkFunctionsWrapper_h
|
|
|
@ -1,18 +0,0 @@
|
||||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
||||||
# vim: set filetype=python:
|
|
||||||
# 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/.
|
|
||||||
|
|
||||||
with Files('**'):
|
|
||||||
BUG_COMPONENT = ('Core', 'Networking: HTTP')
|
|
||||||
|
|
||||||
TEST_DIRS += ['tests/gtest']
|
|
||||||
|
|
||||||
SOURCES += [
|
|
||||||
'DHCPUtils.cpp',
|
|
||||||
'nsWindowsDHCPClient.cpp',
|
|
||||||
'WindowsNetworkFunctionsWrapper.cpp'
|
|
||||||
]
|
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
|
|
@ -1,103 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* 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 "nsWindowsDHCPClient.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "DHCPUtils.h"
|
|
||||||
#include "nsNetCID.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "mozilla/Logging.h"
|
|
||||||
#include "mozilla/ModuleUtils.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace toolkit {
|
|
||||||
namespace system {
|
|
||||||
namespace windowsDHCPClient {
|
|
||||||
|
|
||||||
LazyLogModule gDhcpLog("windowsDHCPClient");
|
|
||||||
|
|
||||||
#undef LOG
|
|
||||||
#define LOG(args) MOZ_LOG(gDhcpLog, LogLevel::Debug, args)
|
|
||||||
|
|
||||||
#define MOZ_MAX_DHCP_OPTION_LENGTH 255 // this is the maximum option length in DHCP V4 and 6
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(nsWindowsDHCPClient, nsIDHCPClient)
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsWindowsDHCPClient::Init()
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsWindowsDHCPClient::GetOption(uint8_t aOption, nsACString& aRetVal)
|
|
||||||
{
|
|
||||||
nsCString networkAdapterName;
|
|
||||||
nsresult rv;
|
|
||||||
rv = GetActiveDHCPNetworkAdapterName(networkAdapterName, mNetworkFunctions);
|
|
||||||
if (rv != NS_OK) {
|
|
||||||
LOG(("Failed to get network adapter name in nsWindowsDHCPClient::GetOption due to error %d", rv));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t sizeOptionValue = MOZ_MAX_DHCP_OPTION_LENGTH;
|
|
||||||
std::vector<char> optionValue;
|
|
||||||
|
|
||||||
bool retryingAfterLossOfSignificantData = false;
|
|
||||||
do {
|
|
||||||
optionValue.resize(sizeOptionValue);
|
|
||||||
rv = RetrieveOption(networkAdapterName,
|
|
||||||
aOption,
|
|
||||||
optionValue,
|
|
||||||
&sizeOptionValue,
|
|
||||||
mNetworkFunctions);
|
|
||||||
if (rv == NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) {
|
|
||||||
LOG(("In nsWindowsDHCPClient::GetOption, DHCP Option %d required %d bytes", aOption, sizeOptionValue));
|
|
||||||
if (retryingAfterLossOfSignificantData) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
retryingAfterLossOfSignificantData = true;
|
|
||||||
}
|
|
||||||
} while (rv == NS_ERROR_LOSS_OF_SIGNIFICANT_DATA);
|
|
||||||
if (rv != NS_OK) {
|
|
||||||
LOG(("Failed to get DHCP Option %d nsWindowsDHCPClient::GetOption due to error %d", aOption, rv));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
aRetVal.Assign(optionValue.data(), sizeOptionValue);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NS_WINDOWSDHCPCLIENTSERVICE_CID /* {FEBF1D69-4D7D-4891-9524-045AD18B5592} */\
|
|
||||||
{ 0xFEBF1D69, 0x4D7D, 0x4891, \
|
|
||||||
{0x95, 0x24, 0x04, 0x5a, 0xd1, 0x8b, 0x55, 0x92 } }
|
|
||||||
|
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowsDHCPClient, Init)
|
|
||||||
NS_DEFINE_NAMED_CID(NS_WINDOWSDHCPCLIENTSERVICE_CID);
|
|
||||||
|
|
||||||
static const mozilla::Module::CIDEntry kSysDHCPClientCIDs[] = {
|
|
||||||
{ &kNS_WINDOWSDHCPCLIENTSERVICE_CID, false, nullptr, nsWindowsDHCPClientConstructor },
|
|
||||||
{ nullptr }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const mozilla::Module::ContractIDEntry kSysDHCPClientContracts[] = {
|
|
||||||
{ NS_DHCPCLIENT_CONTRACTID, &kNS_WINDOWSDHCPCLIENTSERVICE_CID },
|
|
||||||
{ nullptr }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const mozilla::Module kSysDHCPClientModule = {
|
|
||||||
mozilla::Module::kVersion,
|
|
||||||
kSysDHCPClientCIDs,
|
|
||||||
kSysDHCPClientContracts
|
|
||||||
};
|
|
||||||
|
|
||||||
NSMODULE_DEFN(nsDHCPClientModule) = &kSysDHCPClientModule;
|
|
||||||
|
|
||||||
} // namespace windowsDHCPClient
|
|
||||||
} // namespace system
|
|
||||||
} // namespace toolkit
|
|
||||||
} // namespace mozilla
|
|
|
@ -1,38 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* 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 "nsIDHCPClient.h"
|
|
||||||
#include "nsIServiceManager.h"
|
|
||||||
#include "nsNetCID.h"
|
|
||||||
#include "WindowsNetworkFunctionsWrapper.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace toolkit {
|
|
||||||
namespace system {
|
|
||||||
namespace windowsDHCPClient {
|
|
||||||
|
|
||||||
class nsWindowsDHCPClient final : public nsIDHCPClient
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
NS_DECL_NSIDHCPCLIENT
|
|
||||||
|
|
||||||
explicit nsWindowsDHCPClient(WindowsNetworkFunctionsWrapper *aNetworkFunctions = new WindowsNetworkFunctionsWrapper())
|
|
||||||
: mNetworkFunctions(aNetworkFunctions) {};
|
|
||||||
nsresult Init();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
~nsWindowsDHCPClient() {};
|
|
||||||
WindowsNetworkFunctionsWrapper* mNetworkFunctions;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace windowsDHCPClient
|
|
||||||
} // namespace system
|
|
||||||
} // namespace toolkit
|
|
||||||
} // namespace mozilla
|
|
|
@ -1,323 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* 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 "DHCPUtils.h"
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsWindowsDHCPClient.h"
|
|
||||||
|
|
||||||
using namespace mozilla::toolkit::system::windowsDHCPClient;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WindowsNetworkFunctionsMock : public WindowsNetworkFunctionsWrapper {
|
|
||||||
|
|
||||||
public:
|
|
||||||
WindowsNetworkFunctionsMock():mAddressesToReturn(nullptr) {
|
|
||||||
memset(mOptions, 0, sizeof(char*) * 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ULONG GetAdaptersAddressesWrapped(
|
|
||||||
_In_ ULONG Family,
|
|
||||||
_In_ ULONG Flags,
|
|
||||||
_In_ PVOID Reserved,
|
|
||||||
_Inout_ PIP_ADAPTER_ADDRESSES AdapterAddresses,
|
|
||||||
_Inout_ PULONG SizePointer
|
|
||||||
){
|
|
||||||
if (*SizePointer < sizeof(*mAddressesToReturn)){
|
|
||||||
*SizePointer = sizeof(*mAddressesToReturn);
|
|
||||||
return ERROR_BUFFER_OVERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
*SizePointer = sizeof(*mAddressesToReturn);
|
|
||||||
memcpy(AdapterAddresses, mAddressesToReturn,
|
|
||||||
*SizePointer);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD DhcpRequestParamsWrapped(
|
|
||||||
_In_ DWORD Flags,
|
|
||||||
_In_ LPVOID Reserved,
|
|
||||||
_In_ LPWSTR AdapterName,
|
|
||||||
_In_ LPDHCPCAPI_CLASSID ClassId,
|
|
||||||
_In_ DHCPCAPI_PARAMS_ARRAY SendParams,
|
|
||||||
_Inout_ DHCPCAPI_PARAMS_ARRAY RecdParams,
|
|
||||||
_In_ LPBYTE Buffer,
|
|
||||||
_Inout_ LPDWORD pSize,
|
|
||||||
_In_ LPWSTR RequestIdStr
|
|
||||||
)
|
|
||||||
{
|
|
||||||
mLastRequestedNetworkAdapterName.Assign(AdapterName);
|
|
||||||
|
|
||||||
if (mOptions[RecdParams.Params[0].OptionId] == nullptr) {
|
|
||||||
RecdParams.Params[0].nBytesData = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RecdParams.Params[0].Data = Buffer;
|
|
||||||
size_t lengthOfValue = strlen(mOptions[RecdParams.Params[0].OptionId]);
|
|
||||||
if (*pSize > lengthOfValue) {
|
|
||||||
memcpy(Buffer, mOptions[RecdParams.Params[0].OptionId], lengthOfValue);
|
|
||||||
RecdParams.Params[0].nBytesData = lengthOfValue;
|
|
||||||
} else {
|
|
||||||
*pSize = lengthOfValue;
|
|
||||||
return ERROR_MORE_DATA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AddAdapterAddresses(IP_ADAPTER_ADDRESSES& aAddressesToAdd)
|
|
||||||
{
|
|
||||||
if (mAddressesToReturn == nullptr) {
|
|
||||||
mAddressesToReturn = &aAddressesToAdd;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
IP_ADAPTER_ADDRESSES* tail = mAddressesToReturn;
|
|
||||||
|
|
||||||
while (tail->Next != nullptr) {
|
|
||||||
tail = tail->Next;
|
|
||||||
}
|
|
||||||
tail->Next = &aAddressesToAdd;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetDHCPOption(uint8_t option, char* value)
|
|
||||||
{
|
|
||||||
mOptions[option] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsString
|
|
||||||
GetLastRequestedNetworkAdapterName()
|
|
||||||
{
|
|
||||||
return mLastRequestedNetworkAdapterName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
IP_ADAPTER_ADDRESSES* mAddressesToReturn = nullptr;
|
|
||||||
char* mOptions[256];
|
|
||||||
nsString mLastRequestedNetworkAdapterName;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class TestDHCPUtils : public ::testing::Test {
|
|
||||||
protected:
|
|
||||||
RefPtr<WindowsNetworkFunctionsMock> mMockWindowsFunctions;
|
|
||||||
nsCString mDefaultAdapterName;
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
SetUp()
|
|
||||||
{
|
|
||||||
mMockWindowsFunctions = new WindowsNetworkFunctionsMock();
|
|
||||||
mDefaultAdapterName.AssignLiteral("my favourite network adapter");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Given_DHCP_Option_Is(uint8_t option, char* value)
|
|
||||||
{
|
|
||||||
mMockWindowsFunctions.get()->SetDHCPOption(option, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Given_Network_Adapter_Called(
|
|
||||||
IP_ADAPTER_ADDRESSES& adapterAddresses,
|
|
||||||
char* adapterName)
|
|
||||||
{
|
|
||||||
adapterAddresses.AdapterName = adapterName;
|
|
||||||
adapterAddresses.Next = nullptr;
|
|
||||||
adapterAddresses.Dhcpv4Server.iSockaddrLength = 0;
|
|
||||||
adapterAddresses.Dhcpv6Server.iSockaddrLength = 0;
|
|
||||||
AddAdapterAddresses(adapterAddresses);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Given_Network_Adapter_Supports_DHCP_V4(IP_ADAPTER_ADDRESSES& adapterAddresses)
|
|
||||||
{
|
|
||||||
adapterAddresses.Dhcpv4Server.iSockaddrLength = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Given_Network_Adapter_Supports_DHCP_V6(IP_ADAPTER_ADDRESSES& adapterAddresses)
|
|
||||||
{
|
|
||||||
adapterAddresses.Dhcpv6Server.iSockaddrLength = 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Given_Network_Adapter_Has_Operational_Status(
|
|
||||||
IP_ADAPTER_ADDRESSES& adapterAddresses,
|
|
||||||
IF_OPER_STATUS operStatus)
|
|
||||||
{
|
|
||||||
adapterAddresses.OperStatus = operStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void
|
|
||||||
AddAdapterAddresses(IP_ADAPTER_ADDRESSES& aAddressToAdd)
|
|
||||||
{
|
|
||||||
mMockWindowsFunctions.get()->AddAdapterAddresses(aAddressToAdd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// following class currently just distinguishes tests of nsWindowsDHCPClient from
|
|
||||||
// tests of DHCPUtils.
|
|
||||||
class TestNsWindowsDHCPClient : public TestDHCPUtils { };
|
|
||||||
|
|
||||||
|
|
||||||
TEST_F(TestDHCPUtils, TestGetAdaptersAddresses)
|
|
||||||
{
|
|
||||||
IP_ADAPTER_ADDRESSES adapterAddresses = {};
|
|
||||||
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
|
|
||||||
Given_Network_Adapter_Supports_DHCP_V4(adapterAddresses);
|
|
||||||
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusUp);
|
|
||||||
|
|
||||||
nsCString networkAdapterName;
|
|
||||||
|
|
||||||
ASSERT_EQ(NS_OK, GetActiveDHCPNetworkAdapterName(networkAdapterName, mMockWindowsFunctions));
|
|
||||||
|
|
||||||
ASSERT_STREQ(networkAdapterName.Data(), "my favourite network adapter");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestDHCPUtils, TestGetAdaptersAddressesNoAvailableNetworks)
|
|
||||||
{
|
|
||||||
IP_ADAPTER_ADDRESSES adapterAddresses = {};
|
|
||||||
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
|
|
||||||
Given_Network_Adapter_Supports_DHCP_V4(adapterAddresses);
|
|
||||||
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusDown);
|
|
||||||
|
|
||||||
nsCString networkAdapterName;
|
|
||||||
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, GetActiveDHCPNetworkAdapterName(networkAdapterName, mMockWindowsFunctions));
|
|
||||||
|
|
||||||
ASSERT_STREQ(networkAdapterName.Data(), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestDHCPUtils, TestGetAdaptersAddressesNoNetworksWithDHCP)
|
|
||||||
{
|
|
||||||
IP_ADAPTER_ADDRESSES adapterAddresses = {};
|
|
||||||
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
|
|
||||||
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusUp);
|
|
||||||
|
|
||||||
nsCString networkAdapterName;
|
|
||||||
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, GetActiveDHCPNetworkAdapterName(networkAdapterName, mMockWindowsFunctions));
|
|
||||||
|
|
||||||
ASSERT_STREQ(networkAdapterName.Data(), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestDHCPUtils, TestGetAdaptersAddressesSecondNetworkIsAvailable)
|
|
||||||
{
|
|
||||||
IP_ADAPTER_ADDRESSES adapterAddresses = {};
|
|
||||||
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
|
|
||||||
Given_Network_Adapter_Supports_DHCP_V4(adapterAddresses);
|
|
||||||
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusDown);
|
|
||||||
|
|
||||||
|
|
||||||
IP_ADAPTER_ADDRESSES secondAdapterAddresses = {};
|
|
||||||
Given_Network_Adapter_Called(secondAdapterAddresses, "my second favourite network adapter");
|
|
||||||
Given_Network_Adapter_Supports_DHCP_V6(secondAdapterAddresses);
|
|
||||||
Given_Network_Adapter_Has_Operational_Status(secondAdapterAddresses, IfOperStatusUp);
|
|
||||||
|
|
||||||
nsCString networkAdapterName;
|
|
||||||
ASSERT_EQ(NS_OK, GetActiveDHCPNetworkAdapterName(networkAdapterName, mMockWindowsFunctions));
|
|
||||||
|
|
||||||
ASSERT_STREQ(networkAdapterName.Data(), "my second favourite network adapter");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST_F(TestDHCPUtils, TestGetOption)
|
|
||||||
{
|
|
||||||
|
|
||||||
char* pacURL = "http://pac.com";
|
|
||||||
Given_DHCP_Option_Is(1, "My network option");
|
|
||||||
Given_DHCP_Option_Is(252, pacURL);
|
|
||||||
|
|
||||||
std::vector<char> optionValue(255, *"originalValue originalValue");
|
|
||||||
memcpy(optionValue.data(), "originalValue originalValue", strlen("originalValue originalValue") + 1);
|
|
||||||
|
|
||||||
uint32_t size = 255;
|
|
||||||
|
|
||||||
nsresult retVal = RetrieveOption(mDefaultAdapterName, 252, optionValue, &size, mMockWindowsFunctions);
|
|
||||||
|
|
||||||
ASSERT_EQ(strlen(pacURL), size);
|
|
||||||
ASSERT_STREQ("http://pac.comoriginalValue", optionValue.data());
|
|
||||||
ASSERT_EQ(NS_OK, retVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestDHCPUtils, TestGetAbsentOption)
|
|
||||||
{
|
|
||||||
std::vector<char> optionValue(255);
|
|
||||||
uint32_t size = 256;
|
|
||||||
memcpy(optionValue.data(), "originalValue", strlen("originalValue") + 1);
|
|
||||||
|
|
||||||
nsresult retVal = RetrieveOption(mDefaultAdapterName, 252, optionValue, &size, mMockWindowsFunctions);
|
|
||||||
|
|
||||||
ASSERT_EQ(0, size);
|
|
||||||
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, retVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestDHCPUtils, TestGetTooLongOption)
|
|
||||||
{
|
|
||||||
Given_DHCP_Option_Is(252, "http://pac.com");
|
|
||||||
|
|
||||||
std::vector<char> optionValue(255);
|
|
||||||
memcpy(optionValue.data(), "originalValue", strlen("originalValue") + 1);
|
|
||||||
uint32_t size = 4;
|
|
||||||
nsresult retVal = RetrieveOption(mDefaultAdapterName, 252, optionValue, &size, mMockWindowsFunctions);
|
|
||||||
|
|
||||||
ASSERT_STREQ("httpinalValue", optionValue.data());
|
|
||||||
ASSERT_EQ(NS_ERROR_LOSS_OF_SIGNIFICANT_DATA, retVal);
|
|
||||||
ASSERT_EQ(strlen("http://pac.com"), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestNsWindowsDHCPClient, TestGettingOptionThroughNSWindowsDHCPClient)
|
|
||||||
{
|
|
||||||
IP_ADAPTER_ADDRESSES adapterAddresses = {};
|
|
||||||
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
|
|
||||||
Given_Network_Adapter_Supports_DHCP_V4(adapterAddresses);
|
|
||||||
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusUp);
|
|
||||||
Given_DHCP_Option_Is(252, "http://pac.com");
|
|
||||||
|
|
||||||
nsCString optionValue;
|
|
||||||
nsCOMPtr<nsIDHCPClient> dhcpClient = new nsWindowsDHCPClient(mMockWindowsFunctions);
|
|
||||||
nsresult retVal = dhcpClient->GetOption(252, optionValue);
|
|
||||||
|
|
||||||
ASSERT_STREQ("http://pac.com", optionValue.Data());
|
|
||||||
ASSERT_STREQ(L"my favourite network adapter", mMockWindowsFunctions->GetLastRequestedNetworkAdapterName().Data());
|
|
||||||
ASSERT_EQ(NS_OK, retVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestNsWindowsDHCPClient, TestGettingOptionThroughNSWindowsDHCPClientWhenNoAvailableNetworkAdapter)
|
|
||||||
{
|
|
||||||
IP_ADAPTER_ADDRESSES adapterAddresses = {};
|
|
||||||
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
|
|
||||||
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusDown);
|
|
||||||
Given_DHCP_Option_Is(252, "http://pac.com");
|
|
||||||
|
|
||||||
nsCString optionValue;
|
|
||||||
nsCOMPtr<nsIDHCPClient> dhcpClient = new nsWindowsDHCPClient(mMockWindowsFunctions);
|
|
||||||
nsresult retVal = dhcpClient->GetOption(252, optionValue);
|
|
||||||
|
|
||||||
ASSERT_STREQ("", optionValue.Data());
|
|
||||||
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, retVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestNsWindowsDHCPClient, TestGettingAbsentOptionThroughNSWindowsDHCPClient)
|
|
||||||
{
|
|
||||||
IP_ADAPTER_ADDRESSES adapterAddresses = {};
|
|
||||||
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
|
|
||||||
Given_Network_Adapter_Supports_DHCP_V6(adapterAddresses);
|
|
||||||
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusUp);
|
|
||||||
|
|
||||||
nsCString optionValue;
|
|
||||||
nsCOMPtr<nsIDHCPClient> dhcpClient = new nsWindowsDHCPClient(mMockWindowsFunctions);
|
|
||||||
nsresult retVal = dhcpClient->GetOption(252, optionValue);
|
|
||||||
|
|
||||||
ASSERT_STREQ("", optionValue.Data());
|
|
||||||
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, retVal);
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
||||||
# vim: set filetype=python:
|
|
||||||
# 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/.
|
|
||||||
|
|
||||||
with Files('**'):
|
|
||||||
BUG_COMPONENT = ('Core', 'Networking: HTTP')
|
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
|
||||||
'TestDHCPUtils.cpp',
|
|
||||||
]
|
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
|
||||||
'/toolkit/system/windowsDHCPClient',
|
|
||||||
]
|
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul-gtest'
|
|
||||||
|
|
||||||
if CONFIG['GNU_CXX']:
|
|
||||||
CXXFLAGS += ['-Wshadow']
|
|
Загрузка…
Ссылка в новой задаче