diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-08 14:30:41 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-12 13:49:54 +0200 |
commit | ab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch) | |
tree | 498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/libjingle/source/talk/base | |
parent | 4ce69f7403811819800e7c5ae1318b2647e778d1 (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')
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" |