summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/libjingle/source/talk/base
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/libjingle/source/talk/base
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/libjingle/source/talk/base')
-rw-r--r--chromium/third_party/libjingle/source/talk/base/asyncinvoker-inl.h146
-rw-r--r--chromium/third_party/libjingle/source/talk/base/asyncinvoker.cc108
-rw-r--r--chromium/third_party/libjingle/source/talk/base/asyncinvoker.h151
-rw-r--r--chromium/third_party/libjingle/source/talk/base/asyncpacketsocket.h43
-rw-r--r--chromium/third_party/libjingle/source/talk/base/asynctcpsocket.cc11
-rw-r--r--chromium/third_party/libjingle/source/talk/base/asynctcpsocket.h8
-rw-r--r--chromium/third_party/libjingle/source/talk/base/asyncudpsocket.cc8
-rw-r--r--chromium/third_party/libjingle/source/talk/base/asyncudpsocket.h19
-rw-r--r--chromium/third_party/libjingle/source/talk/base/bandwidthsmoother.cc2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/bind.h207
-rw-r--r--chromium/third_party/libjingle/source/talk/base/bind.h.pump30
-rw-r--r--chromium/third_party/libjingle/source/talk/base/bind_unittest.cc10
-rw-r--r--chromium/third_party/libjingle/source/talk/base/buffer.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/bytebuffer.cc5
-rw-r--r--chromium/third_party/libjingle/source/talk/base/byteorder.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/callback.h278
-rw-r--r--chromium/third_party/libjingle/source/talk/base/callback.h.pump120
-rw-r--r--chromium/third_party/libjingle/source/talk/base/callback_unittest.cc98
-rw-r--r--chromium/third_party/libjingle/source/talk/base/common.cc10
-rw-r--r--chromium/third_party/libjingle/source/talk/base/common.h20
-rw-r--r--chromium/third_party/libjingle/source/talk/base/cpumonitor.cc10
-rw-r--r--chromium/third_party/libjingle/source/talk/base/cpumonitor_unittest.cc4
-rw-r--r--chromium/third_party/libjingle/source/talk/base/criticalsection_unittest.cc163
-rw-r--r--chromium/third_party/libjingle/source/talk/base/cryptstring.h4
-rw-r--r--chromium/third_party/libjingle/source/talk/base/event.cc17
-rw-r--r--chromium/third_party/libjingle/source/talk/base/fakesslidentity.h22
-rw-r--r--chromium/third_party/libjingle/source/talk/base/fileutils.cc29
-rw-r--r--chromium/third_party/libjingle/source/talk/base/fileutils.h21
-rw-r--r--chromium/third_party/libjingle/source/talk/base/firewallsocketserver.cc3
-rw-r--r--chromium/third_party/libjingle/source/talk/base/gunit.h7
-rw-r--r--chromium/third_party/libjingle/source/talk/base/helpers.cc26
-rw-r--r--chromium/third_party/libjingle/source/talk/base/helpers_unittest.cc22
-rw-r--r--chromium/third_party/libjingle/source/talk/base/httpserver_unittest.cc6
-rw-r--r--chromium/third_party/libjingle/source/talk/base/iosfilesystem.mm70
-rw-r--r--chromium/third_party/libjingle/source/talk/base/ipaddress.cc4
-rw-r--r--chromium/third_party/libjingle/source/talk/base/ipaddress_unittest.cc12
-rw-r--r--chromium/third_party/libjingle/source/talk/base/json.cc4
-rw-r--r--chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.cc.def13
-rw-r--r--chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.h.def1
-rw-r--r--chromium/third_party/libjingle/source/talk/base/linux.cc83
-rw-r--r--chromium/third_party/libjingle/source/talk/base/linux.h5
-rw-r--r--chromium/third_party/libjingle/source/talk/base/linux_unittest.cc8
-rw-r--r--chromium/third_party/libjingle/source/talk/base/logging.cc5
-rw-r--r--chromium/third_party/libjingle/source/talk/base/logging.h7
-rw-r--r--chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.mm63
-rw-r--r--chromium/third_party/libjingle/source/talk/base/messagedigest.cc13
-rw-r--r--chromium/third_party/libjingle/source/talk/base/messagedigest.h3
-rw-r--r--chromium/third_party/libjingle/source/talk/base/messagehandler.h34
-rw-r--r--chromium/third_party/libjingle/source/talk/base/messagequeue.cc28
-rw-r--r--chromium/third_party/libjingle/source/talk/base/messagequeue.h9
-rw-r--r--chromium/third_party/libjingle/source/talk/base/natserver.cc9
-rw-r--r--chromium/third_party/libjingle/source/talk/base/natsocketfactory.cc8
-rw-r--r--chromium/third_party/libjingle/source/talk/base/nattypes.cc2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/nethelpers.cc9
-rw-r--r--chromium/third_party/libjingle/source/talk/base/nethelpers.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/network.cc119
-rw-r--r--chromium/third_party/libjingle/source/talk/base/network.h39
-rw-r--r--chromium/third_party/libjingle/source/talk/base/network_unittest.cc45
-rw-r--r--chromium/third_party/libjingle/source/talk/base/nssidentity.cc97
-rw-r--r--chromium/third_party/libjingle/source/talk/base/nssidentity.h16
-rw-r--r--chromium/third_party/libjingle/source/talk/base/nssstreamadapter.cc90
-rw-r--r--chromium/third_party/libjingle/source/talk/base/nssstreamadapter.h3
-rw-r--r--chromium/third_party/libjingle/source/talk/base/openssl.h37
-rw-r--r--chromium/third_party/libjingle/source/talk/base/openssladapter.cc14
-rw-r--r--chromium/third_party/libjingle/source/talk/base/openssldigest.cc5
-rw-r--r--chromium/third_party/libjingle/source/talk/base/opensslidentity.cc85
-rw-r--r--chromium/third_party/libjingle/source/talk/base/opensslidentity.h22
-rw-r--r--chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.cc155
-rw-r--r--chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.h16
-rw-r--r--chromium/third_party/libjingle/source/talk/base/optionsfile_unittest.cc209
-rw-r--r--chromium/third_party/libjingle/source/talk/base/physicalsocketserver.cc44
-rw-r--r--chromium/third_party/libjingle/source/talk/base/physicalsocketserver.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/physicalsocketserver_unittest.cc13
-rw-r--r--chromium/third_party/libjingle/source/talk/base/profiler.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/profiler_unittest.cc8
-rw-r--r--chromium/third_party/libjingle/source/talk/base/proxydetect.cc30
-rw-r--r--chromium/third_party/libjingle/source/talk/base/proxydetect_unittest.cc1
-rw-r--r--chromium/third_party/libjingle/source/talk/base/refcount.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h82
-rw-r--r--chromium/third_party/libjingle/source/talk/base/rollingaccumulator_unittest.cc63
-rw-r--r--chromium/third_party/libjingle/source/talk/base/safe_conversions.h96
-rw-r--r--chromium/third_party/libjingle/source/talk/base/safe_conversions_impl.h205
-rw-r--r--chromium/third_party/libjingle/source/talk/base/scoped_ptr.h4
-rw-r--r--chromium/third_party/libjingle/source/talk/base/scoped_ref_ptr.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/scopedptrcollection.h77
-rw-r--r--chromium/third_party/libjingle/source/talk/base/scopedptrcollection_unittest.cc90
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sharedexclusivelock_unittest.cc3
-rw-r--r--chromium/third_party/libjingle/source/talk/base/signalthread_unittest.cc6
-rwxr-xr-xchromium/third_party/libjingle/source/talk/base/sigslottester.h216
-rwxr-xr-xchromium/third_party/libjingle/source/talk/base/sigslottester.h.pump102
-rwxr-xr-xchromium/third_party/libjingle/source/talk/base/sigslottester_unittest.cc74
-rw-r--r--chromium/third_party/libjingle/source/talk/base/socket.h19
-rw-r--r--chromium/third_party/libjingle/source/talk/base/socket_unittest.cc4
-rw-r--r--chromium/third_party/libjingle/source/talk/base/socketaddress.cc2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sslfingerprint.cc114
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sslfingerprint.h74
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sslidentity.cc12
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sslidentity.h20
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sslidentity_unittest.cc45
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sslstreamadapter.h33
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sslstreamadapter_unittest.cc136
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.cc7
-rw-r--r--chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.h11
-rw-r--r--chromium/third_party/libjingle/source/talk/base/stream.cc4
-rw-r--r--chromium/third_party/libjingle/source/talk/base/stream.h7
-rw-r--r--chromium/third_party/libjingle/source/talk/base/stringencode.cc4
-rw-r--r--chromium/third_party/libjingle/source/talk/base/stringutils.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/template_util.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/testclient.cc9
-rw-r--r--chromium/third_party/libjingle/source/talk/base/testechoserver.h3
-rw-r--r--chromium/third_party/libjingle/source/talk/base/testutils.h37
-rw-r--r--chromium/third_party/libjingle/source/talk/base/thread.cc42
-rw-r--r--chromium/third_party/libjingle/source/talk/base/thread.h54
-rw-r--r--chromium/third_party/libjingle/source/talk/base/thread_unittest.cc191
-rw-r--r--chromium/third_party/libjingle/source/talk/base/timeutils.cc21
-rw-r--r--chromium/third_party/libjingle/source/talk/base/timeutils.h11
-rw-r--r--chromium/third_party/libjingle/source/talk/base/timeutils_unittest.cc23
-rw-r--r--chromium/third_party/libjingle/source/talk/base/transformadapter.cc2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/unittest_main.cc23
-rw-r--r--chromium/third_party/libjingle/source/talk/base/unixfilesystem.cc61
-rw-r--r--chromium/third_party/libjingle/source/talk/base/unixfilesystem.h14
-rw-r--r--chromium/third_party/libjingle/source/talk/base/versionparsing.cc2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/virtualsocket_unittest.cc9
-rw-r--r--chromium/third_party/libjingle/source/talk/base/virtualsocketserver.cc10
-rw-r--r--chromium/third_party/libjingle/source/talk/base/virtualsocketserver.h3
-rw-r--r--chromium/third_party/libjingle/source/talk/base/win32regkey.cc60
-rw-r--r--chromium/third_party/libjingle/source/talk/base/win32toolhelp_unittest.cc1
-rw-r--r--chromium/third_party/libjingle/source/talk/base/windowpickerfactory.h2
-rw-r--r--chromium/third_party/libjingle/source/talk/base/winping.cc2
130 files changed, 4147 insertions, 1009 deletions
diff --git a/chromium/third_party/libjingle/source/talk/base/asyncinvoker-inl.h b/chromium/third_party/libjingle/source/talk/base/asyncinvoker-inl.h
new file mode 100644
index 00000000000..b6be1750453
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/asyncinvoker-inl.h
@@ -0,0 +1,146 @@
+/*
+ * libjingle
+ * Copyright 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TALK_BASE_ASYNCINVOKER_INL_H_
+#define TALK_BASE_ASYNCINVOKER_INL_H_
+
+#include "talk/base/bind.h"
+#include "talk/base/callback.h"
+#include "talk/base/criticalsection.h"
+#include "talk/base/messagehandler.h"
+#include "talk/base/refcount.h"
+#include "talk/base/scoped_ref_ptr.h"
+#include "talk/base/sigslot.h"
+#include "talk/base/thread.h"
+
+namespace talk_base {
+
+class AsyncInvoker;
+
+// Helper class for AsyncInvoker. Runs a task and triggers a callback
+// on the calling thread if necessary. Instances are ref-counted so their
+// lifetime can be independent of AsyncInvoker.
+class AsyncClosure : public RefCountInterface {
+ public:
+ virtual ~AsyncClosure() {}
+ // Runs the asynchronous task, and triggers a callback to the calling
+ // thread if needed. Should be called from the target thread.
+ virtual void Execute() = 0;
+};
+
+// Simple closure that doesn't trigger a callback for the calling thread.
+template <class FunctorT>
+class FireAndForgetAsyncClosure : public AsyncClosure {
+ public:
+ explicit FireAndForgetAsyncClosure(const FunctorT& functor)
+ : functor_(functor) {}
+ virtual void Execute() {
+ functor_();
+ }
+ private:
+ FunctorT functor_;
+};
+
+// Base class for closures that may trigger a callback for the calling thread.
+// Listens for the "destroyed" signals from the calling thread and the invoker,
+// and cancels the callback to the calling thread if either is destroyed.
+class NotifyingAsyncClosureBase : public AsyncClosure,
+ public sigslot::has_slots<> {
+ public:
+ virtual ~NotifyingAsyncClosureBase() { disconnect_all(); }
+
+ protected:
+ NotifyingAsyncClosureBase(AsyncInvoker* invoker, Thread* calling_thread);
+ void TriggerCallback();
+ void SetCallback(const Callback0<void>& callback) {
+ CritScope cs(&crit_);
+ callback_ = callback;
+ }
+ bool CallbackCanceled() const { return calling_thread_ == NULL; }
+
+ private:
+ Callback0<void> callback_;
+ CriticalSection crit_;
+ AsyncInvoker* invoker_;
+ Thread* calling_thread_;
+
+ void CancelCallback();
+};
+
+// Closures that have a non-void return value and require a callback.
+template <class ReturnT, class FunctorT, class HostT>
+class NotifyingAsyncClosure : public NotifyingAsyncClosureBase {
+ public:
+ NotifyingAsyncClosure(AsyncInvoker* invoker,
+ Thread* calling_thread,
+ const FunctorT& functor,
+ void (HostT::*callback)(ReturnT),
+ HostT* callback_host)
+ : NotifyingAsyncClosureBase(invoker, calling_thread),
+ functor_(functor),
+ callback_(callback),
+ callback_host_(callback_host) {}
+ virtual void Execute() {
+ ReturnT result = functor_();
+ if (!CallbackCanceled()) {
+ SetCallback(Callback0<void>(Bind(callback_, callback_host_, result)));
+ TriggerCallback();
+ }
+ }
+
+ private:
+ FunctorT functor_;
+ void (HostT::*callback_)(ReturnT);
+ HostT* callback_host_;
+};
+
+// Closures that have a void return value and require a callback.
+template <class FunctorT, class HostT>
+class NotifyingAsyncClosure<void, FunctorT, HostT>
+ : public NotifyingAsyncClosureBase {
+ public:
+ NotifyingAsyncClosure(AsyncInvoker* invoker,
+ Thread* calling_thread,
+ const FunctorT& functor,
+ void (HostT::*callback)(),
+ HostT* callback_host)
+ : NotifyingAsyncClosureBase(invoker, calling_thread),
+ functor_(functor) {
+ SetCallback(Callback0<void>(Bind(callback, callback_host)));
+ }
+ virtual void Execute() {
+ functor_();
+ TriggerCallback();
+ }
+
+ private:
+ FunctorT functor_;
+};
+
+} // namespace talk_base
+
+#endif // TALK_BASE_ASYNCINVOKER_INL_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/asyncinvoker.cc b/chromium/third_party/libjingle/source/talk/base/asyncinvoker.cc
new file mode 100644
index 00000000000..a57eb7b962d
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/asyncinvoker.cc
@@ -0,0 +1,108 @@
+/*
+ * libjingle
+ * Copyright 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/base/asyncinvoker.h"
+
+namespace talk_base {
+
+AsyncInvoker::AsyncInvoker() : destroying_(false) {}
+
+AsyncInvoker::~AsyncInvoker() {
+ destroying_ = true;
+ SignalInvokerDestroyed();
+ // Messages for this need to be cleared *before* our destructor is complete.
+ MessageQueueManager::Clear(this);
+}
+
+void AsyncInvoker::OnMessage(Message* msg) {
+ // Get the AsyncClosure shared ptr from this message's data.
+ ScopedRefMessageData<AsyncClosure>* data =
+ static_cast<ScopedRefMessageData<AsyncClosure>*>(msg->pdata);
+ scoped_refptr<AsyncClosure> closure = data->data();
+ delete msg->pdata;
+ msg->pdata = NULL;
+
+ // Execute the closure and trigger the return message if needed.
+ closure->Execute();
+}
+
+void AsyncInvoker::Flush(Thread* thread, uint32 id /*= MQID_ANY*/) {
+ if (destroying_) return;
+
+ // Run this on |thread| to reduce the number of context switches.
+ if (Thread::Current() != thread) {
+ thread->Invoke<void>(Bind(&AsyncInvoker::Flush, this, thread, id));
+ return;
+ }
+
+ MessageList removed;
+ thread->Clear(this, id, &removed);
+ for (MessageList::iterator it = removed.begin(); it != removed.end(); ++it) {
+ // This message was pending on this thread, so run it now.
+ thread->Send(it->phandler,
+ it->message_id,
+ it->pdata);
+ }
+}
+
+void AsyncInvoker::DoInvoke(Thread* thread, AsyncClosure* closure,
+ uint32 id) {
+ if (destroying_) {
+ LOG(LS_WARNING) << "Tried to invoke while destroying the invoker.";
+ // Since this call transwers ownership of |closure|, we clean it up here.
+ delete closure;
+ return;
+ }
+ thread->Post(this, id, new ScopedRefMessageData<AsyncClosure>(closure));
+}
+
+NotifyingAsyncClosureBase::NotifyingAsyncClosureBase(AsyncInvoker* invoker,
+ Thread* calling_thread)
+ : invoker_(invoker), calling_thread_(calling_thread) {
+ calling_thread->SignalQueueDestroyed.connect(
+ this, &NotifyingAsyncClosureBase::CancelCallback);
+ invoker->SignalInvokerDestroyed.connect(
+ this, &NotifyingAsyncClosureBase::CancelCallback);
+}
+
+void NotifyingAsyncClosureBase::TriggerCallback() {
+ CritScope cs(&crit_);
+ if (!CallbackCanceled() && !callback_.empty()) {
+ invoker_->AsyncInvoke<void>(calling_thread_, callback_);
+ }
+}
+
+void NotifyingAsyncClosureBase::CancelCallback() {
+ // If the callback is triggering when this is called, block the
+ // destructor of the dying object here by waiting until the callback
+ // is done triggering.
+ CritScope cs(&crit_);
+ // calling_thread_ == NULL means do not trigger the callback.
+ calling_thread_ = NULL;
+}
+
+} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/asyncinvoker.h b/chromium/third_party/libjingle/source/talk/base/asyncinvoker.h
new file mode 100644
index 00000000000..b7dfac98381
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/asyncinvoker.h
@@ -0,0 +1,151 @@
+/*
+ * libjingle
+ * Copyright 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TALK_BASE_ASYNCINVOKER_H_
+#define TALK_BASE_ASYNCINVOKER_H_
+
+#include "talk/base/asyncinvoker-inl.h"
+#include "talk/base/bind.h"
+#include "talk/base/sigslot.h"
+#include "talk/base/scopedptrcollection.h"
+#include "talk/base/thread.h"
+
+namespace talk_base {
+
+// Invokes function objects (aka functors) asynchronously on a Thread, and
+// owns the lifetime of calls (ie, when this object is destroyed, calls in
+// flight are cancelled). AsyncInvoker can optionally execute a user-specified
+// function when the asynchronous call is complete, or operates in
+// fire-and-forget mode otherwise.
+//
+// AsyncInvoker does not own the thread it calls functors on.
+//
+// A note about async calls and object lifetimes: users should
+// be mindful of object lifetimes when calling functions asynchronously and
+// ensure objects used by the function _cannot_ be deleted between the
+// invocation and execution of the functor. AsyncInvoker is designed to
+// help: any calls in flight will be cancelled when the AsyncInvoker used to
+// make the call is destructed, and any calls executing will be allowed to
+// complete before AsyncInvoker destructs.
+//
+// The easiest way to ensure lifetimes are handled correctly is to create a
+// class that owns the Thread and AsyncInvoker objects, and then call its
+// methods asynchronously as needed.
+//
+// Example:
+// class MyClass {
+// public:
+// void FireAsyncTaskWithResult(Thread* thread, int x) {
+// // Specify a callback to get the result upon completion.
+// invoker_.AsyncInvoke<int>(
+// thread, Bind(&MyClass::AsyncTaskWithResult, this, x),
+// &MyClass::OnTaskComplete, this);
+// }
+// void FireAnotherAsyncTask(Thread* thread) {
+// // No callback specified means fire-and-forget.
+// invoker_.AsyncInvoke<void>(
+// thread, Bind(&MyClass::AnotherAsyncTask, this));
+//
+// private:
+// int AsyncTaskWithResult(int x) {
+// // Some long running process...
+// return x * x;
+// }
+// void AnotherAsyncTask() {
+// // Some other long running process...
+// }
+// void OnTaskComplete(int result) { result_ = result; }
+//
+// AsyncInvoker invoker_;
+// int result_;
+// };
+class AsyncInvoker : public MessageHandler {
+ public:
+ AsyncInvoker();
+ virtual ~AsyncInvoker();
+
+ // Call |functor| asynchronously on |thread|, with no callback upon
+ // completion. Returns immediately.
+ template <class ReturnT, class FunctorT>
+ void AsyncInvoke(Thread* thread,
+ const FunctorT& functor,
+ uint32 id = 0) {
+ AsyncClosure* closure =
+ new RefCountedObject<FireAndForgetAsyncClosure<FunctorT> >(functor);
+ DoInvoke(thread, closure, id);
+ }
+
+ // Call |functor| asynchronously on |thread|, calling |callback| when done.
+ template <class ReturnT, class FunctorT, class HostT>
+ void AsyncInvoke(Thread* thread,
+ const FunctorT& functor,
+ void (HostT::*callback)(ReturnT),
+ HostT* callback_host,
+ uint32 id = 0) {
+ AsyncClosure* closure =
+ new RefCountedObject<NotifyingAsyncClosure<ReturnT, FunctorT, HostT> >(
+ this, Thread::Current(), functor, callback, callback_host);
+ DoInvoke(thread, closure, id);
+ }
+
+ // Call |functor| asynchronously on |thread|, calling |callback| when done.
+ // Overloaded for void return.
+ template <class ReturnT, class FunctorT, class HostT>
+ void AsyncInvoke(Thread* thread,
+ const FunctorT& functor,
+ void (HostT::*callback)(),
+ HostT* callback_host,
+ uint32 id = 0) {
+ AsyncClosure* closure =
+ new RefCountedObject<NotifyingAsyncClosure<void, FunctorT, HostT> >(
+ this, Thread::Current(), functor, callback, callback_host);
+ DoInvoke(thread, closure, id);
+ }
+
+ // Synchronously execute on |thread| all outstanding calls we own
+ // that are pending on |thread|, and wait for calls to complete
+ // before returning. Optionally filter by message id.
+ // The destructor will not wait for outstanding calls, so if that
+ // behavior is desired, call Flush() before destroying this object.
+ void Flush(Thread* thread, uint32 id = MQID_ANY);
+
+ // Signaled when this object is destructed.
+ sigslot::signal0<> SignalInvokerDestroyed;
+
+ private:
+ virtual void OnMessage(Message* msg);
+ void DoInvoke(Thread* thread, AsyncClosure* closure, uint32 id);
+
+ bool destroying_;
+
+ DISALLOW_COPY_AND_ASSIGN(AsyncInvoker);
+};
+
+} // namespace talk_base
+
+
+#endif // TALK_BASE_ASYNCINVOKER_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/asyncpacketsocket.h b/chromium/third_party/libjingle/source/talk/base/asyncpacketsocket.h
index 29ab55ffc47..091f1d0fe71 100644
--- a/chromium/third_party/libjingle/source/talk/base/asyncpacketsocket.h
+++ b/chromium/third_party/libjingle/source/talk/base/asyncpacketsocket.h
@@ -2,26 +2,26 @@
* libjingle
* Copyright 2004--2005, Google Inc.
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * 1. Redistributions of source code must retain the above copyright notice,
+ * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -35,6 +35,31 @@
namespace talk_base {
+// This structure holds the info needed to update the packet send time header
+// extension, including the information needed to update the authentication tag
+// after changing the value.
+struct PacketTimeUpdateParams {
+ PacketTimeUpdateParams()
+ : rtp_sendtime_extension_id(-1), srtp_auth_tag_len(-1),
+ srtp_packet_index(-1) {
+ }
+
+ int rtp_sendtime_extension_id; // extension header id present in packet.
+ std::vector<char> srtp_auth_key; // Authentication key.
+ int srtp_auth_tag_len; // Authentication tag length.
+ int64 srtp_packet_index; // Required for Rtp Packet authentication.
+};
+
+// This structure holds meta information for the packet which is about to send
+// over network.
+struct PacketOptions {
+ PacketOptions() : dscp(DSCP_NO_CHANGE) {}
+ explicit PacketOptions(DiffServCodePoint dscp) : dscp(dscp) {}
+
+ DiffServCodePoint dscp;
+ PacketTimeUpdateParams packet_time_params;
+};
+
// This structure will have the information about when packet is actually
// received by socket.
struct PacketTime {
@@ -78,9 +103,9 @@ class AsyncPacketSocket : public sigslot::has_slots<> {
virtual SocketAddress GetRemoteAddress() const = 0;
// Send a packet.
- virtual int Send(const void *pv, size_t cb, DiffServCodePoint dscp) = 0;
+ virtual int Send(const void *pv, size_t cb, const PacketOptions& options) = 0;
virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
- DiffServCodePoint) = 0;
+ const PacketOptions& options) = 0;
// Close the socket.
virtual int Close() = 0;
diff --git a/chromium/third_party/libjingle/source/talk/base/asynctcpsocket.cc b/chromium/third_party/libjingle/source/talk/base/asynctcpsocket.cc
index d2ae513fd57..781fb0adee4 100644
--- a/chromium/third_party/libjingle/source/talk/base/asynctcpsocket.cc
+++ b/chromium/third_party/libjingle/source/talk/base/asynctcpsocket.cc
@@ -27,7 +27,7 @@
#include "talk/base/asynctcpsocket.h"
-#include <cstring>
+#include <string.h>
#include "talk/base/byteorder.h"
#include "talk/base/common.h"
@@ -141,12 +141,11 @@ void AsyncTCPSocketBase::SetError(int error) {
return socket_->SetError(error);
}
-// TODO(mallinath) - Add support of setting DSCP code on AsyncSocket.
int AsyncTCPSocketBase::SendTo(const void *pv, size_t cb,
const SocketAddress& addr,
- DiffServCodePoint dscp) {
+ const talk_base::PacketOptions& options) {
if (addr == GetRemoteAddress())
- return Send(pv, cb, dscp);
+ return Send(pv, cb, options);
ASSERT(false);
socket_->SetError(ENOTCONN);
@@ -263,8 +262,8 @@ AsyncTCPSocket::AsyncTCPSocket(AsyncSocket* socket, bool listen)
: AsyncTCPSocketBase(socket, listen, kBufSize) {
}
-// TODO(mallinath) - Add support of setting DSCP code on AsyncSocket.
-int AsyncTCPSocket::Send(const void *pv, size_t cb, DiffServCodePoint dscp) {
+int AsyncTCPSocket::Send(const void *pv, size_t cb,
+ const talk_base::PacketOptions& options) {
if (cb > kBufSize) {
SetError(EMSGSIZE);
return -1;
diff --git a/chromium/third_party/libjingle/source/talk/base/asynctcpsocket.h b/chromium/third_party/libjingle/source/talk/base/asynctcpsocket.h
index a0e7a7e2f41..2b795f64f9e 100644
--- a/chromium/third_party/libjingle/source/talk/base/asynctcpsocket.h
+++ b/chromium/third_party/libjingle/source/talk/base/asynctcpsocket.h
@@ -43,7 +43,8 @@ class AsyncTCPSocketBase : public AsyncPacketSocket {
virtual ~AsyncTCPSocketBase();
// Pure virtual methods to send and recv data.
- virtual int Send(const void *pv, size_t cb, DiffServCodePoint dscp) = 0;
+ virtual int Send(const void *pv, size_t cb,
+ const talk_base::PacketOptions& options) = 0;
virtual void ProcessInput(char* data, size_t* len) = 0;
// Signals incoming connection.
virtual void HandleIncomingConnection(AsyncSocket* socket) = 0;
@@ -51,7 +52,7 @@ class AsyncTCPSocketBase : public AsyncPacketSocket {
virtual SocketAddress GetLocalAddress() const;
virtual SocketAddress GetRemoteAddress() const;
virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
- DiffServCodePoint dscp);
+ const talk_base::PacketOptions& options);
virtual int Close();
virtual State GetState() const;
@@ -102,7 +103,8 @@ class AsyncTCPSocket : public AsyncTCPSocketBase {
AsyncTCPSocket(AsyncSocket* socket, bool listen);
virtual ~AsyncTCPSocket() {}
- virtual int Send(const void* pv, size_t cb, DiffServCodePoint dscp);
+ virtual int Send(const void* pv, size_t cb,
+ const talk_base::PacketOptions& options);
virtual void ProcessInput(char* data, size_t* len);
virtual void HandleIncomingConnection(AsyncSocket* socket);
diff --git a/chromium/third_party/libjingle/source/talk/base/asyncudpsocket.cc b/chromium/third_party/libjingle/source/talk/base/asyncudpsocket.cc
index 50052630d99..367287f800d 100644
--- a/chromium/third_party/libjingle/source/talk/base/asyncudpsocket.cc
+++ b/chromium/third_party/libjingle/source/talk/base/asyncudpsocket.cc
@@ -75,14 +75,14 @@ SocketAddress AsyncUDPSocket::GetRemoteAddress() const {
return socket_->GetRemoteAddress();
}
-// TODO(mallinath) - Add support of setting DSCP code on AsyncSocket.
-int AsyncUDPSocket::Send(const void *pv, size_t cb, DiffServCodePoint dscp) {
+int AsyncUDPSocket::Send(const void *pv, size_t cb,
+ const talk_base::PacketOptions& options) {
return socket_->Send(pv, cb);
}
-// TODO(mallinath) - Add support of setting DSCP code on AsyncSocket.
int AsyncUDPSocket::SendTo(const void *pv, size_t cb,
- const SocketAddress& addr, DiffServCodePoint dscp) {
+ const SocketAddress& addr,
+ const talk_base::PacketOptions& options) {
return socket_->SendTo(pv, cb, addr);
}
diff --git a/chromium/third_party/libjingle/source/talk/base/asyncudpsocket.h b/chromium/third_party/libjingle/source/talk/base/asyncudpsocket.h
index 17e12a26c31..17fb043a39e 100644
--- a/chromium/third_party/libjingle/source/talk/base/asyncudpsocket.h
+++ b/chromium/third_party/libjingle/source/talk/base/asyncudpsocket.h
@@ -2,26 +2,26 @@
* libjingle
* Copyright 2004--2005, Google Inc.
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * 1. Redistributions of source code must retain the above copyright notice,
+ * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -52,9 +52,10 @@ class AsyncUDPSocket : public AsyncPacketSocket {
virtual SocketAddress GetLocalAddress() const;
virtual SocketAddress GetRemoteAddress() const;
- virtual int Send(const void *pv, size_t cb, DiffServCodePoint dscp);
+ virtual int Send(const void *pv, size_t cb,
+ const talk_base::PacketOptions& options);
virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
- DiffServCodePoint dscp);
+ const talk_base::PacketOptions& options);
virtual int Close();
virtual State GetState() const;
diff --git a/chromium/third_party/libjingle/source/talk/base/bandwidthsmoother.cc b/chromium/third_party/libjingle/source/talk/base/bandwidthsmoother.cc
index 39164884d40..edb4edab743 100644
--- a/chromium/third_party/libjingle/source/talk/base/bandwidthsmoother.cc
+++ b/chromium/third_party/libjingle/source/talk/base/bandwidthsmoother.cc
@@ -62,7 +62,7 @@ bool BandwidthSmoother::Sample(uint32 sample_time, int bandwidth) {
}
// Replace bandwidth with the mean of sampled bandwidths.
- const int mean_bandwidth = accumulator_.ComputeMean();
+ const int mean_bandwidth = static_cast<int>(accumulator_.ComputeMean());
if (mean_bandwidth < bandwidth_estimation_) {
time_at_last_change_ = sample_time;
diff --git a/chromium/third_party/libjingle/source/talk/base/bind.h b/chromium/third_party/libjingle/source/talk/base/bind.h
index 622cc679db1..5b4eaac943b 100644
--- a/chromium/third_party/libjingle/source/talk/base/bind.h
+++ b/chromium/third_party/libjingle/source/talk/base/bind.h
@@ -84,6 +84,18 @@ class MethodFunctor0 {
ObjectT* object_;
};
+template <class FunctorT, class R>
+class Functor0 {
+ public:
+ explicit Functor0(const FunctorT& functor)
+ : functor_(functor) {}
+ R operator()() const {
+ return functor_(); }
+ private:
+ FunctorT functor_;
+};
+
+
#define FP_T(x) R (ObjectT::*x)()
template <class ObjectT, class R>
@@ -104,6 +116,16 @@ Bind(FP_T(method), const ObjectT* object) {
}
#undef FP_T
+#define FP_T(x) R (*x)()
+
+template <class R>
+Functor0<FP_T(NONAME), R>
+Bind(FP_T(function)) {
+ return Functor0<FP_T(NONAME), R>(
+ function);
+}
+
+#undef FP_T
template <class ObjectT, class MethodT, class R,
class P1>
@@ -121,6 +143,21 @@ class MethodFunctor1 {
P1 p1_;
};
+template <class FunctorT, class R,
+ class P1>
+class Functor1 {
+ public:
+ Functor1(const FunctorT& functor, P1 p1)
+ : functor_(functor),
+ p1_(p1) {}
+ R operator()() const {
+ return functor_(p1_); }
+ private:
+ FunctorT functor_;
+ P1 p1_;
+};
+
+
#define FP_T(x) R (ObjectT::*x)(P1)
template <class ObjectT, class R,
@@ -145,6 +182,18 @@ Bind(FP_T(method), const ObjectT* object,
}
#undef FP_T
+#define FP_T(x) R (*x)(P1)
+
+template <class R,
+ class P1>
+Functor1<FP_T(NONAME), R, P1>
+Bind(FP_T(function),
+ typename detail::identity<P1>::type p1) {
+ return Functor1<FP_T(NONAME), R, P1>(
+ function, p1);
+}
+
+#undef FP_T
template <class ObjectT, class MethodT, class R,
class P1,
@@ -166,6 +215,24 @@ class MethodFunctor2 {
P2 p2_;
};
+template <class FunctorT, class R,
+ class P1,
+ class P2>
+class Functor2 {
+ public:
+ Functor2(const FunctorT& functor, P1 p1, P2 p2)
+ : functor_(functor),
+ p1_(p1),
+ p2_(p2) {}
+ R operator()() const {
+ return functor_(p1_, p2_); }
+ private:
+ FunctorT functor_;
+ P1 p1_;
+ P2 p2_;
+};
+
+
#define FP_T(x) R (ObjectT::*x)(P1, P2)
template <class ObjectT, class R,
@@ -194,6 +261,20 @@ Bind(FP_T(method), const ObjectT* object,
}
#undef FP_T
+#define FP_T(x) R (*x)(P1, P2)
+
+template <class R,
+ class P1,
+ class P2>
+Functor2<FP_T(NONAME), R, P1, P2>
+Bind(FP_T(function),
+ typename detail::identity<P1>::type p1,
+ typename detail::identity<P2>::type p2) {
+ return Functor2<FP_T(NONAME), R, P1, P2>(
+ function, p1, p2);
+}
+
+#undef FP_T
template <class ObjectT, class MethodT, class R,
class P1,
@@ -219,6 +300,27 @@ class MethodFunctor3 {
P3 p3_;
};
+template <class FunctorT, class R,
+ class P1,
+ class P2,
+ class P3>
+class Functor3 {
+ public:
+ Functor3(const FunctorT& functor, P1 p1, P2 p2, P3 p3)
+ : functor_(functor),
+ p1_(p1),
+ p2_(p2),
+ p3_(p3) {}
+ R operator()() const {
+ return functor_(p1_, p2_, p3_); }
+ private:
+ FunctorT functor_;
+ P1 p1_;
+ P2 p2_;
+ P3 p3_;
+};
+
+
#define FP_T(x) R (ObjectT::*x)(P1, P2, P3)
template <class ObjectT, class R,
@@ -251,6 +353,22 @@ Bind(FP_T(method), const ObjectT* object,
}
#undef FP_T
+#define FP_T(x) R (*x)(P1, P2, P3)
+
+template <class R,
+ class P1,
+ class P2,
+ class P3>
+Functor3<FP_T(NONAME), R, P1, P2, P3>
+Bind(FP_T(function),
+ typename detail::identity<P1>::type p1,
+ typename detail::identity<P2>::type p2,
+ typename detail::identity<P3>::type p3) {
+ return Functor3<FP_T(NONAME), R, P1, P2, P3>(
+ function, p1, p2, p3);
+}
+
+#undef FP_T
template <class ObjectT, class MethodT, class R,
class P1,
@@ -280,6 +398,30 @@ class MethodFunctor4 {
P4 p4_;
};
+template <class FunctorT, class R,
+ class P1,
+ class P2,
+ class P3,
+ class P4>
+class Functor4 {
+ public:
+ Functor4(const FunctorT& functor, P1 p1, P2 p2, P3 p3, P4 p4)
+ : functor_(functor),
+ p1_(p1),
+ p2_(p2),
+ p3_(p3),
+ p4_(p4) {}
+ R operator()() const {
+ return functor_(p1_, p2_, p3_, p4_); }
+ private:
+ FunctorT functor_;
+ P1 p1_;
+ P2 p2_;
+ P3 p3_;
+ P4 p4_;
+};
+
+
#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4)
template <class ObjectT, class R,
@@ -316,6 +458,24 @@ Bind(FP_T(method), const ObjectT* object,
}
#undef FP_T
+#define FP_T(x) R (*x)(P1, P2, P3, P4)
+
+template <class R,
+ class P1,
+ class P2,
+ class P3,
+ class P4>
+Functor4<FP_T(NONAME), R, P1, P2, P3, P4>
+Bind(FP_T(function),
+ typename detail::identity<P1>::type p1,
+ typename detail::identity<P2>::type p2,
+ typename detail::identity<P3>::type p3,
+ typename detail::identity<P4>::type p4) {
+ return Functor4<FP_T(NONAME), R, P1, P2, P3, P4>(
+ function, p1, p2, p3, p4);
+}
+
+#undef FP_T
template <class ObjectT, class MethodT, class R,
class P1,
@@ -349,6 +509,33 @@ class MethodFunctor5 {
P5 p5_;
};
+template <class FunctorT, class R,
+ class P1,
+ class P2,
+ class P3,
+ class P4,
+ class P5>
+class Functor5 {
+ public:
+ Functor5(const FunctorT& functor, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
+ : functor_(functor),
+ p1_(p1),
+ p2_(p2),
+ p3_(p3),
+ p4_(p4),
+ p5_(p5) {}
+ R operator()() const {
+ return functor_(p1_, p2_, p3_, p4_, p5_); }
+ private:
+ FunctorT functor_;
+ P1 p1_;
+ P2 p2_;
+ P3 p3_;
+ P4 p4_;
+ P5 p5_;
+};
+
+
#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5)
template <class ObjectT, class R,
@@ -389,6 +576,26 @@ Bind(FP_T(method), const ObjectT* object,
}
#undef FP_T
+#define FP_T(x) R (*x)(P1, P2, P3, P4, P5)
+
+template <class R,
+ class P1,
+ class P2,
+ class P3,
+ class P4,
+ class P5>
+Functor5<FP_T(NONAME), R, P1, P2, P3, P4, P5>
+Bind(FP_T(function),
+ typename detail::identity<P1>::type p1,
+ typename detail::identity<P2>::type p2,
+ typename detail::identity<P3>::type p3,
+ typename detail::identity<P4>::type p4,
+ typename detail::identity<P5>::type p5) {
+ return Functor5<FP_T(NONAME), R, P1, P2, P3, P4, P5>(
+ function, p1, p2, p3, p4, p5);
+}
+
+#undef FP_T
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/bind.h.pump b/chromium/third_party/libjingle/source/talk/base/bind.h.pump
index 7f4c39e6344..2ebb8955159 100644
--- a/chromium/third_party/libjingle/source/talk/base/bind.h.pump
+++ b/chromium/third_party/libjingle/source/talk/base/bind.h.pump
@@ -91,6 +91,24 @@ class MethodFunctor$i {
};
+template <class FunctorT, class R$for j [[,
+ class P$j]]>
+class Functor$i {
+ public:
+ $if i == 0 [[explicit ]]
+Functor$i(const FunctorT& functor$for j [[, P$j p$j]])
+ : functor_(functor)$for j [[,
+ p$(j)_(p$j)]] {}
+ R operator()() const {
+ return functor_($for j , [[p$(j)_]]); }
+ private:
+ FunctorT functor_;$for j [[
+
+ P$j p$(j)_;]]
+
+};
+
+
#define FP_T(x) R (ObjectT::*x)($for j , [[P$j]])
template <class ObjectT, class R$for j [[,
@@ -115,6 +133,18 @@ Bind(FP_T(method), const ObjectT* object$for j [[,
}
#undef FP_T
+#define FP_T(x) R (*x)($for j , [[P$j]])
+
+template <class R$for j [[,
+ class P$j]]>
+Functor$i<FP_T(NONAME), R$for j [[, P$j]]>
+Bind(FP_T(function)$for j [[,
+ typename detail::identity<P$j>::type p$j]]) {
+ return Functor$i<FP_T(NONAME), R$for j [[, P$j]]>(
+ function$for j [[, p$j]]);
+}
+
+#undef FP_T
]]
diff --git a/chromium/third_party/libjingle/source/talk/base/bind_unittest.cc b/chromium/third_party/libjingle/source/talk/base/bind_unittest.cc
index 81bbddd6b70..78ac278376e 100644
--- a/chromium/third_party/libjingle/source/talk/base/bind_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/bind_unittest.cc
@@ -43,6 +43,10 @@ struct MethodBindTester {
mutable int call_count;
};
+int Return42() { return 42; }
+int Negate(int a) { return -a; }
+int Multiply(int a, int b) { return a * b; }
+
} // namespace
TEST(BindTest, BindToMethod) {
@@ -71,4 +75,10 @@ TEST(BindTest, BindToMethod) {
EXPECT_EQ(8, object.call_count);
}
+TEST(BindTest, BindToFunction) {
+ EXPECT_EQ(42, Bind(&Return42)());
+ EXPECT_EQ(3, Bind(&Negate, -3)());
+ EXPECT_EQ(56, Bind(&Multiply, 8, 7)());
+}
+
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/buffer.h b/chromium/third_party/libjingle/source/talk/base/buffer.h
index 47096332c58..2d589f27ef4 100644
--- a/chromium/third_party/libjingle/source/talk/base/buffer.h
+++ b/chromium/third_party/libjingle/source/talk/base/buffer.h
@@ -28,7 +28,7 @@
#ifndef TALK_BASE_BUFFER_H_
#define TALK_BASE_BUFFER_H_
-#include <cstring>
+#include <string.h>
#include "talk/base/scoped_ptr.h"
diff --git a/chromium/third_party/libjingle/source/talk/base/bytebuffer.cc b/chromium/third_party/libjingle/source/talk/base/bytebuffer.cc
index 523475d82c4..396a1d34282 100644
--- a/chromium/third_party/libjingle/source/talk/base/bytebuffer.cc
+++ b/chromium/third_party/libjingle/source/talk/base/bytebuffer.cc
@@ -27,9 +27,10 @@
#include "talk/base/bytebuffer.h"
+#include <assert.h>
+#include <string.h>
+
#include <algorithm>
-#include <cassert>
-#include <cstring>
#include "talk/base/basictypes.h"
#include "talk/base/byteorder.h"
diff --git a/chromium/third_party/libjingle/source/talk/base/byteorder.h b/chromium/third_party/libjingle/source/talk/base/byteorder.h
index c6d0dbbe0ea..cf26a1292a6 100644
--- a/chromium/third_party/libjingle/source/talk/base/byteorder.h
+++ b/chromium/third_party/libjingle/source/talk/base/byteorder.h
@@ -28,7 +28,7 @@
#ifndef TALK_BASE_BYTEORDER_H_
#define TALK_BASE_BYTEORDER_H_
-#ifdef POSIX
+#if defined(POSIX) && !defined(__native_client__)
#include <arpa/inet.h>
#endif
diff --git a/chromium/third_party/libjingle/source/talk/base/callback.h b/chromium/third_party/libjingle/source/talk/base/callback.h
new file mode 100644
index 00000000000..11fbf86badb
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/callback.h
@@ -0,0 +1,278 @@
+// This file was GENERATED by command:
+// pump.py callback.h.pump
+// DO NOT EDIT BY HAND!!!
+
+/*
+ * libjingle
+ * Copyright 2012 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// To generate callback.h from callback.h.pump, execute:
+// /home/build/google3/third_party/gtest/scripts/pump.py callback.h.pump
+
+// Callbacks are callable object containers. They can hold a function pointer
+// or a function object and behave like a value type. Internally, data is
+// reference-counted, making copies and pass-by-value inexpensive.
+//
+// Callbacks are typed using template arguments. The format is:
+// CallbackN<ReturnType, ParamType1, ..., ParamTypeN>
+// where N is the number of arguments supplied to the callable object.
+// Callbacks are invoked using operator(), just like a function or a function
+// object. Default-constructed callbacks are "empty," and executing an empty
+// callback does nothing. A callback can be made empty by assigning it from
+// a default-constructed callback.
+//
+// Callbacks are similar in purpose to std::function (which isn't available on
+// all platforms we support) and a lightweight alternative to sigslots. Since
+// they effectively hide the type of the object they call, they're useful in
+// breaking dependencies between objects that need to interact with one another.
+// Notably, they can hold the results of Bind(), std::bind*, etc, without
+// needing
+// to know the resulting object type of those calls.
+//
+// Sigslots, on the other hand, provide a fuller feature set, such as multiple
+// subscriptions to a signal, optional thread-safety, and lifetime tracking of
+// slots. When these features are needed, choose sigslots.
+//
+// Example:
+// int sqr(int x) { return x * x; }
+// struct AddK {
+// int k;
+// int operator()(int x) const { return x + k; }
+// } add_k = {5};
+//
+// Callback1<int, int> my_callback;
+// cout << my_callback.empty() << endl; // true
+//
+// my_callback = Callback1<int, int>(&sqr);
+// cout << my_callback.empty() << endl; // false
+// cout << my_callback(3) << endl; // 9
+//
+// my_callback = Callback1<int, int>(add_k);
+// cout << my_callback(10) << endl; // 15
+//
+// my_callback = Callback1<int, int>();
+// cout << my_callback.empty() << endl; // true
+
+#ifndef TALK_BASE_CALLBACK_H_
+#define TALK_BASE_CALLBACK_H_
+
+#include "talk/base/logging.h"
+#include "talk/base/refcount.h"
+#include "talk/base/scoped_ref_ptr.h"
+
+namespace talk_base {
+
+template <class R>
+class Callback0 {
+ public:
+ // Default copy operations are appropriate for this class.
+ Callback0() {}
+ template <class T> Callback0(const T& functor)
+ : helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
+ R operator()() {
+ if (empty())
+ return R();
+ return helper_->Run();
+ }
+ bool empty() const { return !helper_; }
+
+ private:
+ struct Helper : RefCountInterface {
+ virtual ~Helper() {}
+ virtual R Run() = 0;
+ };
+ template <class T> struct HelperImpl : Helper {
+ explicit HelperImpl(const T& functor) : functor_(functor) {}
+ virtual R Run() {
+ return functor_();
+ }
+ T functor_;
+ };
+ scoped_refptr<Helper> helper_;
+};
+
+template <class R,
+ class P1>
+class Callback1 {
+ public:
+ // Default copy operations are appropriate for this class.
+ Callback1() {}
+ template <class T> Callback1(const T& functor)
+ : helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
+ R operator()(P1 p1) {
+ if (empty())
+ return R();
+ return helper_->Run(p1);
+ }
+ bool empty() const { return !helper_; }
+
+ private:
+ struct Helper : RefCountInterface {
+ virtual ~Helper() {}
+ virtual R Run(P1 p1) = 0;
+ };
+ template <class T> struct HelperImpl : Helper {
+ explicit HelperImpl(const T& functor) : functor_(functor) {}
+ virtual R Run(P1 p1) {
+ return functor_(p1);
+ }
+ T functor_;
+ };
+ scoped_refptr<Helper> helper_;
+};
+
+template <class R,
+ class P1,
+ class P2>
+class Callback2 {
+ public:
+ // Default copy operations are appropriate for this class.
+ Callback2() {}
+ template <class T> Callback2(const T& functor)
+ : helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
+ R operator()(P1 p1, P2 p2) {
+ if (empty())
+ return R();
+ return helper_->Run(p1, p2);
+ }
+ bool empty() const { return !helper_; }
+
+ private:
+ struct Helper : RefCountInterface {
+ virtual ~Helper() {}
+ virtual R Run(P1 p1, P2 p2) = 0;
+ };
+ template <class T> struct HelperImpl : Helper {
+ explicit HelperImpl(const T& functor) : functor_(functor) {}
+ virtual R Run(P1 p1, P2 p2) {
+ return functor_(p1, p2);
+ }
+ T functor_;
+ };
+ scoped_refptr<Helper> helper_;
+};
+
+template <class R,
+ class P1,
+ class P2,
+ class P3>
+class Callback3 {
+ public:
+ // Default copy operations are appropriate for this class.
+ Callback3() {}
+ template <class T> Callback3(const T& functor)
+ : helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
+ R operator()(P1 p1, P2 p2, P3 p3) {
+ if (empty())
+ return R();
+ return helper_->Run(p1, p2, p3);
+ }
+ bool empty() const { return !helper_; }
+
+ private:
+ struct Helper : RefCountInterface {
+ virtual ~Helper() {}
+ virtual R Run(P1 p1, P2 p2, P3 p3) = 0;
+ };
+ template <class T> struct HelperImpl : Helper {
+ explicit HelperImpl(const T& functor) : functor_(functor) {}
+ virtual R Run(P1 p1, P2 p2, P3 p3) {
+ return functor_(p1, p2, p3);
+ }
+ T functor_;
+ };
+ scoped_refptr<Helper> helper_;
+};
+
+template <class R,
+ class P1,
+ class P2,
+ class P3,
+ class P4>
+class Callback4 {
+ public:
+ // Default copy operations are appropriate for this class.
+ Callback4() {}
+ template <class T> Callback4(const T& functor)
+ : helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
+ R operator()(P1 p1, P2 p2, P3 p3, P4 p4) {
+ if (empty())
+ return R();
+ return helper_->Run(p1, p2, p3, p4);
+ }
+ bool empty() const { return !helper_; }
+
+ private:
+ struct Helper : RefCountInterface {
+ virtual ~Helper() {}
+ virtual R Run(P1 p1, P2 p2, P3 p3, P4 p4) = 0;
+ };
+ template <class T> struct HelperImpl : Helper {
+ explicit HelperImpl(const T& functor) : functor_(functor) {}
+ virtual R Run(P1 p1, P2 p2, P3 p3, P4 p4) {
+ return functor_(p1, p2, p3, p4);
+ }
+ T functor_;
+ };
+ scoped_refptr<Helper> helper_;
+};
+
+template <class R,
+ class P1,
+ class P2,
+ class P3,
+ class P4,
+ class P5>
+class Callback5 {
+ public:
+ // Default copy operations are appropriate for this class.
+ Callback5() {}
+ template <class T> Callback5(const T& functor)
+ : helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
+ R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
+ if (empty())
+ return R();
+ return helper_->Run(p1, p2, p3, p4, p5);
+ }
+ bool empty() const { return !helper_; }
+
+ private:
+ struct Helper : RefCountInterface {
+ virtual ~Helper() {}
+ virtual R Run(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) = 0;
+ };
+ template <class T> struct HelperImpl : Helper {
+ explicit HelperImpl(const T& functor) : functor_(functor) {}
+ virtual R Run(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
+ return functor_(p1, p2, p3, p4, p5);
+ }
+ T functor_;
+ };
+ scoped_refptr<Helper> helper_;
+};
+} // namespace talk_base
+
+#endif // TALK_BASE_CALLBACK_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/callback.h.pump b/chromium/third_party/libjingle/source/talk/base/callback.h.pump
new file mode 100644
index 00000000000..458eac73bf0
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/callback.h.pump
@@ -0,0 +1,120 @@
+/*
+ * libjingle
+ * Copyright 2012 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// To generate callback.h from callback.h.pump, execute:
+// /home/build/google3/third_party/gtest/scripts/pump.py callback.h.pump
+
+// Callbacks are callable object containers. They can hold a function pointer
+// or a function object and behave like a value type. Internally, data is
+// reference-counted, making copies and pass-by-value inexpensive.
+//
+// Callbacks are typed using template arguments. The format is:
+// CallbackN<ReturnType, ParamType1, ..., ParamTypeN>
+// where N is the number of arguments supplied to the callable object.
+// Callbacks are invoked using operator(), just like a function or a function
+// object. Default-constructed callbacks are "empty," and executing an empty
+// callback does nothing. A callback can be made empty by assigning it from
+// a default-constructed callback.
+//
+// Callbacks are similar in purpose to std::function (which isn't available on
+// all platforms we support) and a lightweight alternative to sigslots. Since
+// they effectively hide the type of the object they call, they're useful in
+// breaking dependencies between objects that need to interact with one another.
+// Notably, they can hold the results of Bind(), std::bind*, etc, without needing
+// to know the resulting object type of those calls.
+//
+// Sigslots, on the other hand, provide a fuller feature set, such as multiple
+// subscriptions to a signal, optional thread-safety, and lifetime tracking of
+// slots. When these features are needed, choose sigslots.
+//
+// Example:
+// int sqr(int x) { return x * x; }
+// struct AddK {
+// int k;
+// int operator()(int x) const { return x + k; }
+// } add_k = {5};
+//
+// Callback1<int, int> my_callback;
+// cout << my_callback.empty() << endl; // true
+//
+// my_callback = Callback1<int, int>(&sqr);
+// cout << my_callback.empty() << endl; // false
+// cout << my_callback(3) << endl; // 9
+//
+// my_callback = Callback1<int, int>(add_k);
+// cout << my_callback(10) << endl; // 15
+//
+// my_callback = Callback1<int, int>();
+// cout << my_callback.empty() << endl; // true
+
+#ifndef TALK_BASE_CALLBACK_H_
+#define TALK_BASE_CALLBACK_H_
+
+#include "talk/base/refcount.h"
+#include "talk/base/scoped_ref_ptr.h"
+
+namespace talk_base {
+
+$var n = 5
+$range i 0..n
+$for i [[
+$range j 1..i
+
+template <class R$for j [[,
+ class P$j]]>
+class Callback$i {
+ public:
+ // Default copy operations are appropriate for this class.
+ Callback$i() {}
+ template <class T> Callback$i(const T& functor)
+ : helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
+ R operator()($for j , [[P$j p$j]]) {
+ if (empty())
+ return R();
+ return helper_->Run($for j , [[p$j]]);
+ }
+ bool empty() const { return !helper_; }
+
+ private:
+ struct Helper : RefCountInterface {
+ virtual ~Helper() {}
+ virtual R Run($for j , [[P$j p$j]]) = 0;
+ };
+ template <class T> struct HelperImpl : Helper {
+ explicit HelperImpl(const T& functor) : functor_(functor) {}
+ virtual R Run($for j , [[P$j p$j]]) {
+ return functor_($for j , [[p$j]]);
+ }
+ T functor_;
+ };
+ scoped_refptr<Helper> helper_;
+};
+
+]]
+} // namespace talk_base
+
+#endif // TALK_BASE_CALLBACK_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/callback_unittest.cc b/chromium/third_party/libjingle/source/talk/base/callback_unittest.cc
new file mode 100644
index 00000000000..c7ca00f0fd2
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/callback_unittest.cc
@@ -0,0 +1,98 @@
+/*
+ * libjingle
+ * Copyright 2004--2011, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/base/bind.h"
+#include "talk/base/callback.h"
+#include "talk/base/gunit.h"
+
+namespace talk_base {
+
+namespace {
+
+void f() {}
+int g() { return 42; }
+int h(int x) { return x * x; }
+void i(int& x) { x *= x; } // NOLINT: Testing refs
+
+struct BindTester {
+ int a() { return 24; }
+ int b(int x) const { return x * x; }
+};
+
+} // namespace
+
+TEST(CallbackTest, VoidReturn) {
+ Callback0<void> cb;
+ EXPECT_TRUE(cb.empty());
+ cb(); // Executing an empty callback should not crash.
+ cb = Callback0<void>(&f);
+ EXPECT_FALSE(cb.empty());
+ cb();
+}
+
+TEST(CallbackTest, IntReturn) {
+ Callback0<int> cb;
+ EXPECT_TRUE(cb.empty());
+ cb = Callback0<int>(&g);
+ EXPECT_FALSE(cb.empty());
+ EXPECT_EQ(42, cb());
+ EXPECT_EQ(42, cb());
+}
+
+TEST(CallbackTest, OneParam) {
+ Callback1<int, int> cb1(&h);
+ EXPECT_FALSE(cb1.empty());
+ EXPECT_EQ(9, cb1(-3));
+ EXPECT_EQ(100, cb1(10));
+
+ // Try clearing a callback.
+ cb1 = Callback1<int, int>();
+ EXPECT_TRUE(cb1.empty());
+
+ // Try a callback with a ref parameter.
+ Callback1<void, int&> cb2(&i);
+ int x = 3;
+ cb2(x);
+ EXPECT_EQ(9, x);
+ cb2(x);
+ EXPECT_EQ(81, x);
+}
+
+TEST(CallbackTest, WithBind) {
+ BindTester t;
+ Callback0<int> cb1 = Bind(&BindTester::a, &t);
+ EXPECT_EQ(24, cb1());
+ EXPECT_EQ(24, cb1());
+ cb1 = Bind(&BindTester::b, &t, 10);
+ EXPECT_EQ(100, cb1());
+ EXPECT_EQ(100, cb1());
+ cb1 = Bind(&BindTester::b, &t, 5);
+ EXPECT_EQ(25, cb1());
+ EXPECT_EQ(25, cb1());
+}
+
+} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/common.cc b/chromium/third_party/libjingle/source/talk/base/common.cc
index 3c0c352a900..9f63aa4da99 100644
--- a/chromium/third_party/libjingle/source/talk/base/common.cc
+++ b/chromium/third_party/libjingle/source/talk/base/common.cc
@@ -28,7 +28,7 @@
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
-#include <memory.h>
+#include <string.h>
#if WIN32
#define WIN32_LEAN_AND_MEAN
@@ -78,4 +78,12 @@ void LogAssert(const char* function, const char* file, int line,
}
}
+bool IsOdd(int n) {
+ return (n & 0x1);
+}
+
+bool IsEven(int n) {
+ return !IsOdd(n);
+}
+
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/common.h b/chromium/third_party/libjingle/source/talk/base/common.h
index a76748b3905..ed7d59ed676 100644
--- a/chromium/third_party/libjingle/source/talk/base/common.h
+++ b/chromium/third_party/libjingle/source/talk/base/common.h
@@ -61,8 +61,14 @@ inline void Unused(const void*) {}
#endif // UNUSED
#ifndef WIN32
+
+#ifndef strnicmp
#define strnicmp(x, y, n) strncasecmp(x, y, n)
+#endif
+
+#ifndef stricmp
#define stricmp(x, y) strcasecmp(x, y)
+#endif
// TODO(fbarchard): Remove this. std::max should be used everywhere in the code.
// NOMINMAX must be defined where we include <windows.h>.
@@ -87,6 +93,11 @@ inline void Unused(const void*) {}
namespace talk_base {
+
+// If a debugger is attached, triggers a debugger breakpoint. If a debugger is
+// not attached, forces program termination.
+void Break();
+
// LogAssert writes information about an assertion to the log. It's called by
// Assert (and from the ASSERT macro in debug mode) before any other action
// is taken (e.g. breaking the debugger, abort()ing, etc.).
@@ -105,17 +116,16 @@ typedef void (*AssertLogger)(const char* function,
// only by one component.
void SetCustomAssertLogger(AssertLogger logger);
-} // namespace talk_base
+bool IsOdd(int n);
+bool IsEven(int n);
+
+} // namespace talk_base
#if ENABLE_DEBUG
namespace talk_base {
-// If a debugger is attached, triggers a debugger breakpoint. If a debugger is
-// not attached, forces program termination.
-void Break();
-
inline bool Assert(bool result, const char* function, const char* file,
int line, const char* expression) {
if (!result) {
diff --git a/chromium/third_party/libjingle/source/talk/base/cpumonitor.cc b/chromium/third_party/libjingle/source/talk/base/cpumonitor.cc
index e9b481fdbd9..aaec77208d4 100644
--- a/chromium/third_party/libjingle/source/talk/base/cpumonitor.cc
+++ b/chromium/third_party/libjingle/source/talk/base/cpumonitor.cc
@@ -48,6 +48,7 @@
#if defined(IOS) || defined(OSX)
#include <mach/mach_host.h>
#include <mach/mach_init.h>
+#include <mach/mach_port.h>
#include <mach/host_info.h>
#include <mach/task.h>
#endif // defined(IOS) || defined(OSX)
@@ -241,11 +242,14 @@ float CpuSampler::GetSystemLoad() {
#endif // WIN32
#if defined(IOS) || defined(OSX)
+ mach_port_t mach_host = mach_host_self();
host_cpu_load_info_data_t cpu_info;
mach_msg_type_number_t info_count = HOST_CPU_LOAD_INFO_COUNT;
- if (KERN_SUCCESS != host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO,
- reinterpret_cast<host_info_t>(&cpu_info),
- &info_count)) {
+ kern_return_t kr = host_statistics(mach_host, HOST_CPU_LOAD_INFO,
+ reinterpret_cast<host_info_t>(&cpu_info),
+ &info_count);
+ mach_port_deallocate(mach_task_self(), mach_host);
+ if (KERN_SUCCESS != kr) {
LOG(LS_ERROR) << "::host_statistics() failed";
return 0.f;
}
diff --git a/chromium/third_party/libjingle/source/talk/base/cpumonitor_unittest.cc b/chromium/third_party/libjingle/source/talk/base/cpumonitor_unittest.cc
index b9f5ba33e77..cdc3e6b79b2 100644
--- a/chromium/third_party/libjingle/source/talk/base/cpumonitor_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/cpumonitor_unittest.cc
@@ -386,8 +386,8 @@ TEST(CpuMonitorTest, TestCpuMonitor) {
CpuLoadListener listener;
monitor.SignalUpdate.connect(&listener, &CpuLoadListener::OnCpuLoad);
EXPECT_TRUE(monitor.Start(10));
- Thread::Current()->ProcessMessages(50);
- EXPECT_GT(listener.count(), 2); // We have checked cpu load more than twice.
+ // We have checked cpu load more than twice.
+ EXPECT_TRUE_WAIT(listener.count() > 2, 1000);
EXPECT_GT(listener.current_cpus(), 0);
EXPECT_GT(listener.cpus(), 0);
EXPECT_GE(listener.process_load(), .0f);
diff --git a/chromium/third_party/libjingle/source/talk/base/criticalsection_unittest.cc b/chromium/third_party/libjingle/source/talk/base/criticalsection_unittest.cc
new file mode 100644
index 00000000000..0bb34b7026c
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/criticalsection_unittest.cc
@@ -0,0 +1,163 @@
+/*
+ * libjingle
+ * Copyright 2014, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <set>
+#include <vector>
+
+#include "talk/base/criticalsection.h"
+#include "talk/base/event.h"
+#include "talk/base/gunit.h"
+#include "talk/base/scopedptrcollection.h"
+#include "talk/base/thread.h"
+
+namespace talk_base {
+
+namespace {
+
+const int kLongTime = 10000; // 10 seconds
+const int kNumThreads = 16;
+const int kOperationsToRun = 1000;
+
+template <class T>
+class AtomicOpRunner : public MessageHandler {
+ public:
+ explicit AtomicOpRunner(int initial_value)
+ : value_(initial_value),
+ threads_active_(0),
+ start_event_(true, false),
+ done_event_(true, false) {}
+
+ int value() const { return value_; }
+
+ bool Run() {
+ // Signal all threads to start.
+ start_event_.Set();
+
+ // Wait for all threads to finish.
+ return done_event_.Wait(kLongTime);
+ }
+
+ void SetExpectedThreadCount(int count) {
+ threads_active_ = count;
+ }
+
+ virtual void OnMessage(Message* msg) {
+ std::vector<int> values;
+ values.reserve(kOperationsToRun);
+
+ // Wait to start.
+ ASSERT_TRUE(start_event_.Wait(kLongTime));
+
+ // Generate a bunch of values by updating value_ atomically.
+ for (int i = 0; i < kOperationsToRun; ++i) {
+ values.push_back(T::AtomicOp(&value_));
+ }
+
+ { // Add them all to the set.
+ CritScope cs(&all_values_crit_);
+ for (size_t i = 0; i < values.size(); ++i) {
+ std::pair<std::set<int>::iterator, bool> result =
+ all_values_.insert(values[i]);
+ // Each value should only be taken by one thread, so if this value
+ // has already been added, something went wrong.
+ EXPECT_TRUE(result.second)
+ << "Thread=" << Thread::Current() << " value=" << values[i];
+ }
+ }
+
+ // Signal that we're done.
+ if (AtomicOps::Decrement(&threads_active_) == 0) {
+ done_event_.Set();
+ }
+ }
+
+ private:
+ int value_;
+ int threads_active_;
+ CriticalSection all_values_crit_;
+ std::set<int> all_values_;
+ Event start_event_;
+ Event done_event_;
+};
+
+struct IncrementOp {
+ static int AtomicOp(int* i) { return AtomicOps::Increment(i); }
+};
+
+struct DecrementOp {
+ static int AtomicOp(int* i) { return AtomicOps::Decrement(i); }
+};
+
+void StartThreads(ScopedPtrCollection<Thread>* threads,
+ MessageHandler* handler) {
+ for (int i = 0; i < kNumThreads; ++i) {
+ Thread* thread = new Thread();
+ thread->Start();
+ thread->Post(handler);
+ threads->PushBack(thread);
+ }
+}
+
+} // namespace
+
+TEST(AtomicOpsTest, Simple) {
+ int value = 0;
+ EXPECT_EQ(1, AtomicOps::Increment(&value));
+ EXPECT_EQ(1, value);
+ EXPECT_EQ(2, AtomicOps::Increment(&value));
+ EXPECT_EQ(2, value);
+ EXPECT_EQ(1, AtomicOps::Decrement(&value));
+ EXPECT_EQ(1, value);
+ EXPECT_EQ(0, AtomicOps::Decrement(&value));
+ EXPECT_EQ(0, value);
+}
+
+TEST(AtomicOpsTest, Increment) {
+ // Create and start lots of threads.
+ AtomicOpRunner<IncrementOp> runner(0);
+ ScopedPtrCollection<Thread> threads;
+ StartThreads(&threads, &runner);
+ runner.SetExpectedThreadCount(kNumThreads);
+
+ // Release the hounds!
+ EXPECT_TRUE(runner.Run());
+ EXPECT_EQ(kOperationsToRun * kNumThreads, runner.value());
+}
+
+TEST(AtomicOpsTest, Decrement) {
+ // Create and start lots of threads.
+ AtomicOpRunner<DecrementOp> runner(kOperationsToRun * kNumThreads);
+ ScopedPtrCollection<Thread> threads;
+ StartThreads(&threads, &runner);
+ runner.SetExpectedThreadCount(kNumThreads);
+
+ // Release the hounds!
+ EXPECT_TRUE(runner.Run());
+ EXPECT_EQ(0, runner.value());
+}
+
+} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/cryptstring.h b/chromium/third_party/libjingle/source/talk/base/cryptstring.h
index eb39be229e0..600474f2adb 100644
--- a/chromium/third_party/libjingle/source/talk/base/cryptstring.h
+++ b/chromium/third_party/libjingle/source/talk/base/cryptstring.h
@@ -28,9 +28,11 @@
#ifndef _TALK_BASE_CRYPTSTRING_H_
#define _TALK_BASE_CRYPTSTRING_H_
-#include <cstring>
+#include <string.h>
+
#include <string>
#include <vector>
+
#include "talk/base/linked_ptr.h"
#include "talk/base/scoped_ptr.h"
diff --git a/chromium/third_party/libjingle/source/talk/base/event.cc b/chromium/third_party/libjingle/source/talk/base/event.cc
index 6089c8c9f94..410c65851f5 100644
--- a/chromium/third_party/libjingle/source/talk/base/event.cc
+++ b/chromium/third_party/libjingle/source/talk/base/event.cc
@@ -103,10 +103,16 @@ bool Event::Wait(int cms) {
// Converting from seconds and microseconds (1e-6) plus
// milliseconds (1e-3) to seconds and nanoseconds (1e-9).
+ struct timespec ts;
+#if HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
+ // Use relative time version, which tends to be more efficient for
+ // pthread implementations where provided (like on Android).
+ ts.tv_sec = cms / 1000;
+ ts.tv_nsec = (cms % 1000) * 1000000;
+#else
struct timeval tv;
gettimeofday(&tv, NULL);
- struct timespec ts;
ts.tv_sec = tv.tv_sec + (cms / 1000);
ts.tv_nsec = tv.tv_usec * 1000 + (cms % 1000) * 1000000;
@@ -115,9 +121,16 @@ bool Event::Wait(int cms) {
ts.tv_sec++;
ts.tv_nsec -= 1000000000;
}
+#endif
- while (!event_status_ && error == 0)
+ while (!event_status_ && error == 0) {
+#if HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
+ error = pthread_cond_timedwait_relative_np(
+ &event_cond_, &event_mutex_, &ts);
+#else
error = pthread_cond_timedwait(&event_cond_, &event_mutex_, &ts);
+#endif
+ }
} else {
while (!event_status_ && error == 0)
error = pthread_cond_wait(&event_cond_, &event_mutex_);
diff --git a/chromium/third_party/libjingle/source/talk/base/fakesslidentity.h b/chromium/third_party/libjingle/source/talk/base/fakesslidentity.h
index 203bb83bf0d..fbe5e648425 100644
--- a/chromium/third_party/libjingle/source/talk/base/fakesslidentity.h
+++ b/chromium/third_party/libjingle/source/talk/base/fakesslidentity.h
@@ -38,9 +38,12 @@ namespace talk_base {
class FakeSSLCertificate : public talk_base::SSLCertificate {
public:
- explicit FakeSSLCertificate(const std::string& data) : data_(data) {}
+ // SHA-1 is the default digest algorithm because it is available in all build
+ // configurations used for unit testing.
+ explicit FakeSSLCertificate(const std::string& data)
+ : data_(data), digest_algorithm_(DIGEST_SHA_1) {}
explicit FakeSSLCertificate(const std::vector<std::string>& certs)
- : data_(certs.front()) {
+ : data_(certs.front()), digest_algorithm_(DIGEST_SHA_1) {
std::vector<std::string>::const_iterator it;
// Skip certs[0].
for (it = certs.begin() + 1; it != certs.end(); ++it) {
@@ -58,15 +61,17 @@ class FakeSSLCertificate : public talk_base::SSLCertificate {
VERIFY(SSLIdentity::PemToDer(kPemTypeCertificate, data_, &der_string));
der_buffer->SetData(der_string.c_str(), der_string.size());
}
+ void set_digest_algorithm(const std::string& algorithm) {
+ digest_algorithm_ = algorithm;
+ }
virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const {
- // SHA-1 is chosen because it is available in all build configurations
- // used for unit testing.
- *algorithm = DIGEST_SHA_1;
+ *algorithm = digest_algorithm_;
return true;
}
- virtual bool ComputeDigest(const std::string &algorithm,
- unsigned char *digest, std::size_t size,
- std::size_t *length) const {
+ virtual bool ComputeDigest(const std::string& algorithm,
+ unsigned char* digest,
+ size_t size,
+ size_t* length) const {
*length = talk_base::ComputeDigest(algorithm, data_.c_str(), data_.size(),
digest, size);
return (*length != 0);
@@ -86,6 +91,7 @@ class FakeSSLCertificate : public talk_base::SSLCertificate {
}
std::string data_;
std::vector<FakeSSLCertificate> certs_;
+ std::string digest_algorithm_;
};
class FakeSSLIdentity : public talk_base::SSLIdentity {
diff --git a/chromium/third_party/libjingle/source/talk/base/fileutils.cc b/chromium/third_party/libjingle/source/talk/base/fileutils.cc
index ff34147db76..72797f3d0ff 100644
--- a/chromium/third_party/libjingle/source/talk/base/fileutils.cc
+++ b/chromium/third_party/libjingle/source/talk/base/fileutils.cc
@@ -25,9 +25,12 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <cassert>
+#include <assert.h>
#ifdef WIN32
+// TODO(grunell): Remove io.h includes when Chromium has started
+// to use AEC in each source. http://crbug.com/264611.
+#include <io.h>
#include "talk/base/win32.h"
#endif
@@ -294,4 +297,28 @@ bool CreateUniqueFile(Pathname& path, bool create_empty) {
return true;
}
+// Taken from Chromium's base/platform_file_*.cc.
+// TODO(grunell): Remove when Chromium has started to use AEC in each source.
+// http://crbug.com/264611.
+FILE* FdopenPlatformFileForWriting(PlatformFile file) {
+#if defined(WIN32)
+ if (file == kInvalidPlatformFileValue)
+ return NULL;
+ int fd = _open_osfhandle(reinterpret_cast<intptr_t>(file), 0);
+ if (fd < 0)
+ return NULL;
+ return _fdopen(fd, "w");
+#else
+ return fdopen(file, "w");
+#endif
+}
+
+bool ClosePlatformFile(PlatformFile file) {
+#if defined(WIN32)
+ return CloseHandle(file) != 0;
+#else
+ return close(file);
+#endif
+}
+
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/fileutils.h b/chromium/third_party/libjingle/source/talk/base/fileutils.h
index 186c9633226..e58f76c7e9a 100644
--- a/chromium/third_party/libjingle/source/talk/base/fileutils.h
+++ b/chromium/third_party/libjingle/source/talk/base/fileutils.h
@@ -33,9 +33,10 @@
#ifdef WIN32
#include "talk/base/win32.h"
#else
-#include <sys/types.h>
#include <dirent.h>
+#include <stdio.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
#endif
@@ -452,6 +453,24 @@ class FilesystemScope{
// process).
bool CreateUniqueFile(Pathname& path, bool create_empty);
+// Taken from Chromium's base/platform_file.h.
+// Don't use ClosePlatformFile to close a file opened with FdopenPlatformFile.
+// Use fclose instead.
+// TODO(grunell): Remove when Chromium has started to use AEC in each source.
+// http://crbug.com/264611.
+#if defined(WIN32)
+typedef HANDLE PlatformFile;
+const PlatformFile kInvalidPlatformFileValue = INVALID_HANDLE_VALUE;
+#elif defined(POSIX)
+typedef int PlatformFile;
+const PlatformFile kInvalidPlatformFileValue = -1;
+#else
+#error Unsupported platform
+#endif
+
+FILE* FdopenPlatformFileForWriting(PlatformFile file);
+bool ClosePlatformFile(PlatformFile file);
+
} // namespace talk_base
#endif // TALK_BASE_FILEUTILS_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/firewallsocketserver.cc b/chromium/third_party/libjingle/source/talk/base/firewallsocketserver.cc
index be8f2e1831c..4a8a66d43e4 100644
--- a/chromium/third_party/libjingle/source/talk/base/firewallsocketserver.cc
+++ b/chromium/third_party/libjingle/source/talk/base/firewallsocketserver.cc
@@ -27,7 +27,8 @@
#include "talk/base/firewallsocketserver.h"
-#include <cassert>
+#include <assert.h>
+
#include <algorithm>
#include "talk/base/asyncsocket.h"
diff --git a/chromium/third_party/libjingle/source/talk/base/gunit.h b/chromium/third_party/libjingle/source/talk/base/gunit.h
index 3a0321468a7..e56dd6f617a 100644
--- a/chromium/third_party/libjingle/source/talk/base/gunit.h
+++ b/chromium/third_party/libjingle/source/talk/base/gunit.h
@@ -36,11 +36,6 @@
#include "testing/base/public/gunit.h"
#endif
-// forward declarations
-namespace talk_base {
-class Pathname;
-}
-
// Wait until "ex" is true, or "timeout" expires.
#define WAIT(ex, timeout) \
for (uint32 start = talk_base::Time(); \
@@ -107,6 +102,4 @@ class Pathname;
} \
} while (0);
-talk_base::Pathname GetTalkDirectory();
-
#endif // TALK_BASE_GUNIT_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/helpers.cc b/chromium/third_party/libjingle/source/talk/base/helpers.cc
index b10a3f742a7..691a8131f84 100644
--- a/chromium/third_party/libjingle/source/talk/base/helpers.cc
+++ b/chromium/third_party/libjingle/source/talk/base/helpers.cc
@@ -29,6 +29,7 @@
#include <limits>
+#if defined(FEATURE_ENABLE_SSL)
#include "talk/base/sslconfig.h"
#if defined(SSL_USE_OPENSSL)
#include <openssl/rand.h>
@@ -40,7 +41,8 @@
#include <windows.h>
#include <ntsecapi.h>
#endif // WIN32
-#endif
+#endif // else
+#endif // FEATURE_ENABLED_SSL
#include "talk/base/base64.h"
#include "talk/base/basictypes.h"
@@ -153,6 +155,28 @@ class SecureRandomGenerator : public RandomGenerator {
RtlGenRandomProc rtl_gen_random_;
};
+#elif !defined(FEATURE_ENABLE_SSL)
+
+// No SSL implementation -- use rand()
+class SecureRandomGenerator : public RandomGenerator {
+ public:
+ virtual bool Init(const void* seed, size_t len) {
+ if (len >= 4) {
+ srand(*reinterpret_cast<const int*>(seed));
+ } else {
+ srand(*reinterpret_cast<const char*>(seed));
+ }
+ return true;
+ }
+ virtual bool Generate(void* buf, size_t len) {
+ char* bytes = reinterpret_cast<char*>(buf);
+ for (size_t i = 0; i < len; ++i) {
+ bytes[i] = static_cast<char>(rand());
+ }
+ return true;
+ }
+};
+
#else
#error No SSL implementation has been selected!
diff --git a/chromium/third_party/libjingle/source/talk/base/helpers_unittest.cc b/chromium/third_party/libjingle/source/talk/base/helpers_unittest.cc
index 0fe1d5b36e1..c2cfdb193d3 100644
--- a/chromium/third_party/libjingle/source/talk/base/helpers_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/helpers_unittest.cc
@@ -29,14 +29,26 @@
#include "talk/base/gunit.h"
#include "talk/base/helpers.h"
+#include "talk/base/ssladapter.h"
namespace talk_base {
-TEST(RandomTest, TestCreateRandomId) {
+class RandomTest : public testing::Test {
+ public:
+ static void SetUpTestCase() {
+ talk_base::InitializeSSL();
+ }
+
+ static void TearDownTestCase() {
+ talk_base::CleanupSSL();
+ }
+};
+
+TEST_F(RandomTest, TestCreateRandomId) {
CreateRandomId();
}
-TEST(RandomTest, TestCreateRandomDouble) {
+TEST_F(RandomTest, TestCreateRandomDouble) {
for (int i = 0; i < 100; ++i) {
double r = CreateRandomDouble();
EXPECT_GE(r, 0.0);
@@ -44,11 +56,11 @@ TEST(RandomTest, TestCreateRandomDouble) {
}
}
-TEST(RandomTest, TestCreateNonZeroRandomId) {
+TEST_F(RandomTest, TestCreateNonZeroRandomId) {
EXPECT_NE(0U, CreateRandomNonZeroId());
}
-TEST(RandomTest, TestCreateRandomString) {
+TEST_F(RandomTest, TestCreateRandomString) {
std::string random = CreateRandomString(256);
EXPECT_EQ(256U, random.size());
std::string random2;
@@ -57,7 +69,7 @@ TEST(RandomTest, TestCreateRandomString) {
EXPECT_EQ(256U, random2.size());
}
-TEST(RandomTest, TestCreateRandomForTest) {
+TEST_F(RandomTest, TestCreateRandomForTest) {
// Make sure we get the output we expect.
SetRandomTestMode(true);
EXPECT_EQ(2154761789U, CreateRandomId());
diff --git a/chromium/third_party/libjingle/source/talk/base/httpserver_unittest.cc b/chromium/third_party/libjingle/source/talk/base/httpserver_unittest.cc
index d0e0760af89..6e12cf51205 100644
--- a/chromium/third_party/libjingle/source/talk/base/httpserver_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/httpserver_unittest.cc
@@ -16,12 +16,6 @@ namespace {
"Host: localhost\r\n"
"\r\n";
- const char* const kResponse =
- "HTTP/1.1 200\r\n"
- "Connection: Close\r\n"
- "Content-Length: 0\r\n"
- "\r\n";
-
struct HttpServerMonitor : public sigslot::has_slots<> {
HttpServerTransaction* transaction;
bool server_closed, connection_closed;
diff --git a/chromium/third_party/libjingle/source/talk/base/iosfilesystem.mm b/chromium/third_party/libjingle/source/talk/base/iosfilesystem.mm
new file mode 100644
index 00000000000..aaefcb03fb5
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/iosfilesystem.mm
@@ -0,0 +1,70 @@
+/*
+ * libjingle
+ * Copyright 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This file only exists because various iOS system APIs are only
+// available from Objective-C. See unixfilesystem.cc for the only use
+// (enforced by a lack of a header file).
+
+#import <Foundation/NSPathUtilities.h>
+#import <Foundation/NSProcessInfo.h>
+#include <string.h>
+
+#include "talk/base/common.h"
+#include "talk/base/pathutils.h"
+
+// Return a new[]'d |char*| copy of the UTF8 representation of |s|.
+// Caller owns the returned memory and must use delete[] on it.
+static char* copyString(NSString* s) {
+ const char* utf8 = [s UTF8String];
+ size_t len = strlen(utf8) + 1;
+ char* copy = new char[len];
+ // This uses a new[] + strcpy (instead of strdup) because the
+ // receiver expects to be able to delete[] the returned pointer
+ // (instead of free()ing it).
+ strcpy(copy, utf8);
+ return copy;
+}
+
+// Return a (leaked) copy of a directory name suitable for application data.
+char* IOSDataDirectory() {
+ NSArray* paths = NSSearchPathForDirectoriesInDomains(
+ NSApplicationSupportDirectory, NSUserDomainMask, YES);
+ ASSERT([paths count] == 1);
+ return copyString([paths objectAtIndex:0]);
+}
+
+// Return a (leaked) copy of a directory name suitable for use as a $TEMP.
+char* IOSTempDirectory() {
+ return copyString(NSTemporaryDirectory());
+}
+
+// Return the binary's path.
+void IOSAppName(talk_base::Pathname* path) {
+ NSProcessInfo *pInfo = [NSProcessInfo processInfo];
+ NSString* argv0 = [[pInfo arguments] objectAtIndex:0];
+ path->SetPathname([argv0 UTF8String]);
+}
diff --git a/chromium/third_party/libjingle/source/talk/base/ipaddress.cc b/chromium/third_party/libjingle/source/talk/base/ipaddress.cc
index 46725908d7d..6c2212bf8b5 100644
--- a/chromium/third_party/libjingle/source/talk/base/ipaddress.cc
+++ b/chromium/third_party/libjingle/source/talk/base/ipaddress.cc
@@ -32,7 +32,9 @@
#ifdef OPENBSD
#include <netinet/in_systm.h>
#endif
+#ifndef __native_client__
#include <netinet/ip.h>
+#endif
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
@@ -49,13 +51,11 @@
namespace talk_base {
// Prefixes used for categorizing IPv6 addresses.
-static const in6_addr kULAPrefix = {{{0xfc, 0}}};
static const in6_addr kV4MappedPrefix = {{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0xFF, 0xFF, 0}}};
static const in6_addr k6To4Prefix = {{{0x20, 0x02, 0}}};
static const in6_addr kTeredoPrefix = {{{0x20, 0x01, 0x00, 0x00}}};
static const in6_addr kV4CompatibilityPrefix = {{{0}}};
-static const in6_addr kSiteLocalPrefix = {{{0xfe, 0xc0, 0}}};
static const in6_addr k6BonePrefix = {{{0x3f, 0xfe, 0}}};
bool IPAddress::strip_sensitive_ = false;
diff --git a/chromium/third_party/libjingle/source/talk/base/ipaddress_unittest.cc b/chromium/third_party/libjingle/source/talk/base/ipaddress_unittest.cc
index 424b557cd63..2c03cbdbd06 100644
--- a/chromium/third_party/libjingle/source/talk/base/ipaddress_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/ipaddress_unittest.cc
@@ -42,18 +42,10 @@ static const in6_addr kIPv6PublicAddr = {{{0x24, 0x01, 0xfa, 0x00,
0x00, 0x04, 0x10, 0x00,
0xbe, 0x30, 0x5b, 0xff,
0xfe, 0xe5, 0x00, 0xc3}}};
-static const in6_addr kIPv6CompatAddr = {{{0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0xfe, 0xe5, 0x00, 0xc3}}};
static const in6_addr kIPv4MappedAnyAddr = {{{0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00}}};
-static const in6_addr kIPv4MappedLoopbackAddr = {{{0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff,
- 0x7f, 0x00, 0x00, 0x01}}};
static const in6_addr kIPv4MappedRFC1918Addr = {{{0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff,
@@ -62,10 +54,6 @@ static const in6_addr kIPv4MappedPublicAddr = {{{0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff,
0x01, 0x02, 0x03, 0x04}}};
-static const in6_addr kIPv6AllNodes = {{{0xff, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01}}};
static const std::string kIPv4AnyAddrString = "0.0.0.0";
static const std::string kIPv4LoopbackAddrString = "127.0.0.1";
diff --git a/chromium/third_party/libjingle/source/talk/base/json.cc b/chromium/third_party/libjingle/source/talk/base/json.cc
index af81e06949c..6b9fce1ae91 100644
--- a/chromium/third_party/libjingle/source/talk/base/json.cc
+++ b/chromium/third_party/libjingle/source/talk/base/json.cc
@@ -28,9 +28,9 @@
#include "talk/base/json.h"
#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
-#include <climits>
-#include <cstdlib>
#include <sstream>
bool GetStringFromJson(const Json::Value& in, std::string* out) {
diff --git a/chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.cc.def b/chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.cc.def
index 1f84f30fc55..64fc0dce2b1 100644
--- a/chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.cc.def
+++ b/chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.cc.def
@@ -63,16 +63,17 @@
#error You must define LATE_BINDING_SYMBOL_TABLE_DLL_NAME
#endif
+#define X(sym) #sym,
+const char* const LATE_BINDING_SYMBOL_TABLE_CLASS_NAME::kSymbolNames[] = {
+ LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST
+};
+#undef X
+
const ::talk_base::LateBindingSymbolTable::TableInfo
LATE_BINDING_SYMBOL_TABLE_CLASS_NAME::kTableInfo = {
LATE_BINDING_SYMBOL_TABLE_DLL_NAME,
SYMBOL_TABLE_SIZE,
- (const char *const []){
-#define X(sym) \
- #sym,
-LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST
-#undef X
- },
+ LATE_BINDING_SYMBOL_TABLE_CLASS_NAME::kSymbolNames
};
LATE_BINDING_SYMBOL_TABLE_CLASS_NAME::LATE_BINDING_SYMBOL_TABLE_CLASS_NAME()
diff --git a/chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.h.def b/chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.h.def
index cd8c176f36b..3e1cdab599e 100644
--- a/chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.h.def
+++ b/chromium/third_party/libjingle/source/talk/base/latebindingsymboltable.h.def
@@ -89,6 +89,7 @@ LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST
};
static const ::talk_base::LateBindingSymbolTable::TableInfo kTableInfo;
+ static const char *const kSymbolNames[];
void *table_[SYMBOL_TABLE_SIZE];
diff --git a/chromium/third_party/libjingle/source/talk/base/linux.cc b/chromium/third_party/libjingle/source/talk/base/linux.cc
index 644ec450655..16666f89761 100644
--- a/chromium/third_party/libjingle/source/talk/base/linux.cc
+++ b/chromium/third_party/libjingle/source/talk/base/linux.cc
@@ -250,6 +250,89 @@ bool ConfigParser::ParseLine(std::string* key, std::string* value) {
return true;
}
+#if !defined(GOOGLE_CHROME_BUILD) && !defined(CHROMIUM_BUILD)
+static bool ExpectLineFromStream(FileStream* stream,
+ std::string* out) {
+ StreamResult res = stream->ReadLine(out);
+ if (res != SR_SUCCESS) {
+ if (res != SR_EOS) {
+ LOG(LS_ERROR) << "Error when reading from stream";
+ } else {
+ LOG(LS_ERROR) << "Incorrect number of lines in stream";
+ }
+ return false;
+ }
+ return true;
+}
+
+static void ExpectEofFromStream(FileStream* stream) {
+ std::string unused;
+ StreamResult res = stream->ReadLine(&unused);
+ if (res == SR_SUCCESS) {
+ LOG(LS_WARNING) << "Ignoring unexpected extra lines from stream";
+ } else if (res != SR_EOS) {
+ LOG(LS_WARNING) << "Error when checking for extra lines from stream";
+ }
+}
+
+// For caching the lsb_release output (reading it invokes a sub-process and
+// hence is somewhat expensive).
+static std::string lsb_release_string;
+static CriticalSection lsb_release_string_critsec;
+
+std::string ReadLinuxLsbRelease() {
+ CritScope cs(&lsb_release_string_critsec);
+ if (!lsb_release_string.empty()) {
+ // Have cached result from previous call.
+ return lsb_release_string;
+ }
+ // No cached result. Run lsb_release and parse output.
+ POpenStream lsb_release_output;
+ if (!lsb_release_output.Open("lsb_release -idrcs", "r", NULL)) {
+ LOG_ERR(LS_ERROR) << "Can't run lsb_release";
+ return lsb_release_string; // empty
+ }
+ // Read in the command's output and build the string.
+ std::ostringstream sstr;
+ std::string line;
+ int wait_status;
+
+ if (!ExpectLineFromStream(&lsb_release_output, &line)) {
+ return lsb_release_string; // empty
+ }
+ sstr << "DISTRIB_ID=" << line;
+
+ if (!ExpectLineFromStream(&lsb_release_output, &line)) {
+ return lsb_release_string; // empty
+ }
+ sstr << " DISTRIB_DESCRIPTION=\"" << line << '"';
+
+ if (!ExpectLineFromStream(&lsb_release_output, &line)) {
+ return lsb_release_string; // empty
+ }
+ sstr << " DISTRIB_RELEASE=" << line;
+
+ if (!ExpectLineFromStream(&lsb_release_output, &line)) {
+ return lsb_release_string; // empty
+ }
+ sstr << " DISTRIB_CODENAME=" << line;
+
+ // Should not be anything left.
+ ExpectEofFromStream(&lsb_release_output);
+
+ lsb_release_output.Close();
+ wait_status = lsb_release_output.GetWaitStatus();
+ if (wait_status == -1 ||
+ !WIFEXITED(wait_status) ||
+ WEXITSTATUS(wait_status) != 0) {
+ LOG(LS_WARNING) << "Unexpected exit status from lsb_release";
+ }
+
+ lsb_release_string = sstr.str();
+
+ return lsb_release_string;
+}
+#endif
std::string ReadLinuxUname() {
struct utsname buf;
diff --git a/chromium/third_party/libjingle/source/talk/base/linux.h b/chromium/third_party/libjingle/source/talk/base/linux.h
index 63e30218140..46fa5ed6b27 100644
--- a/chromium/third_party/libjingle/source/talk/base/linux.h
+++ b/chromium/third_party/libjingle/source/talk/base/linux.h
@@ -121,6 +121,11 @@ class ProcCpuInfo {
ConfigParser::MapVector sections_;
};
+#if !defined(GOOGLE_CHROME_BUILD) && !defined(CHROMIUM_BUILD)
+// Builds a string containing the info from lsb_release on a single line.
+std::string ReadLinuxLsbRelease();
+#endif
+
// Returns the output of "uname".
std::string ReadLinuxUname();
diff --git a/chromium/third_party/libjingle/source/talk/base/linux_unittest.cc b/chromium/third_party/libjingle/source/talk/base/linux_unittest.cc
index efc7f87c1e4..f6815141d2b 100644
--- a/chromium/third_party/libjingle/source/talk/base/linux_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/linux_unittest.cc
@@ -105,6 +105,14 @@ TEST(ConfigParser, ParseConfig) {
EXPECT_EQ(true, parser.Parse(&key_val_pairs));
}
+#if !defined(GOOGLE_CHROME_BUILD) && !defined(CHROMIUM_BUILD)
+TEST(ReadLinuxLsbRelease, ReturnsSomething) {
+ std::string str = ReadLinuxLsbRelease();
+ // ChromeOS don't have lsb_release
+ // EXPECT_FALSE(str.empty());
+}
+#endif
+
TEST(ReadLinuxUname, ReturnsSomething) {
std::string str = ReadLinuxUname();
EXPECT_FALSE(str.empty());
diff --git a/chromium/third_party/libjingle/source/talk/base/logging.cc b/chromium/third_party/libjingle/source/talk/base/logging.cc
index 4c7eae172e7..c1d0a53baaf 100644
--- a/chromium/third_party/libjingle/source/talk/base/logging.cc
+++ b/chromium/third_party/libjingle/source/talk/base/logging.cc
@@ -349,6 +349,9 @@ void LogMessage::ConfigureLogging(const char* params, const char* filename) {
}
#endif // WIN32
+ LogToDebug(debug_level);
+
+#if !defined(__native_client__) // No logging to file in NaCl.
scoped_ptr<FileStream> stream;
if (NO_LOGGING != file_level) {
stream.reset(new FileStream);
@@ -357,8 +360,8 @@ void LogMessage::ConfigureLogging(const char* params, const char* filename) {
}
}
- LogToDebug(debug_level);
LogToStream(stream.release(), file_level);
+#endif
}
int LogMessage::ParseLogSeverity(const std::string& value) {
diff --git a/chromium/third_party/libjingle/source/talk/base/logging.h b/chromium/third_party/libjingle/source/talk/base/logging.h
index 49e126bab0c..01636e89fd6 100644
--- a/chromium/third_party/libjingle/source/talk/base/logging.h
+++ b/chromium/third_party/libjingle/source/talk/base/logging.h
@@ -376,6 +376,13 @@ inline bool LogCheckLevel(LoggingSeverity sev) {
LOG_GLE(sev)
#define LAST_SYSTEM_ERROR \
(::GetLastError())
+#elif __native_client__
+#define LOG_ERR_EX(sev, err) \
+ LOG(sev)
+#define LOG_ERR(sev) \
+ LOG(sev)
+#define LAST_SYSTEM_ERROR \
+ (0)
#elif POSIX
#define LOG_ERR_EX(sev, err) \
LOG_ERRNO_EX(sev, err)
diff --git a/chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.h b/chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.h
index f4aeb339768..51dc749d794 100644
--- a/chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.h
+++ b/chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.h
@@ -54,6 +54,8 @@ class MacCocoaSocketServer : public MacBaseSocketServer {
private:
MacCocoaSocketServerHelper* helper_;
NSTimer* timer_; // Weak.
+ // The count of how many times we're inside the NSApplication main loop.
+ int run_count_;
DISALLOW_EVIL_CONSTRUCTORS(MacCocoaSocketServer);
};
diff --git a/chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.mm b/chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.mm
index bf308e610e0..8257e386626 100644
--- a/chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.mm
+++ b/chromium/third_party/libjingle/source/talk/base/maccocoasocketserver.mm
@@ -53,6 +53,25 @@
- (void)timerFired:(NSTimer*)timer {
socketServer_->WakeUp();
}
+
+- (void)breakMainloop {
+ [NSApp stop:self];
+ // NSApp stop only exits after finishing processing of the
+ // current event. Since we're potentially in a timer callback
+ // and not an NSEvent handler, we need to trigger a dummy one
+ // and turn the loop over. We may be able to skip this if we're
+ // on the ss' thread and not inside the app loop already.
+ NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined
+ location:NSMakePoint(0,0)
+ modifierFlags:0
+ timestamp:0
+ windowNumber:0
+ context:nil
+ subtype:0
+ data1:0
+ data2:0];
+ [NSApp postEvent:event atStart:NO];
+}
@end
namespace talk_base {
@@ -60,6 +79,7 @@ namespace talk_base {
MacCocoaSocketServer::MacCocoaSocketServer() {
helper_ = [[MacCocoaSocketServerHelper alloc] initWithSocketServer:this];
timer_ = nil;
+ run_count_ = 0;
// Initialize the shared NSApplication
[NSApplication sharedApplication];
@@ -71,12 +91,19 @@ MacCocoaSocketServer::~MacCocoaSocketServer() {
[helper_ release];
}
+// ::Wait is reentrant, for example when blocking on another thread while
+// responding to I/O. Calls to [NSApp] MUST be made from the main thread
+// only!
bool MacCocoaSocketServer::Wait(int cms, bool process_io) {
talk_base::ScopedAutoreleasePool pool;
if (!process_io && cms == 0) {
// No op.
return true;
}
+ if ([NSApp isRunning]) {
+ // Only allow reentrant waiting if we're in a blocking send.
+ ASSERT(!process_io && cms == kForever);
+ }
if (!process_io) {
// No way to listen to common modes and not get socket events, unless
@@ -96,7 +123,9 @@ bool MacCocoaSocketServer::Wait(int cms, bool process_io) {
}
// Run until WakeUp is called, which will call stop and exit this loop.
+ run_count_++;
[NSApp run];
+ run_count_--;
if (!process_io) {
// Reenable them. Hopefully this won't cause spurious callbacks or
@@ -107,28 +136,22 @@ bool MacCocoaSocketServer::Wait(int cms, bool process_io) {
return true;
}
+// Can be called from any thread. Post a message back to the main thread to
+// break out of the NSApp loop.
void MacCocoaSocketServer::WakeUp() {
- // Timer has either fired or shortcutted.
- [timer_ invalidate];
- [timer_ release];
- timer_ = nil;
- [NSApp stop:nil];
+ if (timer_ != nil) {
+ [timer_ invalidate];
+ [timer_ release];
+ timer_ = nil;
+ }
- // NSApp stop only exits after finishing processing of the
- // current event. Since we're potentially in a timer callback
- // and not an NSEvent handler, we need to trigger a dummy one
- // and turn the loop over. We may be able to skip this if we're
- // on the ss' thread and not inside the app loop already.
- NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined
- location:NSMakePoint(0,0)
- modifierFlags:0
- timestamp:0
- windowNumber:0
- context:nil
- subtype:1
- data1:1
- data2:1];
- [NSApp postEvent:event atStart:YES];
+ // [NSApp isRunning] returns unexpected results when called from another
+ // thread. Maintain our own count of how many times to break the main loop.
+ if (run_count_ > 0) {
+ [helper_ performSelectorOnMainThread:@selector(breakMainloop)
+ withObject:nil
+ waitUntilDone:false];
+ }
}
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/messagedigest.cc b/chromium/third_party/libjingle/source/talk/base/messagedigest.cc
index d91d0674b5f..975991db7c0 100644
--- a/chromium/third_party/libjingle/source/talk/base/messagedigest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/messagedigest.cc
@@ -70,6 +70,19 @@ MessageDigest* MessageDigestFactory::Create(const std::string& alg) {
#endif
}
+bool IsFips180DigestAlgorithm(const std::string& alg) {
+ // These are the FIPS 180 algorithms. According to RFC 4572 Section 5,
+ // "Self-signed certificates (for which legacy certificates are not a
+ // consideration) MUST use one of the FIPS 180 algorithms (SHA-1,
+ // SHA-224, SHA-256, SHA-384, or SHA-512) as their signature algorithm,
+ // and thus also MUST use it to calculate certificate fingerprints."
+ return alg == DIGEST_SHA_1 ||
+ alg == DIGEST_SHA_224 ||
+ alg == DIGEST_SHA_256 ||
+ alg == DIGEST_SHA_384 ||
+ alg == DIGEST_SHA_512;
+}
+
size_t ComputeDigest(MessageDigest* digest, const void* input, size_t in_len,
void* output, size_t out_len) {
digest->Update(input, in_len);
diff --git a/chromium/third_party/libjingle/source/talk/base/messagedigest.h b/chromium/third_party/libjingle/source/talk/base/messagedigest.h
index 734082b0166..e8f303f2666 100644
--- a/chromium/third_party/libjingle/source/talk/base/messagedigest.h
+++ b/chromium/third_party/libjingle/source/talk/base/messagedigest.h
@@ -60,6 +60,9 @@ class MessageDigestFactory {
static MessageDigest* Create(const std::string& alg);
};
+// A whitelist of approved digest algorithms from RFC 4572 (FIPS 180).
+bool IsFips180DigestAlgorithm(const std::string& alg);
+
// Functions to create hashes.
// Computes the hash of |in_len| bytes of |input|, using the |digest| hash
diff --git a/chromium/third_party/libjingle/source/talk/base/messagehandler.h b/chromium/third_party/libjingle/source/talk/base/messagehandler.h
index 913edf8ce26..6494f2b2561 100644
--- a/chromium/third_party/libjingle/source/talk/base/messagehandler.h
+++ b/chromium/third_party/libjingle/source/talk/base/messagehandler.h
@@ -38,16 +38,48 @@ struct Message;
class MessageHandler {
public:
+ virtual ~MessageHandler();
virtual void OnMessage(Message* msg) = 0;
protected:
MessageHandler() {}
- virtual ~MessageHandler();
private:
DISALLOW_COPY_AND_ASSIGN(MessageHandler);
};
+// Helper class to facilitate executing a functor on a thread.
+template <class ReturnT, class FunctorT>
+class FunctorMessageHandler : public MessageHandler {
+ public:
+ explicit FunctorMessageHandler(const FunctorT& functor)
+ : functor_(functor) {}
+ virtual void OnMessage(Message* msg) {
+ result_ = functor_();
+ }
+ const ReturnT& result() const { return result_; }
+
+ private:
+ FunctorT functor_;
+ ReturnT result_;
+};
+
+// Specialization for ReturnT of void.
+template <class FunctorT>
+class FunctorMessageHandler<void, FunctorT> : public MessageHandler {
+ public:
+ explicit FunctorMessageHandler(const FunctorT& functor)
+ : functor_(functor) {}
+ virtual void OnMessage(Message* msg) {
+ functor_();
+ }
+ void result() const {}
+
+ private:
+ FunctorT functor_;
+};
+
+
} // namespace talk_base
#endif // TALK_BASE_MESSAGEHANDLER_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/messagequeue.cc b/chromium/third_party/libjingle/source/talk/base/messagequeue.cc
index 15b700ffe48..7bda92411c4 100644
--- a/chromium/third_party/libjingle/source/talk/base/messagequeue.cc
+++ b/chromium/third_party/libjingle/source/talk/base/messagequeue.cc
@@ -32,8 +32,13 @@
#include "talk/base/common.h"
#include "talk/base/logging.h"
#include "talk/base/messagequeue.h"
+#if defined(__native_client__)
+#include "talk/base/nullsocketserver.h"
+typedef talk_base::NullSocketServer DefaultSocketServer;
+#else
#include "talk/base/physicalsocketserver.h"
-
+typedef talk_base::PhysicalSocketServer DefaultSocketServer;
+#endif
namespace talk_base {
@@ -121,7 +126,7 @@ void MessageQueueManager::ClearInternal(MessageHandler *handler) {
// MessageQueue
MessageQueue::MessageQueue(SocketServer* ss)
- : ss_(ss), fStop_(false), fPeekKeep_(false), active_(false),
+ : ss_(ss), fStop_(false), fPeekKeep_(false),
dmsgq_next_num_(0) {
if (!ss_) {
// Currently, MessageQueue holds a socket server, and is the base class for
@@ -129,10 +134,11 @@ MessageQueue::MessageQueue(SocketServer* ss)
// server, and provide it to the MessageQueue, since the Thread controls
// the I/O model, and MQ is agnostic to those details. Anyway, this causes
// messagequeue_unittest to depend on network libraries... yuck.
- default_ss_.reset(new PhysicalSocketServer());
+ default_ss_.reset(new DefaultSocketServer());
ss_ = default_ss_.get();
}
ss_->SetMessageQueue(this);
+ MessageQueueManager::Add(this);
}
MessageQueue::~MessageQueue() {
@@ -140,10 +146,8 @@ MessageQueue::~MessageQueue() {
// that it always gets called when the queue
// is going away.
SignalQueueDestroyed();
- if (active_) {
- MessageQueueManager::Remove(this);
- Clear(NULL);
- }
+ MessageQueueManager::Remove(this);
+ Clear(NULL);
if (ss_) {
ss_->SetMessageQueue(NULL);
}
@@ -291,7 +295,6 @@ void MessageQueue::Post(MessageHandler *phandler, uint32 id,
// Signal for the multiplexer to return
CritScope cs(&crit_);
- EnsureActive();
Message msg;
msg.phandler = phandler;
msg.message_id = id;
@@ -313,7 +316,6 @@ void MessageQueue::DoDelayPost(int cmsDelay, uint32 tstamp,
// Signal for the multiplexer to return.
CritScope cs(&crit_);
- EnsureActive();
Message msg;
msg.phandler = phandler;
msg.message_id = id;
@@ -396,12 +398,4 @@ void MessageQueue::Dispatch(Message *pmsg) {
pmsg->phandler->OnMessage(pmsg);
}
-void MessageQueue::EnsureActive() {
- ASSERT(crit_.CurrentThreadIsOwner());
- if (!active_) {
- active_ = true;
- MessageQueueManager::Add(this);
- }
-}
-
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/messagequeue.h b/chromium/third_party/libjingle/source/talk/base/messagequeue.h
index 7b38ba0082d..dc2b5a89a53 100644
--- a/chromium/third_party/libjingle/source/talk/base/messagequeue.h
+++ b/chromium/third_party/libjingle/source/talk/base/messagequeue.h
@@ -28,8 +28,9 @@
#ifndef TALK_BASE_MESSAGEQUEUE_H_
#define TALK_BASE_MESSAGEQUEUE_H_
+#include <string.h>
+
#include <algorithm>
-#include <cstring>
#include <list>
#include <queue>
#include <vector>
@@ -74,7 +75,7 @@ class MessageQueueManager {
void ClearInternal(MessageHandler *handler);
static MessageQueueManager* instance_;
- // This list contains 'active' MessageQueues.
+ // This list contains all live MessageQueues.
std::vector<MessageQueue *> message_queues_;
CriticalSection crit_;
};
@@ -246,7 +247,6 @@ class MessageQueue {
void reheap() { make_heap(c.begin(), c.end(), comp); }
};
- void EnsureActive();
void DoDelayPost(int cmsDelay, uint32 tstamp, MessageHandler *phandler,
uint32 id, MessageData* pdata);
@@ -257,9 +257,6 @@ class MessageQueue {
bool fStop_;
bool fPeekKeep_;
Message msgPeek_;
- // A message queue is active if it has ever had a message posted to it.
- // This also corresponds to being in MessageQueueManager's global list.
- bool active_;
MessageList msgq_;
PriorityQueue dmsgq_;
uint32 dmsgq_next_num_;
diff --git a/chromium/third_party/libjingle/source/talk/base/natserver.cc b/chromium/third_party/libjingle/source/talk/base/natserver.cc
index 46980487175..f69baa0c427 100644
--- a/chromium/third_party/libjingle/source/talk/base/natserver.cc
+++ b/chromium/third_party/libjingle/source/talk/base/natserver.cc
@@ -126,8 +126,8 @@ void NATServer::OnInternalPacket(
iter->second->WhitelistInsert(dest_addr);
// Send the packet to its intended destination.
- iter->second->socket->SendTo(buf + length, size - length, dest_addr,
- DSCP_NO_CHANGE);
+ talk_base::PacketOptions options;
+ iter->second->socket->SendTo(buf + length, size - length, dest_addr, options);
}
void NATServer::OnExternalPacket(
@@ -154,9 +154,10 @@ void NATServer::OnExternalPacket(
size + kNATEncodedIPv6AddressSize,
remote_addr);
// Copy the data part after the address.
- std::memcpy(real_buf.get() + addrlength, buf, size);
+ talk_base::PacketOptions options;
+ memcpy(real_buf.get() + addrlength, buf, size);
server_socket_->SendTo(real_buf.get(), size + addrlength,
- iter->second->route.source(), DSCP_NO_CHANGE);
+ iter->second->route.source(), options);
}
void NATServer::Translate(const SocketAddressPair& route) {
diff --git a/chromium/third_party/libjingle/source/talk/base/natsocketfactory.cc b/chromium/third_party/libjingle/source/talk/base/natsocketfactory.cc
index 395069e6658..6ce09fd251c 100644
--- a/chromium/third_party/libjingle/source/talk/base/natsocketfactory.cc
+++ b/chromium/third_party/libjingle/source/talk/base/natsocketfactory.cc
@@ -47,12 +47,12 @@ size_t PackAddressForNAT(char* buf, size_t buf_size,
if (family == AF_INET) {
ASSERT(buf_size >= kNATEncodedIPv4AddressSize);
in_addr v4addr = ip.ipv4_address();
- std::memcpy(&buf[4], &v4addr, kNATEncodedIPv4AddressSize - 4);
+ memcpy(&buf[4], &v4addr, kNATEncodedIPv4AddressSize - 4);
return kNATEncodedIPv4AddressSize;
} else if (family == AF_INET6) {
ASSERT(buf_size >= kNATEncodedIPv6AddressSize);
in6_addr v6addr = ip.ipv6_address();
- std::memcpy(&buf[4], &v6addr, kNATEncodedIPv6AddressSize - 4);
+ memcpy(&buf[4], &v6addr, kNATEncodedIPv6AddressSize - 4);
return kNATEncodedIPv6AddressSize;
}
return 0U;
@@ -159,7 +159,7 @@ class NATSocket : public AsyncSocket, public sigslot::has_slots<> {
size + kNATEncodedIPv6AddressSize,
addr);
size_t encoded_size = size + addrlength;
- std::memcpy(buf.get() + addrlength, data, size);
+ memcpy(buf.get() + addrlength, data, size);
int result = socket_->SendTo(buf.get(), encoded_size, server_addr_);
if (result >= 0) {
ASSERT(result == static_cast<int>(encoded_size));
@@ -196,7 +196,7 @@ class NATSocket : public AsyncSocket, public sigslot::has_slots<> {
SocketAddress real_remote_addr;
size_t addrlength =
UnpackAddressFromNAT(buf_, result, &real_remote_addr);
- std::memcpy(data, buf_ + addrlength, result - addrlength);
+ memcpy(data, buf_ + addrlength, result - addrlength);
// Make sure this packet should be delivered before returning it.
if (!connected_ || (real_remote_addr == remote_addr_)) {
diff --git a/chromium/third_party/libjingle/source/talk/base/nattypes.cc b/chromium/third_party/libjingle/source/talk/base/nattypes.cc
index 290c3adde77..da1d0116110 100644
--- a/chromium/third_party/libjingle/source/talk/base/nattypes.cc
+++ b/chromium/third_party/libjingle/source/talk/base/nattypes.cc
@@ -25,7 +25,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <cassert>
+#include <assert.h>
#include "talk/base/nattypes.h"
diff --git a/chromium/third_party/libjingle/source/talk/base/nethelpers.cc b/chromium/third_party/libjingle/source/talk/base/nethelpers.cc
index e6310ac45fe..057f34ddc15 100644
--- a/chromium/third_party/libjingle/source/talk/base/nethelpers.cc
+++ b/chromium/third_party/libjingle/source/talk/base/nethelpers.cc
@@ -34,12 +34,18 @@
#endif
#include "talk/base/byteorder.h"
+#include "talk/base/logging.h"
#include "talk/base/signalthread.h"
namespace talk_base {
int ResolveHostname(const std::string& hostname, int family,
std::vector<IPAddress>* addresses) {
+#ifdef __native_client__
+ ASSERT(false);
+ LOG(LS_WARNING) << "ResolveHostname() is not implemented for NaCl";
+ return -1;
+#else // __native_client__
if (!addresses) {
return -1;
}
@@ -64,6 +70,7 @@ int ResolveHostname(const std::string& hostname, int family,
}
freeaddrinfo(result);
return 0;
+#endif // !__native_client__
}
// AsyncResolver
@@ -83,7 +90,7 @@ bool AsyncResolver::GetResolvedAddress(int family, SocketAddress* addr) const {
*addr = addr_;
for (size_t i = 0; i < addresses_.size(); ++i) {
if (family == addresses_[i].family()) {
- addr->SetIP(addresses_[i]);
+ addr->SetResolvedIP(addresses_[i]);
return true;
}
}
diff --git a/chromium/third_party/libjingle/source/talk/base/nethelpers.h b/chromium/third_party/libjingle/source/talk/base/nethelpers.h
index a49f48ac7cd..5b385bbc509 100644
--- a/chromium/third_party/libjingle/source/talk/base/nethelpers.h
+++ b/chromium/third_party/libjingle/source/talk/base/nethelpers.h
@@ -30,7 +30,7 @@
#ifdef POSIX
#include <netdb.h>
-#include <cstddef>
+#include <stddef.h>
#elif WIN32
#include <winsock2.h> // NOLINT
#endif
diff --git a/chromium/third_party/libjingle/source/talk/base/network.cc b/chromium/third_party/libjingle/source/talk/base/network.cc
index d4dda138135..829507aec7d 100644
--- a/chromium/third_party/libjingle/source/talk/base/network.cc
+++ b/chromium/third_party/libjingle/source/talk/base/network.cc
@@ -38,7 +38,7 @@
#if defined(ANDROID) || defined(LINUX)
#include <linux/if.h>
#include <linux/route.h>
-#else
+#elif !defined(__native_client__)
#include <net/if.h>
#endif
#include <sys/socket.h>
@@ -46,11 +46,13 @@
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
+
#ifdef ANDROID
#include "talk/base/ifaddrs-android.h"
-#else
+#elif !defined(__native_client__)
#include <ifaddrs.h>
#endif
+
#endif // POSIX
#ifdef WIN32
@@ -58,8 +60,9 @@
#include <Iphlpapi.h>
#endif
+#include <stdio.h>
+
#include <algorithm>
-#include <cstdio>
#include "talk/base/logging.h"
#include "talk/base/scoped_ptr.h"
@@ -77,16 +80,7 @@ const uint32 kSignalNetworksMessage = 2;
// Fetch list of networks every two seconds.
const int kNetworksUpdateIntervalMs = 2000;
-
-// Makes a string key for this network. Used in the network manager's maps.
-// Network objects are keyed on interface name, network prefix and the
-// length of that prefix.
-std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
- int prefix_length) {
- std::ostringstream ost;
- ost << name << "%" << prefix.ToString() << "/" << prefix_length;
- return ost.str();
-}
+const int kHighestNetworkPreference = 127;
bool CompareNetworks(const Network* a, const Network* b) {
if (a->prefix_length() == b->prefix_length()) {
@@ -97,9 +91,54 @@ bool CompareNetworks(const Network* a, const Network* b) {
return a->name() < b->name();
}
+bool SortNetworks(const Network* a, const Network* b) {
+ // Network types will be preferred above everything else while sorting
+ // Networks.
+
+ // Networks are sorted first by type.
+ if (a->type() != b->type()) {
+ return a->type() < b->type();
+ }
+
+ // After type, networks are sorted by IP address precedence values
+ // from RFC 3484-bis
+ if (IPAddressPrecedence(a->ip()) != IPAddressPrecedence(b->ip())) {
+ return IPAddressPrecedence(a->ip()) > IPAddressPrecedence(b->ip());
+ }
+
+ // TODO(mallinath) - Add VPN and Link speed conditions while sorting.
+
+ // Networks are sorted last by key.
+ return a->key() > b->key();
+}
+
+std::string AdapterTypeToString(AdapterType type) {
+ switch (type) {
+ case ADAPTER_TYPE_UNKNOWN:
+ return "Unknown";
+ case ADAPTER_TYPE_ETHERNET:
+ return "Ethernet";
+ case ADAPTER_TYPE_WIFI:
+ return "Wifi";
+ case ADAPTER_TYPE_CELLULAR:
+ return "Cellular";
+ case ADAPTER_TYPE_VPN:
+ return "VPN";
+ default:
+ ASSERT(false);
+ return std::string();
+ }
+}
} // namespace
+std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
+ int prefix_length) {
+ std::ostringstream ost;
+ ost << name << "%" << prefix.ToString() << "/" << prefix_length;
+ return ost.str();
+}
+
NetworkManager::NetworkManager() {
}
@@ -178,6 +217,29 @@ void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
}
}
networks_ = merged_list;
+
+ // If the network lists changes, we resort it.
+ if (changed) {
+ std::sort(networks_.begin(), networks_.end(), SortNetworks);
+ // Now network interfaces are sorted, we should set the preference value
+ // for each of the interfaces we are planning to use.
+ // Preference order of network interfaces might have changed from previous
+ // sorting due to addition of higher preference network interface.
+ // Since we have already sorted the network interfaces based on our
+ // requirements, we will just assign a preference value starting with 127,
+ // in decreasing order.
+ int pref = kHighestNetworkPreference;
+ for (NetworkList::const_iterator iter = networks_.begin();
+ iter != networks_.end(); ++iter) {
+ (*iter)->set_preference(pref);
+ if (pref > 0) {
+ --pref;
+ } else {
+ LOG(LS_ERROR) << "Too many network interfaces to handle!";
+ break;
+ }
+ }
+ }
}
BasicNetworkManager::BasicNetworkManager()
@@ -188,7 +250,16 @@ BasicNetworkManager::BasicNetworkManager()
BasicNetworkManager::~BasicNetworkManager() {
}
-#if defined(POSIX)
+#if defined(__native_client__)
+
+bool BasicNetworkManager::CreateNetworks(bool include_ignored,
+ NetworkList* networks) const {
+ ASSERT(false);
+ LOG(LS_WARNING) << "BasicNetworkManager doesn't work on NaCl yet";
+ return false;
+}
+
+#elif defined(POSIX)
void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
bool include_ignored,
NetworkList* networks) const {
@@ -229,6 +300,7 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
continue;
}
}
+
int prefix_length = CountIPMaskBits(mask);
prefix = TruncateIP(ip, prefix_length);
std::string key = MakeNetworkKey(std::string(cursor->ifa_name),
@@ -375,6 +447,7 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored,
continue;
}
}
+
IPAddress prefix;
int prefix_length = GetPrefix(prefixlist, ip, &prefix);
std::string key = MakeNetworkKey(name, prefix, prefix_length);
@@ -553,9 +626,17 @@ void BasicNetworkManager::DumpNetworks(bool include_ignored) {
Network::Network(const std::string& name, const std::string& desc,
const IPAddress& prefix, int prefix_length)
: name_(name), description_(desc), prefix_(prefix),
- prefix_length_(prefix_length), scope_id_(0), ignored_(false),
- uniform_numerator_(0), uniform_denominator_(0), exponential_numerator_(0),
- exponential_denominator_(0) {
+ prefix_length_(prefix_length),
+ key_(MakeNetworkKey(name, prefix, prefix_length)), scope_id_(0),
+ ignored_(false), type_(ADAPTER_TYPE_UNKNOWN), preference_(0) {
+}
+
+Network::Network(const std::string& name, const std::string& desc,
+ const IPAddress& prefix, int prefix_length, AdapterType type)
+ : name_(name), description_(desc), prefix_(prefix),
+ prefix_length_(prefix_length),
+ key_(MakeNetworkKey(name, prefix, prefix_length)), scope_id_(0),
+ ignored_(false), type_(type), preference_(0) {
}
std::string Network::ToString() const {
@@ -563,7 +644,8 @@ std::string Network::ToString() const {
// Print out the first space-terminated token of the network desc, plus
// the IP address.
ss << "Net[" << description_.substr(0, description_.find(' '))
- << ":" << prefix_.ToSensitiveString() << "/" << prefix_length_ << "]";
+ << ":" << prefix_.ToSensitiveString() << "/" << prefix_length_
+ << ":" << AdapterTypeToString(type_) << "]";
return ss.str();
}
@@ -589,4 +671,5 @@ bool Network::SetIPs(const std::vector<IPAddress>& ips, bool changed) {
ips_ = ips;
return changed;
}
+
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/network.h b/chromium/third_party/libjingle/source/talk/base/network.h
index 63f3e732fd9..2be81bb1c8d 100644
--- a/chromium/third_party/libjingle/source/talk/base/network.h
+++ b/chromium/third_party/libjingle/source/talk/base/network.h
@@ -45,9 +45,23 @@ struct ifaddrs;
namespace talk_base {
class Network;
-class NetworkSession;
class Thread;
+enum AdapterType {
+ // This enum resembles the one in Chromium net::ConnectionType.
+ ADAPTER_TYPE_UNKNOWN = 0,
+ ADAPTER_TYPE_ETHERNET = 1,
+ ADAPTER_TYPE_WIFI = 2,
+ ADAPTER_TYPE_CELLULAR = 3,
+ ADAPTER_TYPE_VPN = 4
+};
+
+// Makes a string key for this network. Used in the network manager's maps.
+// Network objects are keyed on interface name, network prefix and the
+// length of that prefix.
+std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
+ int prefix_length);
+
// Generic network manager interface. It provides list of local
// networks.
class NetworkManager {
@@ -168,10 +182,12 @@ class BasicNetworkManager : public NetworkManagerBase,
// Represents a Unix-type network interface, with a name and single address.
class Network {
public:
- Network() : prefix_(INADDR_ANY), scope_id_(0) {}
Network(const std::string& name, const std::string& description,
const IPAddress& prefix, int prefix_length);
+ Network(const std::string& name, const std::string& description,
+ const IPAddress& prefix, int prefix_length, AdapterType type);
+
// Returns the name of the interface this network is associated wtih.
const std::string& name() const { return name_; }
@@ -184,6 +200,10 @@ class Network {
// Returns the length, in bits, of this network's prefix.
int prefix_length() const { return prefix_length_; }
+ // |key_| has unique value per network interface. Used in sorting network
+ // interfaces. Key is derived from interface name and it's prefix.
+ std::string key() const { return key_; }
+
// Returns the Network's current idea of the 'best' IP it has.
// 'Best' currently means the first one added.
// TODO: We should be preferring temporary addresses.
@@ -215,27 +235,28 @@ class Network {
bool ignored() const { return ignored_; }
void set_ignored(bool ignored) { ignored_ = ignored; }
+ AdapterType type() const { return type_; }
+ int preference() const { return preference_; }
+ void set_preference(int preference) { preference_ = preference; }
+
// Debugging description of this network
std::string ToString() const;
private:
- typedef std::vector<NetworkSession*> SessionList;
-
std::string name_;
std::string description_;
IPAddress prefix_;
int prefix_length_;
+ std::string key_;
std::vector<IPAddress> ips_;
int scope_id_;
bool ignored_;
- SessionList sessions_;
- double uniform_numerator_;
- double uniform_denominator_;
- double exponential_numerator_;
- double exponential_denominator_;
+ AdapterType type_;
+ int preference_;
friend class NetworkManager;
};
+
} // namespace talk_base
#endif // TALK_BASE_NETWORK_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/network_unittest.cc b/chromium/third_party/libjingle/source/talk/base/network_unittest.cc
index e11e78daa4a..56b11c617aa 100644
--- a/chromium/third_party/libjingle/source/talk/base/network_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/network_unittest.cc
@@ -527,6 +527,51 @@ TEST_F(NetworkTest, TestIPv6Toggle) {
}
}
+TEST_F(NetworkTest, TestNetworkListSorting) {
+ BasicNetworkManager manager;
+ Network ipv4_network1("test_eth0", "Test Network Adapter 1",
+ IPAddress(0x12345600U), 24);
+ ipv4_network1.AddIP(IPAddress(0x12345600U));
+
+ IPAddress ip;
+ IPAddress prefix;
+ EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:abcd:efab:cdef", &ip));
+ prefix = TruncateIP(ip, 64);
+ Network ipv6_eth1_publicnetwork1_ip1("test_eth1", "Test NetworkAdapter 2",
+ prefix, 64);
+ ipv6_eth1_publicnetwork1_ip1.AddIP(ip);
+
+ NetworkManager::NetworkList list;
+ list.push_back(new Network(ipv4_network1));
+ list.push_back(new Network(ipv6_eth1_publicnetwork1_ip1));
+ Network* net1 = list[0];
+ Network* net2 = list[1];
+
+ bool changed = false;
+ MergeNetworkList(manager, list, &changed);
+ ASSERT_TRUE(changed);
+ // After sorting IPv6 network should be higher order than IPv4 networks.
+ EXPECT_TRUE(net1->preference() < net2->preference());
+}
+
+TEST_F(NetworkTest, TestNetworkAdapterTypes) {
+ Network wifi("wlan0", "Wireless Adapter", IPAddress(0x12345600U), 24,
+ ADAPTER_TYPE_WIFI);
+ EXPECT_EQ(ADAPTER_TYPE_WIFI, wifi.type());
+ Network ethernet("eth0", "Ethernet", IPAddress(0x12345600U), 24,
+ ADAPTER_TYPE_ETHERNET);
+ EXPECT_EQ(ADAPTER_TYPE_ETHERNET, ethernet.type());
+ Network cellular("test_cell", "Cellular Adapter", IPAddress(0x12345600U), 24,
+ ADAPTER_TYPE_CELLULAR);
+ EXPECT_EQ(ADAPTER_TYPE_CELLULAR, cellular.type());
+ Network vpn("bridge_test", "VPN Adapter", IPAddress(0x12345600U), 24,
+ ADAPTER_TYPE_VPN);
+ EXPECT_EQ(ADAPTER_TYPE_VPN, vpn.type());
+ Network unknown("test", "Test Adapter", IPAddress(0x12345600U), 24,
+ ADAPTER_TYPE_UNKNOWN);
+ EXPECT_EQ(ADAPTER_TYPE_UNKNOWN, unknown.type());
+}
+
#if defined(POSIX)
// Verify that we correctly handle interfaces with no address.
TEST_F(NetworkTest, TestConvertIfAddrsNoAddress) {
diff --git a/chromium/third_party/libjingle/source/talk/base/nssidentity.cc b/chromium/third_party/libjingle/source/talk/base/nssidentity.cc
index 053035e562e..a0cd8b217bb 100644
--- a/chromium/third_party/libjingle/source/talk/base/nssidentity.cc
+++ b/chromium/third_party/libjingle/source/talk/base/nssidentity.cc
@@ -48,9 +48,16 @@
#include "talk/base/logging.h"
#include "talk/base/helpers.h"
#include "talk/base/nssstreamadapter.h"
+#include "talk/base/safe_conversions.h"
namespace talk_base {
+// Certificate validity lifetime in seconds.
+static const int CERTIFICATE_LIFETIME = 60*60*24*30; // 30 days, arbitrarily
+// Certificate validity window in seconds.
+// This is to compensate for slightly incorrect system clocks.
+static const int CERTIFICATE_WINDOW = -60*60*24;
+
NSSKeyPair::~NSSKeyPair() {
if (privkey_)
SECKEY_DestroyPrivateKey(privkey_);
@@ -137,7 +144,7 @@ NSSCertificate *NSSCertificate::FromPEMString(const std::string &pem_string) {
SECItem der_cert;
der_cert.data = reinterpret_cast<unsigned char *>(const_cast<char *>(
der.data()));
- der_cert.len = der.size();
+ der_cert.len = checked_cast<unsigned int>(der.size());
CERTCertificate *cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
&der_cert, NULL, PR_FALSE, PR_TRUE);
@@ -163,8 +170,49 @@ void NSSCertificate::ToDER(Buffer* der_buffer) const {
der_buffer->SetData(certificate_->derCert.data, certificate_->derCert.len);
}
-bool NSSCertificate::GetDigestLength(const std::string &algorithm,
- std::size_t *length) {
+static bool Certifies(CERTCertificate* parent, CERTCertificate* child) {
+ // TODO(bemasc): Identify stricter validation checks to use here. In the
+ // context of some future identity standard, it might make sense to check
+ // the certificates' roles, expiration dates, self-signatures (if
+ // self-signed), certificate transparency logging, or many other attributes.
+ // NOTE: Future changes to this validation may reject some previously allowed
+ // certificate chains. Users should be advised not to deploy chained
+ // certificates except in controlled environments until the validity
+ // requirements are finalized.
+
+ // Check that the parent's name is the same as the child's claimed issuer.
+ SECComparison name_status =
+ CERT_CompareName(&child->issuer, &parent->subject);
+ if (name_status != SECEqual)
+ return false;
+
+ // Extract the parent's public key, or fail if the key could not be read
+ // (e.g. certificate is corrupted).
+ SECKEYPublicKey* parent_key = CERT_ExtractPublicKey(parent);
+ if (!parent_key)
+ return false;
+
+ // Check that the parent's privkey was actually used to generate the child's
+ // signature.
+ SECStatus verified = CERT_VerifySignedDataWithPublicKey(
+ &child->signatureWrap, parent_key, NULL);
+ SECKEY_DestroyPublicKey(parent_key);
+ return verified == SECSuccess;
+}
+
+bool NSSCertificate::IsValidChain(const CERTCertList* cert_list) {
+ CERTCertListNode* child = CERT_LIST_HEAD(cert_list);
+ for (CERTCertListNode* parent = CERT_LIST_NEXT(child);
+ !CERT_LIST_END(parent, cert_list);
+ child = parent, parent = CERT_LIST_NEXT(parent)) {
+ if (!Certifies(parent->cert, child->cert))
+ return false;
+ }
+ return true;
+}
+
+bool NSSCertificate::GetDigestLength(const std::string& algorithm,
+ size_t* length) {
const SECHashObject *ho;
if (!GetDigestObject(algorithm, &ho))
@@ -223,9 +271,10 @@ bool NSSCertificate::GetSignatureDigestAlgorithm(std::string* algorithm) const {
return true;
}
-bool NSSCertificate::ComputeDigest(const std::string &algorithm,
- unsigned char *digest, std::size_t size,
- std::size_t *length) const {
+bool NSSCertificate::ComputeDigest(const std::string& algorithm,
+ unsigned char* digest,
+ size_t size,
+ size_t* length) const {
const SECHashObject *ho;
if (!GetDigestObject(algorithm, &ho))
@@ -299,23 +348,25 @@ bool NSSCertificate::GetDigestObject(const std::string &algorithm,
}
-NSSIdentity *NSSIdentity::Generate(const std::string &common_name) {
- std::string subject_name_string = "CN=" + common_name;
+NSSIdentity* NSSIdentity::GenerateInternal(const SSLIdentityParams& params) {
+ std::string subject_name_string = "CN=" + params.common_name;
CERTName *subject_name = CERT_AsciiToName(
const_cast<char *>(subject_name_string.c_str()));
NSSIdentity *identity = NULL;
CERTSubjectPublicKeyInfo *spki = NULL;
CERTCertificateRequest *certreq = NULL;
- CERTValidity *validity;
+ CERTValidity *validity = NULL;
CERTCertificate *certificate = NULL;
NSSKeyPair *keypair = NSSKeyPair::Generate();
SECItem inner_der;
SECStatus rv;
PLArenaPool* arena;
SECItem signed_cert;
- PRTime not_before, not_after;
PRTime now = PR_Now();
- PRTime one_day;
+ PRTime not_before =
+ now + static_cast<PRTime>(params.not_before) * PR_USEC_PER_SEC;
+ PRTime not_after =
+ now + static_cast<PRTime>(params.not_after) * PR_USEC_PER_SEC;
inner_der.len = 0;
inner_der.data = NULL;
@@ -342,11 +393,6 @@ NSSIdentity *NSSIdentity::Generate(const std::string &common_name) {
goto fail;
}
- one_day = 86400;
- one_day *= PR_USEC_PER_SEC;
- not_before = now - one_day;
- not_after = now + 30 * one_day;
-
validity = CERT_CreateValidity(not_before, not_after);
if (!validity) {
LOG(LS_ERROR) << "Couldn't create validity";
@@ -408,6 +454,18 @@ NSSIdentity *NSSIdentity::Generate(const std::string &common_name) {
return identity;
}
+NSSIdentity* NSSIdentity::Generate(const std::string &common_name) {
+ SSLIdentityParams params;
+ params.common_name = common_name;
+ params.not_before = CERTIFICATE_WINDOW;
+ params.not_after = CERTIFICATE_LIFETIME;
+ return GenerateInternal(params);
+}
+
+NSSIdentity* NSSIdentity::GenerateForTest(const SSLIdentityParams& params) {
+ return GenerateInternal(params);
+}
+
SSLIdentity* NSSIdentity::FromPEMStrings(const std::string& private_key,
const std::string& certificate) {
std::string private_key_der;
@@ -416,10 +474,9 @@ SSLIdentity* NSSIdentity::FromPEMStrings(const std::string& private_key,
return NULL;
SECItem private_key_item;
- private_key_item.data =
- reinterpret_cast<unsigned char *>(
- const_cast<char *>(private_key_der.c_str()));
- private_key_item.len = private_key_der.size();
+ private_key_item.data = reinterpret_cast<unsigned char *>(
+ const_cast<char *>(private_key_der.c_str()));
+ private_key_item.len = checked_cast<unsigned int>(private_key_der.size());
const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT |
KU_DIGITAL_SIGNATURE;
diff --git a/chromium/third_party/libjingle/source/talk/base/nssidentity.h b/chromium/third_party/libjingle/source/talk/base/nssidentity.h
index 3f97ebbb619..b4376d521a6 100644
--- a/chromium/third_party/libjingle/source/talk/base/nssidentity.h
+++ b/chromium/third_party/libjingle/source/talk/base/nssidentity.h
@@ -84,16 +84,21 @@ class NSSCertificate : public SSLCertificate {
virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const;
virtual bool ComputeDigest(const std::string& algorithm,
- unsigned char* digest, std::size_t size,
- std::size_t* length) const;
+ unsigned char* digest,
+ size_t size,
+ size_t* length) const;
virtual bool GetChain(SSLCertChain** chain) const;
CERTCertificate* certificate() { return certificate_; }
+ // Performs minimal checks to determine if the list is a valid chain. This
+ // only checks that each certificate certifies the preceding certificate,
+ // and ignores many other certificate features such as expiration dates.
+ static bool IsValidChain(const CERTCertList* cert_list);
+
// Helper function to get the length of a digest
- static bool GetDigestLength(const std::string& algorithm,
- std::size_t* length);
+ static bool GetDigestLength(const std::string& algorithm, size_t* length);
// Comparison. Only the certificate itself is considered, not the chain.
bool Equals(const NSSCertificate* tocompare) const;
@@ -113,6 +118,7 @@ class NSSCertificate : public SSLCertificate {
class NSSIdentity : public SSLIdentity {
public:
static NSSIdentity* Generate(const std::string& common_name);
+ static NSSIdentity* GenerateForTest(const SSLIdentityParams& params);
static SSLIdentity* FromPEMStrings(const std::string& private_key,
const std::string& certificate);
virtual ~NSSIdentity() {
@@ -128,6 +134,8 @@ class NSSIdentity : public SSLIdentity {
NSSIdentity(NSSKeyPair* keypair, NSSCertificate* cert) :
keypair_(keypair), certificate_(cert) {}
+ static NSSIdentity* GenerateInternal(const SSLIdentityParams& params);
+
talk_base::scoped_ptr<NSSKeyPair> keypair_;
talk_base::scoped_ptr<NSSCertificate> certificate_;
diff --git a/chromium/third_party/libjingle/source/talk/base/nssstreamadapter.cc b/chromium/third_party/libjingle/source/talk/base/nssstreamadapter.cc
index 185c243f5e5..60fa738b3c1 100644
--- a/chromium/third_party/libjingle/source/talk/base/nssstreamadapter.cc
+++ b/chromium/third_party/libjingle/source/talk/base/nssstreamadapter.cc
@@ -53,6 +53,7 @@
#endif
#include "talk/base/nssidentity.h"
+#include "talk/base/safe_conversions.h"
#include "talk/base/thread.h"
namespace talk_base {
@@ -86,7 +87,8 @@ static const SrtpCipherMapEntry kSrtpCipherMap[] = {
// Implementation of NSPR methods
static PRStatus StreamClose(PRFileDesc *socket) {
- // Noop
+ ASSERT(!socket->lower);
+ socket->dtor(socket);
return PR_SUCCESS;
}
@@ -96,7 +98,7 @@ static PRInt32 StreamRead(PRFileDesc *socket, void *buf, PRInt32 length) {
int error;
StreamResult result = stream->Read(buf, length, &read, &error);
if (result == SR_SUCCESS) {
- return read;
+ return checked_cast<PRInt32>(read);
}
if (result == SR_EOS) {
@@ -119,7 +121,7 @@ static PRInt32 StreamWrite(PRFileDesc *socket, const void *buf,
int error;
StreamResult result = stream->Write(buf, length, &written, &error);
if (result == SR_SUCCESS) {
- return written;
+ return checked_cast<PRInt32>(written);
}
if (result == SR_BLOCK) {
@@ -437,7 +439,7 @@ bool NSSStreamAdapter::Init() {
LOG(LS_ERROR) << "Error disabling false start";
return false;
}
-
+
ssl_fd_ = ssl_fd;
return true;
@@ -515,7 +517,7 @@ int NSSStreamAdapter::BeginSSL() {
SSL_LIBRARY_VERSION_TLS_1_1 :
SSL_LIBRARY_VERSION_TLS_1_0;
vrange.max = SSL_LIBRARY_VERSION_TLS_1_1;
-
+
rv = SSL_VersionRangeSet(ssl_fd_, &vrange);
if (rv != SECSuccess) {
Error("BeginSSL", -1, false);
@@ -525,7 +527,9 @@ int NSSStreamAdapter::BeginSSL() {
// SRTP
#ifdef HAVE_DTLS_SRTP
if (!srtp_ciphers_.empty()) {
- rv = SSL_SetSRTPCiphers(ssl_fd_, &srtp_ciphers_[0], srtp_ciphers_.size());
+ rv = SSL_SetSRTPCiphers(
+ ssl_fd_, &srtp_ciphers_[0],
+ checked_cast<unsigned int>(srtp_ciphers_.size()));
if (rv != SECSuccess) {
Error("BeginSSL", -1, false);
return -1;
@@ -644,7 +648,7 @@ StreamResult NSSStreamAdapter::Read(void* data, size_t data_len,
return SR_ERROR;
}
- PRInt32 rv = PR_Read(ssl_fd_, data, data_len);
+ PRInt32 rv = PR_Read(ssl_fd_, data, checked_cast<PRInt32>(data_len));
if (rv == 0) {
return SR_EOS;
@@ -681,7 +685,7 @@ StreamResult NSSStreamAdapter::Write(const void* data, size_t data_len,
case SSL_CONNECTED:
break;
-
+
case SSL_ERROR:
case SSL_CLOSED:
default:
@@ -690,7 +694,7 @@ StreamResult NSSStreamAdapter::Write(const void* data, size_t data_len,
return SR_ERROR;
}
- PRInt32 rv = PR_Write(ssl_fd_, data, data_len);
+ PRInt32 rv = PR_Write(ssl_fd_, data, checked_cast<PRInt32>(data_len));
// Error
if (rv < 0) {
@@ -780,12 +784,33 @@ SECStatus NSSStreamAdapter::AuthCertificateHook(void *arg,
PRBool checksig,
PRBool isServer) {
LOG(LS_INFO) << "NSSStreamAdapter::AuthCertificateHook";
- NSSCertificate peer_cert(SSL_PeerCertificate(fd));
- bool ok = false;
+ // SSL_PeerCertificate returns a pointer that is owned by the caller, and
+ // the NSSCertificate constructor copies its argument, so |raw_peer_cert|
+ // must be destroyed in this function.
+ CERTCertificate* raw_peer_cert = SSL_PeerCertificate(fd);
+ NSSCertificate peer_cert(raw_peer_cert);
+ CERT_DestroyCertificate(raw_peer_cert);
- // TODO(ekr@rtfm.com): Should we be enforcing self-signed like
- // the OpenSSL version?
NSSStreamAdapter *stream = reinterpret_cast<NSSStreamAdapter *>(arg);
+ stream->cert_ok_ = false;
+
+ // Read the peer's certificate chain.
+ CERTCertList* cert_list = SSL_PeerCertificateChain(fd);
+ ASSERT(cert_list != NULL);
+
+ // If the peer provided multiple certificates, check that they form a valid
+ // chain as defined by RFC 5246 Section 7.4.2: "Each following certificate
+ // MUST directly certify the one preceding it.". This check does NOT
+ // verify other requirements, such as whether the chain reaches a trusted
+ // root, self-signed certificates have valid signatures, certificates are not
+ // expired, etc.
+ // Even if the chain is valid, the leaf certificate must still match a
+ // provided certificate or digest.
+ if (!NSSCertificate::IsValidChain(cert_list)) {
+ CERT_DestroyCertList(cert_list);
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ return SECFailure;
+ }
if (stream->peer_certificate_.get()) {
LOG(LS_INFO) << "Checking against specified certificate";
@@ -794,13 +819,13 @@ SECStatus NSSStreamAdapter::AuthCertificateHook(void *arg,
if (reinterpret_cast<NSSCertificate *>(stream->peer_certificate_.get())->
Equals(&peer_cert)) {
LOG(LS_INFO) << "Accepted peer certificate";
- ok = true;
+ stream->cert_ok_ = true;
}
} else if (!stream->peer_certificate_digest_algorithm_.empty()) {
LOG(LS_INFO) << "Checking against specified digest";
// The peer certificate digest was specified
unsigned char digest[64]; // Maximum size
- std::size_t digest_length;
+ size_t digest_length;
if (!peer_cert.ComputeDigest(
stream->peer_certificate_digest_algorithm_,
@@ -810,7 +835,7 @@ SECStatus NSSStreamAdapter::AuthCertificateHook(void *arg,
Buffer computed_digest(digest, digest_length);
if (computed_digest == stream->peer_certificate_digest_value_) {
LOG(LS_INFO) << "Accepted peer certificate";
- ok = true;
+ stream->cert_ok_ = true;
}
}
} else {
@@ -819,23 +844,18 @@ SECStatus NSSStreamAdapter::AuthCertificateHook(void *arg,
UNIMPLEMENTED;
}
- if (ok) {
+ if (!stream->cert_ok_ && stream->ignore_bad_cert()) {
+ LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
stream->cert_ok_ = true;
+ }
- // Record the peer's certificate chain.
- CERTCertList* cert_list = SSL_PeerCertificateChain(fd);
- ASSERT(cert_list != NULL);
-
+ if (stream->cert_ok_)
stream->peer_certificate_.reset(new NSSCertificate(cert_list));
- CERT_DestroyCertList(cert_list);
- return SECSuccess;
- }
- if (!ok && stream->ignore_bad_cert()) {
- LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
- stream->cert_ok_ = true;
+ CERT_DestroyCertList(cert_list);
+
+ if (stream->cert_ok_)
return SECSuccess;
- }
PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
return SECFailure;
@@ -869,11 +889,15 @@ bool NSSStreamAdapter::ExportKeyingMaterial(const std::string& label,
bool use_context,
uint8* result,
size_t result_len) {
- SECStatus rv = SSL_ExportKeyingMaterial(ssl_fd_,
- label.c_str(), label.size(),
- use_context,
- context, context_len,
- result, result_len);
+ SECStatus rv = SSL_ExportKeyingMaterial(
+ ssl_fd_,
+ label.c_str(),
+ checked_cast<unsigned int>(label.size()),
+ use_context,
+ context,
+ checked_cast<unsigned int>(context_len),
+ result,
+ checked_cast<unsigned int>(result_len));
return rv == SECSuccess;
}
diff --git a/chromium/third_party/libjingle/source/talk/base/nssstreamadapter.h b/chromium/third_party/libjingle/source/talk/base/nssstreamadapter.h
index 219f6193f07..3919c5a1571 100644
--- a/chromium/third_party/libjingle/source/talk/base/nssstreamadapter.h
+++ b/chromium/third_party/libjingle/source/talk/base/nssstreamadapter.h
@@ -103,8 +103,7 @@ class NSSStreamAdapter : public SSLStreamAdapterHelper {
// Override SSLStreamAdapterHelper
virtual int BeginSSL();
virtual void Cleanup();
- virtual bool GetDigestLength(const std::string &algorithm,
- std::size_t *length) {
+ virtual bool GetDigestLength(const std::string& algorithm, size_t* length) {
return NSSCertificate::GetDigestLength(algorithm, length);
}
diff --git a/chromium/third_party/libjingle/source/talk/base/openssl.h b/chromium/third_party/libjingle/source/talk/base/openssl.h
new file mode 100644
index 00000000000..d9628a76368
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/openssl.h
@@ -0,0 +1,37 @@
+/*
+ * libjingle
+ * Copyright 2013, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TALK_BASE_OPENSSL_H_
+#define TALK_BASE_OPENSSL_H_
+
+#include <openssl/ssl.h>
+
+#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
+#error OpenSSL is older than 1.0.0, which is the minimum supported version.
+#endif
+
+#endif // TALK_BASE_OPENSSL_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/openssladapter.cc b/chromium/third_party/libjingle/source/talk/base/openssladapter.cc
index af92f0c4534..9e6fe72c244 100644
--- a/chromium/third_party/libjingle/source/talk/base/openssladapter.cc
+++ b/chromium/third_party/libjingle/source/talk/base/openssladapter.cc
@@ -41,7 +41,6 @@
#include <openssl/err.h>
#include <openssl/opensslv.h>
#include <openssl/rand.h>
-#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#if HAVE_CONFIG_H
@@ -50,6 +49,7 @@
#include "talk/base/common.h"
#include "talk/base/logging.h"
+#include "talk/base/openssl.h"
#include "talk/base/sslroots.h"
#include "talk/base/stringutils.h"
@@ -62,9 +62,7 @@
#define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE)
#define MUTEX_UNLOCK(x) ReleaseMutex(x)
#define THREAD_ID GetCurrentThreadId()
-#elif defined(_POSIX_THREADS)
- // _POSIX_THREADS is normally defined in unistd.h if pthreads are available
- // on your platform.
+#elif defined(POSIX)
#define MUTEX_TYPE pthread_mutex_t
#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
@@ -690,11 +688,7 @@ bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host,
int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
if (extension_nid == NID_subject_alt_name) {
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
-#else
- X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
-#endif
if (!meth)
break;
@@ -705,12 +699,8 @@ bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host,
// See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html.
unsigned char* ext_value_data = extension->value->data;
-#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
const unsigned char **ext_value_data_ptr =
(const_cast<const unsigned char **>(&ext_value_data));
-#else
- unsigned char **ext_value_data_ptr = &ext_value_data;
-#endif
if (meth->it) {
ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr,
diff --git a/chromium/third_party/libjingle/source/talk/base/openssldigest.cc b/chromium/third_party/libjingle/source/talk/base/openssldigest.cc
index 3d9276de844..3d0d227e67c 100644
--- a/chromium/third_party/libjingle/source/talk/base/openssldigest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/openssldigest.cc
@@ -30,6 +30,7 @@
#include "talk/base/openssldigest.h"
#include "talk/base/common.h"
+#include "talk/base/openssl.h"
namespace talk_base {
@@ -78,7 +79,6 @@ bool OpenSSLDigest::GetDigestEVP(const std::string& algorithm,
md = EVP_md5();
} else if (algorithm == DIGEST_SHA_1) {
md = EVP_sha1();
-#if OPENSSL_VERSION_NUMBER >= 0x00908000L
} else if (algorithm == DIGEST_SHA_224) {
md = EVP_sha224();
} else if (algorithm == DIGEST_SHA_256) {
@@ -87,7 +87,6 @@ bool OpenSSLDigest::GetDigestEVP(const std::string& algorithm,
md = EVP_sha384();
} else if (algorithm == DIGEST_SHA_512) {
md = EVP_sha512();
-#endif
} else {
return false;
}
@@ -108,7 +107,6 @@ bool OpenSSLDigest::GetDigestName(const EVP_MD* md,
*algorithm = DIGEST_MD5;
} else if (md_type == NID_sha1) {
*algorithm = DIGEST_SHA_1;
-#if OPENSSL_VERSION_NUMBER >= 0x00908000L
} else if (md_type == NID_sha224) {
*algorithm = DIGEST_SHA_224;
} else if (md_type == NID_sha256) {
@@ -117,7 +115,6 @@ bool OpenSSLDigest::GetDigestName(const EVP_MD* md,
*algorithm = DIGEST_SHA_384;
} else if (md_type == NID_sha512) {
*algorithm = DIGEST_SHA_512;
-#endif
} else {
algorithm->clear();
return false;
diff --git a/chromium/third_party/libjingle/source/talk/base/opensslidentity.cc b/chromium/third_party/libjingle/source/talk/base/opensslidentity.cc
index 4ff76016183..a58f83967e8 100644
--- a/chromium/third_party/libjingle/source/talk/base/opensslidentity.cc
+++ b/chromium/third_party/libjingle/source/talk/base/opensslidentity.cc
@@ -32,7 +32,6 @@
// Must be included first before openssl headers.
#include "talk/base/win32.h" // NOLINT
-#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
@@ -43,6 +42,7 @@
#include "talk/base/checks.h"
#include "talk/base/helpers.h"
#include "talk/base/logging.h"
+#include "talk/base/openssl.h"
#include "talk/base/openssldigest.h"
namespace talk_base {
@@ -57,7 +57,7 @@ static const int KEY_LENGTH = 1024;
static const int SERIAL_RAND_BITS = 64;
// Certificate validity lifetime
-static const int CERTIFICATE_LIFETIME = 60*60*24*365; // one year, arbitrarily
+static const int CERTIFICATE_LIFETIME = 60*60*24*30; // 30 days, arbitrarily
// Certificate validity window.
// This is to compensate for slightly incorrect system clocks.
static const int CERTIFICATE_WINDOW = -60*60*24;
@@ -66,15 +66,6 @@ static const int CERTIFICATE_WINDOW = -60*60*24;
static EVP_PKEY* MakeKey() {
LOG(LS_INFO) << "Making key pair";
EVP_PKEY* pkey = EVP_PKEY_new();
-#if OPENSSL_VERSION_NUMBER < 0x00908000l
- // Only RSA_generate_key is available. Use that.
- RSA* rsa = RSA_generate_key(KEY_LENGTH, 0x10001, NULL, NULL);
- if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
- EVP_PKEY_free(pkey);
- RSA_free(rsa);
- return NULL;
- }
-#else
// RSA_generate_key is deprecated. Use _ex version.
BIGNUM* exponent = BN_new();
RSA* rsa = RSA_new();
@@ -89,15 +80,14 @@ static EVP_PKEY* MakeKey() {
}
// ownership of rsa struct was assigned, don't free it.
BN_free(exponent);
-#endif
LOG(LS_INFO) << "Returning key pair";
return pkey;
}
// Generate a self-signed certificate, with the public key from the
// given key pair. Caller is responsible for freeing the returned object.
-static X509* MakeCertificate(EVP_PKEY* pkey, const char* common_name) {
- LOG(LS_INFO) << "Making certificate for " << common_name;
+static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) {
+ LOG(LS_INFO) << "Making certificate for " << params.common_name;
X509* x509 = NULL;
BIGNUM* serial_number = NULL;
X509_NAME* name = NULL;
@@ -128,14 +118,15 @@ static X509* MakeCertificate(EVP_PKEY* pkey, const char* common_name) {
// clear during SSL negotiation, so there may be a privacy issue in
// putting anything recognizable here.
if ((name = X509_NAME_new()) == NULL ||
- !X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8,
- (unsigned char*)common_name, -1, -1, 0) ||
+ !X509_NAME_add_entry_by_NID(
+ name, NID_commonName, MBSTRING_UTF8,
+ (unsigned char*)params.common_name.c_str(), -1, -1, 0) ||
!X509_set_subject_name(x509, name) ||
!X509_set_issuer_name(x509, name))
goto error;
- if (!X509_gmtime_adj(X509_get_notBefore(x509), CERTIFICATE_WINDOW) ||
- !X509_gmtime_adj(X509_get_notAfter(x509), CERTIFICATE_LIFETIME))
+ if (!X509_gmtime_adj(X509_get_notBefore(x509), params.not_before) ||
+ !X509_gmtime_adj(X509_get_notAfter(x509), params.not_after))
goto error;
if (!X509_sign(x509, pkey, EVP_sha1()))
@@ -199,12 +190,13 @@ static void PrintCert(X509* x509) {
#endif
OpenSSLCertificate* OpenSSLCertificate::Generate(
- OpenSSLKeyPair* key_pair, const std::string& common_name) {
- std::string actual_common_name = common_name;
- if (actual_common_name.empty())
+ OpenSSLKeyPair* key_pair, const SSLIdentityParams& params) {
+ SSLIdentityParams actual_params(params);
+ if (actual_params.common_name.empty()) {
// Use a random string, arbitrarily 8chars long.
- actual_common_name = CreateRandomString(8);
- X509* x509 = MakeCertificate(key_pair->pkey(), actual_common_name.c_str());
+ actual_params.common_name = CreateRandomString(8);
+ }
+ X509* x509 = MakeCertificate(key_pair->pkey(), actual_params);
if (!x509) {
LogSSLErrors("Generating certificate");
return NULL;
@@ -222,11 +214,11 @@ OpenSSLCertificate* OpenSSLCertificate::FromPEMString(
BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1);
if (!bio)
return NULL;
- (void)BIO_set_close(bio, BIO_NOCLOSE);
BIO_set_mem_eof_return(bio, 0);
X509 *x509 = PEM_read_bio_X509(bio, NULL, NULL,
const_cast<char*>("\0"));
- BIO_free(bio);
+ BIO_free(bio); // Frees the BIO, but not the pointed-to string.
+
if (!x509)
return NULL;
@@ -243,18 +235,18 @@ bool OpenSSLCertificate::GetSignatureDigestAlgorithm(
EVP_get_digestbyobj(x509_->sig_alg->algorithm), algorithm);
}
-bool OpenSSLCertificate::ComputeDigest(const std::string &algorithm,
- unsigned char *digest,
- std::size_t size,
- std::size_t *length) const {
+bool OpenSSLCertificate::ComputeDigest(const std::string& algorithm,
+ unsigned char* digest,
+ size_t size,
+ size_t* length) const {
return ComputeDigest(x509_, algorithm, digest, size, length);
}
-bool OpenSSLCertificate::ComputeDigest(const X509 *x509,
- const std::string &algorithm,
- unsigned char *digest,
- std::size_t size,
- std::size_t *length) {
+bool OpenSSLCertificate::ComputeDigest(const X509* x509,
+ const std::string& algorithm,
+ unsigned char* digest,
+ size_t size,
+ size_t* length) {
const EVP_MD *md;
unsigned int n;
@@ -320,11 +312,12 @@ void OpenSSLCertificate::AddReference() const {
CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509);
}
-OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name) {
+OpenSSLIdentity* OpenSSLIdentity::GenerateInternal(
+ const SSLIdentityParams& params) {
OpenSSLKeyPair *key_pair = OpenSSLKeyPair::Generate();
if (key_pair) {
- OpenSSLCertificate *certificate =
- OpenSSLCertificate::Generate(key_pair, common_name);
+ OpenSSLCertificate *certificate = OpenSSLCertificate::Generate(
+ key_pair, params);
if (certificate)
return new OpenSSLIdentity(key_pair, certificate);
delete key_pair;
@@ -333,6 +326,19 @@ OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name) {
return NULL;
}
+OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name) {
+ SSLIdentityParams params;
+ params.common_name = common_name;
+ params.not_before = CERTIFICATE_WINDOW;
+ params.not_after = CERTIFICATE_LIFETIME;
+ return GenerateInternal(params);
+}
+
+OpenSSLIdentity* OpenSSLIdentity::GenerateForTest(
+ const SSLIdentityParams& params) {
+ return GenerateInternal(params);
+}
+
SSLIdentity* OpenSSLIdentity::FromPEMStrings(
const std::string& private_key,
const std::string& certificate) {
@@ -348,11 +354,10 @@ SSLIdentity* OpenSSLIdentity::FromPEMStrings(
LOG(LS_ERROR) << "Failed to create a new BIO buffer.";
return NULL;
}
- (void)BIO_set_close(bio, BIO_NOCLOSE);
BIO_set_mem_eof_return(bio, 0);
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL,
const_cast<char*>("\0"));
- BIO_free(bio);
+ BIO_free(bio); // Frees the BIO, but not the pointed-to string.
if (!pkey) {
LOG(LS_ERROR) << "Failed to create the private key from PEM string.";
@@ -376,5 +381,3 @@ bool OpenSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) {
} // namespace talk_base
#endif // HAVE_OPENSSL_SSL_H
-
-
diff --git a/chromium/third_party/libjingle/source/talk/base/opensslidentity.h b/chromium/third_party/libjingle/source/talk/base/opensslidentity.h
index af18c5c4d09..84b28261e4d 100644
--- a/chromium/third_party/libjingle/source/talk/base/opensslidentity.h
+++ b/chromium/third_party/libjingle/source/talk/base/opensslidentity.h
@@ -78,7 +78,7 @@ class OpenSSLCertificate : public SSLCertificate {
}
static OpenSSLCertificate* Generate(OpenSSLKeyPair* key_pair,
- const std::string& common_name);
+ const SSLIdentityParams& params);
static OpenSSLCertificate* FromPEMString(const std::string& pem_string);
virtual ~OpenSSLCertificate();
@@ -94,16 +94,17 @@ class OpenSSLCertificate : public SSLCertificate {
virtual void ToDER(Buffer* der_buffer) const;
// Compute the digest of the certificate given algorithm
- virtual bool ComputeDigest(const std::string &algorithm,
- unsigned char *digest, std::size_t size,
- std::size_t *length) const;
+ virtual bool ComputeDigest(const std::string& algorithm,
+ unsigned char* digest,
+ size_t size,
+ size_t* length) const;
// Compute the digest of a certificate as an X509 *
- static bool ComputeDigest(const X509 *x509,
- const std::string &algorithm,
- unsigned char *digest,
- std::size_t size,
- std::size_t *length);
+ static bool ComputeDigest(const X509* x509,
+ const std::string& algorithm,
+ unsigned char* digest,
+ size_t size,
+ size_t* length);
virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const;
@@ -127,6 +128,7 @@ class OpenSSLCertificate : public SSLCertificate {
class OpenSSLIdentity : public SSLIdentity {
public:
static OpenSSLIdentity* Generate(const std::string& common_name);
+ static OpenSSLIdentity* GenerateForTest(const SSLIdentityParams& params);
static SSLIdentity* FromPEMStrings(const std::string& private_key,
const std::string& certificate);
virtual ~OpenSSLIdentity() { }
@@ -151,6 +153,8 @@ class OpenSSLIdentity : public SSLIdentity {
ASSERT(certificate != NULL);
}
+ static OpenSSLIdentity* GenerateInternal(const SSLIdentityParams& params);
+
scoped_ptr<OpenSSLKeyPair> key_pair_;
scoped_ptr<OpenSSLCertificate> certificate_;
diff --git a/chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.cc b/chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.cc
index 034dfcf9266..218f656be12 100644
--- a/chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.cc
+++ b/chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.cc
@@ -37,7 +37,6 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
-#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#include <vector>
@@ -45,6 +44,7 @@
#include "talk/base/common.h"
#include "talk/base/logging.h"
#include "talk/base/stream.h"
+#include "talk/base/openssl.h"
#include "talk/base/openssladapter.h"
#include "talk/base/openssldigest.h"
#include "talk/base/opensslidentity.h"
@@ -57,10 +57,6 @@ namespace talk_base {
#define HAVE_DTLS_SRTP
#endif
-#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
-#define HAVE_DTLS
-#endif
-
#ifdef HAVE_DTLS_SRTP
// SRTP cipher suite table
struct SrtpCipherMapEntry {
@@ -210,13 +206,6 @@ void OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
role_ = role;
}
-void OpenSSLStreamAdapter::SetPeerCertificate(SSLCertificate* cert) {
- ASSERT(!peer_certificate_);
- ASSERT(peer_certificate_digest_algorithm_.empty());
- ASSERT(ssl_server_name_.empty());
- peer_certificate_.reset(static_cast<OpenSSLCertificate*>(cert));
-}
-
bool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const {
if (!peer_certificate_)
return false;
@@ -274,12 +263,12 @@ bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
bool OpenSSLStreamAdapter::SetDtlsSrtpCiphers(
const std::vector<std::string>& ciphers) {
+#ifdef HAVE_DTLS_SRTP
std::string internal_ciphers;
if (state_ != SSL_NONE)
return false;
-#ifdef HAVE_DTLS_SRTP
for (std::vector<std::string>::const_iterator cipher = ciphers.begin();
cipher != ciphers.end(); ++cipher) {
bool found = false;
@@ -613,7 +602,6 @@ int OpenSSLStreamAdapter::BeginSSL() {
// The underlying stream has open. If we are in peer-to-peer mode
// then a peer certificate must have been specified by now.
ASSERT(!ssl_server_name_.empty() ||
- peer_certificate_ ||
!peer_certificate_digest_algorithm_.empty());
LOG(LS_INFO) << "BeginSSL: "
<< (!ssl_server_name_.empty() ? ssl_server_name_ :
@@ -661,9 +649,7 @@ int OpenSSLStreamAdapter::ContinueSSL() {
case SSL_ERROR_NONE:
LOG(LS_VERBOSE) << " -- success";
- if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(),
- peer_certificate_ ?
- peer_certificate_->x509() : NULL,
+ if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(), NULL,
peer_certificate_digest_algorithm_)) {
LOG(LS_ERROR) << "TLS post connection check failed";
return -1;
@@ -675,14 +661,12 @@ int OpenSSLStreamAdapter::ContinueSSL() {
case SSL_ERROR_WANT_READ: {
LOG(LS_VERBOSE) << " -- error want read";
-#ifdef HAVE_DTLS
struct timeval timeout;
if (DTLSv1_get_timeout(ssl_, &timeout)) {
int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
}
-#endif
}
break;
@@ -737,9 +721,7 @@ void OpenSSLStreamAdapter::OnMessage(Message* msg) {
// Process our own messages and then pass others to the superclass
if (MSG_TIMEOUT == msg->message_id) {
LOG(LS_INFO) << "DTLS timeout expired";
-#ifdef HAVE_DTLS
DTLSv1_handle_timeout(ssl_);
-#endif
ContinueSSL();
} else {
StreamInterface::OnMessage(msg);
@@ -750,19 +732,11 @@ SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
SSL_CTX *ctx = NULL;
if (role_ == SSL_CLIENT) {
-#ifdef HAVE_DTLS
ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
DTLSv1_client_method() : TLSv1_client_method());
-#else
- ctx = SSL_CTX_new(TLSv1_client_method());
-#endif
} else {
-#ifdef HAVE_DTLS
ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
DTLSv1_server_method() : TLSv1_server_method());
-#else
- ctx = SSL_CTX_new(TLSv1_server_method());
-#endif
}
if (ctx == NULL)
return NULL;
@@ -772,18 +746,6 @@ SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
return NULL;
}
- if (!peer_certificate_) { // traditional mode
- // Add the root cert to the SSL context
- if (!OpenSSLAdapter::ConfigureTrustedRootCertificates(ctx)) {
- SSL_CTX_free(ctx);
- return NULL;
- }
- }
-
- if (peer_certificate_ && role_ == SSL_SERVER)
- // we must specify which client cert to ask for
- SSL_CTX_add_client_CA(ctx, peer_certificate_->x509());
-
#ifdef _DEBUG
SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
#endif
@@ -806,88 +768,53 @@ SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
}
int OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
-#if _DEBUG
- if (!ok) {
- char data[256];
- X509* cert = X509_STORE_CTX_get_current_cert(store);
- int depth = X509_STORE_CTX_get_error_depth(store);
- int err = X509_STORE_CTX_get_error(store);
-
- LOG(LS_INFO) << "Error with certificate at depth: " << depth;
- X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
- LOG(LS_INFO) << " issuer = " << data;
- X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
- LOG(LS_INFO) << " subject = " << data;
- LOG(LS_INFO) << " err = " << err
- << ":" << X509_verify_cert_error_string(err);
- }
-#endif
-
// Get our SSL structure from the store
SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
store,
SSL_get_ex_data_X509_STORE_CTX_idx()));
-
OpenSSLStreamAdapter* stream =
reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
- // In peer-to-peer mode, no root cert / certificate authority was
- // specified, so the libraries knows of no certificate to accept,
- // and therefore it will necessarily call here on the first cert it
- // tries to verify.
- if (!ok && stream->peer_certificate_) {
- X509* cert = X509_STORE_CTX_get_current_cert(store);
- int err = X509_STORE_CTX_get_error(store);
- // peer-to-peer mode: allow the certificate to be self-signed,
- // assuming it matches the cert that was specified.
- if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
- X509_cmp(cert, stream->peer_certificate_->x509()) == 0) {
- LOG(LS_INFO) << "Accepted self-signed peer certificate authority";
- ok = 1;
- }
- } else if (!ok && !stream->peer_certificate_digest_algorithm_.empty()) {
- X509* cert = X509_STORE_CTX_get_current_cert(store);
- int err = X509_STORE_CTX_get_error(store);
-
- // peer-to-peer mode: allow the certificate to be self-signed,
- // assuming it matches the digest that was specified.
- if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) {
- unsigned char digest[EVP_MAX_MD_SIZE];
- std::size_t digest_length;
-
- if (OpenSSLCertificate::
- ComputeDigest(cert,
- stream->peer_certificate_digest_algorithm_,
- digest, sizeof(digest),
- &digest_length)) {
- Buffer computed_digest(digest, digest_length);
- if (computed_digest == stream->peer_certificate_digest_value_) {
- LOG(LS_INFO) <<
- "Accepted self-signed peer certificate authority";
- ok = 1;
-
- // Record the peer's certificate.
- stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
- }
- }
- }
- } else if (!ok && OpenSSLAdapter::custom_verify_callback_) {
- // this applies only in traditional mode
- void* cert =
- reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store));
- if (OpenSSLAdapter::custom_verify_callback_(cert)) {
- stream->custom_verification_succeeded_ = true;
- LOG(LS_INFO) << "validated certificate using custom callback";
- ok = 1;
- }
+ if (stream->peer_certificate_digest_algorithm_.empty()) {
+ return 0;
+ }
+ X509* cert = X509_STORE_CTX_get_current_cert(store);
+ int depth = X509_STORE_CTX_get_error_depth(store);
+
+ // For now We ignore the parent certificates and verify the leaf against
+ // the digest.
+ //
+ // TODO(jiayl): Verify the chain is a proper chain and report the chain to
+ // |stream->peer_certificate_|, like what NSS does.
+ if (depth > 0) {
+ LOG(LS_INFO) << "Ignored chained certificate at depth " << depth;
+ return 1;
+ }
+
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ size_t digest_length;
+ if (!OpenSSLCertificate::ComputeDigest(
+ cert,
+ stream->peer_certificate_digest_algorithm_,
+ digest, sizeof(digest),
+ &digest_length)) {
+ LOG(LS_WARNING) << "Failed to compute peer cert digest.";
+ return 0;
}
- if (!ok && stream->ignore_bad_cert()) {
- LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
- ok = 1;
+ Buffer computed_digest(digest, digest_length);
+ if (computed_digest != stream->peer_certificate_digest_value_) {
+ LOG(LS_WARNING) << "Rejected peer certificate due to mismatched digest.";
+ return 0;
}
+ // Ignore any verification error if the digest matches, since there is no
+ // value in checking the validity of a self-signed cert issued by untrusted
+ // sources.
+ LOG(LS_INFO) << "Accepted peer certificate.";
- return ok;
+ // Record the peer's certificate.
+ stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
+ return 1;
}
// This code is taken from the "Network Security with OpenSSL"
@@ -923,11 +850,7 @@ bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
}
bool OpenSSLStreamAdapter::HaveDtls() {
-#ifdef HAVE_DTLS
return true;
-#else
- return false;
-#endif
}
bool OpenSSLStreamAdapter::HaveDtlsSrtp() {
diff --git a/chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.h b/chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.h
index 3c478187fcc..744d29980e1 100644
--- a/chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.h
+++ b/chromium/third_party/libjingle/source/talk/base/opensslstreamadapter.h
@@ -2,26 +2,26 @@
* libjingle
* Copyright 2004--2008, Google Inc.
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * 1. Redistributions of source code must retain the above copyright notice,
+ * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -81,7 +81,6 @@ class OpenSSLStreamAdapter : public SSLStreamAdapter {
// Default argument is for compatibility
virtual void SetServerRole(SSLRole role = SSL_SERVER);
- virtual void SetPeerCertificate(SSLCertificate* cert);
virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
const unsigned char* digest_val,
size_t digest_len);
@@ -175,7 +174,6 @@ class OpenSSLStreamAdapter : public SSLStreamAdapter {
// passed.
static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
-
SSLState state_;
SSLRole role_;
int ssl_error_code_; // valid when state_ == SSL_ERROR or SSL_CLOSED
diff --git a/chromium/third_party/libjingle/source/talk/base/optionsfile_unittest.cc b/chromium/third_party/libjingle/source/talk/base/optionsfile_unittest.cc
index 65861ff4982..afb79cf9a7b 100644
--- a/chromium/third_party/libjingle/source/talk/base/optionsfile_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/optionsfile_unittest.cc
@@ -25,19 +25,13 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "talk/base/fileutils.h"
#include "talk/base/gunit.h"
#include "talk/base/optionsfile.h"
+#include "talk/base/pathutils.h"
namespace talk_base {
-#ifdef ANDROID
-static const char *kTestFile = "/sdcard/.testfile";
-#elif CHROMEOS
-static const char *kTestFile = "/tmp/.testfile";
-#else
-static const char *kTestFile = ".testfile";
-#endif
-
static const std::string kTestOptionA = "test-option-a";
static const std::string kTestOptionB = "test-option-b";
static const std::string kTestString1 = "a string";
@@ -56,122 +50,135 @@ static int kTestInt2 = 67890;
static int kNegInt = -634;
static int kZero = 0;
-TEST(OptionsFile, GetSetString) {
- OptionsFile store(kTestFile);
+class OptionsFileTest : public testing::Test {
+ public:
+ OptionsFileTest() {
+ Pathname dir;
+ ASSERT(Filesystem::GetTemporaryFolder(dir, true, NULL));
+ test_file_ = Filesystem::TempFilename(dir, ".testfile");
+ OpenStore();
+ }
+
+ protected:
+ void OpenStore() {
+ store_.reset(new OptionsFile(test_file_));
+ }
+
+ talk_base::scoped_ptr<OptionsFile> store_;
+
+ private:
+ std::string test_file_;
+};
+
+TEST_F(OptionsFileTest, GetSetString) {
// Clear contents of the file on disk.
- EXPECT_TRUE(store.Save());
+ EXPECT_TRUE(store_->Save());
std::string out1, out2;
- EXPECT_FALSE(store.GetStringValue(kTestOptionA, &out1));
- EXPECT_FALSE(store.GetStringValue(kTestOptionB, &out2));
- EXPECT_TRUE(store.SetStringValue(kTestOptionA, kTestString1));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.SetStringValue(kTestOptionB, kTestString2));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out1));
- EXPECT_TRUE(store.GetStringValue(kTestOptionB, &out2));
+ EXPECT_FALSE(store_->GetStringValue(kTestOptionA, &out1));
+ EXPECT_FALSE(store_->GetStringValue(kTestOptionB, &out2));
+ EXPECT_TRUE(store_->SetStringValue(kTestOptionA, kTestString1));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->SetStringValue(kTestOptionB, kTestString2));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out1));
+ EXPECT_TRUE(store_->GetStringValue(kTestOptionB, &out2));
EXPECT_EQ(kTestString1, out1);
EXPECT_EQ(kTestString2, out2);
- EXPECT_TRUE(store.RemoveValue(kTestOptionA));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.RemoveValue(kTestOptionB));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_FALSE(store.GetStringValue(kTestOptionA, &out1));
- EXPECT_FALSE(store.GetStringValue(kTestOptionB, &out2));
+ EXPECT_TRUE(store_->RemoveValue(kTestOptionA));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->RemoveValue(kTestOptionB));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_FALSE(store_->GetStringValue(kTestOptionA, &out1));
+ EXPECT_FALSE(store_->GetStringValue(kTestOptionB, &out2));
}
-TEST(OptionsFile, GetSetInt) {
- OptionsFile store(kTestFile);
+TEST_F(OptionsFileTest, GetSetInt) {
// Clear contents of the file on disk.
- EXPECT_TRUE(store.Save());
+ EXPECT_TRUE(store_->Save());
int out1, out2;
- EXPECT_FALSE(store.GetIntValue(kTestOptionA, &out1));
- EXPECT_FALSE(store.GetIntValue(kTestOptionB, &out2));
- EXPECT_TRUE(store.SetIntValue(kTestOptionA, kTestInt1));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.SetIntValue(kTestOptionB, kTestInt2));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.GetIntValue(kTestOptionA, &out1));
- EXPECT_TRUE(store.GetIntValue(kTestOptionB, &out2));
+ EXPECT_FALSE(store_->GetIntValue(kTestOptionA, &out1));
+ EXPECT_FALSE(store_->GetIntValue(kTestOptionB, &out2));
+ EXPECT_TRUE(store_->SetIntValue(kTestOptionA, kTestInt1));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->SetIntValue(kTestOptionB, kTestInt2));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->GetIntValue(kTestOptionA, &out1));
+ EXPECT_TRUE(store_->GetIntValue(kTestOptionB, &out2));
EXPECT_EQ(kTestInt1, out1);
EXPECT_EQ(kTestInt2, out2);
- EXPECT_TRUE(store.RemoveValue(kTestOptionA));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.RemoveValue(kTestOptionB));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_FALSE(store.GetIntValue(kTestOptionA, &out1));
- EXPECT_FALSE(store.GetIntValue(kTestOptionB, &out2));
- EXPECT_TRUE(store.SetIntValue(kTestOptionA, kNegInt));
- EXPECT_TRUE(store.GetIntValue(kTestOptionA, &out1));
+ EXPECT_TRUE(store_->RemoveValue(kTestOptionA));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->RemoveValue(kTestOptionB));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_FALSE(store_->GetIntValue(kTestOptionA, &out1));
+ EXPECT_FALSE(store_->GetIntValue(kTestOptionB, &out2));
+ EXPECT_TRUE(store_->SetIntValue(kTestOptionA, kNegInt));
+ EXPECT_TRUE(store_->GetIntValue(kTestOptionA, &out1));
EXPECT_EQ(kNegInt, out1);
- EXPECT_TRUE(store.SetIntValue(kTestOptionA, kZero));
- EXPECT_TRUE(store.GetIntValue(kTestOptionA, &out1));
+ EXPECT_TRUE(store_->SetIntValue(kTestOptionA, kZero));
+ EXPECT_TRUE(store_->GetIntValue(kTestOptionA, &out1));
EXPECT_EQ(kZero, out1);
}
-TEST(OptionsFile, Persist) {
- {
- OptionsFile store(kTestFile);
- // Clear contents of the file on disk.
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.SetStringValue(kTestOptionA, kTestString1));
- EXPECT_TRUE(store.SetIntValue(kTestOptionB, kNegInt));
- EXPECT_TRUE(store.Save());
- }
- {
- OptionsFile store(kTestFile);
- // Load the saved contents from above.
- EXPECT_TRUE(store.Load());
- std::string out1;
- int out2;
- EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out1));
- EXPECT_TRUE(store.GetIntValue(kTestOptionB, &out2));
- EXPECT_EQ(kTestString1, out1);
- EXPECT_EQ(kNegInt, out2);
- }
+TEST_F(OptionsFileTest, Persist) {
+ // Clear contents of the file on disk.
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->SetStringValue(kTestOptionA, kTestString1));
+ EXPECT_TRUE(store_->SetIntValue(kTestOptionB, kNegInt));
+ EXPECT_TRUE(store_->Save());
+
+ // Load the saved contents from above.
+ OpenStore();
+ EXPECT_TRUE(store_->Load());
+ std::string out1;
+ int out2;
+ EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out1));
+ EXPECT_TRUE(store_->GetIntValue(kTestOptionB, &out2));
+ EXPECT_EQ(kTestString1, out1);
+ EXPECT_EQ(kNegInt, out2);
}
-TEST(OptionsFile, SpecialCharacters) {
- OptionsFile store(kTestFile);
+TEST_F(OptionsFileTest, SpecialCharacters) {
// Clear contents of the file on disk.
- EXPECT_TRUE(store.Save());
+ EXPECT_TRUE(store_->Save());
std::string out;
- EXPECT_FALSE(store.SetStringValue(kOptionWithEquals, kTestString1));
- EXPECT_FALSE(store.GetStringValue(kOptionWithEquals, &out));
- EXPECT_FALSE(store.SetStringValue(kOptionWithNewline, kTestString1));
- EXPECT_FALSE(store.GetStringValue(kOptionWithNewline, &out));
- EXPECT_TRUE(store.SetStringValue(kOptionWithUtf8, kValueWithUtf8));
- EXPECT_TRUE(store.SetStringValue(kTestOptionA, kTestString1));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out));
+ EXPECT_FALSE(store_->SetStringValue(kOptionWithEquals, kTestString1));
+ EXPECT_FALSE(store_->GetStringValue(kOptionWithEquals, &out));
+ EXPECT_FALSE(store_->SetStringValue(kOptionWithNewline, kTestString1));
+ EXPECT_FALSE(store_->GetStringValue(kOptionWithNewline, &out));
+ EXPECT_TRUE(store_->SetStringValue(kOptionWithUtf8, kValueWithUtf8));
+ EXPECT_TRUE(store_->SetStringValue(kTestOptionA, kTestString1));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out));
EXPECT_EQ(kTestString1, out);
- EXPECT_TRUE(store.GetStringValue(kOptionWithUtf8, &out));
+ EXPECT_TRUE(store_->GetStringValue(kOptionWithUtf8, &out));
EXPECT_EQ(kValueWithUtf8, out);
- EXPECT_FALSE(store.SetStringValue(kTestOptionA, kValueWithNewline));
- EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out));
+ EXPECT_FALSE(store_->SetStringValue(kTestOptionA, kValueWithNewline));
+ EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out));
EXPECT_EQ(kTestString1, out);
- EXPECT_TRUE(store.SetStringValue(kTestOptionA, kValueWithEquals));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out));
+ EXPECT_TRUE(store_->SetStringValue(kTestOptionA, kValueWithEquals));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out));
EXPECT_EQ(kValueWithEquals, out);
- EXPECT_TRUE(store.SetStringValue(kEmptyString, kTestString2));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.GetStringValue(kEmptyString, &out));
+ EXPECT_TRUE(store_->SetStringValue(kEmptyString, kTestString2));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->GetStringValue(kEmptyString, &out));
EXPECT_EQ(kTestString2, out);
- EXPECT_TRUE(store.SetStringValue(kTestOptionB, kEmptyString));
- EXPECT_TRUE(store.Save());
- EXPECT_TRUE(store.Load());
- EXPECT_TRUE(store.GetStringValue(kTestOptionB, &out));
+ EXPECT_TRUE(store_->SetStringValue(kTestOptionB, kEmptyString));
+ EXPECT_TRUE(store_->Save());
+ EXPECT_TRUE(store_->Load());
+ EXPECT_TRUE(store_->GetStringValue(kTestOptionB, &out));
EXPECT_EQ(kEmptyString, out);
}
diff --git a/chromium/third_party/libjingle/source/talk/base/physicalsocketserver.cc b/chromium/third_party/libjingle/source/talk/base/physicalsocketserver.cc
index 43be440e7bd..a7f65c57acc 100644
--- a/chromium/third_party/libjingle/source/talk/base/physicalsocketserver.cc
+++ b/chromium/third_party/libjingle/source/talk/base/physicalsocketserver.cc
@@ -29,13 +29,14 @@
#pragma warning(disable:4786)
#endif
-#include <cassert>
+#include <assert.h>
#ifdef POSIX
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/time.h>
+#include <sys/select.h>
#include <unistd.h>
#include <signal.h>
#endif
@@ -78,6 +79,7 @@ typedef char* SockOptArg;
namespace talk_base {
+#if defined(WIN32)
// Standard MTUs, from RFC 1191
const uint16 PACKET_MAXIMUMS[] = {
65535, // Theoretical maximum, Hyperchannel
@@ -105,6 +107,7 @@ static const int IP_HEADER_SIZE = 20u;
static const int IPV6_HEADER_SIZE = 40u;
static const int ICMP_HEADER_SIZE = 8u;
static const int ICMP_PING_TIMEOUT_MILLIS = 10000u;
+#endif
class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
public:
@@ -498,7 +501,7 @@ class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
}
void MaybeRemapSendError() {
-#if defined(OSX)
+#if defined(OSX) || defined(IOS)
// https://developer.apple.com/library/mac/documentation/Darwin/
// Reference/ManPages/man2/sendto.2.html
// ENOBUFS - The output queue for a network interface is full.
@@ -517,7 +520,7 @@ class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
*slevel = IPPROTO_IP;
*sopt = IP_DONTFRAGMENT;
break;
-#elif defined(IOS) || defined(OSX) || defined(BSD)
+#elif defined(IOS) || defined(OSX) || defined(BSD) || defined(__native_client__)
LOG(LS_WARNING) << "Socket::OPT_DONTFRAGMENT not supported.";
return -1;
#elif defined(POSIX)
@@ -540,6 +543,8 @@ class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
case OPT_DSCP:
LOG(LS_WARNING) << "Socket::OPT_DSCP not supported.";
return -1;
+ case OPT_RTP_SENDTIME_EXTN_ID:
+ return -1; // No logging is necessary as this not a OS socket option.
default:
ASSERT(false);
return -1;
@@ -1199,9 +1204,7 @@ class Signaler : public EventDispatcher {
};
PhysicalSocketServer::PhysicalSocketServer()
- : fWait_(false),
- last_tick_tracked_(0),
- last_tick_dispatch_count_(0) {
+ : fWait_(false) {
signal_wakeup_ = new Signaler(this, &fWait_);
#ifdef WIN32
socket_ev_ = WSACreateEvent();
@@ -1489,10 +1492,14 @@ bool PhysicalSocketServer::InstallSignal(int signum, void (*handler)(int)) {
return false;
}
act.sa_handler = handler;
+#if !defined(__native_client__)
// Use SA_RESTART so that our syscalls don't get EINTR, since we don't need it
// and it's a nuisance. Though some syscalls still return EINTR and there's no
// real standard for which ones. :(
act.sa_flags = SA_RESTART;
+#else
+ act.sa_flags = 0;
+#endif
if (sigaction(signum, &act, NULL) != 0) {
LOG_ERR(LS_ERROR) << "Couldn't set sigaction";
return false;
@@ -1507,12 +1514,6 @@ bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) {
int cmsElapsed = 0;
uint32 msStart = Time();
-#if LOGGING
- if (last_tick_dispatch_count_ == 0) {
- last_tick_tracked_ = msStart;
- }
-#endif
-
fWait_ = true;
while (fWait_) {
std::vector<WSAEVENT> events;
@@ -1562,27 +1563,10 @@ bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) {
cmsNext,
false);
-#if 0 // LOGGING
- // we track this information purely for logging purposes.
- last_tick_dispatch_count_++;
- if (last_tick_dispatch_count_ >= 1000) {
- int32 elapsed = TimeSince(last_tick_tracked_);
- LOG(INFO) << "PhysicalSocketServer took " << elapsed
- << "ms for 1000 events";
-
- // If we get more than 1000 events in a second, we are spinning badly
- // (normally it should take about 8-20 seconds).
- ASSERT(elapsed > 1000);
-
- last_tick_tracked_ = Time();
- last_tick_dispatch_count_ = 0;
- }
-#endif
-
if (dw == WSA_WAIT_FAILED) {
// Failed?
// TODO: need a better strategy than this!
- int error = WSAGetLastError();
+ WSAGetLastError();
ASSERT(false);
return false;
} else if (dw == WSA_WAIT_TIMEOUT) {
diff --git a/chromium/third_party/libjingle/source/talk/base/physicalsocketserver.h b/chromium/third_party/libjingle/source/talk/base/physicalsocketserver.h
index 709f85ab105..9173f238dff 100644
--- a/chromium/third_party/libjingle/source/talk/base/physicalsocketserver.h
+++ b/chromium/third_party/libjingle/source/talk/base/physicalsocketserver.h
@@ -127,8 +127,6 @@ class PhysicalSocketServer : public SocketServer {
Signaler* signal_wakeup_;
CriticalSection crit_;
bool fWait_;
- uint32 last_tick_tracked_;
- int last_tick_dispatch_count_;
#ifdef WIN32
WSAEVENT socket_ev_;
#endif
diff --git a/chromium/third_party/libjingle/source/talk/base/physicalsocketserver_unittest.cc b/chromium/third_party/libjingle/source/talk/base/physicalsocketserver_unittest.cc
index 329cf5d5f25..cbdbd9cad6a 100644
--- a/chromium/third_party/libjingle/source/talk/base/physicalsocketserver_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/physicalsocketserver_unittest.cc
@@ -33,6 +33,7 @@
#include "talk/base/physicalsocketserver.h"
#include "talk/base/scoped_ptr.h"
#include "talk/base/socket_unittest.h"
+#include "talk/base/testutils.h"
#include "talk/base/thread.h"
namespace talk_base {
@@ -74,21 +75,11 @@ TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) {
}
-#ifdef OSX
-// This test crashes the OS X kernel on 10.6 (at bsd/netinet/tcp_subr.c:2118).
-TEST_F(PhysicalSocketTest, DISABLED_TestConnectWithClosedSocketIPv4) {
-#else
TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
-#endif
SocketTest::TestConnectWithClosedSocketIPv4();
}
-#ifdef OSX
-// This test crashes the OS X kernel on 10.6 (at bsd/netinet/tcp_subr.c:2118).
-TEST_F(PhysicalSocketTest, DISABLED_TestConnectWithClosedSocketIPv6) {
-#else
TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) {
-#endif
SocketTest::TestConnectWithClosedSocketIPv6();
}
@@ -227,7 +218,7 @@ Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
// Test receiving a synchronous signal while not in Wait() and then entering
// Wait() afterwards.
TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
- ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
+ ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
raise(SIGTERM);
EXPECT_TRUE(ss_->Wait(0, true));
EXPECT_TRUE(ExpectSignal(SIGTERM));
diff --git a/chromium/third_party/libjingle/source/talk/base/profiler.h b/chromium/third_party/libjingle/source/talk/base/profiler.h
index 90c5c722a30..f74a540ae47 100644
--- a/chromium/third_party/libjingle/source/talk/base/profiler.h
+++ b/chromium/third_party/libjingle/source/talk/base/profiler.h
@@ -57,7 +57,9 @@
#include "talk/base/sharedexclusivelock.h"
// Profiling could be switched via a build flag, but for now, it's always on.
+#ifndef ENABLE_PROFILING
#define ENABLE_PROFILING
+#endif
#ifdef ENABLE_PROFILING
diff --git a/chromium/third_party/libjingle/source/talk/base/profiler_unittest.cc b/chromium/third_party/libjingle/source/talk/base/profiler_unittest.cc
index f451e5fab83..a39b32c4995 100644
--- a/chromium/third_party/libjingle/source/talk/base/profiler_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/profiler_unittest.cc
@@ -47,13 +47,15 @@ namespace talk_base {
TEST(ProfilerTest, TestFunction) {
ASSERT_TRUE(Profiler::Instance()->Clear());
+
// Profile a long-running function.
const char* function_name = TestFunc();
const ProfilerEvent* event = Profiler::Instance()->GetEvent(function_name);
ASSERT_TRUE(event != NULL);
EXPECT_FALSE(event->is_started());
EXPECT_EQ(1, event->event_count());
- EXPECT_NEAR(kWaitSec, event->mean(), kTolerance);
+ EXPECT_NEAR(kWaitSec, event->mean(), kTolerance * 3);
+
// Run it a second time.
TestFunc();
EXPECT_FALSE(event->is_started());
@@ -95,7 +97,9 @@ TEST(ProfilerTest, TestScopedEvents) {
// Check the result.
EXPECT_FALSE(event2->is_started());
EXPECT_EQ(1, event2->event_count());
- EXPECT_NEAR(kEvent2WaitSec, event2->mean(), kTolerance);
+
+ // The difference here can be as much as 0.33, so we need high tolerance.
+ EXPECT_NEAR(kEvent2WaitSec, event2->mean(), kTolerance * 4);
// Make sure event1 is unchanged.
EXPECT_FALSE(event1->is_started());
EXPECT_EQ(1, event1->event_count());
diff --git a/chromium/third_party/libjingle/source/talk/base/proxydetect.cc b/chromium/third_party/libjingle/source/talk/base/proxydetect.cc
index 7292f3b9fd2..8f7f7f87260 100644
--- a/chromium/third_party/libjingle/source/talk/base/proxydetect.cc
+++ b/chromium/third_party/libjingle/source/talk/base/proxydetect.cc
@@ -638,27 +638,27 @@ bool IsDefaultBrowserFirefox() {
if (ERROR_SUCCESS != result)
return false;
- wchar_t* value = NULL;
DWORD size, type;
+ bool success = false;
result = RegQueryValueEx(key, L"", 0, &type, NULL, &size);
- if (REG_SZ != type) {
- result = ERROR_ACCESS_DENIED; // Any error is fine
- } else if (ERROR_SUCCESS == result) {
- value = new wchar_t[size+1];
+ if (result == ERROR_SUCCESS && type == REG_SZ) {
+ wchar_t* value = new wchar_t[size+1];
BYTE* buffer = reinterpret_cast<BYTE*>(value);
result = RegQueryValueEx(key, L"", 0, &type, buffer, &size);
- }
- RegCloseKey(key);
-
- bool success = false;
- if (ERROR_SUCCESS == result) {
- value[size] = L'\0';
- for (size_t i = 0; i < size; ++i) {
- value[i] = tolowercase(value[i]);
+ if (result == ERROR_SUCCESS) {
+ // Size returned by RegQueryValueEx is in bytes, convert to number of
+ // wchar_t's.
+ size /= sizeof(value[0]);
+ value[size] = L'\0';
+ for (size_t i = 0; i < size; ++i) {
+ value[i] = tolowercase(value[i]);
+ }
+ success = (NULL != strstr(value, L"firefox.exe"));
}
- success = (NULL != strstr(value, L"firefox.exe"));
+ delete[] value;
}
- delete [] value;
+
+ RegCloseKey(key);
return success;
}
diff --git a/chromium/third_party/libjingle/source/talk/base/proxydetect_unittest.cc b/chromium/third_party/libjingle/source/talk/base/proxydetect_unittest.cc
index 685066d9432..e09518b5f41 100644
--- a/chromium/third_party/libjingle/source/talk/base/proxydetect_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/proxydetect_unittest.cc
@@ -51,7 +51,6 @@ static const std::string kFirefoxCorruptHeader =
"iuahueqe32164";
static const std::string kProxyAddress = "proxy.net.com";
-static const int kProxyPort = 9999;
// Mocking out platform specific path to firefox prefs file.
class FirefoxPrefsFileSystem : public FakeFileSystem {
diff --git a/chromium/third_party/libjingle/source/talk/base/refcount.h b/chromium/third_party/libjingle/source/talk/base/refcount.h
index 38cf147621a..e8950e9b04c 100644
--- a/chromium/third_party/libjingle/source/talk/base/refcount.h
+++ b/chromium/third_party/libjingle/source/talk/base/refcount.h
@@ -28,7 +28,7 @@
#ifndef TALK_APP_BASE_REFCOUNT_H_
#define TALK_APP_BASE_REFCOUNT_H_
-#include <cstring>
+#include <string.h>
#include "talk/base/criticalsection.h"
diff --git a/chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h b/chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h
index cdad0251f3f..dfda8fec072 100644
--- a/chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h
+++ b/chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h
@@ -42,11 +42,8 @@ template<typename T>
class RollingAccumulator {
public:
explicit RollingAccumulator(size_t max_count)
- : count_(0),
- next_index_(0),
- sum_(0.0),
- sum_2_(0.0),
- samples_(max_count) {
+ : samples_(max_count) {
+ Reset();
}
~RollingAccumulator() {
}
@@ -59,12 +56,29 @@ class RollingAccumulator {
return count_;
}
+ void Reset() {
+ count_ = 0U;
+ next_index_ = 0U;
+ sum_ = 0.0;
+ sum_2_ = 0.0;
+ max_ = T();
+ max_stale_ = false;
+ min_ = T();
+ min_stale_ = false;
+ }
+
void AddSample(T sample) {
if (count_ == max_count()) {
// Remove oldest sample.
T sample_to_remove = samples_[next_index_];
sum_ -= sample_to_remove;
sum_2_ -= sample_to_remove * sample_to_remove;
+ if (sample_to_remove >= max_) {
+ max_stale_ = true;
+ }
+ if (sample_to_remove <= min_) {
+ min_stale_ = true;
+ }
} else {
// Increase count of samples.
++count_;
@@ -73,6 +87,14 @@ class RollingAccumulator {
samples_[next_index_] = sample;
sum_ += sample;
sum_2_ += sample * sample;
+ if (count_ == 1 || sample >= max_) {
+ max_ = sample;
+ max_stale_ = false;
+ }
+ if (count_ == 1 || sample <= min_) {
+ min_ = sample;
+ min_stale_ = false;
+ }
// Update next_index_.
next_index_ = (next_index_ + 1) % max_count();
}
@@ -81,17 +103,43 @@ class RollingAccumulator {
return static_cast<T>(sum_);
}
- T ComputeMean() const {
+ double ComputeMean() const {
if (count_ == 0) {
- return static_cast<T>(0);
+ return 0.0;
+ }
+ return sum_ / count_;
+ }
+
+ T ComputeMax() const {
+ if (max_stale_) {
+ ASSERT(count_ > 0 &&
+ "It shouldn't be possible for max_stale_ && count_ == 0");
+ max_ = samples_[next_index_];
+ for (size_t i = 1u; i < count_; i++) {
+ max_ = _max(max_, samples_[(next_index_ + i) % max_count()]);
+ }
+ max_stale_ = false;
+ }
+ return max_;
+ }
+
+ T ComputeMin() const {
+ if (min_stale_) {
+ ASSERT(count_ > 0 &&
+ "It shouldn't be possible for min_stale_ && count_ == 0");
+ min_ = samples_[next_index_];
+ for (size_t i = 1u; i < count_; i++) {
+ min_ = _min(min_, samples_[(next_index_ + i) % max_count()]);
+ }
+ min_stale_ = false;
}
- return static_cast<T>(sum_ / count_);
+ return min_;
}
// O(n) time complexity.
// Weights nth sample with weight (learning_rate)^n. Learning_rate should be
// between (0.0, 1.0], otherwise the non-weighted mean is returned.
- T ComputeWeightedMean(double learning_rate) const {
+ double ComputeWeightedMean(double learning_rate) const {
if (count_ < 1 || learning_rate <= 0.0 || learning_rate >= 1.0) {
return ComputeMean();
}
@@ -106,27 +154,31 @@ class RollingAccumulator {
size_t index = (next_index_ + max_size - i - 1) % max_size;
weighted_mean += current_weight * samples_[index];
}
- return static_cast<T>(weighted_mean / weight_sum);
+ return weighted_mean / weight_sum;
}
// Compute estimated variance. Estimation is more accurate
// as the number of samples grows.
- T ComputeVariance() const {
+ double ComputeVariance() const {
if (count_ == 0) {
- return static_cast<T>(0);
+ return 0.0;
}
// Var = E[x^2] - (E[x])^2
double count_inv = 1.0 / count_;
double mean_2 = sum_2_ * count_inv;
double mean = sum_ * count_inv;
- return static_cast<T>(mean_2 - (mean * mean));
+ return mean_2 - (mean * mean);
}
private:
size_t count_;
size_t next_index_;
- double sum_; // Sum(x)
- double sum_2_; // Sum(x*x)
+ double sum_; // Sum(x) - double to avoid overflow
+ double sum_2_; // Sum(x*x) - double to avoid overflow
+ mutable T max_;
+ mutable bool max_stale_;
+ mutable T min_;
+ mutable bool min_stale_;
std::vector<T> samples_;
DISALLOW_COPY_AND_ASSIGN(RollingAccumulator);
diff --git a/chromium/third_party/libjingle/source/talk/base/rollingaccumulator_unittest.cc b/chromium/third_party/libjingle/source/talk/base/rollingaccumulator_unittest.cc
index c2831033645..e6d0ea2b750 100644
--- a/chromium/third_party/libjingle/source/talk/base/rollingaccumulator_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/rollingaccumulator_unittest.cc
@@ -40,8 +40,10 @@ TEST(RollingAccumulatorTest, ZeroSamples) {
RollingAccumulator<int> accum(10);
EXPECT_EQ(0U, accum.count());
- EXPECT_EQ(0, accum.ComputeMean());
- EXPECT_EQ(0, accum.ComputeVariance());
+ EXPECT_DOUBLE_EQ(0.0, accum.ComputeMean());
+ EXPECT_DOUBLE_EQ(0.0, accum.ComputeVariance());
+ EXPECT_EQ(0, accum.ComputeMin());
+ EXPECT_EQ(0, accum.ComputeMax());
}
TEST(RollingAccumulatorTest, SomeSamples) {
@@ -52,9 +54,11 @@ TEST(RollingAccumulatorTest, SomeSamples) {
EXPECT_EQ(4U, accum.count());
EXPECT_EQ(6, accum.ComputeSum());
- EXPECT_EQ(1, accum.ComputeMean());
- EXPECT_EQ(2, accum.ComputeWeightedMean(kLearningRate));
- EXPECT_EQ(1, accum.ComputeVariance());
+ EXPECT_DOUBLE_EQ(1.5, accum.ComputeMean());
+ EXPECT_NEAR(2.26666, accum.ComputeWeightedMean(kLearningRate), 0.01);
+ EXPECT_DOUBLE_EQ(1.25, accum.ComputeVariance());
+ EXPECT_EQ(0, accum.ComputeMin());
+ EXPECT_EQ(3, accum.ComputeMax());
}
TEST(RollingAccumulatorTest, RollingSamples) {
@@ -65,9 +69,36 @@ TEST(RollingAccumulatorTest, RollingSamples) {
EXPECT_EQ(10U, accum.count());
EXPECT_EQ(65, accum.ComputeSum());
- EXPECT_EQ(6, accum.ComputeMean());
- EXPECT_EQ(10, accum.ComputeWeightedMean(kLearningRate));
- EXPECT_NEAR(9, accum.ComputeVariance(), 1);
+ EXPECT_DOUBLE_EQ(6.5, accum.ComputeMean());
+ EXPECT_NEAR(10.0, accum.ComputeWeightedMean(kLearningRate), 0.01);
+ EXPECT_NEAR(9.0, accum.ComputeVariance(), 1.0);
+ EXPECT_EQ(2, accum.ComputeMin());
+ EXPECT_EQ(11, accum.ComputeMax());
+}
+
+TEST(RollingAccumulatorTest, ResetSamples) {
+ RollingAccumulator<int> accum(10);
+
+ for (int i = 0; i < 10; ++i) {
+ accum.AddSample(100);
+ }
+ EXPECT_EQ(10U, accum.count());
+ EXPECT_DOUBLE_EQ(100.0, accum.ComputeMean());
+ EXPECT_EQ(100, accum.ComputeMin());
+ EXPECT_EQ(100, accum.ComputeMax());
+
+ accum.Reset();
+ EXPECT_EQ(0U, accum.count());
+
+ for (int i = 0; i < 5; ++i) {
+ accum.AddSample(i);
+ }
+
+ EXPECT_EQ(5U, accum.count());
+ EXPECT_EQ(10, accum.ComputeSum());
+ EXPECT_DOUBLE_EQ(2.0, accum.ComputeMean());
+ EXPECT_EQ(0, accum.ComputeMin());
+ EXPECT_EQ(4, accum.ComputeMax());
}
TEST(RollingAccumulatorTest, RollingSamplesDouble) {
@@ -81,22 +112,24 @@ TEST(RollingAccumulatorTest, RollingSamplesDouble) {
EXPECT_DOUBLE_EQ(87.5, accum.ComputeMean());
EXPECT_NEAR(105.049, accum.ComputeWeightedMean(kLearningRate), 0.1);
EXPECT_NEAR(229.166667, accum.ComputeVariance(), 25);
+ EXPECT_DOUBLE_EQ(65.0, accum.ComputeMin());
+ EXPECT_DOUBLE_EQ(110.0, accum.ComputeMax());
}
TEST(RollingAccumulatorTest, ComputeWeightedMeanCornerCases) {
RollingAccumulator<int> accum(10);
- EXPECT_EQ(0, accum.ComputeWeightedMean(kLearningRate));
- EXPECT_EQ(0, accum.ComputeWeightedMean(0.0));
- EXPECT_EQ(0, accum.ComputeWeightedMean(1.1));
+ EXPECT_DOUBLE_EQ(0.0, accum.ComputeWeightedMean(kLearningRate));
+ EXPECT_DOUBLE_EQ(0.0, accum.ComputeWeightedMean(0.0));
+ EXPECT_DOUBLE_EQ(0.0, accum.ComputeWeightedMean(1.1));
for (int i = 0; i < 8; ++i) {
accum.AddSample(i);
}
- EXPECT_EQ(3, accum.ComputeMean());
- EXPECT_EQ(3, accum.ComputeWeightedMean(0));
- EXPECT_EQ(3, accum.ComputeWeightedMean(1.1));
- EXPECT_EQ(6, accum.ComputeWeightedMean(kLearningRate));
+ EXPECT_DOUBLE_EQ(3.5, accum.ComputeMean());
+ EXPECT_DOUBLE_EQ(3.5, accum.ComputeWeightedMean(0));
+ EXPECT_DOUBLE_EQ(3.5, accum.ComputeWeightedMean(1.1));
+ EXPECT_NEAR(6.0, accum.ComputeWeightedMean(kLearningRate), 0.1);
}
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/safe_conversions.h b/chromium/third_party/libjingle/source/talk/base/safe_conversions.h
new file mode 100644
index 00000000000..d246d4ffce1
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/safe_conversions.h
@@ -0,0 +1,96 @@
+/*
+ * libjingle
+ * Copyright 2014, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Borrowed from Chromium's src/base/numerics/safe_conversions.h.
+
+#ifndef TALK_BASE_SAFE_CONVERSIONS_H_
+#define TALK_BASE_SAFE_CONVERSIONS_H_
+
+#include <limits>
+
+#include "talk/base/common.h"
+#include "talk/base/logging.h"
+#include "talk/base/safe_conversions_impl.h"
+
+namespace talk_base {
+
+inline void Check(bool condition) {
+ if (!condition) {
+ LOG(LS_ERROR) << "CHECK failed.";
+ Break();
+ // The program should have crashed at this point.
+ }
+}
+
+// Convenience function that returns true if the supplied value is in range
+// for the destination type.
+template <typename Dst, typename Src>
+inline bool IsValueInRangeForNumericType(Src value) {
+ return internal::RangeCheck<Dst>(value) == internal::TYPE_VALID;
+}
+
+// checked_cast<> is analogous to static_cast<> for numeric types,
+// except that it CHECKs that the specified numeric conversion will not
+// overflow or underflow. NaN source will always trigger a CHECK.
+template <typename Dst, typename Src>
+inline Dst checked_cast(Src value) {
+ Check(IsValueInRangeForNumericType<Dst>(value));
+ return static_cast<Dst>(value);
+}
+
+// saturated_cast<> is analogous to static_cast<> for numeric types, except
+// that the specified numeric conversion will saturate rather than overflow or
+// underflow. NaN assignment to an integral will trigger a CHECK condition.
+template <typename Dst, typename Src>
+inline Dst saturated_cast(Src value) {
+ // Optimization for floating point values, which already saturate.
+ if (std::numeric_limits<Dst>::is_iec559)
+ return static_cast<Dst>(value);
+
+ switch (internal::RangeCheck<Dst>(value)) {
+ case internal::TYPE_VALID:
+ return static_cast<Dst>(value);
+
+ case internal::TYPE_UNDERFLOW:
+ return std::numeric_limits<Dst>::min();
+
+ case internal::TYPE_OVERFLOW:
+ return std::numeric_limits<Dst>::max();
+
+ // Should fail only on attempting to assign NaN to a saturated integer.
+ case internal::TYPE_INVALID:
+ Check(false);
+ return std::numeric_limits<Dst>::max();
+ }
+
+ Check(false); // NOTREACHED();
+ return static_cast<Dst>(value);
+}
+
+} // namespace talk_base
+
+#endif // TALK_BASE_SAFE_CONVERSIONS_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/safe_conversions_impl.h b/chromium/third_party/libjingle/source/talk/base/safe_conversions_impl.h
new file mode 100644
index 00000000000..391e5966b9a
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/safe_conversions_impl.h
@@ -0,0 +1,205 @@
+/*
+ * libjingle
+ * Copyright 2014, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Borrowed from Chromium's src/base/numerics/safe_conversions_impl.h.
+
+#ifndef TALK_BASE_SAFE_CONVERSIONS_IMPL_H_
+#define TALK_BASE_SAFE_CONVERSIONS_IMPL_H_
+
+#include <limits>
+
+namespace talk_base {
+namespace internal {
+
+enum DstSign {
+ DST_UNSIGNED,
+ DST_SIGNED
+};
+
+enum SrcSign {
+ SRC_UNSIGNED,
+ SRC_SIGNED
+};
+
+enum DstRange {
+ OVERLAPS_RANGE,
+ CONTAINS_RANGE
+};
+
+// Helper templates to statically determine if our destination type can contain
+// all values represented by the source type.
+
+template <typename Dst, typename Src,
+ DstSign IsDstSigned = std::numeric_limits<Dst>::is_signed ?
+ DST_SIGNED : DST_UNSIGNED,
+ SrcSign IsSrcSigned = std::numeric_limits<Src>::is_signed ?
+ SRC_SIGNED : SRC_UNSIGNED>
+struct StaticRangeCheck {};
+
+template <typename Dst, typename Src>
+struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_SIGNED> {
+ typedef std::numeric_limits<Dst> DstLimits;
+ typedef std::numeric_limits<Src> SrcLimits;
+ // Compare based on max_exponent, which we must compute for integrals.
+ static const size_t kDstMaxExponent = DstLimits::is_iec559 ?
+ DstLimits::max_exponent :
+ (sizeof(Dst) * 8 - 1);
+ static const size_t kSrcMaxExponent = SrcLimits::is_iec559 ?
+ SrcLimits::max_exponent :
+ (sizeof(Src) * 8 - 1);
+ static const DstRange value = kDstMaxExponent >= kSrcMaxExponent ?
+ CONTAINS_RANGE : OVERLAPS_RANGE;
+};
+
+template <typename Dst, typename Src>
+struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED> {
+ static const DstRange value = sizeof(Dst) >= sizeof(Src) ?
+ CONTAINS_RANGE : OVERLAPS_RANGE;
+};
+
+template <typename Dst, typename Src>
+struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_UNSIGNED> {
+ typedef std::numeric_limits<Dst> DstLimits;
+ typedef std::numeric_limits<Src> SrcLimits;
+ // Compare based on max_exponent, which we must compute for integrals.
+ static const size_t kDstMaxExponent = DstLimits::is_iec559 ?
+ DstLimits::max_exponent :
+ (sizeof(Dst) * 8 - 1);
+ static const size_t kSrcMaxExponent = sizeof(Src) * 8;
+ static const DstRange value = kDstMaxExponent >= kSrcMaxExponent ?
+ CONTAINS_RANGE : OVERLAPS_RANGE;
+};
+
+template <typename Dst, typename Src>
+struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_SIGNED> {
+ static const DstRange value = OVERLAPS_RANGE;
+};
+
+
+enum RangeCheckResult {
+ TYPE_VALID = 0, // Value can be represented by the destination type.
+ TYPE_UNDERFLOW = 1, // Value would overflow.
+ TYPE_OVERFLOW = 2, // Value would underflow.
+ TYPE_INVALID = 3 // Source value is invalid (i.e. NaN).
+};
+
+// This macro creates a RangeCheckResult from an upper and lower bound
+// check by taking advantage of the fact that only NaN can be out of range in
+// both directions at once.
+#define BASE_NUMERIC_RANGE_CHECK_RESULT(is_in_upper_bound, is_in_lower_bound) \
+ RangeCheckResult(((is_in_upper_bound) ? 0 : TYPE_OVERFLOW) | \
+ ((is_in_lower_bound) ? 0 : TYPE_UNDERFLOW))
+
+template <typename Dst,
+ typename Src,
+ DstSign IsDstSigned = std::numeric_limits<Dst>::is_signed ?
+ DST_SIGNED : DST_UNSIGNED,
+ SrcSign IsSrcSigned = std::numeric_limits<Src>::is_signed ?
+ SRC_SIGNED : SRC_UNSIGNED,
+ DstRange IsSrcRangeContained = StaticRangeCheck<Dst, Src>::value>
+struct RangeCheckImpl {};
+
+// The following templates are for ranges that must be verified at runtime. We
+// split it into checks based on signedness to avoid confusing casts and
+// compiler warnings on signed an unsigned comparisons.
+
+// Dst range always contains the result: nothing to check.
+template <typename Dst, typename Src, DstSign IsDstSigned, SrcSign IsSrcSigned>
+struct RangeCheckImpl<Dst, Src, IsDstSigned, IsSrcSigned, CONTAINS_RANGE> {
+ static RangeCheckResult Check(Src value) {
+ return TYPE_VALID;
+ }
+};
+
+// Signed to signed narrowing.
+template <typename Dst, typename Src>
+struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
+ static RangeCheckResult Check(Src value) {
+ typedef std::numeric_limits<Dst> DstLimits;
+ return DstLimits::is_iec559 ?
+ BASE_NUMERIC_RANGE_CHECK_RESULT(
+ value <= static_cast<Src>(DstLimits::max()),
+ value >= static_cast<Src>(DstLimits::max() * -1)) :
+ BASE_NUMERIC_RANGE_CHECK_RESULT(
+ value <= static_cast<Src>(DstLimits::max()),
+ value >= static_cast<Src>(DstLimits::min()));
+ }
+};
+
+// Unsigned to unsigned narrowing.
+template <typename Dst, typename Src>
+struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
+ static RangeCheckResult Check(Src value) {
+ typedef std::numeric_limits<Dst> DstLimits;
+ return BASE_NUMERIC_RANGE_CHECK_RESULT(
+ value <= static_cast<Src>(DstLimits::max()), true);
+ }
+};
+
+// Unsigned to signed.
+template <typename Dst, typename Src>
+struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
+ static RangeCheckResult Check(Src value) {
+ typedef std::numeric_limits<Dst> DstLimits;
+ return sizeof(Dst) > sizeof(Src) ? TYPE_VALID :
+ BASE_NUMERIC_RANGE_CHECK_RESULT(
+ value <= static_cast<Src>(DstLimits::max()), true);
+ }
+};
+
+// Signed to unsigned.
+template <typename Dst, typename Src>
+struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
+ static RangeCheckResult Check(Src value) {
+ typedef std::numeric_limits<Dst> DstLimits;
+ typedef std::numeric_limits<Src> SrcLimits;
+ // Compare based on max_exponent, which we must compute for integrals.
+ static const size_t kDstMaxExponent = sizeof(Dst) * 8;
+ static const size_t kSrcMaxExponent = SrcLimits::is_iec559 ?
+ SrcLimits::max_exponent :
+ (sizeof(Src) * 8 - 1);
+ return (kDstMaxExponent >= kSrcMaxExponent) ?
+ BASE_NUMERIC_RANGE_CHECK_RESULT(true, value >= static_cast<Src>(0)) :
+ BASE_NUMERIC_RANGE_CHECK_RESULT(
+ value <= static_cast<Src>(DstLimits::max()),
+ value >= static_cast<Src>(0));
+ }
+};
+
+template <typename Dst, typename Src>
+inline RangeCheckResult RangeCheck(Src value) {
+ COMPILE_ASSERT(std::numeric_limits<Src>::is_specialized,
+ argument_must_be_numeric);
+ COMPILE_ASSERT(std::numeric_limits<Dst>::is_specialized,
+ result_must_be_numeric);
+ return RangeCheckImpl<Dst, Src>::Check(value);
+}
+
+} // namespace internal
+} // namespace talk_base
+
+#endif // TALK_BASE_SAFE_CONVERSIONS_IMPL_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/scoped_ptr.h b/chromium/third_party/libjingle/source/talk/base/scoped_ptr.h
index 90f743c6285..5158a9e69cd 100644
--- a/chromium/third_party/libjingle/source/talk/base/scoped_ptr.h
+++ b/chromium/third_party/libjingle/source/talk/base/scoped_ptr.h
@@ -88,8 +88,8 @@
#ifndef TALK_BASE_SCOPED_PTR_H__
#define TALK_BASE_SCOPED_PTR_H__
-#include <cstddef> // for std::ptrdiff_t
-#include <stdlib.h> // for free() decl
+#include <stddef.h> // for ptrdiff_t
+#include <stdlib.h> // for free() decl
#include <algorithm> // For std::swap().
diff --git a/chromium/third_party/libjingle/source/talk/base/scoped_ref_ptr.h b/chromium/third_party/libjingle/source/talk/base/scoped_ref_ptr.h
index 3ce72cbce6d..ae1ab0f230e 100644
--- a/chromium/third_party/libjingle/source/talk/base/scoped_ref_ptr.h
+++ b/chromium/third_party/libjingle/source/talk/base/scoped_ref_ptr.h
@@ -80,6 +80,8 @@
#ifndef TALK_BASE_SCOPED_REF_PTR_H_
#define TALK_BASE_SCOPED_REF_PTR_H_
+#include <stddef.h>
+
namespace talk_base {
template <class T>
diff --git a/chromium/third_party/libjingle/source/talk/base/scopedptrcollection.h b/chromium/third_party/libjingle/source/talk/base/scopedptrcollection.h
new file mode 100644
index 00000000000..ec2726e272c
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/scopedptrcollection.h
@@ -0,0 +1,77 @@
+/*
+ * libjingle
+ * Copyright 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Stores a collection of pointers that are deleted when the container is
+// destructed.
+
+#ifndef TALK_BASE_SCOPEDPTRCOLLECTION_H_
+#define TALK_BASE_SCOPEDPTRCOLLECTION_H_
+
+#include <algorithm>
+#include <vector>
+
+#include "talk/base/basictypes.h"
+#include "talk/base/constructormagic.h"
+
+namespace talk_base {
+
+template<class T>
+class ScopedPtrCollection {
+ public:
+ typedef std::vector<T*> VectorT;
+
+ ScopedPtrCollection() { }
+ ~ScopedPtrCollection() {
+ for (typename VectorT::iterator it = collection_.begin();
+ it != collection_.end(); ++it) {
+ delete *it;
+ }
+ }
+
+ const VectorT& collection() const { return collection_; }
+ void Reserve(size_t size) {
+ collection_.reserve(size);
+ }
+ void PushBack(T* t) {
+ collection_.push_back(t);
+ }
+
+ // Remove |t| from the collection without deleting it.
+ void Remove(T* t) {
+ collection_.erase(std::remove(collection_.begin(), collection_.end(), t),
+ collection_.end());
+ }
+
+ private:
+ VectorT collection_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedPtrCollection);
+};
+
+} // namespace talk_base
+
+#endif // TALK_BASE_SCOPEDPTRCOLLECTION_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/scopedptrcollection_unittest.cc b/chromium/third_party/libjingle/source/talk/base/scopedptrcollection_unittest.cc
new file mode 100644
index 00000000000..dd9002e42f1
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/scopedptrcollection_unittest.cc
@@ -0,0 +1,90 @@
+/*
+ * libjingle
+ * Copyright 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/base/scopedptrcollection.h"
+#include "talk/base/gunit.h"
+
+namespace talk_base {
+
+namespace {
+
+class InstanceCounter {
+ public:
+ explicit InstanceCounter(int* num_instances)
+ : num_instances_(num_instances) {
+ ++(*num_instances_);
+ }
+ ~InstanceCounter() {
+ --(*num_instances_);
+ }
+
+ private:
+ int* num_instances_;
+
+ DISALLOW_COPY_AND_ASSIGN(InstanceCounter);
+};
+
+} // namespace
+
+class ScopedPtrCollectionTest : public testing::Test {
+ protected:
+ ScopedPtrCollectionTest()
+ : num_instances_(0),
+ collection_(new ScopedPtrCollection<InstanceCounter>()) {
+ }
+
+ int num_instances_;
+ scoped_ptr<ScopedPtrCollection<InstanceCounter> > collection_;
+};
+
+TEST_F(ScopedPtrCollectionTest, PushBack) {
+ EXPECT_EQ(0u, collection_->collection().size());
+ EXPECT_EQ(0, num_instances_);
+ const int kNum = 100;
+ for (int i = 0; i < kNum; ++i) {
+ collection_->PushBack(new InstanceCounter(&num_instances_));
+ }
+ EXPECT_EQ(static_cast<size_t>(kNum), collection_->collection().size());
+ EXPECT_EQ(kNum, num_instances_);
+ collection_.reset();
+ EXPECT_EQ(0, num_instances_);
+}
+
+TEST_F(ScopedPtrCollectionTest, Remove) {
+ InstanceCounter* ic = new InstanceCounter(&num_instances_);
+ collection_->PushBack(ic);
+ EXPECT_EQ(1u, collection_->collection().size());
+ collection_->Remove(ic);
+ EXPECT_EQ(1, num_instances_);
+ collection_.reset();
+ EXPECT_EQ(1, num_instances_);
+ delete ic;
+ EXPECT_EQ(0, num_instances_);
+}
+
+
+} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/sharedexclusivelock_unittest.cc b/chromium/third_party/libjingle/source/talk/base/sharedexclusivelock_unittest.cc
index 46b7fdfdc2c..e280aa28a88 100644
--- a/chromium/third_party/libjingle/source/talk/base/sharedexclusivelock_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/sharedexclusivelock_unittest.cc
@@ -148,7 +148,8 @@ class SharedExclusiveLockTest
int value_;
};
-TEST_F(SharedExclusiveLockTest, TestSharedShared) {
+// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3318
+TEST_F(SharedExclusiveLockTest, DISABLED_TestSharedShared) {
int value0, value1;
bool done0, done1;
ReadTask reader0(shared_exclusive_lock_.get(), &value_, &done0);
diff --git a/chromium/third_party/libjingle/source/talk/base/signalthread_unittest.cc b/chromium/third_party/libjingle/source/talk/base/signalthread_unittest.cc
index e5734d4df11..7bc73f05d0c 100644
--- a/chromium/third_party/libjingle/source/talk/base/signalthread_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/signalthread_unittest.cc
@@ -50,19 +50,19 @@ class SignalThreadTest : public testing::Test, public sigslot::has_slots<> {
ASSERT_TRUE(harness_ != NULL);
++harness_->thread_started_;
EXPECT_EQ(harness_->main_thread_, Thread::Current());
- EXPECT_FALSE(worker()->started()); // not started yet
+ EXPECT_FALSE(worker()->RunningForTest()); // not started yet
}
virtual void OnWorkStop() {
++harness_->thread_stopped_;
EXPECT_EQ(harness_->main_thread_, Thread::Current());
- EXPECT_TRUE(worker()->started()); // not stopped yet
+ EXPECT_TRUE(worker()->RunningForTest()); // not stopped yet
}
virtual void OnWorkDone() {
++harness_->thread_done_;
EXPECT_EQ(harness_->main_thread_, Thread::Current());
- EXPECT_TRUE(worker()->started()); // not stopped yet
+ EXPECT_TRUE(worker()->RunningForTest()); // not stopped yet
}
virtual void DoWork() {
diff --git a/chromium/third_party/libjingle/source/talk/base/sigslottester.h b/chromium/third_party/libjingle/source/talk/base/sigslottester.h
new file mode 100755
index 00000000000..9422318e236
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/sigslottester.h
@@ -0,0 +1,216 @@
+// This file was GENERATED by command:
+// pump.py sigslottester.h.pump
+// DO NOT EDIT BY HAND!!!
+
+/*
+ * libjingle
+ * Copyright 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TALK_BASE_SIGSLOTTESTER_H_
+#define TALK_BASE_SIGSLOTTESTER_H_
+
+// To generate sigslottester.h from sigslottester.h.pump, execute:
+// /home/build/google3/third_party/gtest/scripts/pump.py sigslottester.h.pump
+
+
+// SigslotTester(s) are utility classes to check if signals owned by an
+// object are being invoked at the right time and with the right arguments.
+// They are meant to be used in tests. Tests must provide "capture" pointers
+// (i.e. address of variables) where the arguments from the signal callback
+// can be stored.
+//
+// Example:
+// /* Some signal */
+// sigslot::signal1<const std::string&> foo;
+//
+// /* We want to monitor foo in some test. Note how signal argument is
+// const std::string&, but capture-type is std::string. Capture type
+// must be type that can be assigned to. */
+// std::string capture;
+// SigslotTester1<const std::string&, std::string> slot(&foo, &capture);
+// foo.emit("hello");
+// EXPECT_EQ(1, slot.callback_count());
+// EXPECT_EQ("hello", capture);
+// /* See unit-tests for more examples */
+
+#include "talk/base/constructormagic.h"
+#include "talk/base/sigslot.h"
+
+namespace talk_base {
+
+// For all the templates below:
+// - A1-A5 is the type of the argument i in the callback. Signals may and often
+// do use const-references here for efficiency.
+// - C1-C5 is the type of the variable to capture argument i. These should be
+// non-const value types suitable for use as lvalues.
+
+template <class A1, class C1>
+class SigslotTester1 : public sigslot::has_slots<> {
+ public:
+ SigslotTester1(sigslot::signal1<A1>* signal,
+ C1* capture1)
+ : callback_count_(0),
+ capture1_(capture1) {
+ signal->connect(this, &SigslotTester1::OnSignalCallback);
+ }
+
+ int callback_count() const { return callback_count_; }
+
+ private:
+ void OnSignalCallback(A1 arg1) {
+ callback_count_++;
+ *capture1_ = arg1;
+ }
+
+ int callback_count_;
+ C1* capture1_;
+
+ DISALLOW_COPY_AND_ASSIGN(SigslotTester1);
+};
+
+template <class A1, class A2, class C1, class C2>
+class SigslotTester2 : public sigslot::has_slots<> {
+ public:
+ SigslotTester2(sigslot::signal2<A1, A2>* signal,
+ C1* capture1, C2* capture2)
+ : callback_count_(0),
+ capture1_(capture1), capture2_(capture2) {
+ signal->connect(this, &SigslotTester2::OnSignalCallback);
+ }
+
+ int callback_count() const { return callback_count_; }
+
+ private:
+ void OnSignalCallback(A1 arg1, A2 arg2) {
+ callback_count_++;
+ *capture1_ = arg1;
+ *capture2_ = arg2;
+ }
+
+ int callback_count_;
+ C1* capture1_;
+ C2* capture2_;
+
+ DISALLOW_COPY_AND_ASSIGN(SigslotTester2);
+};
+
+template <class A1, class A2, class A3, class C1, class C2, class C3>
+class SigslotTester3 : public sigslot::has_slots<> {
+ public:
+ SigslotTester3(sigslot::signal3<A1, A2, A3>* signal,
+ C1* capture1, C2* capture2, C3* capture3)
+ : callback_count_(0),
+ capture1_(capture1), capture2_(capture2), capture3_(capture3) {
+ signal->connect(this, &SigslotTester3::OnSignalCallback);
+ }
+
+ int callback_count() const { return callback_count_; }
+
+ private:
+ void OnSignalCallback(A1 arg1, A2 arg2, A3 arg3) {
+ callback_count_++;
+ *capture1_ = arg1;
+ *capture2_ = arg2;
+ *capture3_ = arg3;
+ }
+
+ int callback_count_;
+ C1* capture1_;
+ C2* capture2_;
+ C3* capture3_;
+
+ DISALLOW_COPY_AND_ASSIGN(SigslotTester3);
+};
+
+template <class A1, class A2, class A3, class A4, class C1, class C2, class C3,
+ class C4>
+class SigslotTester4 : public sigslot::has_slots<> {
+ public:
+ SigslotTester4(sigslot::signal4<A1, A2, A3, A4>* signal,
+ C1* capture1, C2* capture2, C3* capture3, C4* capture4)
+ : callback_count_(0),
+ capture1_(capture1), capture2_(capture2), capture3_(capture3),
+ capture4_(capture4) {
+ signal->connect(this, &SigslotTester4::OnSignalCallback);
+ }
+
+ int callback_count() const { return callback_count_; }
+
+ private:
+ void OnSignalCallback(A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
+ callback_count_++;
+ *capture1_ = arg1;
+ *capture2_ = arg2;
+ *capture3_ = arg3;
+ *capture4_ = arg4;
+ }
+
+ int callback_count_;
+ C1* capture1_;
+ C2* capture2_;
+ C3* capture3_;
+ C4* capture4_;
+
+ DISALLOW_COPY_AND_ASSIGN(SigslotTester4);
+};
+
+template <class A1, class A2, class A3, class A4, class A5, class C1, class C2,
+ class C3, class C4, class C5>
+class SigslotTester5 : public sigslot::has_slots<> {
+ public:
+ SigslotTester5(sigslot::signal5<A1, A2, A3, A4, A5>* signal,
+ C1* capture1, C2* capture2, C3* capture3, C4* capture4,
+ C5* capture5)
+ : callback_count_(0),
+ capture1_(capture1), capture2_(capture2), capture3_(capture3),
+ capture4_(capture4), capture5_(capture5) {
+ signal->connect(this, &SigslotTester5::OnSignalCallback);
+ }
+
+ int callback_count() const { return callback_count_; }
+
+ private:
+ void OnSignalCallback(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5) {
+ callback_count_++;
+ *capture1_ = arg1;
+ *capture2_ = arg2;
+ *capture3_ = arg3;
+ *capture4_ = arg4;
+ *capture5_ = arg5;
+ }
+
+ int callback_count_;
+ C1* capture1_;
+ C2* capture2_;
+ C3* capture3_;
+ C4* capture4_;
+ C5* capture5_;
+
+ DISALLOW_COPY_AND_ASSIGN(SigslotTester5);
+};
+} // namespace talk_base
+
+#endif // TALK_BASE_SIGSLOTTESTER_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/sigslottester.h.pump b/chromium/third_party/libjingle/source/talk/base/sigslottester.h.pump
new file mode 100755
index 00000000000..dce1c7b26ea
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/sigslottester.h.pump
@@ -0,0 +1,102 @@
+/*
+ * libjingle
+ * Copyright 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TALK_BASE_SIGSLOTTESTER_H_
+#define TALK_BASE_SIGSLOTTESTER_H_
+
+// To generate sigslottester.h from sigslottester.h.pump, execute:
+// /home/build/google3/third_party/gtest/scripts/pump.py sigslottester.h.pump
+
+
+// SigslotTester(s) are utility classes to check if signals owned by an
+// object are being invoked at the right time and with the right arguments.
+// They are meant to be used in tests. Tests must provide "capture" pointers
+// (i.e. address of variables) where the arguments from the signal callback
+// can be stored.
+//
+// Example:
+// /* Some signal */
+// sigslot::signal1<const std::string&> foo;
+//
+// /* We want to monitor foo in some test. Note how signal argument is
+// const std::string&, but capture-type is std::string. Capture type
+// must be type that can be assigned to. */
+// std::string capture;
+// SigslotTester1<const std::string&, std::string> slot(&foo, &capture);
+// foo.emit("hello");
+// EXPECT_EQ(1, slot.callback_count());
+// EXPECT_EQ("hello", capture);
+// /* See unit-tests for more examples */
+
+#include "talk/base/constructormagic.h"
+#include "talk/base/sigslot.h"
+
+namespace talk_base {
+
+// For all the templates below:
+// - A1-A5 is the type of the argument i in the callback. Signals may and often
+// do use const-references here for efficiency.
+// - C1-C5 is the type of the variable to capture argument i. These should be
+// non-const value types suitable for use as lvalues.
+
+$var n = 5
+$range i 1..n
+$for i [[
+$range j 1..i
+
+template <$for j , [[class A$j]], $for j , [[class C$j]]>
+class SigslotTester$i : public sigslot::has_slots<> {
+ public:
+ SigslotTester$i(sigslot::signal$i<$for j , [[A$j]]>* signal,
+ $for j , [[C$j* capture$j]])
+ : callback_count_(0),
+ $for j , [[capture$j[[]]_(capture$j)]] {
+ signal->connect(this, &SigslotTester$i::OnSignalCallback);
+ }
+
+ int callback_count() const { return callback_count_; }
+
+ private:
+ void OnSignalCallback($for j , [[A$j arg$j]]) {
+ callback_count_++;$for j [[
+
+ *capture$j[[]]_ = arg$j;]]
+
+ }
+
+ int callback_count_;$for j [[
+
+ C$j* capture$j[[]]_;]]
+
+
+ DISALLOW_COPY_AND_ASSIGN(SigslotTester$i);
+};
+
+]]
+} // namespace talk_base
+
+#endif // TALK_BASE_SIGSLOTTESTER_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/sigslottester_unittest.cc b/chromium/third_party/libjingle/source/talk/base/sigslottester_unittest.cc
new file mode 100755
index 00000000000..b427ef67c2d
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/sigslottester_unittest.cc
@@ -0,0 +1,74 @@
+#include "talk/base/sigslottester.h"
+
+#include "talk/base/gunit.h"
+#include "talk/base/sigslot.h"
+
+namespace talk_base {
+
+TEST(SigslotTester, TestSignal1Arg) {
+ sigslot::signal1<int> source1;
+ int capture1;
+ SigslotTester1<int, int> slot1(&source1, &capture1);
+ EXPECT_EQ(0, slot1.callback_count());
+
+ source1.emit(10);
+ EXPECT_EQ(1, slot1.callback_count());
+ EXPECT_EQ(10, capture1);
+
+ source1.emit(20);
+ EXPECT_EQ(2, slot1.callback_count());
+ EXPECT_EQ(20, capture1);
+}
+
+TEST(SigslotTester, TestSignal2Args) {
+ sigslot::signal2<int, char> source2;
+ int capture1;
+ char capture2;
+ SigslotTester2<int, char, int, char> slot2(&source2, &capture1, &capture2);
+ EXPECT_EQ(0, slot2.callback_count());
+
+ source2.emit(10, 'x');
+ EXPECT_EQ(1, slot2.callback_count());
+ EXPECT_EQ(10, capture1);
+ EXPECT_EQ('x', capture2);
+
+ source2.emit(20, 'y');
+ EXPECT_EQ(2, slot2.callback_count());
+ EXPECT_EQ(20, capture1);
+ EXPECT_EQ('y', capture2);
+}
+
+// Since it applies for 1 and 2 args, we assume it will work for up to 5 args.
+
+TEST(SigslotTester, TestSignalWithConstReferenceArgs) {
+ sigslot::signal1<const std::string&> source1;
+ std::string capture1;
+ SigslotTester1<const std::string&, std::string> slot1(&source1, &capture1);
+ EXPECT_EQ(0, slot1.callback_count());
+ source1.emit("hello");
+ EXPECT_EQ(1, slot1.callback_count());
+ EXPECT_EQ("hello", capture1);
+}
+
+TEST(SigslotTester, TestSignalWithPointerToConstArgs) {
+ sigslot::signal1<const std::string*> source1;
+ const std::string* capture1;
+ SigslotTester1<const std::string*, const std::string*> slot1(&source1,
+ &capture1);
+ EXPECT_EQ(0, slot1.callback_count());
+ source1.emit(NULL);
+ EXPECT_EQ(1, slot1.callback_count());
+ EXPECT_EQ(NULL, capture1);
+}
+
+TEST(SigslotTester, TestSignalWithConstPointerArgs) {
+ sigslot::signal1<std::string* const> source1;
+ std::string* capture1;
+ SigslotTester1<std::string* const, std::string*> slot1(&source1, &capture1);
+ EXPECT_EQ(0, slot1.callback_count());
+ source1.emit(NULL);
+ EXPECT_EQ(1, slot1.callback_count());
+ EXPECT_EQ(NULL, capture1);
+}
+
+} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/socket.h b/chromium/third_party/libjingle/source/talk/base/socket.h
index e738060f89d..590645f83d4 100644
--- a/chromium/third_party/libjingle/source/talk/base/socket.h
+++ b/chromium/third_party/libjingle/source/talk/base/socket.h
@@ -2,26 +2,26 @@
* libjingle
* Copyright 2004--2005, Google Inc.
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * 1. Redistributions of source code must retain the above copyright notice,
+ * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -185,7 +185,10 @@ class Socket {
OPT_SNDBUF, // send buffer size
OPT_NODELAY, // whether Nagle algorithm is enabled
OPT_IPV6_V6ONLY, // Whether the socket is IPv6 only.
- OPT_DSCP // DSCP code
+ OPT_DSCP, // DSCP code
+ OPT_RTP_SENDTIME_EXTN_ID, // This is a non-traditional socket option param.
+ // This is specific to libjingle and will be used
+ // if SendTime option is needed at socket level.
};
virtual int GetOption(Option opt, int* value) = 0;
virtual int SetOption(Option opt, int value) = 0;
diff --git a/chromium/third_party/libjingle/source/talk/base/socket_unittest.cc b/chromium/third_party/libjingle/source/talk/base/socket_unittest.cc
index a9c4dbb0de4..e76d113b2e9 100644
--- a/chromium/third_party/libjingle/source/talk/base/socket_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/socket_unittest.cc
@@ -172,8 +172,8 @@ void SocketTest::TestUdpIPv6() {
}
void SocketTest::TestUdpReadyToSendIPv4() {
-#if !defined(OSX)
- // TODO(ronghuawu): Enable this test (currently failed on build bots) on mac.
+#if !defined(OSX) && !defined(IOS)
+ // TODO(ronghuawu): Enable this test on mac/ios.
UdpReadyToSend(kIPv4Loopback);
#endif
}
diff --git a/chromium/third_party/libjingle/source/talk/base/socketaddress.cc b/chromium/third_party/libjingle/source/talk/base/socketaddress.cc
index 193a2328208..792d414adcf 100644
--- a/chromium/third_party/libjingle/source/talk/base/socketaddress.cc
+++ b/chromium/third_party/libjingle/source/talk/base/socketaddress.cc
@@ -34,7 +34,9 @@
#if defined(OPENBSD)
#include <netinet/in_systm.h>
#endif
+#if !defined(__native_client__)
#include <netinet/ip.h>
+#endif
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
diff --git a/chromium/third_party/libjingle/source/talk/base/sslfingerprint.cc b/chromium/third_party/libjingle/source/talk/base/sslfingerprint.cc
new file mode 100644
index 00000000000..dfd5551abcd
--- /dev/null
+++ b/chromium/third_party/libjingle/source/talk/base/sslfingerprint.cc
@@ -0,0 +1,114 @@
+/*
+ * libjingle
+ * Copyright 2012, Google Inc.
+ * Copyright 2012, RTFM Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/base/sslfingerprint.h"
+
+#include <ctype.h>
+#include <string>
+
+#include "talk/base/helpers.h"
+#include "talk/base/messagedigest.h"
+#include "talk/base/stringencode.h"
+
+namespace talk_base {
+
+SSLFingerprint* SSLFingerprint::Create(
+ const std::string& algorithm, const talk_base::SSLIdentity* identity) {
+ if (!identity) {
+ return NULL;
+ }
+
+ return Create(algorithm, &(identity->certificate()));
+}
+
+SSLFingerprint* SSLFingerprint::Create(
+ const std::string& algorithm, const talk_base::SSLCertificate* cert) {
+ uint8 digest_val[64];
+ size_t digest_len;
+ bool ret = cert->ComputeDigest(
+ algorithm, digest_val, sizeof(digest_val), &digest_len);
+ if (!ret) {
+ return NULL;
+ }
+
+ return new SSLFingerprint(algorithm, digest_val, digest_len);
+}
+
+SSLFingerprint* SSLFingerprint::CreateFromRfc4572(
+ const std::string& algorithm, const std::string& fingerprint) {
+ if (algorithm.empty() || !talk_base::IsFips180DigestAlgorithm(algorithm))
+ return NULL;
+
+ if (fingerprint.empty())
+ return NULL;
+
+ size_t value_len;
+ char value[talk_base::MessageDigest::kMaxSize];
+ value_len = talk_base::hex_decode_with_delimiter(value, sizeof(value),
+ fingerprint.c_str(),
+ fingerprint.length(),
+ ':');
+ if (!value_len)
+ return NULL;
+
+ return new SSLFingerprint(algorithm,
+ reinterpret_cast<uint8*>(value),
+ value_len);
+}
+
+SSLFingerprint::SSLFingerprint(
+ const std::string& algorithm, const uint8* digest_in, size_t digest_len)
+ : algorithm(algorithm) {
+ digest.SetData(digest_in, digest_len);
+}
+
+SSLFingerprint::SSLFingerprint(const SSLFingerprint& from)
+ : algorithm(from.algorithm), digest(from.digest) {}
+
+bool SSLFingerprint::operator==(const SSLFingerprint& other) const {
+ return algorithm == other.algorithm &&
+ digest == other.digest;
+}
+
+std::string SSLFingerprint::GetRfc4572Fingerprint() const {
+ std::string fingerprint =
+ talk_base::hex_encode_with_delimiter(
+ digest.data(), digest.length(), ':');
+ std::transform(fingerprint.begin(), fingerprint.end(),
+ fingerprint.begin(), ::toupper);
+ return fingerprint;
+}
+
+std::string SSLFingerprint::ToString() {
+ std::string fp_str = algorithm;
+ fp_str.append(" ");
+ fp_str.append(GetRfc4572Fingerprint());
+ return fp_str;
+}
+
+} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/sslfingerprint.h b/chromium/third_party/libjingle/source/talk/base/sslfingerprint.h
index b85778947e6..a803d2129a7 100644
--- a/chromium/third_party/libjingle/source/talk/base/sslfingerprint.h
+++ b/chromium/third_party/libjingle/source/talk/base/sslfingerprint.h
@@ -29,81 +29,35 @@
#ifndef TALK_BASE_SSLFINGERPRINT_H_
#define TALK_BASE_SSLFINGERPRINT_H_
-#include <ctype.h>
#include <string>
#include "talk/base/buffer.h"
-#include "talk/base/helpers.h"
-#include "talk/base/messagedigest.h"
#include "talk/base/sslidentity.h"
-#include "talk/base/stringencode.h"
namespace talk_base {
+class SSLCertificate;
+
struct SSLFingerprint {
static SSLFingerprint* Create(const std::string& algorithm,
- const talk_base::SSLIdentity* identity) {
- if (!identity) {
- return NULL;
- }
-
- return Create(algorithm, &(identity->certificate()));
- }
+ const talk_base::SSLIdentity* identity);
static SSLFingerprint* Create(const std::string& algorithm,
- const talk_base::SSLCertificate* cert) {
- uint8 digest_val[64];
- size_t digest_len;
- bool ret = cert->ComputeDigest(
- algorithm, digest_val, sizeof(digest_val), &digest_len);
- if (!ret) {
- return NULL;
- }
-
- return new SSLFingerprint(algorithm, digest_val, digest_len);
- }
+ const talk_base::SSLCertificate* cert);
static SSLFingerprint* CreateFromRfc4572(const std::string& algorithm,
- const std::string& fingerprint) {
- if (algorithm.empty())
- return NULL;
-
- if (fingerprint.empty())
- return NULL;
-
- size_t value_len;
- char value[talk_base::MessageDigest::kMaxSize];
- value_len = talk_base::hex_decode_with_delimiter(value, sizeof(value),
- fingerprint.c_str(),
- fingerprint.length(),
- ':');
- if (!value_len)
- return NULL;
-
- return new SSLFingerprint(algorithm,
- reinterpret_cast<uint8*>(value),
- value_len);
- }
+ const std::string& fingerprint);
SSLFingerprint(const std::string& algorithm, const uint8* digest_in,
- size_t digest_len) : algorithm(algorithm) {
- digest.SetData(digest_in, digest_len);
- }
- SSLFingerprint(const SSLFingerprint& from)
- : algorithm(from.algorithm), digest(from.digest) {}
- bool operator==(const SSLFingerprint& other) const {
- return algorithm == other.algorithm &&
- digest == other.digest;
- }
-
- std::string GetRfc4572Fingerprint() const {
- std::string fingerprint =
- talk_base::hex_encode_with_delimiter(
- digest.data(), digest.length(), ':');
- std::transform(fingerprint.begin(), fingerprint.end(),
- fingerprint.begin(), ::toupper);
- return fingerprint;
- }
+ size_t digest_len);
+
+ SSLFingerprint(const SSLFingerprint& from);
+
+ bool operator==(const SSLFingerprint& other) const;
+
+ std::string GetRfc4572Fingerprint() const;
+
+ std::string ToString();
std::string algorithm;
talk_base::Buffer digest;
diff --git a/chromium/third_party/libjingle/source/talk/base/sslidentity.cc b/chromium/third_party/libjingle/source/talk/base/sslidentity.cc
index 8f704dc300e..d2d2b11f173 100644
--- a/chromium/third_party/libjingle/source/talk/base/sslidentity.cc
+++ b/chromium/third_party/libjingle/source/talk/base/sslidentity.cc
@@ -115,6 +115,10 @@ SSLIdentity* SSLIdentity::Generate(const std::string& common_name) {
return NULL;
}
+SSLIdentity* GenerateForTest(const SSLIdentityParams& params) {
+ return NULL;
+}
+
SSLIdentity* SSLIdentity::FromPEMStrings(const std::string& private_key,
const std::string& certificate) {
return NULL;
@@ -130,6 +134,10 @@ SSLIdentity* SSLIdentity::Generate(const std::string& common_name) {
return OpenSSLIdentity::Generate(common_name);
}
+SSLIdentity* SSLIdentity::GenerateForTest(const SSLIdentityParams& params) {
+ return OpenSSLIdentity::GenerateForTest(params);
+}
+
SSLIdentity* SSLIdentity::FromPEMStrings(const std::string& private_key,
const std::string& certificate) {
return OpenSSLIdentity::FromPEMStrings(private_key, certificate);
@@ -145,6 +153,10 @@ SSLIdentity* SSLIdentity::Generate(const std::string& common_name) {
return NSSIdentity::Generate(common_name);
}
+SSLIdentity* SSLIdentity::GenerateForTest(const SSLIdentityParams& params) {
+ return NSSIdentity::GenerateForTest(params);
+}
+
SSLIdentity* SSLIdentity::FromPEMStrings(const std::string& private_key,
const std::string& certificate) {
return NSSIdentity::FromPEMStrings(private_key, certificate);
diff --git a/chromium/third_party/libjingle/source/talk/base/sslidentity.h b/chromium/third_party/libjingle/source/talk/base/sslidentity.h
index 89b1008983c..b930f063ce2 100644
--- a/chromium/third_party/libjingle/source/talk/base/sslidentity.h
+++ b/chromium/third_party/libjingle/source/talk/base/sslidentity.h
@@ -81,9 +81,10 @@ class SSLCertificate {
virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const = 0;
// Compute the digest of the certificate given algorithm
- virtual bool ComputeDigest(const std::string &algorithm,
- unsigned char* digest, std::size_t size,
- std::size_t* length) const = 0;
+ virtual bool ComputeDigest(const std::string& algorithm,
+ unsigned char* digest,
+ size_t size,
+ size_t* length) const = 0;
};
// SSLCertChain is a simple wrapper for a vector of SSLCertificates. It serves
@@ -132,6 +133,16 @@ class SSLCertChain {
DISALLOW_COPY_AND_ASSIGN(SSLCertChain);
};
+// Parameters for generating an identity for testing. If common_name is
+// non-empty, it will be used for the certificate's subject and issuer name,
+// otherwise a random string will be used. |not_before| and |not_after| are
+// offsets to the current time in number of seconds.
+struct SSLIdentityParams {
+ std::string common_name;
+ int not_before; // in seconds.
+ int not_after; // in seconds.
+};
+
// Our identity in an SSL negotiation: a keypair and certificate (both
// with the same public key).
// This too is pretty much immutable once created.
@@ -144,6 +155,9 @@ class SSLIdentity {
// Caller is responsible for freeing the returned object.
static SSLIdentity* Generate(const std::string& common_name);
+ // Generates an identity with the specified validity period.
+ static SSLIdentity* GenerateForTest(const SSLIdentityParams& params);
+
// Construct an identity from a private key and a certificate.
static SSLIdentity* FromPEMStrings(const std::string& private_key,
const std::string& certificate);
diff --git a/chromium/third_party/libjingle/source/talk/base/sslidentity_unittest.cc b/chromium/third_party/libjingle/source/talk/base/sslidentity_unittest.cc
index b63b8b9d439..fdb165c9f61 100644
--- a/chromium/third_party/libjingle/source/talk/base/sslidentity_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/sslidentity_unittest.cc
@@ -177,32 +177,33 @@ TEST_F(SSLIdentityTest, DigestSHA512) {
TEST_F(SSLIdentityTest, FromPEMStrings) {
static const char kRSA_PRIVATE_KEY_PEM[] =
"-----BEGIN RSA PRIVATE KEY-----\n"
- "MIICXQIBAAKBgQDCueE4a9hDMZ3sbVZdlXOz9ZA+cvzie3zJ9gXnT/BCt9P4b9HE\n"
- "vD/tr73YBqD3Wr5ZWScmyGYF9EMn0r3rzBxv6oooLU5TdUvOm4rzUjkCLQaQML8o\n"
- "NxXq+qW/j3zUKGikLhaaAl/amaX2zSWUsRQ1CpngQ3+tmDNH4/25TncNmQIDAQAB\n"
- "AoGAUcuU0Id0k10fMjYHZk4mCPzot2LD2Tr4Aznl5vFMQipHzv7hhZtx2xzMSRcX\n"
- "vG+Qr6VkbcUWHgApyWubvZXCh3+N7Vo2aYdMAQ8XqmFpBdIrL5CVdVfqFfEMlgEy\n"
- "LSZNG5klnrIfl3c7zQVovLr4eMqyl2oGfAqPQz75+fecv1UCQQD6wNHch9NbAG1q\n"
- "yuFEhMARB6gDXb+5SdzFjjtTWW5uJfm4DcZLoYyaIZm0uxOwsUKd0Rsma+oGitS1\n"
- "CXmuqfpPAkEAxszyN3vIdpD44SREEtyKZBMNOk5pEIIGdbeMJC5/XHvpxww9xkoC\n"
- "+39NbvUZYd54uT+rafbx4QZKc0h9xA/HlwJBAL37lYVWy4XpPv1olWCKi9LbUCqs\n"
- "vvQtyD1N1BkEayy9TQRsO09WKOcmigRqsTJwOx7DLaTgokEuspYvhagWVPUCQE/y\n"
- "0+YkTbYBD1Xbs9SyBKXCU6uDJRWSdO6aZi2W1XloC9gUwDMiSJjD1Wwt/YsyYPJ+\n"
- "/Hyc5yFL2l0KZimW/vkCQQCjuZ/lPcH46EuzhdbRfumDOG5N3ld7UhGI1TIRy17W\n"
- "dGF90cG33/L6BfS8Ll+fkkW/2AMRk8FDvF4CZi2nfW4L\n"
+ "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n"
+ "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
+ "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
+ "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n"
+ "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n"
+ "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n"
+ "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n"
+ "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n"
+ "kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n"
+ "ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n"
+ "54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n"
+ "MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n"
+ "1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n"
+ "UCXiYxSsu20QNVw=\n"
"-----END RSA PRIVATE KEY-----\n";
static const char kCERT_PEM[] =
"-----BEGIN CERTIFICATE-----\n"
- "MIIBmTCCAQICCQCPNJORW/M13DANBgkqhkiG9w0BAQUFADARMQ8wDQYDVQQDDAZ3\n"
- "ZWJydGMwHhcNMTMwNjE0MjIzMDAxWhcNMTQwNjE0MjIzMDAxWjARMQ8wDQYDVQQD\n"
- "DAZ3ZWJydGMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMK54Thr2EMxnext\n"
- "Vl2Vc7P1kD5y/OJ7fMn2BedP8EK30/hv0cS8P+2vvdgGoPdavllZJybIZgX0QyfS\n"
- "vevMHG/qiigtTlN1S86bivNSOQItBpAwvyg3Fer6pb+PfNQoaKQuFpoCX9qZpfbN\n"
- "JZSxFDUKmeBDf62YM0fj/blOdw2ZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAECMt\n"
- "UZb35H8TnjGx4XPzco/kbnurMLFFWcuve/DwTsuf10Ia9N4md8LY0UtgIgtyNqWc\n"
- "ZwyRMwxONF6ty3wcaIiPbGqiAa55T3YRuPibkRmck9CjrmM9JAtyvqHnpHd2TsBD\n"
- "qCV42aXS3onOXDQ1ibuWq0fr0//aj0wo4KV474c=\n"
+ "MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n"
+ "ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n"
+ "EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n"
+ "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
+ "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
+ "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n"
+ "VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n"
+ "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n"
+ "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n"
"-----END CERTIFICATE-----\n";
talk_base::scoped_ptr<SSLIdentity> identity(
diff --git a/chromium/third_party/libjingle/source/talk/base/sslstreamadapter.h b/chromium/third_party/libjingle/source/talk/base/sslstreamadapter.h
index 3a7797370c3..1811f9566b8 100644
--- a/chromium/third_party/libjingle/source/talk/base/sslstreamadapter.h
+++ b/chromium/third_party/libjingle/source/talk/base/sslstreamadapter.h
@@ -2,26 +2,26 @@
* libjingle
* Copyright 2004--2008, Google Inc.
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * 1. Redistributions of source code must retain the above copyright notice,
+ * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -116,17 +116,6 @@ class SSLStreamAdapter : public StreamAdapterInterface {
// underlying stream opens.
virtual int StartSSLWithPeer() = 0;
- // Specify the certificate that our peer is expected to use in
- // peer-to-peer mode. Only this certificate will be accepted during
- // SSL verification. The certificate is assumed to have been
- // obtained through some other secure channel (such as the XMPP
- // channel). (This could also specify the certificate authority that
- // will sign the peer's certificate.)
- // SSLStream takes ownership of the SSLCertificate object and will
- // free it when appropriate. Should be called no more than once on a
- // given SSLStream instance.
- virtual void SetPeerCertificate(SSLCertificate* cert) = 0;
-
// Specify the digest of the certificate that our peer is expected to use in
// peer-to-peer mode. Only this certificate will be accepted during
// SSL verification. The certificate is assumed to have been
@@ -138,11 +127,9 @@ class SSLStreamAdapter : public StreamAdapterInterface {
const unsigned char* digest_val,
size_t digest_len) = 0;
- // Retrieves the peer's X.509 certificate, if a certificate has been
- // provided by SetPeerCertificate or a connection has been established. If
- // a connection has been established, this returns the
- // certificate transmitted over SSL, including the entire chain.
- // The returned certificate is owned by the caller.
+ // Retrieves the peer's X.509 certificate, if a connection has been
+ // established. It returns the transmitted over SSL, including the entire
+ // chain. The returned certificate is owned by the caller.
virtual bool GetPeerCertificate(SSLCertificate** cert) const = 0;
// Key Exporter interface from RFC 5705
diff --git a/chromium/third_party/libjingle/source/talk/base/sslstreamadapter_unittest.cc b/chromium/third_party/libjingle/source/talk/base/sslstreamadapter_unittest.cc
index 4b2fd6d84c0..fe276b3fcc7 100644
--- a/chromium/third_party/libjingle/source/talk/base/sslstreamadapter_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/sslstreamadapter_unittest.cc
@@ -49,32 +49,33 @@ static int kExporterContextLen = sizeof(kExporterContext);
static const char kRSA_PRIVATE_KEY_PEM[] =
"-----BEGIN RSA PRIVATE KEY-----\n"
- "MIICXQIBAAKBgQDCueE4a9hDMZ3sbVZdlXOz9ZA+cvzie3zJ9gXnT/BCt9P4b9HE\n"
- "vD/tr73YBqD3Wr5ZWScmyGYF9EMn0r3rzBxv6oooLU5TdUvOm4rzUjkCLQaQML8o\n"
- "NxXq+qW/j3zUKGikLhaaAl/amaX2zSWUsRQ1CpngQ3+tmDNH4/25TncNmQIDAQAB\n"
- "AoGAUcuU0Id0k10fMjYHZk4mCPzot2LD2Tr4Aznl5vFMQipHzv7hhZtx2xzMSRcX\n"
- "vG+Qr6VkbcUWHgApyWubvZXCh3+N7Vo2aYdMAQ8XqmFpBdIrL5CVdVfqFfEMlgEy\n"
- "LSZNG5klnrIfl3c7zQVovLr4eMqyl2oGfAqPQz75+fecv1UCQQD6wNHch9NbAG1q\n"
- "yuFEhMARB6gDXb+5SdzFjjtTWW5uJfm4DcZLoYyaIZm0uxOwsUKd0Rsma+oGitS1\n"
- "CXmuqfpPAkEAxszyN3vIdpD44SREEtyKZBMNOk5pEIIGdbeMJC5/XHvpxww9xkoC\n"
- "+39NbvUZYd54uT+rafbx4QZKc0h9xA/HlwJBAL37lYVWy4XpPv1olWCKi9LbUCqs\n"
- "vvQtyD1N1BkEayy9TQRsO09WKOcmigRqsTJwOx7DLaTgokEuspYvhagWVPUCQE/y\n"
- "0+YkTbYBD1Xbs9SyBKXCU6uDJRWSdO6aZi2W1XloC9gUwDMiSJjD1Wwt/YsyYPJ+\n"
- "/Hyc5yFL2l0KZimW/vkCQQCjuZ/lPcH46EuzhdbRfumDOG5N3ld7UhGI1TIRy17W\n"
- "dGF90cG33/L6BfS8Ll+fkkW/2AMRk8FDvF4CZi2nfW4L\n"
+ "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n"
+ "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
+ "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
+ "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n"
+ "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n"
+ "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n"
+ "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n"
+ "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n"
+ "kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n"
+ "ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n"
+ "54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n"
+ "MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n"
+ "1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n"
+ "UCXiYxSsu20QNVw=\n"
"-----END RSA PRIVATE KEY-----\n";
static const char kCERT_PEM[] =
"-----BEGIN CERTIFICATE-----\n"
- "MIIBmTCCAQICCQCPNJORW/M13DANBgkqhkiG9w0BAQUFADARMQ8wDQYDVQQDDAZ3\n"
- "ZWJydGMwHhcNMTMwNjE0MjIzMDAxWhcNMTQwNjE0MjIzMDAxWjARMQ8wDQYDVQQD\n"
- "DAZ3ZWJydGMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMK54Thr2EMxnext\n"
- "Vl2Vc7P1kD5y/OJ7fMn2BedP8EK30/hv0cS8P+2vvdgGoPdavllZJybIZgX0QyfS\n"
- "vevMHG/qiigtTlN1S86bivNSOQItBpAwvyg3Fer6pb+PfNQoaKQuFpoCX9qZpfbN\n"
- "JZSxFDUKmeBDf62YM0fj/blOdw2ZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAECMt\n"
- "UZb35H8TnjGx4XPzco/kbnurMLFFWcuve/DwTsuf10Ia9N4md8LY0UtgIgtyNqWc\n"
- "ZwyRMwxONF6ty3wcaIiPbGqiAa55T3YRuPibkRmck9CjrmM9JAtyvqHnpHd2TsBD\n"
- "qCV42aXS3onOXDQ1ibuWq0fr0//aj0wo4KV474c=\n"
+ "MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n"
+ "ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n"
+ "EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n"
+ "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
+ "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
+ "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n"
+ "VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n"
+ "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n"
+ "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n"
"-----END CERTIFICATE-----\n";
#define MAYBE_SKIP_TEST(feature) \
@@ -208,13 +209,47 @@ class SSLStreamAdapterTestBase : public testing::Test,
~SSLStreamAdapterTestBase() {
// Put it back for the next test.
talk_base::SetRandomTestMode(false);
- talk_base::CleanupSSL();
}
static void SetUpTestCase() {
talk_base::InitializeSSL();
}
+ static void TearDownTestCase() {
+ talk_base::CleanupSSL();
+ }
+
+ // Recreate the client/server identities with the specified validity period.
+ // |not_before| and |not_after| are offsets from the current time in number
+ // of seconds.
+ void ResetIdentitiesWithValidity(int not_before, int not_after) {
+ client_stream_ =
+ new SSLDummyStream(this, "c2s", &client_buffer_, &server_buffer_);
+ server_stream_ =
+ new SSLDummyStream(this, "s2c", &server_buffer_, &client_buffer_);
+
+ client_ssl_.reset(talk_base::SSLStreamAdapter::Create(client_stream_));
+ server_ssl_.reset(talk_base::SSLStreamAdapter::Create(server_stream_));
+
+ client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
+ server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
+
+ talk_base::SSLIdentityParams client_params;
+ client_params.common_name = "client";
+ client_params.not_before = not_before;
+ client_params.not_after = not_after;
+ client_identity_ = talk_base::SSLIdentity::GenerateForTest(client_params);
+
+ talk_base::SSLIdentityParams server_params;
+ server_params.common_name = "server";
+ server_params.not_before = not_before;
+ server_params.not_after = not_after;
+ server_identity_ = talk_base::SSLIdentity::GenerateForTest(server_params);
+
+ client_ssl_->SetIdentity(client_identity_);
+ server_ssl_->SetIdentity(server_identity_);
+ }
+
virtual void OnEvent(talk_base::StreamInterface *stream, int sig, int err) {
LOG(LS_INFO) << "SSLStreamAdapterTestBase::OnEvent sig=" << sig;
@@ -227,24 +262,6 @@ class SSLStreamAdapterTestBase : public testing::Test,
}
}
- void SetPeerIdentitiesByCertificate(bool correct) {
- LOG(LS_INFO) << "Setting peer identities by certificate";
-
- if (correct) {
- client_ssl_->SetPeerCertificate(server_identity_->certificate().
- GetReference());
- server_ssl_->SetPeerCertificate(client_identity_->certificate().
- GetReference());
- } else {
- // If incorrect, set up to expect our own certificate at the peer
- client_ssl_->SetPeerCertificate(client_identity_->certificate().
- GetReference());
- server_ssl_->SetPeerCertificate(server_identity_->certificate().
- GetReference());
- }
- identities_set_ = true;
- }
-
void SetPeerIdentitiesByDigest(bool correct) {
unsigned char digest[20];
size_t digest_len;
@@ -253,8 +270,8 @@ class SSLStreamAdapterTestBase : public testing::Test,
LOG(LS_INFO) << "Setting peer identities by digest";
rv = server_identity_->certificate().ComputeDigest(talk_base::DIGEST_SHA_1,
- digest, 20,
- &digest_len);
+ digest, 20,
+ &digest_len);
ASSERT_TRUE(rv);
if (!correct) {
LOG(LS_INFO) << "Setting bogus digest for server cert";
@@ -266,7 +283,7 @@ class SSLStreamAdapterTestBase : public testing::Test,
rv = client_identity_->certificate().ComputeDigest(talk_base::DIGEST_SHA_1,
- digest, 20, &digest_len);
+ digest, 20, &digest_len);
ASSERT_TRUE(rv);
if (!correct) {
LOG(LS_INFO) << "Setting bogus digest for client cert";
@@ -722,17 +739,6 @@ TEST_F(SSLStreamAdapterTestTLS, TestTLSBogusDigest) {
TestHandshake(false);
};
-// Test a handshake with a peer certificate
-TEST_F(SSLStreamAdapterTestTLS, TestTLSPeerCertificate) {
- SetPeerIdentitiesByCertificate(true);
- TestHandshake();
-};
-
-// Test a handshake with a bogus peer certificate
-TEST_F(SSLStreamAdapterTestTLS, TestTLSBogusPeerCertificate) {
- SetPeerIdentitiesByCertificate(false);
- TestHandshake(false);
-};
// Test moving a bunch of data
// Basic tests: DTLS
@@ -762,7 +768,7 @@ TEST_F(SSLStreamAdapterTestDTLS,
};
// Test a handshake with small MTU
-TEST_F(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSConnectWithSmallMtu) {
+TEST_F(SSLStreamAdapterTestDTLS, TestDTLSConnectWithSmallMtu) {
MAYBE_SKIP_TEST(HaveDtls);
SetMtu(700);
SetHandshakeWait(20000);
@@ -887,6 +893,24 @@ TEST_F(SSLStreamAdapterTestDTLS, TestDTLSExporter) {
ASSERT_TRUE(!memcmp(client_out, server_out, sizeof(client_out)));
}
+// Test not yet valid certificates are not rejected.
+TEST_F(SSLStreamAdapterTestDTLS, TestCertNotYetValid) {
+ MAYBE_SKIP_TEST(HaveDtls);
+ long one_day = 60 * 60 * 24;
+ // Make the certificates not valid until one day later.
+ ResetIdentitiesWithValidity(one_day, one_day);
+ TestHandshake();
+}
+
+// Test expired certificates are not rejected.
+TEST_F(SSLStreamAdapterTestDTLS, TestCertExpired) {
+ MAYBE_SKIP_TEST(HaveDtls);
+ long one_day = 60 * 60 * 24;
+ // Make the certificates already expired.
+ ResetIdentitiesWithValidity(-one_day, -one_day);
+ TestHandshake();
+}
+
// Test data transfer using certs created from strings.
TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestTransfer) {
MAYBE_SKIP_TEST(HaveDtls);
diff --git a/chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.cc b/chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.cc
index b42faa80c60..7be2878d016 100644
--- a/chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.cc
+++ b/chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.cc
@@ -80,13 +80,6 @@ StreamState SSLStreamAdapterHelper::GetState() const {
// not reached
}
-void SSLStreamAdapterHelper::SetPeerCertificate(SSLCertificate* cert) {
- ASSERT(peer_certificate_.get() == NULL);
- ASSERT(peer_certificate_digest_algorithm_.empty());
- ASSERT(ssl_server_name_.empty());
- peer_certificate_.reset(cert);
-}
-
bool SSLStreamAdapterHelper::GetPeerCertificate(SSLCertificate** cert) const {
if (!peer_certificate_)
return false;
diff --git a/chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.h b/chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.h
index 7c280566127..5023d52ec19 100644
--- a/chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.h
+++ b/chromium/third_party/libjingle/source/talk/base/sslstreamadapterhelper.h
@@ -59,7 +59,6 @@ class SSLStreamAdapterHelper : public SSLStreamAdapter {
virtual int StartSSLWithServer(const char* server_name);
virtual int StartSSLWithPeer();
- virtual void SetPeerCertificate(SSLCertificate* cert);
virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
const unsigned char* digest_val,
size_t digest_len);
@@ -88,8 +87,8 @@ class SSLStreamAdapterHelper : public SSLStreamAdapter {
// Must be implemented by descendents
virtual int BeginSSL() = 0;
virtual void Cleanup() = 0;
- virtual bool GetDigestLength(const std::string &algorithm,
- std::size_t *length) = 0;
+ virtual bool GetDigestLength(const std::string& algorithm,
+ size_t* length) = 0;
enum SSLState {
// Before calling one of the StartSSL methods, data flows
@@ -114,12 +113,10 @@ class SSLStreamAdapterHelper : public SSLStreamAdapter {
// in traditional mode, the server name that the server's certificate
// must specify. Empty in peer-to-peer mode.
std::string ssl_server_name_;
- // In peer-to-peer mode, the certificate that the peer must
- // present. Empty in traditional mode.
+ // The peer's certificate. Only used for GetPeerCertificate.
scoped_ptr<SSLCertificate> peer_certificate_;
- // In peer-to-peer mode, the digest of the certificate that
- // the peer must present.
+ // The digest of the certificate that the peer must present.
Buffer peer_certificate_digest_value_;
std::string peer_certificate_digest_algorithm_;
diff --git a/chromium/third_party/libjingle/source/talk/base/stream.cc b/chromium/third_party/libjingle/source/talk/base/stream.cc
index c1cf90743a0..02ae4094fa5 100644
--- a/chromium/third_party/libjingle/source/talk/base/stream.cc
+++ b/chromium/third_party/libjingle/source/talk/base/stream.cc
@@ -495,7 +495,7 @@ bool FileStream::Flush() {
return false;
}
-#if defined(POSIX)
+#if defined(POSIX) && !defined(__native_client__)
bool FileStream::TryLock() {
if (file_ == NULL) {
@@ -711,7 +711,7 @@ void AsyncWriteStream::ClearBufferAndWrite() {
}
}
-#ifdef POSIX
+#if defined(POSIX) && !defined(__native_client__)
// Have to identically rewrite the FileStream destructor or else it would call
// the base class's Close() instead of the sub-class's.
diff --git a/chromium/third_party/libjingle/source/talk/base/stream.h b/chromium/third_party/libjingle/source/talk/base/stream.h
index 4571def9bb9..fceb4a80f0d 100644
--- a/chromium/third_party/libjingle/source/talk/base/stream.h
+++ b/chromium/third_party/libjingle/source/talk/base/stream.h
@@ -28,6 +28,8 @@
#ifndef TALK_BASE_STREAM_H_
#define TALK_BASE_STREAM_H_
+#include <stdio.h>
+
#include "talk/base/basictypes.h"
#include "talk/base/buffer.h"
#include "talk/base/criticalsection.h"
@@ -449,7 +451,7 @@ class FileStream : public StreamInterface {
virtual bool Flush();
-#if defined(POSIX)
+#if defined(POSIX) && !defined(__native_client__)
// Tries to aquire an exclusive lock on the file.
// Use OpenShare(...) on win32 to get similar functionality.
bool TryLock();
@@ -497,7 +499,6 @@ class CircularFileStream : public FileStream {
size_t read_segment_available_;
};
-
// A stream which pushes writes onto a separate thread and
// returns from the write call immediately.
class AsyncWriteStream : public StreamInterface {
@@ -539,7 +540,7 @@ class AsyncWriteStream : public StreamInterface {
};
-#ifdef POSIX
+#if defined(POSIX) && !defined(__native_client__)
// A FileStream that is actually not a file, but the output or input of a
// sub-command. See "man 3 popen" for documentation of the underlying OS popen()
// function.
diff --git a/chromium/third_party/libjingle/source/talk/base/stringencode.cc b/chromium/third_party/libjingle/source/talk/base/stringencode.cc
index 194848e1ec6..4c88a9772f1 100644
--- a/chromium/third_party/libjingle/source/talk/base/stringencode.cc
+++ b/chromium/third_party/libjingle/source/talk/base/stringencode.cc
@@ -27,8 +27,8 @@
#include "talk/base/stringencode.h"
-#include <cstdio>
-#include <cstdlib>
+#include <stdio.h>
+#include <stdlib.h>
#include "talk/base/basictypes.h"
#include "talk/base/common.h"
diff --git a/chromium/third_party/libjingle/source/talk/base/stringutils.h b/chromium/third_party/libjingle/source/talk/base/stringutils.h
index 9f9e1a65a55..2c12118b96f 100644
--- a/chromium/third_party/libjingle/source/talk/base/stringutils.h
+++ b/chromium/third_party/libjingle/source/talk/base/stringutils.h
@@ -31,6 +31,7 @@
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
+#include <string.h>
#ifdef WIN32
#include <malloc.h>
@@ -46,7 +47,6 @@
#endif // !BSD
#endif // POSIX
-#include <cstring>
#include <string>
#include "talk/base/basictypes.h"
diff --git a/chromium/third_party/libjingle/source/talk/base/template_util.h b/chromium/third_party/libjingle/source/talk/base/template_util.h
index 5cc4ba430a2..00f1d7d4a11 100644
--- a/chromium/third_party/libjingle/source/talk/base/template_util.h
+++ b/chromium/third_party/libjingle/source/talk/base/template_util.h
@@ -5,7 +5,7 @@
#ifndef TALK_BASE_TEMPLATE_UTIL_H_
#define TALK_BASE_TEMPLATE_UTIL_H_
-#include <cstddef> // For size_t.
+#include <stddef.h> // For size_t.
namespace talk_base {
diff --git a/chromium/third_party/libjingle/source/talk/base/testclient.cc b/chromium/third_party/libjingle/source/talk/base/testclient.cc
index 04d60309963..92e1f397424 100644
--- a/chromium/third_party/libjingle/source/talk/base/testclient.cc
+++ b/chromium/third_party/libjingle/source/talk/base/testclient.cc
@@ -25,7 +25,6 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "talk/base/dscp.h"
#include "talk/base/testclient.h"
#include "talk/base/thread.h"
#include "talk/base/timeutils.h"
@@ -59,12 +58,14 @@ bool TestClient::CheckConnState(AsyncPacketSocket::State state) {
}
int TestClient::Send(const char* buf, size_t size) {
- return socket_->Send(buf, size, DSCP_NO_CHANGE);
+ talk_base::PacketOptions options;
+ return socket_->Send(buf, size, options);
}
int TestClient::SendTo(const char* buf, size_t size,
const SocketAddress& dest) {
- return socket_->SendTo(buf, size, dest, DSCP_NO_CHANGE);
+ talk_base::PacketOptions options;
+ return socket_->SendTo(buf, size, dest, options);
}
TestClient::Packet* TestClient::NextPacket() {
@@ -106,7 +107,7 @@ bool TestClient::CheckNextPacket(const char* buf, size_t size,
bool res = false;
Packet* packet = NextPacket();
if (packet) {
- res = (packet->size == size && std::memcmp(packet->buf, buf, size) == 0);
+ res = (packet->size == size && memcmp(packet->buf, buf, size) == 0);
if (addr)
*addr = packet->addr;
delete packet;
diff --git a/chromium/third_party/libjingle/source/talk/base/testechoserver.h b/chromium/third_party/libjingle/source/talk/base/testechoserver.h
index 5c1045423c3..380f9615363 100644
--- a/chromium/third_party/libjingle/source/talk/base/testechoserver.h
+++ b/chromium/third_party/libjingle/source/talk/base/testechoserver.h
@@ -69,7 +69,8 @@ class TestEchoServer : public sigslot::has_slots<> {
void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size,
const SocketAddress& remote_addr,
const PacketTime& packet_time) {
- socket->Send(buf, size, DSCP_NO_CHANGE);
+ talk_base::PacketOptions options;
+ socket->Send(buf, size, options);
}
void OnClose(AsyncPacketSocket* socket, int err) {
ClientList::iterator it =
diff --git a/chromium/third_party/libjingle/source/talk/base/testutils.h b/chromium/third_party/libjingle/source/talk/base/testutils.h
index e8ad7200940..86e946fc0d2 100644
--- a/chromium/third_party/libjingle/source/talk/base/testutils.h
+++ b/chromium/third_party/libjingle/source/talk/base/testutils.h
@@ -32,6 +32,8 @@
#ifdef LINUX
#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+
// X defines a few macros that stomp on types that gunit.h uses.
#undef None
#undef Bool
@@ -43,6 +45,7 @@
#include "talk/base/common.h"
#include "talk/base/gunit.h"
#include "talk/base/nethelpers.h"
+#include "talk/base/pathutils.h"
#include "talk/base/stream.h"
#include "talk/base/stringencode.h"
#include "talk/base/stringutils.h"
@@ -449,6 +452,30 @@ inline bool ReadFile(const char* filename, std::string* contents) {
return success;
}
+// Look in parent dir for parallel directory.
+inline talk_base::Pathname GetSiblingDirectory(
+ const std::string& parallel_dir) {
+ talk_base::Pathname path = talk_base::Filesystem::GetCurrentDirectory();
+ while (!path.empty()) {
+ talk_base::Pathname potential_parallel_dir = path;
+ potential_parallel_dir.AppendFolder(parallel_dir);
+ if (talk_base::Filesystem::IsFolder(potential_parallel_dir)) {
+ return potential_parallel_dir;
+ }
+
+ path.SetFolder(path.parent_folder());
+ }
+ return path;
+}
+
+inline talk_base::Pathname GetGoogle3Directory() {
+ return GetSiblingDirectory("google3");
+}
+
+inline talk_base::Pathname GetTalkDirectory() {
+ return GetSiblingDirectory("talk");
+}
+
///////////////////////////////////////////////////////////////////////////////
// Unittest predicates which are similar to STREQ, but for raw memory
///////////////////////////////////////////////////////////////////////////////
@@ -601,6 +628,16 @@ inline bool IsScreencastingAvailable() {
LOG(LS_WARNING) << "No X Display available.";
return false;
}
+ int ignored_int, major_version, minor_version;
+ if (!XRRQueryExtension(display, &ignored_int, &ignored_int) ||
+ !XRRQueryVersion(display, &major_version, &minor_version) ||
+ major_version < 1 ||
+ (major_version < 2 && minor_version < 3)) {
+ LOG(LS_WARNING) << "XRandr version: " << major_version << "."
+ << minor_version;
+ LOG(LS_WARNING) << "XRandr is not supported or is too old (pre 1.3).";
+ return false;
+ }
#endif
return true;
}
diff --git a/chromium/third_party/libjingle/source/talk/base/thread.cc b/chromium/third_party/libjingle/source/talk/base/thread.cc
index d07efb51568..87e4ffff614 100644
--- a/chromium/third_party/libjingle/source/talk/base/thread.cc
+++ b/chromium/third_party/libjingle/source/talk/base/thread.cc
@@ -145,20 +145,18 @@ struct ThreadInit {
Thread::Thread(SocketServer* ss)
: MessageQueue(ss),
priority_(PRIORITY_NORMAL),
- started_(false),
+ running_(true, false),
#if defined(WIN32)
thread_(NULL),
thread_id_(0),
#endif
- owned_(true),
- delete_self_when_complete_(false) {
+ owned_(true) {
SetName("Thread", this); // default name
}
Thread::~Thread() {
Stop();
- if (active_)
- Clear(NULL);
+ Clear(NULL);
}
bool Thread::SleepMs(int milliseconds) {
@@ -181,7 +179,7 @@ bool Thread::SleepMs(int milliseconds) {
}
bool Thread::SetName(const std::string& name, const void* obj) {
- if (started_) return false;
+ if (running()) return false;
name_ = name;
if (obj) {
char buf[16];
@@ -193,7 +191,7 @@ bool Thread::SetName(const std::string& name, const void* obj) {
bool Thread::SetPriority(ThreadPriority priority) {
#if defined(WIN32)
- if (started_) {
+ if (running()) {
BOOL ret = FALSE;
if (priority == PRIORITY_NORMAL) {
ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_NORMAL);
@@ -212,7 +210,7 @@ bool Thread::SetPriority(ThreadPriority priority) {
return true;
#else
// TODO: Implement for Linux/Mac if possible.
- if (started_) return false;
+ if (running()) return false;
priority_ = priority;
return true;
#endif
@@ -221,8 +219,8 @@ bool Thread::SetPriority(ThreadPriority priority) {
bool Thread::Start(Runnable* runnable) {
ASSERT(owned_);
if (!owned_) return false;
- ASSERT(!started_);
- if (started_) return false;
+ ASSERT(!running());
+ if (running()) return false;
Restart(); // reset fStop_ if the thread is being restarted
@@ -241,7 +239,7 @@ bool Thread::Start(Runnable* runnable) {
thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreRun, init, flags,
&thread_id_);
if (thread_) {
- started_ = true;
+ running_.Set();
if (priority_ != PRIORITY_NORMAL) {
SetPriority(priority_);
::ResumeThread(thread_);
@@ -252,6 +250,9 @@ bool Thread::Start(Runnable* runnable) {
#elif defined(POSIX)
pthread_attr_t attr;
pthread_attr_init(&attr);
+
+ // Thread priorities are not supported in NaCl.
+#if !defined(__native_client__)
if (priority_ != PRIORITY_NORMAL) {
if (priority_ == PRIORITY_IDLE) {
// There is no POSIX-standard way to set a below-normal priority for an
@@ -279,18 +280,20 @@ bool Thread::Start(Runnable* runnable) {
}
}
}
+#endif // !defined(__native_client__)
+
int error_code = pthread_create(&thread_, &attr, PreRun, init);
if (0 != error_code) {
LOG(LS_ERROR) << "Unable to create pthread, error " << error_code;
return false;
}
- started_ = true;
+ running_.Set();
#endif
return true;
}
void Thread::Join() {
- if (started_) {
+ if (running()) {
ASSERT(!IsCurrent());
#if defined(WIN32)
WaitForSingleObject(thread_, INFINITE);
@@ -301,7 +304,7 @@ void Thread::Join() {
void *pv;
pthread_join(thread_, &pv);
#endif
- started_ = false;
+ running_.Reset();
}
}
@@ -352,10 +355,6 @@ void* Thread::PreRun(void* pv) {
} else {
init->thread->Run();
}
- if (init->thread->delete_self_when_complete_) {
- init->thread->started_ = false;
- delete init->thread;
- }
delete init;
return NULL;
}
@@ -398,7 +397,6 @@ void Thread::Send(MessageHandler *phandler, uint32 id, MessageData *pdata) {
bool ready = false;
{
CritScope cs(&crit_);
- EnsureActive();
_SendMessage smsg;
smsg.thread = current_thread;
smsg.msg = msg;
@@ -518,7 +516,7 @@ bool Thread::WrapCurrent() {
}
bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager) {
- if (started_)
+ if (running())
return false;
#if defined(WIN32)
// We explicitly ask for no rights other than synchronization.
@@ -533,7 +531,7 @@ bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager) {
thread_ = pthread_self();
#endif
owned_ = false;
- started_ = true;
+ running_.Set();
thread_manager->SetCurrentThread(this);
return true;
}
@@ -546,7 +544,7 @@ void Thread::UnwrapCurrent() {
LOG_GLE(LS_ERROR) << "When unwrapping thread, failed to close handle.";
}
#endif
- started_ = false;
+ running_.Reset();
}
diff --git a/chromium/third_party/libjingle/source/talk/base/thread.h b/chromium/third_party/libjingle/source/talk/base/thread.h
index 4dc09f641d7..4cbf721fa63 100644
--- a/chromium/third_party/libjingle/source/talk/base/thread.h
+++ b/chromium/third_party/libjingle/source/talk/base/thread.h
@@ -37,6 +37,7 @@
#include <pthread.h>
#endif
#include "talk/base/constructormagic.h"
+#include "talk/base/event.h"
#include "talk/base/messagequeue.h"
#ifdef WIN32
@@ -143,15 +144,8 @@ class Thread : public MessageQueue {
bool SetPriority(ThreadPriority priority);
// Starts the execution of the thread.
- bool started() const { return started_; }
bool Start(Runnable* runnable = NULL);
- // Used for fire-and-forget threads. Deletes this thread object when the
- // Run method returns.
- void Release() {
- delete_self_when_complete_ = true;
- }
-
// Tells the thread to stop and waits until it is joined.
// Never call Stop on the current thread. Instead use the inherited Quit
// function which will exit the base MessageQueue without terminating the
@@ -218,38 +212,24 @@ class Thread : public MessageQueue {
bool WrapCurrent();
void UnwrapCurrent();
+ // Expose private method running() for tests.
+ //
+ // DANGER: this is a terrible public API. Most callers that might want to
+ // call this likely do not have enough control/knowledge of the Thread in
+ // question to guarantee that the returned value remains true for the duration
+ // of whatever code is conditionally executing because of the return value!
+ bool RunningForTest() { return running(); }
+ // This is a legacy call-site that probably doesn't need to exist in the first
+ // place.
+ // TODO(fischman): delete once the ASSERT added in channelmanager.cc sticks
+ // for a month (ETA 2014/06/22).
+ bool RunningForChannelManager() { return running(); }
+
protected:
// Blocks the calling thread until this thread has terminated.
void Join();
private:
- // Helper class to facilitate executing a functor on a thread.
- template <class ReturnT, class FunctorT>
- class FunctorMessageHandler : public MessageHandler {
- public:
- explicit FunctorMessageHandler(const FunctorT& functor)
- : functor_(functor) {}
- virtual void OnMessage(Message* msg) {
- result_ = functor_();
- }
- const ReturnT& result() const { return result_; }
- private:
- FunctorT functor_;
- ReturnT result_;
- };
-
- // Specialization for ReturnT of void.
- template <class FunctorT>
- class FunctorMessageHandler<void, FunctorT> : public MessageHandler {
- public:
- explicit FunctorMessageHandler(const FunctorT& functor)
- : functor_(functor) {}
- virtual void OnMessage(Message* msg) { functor_(); }
- void result() const {}
- private:
- FunctorT functor_;
- };
-
static void *PreRun(void *pv);
// ThreadManager calls this instead WrapCurrent() because
@@ -257,10 +237,13 @@ class Thread : public MessageQueue {
// being created.
bool WrapCurrentWithThreadManager(ThreadManager* thread_manager);
+ // Return true if the thread was started and hasn't yet stopped.
+ bool running() { return running_.Wait(0); }
+
std::list<_SendMessage> sendlist_;
std::string name_;
ThreadPriority priority_;
- bool started_;
+ Event running_; // Signalled means running.
#ifdef POSIX
pthread_t thread_;
@@ -272,7 +255,6 @@ class Thread : public MessageQueue {
#endif
bool owned_;
- bool delete_self_when_complete_;
friend class ThreadManager;
diff --git a/chromium/third_party/libjingle/source/talk/base/thread_unittest.cc b/chromium/third_party/libjingle/source/talk/base/thread_unittest.cc
index 896fbabc5fd..d7d6a0129e4 100644
--- a/chromium/third_party/libjingle/source/talk/base/thread_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/thread_unittest.cc
@@ -25,6 +25,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "talk/base/asyncinvoker.h"
#include "talk/base/asyncudpsocket.h"
#include "talk/base/event.h"
#include "talk/base/gunit.h"
@@ -38,8 +39,6 @@
using namespace talk_base;
-const int MAX = 65536;
-
// Generates a sequence of numbers (collaboratively).
class TestGenerator {
public:
@@ -87,7 +86,6 @@ class SocketClient : public TestGenerator, public sigslot::has_slots<> {
uint32 prev = reinterpret_cast<const uint32*>(buf)[0];
uint32 result = Next(prev);
- //socket_->set_readable(last < MAX);
post_thread_->PostDelayed(200, post_handler_, 0, new TestMessage(result));
}
@@ -101,7 +99,7 @@ class SocketClient : public TestGenerator, public sigslot::has_slots<> {
class MessageClient : public MessageHandler, public TestGenerator {
public:
MessageClient(Thread* pth, Socket* socket)
- : thread_(pth), socket_(socket) {
+ : socket_(socket) {
}
virtual ~MessageClient() {
@@ -116,7 +114,6 @@ class MessageClient : public MessageHandler, public TestGenerator {
}
private:
- Thread* thread_;
Socket* socket_;
};
@@ -150,16 +147,22 @@ class SignalWhenDestroyedThread : public Thread {
};
// Function objects to test Thread::Invoke.
-struct Functor1 {
+struct FunctorA {
int operator()() { return 42; }
};
-class Functor2 {
+class FunctorB {
public:
- explicit Functor2(bool* flag) : flag_(flag) {}
+ explicit FunctorB(bool* flag) : flag_(flag) {}
void operator()() { if (flag_) *flag_ = true; }
private:
bool* flag_;
};
+struct FunctorC {
+ int operator()() {
+ Thread::Current()->ProcessMessages(50);
+ return 24;
+ }
+};
// See: https://code.google.com/p/webrtc/issues/detail?id=2409
TEST(ThreadTest, DISABLED_Main) {
@@ -258,40 +261,22 @@ TEST(ThreadTest, Wrap) {
current_thread->UnwrapCurrent();
CustomThread* cthread = new CustomThread();
EXPECT_TRUE(cthread->WrapCurrent());
- EXPECT_TRUE(cthread->started());
+ EXPECT_TRUE(cthread->RunningForTest());
EXPECT_FALSE(cthread->IsOwned());
cthread->UnwrapCurrent();
- EXPECT_FALSE(cthread->started());
+ EXPECT_FALSE(cthread->RunningForTest());
delete cthread;
current_thread->WrapCurrent();
}
-// Test that calling Release on a thread causes it to self-destruct when
-// it's finished running
-TEST(ThreadTest, Release) {
- scoped_ptr<Event> event(new Event(true, false));
- // Ensure the event is initialized.
- event->Reset();
-
- Thread* thread = new SignalWhenDestroyedThread(event.get());
- thread->Start();
- thread->Release();
-
- // The event should get signaled when the thread completes, which should
- // be nearly instantaneous, since it doesn't do anything. For safety,
- // give it 3 seconds in case the machine is under load.
- bool signaled = event->Wait(3000);
- EXPECT_TRUE(signaled);
-}
-
TEST(ThreadTest, Invoke) {
// Create and start the thread.
Thread thread;
thread.Start();
// Try calling functors.
- EXPECT_EQ(42, thread.Invoke<int>(Functor1()));
+ EXPECT_EQ(42, thread.Invoke<int>(FunctorA()));
bool called = false;
- Functor2 f2(&called);
+ FunctorB f2(&called);
thread.Invoke<void>(f2);
EXPECT_TRUE(called);
// Try calling bare functions.
@@ -303,6 +288,152 @@ TEST(ThreadTest, Invoke) {
thread.Invoke<void>(&LocalFuncs::Func2);
}
+class AsyncInvokeTest : public testing::Test {
+ public:
+ void IntCallback(int value) {
+ EXPECT_EQ(expected_thread_, Thread::Current());
+ int_value_ = value;
+ }
+ void AsyncInvokeIntCallback(AsyncInvoker* invoker, Thread* thread) {
+ expected_thread_ = thread;
+ invoker->AsyncInvoke(thread, FunctorC(),
+ &AsyncInvokeTest::IntCallback,
+ static_cast<AsyncInvokeTest*>(this));
+ invoke_started_.Set();
+ }
+ void SetExpectedThreadForIntCallback(Thread* thread) {
+ expected_thread_ = thread;
+ }
+
+ protected:
+ enum { kWaitTimeout = 1000 };
+ AsyncInvokeTest()
+ : int_value_(0),
+ invoke_started_(true, false),
+ expected_thread_(NULL) {}
+
+ int int_value_;
+ Event invoke_started_;
+ Thread* expected_thread_;
+};
+
+TEST_F(AsyncInvokeTest, FireAndForget) {
+ AsyncInvoker invoker;
+ // Create and start the thread.
+ Thread thread;
+ thread.Start();
+ // Try calling functor.
+ bool called = false;
+ invoker.AsyncInvoke<void>(&thread, FunctorB(&called));
+ EXPECT_TRUE_WAIT(called, kWaitTimeout);
+}
+
+TEST_F(AsyncInvokeTest, WithCallback) {
+ AsyncInvoker invoker;
+ // Create and start the thread.
+ Thread thread;
+ thread.Start();
+ // Try calling functor.
+ SetExpectedThreadForIntCallback(Thread::Current());
+ invoker.AsyncInvoke(&thread, FunctorA(),
+ &AsyncInvokeTest::IntCallback,
+ static_cast<AsyncInvokeTest*>(this));
+ EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout);
+}
+
+TEST_F(AsyncInvokeTest, CancelInvoker) {
+ // Create and start the thread.
+ Thread thread;
+ thread.Start();
+ // Try destroying invoker during call.
+ {
+ AsyncInvoker invoker;
+ invoker.AsyncInvoke(&thread, FunctorC(),
+ &AsyncInvokeTest::IntCallback,
+ static_cast<AsyncInvokeTest*>(this));
+ }
+ // With invoker gone, callback should be cancelled.
+ Thread::Current()->ProcessMessages(kWaitTimeout);
+ EXPECT_EQ(0, int_value_);
+}
+
+TEST_F(AsyncInvokeTest, CancelCallingThread) {
+ AsyncInvoker invoker;
+ { // Create and start the thread.
+ Thread thread;
+ thread.Start();
+ // Try calling functor.
+ thread.Invoke<void>(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback,
+ static_cast<AsyncInvokeTest*>(this),
+ &invoker, Thread::Current()));
+ // Wait for the call to begin.
+ ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout));
+ }
+ // Calling thread is gone. Return message shouldn't happen.
+ Thread::Current()->ProcessMessages(kWaitTimeout);
+ EXPECT_EQ(0, int_value_);
+}
+
+TEST_F(AsyncInvokeTest, KillInvokerBeforeExecute) {
+ Thread thread;
+ thread.Start();
+ {
+ AsyncInvoker invoker;
+ // Try calling functor.
+ thread.Invoke<void>(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback,
+ static_cast<AsyncInvokeTest*>(this),
+ &invoker, Thread::Current()));
+ // Wait for the call to begin.
+ ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout));
+ }
+ // Invoker is destroyed. Function should not execute.
+ Thread::Current()->ProcessMessages(kWaitTimeout);
+ EXPECT_EQ(0, int_value_);
+}
+
+TEST_F(AsyncInvokeTest, Flush) {
+ AsyncInvoker invoker;
+ bool flag1 = false;
+ bool flag2 = false;
+ // Queue two async calls to the current thread.
+ invoker.AsyncInvoke<void>(Thread::Current(),
+ FunctorB(&flag1));
+ invoker.AsyncInvoke<void>(Thread::Current(),
+ FunctorB(&flag2));
+ // Because we haven't pumped messages, these should not have run yet.
+ EXPECT_FALSE(flag1);
+ EXPECT_FALSE(flag2);
+ // Force them to run now.
+ invoker.Flush(Thread::Current());
+ EXPECT_TRUE(flag1);
+ EXPECT_TRUE(flag2);
+}
+
+TEST_F(AsyncInvokeTest, FlushWithIds) {
+ AsyncInvoker invoker;
+ bool flag1 = false;
+ bool flag2 = false;
+ // Queue two async calls to the current thread, one with a message id.
+ invoker.AsyncInvoke<void>(Thread::Current(),
+ FunctorB(&flag1),
+ 5);
+ invoker.AsyncInvoke<void>(Thread::Current(),
+ FunctorB(&flag2));
+ // Because we haven't pumped messages, these should not have run yet.
+ EXPECT_FALSE(flag1);
+ EXPECT_FALSE(flag2);
+ // Execute pending calls with id == 5.
+ invoker.Flush(Thread::Current(), 5);
+ EXPECT_TRUE(flag1);
+ EXPECT_FALSE(flag2);
+ flag1 = false;
+ // Execute all pending calls. The id == 5 call should not execute again.
+ invoker.Flush(Thread::Current());
+ EXPECT_FALSE(flag1);
+ EXPECT_TRUE(flag2);
+}
+
+
#ifdef WIN32
class ComThreadTest : public testing::Test, public MessageHandler {
public:
diff --git a/chromium/third_party/libjingle/source/talk/base/timeutils.cc b/chromium/third_party/libjingle/source/talk/base/timeutils.cc
index 54db3418bbb..c4e84cc20db 100644
--- a/chromium/third_party/libjingle/source/talk/base/timeutils.cc
+++ b/chromium/third_party/libjingle/source/talk/base/timeutils.cc
@@ -25,6 +25,8 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stdint.h>
+
#ifdef POSIX
#include <sys/time.h>
#if defined(OSX) || defined(IOS)
@@ -45,7 +47,6 @@
namespace talk_base {
-const uint32 LAST = 0xFFFFFFFF;
const uint32 HALF = 0x80000000;
uint64 TimeNanos() {
@@ -190,16 +191,30 @@ int32 TimeDiff(uint32 later, uint32 earlier) {
if (earlier <= later) {
return static_cast<long>(later - earlier);
} else {
- return static_cast<long>(later + (LAST - earlier) + 1);
+ return static_cast<long>(later + (UINT32_MAX - earlier) + 1);
}
} else {
if (later <= earlier) {
return -static_cast<long>(earlier - later);
} else {
- return -static_cast<long>(earlier + (LAST - later) + 1);
+ return -static_cast<long>(earlier + (UINT32_MAX - later) + 1);
}
}
#endif
}
+TimestampWrapAroundHandler::TimestampWrapAroundHandler()
+ : last_ts_(0), num_wrap_(0) {}
+
+int64 TimestampWrapAroundHandler::Unwrap(uint32 ts) {
+ if (ts < last_ts_) {
+ if (last_ts_ > 0xf0000000 && ts < 0x0fffffff) {
+ ++num_wrap_;
+ }
+ }
+ last_ts_ = ts;
+ int64_t unwrapped_ts = ts + (num_wrap_ << 32);
+ return unwrapped_ts;
+}
+
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/timeutils.h b/chromium/third_party/libjingle/source/talk/base/timeutils.h
index f13c3f2ef2d..6de9df67142 100644
--- a/chromium/third_party/libjingle/source/talk/base/timeutils.h
+++ b/chromium/third_party/libjingle/source/talk/base/timeutils.h
@@ -97,6 +97,17 @@ inline int64 UnixTimestampNanosecsToNtpMillisecs(int64 unix_ts_ns) {
return unix_ts_ns / kNumNanosecsPerMillisec + kJan1970AsNtpMillisecs;
}
+class TimestampWrapAroundHandler {
+ public:
+ TimestampWrapAroundHandler();
+
+ int64 Unwrap(uint32 ts);
+
+ private:
+ uint32 last_ts_;
+ int64 num_wrap_;
+};
+
} // namespace talk_base
#endif // TALK_BASE_TIMEUTILS_H_
diff --git a/chromium/third_party/libjingle/source/talk/base/timeutils_unittest.cc b/chromium/third_party/libjingle/source/talk/base/timeutils_unittest.cc
index 0fc5eb19c8a..a078abee2c1 100644
--- a/chromium/third_party/libjingle/source/talk/base/timeutils_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/timeutils_unittest.cc
@@ -160,4 +160,27 @@ TEST(TimeTest, DISABLED_CurrentTmTime) {
EXPECT_TRUE(0 <= microseconds && microseconds < 1000000);
}
+class TimestampWrapAroundHandlerTest : public testing::Test {
+ public:
+ TimestampWrapAroundHandlerTest() {}
+
+ protected:
+ TimestampWrapAroundHandler wraparound_handler_;
+};
+
+TEST_F(TimestampWrapAroundHandlerTest, Unwrap) {
+ uint32 ts = 0xfffffff2;
+ int64 unwrapped_ts = ts;
+ EXPECT_EQ(ts, wraparound_handler_.Unwrap(ts));
+ ts = 2;
+ unwrapped_ts += 0x10;
+ EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts));
+ ts = 0xfffffff2;
+ unwrapped_ts += 0xfffffff0;
+ EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts));
+ ts = 0;
+ unwrapped_ts += 0xe;
+ EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts));
+}
+
} // namespace talk_base
diff --git a/chromium/third_party/libjingle/source/talk/base/transformadapter.cc b/chromium/third_party/libjingle/source/talk/base/transformadapter.cc
index 53a55a85b4d..2a240eb9f73 100644
--- a/chromium/third_party/libjingle/source/talk/base/transformadapter.cc
+++ b/chromium/third_party/libjingle/source/talk/base/transformadapter.cc
@@ -27,7 +27,7 @@
#include "talk/base/transformadapter.h"
-#include <cstring>
+#include <string.h>
#include "talk/base/common.h"
diff --git a/chromium/third_party/libjingle/source/talk/base/unittest_main.cc b/chromium/third_party/libjingle/source/talk/base/unittest_main.cc
index bca3671b0c4..def763c30d8 100644
--- a/chromium/third_party/libjingle/source/talk/base/unittest_main.cc
+++ b/chromium/third_party/libjingle/source/talk/base/unittest_main.cc
@@ -12,7 +12,6 @@
#include "talk/base/fileutils.h"
#include "talk/base/gunit.h"
#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
DEFINE_bool(help, false, "prints this message");
DEFINE_string(log, "", "logging options to use");
@@ -47,28 +46,6 @@ int TestCrtReportHandler(int report_type, char* msg, int* retval) {
}
#endif // WIN32
-talk_base::Pathname GetTalkDirectory() {
- // Locate talk directory.
- talk_base::Pathname path = talk_base::Filesystem::GetCurrentDirectory();
- std::string talk_folder_name("talk");
- talk_folder_name += path.folder_delimiter();
- while (path.folder_name() != talk_folder_name && !path.empty()) {
- path.SetFolder(path.parent_folder());
- }
-
- // If not running inside "talk" folder, then assume running in its parent
- // folder.
- if (path.empty()) {
- path = talk_base::Filesystem::GetCurrentDirectory();
- path.AppendFolder("talk");
- // Make sure the folder exist.
- if (!talk_base::Filesystem::IsFolder(path)) {
- path.clear();
- }
- }
- return path;
-}
-
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
FlagList::SetFlagsFromCommandLine(&argc, argv, false);
diff --git a/chromium/third_party/libjingle/source/talk/base/unixfilesystem.cc b/chromium/third_party/libjingle/source/talk/base/unixfilesystem.cc
index 74168f267bd..8ac74994586 100644
--- a/chromium/third_party/libjingle/source/talk/base/unixfilesystem.cc
+++ b/chromium/third_party/libjingle/source/talk/base/unixfilesystem.cc
@@ -42,26 +42,39 @@
#if defined(POSIX) && !defined(OSX)
#include <sys/types.h>
-#ifdef ANDROID
+#if defined(ANDROID)
#include <sys/statfs.h>
-#else
+#elif !defined(__native_client__)
#include <sys/statvfs.h>
-#endif // ANDROID
+#endif // !defined(__native_client__)
+#include <limits.h>
#include <pwd.h>
#include <stdio.h>
-#include <unistd.h>
#endif // POSIX && !OSX
-#ifdef LINUX
+#if defined(LINUX)
#include <ctype.h>
#include <algorithm>
#endif
+#if defined(__native_client__) && !defined(__GLIBC__)
+#include <sys/syslimits.h>
+#endif
+
#include "talk/base/fileutils.h"
#include "talk/base/pathutils.h"
#include "talk/base/stream.h"
#include "talk/base/stringutils.h"
+#if defined(IOS)
+// Defined in iosfilesystem.mm. No header file to discourage use
+// elsewhere; other places should use GetApp{Data,Temp}Folder() in
+// this file. Don't copy/paste. I mean it.
+char* IOSDataDirectory();
+char* IOSTempDirectory();
+void IOSAppName(talk_base::Pathname* path);
+#endif
+
namespace talk_base {
#if !defined(ANDROID) && !defined(IOS)
@@ -81,6 +94,17 @@ void UnixFilesystem::SetAppTempFolder(const std::string& folder) {
}
#endif
+UnixFilesystem::UnixFilesystem() {
+#if defined(IOS)
+ if (!provided_app_data_folder_)
+ provided_app_data_folder_ = IOSDataDirectory();
+ if (!provided_app_temp_folder_)
+ provided_app_temp_folder_ = IOSTempDirectory();
+#endif
+}
+
+UnixFilesystem::~UnixFilesystem() {}
+
bool UnixFilesystem::CreateFolder(const Pathname &path, mode_t mode) {
std::string pathname(path.pathname());
int len = pathname.length();
@@ -363,10 +387,15 @@ bool UnixFilesystem::GetAppPathname(Pathname* path) {
if (success)
path->SetPathname(path8);
return success;
+#elif defined(__native_client__)
+ return false;
+#elif IOS
+ IOSAppName(path);
+ return true;
#else // OSX
- char buffer[NAME_MAX+1];
- size_t len = readlink("/proc/self/exe", buffer, ARRAY_SIZE(buffer) - 1);
- if (len <= 0)
+ char buffer[PATH_MAX + 2];
+ ssize_t len = readlink("/proc/self/exe", buffer, ARRAY_SIZE(buffer) - 1);
+ if ((len <= 0) || (len == PATH_MAX + 1))
return false;
buffer[len] = '\0';
path->SetPathname(buffer);
@@ -448,6 +477,7 @@ bool UnixFilesystem::GetAppDataFolder(Pathname* path, bool per_user) {
if (!CreateFolder(*path, 0700)) {
return false;
}
+#if !defined(__native_client__)
// If the folder already exists, it may have the wrong mode or be owned by
// someone else, both of which are security problems. Setting the mode
// avoids both issues since it will fail if the path is not owned by us.
@@ -455,6 +485,7 @@ bool UnixFilesystem::GetAppDataFolder(Pathname* path, bool per_user) {
LOG_ERR(LS_ERROR) << "Can't set mode on " << path;
return false;
}
+#endif
return true;
}
@@ -489,6 +520,9 @@ bool UnixFilesystem::GetAppTempFolder(Pathname* path) {
}
bool UnixFilesystem::GetDiskFreeSpace(const Pathname& path, int64 *freebytes) {
+#ifdef __native_client__
+ return false;
+#else // __native_client__
ASSERT(NULL != freebytes);
// TODO: Consider making relative paths absolute using cwd.
// TODO: When popping off a symlink, push back on the components of the
@@ -510,11 +544,12 @@ bool UnixFilesystem::GetDiskFreeSpace(const Pathname& path, int64 *freebytes) {
#endif // ANDROID
#if defined(LINUX) || defined(ANDROID)
*freebytes = static_cast<int64>(vfs.f_bsize) * vfs.f_bavail;
-#elif defined(OSX)
+#elif defined(OSX) || defined(IOS)
*freebytes = static_cast<int64>(vfs.f_frsize) * vfs.f_bavail;
#endif
return true;
+#endif // !__native_client__
}
Pathname UnixFilesystem::GetCurrentDirectory() {
@@ -544,3 +579,11 @@ char* UnixFilesystem::CopyString(const std::string& str) {
}
} // namespace talk_base
+
+#if defined(__native_client__)
+extern "C" int __attribute__((weak))
+link(const char* oldpath, const char* newpath) {
+ errno = EACCES;
+ return -1;
+}
+#endif
diff --git a/chromium/third_party/libjingle/source/talk/base/unixfilesystem.h b/chromium/third_party/libjingle/source/talk/base/unixfilesystem.h
index aa9c920e625..d709115fe9f 100644
--- a/chromium/third_party/libjingle/source/talk/base/unixfilesystem.h
+++ b/chromium/third_party/libjingle/source/talk/base/unixfilesystem.h
@@ -36,13 +36,17 @@ namespace talk_base {
class UnixFilesystem : public FilesystemInterface {
public:
+ UnixFilesystem();
+ virtual ~UnixFilesystem();
#if defined(ANDROID) || defined(IOS)
-// Android does not have a native code API to fetch the app data or temp
-// folders. That needs to be passed into this class from Java. Similarly, iOS
-// only supports an Objective-C API for fetching the folder locations, so that
-// needs to be passed in here from Objective-C.
-
+ // Android does not have a native code API to fetch the app data or temp
+ // folders. That needs to be passed into this class from Java. Similarly, iOS
+ // only supports an Objective-C API for fetching the folder locations, so that
+ // needs to be passed in here from Objective-C. Or at least that used to be
+ // the case; now the ctor will do the work if necessary and possible.
+ // TODO(fischman): add an Android version that uses JNI and drop the
+ // SetApp*Folder() APIs once external users stop using them.
static void SetAppDataFolder(const std::string& folder);
static void SetAppTempFolder(const std::string& folder);
#endif
diff --git a/chromium/third_party/libjingle/source/talk/base/versionparsing.cc b/chromium/third_party/libjingle/source/talk/base/versionparsing.cc
index 03f3dec1ee9..6a57dc9fe0c 100644
--- a/chromium/third_party/libjingle/source/talk/base/versionparsing.cc
+++ b/chromium/third_party/libjingle/source/talk/base/versionparsing.cc
@@ -27,7 +27,7 @@
#include "talk/base/versionparsing.h"
-#include <cstdlib>
+#include <stdlib.h>
namespace talk_base {
diff --git a/chromium/third_party/libjingle/source/talk/base/virtualsocket_unittest.cc b/chromium/third_party/libjingle/source/talk/base/virtualsocket_unittest.cc
index b31b8c8b074..58dab143a27 100644
--- a/chromium/third_party/libjingle/source/talk/base/virtualsocket_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/virtualsocket_unittest.cc
@@ -25,11 +25,11 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <math.h>
#include <time.h>
#ifdef POSIX
#include <netinet/in.h>
#endif
-#include <cmath>
#include "talk/base/logging.h"
#include "talk/base/gunit.h"
@@ -69,7 +69,7 @@ struct Sender : public MessageHandler {
count += size;
memcpy(dummy, &cur_time, sizeof(cur_time));
- socket->Send(dummy, size, DSCP_NO_CHANGE);
+ socket->Send(dummy, size, options);
last_send = cur_time;
thread->PostDelayed(NextDelay(), this, 1);
@@ -77,6 +77,7 @@ struct Sender : public MessageHandler {
Thread* thread;
scoped_ptr<AsyncUDPSocket> socket;
+ talk_base::PacketOptions options;
bool done;
uint32 rate; // bytes per second
uint32 count;
@@ -685,7 +686,7 @@ class VirtualSocketServerTest : public testing::Test {
double num =
receiver.samples * receiver.sum_sq - receiver.sum * receiver.sum;
double den = receiver.samples * (receiver.samples - 1);
- const double sample_stddev = std::sqrt(num / den);
+ const double sample_stddev = sqrt(num / den);
LOG(LS_VERBOSE) << "mean=" << sample_mean << " stddev=" << sample_stddev;
EXPECT_LE(500u, receiver.samples);
@@ -1001,7 +1002,7 @@ TEST_F(VirtualSocketServerTest, CreatesStandardDistribution) {
double dev = (*f)[i].second - mean;
sum_sq_dev += dev * dev;
}
- const double stddev = std::sqrt(sum_sq_dev / f->size());
+ const double stddev = sqrt(sum_sq_dev / f->size());
EXPECT_NEAR(kTestMean[midx], mean, 0.1 * kTestMean[midx])
<< "M=" << kTestMean[midx]
<< " SD=" << kStdDev
diff --git a/chromium/third_party/libjingle/source/talk/base/virtualsocketserver.cc b/chromium/third_party/libjingle/source/talk/base/virtualsocketserver.cc
index 6d95c19d1d1..6589ebb5a20 100644
--- a/chromium/third_party/libjingle/source/talk/base/virtualsocketserver.cc
+++ b/chromium/third_party/libjingle/source/talk/base/virtualsocketserver.cc
@@ -28,9 +28,9 @@
#include "talk/base/virtualsocketserver.h"
#include <errno.h>
+#include <math.h>
#include <algorithm>
-#include <cmath>
#include <map>
#include <vector>
@@ -80,7 +80,7 @@ class Packet : public MessageData {
: size_(size), consumed_(0), from_(from) {
ASSERT(NULL != data);
data_ = new char[size_];
- std::memcpy(data_, data, size_);
+ memcpy(data_, data, size_);
}
virtual ~Packet() {
@@ -283,7 +283,7 @@ class VirtualSocket : public AsyncSocket, public MessageHandler {
// Return the packet at the front of the queue.
Packet* packet = recv_buffer_.front();
size_t data_read = _min(cb, packet->size());
- std::memcpy(pv, packet->data(), data_read);
+ memcpy(pv, packet->data(), data_read);
*paddr = packet->from();
if (data_read < packet->size()) {
@@ -963,11 +963,11 @@ void VirtualSocketServer::UpdateDelayDistribution() {
}
}
-static double PI = 4 * std::atan(1.0);
+static double PI = 4 * atan(1.0);
static double Normal(double x, double mean, double stddev) {
double a = (x - mean) * (x - mean) / (2 * stddev * stddev);
- return std::exp(-a) / (stddev * sqrt(2 * PI));
+ return exp(-a) / (stddev * sqrt(2 * PI));
}
#if 0 // static unused gives a warning
diff --git a/chromium/third_party/libjingle/source/talk/base/virtualsocketserver.h b/chromium/third_party/libjingle/source/talk/base/virtualsocketserver.h
index 280ae657295..56e37a14e3b 100644
--- a/chromium/third_party/libjingle/source/talk/base/virtualsocketserver.h
+++ b/chromium/third_party/libjingle/source/talk/base/virtualsocketserver.h
@@ -28,7 +28,8 @@
#ifndef TALK_BASE_VIRTUALSOCKETSERVER_H_
#define TALK_BASE_VIRTUALSOCKETSERVER_H_
-#include <cassert>
+#include <assert.h>
+
#include <deque>
#include <map>
diff --git a/chromium/third_party/libjingle/source/talk/base/win32regkey.cc b/chromium/third_party/libjingle/source/talk/base/win32regkey.cc
index 403fdc014c0..614f698e7c4 100644
--- a/chromium/third_party/libjingle/source/talk/base/win32regkey.cc
+++ b/chromium/third_party/libjingle/source/talk/base/win32regkey.cc
@@ -984,21 +984,21 @@ std::wstring RegKey::GetParentKeyInfo(std::wstring* key_name) {
uint32 RegKey::GetValueCount() {
DWORD num_values = 0;
- LONG res = ::RegQueryInfoKey(
- h_key_, // key handle
- NULL, // buffer for class name
- NULL, // size of class string
- NULL, // reserved
- NULL, // number of subkeys
- NULL, // longest subkey size
- NULL, // longest class string
- &num_values, // number of values for this key
- NULL, // longest value name
- NULL, // longest value data
- NULL, // security descriptor
- NULL); // last write time
-
- ASSERT(res == ERROR_SUCCESS);
+ if (ERROR_SUCCESS != ::RegQueryInfoKey(
+ h_key_, // key handle
+ NULL, // buffer for class name
+ NULL, // size of class string
+ NULL, // reserved
+ NULL, // number of subkeys
+ NULL, // longest subkey size
+ NULL, // longest class string
+ &num_values, // number of values for this key
+ NULL, // longest value name
+ NULL, // longest value data
+ NULL, // security descriptor
+ NULL)) { // last write time
+ ASSERT(false);
+ }
return num_values;
}
@@ -1028,21 +1028,21 @@ uint32 RegKey::GetSubkeyCount() {
// number of values for key
DWORD num_subkeys = 0;
- LONG res = ::RegQueryInfoKey(
- h_key_, // key handle
- NULL, // buffer for class name
- NULL, // size of class string
- NULL, // reserved
- &num_subkeys, // number of subkeys
- NULL, // longest subkey size
- NULL, // longest class string
- NULL, // number of values for this key
- NULL, // longest value name
- NULL, // longest value data
- NULL, // security descriptor
- NULL); // last write time
-
- ASSERT(res == ERROR_SUCCESS);
+ if (ERROR_SUCCESS != ::RegQueryInfoKey(
+ h_key_, // key handle
+ NULL, // buffer for class name
+ NULL, // size of class string
+ NULL, // reserved
+ &num_subkeys, // number of subkeys
+ NULL, // longest subkey size
+ NULL, // longest class string
+ NULL, // number of values for this key
+ NULL, // longest value name
+ NULL, // longest value data
+ NULL, // security descriptor
+ NULL)) { // last write time
+ ASSERT(false);
+ }
return num_subkeys;
}
diff --git a/chromium/third_party/libjingle/source/talk/base/win32toolhelp_unittest.cc b/chromium/third_party/libjingle/source/talk/base/win32toolhelp_unittest.cc
index 529bef95ab5..e740345978c 100644
--- a/chromium/third_party/libjingle/source/talk/base/win32toolhelp_unittest.cc
+++ b/chromium/third_party/libjingle/source/talk/base/win32toolhelp_unittest.cc
@@ -267,7 +267,6 @@ TEST_F(Win32ToolhelpTest, TestCurrentNextCalled) {
}
TEST_F(Win32ToolhelpTest, TestCurrentProcess) {
- int size = MAX_PATH;
WCHAR buf[MAX_PATH];
GetModuleFileName(NULL, buf, ARRAY_SIZE(buf));
std::wstring name = ToUtf16(Pathname(ToUtf8(buf)).filename());
diff --git a/chromium/third_party/libjingle/source/talk/base/windowpickerfactory.h b/chromium/third_party/libjingle/source/talk/base/windowpickerfactory.h
index b55cc7dc35e..e9ba6c46a2a 100644
--- a/chromium/third_party/libjingle/source/talk/base/windowpickerfactory.h
+++ b/chromium/third_party/libjingle/source/talk/base/windowpickerfactory.h
@@ -55,7 +55,7 @@ class WindowPickerFactory {
return new Win32WindowPicker();
#elif defined(OSX)
return new MacWindowPicker();
-#elif defined(LINUX)
+#elif defined(LINUX) && defined(HAVE_X11)
return new LinuxWindowPicker();
#else
return NULL;
diff --git a/chromium/third_party/libjingle/source/talk/base/winping.cc b/chromium/third_party/libjingle/source/talk/base/winping.cc
index 001740ad26d..fd25a2374d4 100644
--- a/chromium/third_party/libjingle/source/talk/base/winping.cc
+++ b/chromium/third_party/libjingle/source/talk/base/winping.cc
@@ -27,8 +27,8 @@
#include "talk/base/winping.h"
+#include <assert.h>
#include <Iphlpapi.h>
-#include <cassert>
#include "talk/base/byteorder.h"
#include "talk/base/common.h"