diff --git a/tools/valgrind-webrtc/drmemory/suppressions.txt b/tools/valgrind-webrtc/drmemory/suppressions.txt index 32be45aef..14bfd7c83 100644 --- a/tools/valgrind-webrtc/drmemory/suppressions.txt +++ b/tools/valgrind-webrtc/drmemory/suppressions.txt @@ -180,174 +180,6 @@ name=https://code.google.com/p/webrtc/issues/detail?id=3158 (3) KERNEL32.dll!BaseThreadInitThunk # libjingle_unittest, fails on Win DrMemory Full -UNINITIALIZED READ -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (4) -*!_towlower_l -*!towlower -*!tolowercase -*!rtc::IsDefaultBrowserFirefox -*!rtc::GetProxySettingsForUrl -*!rtc::AutoDetectProxy::GetProxyForUrl -*!rtc::AutoDetectProxy::DoWork -*!rtc::SignalThread::Run -*!rtc::SignalThread::Worker::Run -*!rtc::Thread::PreRun -KERNEL32.dll!BaseThreadInitThunk - -UNADDRESSABLE ACCESS -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (12) -ntdll.dll!RtlIntegerToUnicodeString -ntdll.dll!RtlIntegerToUnicodeString -libjingle_peerconnection_unittes!rtc::CriticalSection::Enter -libjingle_peerconnection_unittes!rtc::CritScope::CritScope -libjingle_peerconnection_unittes!rtc::LogMessage::~LogMessage -libjingle_peerconnection_unittes!cricket::WebRtcVideoEngine::Print -libjingle_peerconnection_unittes!webrtc::TraceImpl::WriteToFile -libjingle_peerconnection_unittes!webrtc::TraceImpl::Process -libjingle_peerconnection_unittes!webrtc::TraceImpl::Run -libjingle_peerconnection_unittes!webrtc::ThreadWindows::Run -libjingle_peerconnection_unittes!webrtc::ThreadWindows::StartThread -libjingle_peerconnection_unittes!_callthreadstartex -libjingle_peerconnection_unittes!_threadstartex -KERNEL32.dll!BaseThreadInitThunk - -UNADDRESSABLE ACCESS -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (14) -libjingle_peerconnection_unittes!std::list<>::begin -libjingle_peerconnection_unittes!rtc::LogMessage::~LogMessage -libjingle_peerconnection_unittes!cricket::WebRtcVideoEngine::Construct -libjingle_peerconnection_unittes!cricket::WebRtcVideoEngine::WebRtcVideoEngine -libjingle_peerconnection_unittes!cricket::CompositeMediaEngine<>::CompositeMediaEngine<> -libjingle_peerconnection_unittes!cricket::WebRtcMediaEngine::WebRtcMediaEngine -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::Initialize_s -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::OnMessage -libjingle_peerconnection_unittes!rtc::Thread::Send -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::Initialize -libjingle_peerconnection_unittes!webrtc::CreatePeerConnectionFactory -libjingle_peerconnection_unittes!PeerConnectionInterfaceTest::SetUp -libjingle_peerconnection_unittes!testing::internal::HandleSehExceptionsInMethodIfSupported<> - -UNADDRESSABLE ACCESS -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (15) -ntdll.dll!RtlIntegerToUnicodeString -ntdll.dll!RtlIntegerToUnicodeString -libjingle_peerconnection_unittes!rtc::CriticalSection::Enter -libjingle_peerconnection_unittes!rtc::CritScope::CritScope -libjingle_peerconnection_unittes!rtc::LogMessage::~LogMessage -libjingle_peerconnection_unittes!TestInvalidParameterHandler -libjingle_peerconnection_unittes!_invalid_parameter -... -libjingle_peerconnection_unittes!cricket::WebRtcVideoEngine::Construct -libjingle_peerconnection_unittes!cricket::WebRtcVideoEngine::WebRtcVideoEngine -libjingle_peerconnection_unittes!cricket::CompositeMediaEngine<>::CompositeMediaEngine<> -libjingle_peerconnection_unittes!cricket::WebRtcMediaEngine::WebRtcMediaEngine -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::Initialize_s -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::OnMessage -libjingle_peerconnection_unittes!rtc::Thread::Send -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::Initialize -libjingle_peerconnection_unittes!webrtc::CreatePeerConnectionFactory -libjingle_peerconnection_unittes!PeerConnectionInterfaceTest::SetUp -libjingle_peerconnection_unittes!testing::internal::HandleSehExceptionsInMethodIfSupported<> - -UNADDRESSABLE ACCESS -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (16) -ntdll.dll!RtlIntegerToUnicodeString -ntdll.dll!RtlIntegerToUnicodeString -libjingle_peerconnection_unittes!rtc::CriticalSection::Enter -libjingle_peerconnection_unittes!rtc::CritScope::CritScope -libjingle_peerconnection_unittes!rtc::LogMessage::~LogMessage -libjingle_peerconnection_unittes!cricket::WebRtcVoiceEngine::ConstructCodecs -libjingle_peerconnection_unittes!cricket::WebRtcVoiceEngine::Construct -libjingle_peerconnection_unittes!cricket::WebRtcVoiceEngine::WebRtcVoiceEngine -libjingle_peerconnection_unittes!cricket::CompositeMediaEngine<>::CompositeMediaEngine<> -libjingle_peerconnection_unittes!cricket::WebRtcMediaEngine::WebRtcMediaEngine -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::Initialize_s -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::OnMessage -libjingle_peerconnection_unittes!rtc::Thread::Send -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::Initialize -libjingle_peerconnection_unittes!webrtc::CreatePeerConnectionFactory -libjingle_peerconnection_unittes!PeerConnectionInterfaceTest::SetUp -libjingle_peerconnection_unittes!testing::internal::HandleSehExceptionsInMethodIfSupported<> - -UNADDRESSABLE ACCESS -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (32) -ntdll.dll!RtlIntegerToUnicodeString -ntdll.dll!RtlIntegerToUnicodeString -libjingle_peerconnection_unittes!rtc::CriticalSection::Enter -libjingle_peerconnection_unittes!rtc::CritScope::CritScope -... -libjingle_peerconnection_unittes!testing::internal::CountIf<> -libjingle_peerconnection_unittes!testing::TestResult::HasFatalFailure -libjingle_peerconnection_unittes!testing::Test::HasFatalFailure -libjingle_peerconnection_unittes!testing::Test::Run - -UNADDRESSABLE ACCESS -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (34) -ntdll.dll!RtlIntegerToUnicodeString -ntdll.dll!RtlIntegerToUnicodeString -libjingle_peerconnection_unittes!rtc::CriticalSection::Enter -libjingle_peerconnection_unittes!rtc::CritScope::CritScope -... -libjingle_peerconnection_unittes!TestPureCallHandler -libjingle_peerconnection_unittes!_purecall -libjingle_peerconnection_unittes!testing::internal::DefaultGlobalTestPartResultReporter::ReportTestPartResult -libjingle_peerconnection_unittes!testing::internal::DefaultPerThreadTestPartResultReporter::ReportTestPartResult -libjingle_peerconnection_unittes!testing::UnitTest::AddTestPartResult -libjingle_peerconnection_unittes!testing::internal::ReportFailureInUnknownLocation -libjingle_peerconnection_unittes!testing::internal::HandleSehExceptionsInMethodIfSupported<> - -HANDLE LEAK -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (35) -system call NtCreateEvent -KERNELBASE.dll!CreateEventExW -KERNELBASE.dll!CreateEventW -libjingle_peerconnection_unittes!webrtc::EventWindows::EventWindows -libjingle_peerconnection_unittes!webrtc::EventWrapper::Create -libjingle_peerconnection_unittes!webrtc::ProcessThreadImpl::ProcessThreadImpl -libjingle_peerconnection_unittes!webrtc::ProcessThread::CreateProcessThread -libjingle_peerconnection_unittes!webrtc::voe::SharedData::SharedData -libjingle_peerconnection_unittes!webrtc::VoiceEngineImpl::VoiceEngineImpl -libjingle_peerconnection_unittes!webrtc::GetVoiceEngine -libjingle_peerconnection_unittes!webrtc::VoiceEngine::Create -libjingle_peerconnection_unittes!cricket::VoEWrapper::VoEWrapper -libjingle_peerconnection_unittes!cricket::WebRtcVoiceEngine::WebRtcVoiceEngine -libjingle_peerconnection_unittes!cricket::CompositeMediaEngine<>::CompositeMediaEngine<> -libjingle_peerconnection_unittes!cricket::WebRtcMediaEngine::WebRtcMediaEngine -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::Initialize_s -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::OnMessage -libjingle_peerconnection_unittes!rtc::Thread::Send -libjingle_peerconnection_unittes!webrtc::PeerConnectionFactory::Initialize -libjingle_peerconnection_unittes!webrtc::CreatePeerConnectionFactory -libjingle_peerconnection_unittes!PeerConnectionInterfaceTest::SetUp -libjingle_peerconnection_unittes!testing::internal::HandleSehExceptionsInMethodIfSupported<> - -UNINITIALIZED READ -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (36) -libjingle_peerconnection_unittes!webrtc::WebRtcSessionDescriptionFactory::InternalCreateAnswer -libjingle_peerconnection_unittes!webrtc::WebRtcSessionDescriptionFactory::CreateAnswer -libjingle_peerconnection_unittes!webrtc::WebRtcSession::CreateAnswer -libjingle_peerconnection_unittes!webrtc::PeerConnection::CreateAnswer -libjingle_peerconnection_unittes!webrtc::ReturnType<>::Invoke<> -libjingle_peerconnection_unittes!webrtc::MethodCall2<>::OnMessage -libjingle_peerconnection_unittes!rtc::Thread::Send -libjingle_peerconnection_unittes!webrtc::MethodCall2<>::Marshal -libjingle_peerconnection_unittes!webrtc::PeerConnectionProxy::CreateAnswer -libjingle_peerconnection_unittes!PeerConnectionInterfaceTest::DoCreateOfferAnswer -libjingle_peerconnection_unittes!PeerConnectionInterfaceTest::DoCreateAnswer -libjingle_peerconnection_unittes!PeerConnectionInterfaceTest::CreateAnswerAsLocalDescription -libjingle_peerconnection_unittes!PeerConnectionInterfaceTest_ReceiveOfferCreatePrAnswerAndAnswer_Test::TestBody -libjingle_peerconnection_unittes!testing::internal::HandleSehExceptionsInMethodIfSupported<> - -UNADDRESSABLE ACCESS -name=https://code.google.com/p/webrtc/issues/detail?id=3158 (37) -ntdll.dll!RtlIntegerToUnicodeString -ntdll.dll!RtlIntegerToUnicodeString -libjingle_peerconnection_unittes!rtc::CriticalSection::Enter -libjingle_peerconnection_unittes!rtc::CritScope::CritScope -libjingle_peerconnection_unittes!rtc::LogMessage::GetLogToStream -libjingle_peerconnection_unittes!rtc::LogMessage::ConfigureLogging -libjingle_peerconnection_unittes!main - UNINITIALIZED READ name=https://code.google.com/p/webrtc/issues/detail?id=3158 (4) *!_towlower_l diff --git a/tools/valgrind-webrtc/memcheck/suppressions.txt b/tools/valgrind-webrtc/memcheck/suppressions.txt index 72650269c..e95abb850 100644 --- a/tools/valgrind-webrtc/memcheck/suppressions.txt +++ b/tools/valgrind-webrtc/memcheck/suppressions.txt @@ -9,102 +9,6 @@ #----------------------------------------------------------------------- # 1. webrtc stuff -{ - bug_1976_1 - Memcheck:Unaddressable - fun:pthread_mutex_unlock - fun:_ZN9rtc15CriticalSection5LeaveEv - fun:_ZN9rtc9CritScopeD1Ev - ... - fun:_ZN9rtc6Thread15ProcessMessagesEi - fun:_ZN9rtc6Thread3RunEv - fun:_ZN9rtc6Thread6PreRunEPv -} -{ - bug_1976_2 - Memcheck:Leak - fun:calloc - obj:/usr/lib/x86_64-linux-gnu/libnss3.so - ... - fun:NSS_NoDB_Init - fun:_ZN9rtc10NSSContext13InitializeSSLEPFbPvE - fun:_ZN9rtc13InitializeSSLEPFbPvE - fun:_ZN9rtc10RandomTest13SetUpTestCaseEv - fun:_ZN7testing8TestCase16RunSetUpTestCaseEv -} -{ - bug_2100_3 - Memcheck:Uninitialized - fun:tls1_enc - fun:ssl3_get_record - fun:ssl3_read_bytes - fun:ssl3_read_internal - fun:ssl3_read - fun:SSL_read - fun:_ZN9rtc20OpenSSLStreamAdapter4ReadEPvmPmPi - ... -} -{ - bug_2100_4 - Memcheck:Uninitialized - fun:_ZN7testing8internal11CmpHelperEQIjhEENS_15AssertionResultEPKcS4_RKT_RKT0_ - fun:_ZN7testing8internal8EqHelperILb0EE7CompareIjhEENS_15AssertionResultEPKcS6_RKT_RKT0_ - fun:_ZN24SSLStreamAdapterTestDTLS8ReadDataEPN9rtc15StreamInterfaceE - ... -} -{ - bug_2100_5 - Memcheck:Uninitialized - fun:dtls1_process_record - fun:dtls1_get_record - fun:dtls1_read_bytes - fun:ssl3_read_internal - fun:ssl3_read - fun:SSL_read - fun:_ZN9rtc20OpenSSLStreamAdapter4ReadEPvmPmPi - ... -} -{ - BIO_new_mem_buf_1 - Memcheck:Leak - fun:malloc - fun:default_malloc_ex - fun:CRYPTO_malloc - fun:BUF_MEM_new - fun:mem_new - fun:BIO_set - fun:BIO_new - fun:BIO_new_mem_buf - fun:_ZN9rtc18OpenSSLCertificate13FromPEMStringERKSs - ... -} -{ - BIO_new_mem_buf_2 - Memcheck:Leak - fun:malloc - fun:default_malloc_ex - fun:CRYPTO_malloc - fun:BUF_MEM_new - fun:mem_new - fun:BIO_set - fun:BIO_new - fun:BIO_new_mem_buf - fun:_ZN9rtc15OpenSSLIdentity14FromPEMStringsERKSsS2_ -} -{ - SignalsCloseAfterForcedCloseAll - Memcheck:Leak - fun:_Znw* - fun:_ZN9rtc10HttpServer10Connection12BeginProcessEPNS_15StreamInterfaceE - ... -} -{ - DoNotDeleteTask2 - Memcheck:Leak - fun:_Znw* - ... - fun:_ZN9rtc41unstarted_task_test_DoNotDeleteTask2_Test8TestBodyEv -} { bug_716 Memcheck:Leak diff --git a/tools/valgrind-webrtc/tsan/suppressions.txt b/tools/valgrind-webrtc/tsan/suppressions.txt index 8257608cd..b9cac45ac 100644 --- a/tools/valgrind-webrtc/tsan/suppressions.txt +++ b/tools/valgrind-webrtc/tsan/suppressions.txt @@ -9,473 +9,6 @@ #----------------------------------------------------------------------- # 1. webrtc stuff -{ - bug_1205_33 - ThreadSanitizer:Race - fun:webrtc::PeerConnectionProxy::~PeerConnectionProxy - fun:rtc::RefCountedObject::~RefCountedObject - fun:rtc::RefCountedObject::~RefCountedObject - fun:rtc::RefCountedObject::Release - fun:rtc::scoped_refptr::~scoped_refptr - ... -} -{ - bug_1205_34 - ThreadSanitizer:Race - fun:rtc::AtomicOps::Increment - fun:rtc::RefCountedObject::AddRef - fun:rtc::scoped_refptr::scoped_refptr - fun:webrtc::PeerConnectionFactory::CreatePeerConnection - fun:webrtc::PeerConnectionFactory::CreatePeerConnection - ... -} -{ - bug_1205_35 - ThreadSanitizer:Race - fun:rtc::scoped_refptr::scoped_refptr - fun:webrtc::PeerConnectionFactory::CreatePeerConnection - fun:webrtc::PeerConnectionFactory::CreatePeerConnection - ... -} -{ - bug_1205_36 - ThreadSanitizer:Race - fun:rtc::MessageHandler::~MessageHandler - fun:FakeAudioCaptureModule::~FakeAudioCaptureModule - ... -} -{ - bug_1205_39 - ThreadSanitizer:Race - fun:rtc::Thread::Send - fun:FakeAudioCaptureModule::UpdateProcessing - fun:FakeAudioCaptureModule::StopRecording - fun:webrtc::VoEBaseImpl::StopSend - fun:webrtc::VoEBaseImpl::DeleteChannel - fun:cricket::WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel - ... -} -{ - bug_1205_41 - ThreadSanitizer:Race - fun:rtc::Thread::Send - fun:FakeAudioCaptureModule::~FakeAudioCaptureModule - ... -} -{ - bug_2078_2 - ThreadSanitizer:Race - ... - fun:rtc::MemoryStreamBase::Read - ... - fun:cricket::RtpDumpReader::ReadPacket - ... -} -{ - bug_2078_3 - ThreadSanitizer:Race - fun:cricket::RtpSenderReceiver::OnMessage - fun:rtc::MessageQueue::Dispatch - fun:rtc::Thread::ProcessMessages - fun:rtc::Thread::Run - fun:rtc::Thread::PreRun -} -{ - bug_2078_4 - ThreadSanitizer:Race - fun:cricket::FileNetworkInterface::SendPacket - fun:cricket::RtpSenderReceiver::SendRtpPacket - fun:cricket::RtpSenderReceiver::OnMessage - fun:rtc::MessageQueue::Dispatch - fun:rtc::Thread::ProcessMessages - fun:rtc::Thread::Run - fun:rtc::Thread::PreRun -} -{ - bug_2078_7 - ThreadSanitizer:Race - fun:rtc::MemoryStreamBase::~MemoryStreamBase - fun:rtc::MemoryStream::~MemoryStream - ... -} -{ - bug_2078_8 - ThreadSanitizer:Race - fun:rtc::MemoryStreamBase::SetPosition - fun:rtc::StreamInterface::Rewind - fun:cricket::RtpTestUtility::VerifyTestPacketsFromStream - ... -} -{ - bug_2078_13 - ThreadSanitizer:Race - fun:std::_Vector_base::~_Vector_base - fun:std::vector::~vector - fun:cricket::RtpDumpPacket::~RtpDumpPacket - fun:cricket::RtpSenderReceiver::~RtpSenderReceiver - fun:cricket::RtpSenderReceiver::~RtpSenderReceiver - fun:rtc::scoped_ptr::~scoped_ptr - ... -} -{ - bug_2078_14 - ThreadSanitizer:Race - fun:cricket::RtpDumpReader::~RtpDumpReader - fun:cricket::RtpDumpLoopReader::~RtpDumpLoopReader - fun:cricket::RtpDumpLoopReader::~RtpDumpLoopReader - fun:rtc::scoped_ptr::~scoped_ptr - fun:cricket::RtpSenderReceiver::~RtpSenderReceiver - fun:cricket::RtpSenderReceiver::~RtpSenderReceiver - fun:rtc::scoped_ptr::~scoped_ptr - ... -} -{ - bug_2078_15 - ThreadSanitizer:Race - fun:rtc::FileStream::Close - fun:rtc::FileStream::~FileStream - fun:rtc::FileStream::~FileStream - fun:rtc::scoped_ptr::~scoped_ptr - fun:cricket::RtpSenderReceiver::~RtpSenderReceiver - fun:cricket::RtpSenderReceiver::~RtpSenderReceiver - fun:rtc::scoped_ptr::~scoped_ptr - ... -} -{ - bug_2078_16 - ThreadSanitizer:Race - fun:rtc::StreamInterface::~StreamInterface - fun:rtc::FileStream::~FileStream - fun:rtc::FileStream::~FileStream - fun:rtc::scoped_ptr::~scoped_ptr - fun:cricket::RtpSenderReceiver::~RtpSenderReceiver - fun:cricket::RtpSenderReceiver::~RtpSenderReceiver - fun:rtc::scoped_ptr::~scoped_ptr - ... -} -{ - bug_2078_18 - ThreadSanitizer:Race - fun:rtc::MemoryStream::~MemoryStream - ... -} -{ - bug_2078_22 - ThreadSanitizer:Race - fun:rtc::MessageQueue::Quit - fun:rtc::Thread::Stop - ... -} -{ - bug_2078_23 - ThreadSanitizer:Race - fun:::FileVideoCapturerTest::VideoCapturerListener::OnFrameCaptured - fun:sigslot::_connection2::emit - ... - fun:cricket::FileVideoCapturer::ReadFrame - fun:cricket::FileVideoCapturer::FileReadThread::OnMessage - fun:rtc::MessageQueue::Dispatch - fun:rtc::Thread::ProcessMessages - fun:rtc::Thread::Run - fun:cricket::FileVideoCapturer::FileReadThread::Run - fun:rtc::Thread::PreRun -} -{ - bug_2078_24 - ThreadSanitizer:Race - fun:rtc::MemoryStreamBase::SetPosition - fun:rtc::StreamInterface::Rewind - ... -} -{ - bug_2078_25 - ThreadSanitizer:Race - fun:cricket::FileNetworkInterface::SendPacket - fun:cricket::MediaChannel::DoSendPacket - fun:cricket::MediaChannel::SendPacket - fun:cricket::RtpSenderReceiver::SendRtpPacket - fun:cricket::RtpSenderReceiver::OnMessage - fun:rtc::MessageQueue::Dispatch - fun:rtc::Thread::ProcessMessages - fun:rtc::Thread::Run - fun:rtc::Thread::PreRun -} -{ - bug_2079_1 - ThreadSanitizer:Race - fun:rtc::VirtualSocketServer::AddPacketToNetwork - fun:rtc::VirtualSocketServer::SendUdp - fun:rtc::VirtualSocket::SendUdp - fun:rtc::VirtualSocket::SendTo - fun:rtc::AsyncUDPSocket::SendTo - fun:cricket::StunServer::SendResponse - fun:cricket::StunServer::OnBindingRequest - fun:cricket::StunServer::OnPacket - fun:sigslot::_connection4::emit - ... -} -{ - bug_2079_5 - ThreadSanitizer:Race - fun:rtc::Thread::Send - fun:cricket::Transport::SetRole - fun:cricket::BaseSession::GetOrCreateTransportProxy - fun:cricket::BaseSession::CreateChannel - fun:cricket::FakeSession::CreateChannel - fun:cricket::VoiceChannel::Init - fun:cricket::ChannelManager::CreateVoiceChannel_w - ... -} -{ - bug_2079_6 - ThreadSanitizer:Race - fun:rtc::Thread::ReceiveSends - fun:rtc::Thread::Send - fun:rtc::Thread::Invoke - ... -} -{ - bug_2079_8 - ThreadSanitizer:Race - fun:rtc::Thread::Invoke - fun:cricket::ChannelManager::SetCaptureDevice - ... -} -{ - bug_2079_9 - ThreadSanitizer:Race - fun:rtc::Thread::Send - fun:cricket::Transport::SetIceRole - fun:cricket::BaseSession::GetOrCreateTransportProxy - fun:cricket::BaseSession::CreateChannel - fun:cricket::FakeSession::CreateChannel - fun:cricket::VoiceChannel::Init - fun:cricket::ChannelManager::CreateVoiceChannel_w - ... -} -{ - bug_2080_1 - ThreadSanitizer:Race - fun:rtc::MessageQueue::Quit - fun:rtc::SignalThread::Destroy - ... -} -{ - bug_2080_2 - ThreadSanitizer:Race - fun:rtc::MessageQueue::Quit - fun:rtc::AsyncHttpRequest::OnComplete - fun:sigslot::_connection2::emit - ... -} -{ - bug_2080_3 - ThreadSanitizer:Race - fun:rtc::LogMessage::UpdateMinLogSeverity - fun:rtc::LogMessage::AddLogToStream - ... -} -{ - bug_2080_8 - ThreadSanitizer:Race - ... - fun:rtc::AsyncUDPSocket::OnReadEvent - fun:sigslot::_connection1::emit - ... -} -{ - bug_2080_9 - ThreadSanitizer:Race - ... - fun:rtc::AsyncUDPSocket::OnWriteEvent - fun:sigslot::_connection1::emit - ... -} -{ - bug_2080_14 - ThreadSanitizer:Race - fun:rtc::IPAddress::IPAddress - fun:rtc::SocketAddress::ToSockAddrStorage - fun:rtc::PhysicalSocket::SendTo - fun:rtc::AsyncUDPSocket::SendTo - fun:rtc::NATServer::OnExternalPacket - ... -} -{ - bug_2080_16 - ThreadSanitizer:Race - ... - fun:rtc::IPAddress::operator< - ... -} -{ - bug_2080_18 - ThreadSanitizer:Race - fun:rtc::SocketAddress::port - ... -} -{ - bug_2080_19 - ThreadSanitizer:Race - fun:std::vector::_M_insert_aux - fun:std::vector::push_back - fun:rtc::TestClient::OnPacket - ... -} -{ - bug_2080_20 - ThreadSanitizer:Race - fun:rtc::VirtualSocketServer::AddPacketToNetwork - fun:rtc::VirtualSocketServer::SendUdp - fun:rtc::VirtualSocket::SendUdp - fun:rtc::VirtualSocket::SendTo - fun:rtc::AsyncUDPSocket::SendTo - fun:rtc::TestClient::SendTo - ... -} -{ - bug_2080_21 - ThreadSanitizer:Race - fun:rtc::SharedExclusiveTask::waiting_time_in_ms - ... -} -{ - bug_2080_22 - ThreadSanitizer:Race - fun:rtc::SharedExclusiveTask::~SharedExclusiveTask - fun:rtc::ReadTask::~ReadTask - ... -} -{ - bug_2080_24 - ThreadSanitizer:Race - ... - fun:OwnerThread::Run - fun:rtc::Thread::PreRun -} -{ - bug_2080_25 - ThreadSanitizer:Race - fun:sigslot::has_slots::~has_slots - fun:OwnerThread::~OwnerThread - fun:OwnerThread::~OwnerThread - fun:rtc::scoped_ptr::~scoped_ptr - ... -} -{ - bug_2080_27 - ThreadSanitizer:Race - ... - fun:std::_Rb_tree::clear - fun:std::_Rb_tree::_M_erase_aux - fun:std::_Rb_tree::erase - fun:std::set::erase - fun:sigslot::has_slots::disconnect_all - fun:sigslot::has_slots::~has_slots - fun:OwnerThread::~OwnerThread - fun:OwnerThread::~OwnerThread - fun:rtc::scoped_ptr::~scoped_ptr - ... -} -{ - bug_2080_29 - ThreadSanitizer:Race - fun:rtc::Thread::Release - fun:ThreadTest_Release_Test::TestBody - ... -} -{ - bug_2080_30 - ThreadSanitizer:Race - fun:rtc::Thread::Invoke - fun:MessageQueueTest::IsLocked - fun:DeletedLockChecker::~DeletedLockChecker - ... -} -{ - bug_2080_31 - ThreadSanitizer:Race - fun:rtc::MessageHandler::~MessageHandler - fun:rtc::Thread::FunctorMessageHandler::~FunctorMessageHandler - ... -} -{ - bug_2080_32 - ThreadSanitizer:Race - fun:rtc::ReadTask::OnMessage - fun:rtc::MessageQueue::Dispatch - ... -} -{ - bug_2080_33 - ThreadSanitizer:Race - fun:rtc::SharedExclusiveLockTest_TestSharedShared_Test::TestBody - fun:testing::internal::HandleSehExceptionsInMethodIfSupported -} -{ - bug_2080_34 - ThreadSanitizer:Race - fun:rtc::WriteTask::OnMessage - fun:rtc::MessageQueue::Dispatch - fun:rtc::Thread::ProcessMessages - fun:rtc::Thread::Run - fun:rtc::Thread::PreRun -} -{ - bug_2080_35 - ThreadSanitizer:UnlockNonLocked - fun:pthread_mutex_unlock - fun:rtc::CriticalSection::Leave - fun:rtc::CritScope::~CritScope - ... - fun:rtc::AsyncFunctorMessageHandler::OnMessage - fun:rtc::MessageQueue::Dispatch - fun:rtc::Thread::ProcessMessages - fun:rtc::Thread::Run - fun:rtc::Thread::PreRun -} -{ - bug_2080_36 - ThreadSanitizer:Race - ... - fun:rtc::FunctorMessageHandler::OnMessage - fun:rtc::MessageQueue::Dispatch - fun:rtc::Thread::ProcessMessages - fun:rtc::Thread::Run - fun:rtc::Thread::PreRun -} -{ - bug_2931_1 - ThreadSanitizer:Race - ... - fun:rtc::FireAndForgetAsyncClosure::Execute - fun:rtc::AsyncInvoker::OnMessage - fun:rtc::MessageQueue::Dispatch - fun:rtc::Thread::ProcessMessages - fun:rtc::Thread::Run - fun:rtc::Thread::PreRun -} -{ - bug_2931_2 - ThreadSanitizer:Race - ... - fun:rtc::Callback0::HelperImpl::~HelperImpl - fun:rtc::RefCountedObject::~RefCountedObject - fun:rtc::RefCountedObject::~RefCountedObject - fun:rtc::RefCountedObject::Release - fun:rtc::scoped_refptr::~scoped_refptr - fun:rtc::Callback0::~Callback0 - fun:rtc::FireAndForgetAsyncClosure::~FireAndForgetAsyncClosure - fun:rtc::RefCountedObject::~RefCountedObject - fun:rtc::RefCountedObject::~RefCountedObject - fun:rtc::RefCountedObject::Release - fun:rtc::scoped_refptr::~scoped_refptr - fun:rtc::AsyncInvoker::OnMessage - fun:rtc::MessageQueue::Dispatch - fun:rtc::Thread::ProcessMessages - fun:AsyncInvokeTest_WithCallback_Test::TestBody - ... -} { bug_300 ThreadSanitizer:Race diff --git a/tools/valgrind-webrtc/tsan_v2/suppressions.txt b/tools/valgrind-webrtc/tsan_v2/suppressions.txt index 5dca18475..aa28bfaff 100644 --- a/tools/valgrind-webrtc/tsan_v2/suppressions.txt +++ b/tools/valgrind-webrtc/tsan_v2/suppressions.txt @@ -13,9 +13,6 @@ race:webrtc/modules/audio_processing/aec/aec_rdft.c # libjingle_p2p_unittest # See https://code.google.com/p/webrtc/issues/detail?id=2079 -race:webrtc/base/messagequeue.cc -race:webrtc/base/testclient.cc -race:webrtc/base/virtualsocketserver.cc race:talk/base/messagequeue.cc race:talk/base/testclient.cc race:talk/base/virtualsocketserver.cc @@ -23,10 +20,6 @@ race:talk/p2p/base/stunserver_unittest.cc # libjingle_unittest # See https://code.google.com/p/webrtc/issues/detail?id=2080 -race:webrtc/base/logging.cc -race:webrtc/base/sharedexclusivelock_unittest.cc -race:webrtc/base/signalthread_unittest.cc -race:webrtc/base/thread.cc race:talk/base/logging.cc race:talk/base/sharedexclusivelock_unittest.cc race:talk/base/signalthread_unittest.cc diff --git a/webrtc/base/asyncfile.cc b/webrtc/base/asyncfile.cc deleted file mode 100644 index ea904c554..000000000 --- a/webrtc/base/asyncfile.cc +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/asyncfile.h" - -namespace rtc { - -AsyncFile::AsyncFile() { -} - -AsyncFile::~AsyncFile() { -} - -} // namespace rtc diff --git a/webrtc/base/asyncfile.h b/webrtc/base/asyncfile.h deleted file mode 100644 index dd4676688..000000000 --- a/webrtc/base/asyncfile.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCFILE_H__ -#define WEBRTC_BASE_ASYNCFILE_H__ - -#include "webrtc/base/sigslot.h" - -namespace rtc { - -// Provides the ability to perform file I/O asynchronously. -// TODO: Create a common base class with AsyncSocket. -class AsyncFile { - public: - AsyncFile(); - virtual ~AsyncFile(); - - // Determines whether the file will receive read events. - virtual bool readable() = 0; - virtual void set_readable(bool value) = 0; - - // Determines whether the file will receive write events. - virtual bool writable() = 0; - virtual void set_writable(bool value) = 0; - - sigslot::signal1 SignalReadEvent; - sigslot::signal1 SignalWriteEvent; - sigslot::signal2 SignalCloseEvent; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_ASYNCFILE_H__ diff --git a/webrtc/base/asynchttprequest.cc b/webrtc/base/asynchttprequest.cc deleted file mode 100644 index 23042f17d..000000000 --- a/webrtc/base/asynchttprequest.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/asynchttprequest.h" - -namespace rtc { - -enum { - MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE, - MSG_LAUNCH_REQUEST -}; -static const int kDefaultHTTPTimeout = 30 * 1000; // 30 sec - -/////////////////////////////////////////////////////////////////////////////// -// AsyncHttpRequest -/////////////////////////////////////////////////////////////////////////////// - -AsyncHttpRequest::AsyncHttpRequest(const std::string &user_agent) - : start_delay_(0), - firewall_(NULL), - port_(80), - secure_(false), - timeout_(kDefaultHTTPTimeout), - fail_redirect_(false), - factory_(Thread::Current()->socketserver(), user_agent), - pool_(&factory_), - client_(user_agent.c_str(), &pool_), - error_(HE_NONE) { - client_.SignalHttpClientComplete.connect(this, - &AsyncHttpRequest::OnComplete); -} - -AsyncHttpRequest::~AsyncHttpRequest() { -} - -void AsyncHttpRequest::OnWorkStart() { - if (start_delay_ <= 0) { - LaunchRequest(); - } else { - Thread::Current()->PostDelayed(start_delay_, this, MSG_LAUNCH_REQUEST); - } -} - -void AsyncHttpRequest::OnWorkStop() { - // worker is already quitting, no need to explicitly quit - LOG(LS_INFO) << "HttpRequest cancelled"; -} - -void AsyncHttpRequest::OnComplete(HttpClient* client, HttpErrorType error) { - Thread::Current()->Clear(this, MSG_TIMEOUT); - - set_error(error); - if (!error) { - LOG(LS_INFO) << "HttpRequest completed successfully"; - - std::string value; - if (client_.response().hasHeader(HH_LOCATION, &value)) { - response_redirect_ = value.c_str(); - } - } else { - LOG(LS_INFO) << "HttpRequest completed with error: " << error; - } - - worker()->Quit(); -} - -void AsyncHttpRequest::OnMessage(Message* message) { - switch (message->message_id) { - case MSG_TIMEOUT: - LOG(LS_INFO) << "HttpRequest timed out"; - client_.reset(); - worker()->Quit(); - break; - case MSG_LAUNCH_REQUEST: - LaunchRequest(); - break; - default: - SignalThread::OnMessage(message); - break; - } -} - -void AsyncHttpRequest::DoWork() { - // Do nothing while we wait for the request to finish. We only do this so - // that we can be a SignalThread; in the future this class should not be - // a SignalThread, since it does not need to spawn a new thread. - Thread::Current()->ProcessMessages(kForever); -} - -void AsyncHttpRequest::LaunchRequest() { - factory_.SetProxy(proxy_); - if (secure_) - factory_.UseSSL(host_.c_str()); - - bool transparent_proxy = (port_ == 80) && - ((proxy_.type == PROXY_HTTPS) || (proxy_.type == PROXY_UNKNOWN)); - if (transparent_proxy) { - client_.set_proxy(proxy_); - } - client_.set_fail_redirect(fail_redirect_); - client_.set_server(SocketAddress(host_, port_)); - - LOG(LS_INFO) << "HttpRequest start: " << host_ + client_.request().path; - - Thread::Current()->PostDelayed(timeout_, this, MSG_TIMEOUT); - client_.start(); -} - -} // namespace rtc diff --git a/webrtc/base/asynchttprequest.h b/webrtc/base/asynchttprequest.h deleted file mode 100644 index b8d13db8f..000000000 --- a/webrtc/base/asynchttprequest.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCHTTPREQUEST_H_ -#define WEBRTC_BASE_ASYNCHTTPREQUEST_H_ - -#include -#include "webrtc/base/event.h" -#include "webrtc/base/httpclient.h" -#include "webrtc/base/signalthread.h" -#include "webrtc/base/socketpool.h" -#include "webrtc/base/sslsocketfactory.h" - -namespace rtc { - -class FirewallManager; - -/////////////////////////////////////////////////////////////////////////////// -// AsyncHttpRequest -// Performs an HTTP request on a background thread. Notifies on the foreground -// thread once the request is done (successfully or unsuccessfully). -/////////////////////////////////////////////////////////////////////////////// - -class AsyncHttpRequest : public SignalThread { - public: - explicit AsyncHttpRequest(const std::string &user_agent); - ~AsyncHttpRequest(); - - // If start_delay is less than or equal to zero, this starts immediately. - // Start_delay defaults to zero. - int start_delay() const { return start_delay_; } - void set_start_delay(int delay) { start_delay_ = delay; } - - const ProxyInfo& proxy() const { return proxy_; } - void set_proxy(const ProxyInfo& proxy) { - proxy_ = proxy; - } - void set_firewall(FirewallManager * firewall) { - firewall_ = firewall; - } - - // The DNS name of the host to connect to. - const std::string& host() { return host_; } - void set_host(const std::string& host) { host_ = host; } - - // The port to connect to on the target host. - int port() { return port_; } - void set_port(int port) { port_ = port; } - - // Whether the request should use SSL. - bool secure() { return secure_; } - void set_secure(bool secure) { secure_ = secure; } - - // Time to wait on the download, in ms. - int timeout() { return timeout_; } - void set_timeout(int timeout) { timeout_ = timeout; } - - // Fail redirects to allow analysis of redirect urls, etc. - bool fail_redirect() const { return fail_redirect_; } - void set_fail_redirect(bool redirect) { fail_redirect_ = redirect; } - - // Returns the redirect when redirection occurs - const std::string& response_redirect() { return response_redirect_; } - - HttpRequestData& request() { return client_.request(); } - HttpResponseData& response() { return client_.response(); } - HttpErrorType error() { return error_; } - - protected: - void set_error(HttpErrorType error) { error_ = error; } - virtual void OnWorkStart(); - virtual void OnWorkStop(); - void OnComplete(HttpClient* client, HttpErrorType error); - virtual void OnMessage(Message* message); - virtual void DoWork(); - - private: - void LaunchRequest(); - - int start_delay_; - ProxyInfo proxy_; - FirewallManager* firewall_; - std::string host_; - int port_; - bool secure_; - int timeout_; - bool fail_redirect_; - SslSocketFactory factory_; - ReuseSocketPool pool_; - HttpClient client_; - HttpErrorType error_; - std::string response_redirect_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_ASYNCHTTPREQUEST_H_ diff --git a/webrtc/base/asynchttprequest_unittest.cc b/webrtc/base/asynchttprequest_unittest.cc deleted file mode 100644 index 0bfd795b1..000000000 --- a/webrtc/base/asynchttprequest_unittest.cc +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "webrtc/base/asynchttprequest.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/httpserver.h" -#include "webrtc/base/socketstream.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -static const SocketAddress kServerAddr("127.0.0.1", 0); -static const SocketAddress kServerHostnameAddr("localhost", 0); -static const char kServerGetPath[] = "/get"; -static const char kServerPostPath[] = "/post"; -static const char kServerResponse[] = "This is a test"; - -class TestHttpServer : public HttpServer, public sigslot::has_slots<> { - public: - TestHttpServer(Thread* thread, const SocketAddress& addr) : - socket_(thread->socketserver()->CreateAsyncSocket(addr.family(), - SOCK_STREAM)) { - socket_->Bind(addr); - socket_->Listen(5); - socket_->SignalReadEvent.connect(this, &TestHttpServer::OnAccept); - } - - SocketAddress address() const { return socket_->GetLocalAddress(); } - void Close() const { socket_->Close(); } - - private: - void OnAccept(AsyncSocket* socket) { - AsyncSocket* new_socket = socket_->Accept(NULL); - if (new_socket) { - HandleConnection(new SocketStream(new_socket)); - } - } - rtc::scoped_ptr socket_; -}; - -class AsyncHttpRequestTest : public testing::Test, - public sigslot::has_slots<> { - public: - AsyncHttpRequestTest() - : started_(false), - done_(false), - server_(Thread::Current(), kServerAddr) { - server_.SignalHttpRequest.connect(this, &AsyncHttpRequestTest::OnRequest); - } - - bool started() const { return started_; } - bool done() const { return done_; } - - AsyncHttpRequest* CreateGetRequest(const std::string& host, int port, - const std::string& path) { - rtc::AsyncHttpRequest* request = - new rtc::AsyncHttpRequest("unittest"); - request->SignalWorkDone.connect(this, - &AsyncHttpRequestTest::OnRequestDone); - request->request().verb = rtc::HV_GET; - request->set_host(host); - request->set_port(port); - request->request().path = path; - request->response().document.reset(new MemoryStream()); - return request; - } - AsyncHttpRequest* CreatePostRequest(const std::string& host, int port, - const std::string& path, - const std::string content_type, - StreamInterface* content) { - rtc::AsyncHttpRequest* request = - new rtc::AsyncHttpRequest("unittest"); - request->SignalWorkDone.connect(this, - &AsyncHttpRequestTest::OnRequestDone); - request->request().verb = rtc::HV_POST; - request->set_host(host); - request->set_port(port); - request->request().path = path; - request->request().setContent(content_type, content); - request->response().document.reset(new MemoryStream()); - return request; - } - - const TestHttpServer& server() const { return server_; } - - protected: - void OnRequest(HttpServer* server, HttpServerTransaction* t) { - started_ = true; - - if (t->request.path == kServerGetPath) { - t->response.set_success("text/plain", new MemoryStream(kServerResponse)); - } else if (t->request.path == kServerPostPath) { - // reverse the data and reply - size_t size; - StreamInterface* in = t->request.document.get(); - StreamInterface* out = new MemoryStream(); - in->GetSize(&size); - for (size_t i = 0; i < size; ++i) { - char ch; - in->SetPosition(size - i - 1); - in->Read(&ch, 1, NULL, NULL); - out->Write(&ch, 1, NULL, NULL); - } - out->Rewind(); - t->response.set_success("text/plain", out); - } else { - t->response.set_error(404); - } - server_.Respond(t); - } - void OnRequestDone(SignalThread* thread) { - done_ = true; - } - - private: - bool started_; - bool done_; - TestHttpServer server_; -}; - -TEST_F(AsyncHttpRequestTest, TestGetSuccess) { - AsyncHttpRequest* req = CreateGetRequest( - kServerHostnameAddr.hostname(), server().address().port(), - kServerGetPath); - EXPECT_FALSE(started()); - req->Start(); - EXPECT_TRUE_WAIT(started(), 5000); // Should have started by now. - EXPECT_TRUE_WAIT(done(), 5000); - std::string response; - EXPECT_EQ(200U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->Rewind(); - req->response().document->ReadLine(&response); - EXPECT_EQ(kServerResponse, response); - req->Release(); -} - -TEST_F(AsyncHttpRequestTest, TestGetNotFound) { - AsyncHttpRequest* req = CreateGetRequest( - kServerHostnameAddr.hostname(), server().address().port(), - "/bad"); - req->Start(); - EXPECT_TRUE_WAIT(done(), 5000); - size_t size; - EXPECT_EQ(404U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->GetSize(&size); - EXPECT_EQ(0U, size); - req->Release(); -} - -TEST_F(AsyncHttpRequestTest, TestGetToNonServer) { - AsyncHttpRequest* req = CreateGetRequest( - "127.0.0.1", server().address().port(), - kServerGetPath); - // Stop the server before we send the request. - server().Close(); - req->Start(); - EXPECT_TRUE_WAIT(done(), 10000); - size_t size; - EXPECT_EQ(500U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->GetSize(&size); - EXPECT_EQ(0U, size); - req->Release(); -} - -TEST_F(AsyncHttpRequestTest, DISABLED_TestGetToInvalidHostname) { - AsyncHttpRequest* req = CreateGetRequest( - "invalid", server().address().port(), - kServerGetPath); - req->Start(); - EXPECT_TRUE_WAIT(done(), 5000); - size_t size; - EXPECT_EQ(500U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->GetSize(&size); - EXPECT_EQ(0U, size); - req->Release(); -} - -TEST_F(AsyncHttpRequestTest, TestPostSuccess) { - AsyncHttpRequest* req = CreatePostRequest( - kServerHostnameAddr.hostname(), server().address().port(), - kServerPostPath, "text/plain", new MemoryStream("abcd1234")); - req->Start(); - EXPECT_TRUE_WAIT(done(), 5000); - std::string response; - EXPECT_EQ(200U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->Rewind(); - req->response().document->ReadLine(&response); - EXPECT_EQ("4321dcba", response); - req->Release(); -} - -// Ensure that we shut down properly even if work is outstanding. -TEST_F(AsyncHttpRequestTest, TestCancel) { - AsyncHttpRequest* req = CreateGetRequest( - kServerHostnameAddr.hostname(), server().address().port(), - kServerGetPath); - req->Start(); - req->Destroy(true); -} - -TEST_F(AsyncHttpRequestTest, TestGetSuccessDelay) { - AsyncHttpRequest* req = CreateGetRequest( - kServerHostnameAddr.hostname(), server().address().port(), - kServerGetPath); - req->set_start_delay(10); // Delay 10ms. - req->Start(); - Thread::SleepMs(5); - EXPECT_FALSE(started()); // Should not have started immediately. - EXPECT_TRUE_WAIT(started(), 5000); // Should have started by now. - EXPECT_TRUE_WAIT(done(), 5000); - std::string response; - EXPECT_EQ(200U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->Rewind(); - req->response().document->ReadLine(&response); - EXPECT_EQ(kServerResponse, response); - req->Release(); -} - -} // namespace rtc diff --git a/webrtc/base/asyncinvoker-inl.h b/webrtc/base/asyncinvoker-inl.h deleted file mode 100644 index 733cb0e79..000000000 --- a/webrtc/base/asyncinvoker-inl.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCINVOKER_INL_H_ -#define WEBRTC_BASE_ASYNCINVOKER_INL_H_ - -#include "webrtc/base/bind.h" -#include "webrtc/base/callback.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/refcount.h" -#include "webrtc/base/scoped_ref_ptr.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -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 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& callback) { - CritScope cs(&crit_); - callback_ = callback; - } - bool CallbackCanceled() const { return calling_thread_ == NULL; } - - private: - Callback0 callback_; - CriticalSection crit_; - AsyncInvoker* invoker_; - Thread* calling_thread_; - - void CancelCallback(); -}; - -// Closures that have a non-void return value and require a callback. -template -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(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 NotifyingAsyncClosure - : 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(Bind(callback, callback_host))); - } - virtual void Execute() { - functor_(); - TriggerCallback(); - } - - private: - FunctorT functor_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_ASYNCINVOKER_INL_H_ diff --git a/webrtc/base/asyncinvoker.cc b/webrtc/base/asyncinvoker.cc deleted file mode 100644 index ee423f110..000000000 --- a/webrtc/base/asyncinvoker.cc +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/asyncinvoker.h" - -namespace rtc { - -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* data = - static_cast*>(msg->pdata); - scoped_refptr 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(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(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(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 rtc diff --git a/webrtc/base/asyncinvoker.h b/webrtc/base/asyncinvoker.h deleted file mode 100644 index ee9a03c80..000000000 --- a/webrtc/base/asyncinvoker.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCINVOKER_H_ -#define WEBRTC_BASE_ASYNCINVOKER_H_ - -#include "webrtc/base/asyncinvoker-inl.h" -#include "webrtc/base/bind.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/scopedptrcollection.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -// 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( -// thread, Bind(&MyClass::AsyncTaskWithResult, this, x), -// &MyClass::OnTaskComplete, this); -// } -// void FireAnotherAsyncTask(Thread* thread) { -// // No callback specified means fire-and-forget. -// invoker_.AsyncInvoke( -// 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 - void AsyncInvoke(Thread* thread, - const FunctorT& functor, - uint32 id = 0) { - AsyncClosure* closure = - new RefCountedObject >(functor); - DoInvoke(thread, closure, id); - } - - // Call |functor| asynchronously on |thread|, calling |callback| when done. - template - void AsyncInvoke(Thread* thread, - const FunctorT& functor, - void (HostT::*callback)(ReturnT), - HostT* callback_host, - uint32 id = 0) { - AsyncClosure* closure = - new RefCountedObject >( - 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 - void AsyncInvoke(Thread* thread, - const FunctorT& functor, - void (HostT::*callback)(), - HostT* callback_host, - uint32 id = 0) { - AsyncClosure* closure = - new RefCountedObject >( - 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 rtc - - -#endif // WEBRTC_BASE_ASYNCINVOKER_H_ diff --git a/webrtc/base/asyncpacketsocket.h b/webrtc/base/asyncpacketsocket.h deleted file mode 100644 index dd91ea1f1..000000000 --- a/webrtc/base/asyncpacketsocket.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCPACKETSOCKET_H_ -#define WEBRTC_BASE_ASYNCPACKETSOCKET_H_ - -#include "webrtc/base/dscp.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/socket.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { - -// 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 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 { - PacketTime() : timestamp(-1), not_before(-1) {} - PacketTime(int64 timestamp, int64 not_before) - : timestamp(timestamp), not_before(not_before) { - } - - int64 timestamp; // Receive time after socket delivers the data. - int64 not_before; // Earliest possible time the data could have arrived, - // indicating the potential error in the |timestamp| value, - // in case the system, is busy. For example, the time of - // the last select() call. - // If unknown, this value will be set to zero. -}; - -inline PacketTime CreatePacketTime(int64 not_before) { - return PacketTime(TimeMicros(), not_before); -} - -// Provides the ability to receive packets asynchronously. Sends are not -// buffered since it is acceptable to drop packets under high load. -class AsyncPacketSocket : public sigslot::has_slots<> { - public: - enum State { - STATE_CLOSED, - STATE_BINDING, - STATE_BOUND, - STATE_CONNECTING, - STATE_CONNECTED - }; - - AsyncPacketSocket() { } - virtual ~AsyncPacketSocket() { } - - // Returns current local address. Address may be set to NULL if the - // socket is not bound yet (GetState() returns STATE_BINDING). - virtual SocketAddress GetLocalAddress() const = 0; - - // Returns remote address. Returns zeroes if this is not a client TCP socket. - virtual SocketAddress GetRemoteAddress() const = 0; - - // Send a packet. - 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, - const PacketOptions& options) = 0; - - // Close the socket. - virtual int Close() = 0; - - // Returns current state of the socket. - virtual State GetState() const = 0; - - // Get/set options. - virtual int GetOption(Socket::Option opt, int* value) = 0; - virtual int SetOption(Socket::Option opt, int value) = 0; - - // Get/Set current error. - // TODO: Remove SetError(). - virtual int GetError() const = 0; - virtual void SetError(int error) = 0; - - // Emitted each time a packet is read. Used only for UDP and - // connected TCP sockets. - sigslot::signal5 SignalReadPacket; - - // Emitted when the socket is currently able to send. - sigslot::signal1 SignalReadyToSend; - - // Emitted after address for the socket is allocated, i.e. binding - // is finished. State of the socket is changed from BINDING to BOUND - // (for UDP and server TCP sockets) or CONNECTING (for client TCP - // sockets). - sigslot::signal2 SignalAddressReady; - - // Emitted for client TCP sockets when state is changed from - // CONNECTING to CONNECTED. - sigslot::signal1 SignalConnect; - - // Emitted for client TCP sockets when state is changed from - // CONNECTED to CLOSED. - sigslot::signal2 SignalClose; - - // Used only for listening TCP sockets. - sigslot::signal2 SignalNewConnection; - - private: - DISALLOW_EVIL_CONSTRUCTORS(AsyncPacketSocket); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_ASYNCPACKETSOCKET_H_ diff --git a/webrtc/base/asyncresolverinterface.h b/webrtc/base/asyncresolverinterface.h deleted file mode 100644 index 4b401bd97..000000000 --- a/webrtc/base/asyncresolverinterface.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCRESOLVERINTERFACE_H_ -#define WEBRTC_BASE_ASYNCRESOLVERINTERFACE_H_ - -#include "webrtc/base/sigslot.h" -#include "webrtc/base/socketaddress.h" - -namespace rtc { - -// This interface defines the methods to resolve the address asynchronously. -class AsyncResolverInterface { - public: - AsyncResolverInterface() {} - virtual ~AsyncResolverInterface() {} - - // Start address resolve process. - virtual void Start(const SocketAddress& addr) = 0; - // Returns top most resolved address of |family| - virtual bool GetResolvedAddress(int family, SocketAddress* addr) const = 0; - // Returns error from resolver. - virtual int GetError() const = 0; - // Delete the resolver. - virtual void Destroy(bool wait) = 0; - // Returns top most resolved IPv4 address if address is resolved successfully. - // Otherwise returns address set in SetAddress. - SocketAddress address() const { - SocketAddress addr; - GetResolvedAddress(AF_INET, &addr); - return addr; - } - - // This signal is fired when address resolve process is completed. - sigslot::signal1 SignalDone; -}; - -} // namespace rtc - -#endif diff --git a/webrtc/base/asyncsocket.cc b/webrtc/base/asyncsocket.cc deleted file mode 100644 index d565c6e99..000000000 --- a/webrtc/base/asyncsocket.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/asyncsocket.h" - -namespace rtc { - -AsyncSocket::AsyncSocket() { -} - -AsyncSocket::~AsyncSocket() { -} - -AsyncSocketAdapter::AsyncSocketAdapter(AsyncSocket* socket) : socket_(NULL) { - Attach(socket); -} - -AsyncSocketAdapter::~AsyncSocketAdapter() { - delete socket_; -} - -void AsyncSocketAdapter::Attach(AsyncSocket* socket) { - ASSERT(!socket_); - socket_ = socket; - if (socket_) { - socket_->SignalConnectEvent.connect(this, - &AsyncSocketAdapter::OnConnectEvent); - socket_->SignalReadEvent.connect(this, - &AsyncSocketAdapter::OnReadEvent); - socket_->SignalWriteEvent.connect(this, - &AsyncSocketAdapter::OnWriteEvent); - socket_->SignalCloseEvent.connect(this, - &AsyncSocketAdapter::OnCloseEvent); - } -} - -} // namespace rtc diff --git a/webrtc/base/asyncsocket.h b/webrtc/base/asyncsocket.h deleted file mode 100644 index a6f3158e9..000000000 --- a/webrtc/base/asyncsocket.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCSOCKET_H_ -#define WEBRTC_BASE_ASYNCSOCKET_H_ - -#include "webrtc/base/common.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/socket.h" - -namespace rtc { - -// TODO: Remove Socket and rename AsyncSocket to Socket. - -// Provides the ability to perform socket I/O asynchronously. -class AsyncSocket : public Socket { - public: - AsyncSocket(); - virtual ~AsyncSocket(); - - virtual AsyncSocket* Accept(SocketAddress* paddr) = 0; - - // SignalReadEvent and SignalWriteEvent use multi_threaded_local to allow - // access concurrently from different thread. - // For example SignalReadEvent::connect will be called in AsyncUDPSocket ctor - // but at the same time the SocketDispatcher maybe signaling the read event. - // ready to read - sigslot::signal1 SignalReadEvent; - // ready to write - sigslot::signal1 SignalWriteEvent; - sigslot::signal1 SignalConnectEvent; // connected - sigslot::signal2 SignalCloseEvent; // closed -}; - -class AsyncSocketAdapter : public AsyncSocket, public sigslot::has_slots<> { - public: - // The adapted socket may explicitly be NULL, and later assigned using Attach. - // However, subclasses which support detached mode must override any methods - // that will be called during the detached period (usually GetState()), to - // avoid dereferencing a null pointer. - explicit AsyncSocketAdapter(AsyncSocket* socket); - virtual ~AsyncSocketAdapter(); - void Attach(AsyncSocket* socket); - virtual SocketAddress GetLocalAddress() const { - return socket_->GetLocalAddress(); - } - virtual SocketAddress GetRemoteAddress() const { - return socket_->GetRemoteAddress(); - } - virtual int Bind(const SocketAddress& addr) { - return socket_->Bind(addr); - } - virtual int Connect(const SocketAddress& addr) { - return socket_->Connect(addr); - } - virtual int Send(const void* pv, size_t cb) { - return socket_->Send(pv, cb); - } - virtual int SendTo(const void* pv, size_t cb, const SocketAddress& addr) { - return socket_->SendTo(pv, cb, addr); - } - virtual int Recv(void* pv, size_t cb) { - return socket_->Recv(pv, cb); - } - virtual int RecvFrom(void* pv, size_t cb, SocketAddress* paddr) { - return socket_->RecvFrom(pv, cb, paddr); - } - virtual int Listen(int backlog) { - return socket_->Listen(backlog); - } - virtual AsyncSocket* Accept(SocketAddress* paddr) { - return socket_->Accept(paddr); - } - virtual int Close() { - return socket_->Close(); - } - virtual int GetError() const { - return socket_->GetError(); - } - virtual void SetError(int error) { - return socket_->SetError(error); - } - virtual ConnState GetState() const { - return socket_->GetState(); - } - virtual int EstimateMTU(uint16* mtu) { - return socket_->EstimateMTU(mtu); - } - virtual int GetOption(Option opt, int* value) { - return socket_->GetOption(opt, value); - } - virtual int SetOption(Option opt, int value) { - return socket_->SetOption(opt, value); - } - - protected: - virtual void OnConnectEvent(AsyncSocket* socket) { - SignalConnectEvent(this); - } - virtual void OnReadEvent(AsyncSocket* socket) { - SignalReadEvent(this); - } - virtual void OnWriteEvent(AsyncSocket* socket) { - SignalWriteEvent(this); - } - virtual void OnCloseEvent(AsyncSocket* socket, int err) { - SignalCloseEvent(this, err); - } - - AsyncSocket* socket_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_ASYNCSOCKET_H_ diff --git a/webrtc/base/asynctcpsocket.cc b/webrtc/base/asynctcpsocket.cc deleted file mode 100644 index 0f7abd5a6..000000000 --- a/webrtc/base/asynctcpsocket.cc +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/asynctcpsocket.h" - -#include - -#include "webrtc/base/byteorder.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" - -#if defined(WEBRTC_POSIX) -#include -#endif // WEBRTC_POSIX - -namespace rtc { - -static const size_t kMaxPacketSize = 64 * 1024; - -typedef uint16 PacketLength; -static const size_t kPacketLenSize = sizeof(PacketLength); - -static const size_t kBufSize = kMaxPacketSize + kPacketLenSize; - -static const int kListenBacklog = 5; - -// Binds and connects |socket| -AsyncSocket* AsyncTCPSocketBase::ConnectSocket( - rtc::AsyncSocket* socket, - const rtc::SocketAddress& bind_address, - const rtc::SocketAddress& remote_address) { - rtc::scoped_ptr owned_socket(socket); - if (socket->Bind(bind_address) < 0) { - LOG(LS_ERROR) << "Bind() failed with error " << socket->GetError(); - return NULL; - } - if (socket->Connect(remote_address) < 0) { - LOG(LS_ERROR) << "Connect() failed with error " << socket->GetError(); - return NULL; - } - return owned_socket.release(); -} - -AsyncTCPSocketBase::AsyncTCPSocketBase(AsyncSocket* socket, bool listen, - size_t max_packet_size) - : socket_(socket), - listen_(listen), - insize_(max_packet_size), - inpos_(0), - outsize_(max_packet_size), - outpos_(0) { - inbuf_ = new char[insize_]; - outbuf_ = new char[outsize_]; - - ASSERT(socket_.get() != NULL); - socket_->SignalConnectEvent.connect( - this, &AsyncTCPSocketBase::OnConnectEvent); - socket_->SignalReadEvent.connect(this, &AsyncTCPSocketBase::OnReadEvent); - socket_->SignalWriteEvent.connect(this, &AsyncTCPSocketBase::OnWriteEvent); - socket_->SignalCloseEvent.connect(this, &AsyncTCPSocketBase::OnCloseEvent); - - if (listen_) { - if (socket_->Listen(kListenBacklog) < 0) { - LOG(LS_ERROR) << "Listen() failed with error " << socket_->GetError(); - } - } -} - -AsyncTCPSocketBase::~AsyncTCPSocketBase() { - delete [] inbuf_; - delete [] outbuf_; -} - -SocketAddress AsyncTCPSocketBase::GetLocalAddress() const { - return socket_->GetLocalAddress(); -} - -SocketAddress AsyncTCPSocketBase::GetRemoteAddress() const { - return socket_->GetRemoteAddress(); -} - -int AsyncTCPSocketBase::Close() { - return socket_->Close(); -} - -AsyncTCPSocket::State AsyncTCPSocketBase::GetState() const { - switch (socket_->GetState()) { - case Socket::CS_CLOSED: - return STATE_CLOSED; - case Socket::CS_CONNECTING: - if (listen_) { - return STATE_BOUND; - } else { - return STATE_CONNECTING; - } - case Socket::CS_CONNECTED: - return STATE_CONNECTED; - default: - ASSERT(false); - return STATE_CLOSED; - } -} - -int AsyncTCPSocketBase::GetOption(Socket::Option opt, int* value) { - return socket_->GetOption(opt, value); -} - -int AsyncTCPSocketBase::SetOption(Socket::Option opt, int value) { - return socket_->SetOption(opt, value); -} - -int AsyncTCPSocketBase::GetError() const { - return socket_->GetError(); -} - -void AsyncTCPSocketBase::SetError(int error) { - return socket_->SetError(error); -} - -int AsyncTCPSocketBase::SendTo(const void *pv, size_t cb, - const SocketAddress& addr, - const rtc::PacketOptions& options) { - if (addr == GetRemoteAddress()) - return Send(pv, cb, options); - - ASSERT(false); - socket_->SetError(ENOTCONN); - return -1; -} - -int AsyncTCPSocketBase::SendRaw(const void * pv, size_t cb) { - if (outpos_ + cb > outsize_) { - socket_->SetError(EMSGSIZE); - return -1; - } - - memcpy(outbuf_ + outpos_, pv, cb); - outpos_ += cb; - - return FlushOutBuffer(); -} - -int AsyncTCPSocketBase::FlushOutBuffer() { - int res = socket_->Send(outbuf_, outpos_); - if (res <= 0) { - return res; - } - if (static_cast(res) <= outpos_) { - outpos_ -= res; - } else { - ASSERT(false); - return -1; - } - if (outpos_ > 0) { - memmove(outbuf_, outbuf_ + res, outpos_); - } - return res; -} - -void AsyncTCPSocketBase::AppendToOutBuffer(const void* pv, size_t cb) { - ASSERT(outpos_ + cb < outsize_); - memcpy(outbuf_ + outpos_, pv, cb); - outpos_ += cb; -} - -void AsyncTCPSocketBase::OnConnectEvent(AsyncSocket* socket) { - SignalConnect(this); -} - -void AsyncTCPSocketBase::OnReadEvent(AsyncSocket* socket) { - ASSERT(socket_.get() == socket); - - if (listen_) { - rtc::SocketAddress address; - rtc::AsyncSocket* new_socket = socket->Accept(&address); - if (!new_socket) { - // TODO: Do something better like forwarding the error - // to the user. - LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError(); - return; - } - - HandleIncomingConnection(new_socket); - - // Prime a read event in case data is waiting. - new_socket->SignalReadEvent(new_socket); - } else { - int len = socket_->Recv(inbuf_ + inpos_, insize_ - inpos_); - if (len < 0) { - // TODO: Do something better like forwarding the error to the user. - if (!socket_->IsBlocking()) { - LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError(); - } - return; - } - - inpos_ += len; - - ProcessInput(inbuf_, &inpos_); - - if (inpos_ >= insize_) { - LOG(LS_ERROR) << "input buffer overflow"; - ASSERT(false); - inpos_ = 0; - } - } -} - -void AsyncTCPSocketBase::OnWriteEvent(AsyncSocket* socket) { - ASSERT(socket_.get() == socket); - - if (outpos_ > 0) { - FlushOutBuffer(); - } - - if (outpos_ == 0) { - SignalReadyToSend(this); - } -} - -void AsyncTCPSocketBase::OnCloseEvent(AsyncSocket* socket, int error) { - SignalClose(this, error); -} - -// AsyncTCPSocket -// Binds and connects |socket| and creates AsyncTCPSocket for -// it. Takes ownership of |socket|. Returns NULL if bind() or -// connect() fail (|socket| is destroyed in that case). -AsyncTCPSocket* AsyncTCPSocket::Create( - AsyncSocket* socket, - const SocketAddress& bind_address, - const SocketAddress& remote_address) { - return new AsyncTCPSocket(AsyncTCPSocketBase::ConnectSocket( - socket, bind_address, remote_address), false); -} - -AsyncTCPSocket::AsyncTCPSocket(AsyncSocket* socket, bool listen) - : AsyncTCPSocketBase(socket, listen, kBufSize) { -} - -int AsyncTCPSocket::Send(const void *pv, size_t cb, - const rtc::PacketOptions& options) { - if (cb > kBufSize) { - SetError(EMSGSIZE); - return -1; - } - - // If we are blocking on send, then silently drop this packet - if (!IsOutBufferEmpty()) - return static_cast(cb); - - PacketLength pkt_len = HostToNetwork16(static_cast(cb)); - AppendToOutBuffer(&pkt_len, kPacketLenSize); - AppendToOutBuffer(pv, cb); - - int res = FlushOutBuffer(); - if (res <= 0) { - // drop packet if we made no progress - ClearOutBuffer(); - return res; - } - - // We claim to have sent the whole thing, even if we only sent partial - return static_cast(cb); -} - -void AsyncTCPSocket::ProcessInput(char * data, size_t* len) { - SocketAddress remote_addr(GetRemoteAddress()); - - while (true) { - if (*len < kPacketLenSize) - return; - - PacketLength pkt_len = rtc::GetBE16(data); - if (*len < kPacketLenSize + pkt_len) - return; - - SignalReadPacket(this, data + kPacketLenSize, pkt_len, remote_addr, - CreatePacketTime(0)); - - *len -= kPacketLenSize + pkt_len; - if (*len > 0) { - memmove(data, data + kPacketLenSize + pkt_len, *len); - } - } -} - -void AsyncTCPSocket::HandleIncomingConnection(AsyncSocket* socket) { - SignalNewConnection(this, new AsyncTCPSocket(socket, false)); -} - -} // namespace rtc diff --git a/webrtc/base/asynctcpsocket.h b/webrtc/base/asynctcpsocket.h deleted file mode 100644 index ddee2615a..000000000 --- a/webrtc/base/asynctcpsocket.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCTCPSOCKET_H_ -#define WEBRTC_BASE_ASYNCTCPSOCKET_H_ - -#include "webrtc/base/asyncpacketsocket.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/socketfactory.h" - -namespace rtc { - -// Simulates UDP semantics over TCP. Send and Recv packet sizes -// are preserved, and drops packets silently on Send, rather than -// buffer them in user space. -class AsyncTCPSocketBase : public AsyncPacketSocket { - public: - AsyncTCPSocketBase(AsyncSocket* socket, bool listen, size_t max_packet_size); - virtual ~AsyncTCPSocketBase(); - - // Pure virtual methods to send and recv data. - virtual int Send(const void *pv, size_t cb, - const rtc::PacketOptions& options) = 0; - virtual void ProcessInput(char* data, size_t* len) = 0; - // Signals incoming connection. - virtual void HandleIncomingConnection(AsyncSocket* socket) = 0; - - virtual SocketAddress GetLocalAddress() const; - virtual SocketAddress GetRemoteAddress() const; - virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr, - const rtc::PacketOptions& options); - virtual int Close(); - - virtual State GetState() const; - virtual int GetOption(Socket::Option opt, int* value); - virtual int SetOption(Socket::Option opt, int value); - virtual int GetError() const; - virtual void SetError(int error); - - protected: - // Binds and connects |socket| and creates AsyncTCPSocket for - // it. Takes ownership of |socket|. Returns NULL if bind() or - // connect() fail (|socket| is destroyed in that case). - static AsyncSocket* ConnectSocket(AsyncSocket* socket, - const SocketAddress& bind_address, - const SocketAddress& remote_address); - virtual int SendRaw(const void* pv, size_t cb); - int FlushOutBuffer(); - // Add data to |outbuf_|. - void AppendToOutBuffer(const void* pv, size_t cb); - - // Helper methods for |outpos_|. - bool IsOutBufferEmpty() const { return outpos_ == 0; } - void ClearOutBuffer() { outpos_ = 0; } - - private: - // Called by the underlying socket - void OnConnectEvent(AsyncSocket* socket); - void OnReadEvent(AsyncSocket* socket); - void OnWriteEvent(AsyncSocket* socket); - void OnCloseEvent(AsyncSocket* socket, int error); - - scoped_ptr socket_; - bool listen_; - char* inbuf_, * outbuf_; - size_t insize_, inpos_, outsize_, outpos_; - - DISALLOW_EVIL_CONSTRUCTORS(AsyncTCPSocketBase); -}; - -class AsyncTCPSocket : public AsyncTCPSocketBase { - public: - // Binds and connects |socket| and creates AsyncTCPSocket for - // it. Takes ownership of |socket|. Returns NULL if bind() or - // connect() fail (|socket| is destroyed in that case). - static AsyncTCPSocket* Create(AsyncSocket* socket, - const SocketAddress& bind_address, - const SocketAddress& remote_address); - AsyncTCPSocket(AsyncSocket* socket, bool listen); - virtual ~AsyncTCPSocket() {} - - virtual int Send(const void* pv, size_t cb, - const rtc::PacketOptions& options); - virtual void ProcessInput(char* data, size_t* len); - virtual void HandleIncomingConnection(AsyncSocket* socket); - - private: - DISALLOW_EVIL_CONSTRUCTORS(AsyncTCPSocket); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_ASYNCTCPSOCKET_H_ diff --git a/webrtc/base/asynctcpsocket_unittest.cc b/webrtc/base/asynctcpsocket_unittest.cc deleted file mode 100644 index b93175864..000000000 --- a/webrtc/base/asynctcpsocket_unittest.cc +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/asynctcpsocket.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/physicalsocketserver.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/virtualsocketserver.h" - -namespace rtc { - -class AsyncTCPSocketTest - : public testing::Test, - public sigslot::has_slots<> { - public: - AsyncTCPSocketTest() - : pss_(new rtc::PhysicalSocketServer), - vss_(new rtc::VirtualSocketServer(pss_.get())), - socket_(vss_->CreateAsyncSocket(SOCK_STREAM)), - tcp_socket_(new AsyncTCPSocket(socket_, true)), - ready_to_send_(false) { - tcp_socket_->SignalReadyToSend.connect(this, - &AsyncTCPSocketTest::OnReadyToSend); - } - - void OnReadyToSend(rtc::AsyncPacketSocket* socket) { - ready_to_send_ = true; - } - - protected: - scoped_ptr pss_; - scoped_ptr vss_; - AsyncSocket* socket_; - scoped_ptr tcp_socket_; - bool ready_to_send_; -}; - -TEST_F(AsyncTCPSocketTest, OnWriteEvent) { - EXPECT_FALSE(ready_to_send_); - socket_->SignalWriteEvent(socket_); - EXPECT_TRUE(ready_to_send_); -} - -} // namespace rtc diff --git a/webrtc/base/asyncudpsocket.cc b/webrtc/base/asyncudpsocket.cc deleted file mode 100644 index 3e2ecc4cd..000000000 --- a/webrtc/base/asyncudpsocket.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/asyncudpsocket.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -static const int BUF_SIZE = 64 * 1024; - -AsyncUDPSocket* AsyncUDPSocket::Create( - AsyncSocket* socket, - const SocketAddress& bind_address) { - scoped_ptr owned_socket(socket); - if (socket->Bind(bind_address) < 0) { - LOG(LS_ERROR) << "Bind() failed with error " << socket->GetError(); - return NULL; - } - return new AsyncUDPSocket(owned_socket.release()); -} - -AsyncUDPSocket* AsyncUDPSocket::Create(SocketFactory* factory, - const SocketAddress& bind_address) { - AsyncSocket* socket = - factory->CreateAsyncSocket(bind_address.family(), SOCK_DGRAM); - if (!socket) - return NULL; - return Create(socket, bind_address); -} - -AsyncUDPSocket::AsyncUDPSocket(AsyncSocket* socket) - : socket_(socket) { - ASSERT(socket_); - size_ = BUF_SIZE; - buf_ = new char[size_]; - - // The socket should start out readable but not writable. - socket_->SignalReadEvent.connect(this, &AsyncUDPSocket::OnReadEvent); - socket_->SignalWriteEvent.connect(this, &AsyncUDPSocket::OnWriteEvent); -} - -AsyncUDPSocket::~AsyncUDPSocket() { - delete [] buf_; -} - -SocketAddress AsyncUDPSocket::GetLocalAddress() const { - return socket_->GetLocalAddress(); -} - -SocketAddress AsyncUDPSocket::GetRemoteAddress() const { - return socket_->GetRemoteAddress(); -} - -int AsyncUDPSocket::Send(const void *pv, size_t cb, - const rtc::PacketOptions& options) { - return socket_->Send(pv, cb); -} - -int AsyncUDPSocket::SendTo(const void *pv, size_t cb, - const SocketAddress& addr, - const rtc::PacketOptions& options) { - return socket_->SendTo(pv, cb, addr); -} - -int AsyncUDPSocket::Close() { - return socket_->Close(); -} - -AsyncUDPSocket::State AsyncUDPSocket::GetState() const { - return STATE_BOUND; -} - -int AsyncUDPSocket::GetOption(Socket::Option opt, int* value) { - return socket_->GetOption(opt, value); -} - -int AsyncUDPSocket::SetOption(Socket::Option opt, int value) { - return socket_->SetOption(opt, value); -} - -int AsyncUDPSocket::GetError() const { - return socket_->GetError(); -} - -void AsyncUDPSocket::SetError(int error) { - return socket_->SetError(error); -} - -void AsyncUDPSocket::OnReadEvent(AsyncSocket* socket) { - ASSERT(socket_.get() == socket); - - SocketAddress remote_addr; - int len = socket_->RecvFrom(buf_, size_, &remote_addr); - if (len < 0) { - // An error here typically means we got an ICMP error in response to our - // send datagram, indicating the remote address was unreachable. - // When doing ICE, this kind of thing will often happen. - // TODO: Do something better like forwarding the error to the user. - SocketAddress local_addr = socket_->GetLocalAddress(); - LOG(LS_INFO) << "AsyncUDPSocket[" << local_addr.ToSensitiveString() << "] " - << "receive failed with error " << socket_->GetError(); - return; - } - - // TODO: Make sure that we got all of the packet. - // If we did not, then we should resize our buffer to be large enough. - SignalReadPacket(this, buf_, static_cast(len), remote_addr, - CreatePacketTime(0)); -} - -void AsyncUDPSocket::OnWriteEvent(AsyncSocket* socket) { - SignalReadyToSend(this); -} - -} // namespace rtc diff --git a/webrtc/base/asyncudpsocket.h b/webrtc/base/asyncudpsocket.h deleted file mode 100644 index ac64dca68..000000000 --- a/webrtc/base/asyncudpsocket.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCUDPSOCKET_H_ -#define WEBRTC_BASE_ASYNCUDPSOCKET_H_ - -#include "webrtc/base/asyncpacketsocket.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/socketfactory.h" - -namespace rtc { - -// Provides the ability to receive packets asynchronously. Sends are not -// buffered since it is acceptable to drop packets under high load. -class AsyncUDPSocket : public AsyncPacketSocket { - public: - // Binds |socket| and creates AsyncUDPSocket for it. Takes ownership - // of |socket|. Returns NULL if bind() fails (|socket| is destroyed - // in that case). - static AsyncUDPSocket* Create(AsyncSocket* socket, - const SocketAddress& bind_address); - // Creates a new socket for sending asynchronous UDP packets using an - // asynchronous socket from the given factory. - static AsyncUDPSocket* Create(SocketFactory* factory, - const SocketAddress& bind_address); - explicit AsyncUDPSocket(AsyncSocket* socket); - virtual ~AsyncUDPSocket(); - - virtual SocketAddress GetLocalAddress() const; - virtual SocketAddress GetRemoteAddress() const; - virtual int Send(const void *pv, size_t cb, - const rtc::PacketOptions& options); - virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr, - const rtc::PacketOptions& options); - virtual int Close(); - - virtual State GetState() const; - virtual int GetOption(Socket::Option opt, int* value); - virtual int SetOption(Socket::Option opt, int value); - virtual int GetError() const; - virtual void SetError(int error); - - private: - // Called when the underlying socket is ready to be read from. - void OnReadEvent(AsyncSocket* socket); - // Called when the underlying socket is ready to send. - void OnWriteEvent(AsyncSocket* socket); - - scoped_ptr socket_; - char* buf_; - size_t size_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_ASYNCUDPSOCKET_H_ diff --git a/webrtc/base/asyncudpsocket_unittest.cc b/webrtc/base/asyncudpsocket_unittest.cc deleted file mode 100644 index bd65940fc..000000000 --- a/webrtc/base/asyncudpsocket_unittest.cc +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/asyncudpsocket.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/physicalsocketserver.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/virtualsocketserver.h" - -namespace rtc { - -class AsyncUdpSocketTest - : public testing::Test, - public sigslot::has_slots<> { - public: - AsyncUdpSocketTest() - : pss_(new rtc::PhysicalSocketServer), - vss_(new rtc::VirtualSocketServer(pss_.get())), - socket_(vss_->CreateAsyncSocket(SOCK_DGRAM)), - udp_socket_(new AsyncUDPSocket(socket_)), - ready_to_send_(false) { - udp_socket_->SignalReadyToSend.connect(this, - &AsyncUdpSocketTest::OnReadyToSend); - } - - void OnReadyToSend(rtc::AsyncPacketSocket* socket) { - ready_to_send_ = true; - } - - protected: - scoped_ptr pss_; - scoped_ptr vss_; - AsyncSocket* socket_; - scoped_ptr udp_socket_; - bool ready_to_send_; -}; - -TEST_F(AsyncUdpSocketTest, OnWriteEvent) { - EXPECT_FALSE(ready_to_send_); - socket_->SignalWriteEvent(socket_); - EXPECT_TRUE(ready_to_send_); -} - -} // namespace rtc diff --git a/webrtc/base/atomicops.h b/webrtc/base/atomicops.h deleted file mode 100644 index 6096e8c08..000000000 --- a/webrtc/base/atomicops.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ATOMICOPS_H_ -#define WEBRTC_BASE_ATOMICOPS_H_ - -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/scoped_ptr.h" - -namespace rtc { - -// A single-producer, single-consumer, fixed-size queue. -// All methods not ending in Unsafe can be safely called without locking, -// provided that calls to consumer methods (Peek/Pop) or producer methods (Push) -// only happen on a single thread per method type. If multiple threads need to -// read simultaneously or write simultaneously, other synchronization is -// necessary. Synchronization is also required if a call into any Unsafe method -// could happen at the same time as a call to any other method. -template -class FixedSizeLockFreeQueue { - private: -// Atomic primitives and memory barrier -#if defined(__arm__) - typedef uint32 Atomic32; - - // Copied from google3/base/atomicops-internals-arm-v6plus.h - static inline void MemoryBarrier() { - asm volatile("dmb":::"memory"); - } - - // Adapted from google3/base/atomicops-internals-arm-v6plus.h - static inline void AtomicIncrement(volatile Atomic32* ptr) { - Atomic32 str_success, value; - asm volatile ( - "1:\n" - "ldrex %1, [%2]\n" - "add %1, %1, #1\n" - "strex %0, %1, [%2]\n" - "teq %0, #0\n" - "bne 1b" - : "=&r"(str_success), "=&r"(value) - : "r" (ptr) - : "cc", "memory"); - } -#elif !defined(SKIP_ATOMIC_CHECK) -#error "No atomic operations defined for the given architecture." -#endif - - public: - // Constructs an empty queue, with capacity 0. - FixedSizeLockFreeQueue() : pushed_count_(0), - popped_count_(0), - capacity_(0), - data_() {} - // Constructs an empty queue with the given capacity. - FixedSizeLockFreeQueue(size_t capacity) : pushed_count_(0), - popped_count_(0), - capacity_(capacity), - data_(new T[capacity]) {} - - // Pushes a value onto the queue. Returns true if the value was successfully - // pushed (there was space in the queue). This method can be safely called at - // the same time as PeekFront/PopFront. - bool PushBack(T value) { - if (capacity_ == 0) { - LOG(LS_WARNING) << "Queue capacity is 0."; - return false; - } - if (IsFull()) { - return false; - } - - data_[pushed_count_ % capacity_] = value; - // Make sure the data is written before the count is incremented, so other - // threads can't see the value exists before being able to read it. - MemoryBarrier(); - AtomicIncrement(&pushed_count_); - return true; - } - - // Retrieves the oldest value pushed onto the queue. Returns true if there was - // an item to peek (the queue was non-empty). This method can be safely called - // at the same time as PushBack. - bool PeekFront(T* value_out) { - if (capacity_ == 0) { - LOG(LS_WARNING) << "Queue capacity is 0."; - return false; - } - if (IsEmpty()) { - return false; - } - - *value_out = data_[popped_count_ % capacity_]; - return true; - } - - // Retrieves the oldest value pushed onto the queue and removes it from the - // queue. Returns true if there was an item to pop (the queue was non-empty). - // This method can be safely called at the same time as PushBack. - bool PopFront(T* value_out) { - if (PeekFront(value_out)) { - AtomicIncrement(&popped_count_); - return true; - } - return false; - } - - // Clears the current items in the queue and sets the new (fixed) size. This - // method cannot be called at the same time as any other method. - void ClearAndResizeUnsafe(int new_capacity) { - capacity_ = new_capacity; - data_.reset(new T[new_capacity]); - pushed_count_ = 0; - popped_count_ = 0; - } - - // Returns true if there is no space left in the queue for new elements. - int IsFull() const { return pushed_count_ == popped_count_ + capacity_; } - // Returns true if there are no elements in the queue. - int IsEmpty() const { return pushed_count_ == popped_count_; } - // Returns the current number of elements in the queue. This is always in the - // range [0, capacity] - size_t Size() const { return pushed_count_ - popped_count_; } - - // Returns the capacity of the queue (max size). - size_t capacity() const { return capacity_; } - - private: - volatile Atomic32 pushed_count_; - volatile Atomic32 popped_count_; - size_t capacity_; - rtc::scoped_ptr data_; - DISALLOW_COPY_AND_ASSIGN(FixedSizeLockFreeQueue); -}; - -} - -#endif // WEBRTC_BASE_ATOMICOPS_H_ diff --git a/webrtc/base/atomicops_unittest.cc b/webrtc/base/atomicops_unittest.cc deleted file mode 100644 index 5152c4de6..000000000 --- a/webrtc/base/atomicops_unittest.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if !defined(__arm__) -// For testing purposes, define faked versions of the atomic operations -#include "webrtc/base/basictypes.h" -namespace rtc { -typedef uint32 Atomic32; -static inline void MemoryBarrier() { } -static inline void AtomicIncrement(volatile Atomic32* ptr) { - *ptr = *ptr + 1; -} -} -#define SKIP_ATOMIC_CHECK -#endif - -#include "webrtc/base/atomicops.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/helpers.h" -#include "webrtc/base/logging.h" - -TEST(FixedSizeLockFreeQueueTest, TestDefaultConstruct) { - rtc::FixedSizeLockFreeQueue queue; - EXPECT_EQ(0u, queue.capacity()); - EXPECT_EQ(0u, queue.Size()); - EXPECT_FALSE(queue.PushBack(1)); - int val; - EXPECT_FALSE(queue.PopFront(&val)); -} - -TEST(FixedSizeLockFreeQueueTest, TestConstruct) { - rtc::FixedSizeLockFreeQueue queue(5); - EXPECT_EQ(5u, queue.capacity()); - EXPECT_EQ(0u, queue.Size()); - int val; - EXPECT_FALSE(queue.PopFront(&val)); -} - -TEST(FixedSizeLockFreeQueueTest, TestPushPop) { - rtc::FixedSizeLockFreeQueue queue(2); - EXPECT_EQ(2u, queue.capacity()); - EXPECT_EQ(0u, queue.Size()); - EXPECT_TRUE(queue.PushBack(1)); - EXPECT_EQ(1u, queue.Size()); - EXPECT_TRUE(queue.PushBack(2)); - EXPECT_EQ(2u, queue.Size()); - EXPECT_FALSE(queue.PushBack(3)); - EXPECT_EQ(2u, queue.Size()); - int val; - EXPECT_TRUE(queue.PopFront(&val)); - EXPECT_EQ(1, val); - EXPECT_EQ(1u, queue.Size()); - EXPECT_TRUE(queue.PopFront(&val)); - EXPECT_EQ(2, val); - EXPECT_EQ(0u, queue.Size()); - EXPECT_FALSE(queue.PopFront(&val)); - EXPECT_EQ(0u, queue.Size()); -} - -TEST(FixedSizeLockFreeQueueTest, TestResize) { - rtc::FixedSizeLockFreeQueue queue(2); - EXPECT_EQ(2u, queue.capacity()); - EXPECT_EQ(0u, queue.Size()); - EXPECT_TRUE(queue.PushBack(1)); - EXPECT_EQ(1u, queue.Size()); - - queue.ClearAndResizeUnsafe(5); - EXPECT_EQ(5u, queue.capacity()); - EXPECT_EQ(0u, queue.Size()); - int val; - EXPECT_FALSE(queue.PopFront(&val)); -} diff --git a/webrtc/base/autodetectproxy.cc b/webrtc/base/autodetectproxy.cc deleted file mode 100644 index bc54b9638..000000000 --- a/webrtc/base/autodetectproxy.cc +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/autodetectproxy.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/httpcommon-inl.h" -#include "webrtc/base/nethelpers.h" - -namespace rtc { - -static const ProxyType TEST_ORDER[] = { - PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN -}; - -static const int kSavedStringLimit = 128; - -static void SaveStringToStack(char *dst, - const std::string &src, - size_t dst_size) { - strncpy(dst, src.c_str(), dst_size - 1); - dst[dst_size - 1] = '\0'; -} - -AutoDetectProxy::AutoDetectProxy(const std::string& user_agent) - : agent_(user_agent), resolver_(NULL), socket_(NULL), next_(0) { -} - -AutoDetectProxy::~AutoDetectProxy() { - if (resolver_) { - resolver_->Destroy(false); - } -} - -void AutoDetectProxy::DoWork() { - // TODO: Try connecting to server_url without proxy first here? - if (!server_url_.empty()) { - LOG(LS_INFO) << "GetProxySettingsForUrl(" << server_url_ << ") - start"; - GetProxyForUrl(agent_.c_str(), server_url_.c_str(), &proxy_); - LOG(LS_INFO) << "GetProxySettingsForUrl - stop"; - } - Url url(proxy_.address.HostAsURIString()); - if (url.valid()) { - LOG(LS_WARNING) << "AutoDetectProxy removing http prefix on proxy host"; - proxy_.address.SetIP(url.host()); - } - LOG(LS_INFO) << "AutoDetectProxy found proxy at " << proxy_.address; - if (proxy_.type == PROXY_UNKNOWN) { - LOG(LS_INFO) << "AutoDetectProxy initiating proxy classification"; - Next(); - // Process I/O until Stop() - Thread::Current()->ProcessMessages(kForever); - // Clean up the autodetect socket, from the thread that created it - delete socket_; - } - // TODO: If we found a proxy, try to use it to verify that it - // works by sending a request to server_url. This could either be - // done here or by the HttpPortAllocator. -} - -void AutoDetectProxy::OnMessage(Message *msg) { - if (MSG_UNRESOLVABLE == msg->message_id) { - // If we can't resolve the proxy, skip straight to failure. - Complete(PROXY_UNKNOWN); - } else if (MSG_TIMEOUT == msg->message_id) { - OnCloseEvent(socket_, ETIMEDOUT); - } else { - // This must be the ST_MSG_WORKER_DONE message that deletes the - // AutoDetectProxy object. We have observed crashes within this stack that - // seem to be highly reproducible for a small subset of users and thus are - // probably correlated with a specific proxy setting, so copy potentially - // relevant information onto the stack to make it available in Windows - // minidumps. - - // Save the user agent and the number of auto-detection passes that we - // needed. - char agent[kSavedStringLimit]; - SaveStringToStack(agent, agent_, sizeof agent); - - int next = next_; - - // Now the detected proxy config (minus the password field, which could be - // sensitive). - ProxyType type = proxy().type; - - char address_hostname[kSavedStringLimit]; - SaveStringToStack(address_hostname, - proxy().address.hostname(), - sizeof address_hostname); - - IPAddress address_ip = proxy().address.ipaddr(); - - uint16 address_port = proxy().address.port(); - - char autoconfig_url[kSavedStringLimit]; - SaveStringToStack(autoconfig_url, - proxy().autoconfig_url, - sizeof autoconfig_url); - - bool autodetect = proxy().autodetect; - - char bypass_list[kSavedStringLimit]; - SaveStringToStack(bypass_list, proxy().bypass_list, sizeof bypass_list); - - char username[kSavedStringLimit]; - SaveStringToStack(username, proxy().username, sizeof username); - - SignalThread::OnMessage(msg); - - // Log the gathered data at a log level that will never actually be enabled - // so that the compiler is forced to retain the data on the stack. - LOG(LS_SENSITIVE) << agent << " " << next << " " << type << " " - << address_hostname << " " << address_ip << " " - << address_port << " " << autoconfig_url << " " - << autodetect << " " << bypass_list << " " << username; - } -} - -void AutoDetectProxy::OnResolveResult(AsyncResolverInterface* resolver) { - if (resolver != resolver_) { - return; - } - int error = resolver_->GetError(); - if (error == 0) { - LOG(LS_VERBOSE) << "Resolved " << proxy_.address << " to " - << resolver_->address(); - proxy_.address = resolver_->address(); - if (!DoConnect()) { - Thread::Current()->Post(this, MSG_TIMEOUT); - } - } else { - LOG(LS_INFO) << "Failed to resolve " << resolver_->address(); - resolver_->Destroy(false); - resolver_ = NULL; - proxy_.address = SocketAddress(); - Thread::Current()->Post(this, MSG_UNRESOLVABLE); - } -} - -void AutoDetectProxy::Next() { - if (TEST_ORDER[next_] >= PROXY_UNKNOWN) { - Complete(PROXY_UNKNOWN); - return; - } - - LOG(LS_VERBOSE) << "AutoDetectProxy connecting to " - << proxy_.address.ToSensitiveString(); - - if (socket_) { - Thread::Current()->Clear(this, MSG_TIMEOUT); - Thread::Current()->Clear(this, MSG_UNRESOLVABLE); - socket_->Close(); - Thread::Current()->Dispose(socket_); - socket_ = NULL; - } - int timeout = 2000; - if (proxy_.address.IsUnresolvedIP()) { - // Launch an asyncresolver. This thread will spin waiting for it. - timeout += 2000; - if (!resolver_) { - resolver_ = new AsyncResolver(); - } - resolver_->SignalDone.connect(this, &AutoDetectProxy::OnResolveResult); - resolver_->Start(proxy_.address); - } else { - if (!DoConnect()) { - Thread::Current()->Post(this, MSG_TIMEOUT); - return; - } - } - Thread::Current()->PostDelayed(timeout, this, MSG_TIMEOUT); -} - -bool AutoDetectProxy::DoConnect() { - if (resolver_) { - resolver_->Destroy(false); - resolver_ = NULL; - } - socket_ = - Thread::Current()->socketserver()->CreateAsyncSocket( - proxy_.address.family(), SOCK_STREAM); - if (!socket_) { - LOG(LS_VERBOSE) << "Unable to create socket for " << proxy_.address; - return false; - } - socket_->SignalConnectEvent.connect(this, &AutoDetectProxy::OnConnectEvent); - socket_->SignalReadEvent.connect(this, &AutoDetectProxy::OnReadEvent); - socket_->SignalCloseEvent.connect(this, &AutoDetectProxy::OnCloseEvent); - socket_->Connect(proxy_.address); - return true; -} - -void AutoDetectProxy::Complete(ProxyType type) { - Thread::Current()->Clear(this, MSG_TIMEOUT); - Thread::Current()->Clear(this, MSG_UNRESOLVABLE); - if (socket_) { - socket_->Close(); - } - - proxy_.type = type; - LoggingSeverity sev = (proxy_.type == PROXY_UNKNOWN) ? LS_ERROR : LS_INFO; - LOG_V(sev) << "AutoDetectProxy detected " - << proxy_.address.ToSensitiveString() - << " as type " << proxy_.type; - - Thread::Current()->Quit(); -} - -void AutoDetectProxy::OnConnectEvent(AsyncSocket * socket) { - std::string probe; - - switch (TEST_ORDER[next_]) { - case PROXY_HTTPS: - probe.assign("CONNECT www.google.com:443 HTTP/1.0\r\n" - "User-Agent: "); - probe.append(agent_); - probe.append("\r\n" - "Host: www.google.com\r\n" - "Content-Length: 0\r\n" - "Proxy-Connection: Keep-Alive\r\n" - "\r\n"); - break; - case PROXY_SOCKS5: - probe.assign("\005\001\000", 3); - break; - default: - ASSERT(false); - return; - } - - LOG(LS_VERBOSE) << "AutoDetectProxy probing type " << TEST_ORDER[next_] - << " sending " << probe.size() << " bytes"; - socket_->Send(probe.data(), probe.size()); -} - -void AutoDetectProxy::OnReadEvent(AsyncSocket * socket) { - char data[257]; - int len = socket_->Recv(data, 256); - if (len > 0) { - data[len] = 0; - LOG(LS_VERBOSE) << "AutoDetectProxy read " << len << " bytes"; - } - - switch (TEST_ORDER[next_]) { - case PROXY_HTTPS: - if ((len >= 2) && (data[0] == '\x05')) { - Complete(PROXY_SOCKS5); - return; - } - if ((len >= 5) && (strncmp(data, "HTTP/", 5) == 0)) { - Complete(PROXY_HTTPS); - return; - } - break; - case PROXY_SOCKS5: - if ((len >= 2) && (data[0] == '\x05')) { - Complete(PROXY_SOCKS5); - return; - } - break; - default: - ASSERT(false); - return; - } - - ++next_; - Next(); -} - -void AutoDetectProxy::OnCloseEvent(AsyncSocket * socket, int error) { - LOG(LS_VERBOSE) << "AutoDetectProxy closed with error: " << error; - ++next_; - Next(); -} - -} // namespace rtc diff --git a/webrtc/base/autodetectproxy.h b/webrtc/base/autodetectproxy.h deleted file mode 100644 index 45e9c40be..000000000 --- a/webrtc/base/autodetectproxy.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_AUTODETECTPROXY_H_ -#define WEBRTC_BASE_AUTODETECTPROXY_H_ - -#include - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/cryptstring.h" -#include "webrtc/base/proxydetect.h" -#include "webrtc/base/proxyinfo.h" -#include "webrtc/base/signalthread.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// AutoDetectProxy -/////////////////////////////////////////////////////////////////////////////// - -class AsyncResolverInterface; -class AsyncSocket; - -class AutoDetectProxy : public SignalThread { - public: - explicit AutoDetectProxy(const std::string& user_agent); - - const ProxyInfo& proxy() const { return proxy_; } - - void set_server_url(const std::string& url) { - server_url_ = url; - } - void set_proxy(const SocketAddress& proxy) { - proxy_.type = PROXY_UNKNOWN; - proxy_.address = proxy; - } - void set_auth_info(bool use_auth, const std::string& username, - const CryptString& password) { - if (use_auth) { - proxy_.username = username; - proxy_.password = password; - } - } - // Default implementation of GetProxySettingsForUrl. Override for special - // implementation. - virtual bool GetProxyForUrl(const char* agent, const char* url, - rtc::ProxyInfo* proxy) { - return GetProxySettingsForUrl(agent, url, proxy, true); - } - enum { MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE, - MSG_UNRESOLVABLE, - ADP_MSG_FIRST_AVAILABLE}; - - protected: - virtual ~AutoDetectProxy(); - - // SignalThread Interface - virtual void DoWork(); - virtual void OnMessage(Message *msg); - - void Next(); - void Complete(ProxyType type); - - void OnConnectEvent(AsyncSocket * socket); - void OnReadEvent(AsyncSocket * socket); - void OnCloseEvent(AsyncSocket * socket, int error); - void OnResolveResult(AsyncResolverInterface* resolver); - bool DoConnect(); - - private: - std::string agent_; - std::string server_url_; - ProxyInfo proxy_; - AsyncResolverInterface* resolver_; - AsyncSocket* socket_; - int next_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(AutoDetectProxy); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_AUTODETECTPROXY_H_ diff --git a/webrtc/base/autodetectproxy_unittest.cc b/webrtc/base/autodetectproxy_unittest.cc deleted file mode 100644 index 80f220f2f..000000000 --- a/webrtc/base/autodetectproxy_unittest.cc +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/autodetectproxy.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/httpcommon-inl.h" - -namespace rtc { - -static const char kUserAgent[] = ""; -static const char kPath[] = "/"; -static const char kHost[] = "relay.google.com"; -static const uint16 kPort = 443; -static const bool kSecure = true; -// At most, AutoDetectProxy should take ~6 seconds. Each connect step is -// allotted 2 seconds, with the initial resolution + connect given an -// extra 2 seconds. The slowest case is: -// 1) Resolution + HTTPS takes full 4 seconds and fails (but resolution -// succeeds). -// 2) SOCKS5 takes the full 2 seconds. -// Socket creation time seems unbounded, and has been observed to take >1 second -// on a linux machine under load. As such, we allow for 10 seconds for timeout, -// though could still end up with some flakiness. -static const int kTimeoutMs = 10000; - -class AutoDetectProxyTest : public testing::Test, public sigslot::has_slots<> { - public: - AutoDetectProxyTest() : auto_detect_proxy_(NULL), done_(false) {} - - protected: - bool Create(const std::string &user_agent, - const std::string &path, - const std::string &host, - uint16 port, - bool secure, - bool startnow) { - auto_detect_proxy_ = new AutoDetectProxy(user_agent); - EXPECT_TRUE(auto_detect_proxy_ != NULL); - if (!auto_detect_proxy_) { - return false; - } - Url host_url(path, host, port); - host_url.set_secure(secure); - auto_detect_proxy_->set_server_url(host_url.url()); - auto_detect_proxy_->SignalWorkDone.connect( - this, - &AutoDetectProxyTest::OnWorkDone); - if (startnow) { - auto_detect_proxy_->Start(); - } - return true; - } - - bool Run(int timeout_ms) { - EXPECT_TRUE_WAIT(done_, timeout_ms); - return done_; - } - - void SetProxy(const SocketAddress& proxy) { - auto_detect_proxy_->set_proxy(proxy); - } - - void Start() { - auto_detect_proxy_->Start(); - } - - void TestCopesWithProxy(const SocketAddress& proxy) { - // Tests that at least autodetect doesn't crash for a given proxy address. - ASSERT_TRUE(Create(kUserAgent, - kPath, - kHost, - kPort, - kSecure, - false)); - SetProxy(proxy); - Start(); - ASSERT_TRUE(Run(kTimeoutMs)); - } - - private: - void OnWorkDone(rtc::SignalThread *thread) { - AutoDetectProxy *auto_detect_proxy = - static_cast(thread); - EXPECT_TRUE(auto_detect_proxy == auto_detect_proxy_); - auto_detect_proxy_ = NULL; - auto_detect_proxy->Release(); - done_ = true; - } - - AutoDetectProxy *auto_detect_proxy_; - bool done_; -}; - -TEST_F(AutoDetectProxyTest, TestDetectUnresolvedProxy) { - TestCopesWithProxy(rtc::SocketAddress("localhost", 9999)); -} - -TEST_F(AutoDetectProxyTest, TestDetectUnresolvableProxy) { - TestCopesWithProxy(rtc::SocketAddress("invalid", 9999)); -} - -TEST_F(AutoDetectProxyTest, TestDetectIPv6Proxy) { - TestCopesWithProxy(rtc::SocketAddress("::1", 9999)); -} - -TEST_F(AutoDetectProxyTest, TestDetectIPv4Proxy) { - TestCopesWithProxy(rtc::SocketAddress("127.0.0.1", 9999)); -} - -// Test that proxy detection completes successfully. (Does not actually verify -// the correct detection result since we don't know what proxy to expect on an -// arbitrary machine.) -TEST_F(AutoDetectProxyTest, TestProxyDetection) { - ASSERT_TRUE(Create(kUserAgent, - kPath, - kHost, - kPort, - kSecure, - true)); - ASSERT_TRUE(Run(kTimeoutMs)); -} - -} // namespace rtc diff --git a/webrtc/base/bandwidthsmoother.cc b/webrtc/base/bandwidthsmoother.cc deleted file mode 100644 index 0cbf3f3d1..000000000 --- a/webrtc/base/bandwidthsmoother.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/bandwidthsmoother.h" - -#include - -namespace rtc { - -BandwidthSmoother::BandwidthSmoother(int initial_bandwidth_guess, - uint32 time_between_increase, - double percent_increase, - size_t samples_count_to_average, - double min_sample_count_percent) - : time_between_increase_(time_between_increase), - percent_increase_(rtc::_max(1.0, percent_increase)), - time_at_last_change_(0), - bandwidth_estimation_(initial_bandwidth_guess), - accumulator_(samples_count_to_average), - min_sample_count_percent_( - rtc::_min(1.0, - rtc::_max(0.0, min_sample_count_percent))) { -} - -// Samples a new bandwidth measurement -// returns true if the bandwidth estimation changed -bool BandwidthSmoother::Sample(uint32 sample_time, int bandwidth) { - if (bandwidth < 0) { - return false; - } - - accumulator_.AddSample(bandwidth); - - if (accumulator_.count() < static_cast( - accumulator_.max_count() * min_sample_count_percent_)) { - // We have not collected enough samples yet. - return false; - } - - // Replace bandwidth with the mean of sampled bandwidths. - const int mean_bandwidth = static_cast(accumulator_.ComputeMean()); - - if (mean_bandwidth < bandwidth_estimation_) { - time_at_last_change_ = sample_time; - bandwidth_estimation_ = mean_bandwidth; - return true; - } - - const int old_bandwidth_estimation = bandwidth_estimation_; - const double increase_threshold_d = percent_increase_ * bandwidth_estimation_; - if (increase_threshold_d > INT_MAX) { - // If bandwidth goes any higher we would overflow. - return false; - } - - const int increase_threshold = static_cast(increase_threshold_d); - if (mean_bandwidth < increase_threshold) { - time_at_last_change_ = sample_time; - // The value of bandwidth_estimation remains the same if we don't exceed - // percent_increase_ * bandwidth_estimation_ for at least - // time_between_increase_ time. - } else if (sample_time >= time_at_last_change_ + time_between_increase_) { - time_at_last_change_ = sample_time; - if (increase_threshold == 0) { - // Bandwidth_estimation_ must be zero. Assume a jump from zero to a - // positive bandwidth means we have regained connectivity. - bandwidth_estimation_ = mean_bandwidth; - } else { - bandwidth_estimation_ = increase_threshold; - } - } - // Else don't make a change. - - return old_bandwidth_estimation != bandwidth_estimation_; -} - -} // namespace rtc diff --git a/webrtc/base/bandwidthsmoother.h b/webrtc/base/bandwidthsmoother.h deleted file mode 100644 index cf5a25dfa..000000000 --- a/webrtc/base/bandwidthsmoother.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_BANDWIDTHSMOOTHER_H_ -#define WEBRTC_BASE_BANDWIDTHSMOOTHER_H_ - -#include "webrtc/base/rollingaccumulator.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { - -// The purpose of BandwidthSmoother is to smooth out bandwidth -// estimations so that 'trstate' messages can be triggered when we -// are "sure" there is sufficient bandwidth. To avoid frequent fluctuations, -// we take a slightly pessimistic view of our bandwidth. We only increase -// our estimation when we have sampled bandwidth measurements of values -// at least as large as the current estimation * percent_increase -// for at least time_between_increase time. If a sampled bandwidth -// is less than our current estimation we immediately decrease our estimation -// to that sampled value. -// We retain the initial bandwidth guess as our current bandwidth estimation -// until we have received (min_sample_count_percent * samples_count_to_average) -// number of samples. Min_sample_count_percent must be in range [0, 1]. -class BandwidthSmoother { - public: - BandwidthSmoother(int initial_bandwidth_guess, - uint32 time_between_increase, - double percent_increase, - size_t samples_count_to_average, - double min_sample_count_percent); - - // Samples a new bandwidth measurement. - // bandwidth is expected to be non-negative. - // returns true if the bandwidth estimation changed - bool Sample(uint32 sample_time, int bandwidth); - - int get_bandwidth_estimation() const { - return bandwidth_estimation_; - } - - private: - uint32 time_between_increase_; - double percent_increase_; - uint32 time_at_last_change_; - int bandwidth_estimation_; - RollingAccumulator accumulator_; - double min_sample_count_percent_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_BANDWIDTHSMOOTHER_H_ diff --git a/webrtc/base/bandwidthsmoother_unittest.cc b/webrtc/base/bandwidthsmoother_unittest.cc deleted file mode 100644 index 132c0b13a..000000000 --- a/webrtc/base/bandwidthsmoother_unittest.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/bandwidthsmoother.h" -#include "webrtc/base/gunit.h" - -namespace rtc { - -static const int kTimeBetweenIncrease = 10; -static const double kPercentIncrease = 1.1; -static const size_t kSamplesCountToAverage = 2; -static const double kMinSampleCountPercent = 1.0; - -TEST(BandwidthSmootherTest, TestSampleIncrease) { - BandwidthSmoother mon(1000, // initial_bandwidth_guess - kTimeBetweenIncrease, - kPercentIncrease, - kSamplesCountToAverage, - kMinSampleCountPercent); - - int bandwidth_sample = 1000; - EXPECT_EQ(bandwidth_sample, mon.get_bandwidth_estimation()); - bandwidth_sample = - static_cast(bandwidth_sample * kPercentIncrease); - EXPECT_FALSE(mon.Sample(9, bandwidth_sample)); - EXPECT_TRUE(mon.Sample(10, bandwidth_sample)); - EXPECT_EQ(bandwidth_sample, mon.get_bandwidth_estimation()); - int next_expected_est = - static_cast(bandwidth_sample * kPercentIncrease); - bandwidth_sample *= 2; - EXPECT_TRUE(mon.Sample(20, bandwidth_sample)); - EXPECT_EQ(next_expected_est, mon.get_bandwidth_estimation()); -} - -TEST(BandwidthSmootherTest, TestSampleIncreaseFromZero) { - BandwidthSmoother mon(0, // initial_bandwidth_guess - kTimeBetweenIncrease, - kPercentIncrease, - kSamplesCountToAverage, - kMinSampleCountPercent); - - const int kBandwidthSample = 1000; - EXPECT_EQ(0, mon.get_bandwidth_estimation()); - EXPECT_FALSE(mon.Sample(9, kBandwidthSample)); - EXPECT_TRUE(mon.Sample(10, kBandwidthSample)); - EXPECT_EQ(kBandwidthSample, mon.get_bandwidth_estimation()); -} - -TEST(BandwidthSmootherTest, TestSampleDecrease) { - BandwidthSmoother mon(1000, // initial_bandwidth_guess - kTimeBetweenIncrease, - kPercentIncrease, - kSamplesCountToAverage, - kMinSampleCountPercent); - - const int kBandwidthSample = 999; - EXPECT_EQ(1000, mon.get_bandwidth_estimation()); - EXPECT_FALSE(mon.Sample(1, kBandwidthSample)); - EXPECT_EQ(1000, mon.get_bandwidth_estimation()); - EXPECT_TRUE(mon.Sample(2, kBandwidthSample)); - EXPECT_EQ(kBandwidthSample, mon.get_bandwidth_estimation()); -} - -TEST(BandwidthSmootherTest, TestSampleTooFewSamples) { - BandwidthSmoother mon(1000, // initial_bandwidth_guess - kTimeBetweenIncrease, - kPercentIncrease, - 10, // 10 samples. - 0.5); // 5 min samples. - - const int kBandwidthSample = 500; - EXPECT_EQ(1000, mon.get_bandwidth_estimation()); - EXPECT_FALSE(mon.Sample(1, kBandwidthSample)); - EXPECT_FALSE(mon.Sample(2, kBandwidthSample)); - EXPECT_FALSE(mon.Sample(3, kBandwidthSample)); - EXPECT_FALSE(mon.Sample(4, kBandwidthSample)); - EXPECT_EQ(1000, mon.get_bandwidth_estimation()); - EXPECT_TRUE(mon.Sample(5, kBandwidthSample)); - EXPECT_EQ(kBandwidthSample, mon.get_bandwidth_estimation()); -} - -TEST(BandwidthSmootherTest, TestSampleRollover) { - const int kHugeBandwidth = 2000000000; // > INT_MAX/1.1 - BandwidthSmoother mon(kHugeBandwidth, - kTimeBetweenIncrease, - kPercentIncrease, - kSamplesCountToAverage, - kMinSampleCountPercent); - - EXPECT_FALSE(mon.Sample(10, INT_MAX)); - EXPECT_FALSE(mon.Sample(11, INT_MAX)); - EXPECT_EQ(kHugeBandwidth, mon.get_bandwidth_estimation()); -} - -TEST(BandwidthSmootherTest, TestSampleNegative) { - BandwidthSmoother mon(1000, // initial_bandwidth_guess - kTimeBetweenIncrease, - kPercentIncrease, - kSamplesCountToAverage, - kMinSampleCountPercent); - - EXPECT_FALSE(mon.Sample(10, -1)); - EXPECT_FALSE(mon.Sample(11, -1)); - EXPECT_EQ(1000, mon.get_bandwidth_estimation()); -} - -} // namespace rtc diff --git a/webrtc/base/base.gyp b/webrtc/base/base.gyp deleted file mode 100644 index a3cf7706e..000000000 --- a/webrtc/base/base.gyp +++ /dev/null @@ -1,708 +0,0 @@ -# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. - -{ - 'includes': [ '../build/common.gypi', ], - 'conditions': [ - ['os_posix == 1 and OS != "mac" and OS != "ios"', { - 'conditions': [ - ['sysroot!=""', { - 'variables': { - 'pkg-config': '../../../build/linux/pkg-config-wrapper "<(sysroot)" "<(target_arch)"', - }, - }, { - 'variables': { - 'pkg-config': 'pkg-config' - }, - }], - ], - }], - ], - 'targets': [ - { - 'target_name': 'webrtc_base', - 'type': 'static_library', - 'defines': [ - 'FEATURE_ENABLE_SSL', - 'GTEST_RELATIVE_PATH', - 'LOGGING=1', - 'USE_WEBRTC_DEV_BRANCH', - ], - 'sources': [ - 'asyncfile.cc', - 'asyncfile.h', - 'asynchttprequest.cc', - 'asynchttprequest.h', - 'asyncinvoker.cc', - 'asyncinvoker.h', - 'asyncpacketsocket.h', - 'asyncresolverinterface.h', - 'asyncsocket.cc', - 'asyncsocket.h', - 'asynctcpsocket.cc', - 'asynctcpsocket.h', - 'asyncudpsocket.cc', - 'asyncudpsocket.h', - 'atomicops.h', - 'autodetectproxy.cc', - 'autodetectproxy.h', - 'bandwidthsmoother.cc', - 'bandwidthsmoother.h', - 'base64.cc', - 'base64.h', - 'basicdefs.h', - 'basictypes.h', - 'bind.h', - 'buffer.h', - 'bytebuffer.cc', - 'bytebuffer.h', - 'byteorder.h', - 'callback.h', - 'checks.cc', - 'checks.h', - 'common.cc', - 'common.h', - 'constructormagic.h', - 'cpumonitor.cc', - 'cpumonitor.h', - 'crc32.cc', - 'crc32.h', - 'criticalsection.h', - 'cryptstring.h', - 'dbus.cc', - 'dbus.h', - 'diskcache.cc', - 'diskcache.h', - 'diskcache_win32.cc', - 'diskcache_win32.h', - 'event.cc', - 'event.h', - 'filelock.cc', - 'filelock.h', - 'fileutils.cc', - 'fileutils.h', - 'fileutils_mock.h', - 'firewallsocketserver.cc', - 'firewallsocketserver.h', - 'flags.cc', - 'flags.h', - 'gunit_prod.h', - 'helpers.cc', - 'helpers.h', - 'httpbase.cc', - 'httpbase.h', - 'httpclient.cc', - 'httpclient.h', - 'httpcommon-inl.h', - 'httpcommon.cc', - 'httpcommon.h', - 'httprequest.cc', - 'httprequest.h', - 'httpserver.cc', - 'httpserver.h', - 'ifaddrs-android.cc', - 'ifaddrs-android.h', - 'iosfilesystem.mm', - 'ipaddress.cc', - 'ipaddress.h', - 'json.cc', - 'json.h', - 'latebindingsymboltable.cc', - 'latebindingsymboltable.h', - 'libdbusglibsymboltable.cc', - 'libdbusglibsymboltable.h', - 'linux.cc', - 'linux.h', - 'linuxfdwalk.c', - 'linuxwindowpicker.cc', - 'linuxwindowpicker.h', - 'linked_ptr.h', - 'logging.cc', - 'logging.h', - 'macasyncsocket.cc', - 'macasyncsocket.h', - 'maccocoasocketserver.h', - 'maccocoasocketserver.mm', - 'maccocoathreadhelper.h', - 'maccocoathreadhelper.mm', - 'macconversion.cc', - 'macconversion.h', - 'macsocketserver.cc', - 'macsocketserver.h', - 'macutils.cc', - 'macutils.h', - 'macwindowpicker.cc', - 'macwindowpicker.h', - 'mathutils.h', - 'md5.cc', - 'md5.h', - 'md5digest.h', - 'messagedigest.cc', - 'messagedigest.h', - 'messagehandler.cc', - 'messagehandler.h', - 'messagequeue.cc', - 'messagequeue.h', - 'multipart.cc', - 'multipart.h', - 'natserver.cc', - 'natserver.h', - 'natsocketfactory.cc', - 'natsocketfactory.h', - 'nattypes.cc', - 'nattypes.h', - 'nethelpers.cc', - 'nethelpers.h', - 'network.cc', - 'network.h', - 'nssidentity.cc', - 'nssidentity.h', - 'nssstreamadapter.cc', - 'nssstreamadapter.h', - 'nullsocketserver.h', - 'openssl.h', - 'openssladapter.cc', - 'openssladapter.h', - 'openssldigest.cc', - 'openssldigest.h', - 'opensslidentity.cc', - 'opensslidentity.h', - 'opensslstreamadapter.cc', - 'opensslstreamadapter.h', - 'optionsfile.cc', - 'optionsfile.h', - 'pathutils.cc', - 'pathutils.h', - 'physicalsocketserver.cc', - 'physicalsocketserver.h', - 'posix.cc', - 'posix.h', - 'profiler.cc', - 'profiler.h', - 'proxydetect.cc', - 'proxydetect.h', - 'proxyinfo.cc', - 'proxyinfo.h', - 'proxyserver.cc', - 'proxyserver.h', - 'ratelimiter.cc', - 'ratelimiter.h', - 'ratetracker.cc', - 'ratetracker.h', - 'refcount.h', - 'referencecountedsingletonfactory.h', - 'rollingaccumulator.h', - 'schanneladapter.cc', - 'schanneladapter.h', - 'scoped_autorelease_pool.h', - 'scoped_autorelease_pool.mm', - 'scoped_ptr.h', - 'scoped_ref_ptr.h', - 'scopedptrcollection.h', - 'sec_buffer.h', - 'sha1.cc', - 'sha1.h', - 'sha1digest.h', - 'sharedexclusivelock.cc', - 'sharedexclusivelock.h', - 'signalthread.cc', - 'signalthread.h', - 'sigslot.h', - 'sigslotrepeater.h', - 'socket.h', - 'socketadapters.cc', - 'socketadapters.h', - 'socketaddress.cc', - 'socketaddress.h', - 'socketaddresspair.cc', - 'socketaddresspair.h', - 'socketfactory.h', - 'socketpool.cc', - 'socketpool.h', - 'socketserver.h', - 'socketstream.cc', - 'socketstream.h', - 'ssladapter.cc', - 'ssladapter.h', - 'sslconfig.h', - 'sslfingerprint.cc', - 'sslfingerprint.h', - 'sslidentity.cc', - 'sslidentity.h', - 'sslroots.h', - 'sslsocketfactory.cc', - 'sslsocketfactory.h', - 'sslstreamadapter.cc', - 'sslstreamadapter.h', - 'sslstreamadapterhelper.cc', - 'sslstreamadapterhelper.h', - 'stream.cc', - 'stream.h', - 'stringdigest.h', - 'stringencode.cc', - 'stringencode.h', - 'stringutils.cc', - 'stringutils.h', - 'systeminfo.cc', - 'systeminfo.h', - 'task.cc', - 'task.h', - 'taskparent.cc', - 'taskparent.h', - 'taskrunner.cc', - 'taskrunner.h', - 'testclient.cc', - 'testclient.h', - 'thread.cc', - 'thread.h', - 'timeutils.cc', - 'timeutils.h', - 'timing.cc', - 'timing.h', - 'transformadapter.cc', - 'transformadapter.h', - 'unixfilesystem.cc', - 'unixfilesystem.h', - 'urlencode.cc', - 'urlencode.h', - 'versionparsing.cc', - 'versionparsing.h', - 'virtualsocketserver.cc', - 'virtualsocketserver.h', - 'win32.cc', - 'win32.h', - 'win32filesystem.cc', - 'win32filesystem.h', - 'win32regkey.cc', - 'win32regkey.h', - 'win32securityerrors.cc', - 'win32socketinit.cc', - 'win32socketinit.h', - 'win32socketserver.cc', - 'win32socketserver.h', - 'win32window.cc', - 'win32window.h', - 'win32windowpicker.cc', - 'win32windowpicker.h', - 'window.h', - 'windowpicker.h', - 'windowpickerfactory.h', - 'winfirewall.cc', - 'winfirewall.h', - 'winping.cc', - 'winping.h', - 'worker.cc', - 'worker.h', - '../overrides/webrtc/base/basictypes.h', - '../overrides/webrtc/base/constructormagic.h', - '../overrides/webrtc/base/logging.cc', - '../overrides/webrtc/base/logging.h', - '../overrides/webrtc/base/win32socketinit.cc', - ], - # TODO(henrike): issue 3307, make webrtc_base build without disabling - # these flags. - 'cflags!': [ - '-Wextra', - '-Wall', - ], - 'cflags_cc!': [ - '-Wnon-virtual-dtor', - ], - 'direct_dependent_settings': { - 'cflags_cc!': [ - '-Wnon-virtual-dtor', - ], - 'defines': [ - 'FEATURE_ENABLE_SSL', - 'GTEST_RELATIVE_PATH', - ], - }, - 'include_dirs': [ - '../../third_party/jsoncpp/overrides/include', - '../../third_party/jsoncpp/source/include', - ], - 'conditions': [ - ['build_with_chromium==1', { - 'include_dirs': [ - '../overrides', - '../../openssl/openssl/include', - ], - 'sources!': [ - 'asyncinvoker.cc', - 'asyncinvoker.h', - 'asyncinvoker-inl.h', - 'asyncresolverinterface.h', - 'atomicops.h', - 'bandwidthsmoother.cc', - 'bandwidthsmoother.h', - 'basictypes.h', - 'bind.h', - 'bind.h.pump', - 'buffer.h', - 'callback.h', - 'callback.h.pump', - 'constructormagic.h', - 'dbus.cc', - 'dbus.h', - 'diskcache_win32.cc', - 'diskcache_win32.h', - 'fakecpumonitor.h', - 'fakenetwork.h', - 'fakesslidentity.h', - 'faketaskrunner.h', - 'filelock.cc', - 'filelock.h', - 'fileutils_mock.h', - 'genericslot.h', - 'genericslot.h.pump', - 'httpserver.cc', - 'httpserver.h', - 'json.cc', - 'json.h', - 'latebindingsymboltable.cc', - 'latebindingsymboltable.cc.def', - 'latebindingsymboltable.h', - 'latebindingsymboltable.h.def', - 'libdbusglibsymboltable.cc', - 'libdbusglibsymboltable.h', - 'linuxfdwalk.c', - 'linuxfdwalk.h', - 'linuxwindowpicker.cc', - 'linuxwindowpicker.h', - 'logging.cc', - 'logging.h', - 'macasyncsocket.cc', - 'macasyncsocket.h', - 'maccocoasocketserver.h', - 'maccocoasocketserver.mm', - 'macsocketserver.cc', - 'macsocketserver.h', - 'macwindowpicker.cc', - 'macwindowpicker.h', - 'mathutils.h', - 'multipart.cc', - 'multipart.h', - 'natserver.cc', - 'natserver.h', - 'natserver_main.cc', - 'natsocketfactory.cc', - 'natsocketfactory.h', - 'nattypes.cc', - 'nattypes.h', - 'openssl.h', - 'optionsfile.cc', - 'optionsfile.h', - 'posix.cc', - 'posix.h', - 'profiler.cc', - 'profiler.h', - 'proxyserver.cc', - 'proxyserver.h', - 'refcount.h', - 'referencecountedsingletonfactory.h', - 'rollingaccumulator.h', - 'safe_conversions.h', - 'safe_conversions_impl.h', - 'scopedptrcollection.h', - 'scoped_ref_ptr.h', - 'sec_buffer.h', - 'sharedexclusivelock.cc', - 'sharedexclusivelock.h', - 'sslconfig.h', - 'sslroots.h', - 'stringdigest.h', - 'testbase64.h', - 'testclient.cc', - 'testclient.h', - 'testechoserver.h', - 'testutils.h', - 'transformadapter.cc', - 'transformadapter.h', - 'versionparsing.cc', - 'versionparsing.h', - 'virtualsocketserver.cc', - 'virtualsocketserver.h', - 'win32regkey.cc', - 'win32regkey.h', - 'win32socketinit.cc', - 'win32socketinit.h', - 'win32socketserver.cc', - 'win32socketserver.h', - 'win32toolhelp.h', - 'window.h', - 'windowpickerfactory.h', - 'windowpicker.h', - ], - 'defines': [ - 'NO_MAIN_THREAD_WRAPPING', - 'SSL_USE_NSS', - ], - 'direct_dependent_settings': { - 'defines': [ - 'NO_MAIN_THREAD_WRAPPING', - 'SSL_USE_NSS', - ], - }, - }, { - 'dependencies': [ - '<(DEPTH)/third_party/jsoncpp/jsoncpp.gyp:jsoncpp', - ], - 'sources!': [ - '../overrides/webrtc/base/basictypes.h', - '../overrides/webrtc/base/constructormagic.h', - '../overrides/webrtc/base/win32socketinit.cc', - '../overrides/webrtc/base/logging.cc', - '../overrides/webrtc/base/logging.h', - ], - }], - ['use_openssl==1', { - 'defines': [ - 'SSL_USE_OPENSSL', - 'HAVE_OPENSSL_SSL_H', - ], - 'direct_dependent_settings': { - 'defines': [ - 'SSL_USE_OPENSSL', - 'HAVE_OPENSSL_SSL_H', - ], - }, - 'dependencies': [ - '<(DEPTH)/third_party/openssl/openssl.gyp:openssl', - ], - }, { - 'defines': [ - 'SSL_USE_NSS', - 'HAVE_NSS_SSL_H', - 'SSL_USE_NSS_RNG', - ], - 'direct_dependent_settings': { - 'defines': [ - 'SSL_USE_NSS', - 'HAVE_NSS_SSL_H', - 'SSL_USE_NSS_RNG', - ], - }, - }], - ['OS == "android"', { - 'defines': [ - 'HAVE_OPENSSL_SSL_H' - ], - 'direct_dependent_settings': { - 'defines': [ - 'HAVE_OPENSSL_SSL_H' - ], - }, - 'link_settings': { - 'libraries': [ - '-llog', - '-lGLESv2', - ], - }, - }, { - 'defines': [ - 'HAVE_NSS_SSL_H' - 'SSL_USE_NSS_RNG', - ], - 'direct_dependent_settings': { - 'defines': [ - 'HAVE_NSS_SSL_H' - 'SSL_USE_NSS_RNG', - ], - }, - 'sources!': [ - 'ifaddrs-android.cc', - 'ifaddrs-android.h', - ], - }], - ['OS=="ios"', { - 'all_dependent_settings': { - 'xcode_settings': { - 'OTHER_LDFLAGS': [ - '-framework Foundation', - '-framework IOKit', - '-framework Security', - '-framework SystemConfiguration', - '-framework UIKit', - ], - }, - }, - 'dependencies': [ - '<(DEPTH)/net/third_party/nss/ssl.gyp:libssl', - ], - }], - ['OS=="linux"', { - 'link_settings': { - 'libraries': [ - '-lcrypto', - '-ldl', - '-lrt', - '-lXext', - '-lX11', - '-lXcomposite', - '-lXrender', - ' - -#include "webrtc/base/common.h" - -using std::vector; - -namespace rtc { - -static const char kPad = '='; -static const unsigned char pd = 0xFD; // Padding -static const unsigned char sp = 0xFE; // Whitespace -static const unsigned char il = 0xFF; // Illegal base64 character - -const char Base64::Base64Table[] = -// 0000000000111111111122222222223333333333444444444455555555556666 -// 0123456789012345678901234567890123456789012345678901234567890123 - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -// Decode Table gives the index of any valid base64 character in the -// Base64 table -// 65 == A, 97 == a, 48 == 0, 43 == +, 47 == / - -const unsigned char Base64::DecodeTable[] = { -// 0 1 2 3 4 5 6 7 8 9 - il,il,il,il,il,il,il,il,il,sp, // 0 - 9 - sp,sp,sp,sp,il,il,il,il,il,il, // 10 - 19 - il,il,il,il,il,il,il,il,il,il, // 20 - 29 - il,il,sp,il,il,il,il,il,il,il, // 30 - 39 - il,il,il,62,il,il,il,63,52,53, // 40 - 49 - 54,55,56,57,58,59,60,61,il,il, // 50 - 59 - il,pd,il,il,il, 0, 1, 2, 3, 4, // 60 - 69 - 5, 6, 7, 8, 9,10,11,12,13,14, // 70 - 79 - 15,16,17,18,19,20,21,22,23,24, // 80 - 89 - 25,il,il,il,il,il,il,26,27,28, // 90 - 99 - 29,30,31,32,33,34,35,36,37,38, // 100 - 109 - 39,40,41,42,43,44,45,46,47,48, // 110 - 119 - 49,50,51,il,il,il,il,il,il,il, // 120 - 129 - il,il,il,il,il,il,il,il,il,il, // 130 - 139 - il,il,il,il,il,il,il,il,il,il, // 140 - 149 - il,il,il,il,il,il,il,il,il,il, // 150 - 159 - il,il,il,il,il,il,il,il,il,il, // 160 - 169 - il,il,il,il,il,il,il,il,il,il, // 170 - 179 - il,il,il,il,il,il,il,il,il,il, // 180 - 189 - il,il,il,il,il,il,il,il,il,il, // 190 - 199 - il,il,il,il,il,il,il,il,il,il, // 200 - 209 - il,il,il,il,il,il,il,il,il,il, // 210 - 219 - il,il,il,il,il,il,il,il,il,il, // 220 - 229 - il,il,il,il,il,il,il,il,il,il, // 230 - 239 - il,il,il,il,il,il,il,il,il,il, // 240 - 249 - il,il,il,il,il,il // 250 - 255 -}; - -bool Base64::IsBase64Char(char ch) { - return (('A' <= ch) && (ch <= 'Z')) || - (('a' <= ch) && (ch <= 'z')) || - (('0' <= ch) && (ch <= '9')) || - (ch == '+') || (ch == '/'); -} - -bool Base64::GetNextBase64Char(char ch, char* next_ch) { - if (next_ch == NULL) { - return false; - } - const char* p = strchr(Base64Table, ch); - if (!p) - return false; - ++p; - *next_ch = (*p) ? *p : Base64Table[0]; - return true; -} - -bool Base64::IsBase64Encoded(const std::string& str) { - for (size_t i = 0; i < str.size(); ++i) { - if (!IsBase64Char(str.at(i))) - return false; - } - return true; -} - -void Base64::EncodeFromArray(const void* data, size_t len, - std::string* result) { - ASSERT(NULL != result); - result->clear(); - result->resize(((len + 2) / 3) * 4); - const unsigned char* byte_data = static_cast(data); - - unsigned char c; - size_t i = 0; - size_t dest_ix = 0; - while (i < len) { - c = (byte_data[i] >> 2) & 0x3f; - (*result)[dest_ix++] = Base64Table[c]; - - c = (byte_data[i] << 4) & 0x3f; - if (++i < len) { - c |= (byte_data[i] >> 4) & 0x0f; - } - (*result)[dest_ix++] = Base64Table[c]; - - if (i < len) { - c = (byte_data[i] << 2) & 0x3f; - if (++i < len) { - c |= (byte_data[i] >> 6) & 0x03; - } - (*result)[dest_ix++] = Base64Table[c]; - } else { - (*result)[dest_ix++] = kPad; - } - - if (i < len) { - c = byte_data[i] & 0x3f; - (*result)[dest_ix++] = Base64Table[c]; - ++i; - } else { - (*result)[dest_ix++] = kPad; - } - } -} - -size_t Base64::GetNextQuantum(DecodeFlags parse_flags, bool illegal_pads, - const char* data, size_t len, size_t* dpos, - unsigned char qbuf[4], bool* padded) -{ - size_t byte_len = 0, pad_len = 0, pad_start = 0; - for (; (byte_len < 4) && (*dpos < len); ++*dpos) { - qbuf[byte_len] = DecodeTable[static_cast(data[*dpos])]; - if ((il == qbuf[byte_len]) || (illegal_pads && (pd == qbuf[byte_len]))) { - if (parse_flags != DO_PARSE_ANY) - break; - // Ignore illegal characters - } else if (sp == qbuf[byte_len]) { - if (parse_flags == DO_PARSE_STRICT) - break; - // Ignore spaces - } else if (pd == qbuf[byte_len]) { - if (byte_len < 2) { - if (parse_flags != DO_PARSE_ANY) - break; - // Ignore unexpected padding - } else if (byte_len + pad_len >= 4) { - if (parse_flags != DO_PARSE_ANY) - break; - // Ignore extra pads - } else { - if (1 == ++pad_len) { - pad_start = *dpos; - } - } - } else { - if (pad_len > 0) { - if (parse_flags != DO_PARSE_ANY) - break; - // Ignore pads which are followed by data - pad_len = 0; - } - ++byte_len; - } - } - for (size_t i = byte_len; i < 4; ++i) { - qbuf[i] = 0; - } - if (4 == byte_len + pad_len) { - *padded = true; - } else { - *padded = false; - if (pad_len) { - // Roll back illegal padding - *dpos = pad_start; - } - } - return byte_len; -} - -bool Base64::DecodeFromArray(const char* data, size_t len, DecodeFlags flags, - std::string* result, size_t* data_used) { - return DecodeFromArrayTemplate( - data, len, flags, result, data_used); -} - -bool Base64::DecodeFromArray(const char* data, size_t len, DecodeFlags flags, - vector* result, size_t* data_used) { - return DecodeFromArrayTemplate >(data, len, flags, result, - data_used); -} - -template -bool Base64::DecodeFromArrayTemplate(const char* data, size_t len, - DecodeFlags flags, T* result, - size_t* data_used) -{ - ASSERT(NULL != result); - ASSERT(flags <= (DO_PARSE_MASK | DO_PAD_MASK | DO_TERM_MASK)); - - const DecodeFlags parse_flags = flags & DO_PARSE_MASK; - const DecodeFlags pad_flags = flags & DO_PAD_MASK; - const DecodeFlags term_flags = flags & DO_TERM_MASK; - ASSERT(0 != parse_flags); - ASSERT(0 != pad_flags); - ASSERT(0 != term_flags); - - result->clear(); - result->reserve(len); - - size_t dpos = 0; - bool success = true, padded; - unsigned char c, qbuf[4]; - while (dpos < len) { - size_t qlen = GetNextQuantum(parse_flags, (DO_PAD_NO == pad_flags), - data, len, &dpos, qbuf, &padded); - c = (qbuf[0] << 2) | ((qbuf[1] >> 4) & 0x3); - if (qlen >= 2) { - result->push_back(c); - c = ((qbuf[1] << 4) & 0xf0) | ((qbuf[2] >> 2) & 0xf); - if (qlen >= 3) { - result->push_back(c); - c = ((qbuf[2] << 6) & 0xc0) | qbuf[3]; - if (qlen >= 4) { - result->push_back(c); - c = 0; - } - } - } - if (qlen < 4) { - if ((DO_TERM_ANY != term_flags) && (0 != c)) { - success = false; // unused bits - } - if ((DO_PAD_YES == pad_flags) && !padded) { - success = false; // expected padding - } - break; - } - } - if ((DO_TERM_BUFFER == term_flags) && (dpos != len)) { - success = false; // unused chars - } - if (data_used) { - *data_used = dpos; - } - return success; -} - -} // namespace rtc diff --git a/webrtc/base/base64.h b/webrtc/base/base64.h deleted file mode 100644 index d5a7dd84c..000000000 --- a/webrtc/base/base64.h +++ /dev/null @@ -1,104 +0,0 @@ - -//********************************************************************* -//* C_Base64 - a simple base64 encoder and decoder. -//* -//* Copyright (c) 1999, Bob Withers - bwit@pobox.com -//* -//* This code may be freely used for any purpose, either personal -//* or commercial, provided the authors copyright notice remains -//* intact. -//********************************************************************* - -#ifndef WEBRTC_BASE_BASE64_H__ -#define WEBRTC_BASE_BASE64_H__ - -#include -#include - -namespace rtc { - -class Base64 -{ -public: - enum DecodeOption { - DO_PARSE_STRICT = 1, // Parse only base64 characters - DO_PARSE_WHITE = 2, // Parse only base64 and whitespace characters - DO_PARSE_ANY = 3, // Parse all characters - DO_PARSE_MASK = 3, - - DO_PAD_YES = 4, // Padding is required - DO_PAD_ANY = 8, // Padding is optional - DO_PAD_NO = 12, // Padding is disallowed - DO_PAD_MASK = 12, - - DO_TERM_BUFFER = 16, // Must termiante at end of buffer - DO_TERM_CHAR = 32, // May terminate at any character boundary - DO_TERM_ANY = 48, // May terminate at a sub-character bit offset - DO_TERM_MASK = 48, - - // Strictest interpretation - DO_STRICT = DO_PARSE_STRICT | DO_PAD_YES | DO_TERM_BUFFER, - - DO_LAX = DO_PARSE_ANY | DO_PAD_ANY | DO_TERM_CHAR, - }; - typedef int DecodeFlags; - - static bool IsBase64Char(char ch); - - // Get the char next to the |ch| from the Base64Table. - // If the |ch| is the last one in the Base64Table then returns - // the first one from the table. - // Expects the |ch| be a base64 char. - // The result will be saved in |next_ch|. - // Returns true on success. - static bool GetNextBase64Char(char ch, char* next_ch); - - // Determines whether the given string consists entirely of valid base64 - // encoded characters. - static bool IsBase64Encoded(const std::string& str); - - static void EncodeFromArray(const void* data, size_t len, - std::string* result); - static bool DecodeFromArray(const char* data, size_t len, DecodeFlags flags, - std::string* result, size_t* data_used); - static bool DecodeFromArray(const char* data, size_t len, DecodeFlags flags, - std::vector* result, size_t* data_used); - - // Convenience Methods - static inline std::string Encode(const std::string& data) { - std::string result; - EncodeFromArray(data.data(), data.size(), &result); - return result; - } - static inline std::string Decode(const std::string& data, DecodeFlags flags) { - std::string result; - DecodeFromArray(data.data(), data.size(), flags, &result, NULL); - return result; - } - static inline bool Decode(const std::string& data, DecodeFlags flags, - std::string* result, size_t* data_used) - { - return DecodeFromArray(data.data(), data.size(), flags, result, data_used); - } - static inline bool Decode(const std::string& data, DecodeFlags flags, - std::vector* result, size_t* data_used) - { - return DecodeFromArray(data.data(), data.size(), flags, result, data_used); - } - -private: - static const char Base64Table[]; - static const unsigned char DecodeTable[]; - - static size_t GetNextQuantum(DecodeFlags parse_flags, bool illegal_pads, - const char* data, size_t len, size_t* dpos, - unsigned char qbuf[4], bool* padded); - template - static bool DecodeFromArrayTemplate(const char* data, size_t len, - DecodeFlags flags, T* result, - size_t* data_used); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_BASE64_H__ diff --git a/webrtc/base/base64_unittest.cc b/webrtc/base/base64_unittest.cc deleted file mode 100644 index c4d407244..000000000 --- a/webrtc/base/base64_unittest.cc +++ /dev/null @@ -1,1001 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/common.h" -#include "webrtc/base/base64.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/stream.h" - -#include "webrtc/base/testbase64.h" - -using namespace std; -using namespace rtc; - -static struct { - size_t plain_length; - const char* plaintext; - const char* cyphertext; -} base64_tests[] = { - - // Basic bit patterns; - // values obtained with "echo -n '...' | uuencode -m test" - - { 1, "\000", "AA==" }, - { 1, "\001", "AQ==" }, - { 1, "\002", "Ag==" }, - { 1, "\004", "BA==" }, - { 1, "\010", "CA==" }, - { 1, "\020", "EA==" }, - { 1, "\040", "IA==" }, - { 1, "\100", "QA==" }, - { 1, "\200", "gA==" }, - - { 1, "\377", "/w==" }, - { 1, "\376", "/g==" }, - { 1, "\375", "/Q==" }, - { 1, "\373", "+w==" }, - { 1, "\367", "9w==" }, - { 1, "\357", "7w==" }, - { 1, "\337", "3w==" }, - { 1, "\277", "vw==" }, - { 1, "\177", "fw==" }, - { 2, "\000\000", "AAA=" }, - { 2, "\000\001", "AAE=" }, - { 2, "\000\002", "AAI=" }, - { 2, "\000\004", "AAQ=" }, - { 2, "\000\010", "AAg=" }, - { 2, "\000\020", "ABA=" }, - { 2, "\000\040", "ACA=" }, - { 2, "\000\100", "AEA=" }, - { 2, "\000\200", "AIA=" }, - { 2, "\001\000", "AQA=" }, - { 2, "\002\000", "AgA=" }, - { 2, "\004\000", "BAA=" }, - { 2, "\010\000", "CAA=" }, - { 2, "\020\000", "EAA=" }, - { 2, "\040\000", "IAA=" }, - { 2, "\100\000", "QAA=" }, - { 2, "\200\000", "gAA=" }, - - { 2, "\377\377", "//8=" }, - { 2, "\377\376", "//4=" }, - { 2, "\377\375", "//0=" }, - { 2, "\377\373", "//s=" }, - { 2, "\377\367", "//c=" }, - { 2, "\377\357", "/+8=" }, - { 2, "\377\337", "/98=" }, - { 2, "\377\277", "/78=" }, - { 2, "\377\177", "/38=" }, - { 2, "\376\377", "/v8=" }, - { 2, "\375\377", "/f8=" }, - { 2, "\373\377", "+/8=" }, - { 2, "\367\377", "9/8=" }, - { 2, "\357\377", "7/8=" }, - { 2, "\337\377", "3/8=" }, - { 2, "\277\377", "v/8=" }, - { 2, "\177\377", "f/8=" }, - - { 3, "\000\000\000", "AAAA" }, - { 3, "\000\000\001", "AAAB" }, - { 3, "\000\000\002", "AAAC" }, - { 3, "\000\000\004", "AAAE" }, - { 3, "\000\000\010", "AAAI" }, - { 3, "\000\000\020", "AAAQ" }, - { 3, "\000\000\040", "AAAg" }, - { 3, "\000\000\100", "AABA" }, - { 3, "\000\000\200", "AACA" }, - { 3, "\000\001\000", "AAEA" }, - { 3, "\000\002\000", "AAIA" }, - { 3, "\000\004\000", "AAQA" }, - { 3, "\000\010\000", "AAgA" }, - { 3, "\000\020\000", "ABAA" }, - { 3, "\000\040\000", "ACAA" }, - { 3, "\000\100\000", "AEAA" }, - { 3, "\000\200\000", "AIAA" }, - { 3, "\001\000\000", "AQAA" }, - { 3, "\002\000\000", "AgAA" }, - { 3, "\004\000\000", "BAAA" }, - { 3, "\010\000\000", "CAAA" }, - { 3, "\020\000\000", "EAAA" }, - { 3, "\040\000\000", "IAAA" }, - { 3, "\100\000\000", "QAAA" }, - { 3, "\200\000\000", "gAAA" }, - - { 3, "\377\377\377", "////" }, - { 3, "\377\377\376", "///+" }, - { 3, "\377\377\375", "///9" }, - { 3, "\377\377\373", "///7" }, - { 3, "\377\377\367", "///3" }, - { 3, "\377\377\357", "///v" }, - { 3, "\377\377\337", "///f" }, - { 3, "\377\377\277", "//+/" }, - { 3, "\377\377\177", "//9/" }, - { 3, "\377\376\377", "//7/" }, - { 3, "\377\375\377", "//3/" }, - { 3, "\377\373\377", "//v/" }, - { 3, "\377\367\377", "//f/" }, - { 3, "\377\357\377", "/+//" }, - { 3, "\377\337\377", "/9//" }, - { 3, "\377\277\377", "/7//" }, - { 3, "\377\177\377", "/3//" }, - { 3, "\376\377\377", "/v//" }, - { 3, "\375\377\377", "/f//" }, - { 3, "\373\377\377", "+///" }, - { 3, "\367\377\377", "9///" }, - { 3, "\357\377\377", "7///" }, - { 3, "\337\377\377", "3///" }, - { 3, "\277\377\377", "v///" }, - { 3, "\177\377\377", "f///" }, - - // Random numbers: values obtained with - // - // #! /bin/bash - // dd bs=$1 count=1 if=/dev/random of=/tmp/bar.random - // od -N $1 -t o1 /tmp/bar.random - // uuencode -m test < /tmp/bar.random - // - // where $1 is the number of bytes (2, 3) - - { 2, "\243\361", "o/E=" }, - { 2, "\024\167", "FHc=" }, - { 2, "\313\252", "y6o=" }, - { 2, "\046\041", "JiE=" }, - { 2, "\145\236", "ZZ4=" }, - { 2, "\254\325", "rNU=" }, - { 2, "\061\330", "Mdg=" }, - { 2, "\245\032", "pRo=" }, - { 2, "\006\000", "BgA=" }, - { 2, "\375\131", "/Vk=" }, - { 2, "\303\210", "w4g=" }, - { 2, "\040\037", "IB8=" }, - { 2, "\261\372", "sfo=" }, - { 2, "\335\014", "3Qw=" }, - { 2, "\233\217", "m48=" }, - { 2, "\373\056", "+y4=" }, - { 2, "\247\232", "p5o=" }, - { 2, "\107\053", "Rys=" }, - { 2, "\204\077", "hD8=" }, - { 2, "\276\211", "vok=" }, - { 2, "\313\110", "y0g=" }, - { 2, "\363\376", "8/4=" }, - { 2, "\251\234", "qZw=" }, - { 2, "\103\262", "Q7I=" }, - { 2, "\142\312", "Yso=" }, - { 2, "\067\211", "N4k=" }, - { 2, "\220\001", "kAE=" }, - { 2, "\152\240", "aqA=" }, - { 2, "\367\061", "9zE=" }, - { 2, "\133\255", "W60=" }, - { 2, "\176\035", "fh0=" }, - { 2, "\032\231", "Gpk=" }, - - { 3, "\013\007\144", "Cwdk" }, - { 3, "\030\112\106", "GEpG" }, - { 3, "\047\325\046", "J9Um" }, - { 3, "\310\160\022", "yHAS" }, - { 3, "\131\100\237", "WUCf" }, - { 3, "\064\342\134", "NOJc" }, - { 3, "\010\177\004", "CH8E" }, - { 3, "\345\147\205", "5WeF" }, - { 3, "\300\343\360", "wOPw" }, - { 3, "\061\240\201", "MaCB" }, - { 3, "\225\333\044", "ldsk" }, - { 3, "\215\137\352", "jV/q" }, - { 3, "\371\147\160", "+Wdw" }, - { 3, "\030\320\051", "GNAp" }, - { 3, "\044\174\241", "JHyh" }, - { 3, "\260\127\037", "sFcf" }, - { 3, "\111\045\033", "SSUb" }, - { 3, "\202\114\107", "gkxH" }, - { 3, "\057\371\042", "L/ki" }, - { 3, "\223\247\244", "k6ek" }, - { 3, "\047\216\144", "J45k" }, - { 3, "\203\070\327", "gzjX" }, - { 3, "\247\140\072", "p2A6" }, - { 3, "\124\115\116", "VE1O" }, - { 3, "\157\162\050", "b3Io" }, - { 3, "\357\223\004", "75ME" }, - { 3, "\052\117\156", "Kk9u" }, - { 3, "\347\154\000", "52wA" }, - { 3, "\303\012\142", "wwpi" }, - { 3, "\060\035\362", "MB3y" }, - { 3, "\130\226\361", "WJbx" }, - { 3, "\173\013\071", "ews5" }, - { 3, "\336\004\027", "3gQX" }, - { 3, "\357\366\234", "7/ac" }, - { 3, "\353\304\111", "68RJ" }, - { 3, "\024\264\131", "FLRZ" }, - { 3, "\075\114\251", "PUyp" }, - { 3, "\315\031\225", "zRmV" }, - { 3, "\154\201\276", "bIG+" }, - { 3, "\200\066\072", "gDY6" }, - { 3, "\142\350\267", "Yui3" }, - { 3, "\033\000\166", "GwB2" }, - { 3, "\210\055\077", "iC0/" }, - { 3, "\341\037\124", "4R9U" }, - { 3, "\161\103\152", "cUNq" }, - { 3, "\270\142\131", "uGJZ" }, - { 3, "\337\076\074", "3z48" }, - { 3, "\375\106\362", "/Uby" }, - { 3, "\227\301\127", "l8FX" }, - { 3, "\340\002\234", "4AKc" }, - { 3, "\121\064\033", "UTQb" }, - { 3, "\157\134\143", "b1xj" }, - { 3, "\247\055\327", "py3X" }, - { 3, "\340\142\005", "4GIF" }, - { 3, "\060\260\143", "MLBj" }, - { 3, "\075\203\170", "PYN4" }, - { 3, "\143\160\016", "Y3AO" }, - { 3, "\313\013\063", "ywsz" }, - { 3, "\174\236\135", "fJ5d" }, - { 3, "\103\047\026", "QycW" }, - { 3, "\365\005\343", "9QXj" }, - { 3, "\271\160\223", "uXCT" }, - { 3, "\362\255\172", "8q16" }, - { 3, "\113\012\015", "SwoN" }, - - // various lengths, generated by this python script: - // - // from string import lowercase as lc - // for i in range(27): - // print '{ %2d, "%s",%s "%s" },' % (i, lc[:i], ' ' * (26-i), - // lc[:i].encode('base64').strip()) - - { 0, "abcdefghijklmnopqrstuvwxyz", "" }, - { 1, "abcdefghijklmnopqrstuvwxyz", "YQ==" }, - { 2, "abcdefghijklmnopqrstuvwxyz", "YWI=" }, - { 3, "abcdefghijklmnopqrstuvwxyz", "YWJj" }, - { 4, "abcdefghijklmnopqrstuvwxyz", "YWJjZA==" }, - { 5, "abcdefghijklmnopqrstuvwxyz", "YWJjZGU=" }, - { 6, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVm" }, - { 7, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZw==" }, - { 8, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2g=" }, - { 9, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hp" }, - { 10, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpag==" }, - { 11, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpams=" }, - { 12, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamts" }, - { 13, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbQ==" }, - { 14, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW4=" }, - { 15, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5v" }, - { 16, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcA==" }, - { 17, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHE=" }, - { 18, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFy" }, - { 19, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFycw==" }, - { 20, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3Q=" }, - { 21, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1" }, - { 22, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dg==" }, - { 23, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnc=" }, - { 24, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4" }, - { 25, "abcdefghijklmnopqrstuvwxy", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eQ==" }, - { 26, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=" }, -}; -#if 0 -static struct { - const char* plaintext; - const char* cyphertext; -} base64_strings[] = { - - // The first few Google quotes - // Cyphertext created with "uuencode - GNU sharutils 4.2.1" - { - "Everyone! We're teetering on the brink of disaster." - " - Sergey Brin, 6/24/99, regarding the company's state " - "after the unleashing of Netscape/Google search", - - "RXZlcnlvbmUhICBXZSdyZSB0ZWV0ZXJpbmcgb24gdGhlIGJyaW5rIG9mIGRp" - "c2FzdGVyLiAtIFNlcmdleSBCcmluLCA2LzI0Lzk5LCByZWdhcmRpbmcgdGhl" - "IGNvbXBhbnkncyBzdGF0ZSBhZnRlciB0aGUgdW5sZWFzaGluZyBvZiBOZXRz" - "Y2FwZS9Hb29nbGUgc2VhcmNo" }, - - { - "I'm not sure why we're still alive, but we seem to be." - " - Larry Page, 6/24/99, while hiding in the kitchenette " - "during the Netscape traffic overflow", - - "SSdtIG5vdCBzdXJlIHdoeSB3ZSdyZSBzdGlsbCBhbGl2ZSwgYnV0IHdlIHNl" - "ZW0gdG8gYmUuIC0gTGFycnkgUGFnZSwgNi8yNC85OSwgd2hpbGUgaGlkaW5n" - "IGluIHRoZSBraXRjaGVuZXR0ZSBkdXJpbmcgdGhlIE5ldHNjYXBlIHRyYWZm" - "aWMgb3ZlcmZsb3c" }, - - { - "I think kids want porn." - " - Sergey Brin, 6/99, on why Google shouldn't prioritize a " - "filtered search for children and families", - - "SSB0aGluayBraWRzIHdhbnQgcG9ybi4gLSBTZXJnZXkgQnJpbiwgNi85OSwg" - "b24gd2h5IEdvb2dsZSBzaG91bGRuJ3QgcHJpb3JpdGl6ZSBhIGZpbHRlcmVk" - "IHNlYXJjaCBmb3IgY2hpbGRyZW4gYW5kIGZhbWlsaWVz" }, -}; -#endif -// Compare bytes 0..len-1 of x and y. If not equal, abort with verbose error -// message showing position and numeric value that differed. -// Handles embedded nulls just like any other byte. -// Only added because string.compare() in gcc-3.3.3 seems to misbehave with -// embedded nulls. -// TODO: switch back to string.compare() if/when gcc is fixed -#define EXPECT_EQ_ARRAY(len, x, y, msg) \ - for (size_t j = 0; j < len; ++j) { \ - if (x[j] != y[j]) { \ - LOG(LS_ERROR) << "" # x << " != " # y \ - << " byte " << j << " msg: " << msg; \ - } \ - } - -size_t Base64Escape(const unsigned char *src, size_t szsrc, char *dest, - size_t szdest) { - std::string escaped; - Base64::EncodeFromArray((const char *)src, szsrc, &escaped); - memcpy(dest, escaped.data(), min(escaped.size(), szdest)); - return escaped.size(); -} - -size_t Base64Unescape(const char *src, size_t szsrc, char *dest, - size_t szdest) { - std::string unescaped; - EXPECT_TRUE(Base64::DecodeFromArray(src, szsrc, Base64::DO_LAX, &unescaped, - NULL)); - memcpy(dest, unescaped.data(), min(unescaped.size(), szdest)); - return unescaped.size(); -} - -size_t Base64Unescape(const char *src, size_t szsrc, string *s) { - EXPECT_TRUE(Base64::DecodeFromArray(src, szsrc, Base64::DO_LAX, s, NULL)); - return s->size(); -} - -TEST(Base64, EncodeDecodeBattery) { - LOG(LS_VERBOSE) << "Testing base-64"; - - size_t i; - - // Check the short strings; this tests the math (and boundaries) - for( i = 0; i < sizeof(base64_tests) / sizeof(base64_tests[0]); ++i ) { - char encode_buffer[100]; - size_t encode_length; - char decode_buffer[100]; - size_t decode_length; - size_t cypher_length; - - LOG(LS_VERBOSE) << "B64: " << base64_tests[i].cyphertext; - - const unsigned char* unsigned_plaintext = - reinterpret_cast(base64_tests[i].plaintext); - - cypher_length = strlen(base64_tests[i].cyphertext); - - // The basic escape function: - memset(encode_buffer, 0, sizeof(encode_buffer)); - encode_length = Base64Escape(unsigned_plaintext, - base64_tests[i].plain_length, - encode_buffer, - sizeof(encode_buffer)); - // Is it of the expected length? - EXPECT_EQ(encode_length, cypher_length); - - // Is it the expected encoded value? - EXPECT_STREQ(encode_buffer, base64_tests[i].cyphertext); - - // If we encode it into a buffer of exactly the right length... - memset(encode_buffer, 0, sizeof(encode_buffer)); - encode_length = Base64Escape(unsigned_plaintext, - base64_tests[i].plain_length, - encode_buffer, - cypher_length); - // Is it still of the expected length? - EXPECT_EQ(encode_length, cypher_length); - - // And is the value still correct? (i.e., not losing the last byte) - EXPECT_STREQ(encode_buffer, base64_tests[i].cyphertext); - - // If we decode it back: - memset(decode_buffer, 0, sizeof(decode_buffer)); - decode_length = Base64Unescape(encode_buffer, - cypher_length, - decode_buffer, - sizeof(decode_buffer)); - - // Is it of the expected length? - EXPECT_EQ(decode_length, base64_tests[i].plain_length); - - // Is it the expected decoded value? - EXPECT_EQ(0, memcmp(decode_buffer, base64_tests[i].plaintext, decode_length)); - - // Our decoder treats the padding '=' characters at the end as - // optional. If encode_buffer has any, run some additional - // tests that fiddle with them. - char* first_equals = strchr(encode_buffer, '='); - if (first_equals) { - // How many equals signs does the string start with? - int equals = (*(first_equals+1) == '=') ? 2 : 1; - - // Try chopping off the equals sign(s) entirely. The decoder - // should still be okay with this. - string decoded2("this junk should also be ignored"); - *first_equals = '\0'; - EXPECT_NE(0U, Base64Unescape(encode_buffer, first_equals-encode_buffer, - &decoded2)); - EXPECT_EQ(decoded2.size(), base64_tests[i].plain_length); - EXPECT_EQ_ARRAY(decoded2.size(), decoded2.data(), base64_tests[i].plaintext, i); - - size_t len; - - // try putting some extra stuff after the equals signs, or in between them - if (equals == 2) { - sprintfn(first_equals, 6, " = = "); - len = first_equals - encode_buffer + 5; - } else { - sprintfn(first_equals, 6, " = "); - len = first_equals - encode_buffer + 3; - } - decoded2.assign("this junk should be ignored"); - EXPECT_NE(0U, Base64Unescape(encode_buffer, len, &decoded2)); - EXPECT_EQ(decoded2.size(), base64_tests[i].plain_length); - EXPECT_EQ_ARRAY(decoded2.size(), decoded2, base64_tests[i].plaintext, i); - } - } -} - -// here's a weird case: a giant base64 encoded stream which broke our base64 -// decoding. Let's test it explicitly. -const char SpecificTest[] = - "/9j/4AAQSkZJRgABAgEASABIAAD/4Q0HRXhpZgAATU0AKgAAAAgADAEOAAIAAAAgAAAAngEPAAI\n" - "AAAAFAAAAvgEQAAIAAAAJAAAAwwESAAMAAAABAAEAAAEaAAUAAAABAAAAzAEbAAUAAAABAAAA1A\n" - "EoAAMAAAABAAIAAAExAAIAAAAUAAAA3AEyAAIAAAAUAAAA8AE8AAIAAAAQAAABBAITAAMAAAABA\n" - "AIAAIdpAAQAAAABAAABFAAAAsQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAFNPTlkA\n" - "RFNDLVAyMDAAAAAASAAAAAEAAABIAAAAAUFkb2JlIFBob3Rvc2hvcCA3LjAAMjAwNzowMTozMCA\n" - "yMzoxMDowNABNYWMgT1MgWCAxMC40LjgAAByCmgAFAAAAAQAAAmqCnQAFAAAAAQAAAnKIIgADAA\n" - "AAAQACAACIJwADAAAAAQBkAACQAAAHAAAABDAyMjCQAwACAAAAFAAAAnqQBAACAAAAFAAAAo6RA\n" - "QAHAAAABAECAwCRAgAFAAAAAQAAAqKSBAAKAAAAAQAAAqqSBQAFAAAAAQAAArKSBwADAAAAAQAF\n" - "AACSCAADAAAAAQAAAACSCQADAAAAAQAPAACSCgAFAAAAAQAAArqgAAAHAAAABDAxMDCgAQADAAA\n" - "AAf//AACgAgAEAAAAAQAAAGSgAwAEAAAAAQAAAGSjAAAHAAAAAQMAAACjAQAHAAAAAQEAAACkAQ\n" - "ADAAAAAQAAAACkAgADAAAAAQAAAACkAwADAAAAAQAAAACkBgADAAAAAQAAAACkCAADAAAAAQAAA\n" - "ACkCQADAAAAAQAAAACkCgADAAAAAQAAAAAAAAAAAAAACgAAAZAAAAAcAAAACjIwMDc6MDE6MjAg\n" - "MjM6MDU6NTIAMjAwNzowMToyMCAyMzowNTo1MgAAAAAIAAAAAQAAAAAAAAAKAAAAMAAAABAAAAB\n" - "PAAAACgAAAAYBAwADAAAAAQAGAAABGgAFAAAAAQAAAxIBGwAFAAAAAQAAAxoBKAADAAAAAQACAA\n" - "ACAQAEAAAAAQAAAyICAgAEAAAAAQAACd0AAAAAAAAASAAAAAEAAABIAAAAAf/Y/+AAEEpGSUYAA\n" - "QIBAEgASAAA/+0ADEFkb2JlX0NNAAL/7gAOQWRvYmUAZIAAAAAB/9sAhAAMCAgICQgMCQkMEQsK\n" - "CxEVDwwMDxUYExMVExMYEQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQ0LCw0\n" - "ODRAODhAUDg4OFBQODg4OFBEMDAwMDBERDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA\n" - "wMDAz/wAARCABkAGQDASIAAhEBAxEB/90ABAAH/8QBPwAAAQUBAQEBAQEAAAAAAAAAAwABAgQFB\n" - "gcICQoLAQABBQEBAQEBAQAAAAAAAAABAAIDBAUGBwgJCgsQAAEEAQMCBAIFBwYIBQMMMwEAAhED\n" - "BCESMQVBUWETInGBMgYUkaGxQiMkFVLBYjM0coLRQwclklPw4fFjczUWorKDJkSTVGRFwqN0Nhf\n" - "SVeJl8rOEw9N14/NGJ5SkhbSVxNTk9KW1xdXl9VZmdoaWprbG1ub2N0dXZ3eHl6e3x9fn9xEAAg\n" - "IBAgQEAwQFBgcHBgU1AQACEQMhMRIEQVFhcSITBTKBkRShsUIjwVLR8DMkYuFygpJDUxVjczTxJ\n" - "QYWorKDByY1wtJEk1SjF2RFVTZ0ZeLys4TD03Xj80aUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm\n" - "9ic3R1dnd4eXp7fH/9oADAMBAAIRAxEAPwDy7bKNTUXNLz9EaJPDWMjxH4ozhtpYwaACT8ShaaW\n" - "bW0uEc9/JFfjj0Q4Hk/PRDxwX7y47W9z/AN9Cv4+O3ILK2DcRqT2CaSvEbcl1Jbz37KG1dBldLo\n" - "qaS4l9xGjG9v6yoDAdYIaIjUk+AREgo4y5sapirb8Yl0NHHdKvBNm4yA1o5Pc+SPEFvCWqB3HZF\n" - "Hj2SbWQ/afGFP0bHP8ATY0uc4w1o1JPkkimGiS2KvqlnmBkOZQTyydzgPMM9v8A0lp4v1Nx9gF1\n" - "tpdqJaGtH/S3I0i3lISXW/8AMqnd/O2bfg2eUkqVYf/Q8zuncO4Bj7lZ+n7f5Mj5KsJcY8NUZ4d\n" - "uEDVo1HkeU0rg3Om4H2rabCWUN7DQuK1n5FWKW4uCwG92gDRJBS6exhxmMboQI+Cv4WFTQ42Bs2\n" - "fvnkkqEmy2YxoMMbpVzaz6jt+RbpHZs8lzkHqrasKkYOKP0jgDfZ4N/wDM1tNrcWfSPmRyq9uNV\n" - "DnFg2s97i7UkjxKVrq0eVz3spZsja+ASDzwsh9jnOk/JFzb3XZD3v1c4yT8UACTCniKDUnKz5Nj\n" - "G33XV1DV73BrT8dF23SejV4zg9g33cOsPb+SxVvqv9ViwNy8vS0iWs/daf8A0Y5dpTi1sADGxCR\n" - "K1o0YBEmInlXWYbDBcDLdPJXa8f71Yrx2jnUoAqLnfZK5hJaW2vdwEk5a/wD/0fN6Ia/e76IiVf\n" - "xavUL7CPpnT4LNbYXAVjuQt/AqDmNYO/Kjnoy4hr5J8SwMhrRMaeSvbsxrfUazcOw4UX0Cisem2\n" - "SBoD4+Kz8nC6llbSLCRrubJA8kwUWbUDa29X1PMa7aQWjuDC0MXMdbDbhI7eazBiUfZ6GOYRe1s\n" - "WvGgJ8Vbw2+m4Bx9s6JpNHuuGo1FF53r/SHYua61gLse0lzXeBP5rkvqx0o5vVWz7WY49QkiQSP\n" - "oN/tLoevW/ogxv0HA7tJ0AnhT+pdDGYVl/wCdcTPkGn2NU0JWNWvlgAbHV6fEqdu2gR/r2WlWwt\n" - "AA5VXAEsLXTqJafArQY5rRr9LiPBJiZsZCI1pJjxCi0j4oncSICSkWwzwkjeaSch//0vO7sP7Lm\n" - "enO9ogtd5FbPT3Q5pCpZVc4ld3Lmn3O8j9EI2BYdunKjOobMQIyI+rusc2wx4d0eutwGnHh/uQc\n" - "Ha7ladj6mVANGvcqOgz0Go7HJ12/GEHcwvB/dPY6ImbbaMaASGuIBjkN7qofs9Ubg9g7OI9p/t/\n" - "RTSmhTHr0v6eSz6UgCPP2/wAVu9Ex2V49dVY2iACB4BZeVXQ/AJ3gzGnnOi2+kACpru8flUsNmt\n" - "zHRf6xfWCnoeAfTh2ZaQKazx/Ke7+QxcKz61fWA2uuObaC4zGhaPJrXBL64ZFmR124O09ENraPK\n" - "N3/AH5GqxIrZVUyp2K2vfdkENsDnxuex9m4Ox9n82xSgNd9D+p/XR1npgseR9ppOy4Dx/NfH/CL\n" - "oQJGunmvMv8AFq3KHVcq3HkYQbD2nuSf0I/rMavSg6TLjLigQhJ7Z58v9QkmlsTOqSCn/9PzL7R\n" - "d6Qq3n0wZ2zotXpT9xLfFYvkr/S7jXeB8E0jRkhKpC3q8LcJ/kmCrTnkuAPCq4do9Q/ytVbuAeY\n" - "Gg5lQybQK+82GBqEQUA1kOHPYf3LLsoyN36G5w8iUfHxepbXE2l0cApALgLHzBq9UxhTXU5hMC1\n" - "ktnSCup6S4Ctk+C5XqVGcaHPfuiuHkeTTuWz0+9zaKiH6CC0/yXBSQ2a/MxojV57634rq+v2PLY\n" - "be1r2nsYG13/AFKxbfCBMcr0brGAzrGEwCG31ncx0SfBzf7S4+zoHUWWsJq3hz9oLfcBH77R9H+\n" - "0pA13u/qPgDp/Q6ri39JlfpXkDx+h/msWn1L6wdO6bSbcrIbU2Q0xLnSe21kuVejJspbVS5+4bd\n" - "ocBAkD/orG+tP1ar67Wy7GtZTm1SCXfRsb+a18fRe38x6SG3/44H1Z3f0y2I+l6DoSXD/8xPrDs\n" - "3enVu3bdnqN3R+//USSVo//1PLohhce+gRWS0Nsby3lRgFkKxQyW7SgUh3em5Tbq2uB9wWw1wey\n" - "J1XGV2XYdm5k7e4WzidXY9oMwo5RZ4T6Hd1ixwfp96PWbAJBVTHzK7O6Ky5oJB1HZMqmUEFlkGy\n" - "xpa4zI1Hkq31dy7bMN9BAc3HeWAnnbyxEycmuup1jiAGglZ31PyrmZ9tQg1WtNj54EHR3/S2qTH\n" - "1Yc5GgD1FFtzPdWGkd2AyflogZmRmsz6PSrbXbdo+txOrP337f3fzVo15DK2uyrTtqpBOnBKx6b\n" - "7MjJsz7tHWOAYP3WD6LU6cqGjFCNl1MmvLcxv6YtDTLSAqP27LrdtYHXFnJZI+Tp3MWg68OpDPv\n" - "UMUM2lkQBoouKQ6swjE9Nml+1sz1PW+z6xt27zuj+skrX2ZvqR5z8kkuOfdPt43/1fMm/grFG6f\n" - "Lss9JA7JG7tnZs/SfJUrfS3foJ9TvHCopJsV8nWx/t24bJn8Fo/5TjWJXMJIS+i+G36TsZ/7Q9P\n" - "8ATfzfeOFofVSZv2/zvt+O3X/v65dJPjt/BiyfN1/wn0zre79nVej/ADG8ep4x2/6Srjd6TdviF\n" - "52ko8m6/Ht9X1KnftEo+POwxzK8mSTF46vrH6T1/OEl5Okkl//Z/+0uHFBob3Rvc2hvcCAzLjAA\n" - "OEJJTQQEAAAAAAArHAIAAAIAAhwCeAAfICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAA\n" - "4QklNBCUAAAAAABD7Caa9B0wqNp2P4sxXqayFOEJJTQPqAAAAAB2wPD94bWwgdmVyc2lvbj0iMS\n" - "4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUgQ\n" - "29tcHV0ZXIvL0RURCBQTElTVCAxLjAvL0VOIiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Q\n" - "cm9wZXJ0eUxpc3QtMS4wLmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdD4KCTxrZXk\n" - "+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1Ib3Jpem9udGFsUmVzPC9rZXk+Cgk8ZGljdD\n" - "4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc+Y\n" - "29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCTxrZXk+Y29tLmFwcGxlLnByaW50\n" - "LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20\n" - "uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUhvcml6b250YWxSZXM8L2tleT4KCQkJCTxyZWFsPj\n" - "cyPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJC\n" - "QkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQk8a2V5PmNv\n" - "bS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJPGRhdGU+MjAwNy0wMS0zMFQ\n" - "yMjowODo0MVo8L2RhdGU+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbG\n" - "FnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2RpY3Q+CgkJPC9hcnJheT4KC\n" - "TwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1PcmllbnRhdGlvbjwv\n" - "a2V5PgoJPGRpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4\n" - "KCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQk8a2V5PmNvbS\n" - "5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJPGFycmF5PgoJCQk8ZGljdD4KC\n" - "QkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1PcmllbnRhdGlvbjwva2V5PgoJ\n" - "CQkJPGludGVnZXI+MTwvaW50ZWdlcj4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5\n" - "jbGllbnQ8L2tleT4KCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW\n" - "5nPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJCTxkY\n" - "XRlPjIwMDctMDEtMzBUMjI6MDg6NDFaPC9kYXRlPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQu\n" - "dGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJPC9kaWN\n" - "0PgoJCTwvYXJyYXk+Cgk8L2RpY3Q+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0Ll\n" - "BNU2NhbGluZzwva2V5PgoJPGRpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZ\n" - "WF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4K\n" - "CQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJPGFycmF5Pgo\n" - "JCQk8ZGljdD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1TY2FsaW5nPC\n" - "9rZXk+CgkJCQk8cmVhbD4xPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0L\n" - "mNsaWVudDwva2V5PgoJCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJp\n" - "bmc+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJPGR\n" - "hdGU+MjAwNy0wMS0zMFQyMjowODo0MVo8L2RhdGU+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC\n" - "50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2RpY\n" - "3Q+CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQu\n" - "UE1WZXJ0aWNhbFJlczwva2V5PgoJPGRpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V\n" - "0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cm\n" - "luZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJPGFyc\n" - "mF5PgoJCQk8ZGljdD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1WZXJ0\n" - "aWNhbFJlczwva2V5PgoJCQkJPHJlYWw+NzI8L3JlYWw+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcml\n" - "udC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbm\n" - "FnZXI8L3N0cmluZz4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZ\n" - "Xk+CgkJCQk8ZGF0ZT4yMDA3LTAxLTMwVDIyOjA4OjQxWjwvZGF0ZT4KCQkJCTxrZXk+Y29tLmFw\n" - "cGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI\n" - "+CgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUG\n" - "FnZUZvcm1hdC5QTVZlcnRpY2FsU2NhbGluZzwva2V5PgoJPGRpY3Q+CgkJPGtleT5jb20uYXBwb\n" - "GUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGlu\n" - "Z21hbmFnZXI8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF\n" - "5PC9rZXk+CgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2\n" - "VGb3JtYXQuUE1WZXJ0aWNhbFNjYWxpbmc8L2tleT4KCQkJCTxyZWFsPjE8L3JlYWw+CgkJCQk8a\n" - "2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQk8c3RyaW5nPmNvbS5h\n" - "cHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnR\n" - "pY2tldC5tb2REYXRlPC9rZXk+CgkJCQk8ZGF0ZT4yMDA3LTAxLTMwVDIyOjA4OjQxWjwvZGF0ZT\n" - "4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpb\n" - "nRlZ2VyPjA8L2ludGVnZXI+CgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5j\n" - "b20uYXBwbGUucHJpbnQuc3ViVGlja2V0LnBhcGVyX2luZm9fdGlja2V0PC9rZXk+Cgk8ZGljdD4\n" - "KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2\n" - "V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5P\n" - "goJCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJPGtleT5j\n" - "b20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGl\n" - "jdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUm\n" - "VjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw+MC4wPC9yZWFsPgoJCQkJCQk8cmVhb\n" - "D4wLjA8L3JlYWw+CgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw+NTc2PC9yZWFs\n" - "PgoJCQkJCTwvYXJyYXk+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDw\n" - "va2V5PgoJCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQ\n" - "kJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+M\n" - "jAwNy0wMS0zMFQyMjowODo0MVo8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlj\n" - "a2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCQk8L2RpY3Q\n" - "+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYX\n" - "QuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wc\n" - "mludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21h\n" - "bmFnZXI8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTw\n" - "va2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYW\n" - "dlRm9ybWF0LlBNQWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk+CgkJCQkJCTxyZ\n" - "WFsPi0xODwvcmVhbD4KCQkJCQkJPHJlYWw+LTE4PC9yZWFsPgoJCQkJCQk8cmVhbD43NzQ8L3Jl\n" - "YWw+CgkJCQkJCTxyZWFsPjU5NDwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk+Y29tLmF\n" - "wcGxlLnByaW50LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCQk8c3RyaW5nPmNvbS5hcHBsZS5wcm\n" - "ludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQub\n" - "W9kRGF0ZTwva2V5PgoJCQkJCTxkYXRlPjIwMDctMDEtMzBUMjI6MDg6NDFaPC9kYXRlPgoJCQkJ\n" - "CTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWd\n" - "lcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5Pm\n" - "NvbS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJP\n" - "GtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20u\n" - "YXBwbGUucHJpbnQucG0uUG9zdFNjcmlwdDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcml\n" - "udC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZX\n" - "k+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVBhcGVyTmFtZTwva2V5PgoJCQkJCTxzdHJpb\n" - "mc+bmEtbGV0dGVyPC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNs\n" - "aWVudDwva2V5PgoJCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50LnBtLlBvc3RTY3JpcHQ8L3N\n" - "0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQ\n" - "kJCTxkYXRlPjIwMDMtMDctMDFUMTc6NDk6MzZaPC9kYXRlPgoJCQkJCTxrZXk+Y29tLmFwcGxlL\n" - "nByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJ\n" - "CQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5\n" - "QYXBlckluZm8uUE1VbmFkanVzdGVkUGFnZVJlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb2\n" - "0uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuc\n" - "HJpbnQucG0uUG9zdFNjcmlwdDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNr\n" - "ZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+Y29tLmF\n" - "wcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcn\n" - "JheT4KCQkJCQkJPHJlYWw+MC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw+CgkJCQkJC\n" - "TxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw+NTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk+CgkJ\n" - "CQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJCTxzdHJpbmc\n" - "+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLn\n" - "ByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+MjAwNy0wMS0zMFQyMjowODo0M\n" - "Vo8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5\n" - "PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCQk8L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9\n" - "kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYXBlcl\n" - "JlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b\n" - "3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQucG0uUG9zdFNjcmlwdDwvc3RyaW5n\n" - "PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJ\n" - "heT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYW\n" - "RqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk+CgkJCQkJCTxyZWFsPi0xODwvcmVhb\n" - "D4KCQkJCQkJPHJlYWw+LTE4PC9yZWFsPgoJCQkJCQk8cmVhbD43NzQ8L3JlYWw+CgkJCQkJCTxy\n" - "ZWFsPjU5NDwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnR\n" - "pY2tldC5jbGllbnQ8L2tleT4KCQkJCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZX\n" - "I8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5P\n" - "goJCQkJCTxkYXRlPjIwMDctMDEtMzBUMjI6MDg6NDFaPC9kYXRlPgoJCQkJCTxrZXk+Y29tLmFw\n" - "cGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2V\n" - "yPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcm\n" - "ludC5QYXBlckluZm8ucHBkLlBNUGFwZXJOYW1lPC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tL\n" - "mFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Y29tLmFwcGxlLnBy\n" - "aW50LnBtLlBvc3RTY3JpcHQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V\n" - "0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcH\n" - "BsZS5wcmludC5QYXBlckluZm8ucHBkLlBNUGFwZXJOYW1lPC9rZXk+CgkJCQkJPHN0cmluZz5VU\n" - "yBMZXR0ZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50\n" - "PC9rZXk+CgkJCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQucG0uUG9zdFNjcmlwdDwvc3RyaW5\n" - "nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPG\n" - "RhdGU+MjAwMy0wNy0wMVQxNzo0OTozNlo8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpb\n" - "nQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8\n" - "L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2t\n" - "ldC5BUElWZXJzaW9uPC9rZXk+CgkJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJCTxrZXk+Y29tLm\n" - "FwcGxlLnByaW50LnRpY2tldC5wcml2YXRlTG9jazwva2V5PgoJCTxmYWxzZS8+CgkJPGtleT5jb\n" - "20uYXBwbGUucHJpbnQudGlja2V0LnR5cGU8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmlu\n" - "dC5QYXBlckluZm9UaWNrZXQ8L3N0cmluZz4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW5\n" - "0LnRpY2tldC5BUElWZXJzaW9uPC9rZXk+Cgk8c3RyaW5nPjAwLjIwPC9zdHJpbmc+Cgk8a2V5Pm\n" - "NvbS5hcHBsZS5wcmludC50aWNrZXQucHJpdmF0ZUxvY2s8L2tleT4KCTxmYWxzZS8+Cgk8a2V5P\n" - "mNvbS5hcHBsZS5wcmludC50aWNrZXQudHlwZTwva2V5PgoJPHN0cmluZz5jb20uYXBwbGUucHJp\n" - "bnQuUGFnZUZvcm1hdFRpY2tldDwvc3RyaW5nPgo8L2RpY3Q+CjwvcGxpc3Q+CjhCSU0D6QAAAAA\n" - "AeAADAAAASABIAAAAAALeAkD/7v/uAwYCUgNnBSgD/AACAAAASABIAAAAAALYAigAAQAAAGQAAA\n" - "ABAAMDAwAAAAF//wABAAEAAAAAAAAAAAAAAABoCAAZAZAAAAAAACAAAAAAAAAAAAAAAAAAAAAAA\n" - "AAAAAAAAAAAADhCSU0D7QAAAAAAEABIAAAAAQABAEgAAAABAAE4QklNBCYAAAAAAA4AAAAAAAAA\n" - "AAAAP4AAADhCSU0EDQAAAAAABAAAAB44QklNBBkAAAAAAAQAAAAeOEJJTQPzAAAAAAAJAAAAAAA\n" - "AAAABADhCSU0ECgAAAAAAAQAAOEJJTScQAAAAAAAKAAEAAAAAAAAAAThCSU0D9QAAAAAASAAvZm\n" - "YAAQBsZmYABgAAAAAAAQAvZmYAAQChmZoABgAAAAAAAQAyAAAAAQBaAAAABgAAAAAAAQA1AAAAA\n" - "QAtAAAABgAAAAAAAThCSU0D+AAAAAAAcAAA/////////////////////////////wPoAAAAAP//\n" - "//////////////////////////8D6AAAAAD/////////////////////////////A+gAAAAA///\n" - "//////////////////////////wPoAAA4QklNBAgAAAAAABAAAAABAAACQAAAAkAAAAAAOEJJTQ\n" - "QeAAAAAAAEAAAAADhCSU0EGgAAAAADRQAAAAYAAAAAAAAAAAAAAGQAAABkAAAACABEAFMAQwAwA\n" - "DIAMwAyADUAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAGQAAABkAAAAAAAAAAAA\n" - "AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAAAAABudWxsAAAAAgAAAAZib3VuZHN\n" - "PYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAA\n" - "AAQnRvbWxvbmcAAABkAAAAAFJnaHRsb25nAAAAZAAAAAZzbGljZXNWbExzAAAAAU9iamMAAAABA\n" - "AAAAAAFc2xpY2UAAAASAAAAB3NsaWNlSURsb25nAAAAAAAAAAdncm91cElEbG9uZwAAAAAAAAAG\n" - "b3JpZ2luZW51bQAAAAxFU2xpY2VPcmlnaW4AAAANYXV0b0dlbmVyYXRlZAAAAABUeXBlZW51bQA\n" - "AAApFU2xpY2VUeXBlAAAAAEltZyAAAAAGYm91bmRzT2JqYwAAAAEAAAAAAABSY3QxAAAABAAAAA\n" - "BUb3AgbG9uZwAAAAAAAAAATGVmdGxvbmcAAAAAAAAAAEJ0b21sb25nAAAAZAAAAABSZ2h0bG9uZ\n" - "wAAAGQAAAADdXJsVEVYVAAAAAEAAAAAAABudWxsVEVYVAAAAAEAAAAAAABNc2dlVEVYVAAAAAEA\n" - "AAAAAAZhbHRUYWdURVhUAAAAAQAAAAAADmNlbGxUZXh0SXNIVE1MYm9vbAEAAAAIY2VsbFRleHR\n" - "URVhUAAAAAQAAAAAACWhvcnpBbGlnbmVudW0AAAAPRVNsaWNlSG9yekFsaWduAAAAB2RlZmF1bH\n" - "QAAAAJdmVydEFsaWduZW51bQAAAA9FU2xpY2VWZXJ0QWxpZ24AAAAHZGVmYXVsdAAAAAtiZ0Nvb\n" - "G9yVHlwZWVudW0AAAARRVNsaWNlQkdDb2xvclR5cGUAAAAATm9uZQAAAAl0b3BPdXRzZXRsb25n\n" - "AAAAAAAAAApsZWZ0T3V0c2V0bG9uZwAAAAAAAAAMYm90dG9tT3V0c2V0bG9uZwAAAAAAAAALcml\n" - "naHRPdXRzZXRsb25nAAAAAAA4QklNBBEAAAAAAAEBADhCSU0EFAAAAAAABAAAAAE4QklNBAwAAA\n" - "AACfkAAAABAAAAZAAAAGQAAAEsAAB1MAAACd0AGAAB/9j/4AAQSkZJRgABAgEASABIAAD/7QAMQ\n" - "WRvYmVfQ00AAv/uAA5BZG9iZQBkgAAAAAH/2wCEAAwICAgJCAwJCQwRCwoLERUPDAwPFRgTExUT\n" - "ExgRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBDQsLDQ4NEA4OEBQODg4UFA4\n" - "ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDP/AABEIAGQAZA\n" - "MBIgACEQEDEQH/3QAEAAf/xAE/AAABBQEBAQEBAQAAAAAAAAADAAECBAUGBwgJCgsBAAEFAQEBA\n" - "QEBAAAAAAAAAAEAAgMEBQYHCAkKCxAAAQQBAwIEAgUHBggFAwwzAQACEQMEIRIxBUFRYRMicYEy\n" - "BhSRobFCIyQVUsFiMzRygtFDByWSU/Dh8WNzNRaisoMmRJNUZEXCo3Q2F9JV4mXys4TD03Xj80Y\n" - "nlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3EQACAgECBAQDBAUGBwcGBT\n" - "UBAAIRAyExEgRBUWFxIhMFMoGRFKGxQiPBUtHwMyRi4XKCkkNTFWNzNPElBhaisoMHJjXC0kSTV\n" - "KMXZEVVNnRl4vKzhMPTdePzRpSkhbSVxNTk9KW1xdXl9VZmdoaWprbG1ub2JzdHV2d3h5ent8f/\n" - "2gAMAwEAAhEDEQA/APLtso1NRc0vP0Rok8NYyPEfijOG2ljBoAJPxKFppZtbS4Rz38kV+OPRDge\n" - "T89EPHBfvLjtb3P8A30K/j47cgsrYNxGpPYJpK8RtyXUlvPfsobV0GV0uippLiX3EaMb2/rKgMB\n" - "1ghoiNST4BESCjjLmxqmKtvxiXQ0cd0q8E2bjIDWjk9z5I8QW8JaoHcdkUePZJtZD9p8YU/Rsc/\n" - "wBNjS5zjDWjUk+SSKYaJLYq+qWeYGQ5lBPLJ3OA8wz2/wDSWni/U3H2AXW2l2oloa0f9LcjSLeU\n" - "hJdb/wAyqd387Zt+DZ5SSpVh/9DzO6dw7gGPuVn6ft/kyPkqwlxjw1Rnh24QNWjUeR5TSuDc6bg\n" - "fatpsJZQ3sNC4rWfkVYpbi4LAb3aANEkFLp7GHGYxuhAj4K/hYVNDjYGzZ++eSSoSbLZjGgwxul\n" - "XNrPqO35FukdmzyXOQeqtqwqRg4o/SOAN9ng3/AMzW02txZ9I+ZHKr241UOcWDaz3uLtSSPEpWu\n" - "rR5XPeylmyNr4BIPPCyH2Oc6T8kXNvddkPe/VzjJPxQAJMKeIoNScrPk2MbfddXUNXvcGtPx0Xb\n" - "dJ6NXjOD2Dfdw6w9v5LFW+q/1WLA3Ly9LSJaz91p/wDRjl2lOLWwAMbEJErWjRgESYieVdZhsMF\n" - "wMt08ldrx/vVivHaOdSgCoud9krmElpba93ASTlr/AP/R83ohr97voiJV/Fq9QvsI+mdPgs1thc\n" - "BWO5C38CoOY1g78qOejLiGvknxLAyGtExp5K9uzGt9RrNw7DhRfQKKx6bZIGgPj4rPycLqWVtIs\n" - "JGu5skDyTBRZtQNrb1fU8xrtpBaO4MLQxcx1sNuEjt5rMGJR9noY5hF7Wxa8aAnxVvDb6bgHH2z\n" - "omk0e64ajUUXnev9Idi5rrWAux7SXNd4E/muS+rHSjm9VbPtZjj1CSJBI+g3+0uh69b+iDG/QcD\n" - "u0nQCeFP6l0MZhWX/AJ1xM+QafY1TQlY1a+WABsdXp8Sp27aBH+vZaVbC0ADlVcASwtdOolp8Ct\n" - "BjmtGv0uI8EmJmxkIjWkmPEKLSPiidxIgJKRbDPCSN5pJyH//S87uw/suZ6c72iC13kVs9PdDmk\n" - "KllVziV3cuafc7yP0QjYFh26cqM6hsxAjIj6u6xzbDHh3R663AaceH+5BwdruVp2PqZUA0a9yo6\n" - "DPQajscnXb8YQdzC8H909joiZttoxoBIa4gGOQ3uqh+z1RuD2Ds4j2n+39FNKaFMevS/p5LPpSA\n" - "I8/b/ABW70THZXj11VjaIAIHgFl5VdD8AneDMaec6Lb6QAKmu7x+VSw2a3MdF/rF9YKeh4B9OHZ\n" - "lpAprPH8p7v5DFwrPrV9YDa645toLjMaFo8mtcEvrhkWZHXbg7T0Q2to8o3f8AfkarEitlVTKnY\n" - "ra992QQ2wOfG57H2bg7H2fzbFKA130P6n9dHWemCx5H2mk7LgPH818f8IuhAka6ea8y/wAWrcod\n" - "VyrceRhBsPae5J/Qj+sxq9KDpMuMuKBCEntnny/1CSaWxM6pIKf/0/MvtF3pCrefTBnbOi1elP3\n" - "Et8Vi+Sv9LuNd4HwTSNGSEqkLerwtwn+SYKtOeS4A8Krh2j1D/K1Vu4B5gaDmVDJtAr7zYYGoRB\n" - "QDWQ4c9h/csuyjI3fobnDyJR8fF6ltcTaXRwCkAuAsfMGr1TGFNdTmEwLWS2dIK6npLgK2T4Lle\n" - "pUZxoc9+6K4eR5NO5bPT73NoqIfoILT/JcFJDZr8zGiNXnvrfiur6/Y8tht7WvaexgbXf8AUrFt\n" - "8IExyvRusYDOsYTAIbfWdzHRJ8HN/tLj7OgdRZawmreHP2gt9wEfvtH0f7SkDXe7+o+AOn9DquL\n" - "f0mV+leQPH6H+axafUvrB07ptJtyshtTZDTEudJ7bWS5V6MmyltVLn7ht2hwECQP+isb60/Vqvr\n" - "tbLsa1lObVIJd9Gxv5rXx9F7fzHpIbf/jgfVnd/TLYj6XoOhJcP/zE+sOzd6dW7dt2eo3dH7/9R\n" - "JJWj//U8uiGFx76BFZLQ2xvLeVGAWQrFDJbtKBSHd6blNura4H3BbDXB7InVcZXZdh2bmTt7hbO\n" - "J1dj2gzCjlFnhPod3WLHB+n3o9ZsAkFVMfMrs7orLmgkHUdkyqZQQWWQbLGlrjMjUeSrfV3Ltsw\n" - "30EBzcd5YCedvLETJya66nWOIAaCVnfU/KuZn21CDVa02PngQdHf9LapMfVhzkaAPUUW3M91YaR\n" - "3YDJ+WiBmZGazPo9Kttdt2j63E6s/fft/d/NWjXkMra7KtO2qkE6cErHpvsyMmzPu0dY4Bg/dYP\n" - "otTpyoaMUI2XUya8tzG/pi0NMtICo/bsut21gdcWclkj5OncxaDrw6kM+9QxQzaWRAGii4pDqzC\n" - "MT02aX7WzPU9b7PrG3bvO6P6yStfZm+pHnPySS4590+3jf/V8yb+CsUbp8uyz0kDskbu2dmz9J8\n" - "lSt9Ld+gn1O8cKikmxXydbH+3bhsmfwWj/lONYlcwkhL6L4bfpOxn/tD0/wBN/N944Wh9VJm/b/\n" - "O+347df+/rl0k+O38GLJ83X/CfTOt7v2dV6P8AMbx6njHb/pKuN3pN2+IXnaSjybr8e31fUqd+0\n" - "Sj487DHMryZJMXjq+sfpPX84SXk6SSX/9kAOEJJTQQhAAAAAABVAAAAAQEAAAAPAEEAZABvAGIA\n" - "ZQAgAFAAaABvAHQAbwBzAGgAbwBwAAAAEwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAA\n" - "gADcALgAwAAAAAQA4QklNBAYAAAAAAAcABQAAAAEBAP/hFWdodHRwOi8vbnMuYWRvYmUuY29tL3\n" - "hhcC8xLjAvADw/eHBhY2tldCBiZWdpbj0n77u/JyBpZD0nVzVNME1wQ2VoaUh6cmVTek5UY3prY\n" - "zlkJz8+Cjw/YWRvYmUteGFwLWZpbHRlcnMgZXNjPSJDUiI/Pgo8eDp4YXBtZXRhIHhtbG5zOng9\n" - "J2Fkb2JlOm5zOm1ldGEvJyB4OnhhcHRrPSdYTVAgdG9vbGtpdCAyLjguMi0zMywgZnJhbWV3b3J\n" - "rIDEuNSc+CjxyZGY6UkRGIHhtbG5zOnJkZj0naHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi\n" - "1yZGYtc3ludGF4LW5zIycgeG1sbnM6aVg9J2h0dHA6Ly9ucy5hZG9iZS5jb20vaVgvMS4wLyc+C\n" - "gogPHJkZjpEZXNjcmlwdGlvbiBhYm91dD0ndXVpZDoyMmQwMmIwYS1iMjQ5LTExZGItOGFmOC05\n" - "MWQ1NDAzZjkyZjknCiAgeG1sbnM6cGRmPSdodHRwOi8vbnMuYWRvYmUuY29tL3BkZi8xLjMvJz4\n" - "KICA8IS0tIHBkZjpTdWJqZWN0IGlzIGFsaWFzZWQgLS0+CiA8L3JkZjpEZXNjcmlwdGlvbj4KCi\n" - "A8cmRmOkRlc2NyaXB0aW9uIGFib3V0PSd1dWlkOjIyZDAyYjBhLWIyNDktMTFkYi04YWY4LTkxZ\n" - "DU0MDNmOTJmOScKICB4bWxuczpwaG90b3Nob3A9J2h0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9z\n" - "aG9wLzEuMC8nPgogIDwhLS0gcGhvdG9zaG9wOkNhcHRpb24gaXMgYWxpYXNlZCAtLT4KIDwvcmR\n" - "mOkRlc2NyaXB0aW9uPgoKIDxyZGY6RGVzY3JpcHRpb24gYWJvdXQ9J3V1aWQ6MjJkMDJiMGEtYj\n" - "I0OS0xMWRiLThhZjgtOTFkNTQwM2Y5MmY5JwogIHhtbG5zOnhhcD0naHR0cDovL25zLmFkb2JlL\n" - "mNvbS94YXAvMS4wLyc+CiAgPCEtLSB4YXA6RGVzY3JpcHRpb24gaXMgYWxpYXNlZCAtLT4KIDwv\n" - "cmRmOkRlc2NyaXB0aW9uPgoKIDxyZGY6RGVzY3JpcHRpb24gYWJvdXQ9J3V1aWQ6MjJkMDJiMGE\n" - "tYjI0OS0xMWRiLThhZjgtOTFkNTQwM2Y5MmY5JwogIHhtbG5zOnhhcE1NPSdodHRwOi8vbnMuYW\n" - "RvYmUuY29tL3hhcC8xLjAvbW0vJz4KICA8eGFwTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwa\n" - "G90b3Nob3A6MjJkMDJiMDYtYjI0OS0xMWRiLThhZjgtOTFkNTQwM2Y5MmY5PC94YXBNTTpEb2N1\n" - "bWVudElEPgogPC9yZGY6RGVzY3JpcHRpb24+CgogPHJkZjpEZXNjcmlwdGlvbiBhYm91dD0ndXV\n" - "pZDoyMmQwMmIwYS1iMjQ5LTExZGItOGFmOC05MWQ1NDAzZjkyZjknCiAgeG1sbnM6ZGM9J2h0dH\n" - "A6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvJz4KICA8ZGM6ZGVzY3JpcHRpb24+CiAgIDxyZ\n" - "GY6QWx0PgogICAgPHJkZjpsaSB4bWw6bGFuZz0neC1kZWZhdWx0Jz4gICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgIDwvcmRmOkFsdD4KICA8L2RjOmRlc2NyaXB0aW9\n" - "uPgogPC9yZGY6RGVzY3JpcHRpb24+Cgo8L3JkZjpSREY+CjwveDp4YXBtZXRhPgogICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA\n" - "ogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC\n" - "AgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI\n" - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAg\n" - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA\n" - "gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgIC\n" - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0ndyc/P\n" - "v/uAA5BZG9iZQBkQAAAAAH/2wCEAAQDAwMDAwQDAwQGBAMEBgcFBAQFBwgGBgcGBggKCAkJCQkI\n" - "CgoMDAwMDAoMDAwMDAwMDAwMDAwMDAwMDAwMDAwBBAUFCAcIDwoKDxQODg4UFA4ODg4UEQwMDAw\n" - "MEREMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDP/AABEIAGQAZAMBEQACEQEDEQ\n" - "H/3QAEAA3/xAGiAAAABwEBAQEBAAAAAAAAAAAEBQMCBgEABwgJCgsBAAICAwEBAQEBAAAAAAAAA\n" - "AEAAgMEBQYHCAkKCxAAAgEDAwIEAgYHAwQCBgJzAQIDEQQABSESMUFRBhNhInGBFDKRoQcVsUIj\n" - "wVLR4TMWYvAkcoLxJUM0U5KismNzwjVEJ5OjszYXVGR0w9LiCCaDCQoYGYSURUaktFbTVSga8uP\n" - "zxNTk9GV1hZWltcXV5fVmdoaWprbG1ub2N0dXZ3eHl6e3x9fn9zhIWGh4iJiouMjY6PgpOUlZaX\n" - "mJmam5ydnp+So6SlpqeoqaqrrK2ur6EQACAgECAwUFBAUGBAgDA20BAAIRAwQhEjFBBVETYSIGc\n" - "YGRMqGx8BTB0eEjQhVSYnLxMyQ0Q4IWklMlomOywgdz0jXiRIMXVJMICQoYGSY2RRonZHRVN/Kj\n" - "s8MoKdPj84SUpLTE1OT0ZXWFlaW1xdXl9UZWZnaGlqa2xtbm9kdXZ3eHl6e3x9fn9zhIWGh4iJi\n" - "ouMjY6Pg5SVlpeYmZqbnJ2en5KjpKWmp6ipqqusra6vr/2gAMAwEAAhEDEQA/APBnplwPAdR+GB\n" - "KY6dYtNG1w39yh4+xb+zIksgEfFaRSSoIx8f7RPRRkSWQimM+lRmwWVXFWYigHxUUVoMiJM+Fj0\n" - "tg0RBegLE0Wu+3c+GTBazFCGI7HtSp9slbFYYzyoBsegw2hY1Afl3wqqRqahk+0tDgKpgu4DAUU\n" - "+HY+GRS2ePiMKtUB3G+KGuONq//Q8OzpFbW5WnxMop4k9crG5ZnZNJkEOn21utVRYw7HxZtz+OR\n" - "vdsrZ2lRtci4aVxFEQA0neg/ZXxJpTITNNuOFss0vSotYNvZ2qGRkPKSTqiU8Sdqk5SZU5Ix8XJ\n" - "NNZ8k6bp8TtM73OputUtYq0Unux/hkRkJOzZLCAN2KR+VpbtSkCBaDnIzdlWu59u+XeJTjeASk8\n" - "+juZOESEAVqx8BvU/PJibScTrTy09560hkWOGFd2YgFnPQKD19zhOSkxw2l8Vm6XAiYb8gg+k5O\n" - "9mnhoon9H3cs5s7WF5pp29OGGMFndyaAKBuTiEEPQLD8h/NDmNdYlttNkYjlbFjcXCr3LLH8II8\n" - "C2WUGviZvon/OPWkm3RNSv72SYllMkKxQRV67CQMSKYQAxMkR/wBC56d61P0heel4cYuVOXWvTp\n" - "h4Qjjf/9Hw5qBYyISaqjBV+QpvkAzKcki4HomnIxck/wBhtlR2bhunvlDywddMUl4zW+kQ9FQ8X\n" - "nfuSewrtmPkycPvc/DhMhvyegXOrWWhmLQPKlsj6xIAiLCoZkY96nv7npmJvI2XOjQFMl0fyRqM\n" - "NoxvZvrGt33wlATwiMnVnY1LEdSfuyXF3KIDmUu88w2XlnTl8raAlb2ZFfVL0jdYRtQnxc7BfDC\n" - "OaJR7nm3me5tdOtjbMvp3ZRXkV6chVQRX79hmVjgZG+jgZ5jHGhzecXF5LPL6jEjstSSaDM51Ka\n" - "6MZ9S1C0sEBe8uZo4YCBXdjxGw60wEWyEqfUHkT8vLXRJFuLdTcaqfhlvWUErtukZ3ABPUjIXTE\n" - "m3rGmeV2Tk5UKz/AG/E/wAcgZKya20C3b02kjYtH8AqCygbkUH0nLYlgUb+gbWtPbpXt/n2ybB/\n" - "/9Lw4oaVxGd+PxH3qBkGaY3KyiSP01IkiUclH8sg+LKydm6INvZvKsFu+kWtvD8LRoFNRup6moO\n" - "aqd277HsGW+XPLmn6XM17FF6l7vW4fd2Zuu+RFls2tmUNrLJb7TSBertGQGqetDkxE0na0pvtHs\n" - "QkszWyiGAG5laYlnkeMVHJj8sA5rPk+SvMepTalqlxd3B5zTOXdj/MxqafLpm5xioh5nPK5kpRG\n" - "pkcKAST0A6k5NpfUP5K/ki1ssHmHzF+71KRQ8Nud/Qibb/kYw6/yjbrXISlSH07YaHbWyxx2kXE\n" - "KACB2zHJtLI7XSelBRvH2xCpvaaTDHXkOTVBPcUG2479RlsdmJVPRtvV+ylenQ0y62FP/9PxRpo\n" - "WG5FxKKxKFDA+GVS5NsebLdFsRePc3siVW4f4QR0QVAGYeSXR2unhtZ6s60K6jt+MMSFwtF2+xX\n" - "wr7eGUGLlRPQMsE2vxQm7itxKg3VCfT2+nb8cDYaCDtfOXmCCcROrQrUhkkCHYn6emRMqZxjbLd\n" - "F1+W/4xajHzjNCtQKMffETWUdngX5p+QZ9A8xS6hbo0ui37NNDPT7DOalHpsCD08Rmyw5ARTpdV\n" - "gIPEF35MeRn80ed4S5EdrpKm9kZ15K0iH92hB7Me/tmS60vt/QrCYyekiBdgSTXcjqV9q9MokFD\n" - "N7S3aFVVR8RoK9zldqndvAY6nffr/AGYQqLhjdpCoIAZW22HavU/LJBUP9WblX0xTw7fOmWsX/9\n" - "Tw7FdvMqWkQ3Z1qfED+mQIbI77PX/LFis9vBajZm2Y+x65rMh3t30Bsze400aVaIbSLk6r8CMRT\n" - "l/NmOcllnGDD9Y8uecNfEEiXrMgDGWAyGOOu5WlB+vMrHODTlxZCdjsyFdB006VpVtLasurQxBL\n" - "64WiLI4/aFT1ANOXemV5piR2b9NiljB4yyHy9CLOVI5GJhB+CvXY9R8xmINzs5HNZ+Z96BZpbxA\n" - "fVJo39UFefwopYgL4nMiMd2qZoIn/AJx00u3t/Lt7qpp9Yv5GLf5MUTERqfbvmzBeezjd9H+VlL\n" - "wSQzBqsvOGQD7L12rXsemPNxmXQSxxIPU2nFV4HYqR1xEUWj4ZAxBryr2G+J2VGDZlLrxUH6KZA\n" - "Fkqb15VFelfwy+2FP8A/9Xxlf6AdA182Yk9eFeLxSjoVfcfSMo4uIOfkweFOnpvlWYrLEwNFAA+\n" - "nMOYdrhFvQLeSO7coBXiK8iKiv07Zj8Ac4QtNrW1njUcKcT+yAR/xGmR4WcsStLpTuPU9IFaEsV\n" - "BP3k4m2AgBzSwyQNcIwNTE1aI3wnam9O2Ug7s5Ckk/NDndeVXa2H78MqqV6jmeBp9+ZWKXqDjZ4\n" - "+gvVvy30qCy0qzsLRBCnBI2VdgUTqPvOZ7y+Q7pz+bn5q6d+VflZxZlJ/NN4ypptk5qtB9qRwDX\n" - "gn/AAx2y2ItpfKFv+eH5qNeTajJ5ovVaVywSqvEtTUKqupAA6D2y0BNPtv/AJx//M5PzL8mJeXT\n" - "L+ndPf6rqarSpkAqsnEAAeoN6DpkJRYci9lROSgSUUH9o9K5Tw0ztfSHnXkOtK9q+PHwydq//9b\n" - "yxrVoZNBtNSA5zRMPXmH8j0CLXuBmHE+qneamHpEuqYeV7pzFVTRgQK5XMNmnlb1vyyY5QA1OwJ\n" - "+eUF2seTOLu5s7azVIVAkpVn/hhnIALG73Yz5jvb1dICqzpDNIqyFD8SxH7R28cxibZCiWOsdJs\n" - "PTM6XNstPhnkjIhcHuJBVfvOCiUSn0TfWrTTLjyw8guA/PifTO3xcxxA8a5ZAbimvJP0m3p/kFF\n" - "WxhmpWQJ9NW3zZPHz5vlb/nIDVbrWfzO1RJhxGnpDaRL/khA1T7ktmSOTAJhZaAUtLawsbayl8v\n" - "xWi3Gpay0cF3HPcFRJJHJMXVrcJ8UaAFG5LWjF8tAYW9H/wCcOo9bTzxrt/owkTyksZW5gkIKvI\n" - "7k26nvyReRJHyyBWT7dWQyOWlbnK2526e1O1MqIUFE84uPLkOdK9RXI0E2/wD/1/DA1bURZLY/W\n" - "ZDZqwb0eXw7dMgIi7bjllVXsz7yNcfWC0Vd3Ip92Y2UOz0cnsPlwyx8xQ/u24sMxCadoJp9LOXk\n" - "VX/uwRUE0BI8cokbLMyoKouHu2MaKGXw7fLDwgoGSkbHpaNZyLLHRSKcFFQQRvUdMlwUFOQyLzr\n" - "ztpCaba6fPau4ijv4OURY8AjVFKV7ZZiO+7Vnh6XvXkSWNbW2WTb92KDxIFMzwHlZc3zX+fuizW\n" - "f5p3ty8XGDU4YLmCQiisyII3+4rvl8UB5ffEghRGvOm7AbnvWvjk1fen/ONPldPKP5aWOpPCfr2\n" - "uE31y6q2wbaMEn+VAMDSdyzrzj+avlHyTp0l/r2rxWFuHWJuIeacu4qFCRgsajfBwsty89/6Gr/\n" - "ACa9an+JL/hSnrfoubhXwpXpjwhaL//Q8E1AqtcAZMs8l6i1nqMa1oSVP0VynKLDmaWdSfQXl69\n" - "jF1Jv8MhDb5rpB3AO7INRRLhhGp4R05FgaGvTMU8200xS70zVDMRp2pTIOvBmB3PgQP15kxIcnD\n" - "LH/EEz0rRvOJhldr9pQtCqyd6VrShGTqw5d4ARv9jHfOGl+ZJNMluLkyenaFbiRdqFYW5nrWuwO\n" - "MKB5MdSMRxnhlu9N8p6lLFpti63FUjCtFJTrDKvse2bEDZ4XJ9RZB+YPli2/Mjy5bxoUi1a0YS2\n" - "85UOwIXiy9jRu+TBppfOF1+V3m22vrdpNPM8cs/oo0VJlUqQPjValR3+IZNNvtLS9Yu9Mi0/TJr\n" - "kyp6QhWVVCIWRATsKBemwwFrDzT87fybs/wA1bW21PRb+DTvNlgGSRp6iC8i3KJJx+y6n7D0Pwm\n" - "hxBZXT55/6Fi/Nf0PW+qWXq+t6X1X67F6vD/ftK04V/wBl344U8b//0fBapxheVh9ocV+nviqY2\n" - "/qQJDew/bioWHiuQ8m0bbvaPKGtQ6jaxSo9JloCK75gZI0Xb4sgkHo8MouoAvP94BsRmGY7uWJU\n" - "gzbypOQpNOvIdK4Nw2WCE2tXulTkjEEbdafgclxMhFBas93dwyQzsWDghlJFONKHJCZtjOFBJfy\n" - "j1y9vPL9zpbIs0WkXL2sUjA8hDXlGCRXtt07ZuYvL5KJeo6bfajbkzWkcToR8dqshZ6in2fhNK/\n" - "PDTUlXmHVvMdr5o0v9H2kdrqGpfu7m0nkY87Uf7tkKAU4/s03ynLkEBbfihx7dGT6va67LbRMNR\n" - "aKOBuUTKgIBXoK1BOYR1M3aQ0mOt9yxUeZNdtJhFapLqMluSXkg5oxJrUMW5KevQ9MmNXXNqOiH\n" - "Rr/Hmv8A1r9I/oj95w+r+j9Yf1+NP5+nXtTD+dF8tkfkOlv/0vC3ph7f0/alcVTbS4A8QibuKb5\n" - "RI05EBYRFpdX3ly79a2qYCavH/EY7TCYyMD5PSdD8+wXUSn1ArDqOhBzFlipz4ZwWbaV5htbsgF\n" - "qg9crMXKErGyYwajFGzxyHlGSePbbwyqg5UZlCaxrFpaWU95LIqrEjMAT4Dp9OShGy1ZslBhv/A\n" - "Dj9rd/a+aL+xUK+m38L3d0HrxRo2HFtu5D8c27y8t30raarbWkU+u6g4gsNORn+EcUaSh2Pc0/4\n" - "lgtAjezzbT9SutY1i782al8Nxdyotqh6xWybIg+jc5q8s+I27bFDgFPQp9RE+nrag70+L6crrZu\n" - "4jajokdv6LW/Dii1Wo61PXKQN3KPK0L+h4/rnD/K5V78a5LhXxd3/0/DMXXtwxVNtL9Xkaf3f7N\n" - "etfbKMjdjtkZ9D6ufrlK0+HpX8coF9HJ26sXvfqXrf7i/U+uften/d/wCyrmQL6uOav0pvpP8Ai\n" - "b1F+rV59+vH6a5XLhcjH4nRmY/xpxHP0/UptWvT6Mx/RbmjxWK+aP8AFf1M/pCv1Kvxen9inavf\n" - "MrFwXtzcLUeLXq5Mv/I3nz1b0v8AjofuKVry9KrUpTanOlf9jmQ68va/zH9b/COn/o7/AI431mP\n" - "65SvLh+zWvbl9rMfNfC34K4kmj9T6lD6FKclp/DNYXZx5srsPrHor6nXvkgxTPS/U+rv6dPU5mt\n" - "fngFN5ulv+l/pL/Lp/scerHo//2Q==\n"; - -static std::string gCommandLine; - -TEST(Base64, LargeSample) { - LOG(LS_VERBOSE) << "Testing specific base64 file"; - - char unescaped[64 * 1024]; - - // unescape that massive blob above - size_t size = Base64Unescape(SpecificTest, - sizeof(SpecificTest), - unescaped, - sizeof(unescaped)); - - EXPECT_EQ(size, sizeof(testbase64)); - EXPECT_EQ(0, memcmp(testbase64, unescaped, sizeof(testbase64))); -} - -bool DecodeTest(const char* encoded, size_t expect_unparsed, - const char* decoded, Base64::DecodeFlags flags) -{ - std::string result; - size_t consumed = 0, encoded_len = strlen(encoded); - bool success = Base64::DecodeFromArray(encoded, encoded_len, flags, - &result, &consumed); - size_t unparsed = encoded_len - consumed; - EXPECT_EQ(expect_unparsed, unparsed) << "\"" << encoded - << "\" -> \"" << decoded - << "\""; - EXPECT_STREQ(decoded, result.c_str()); - return success; -} - -#define Flags(x,y,z) \ - Base64::DO_PARSE_##x | Base64::DO_PAD_##y | Base64::DO_TERM_##z - -TEST(Base64, DecodeParseOptions) { - // Trailing whitespace - EXPECT_TRUE (DecodeTest("YWJjZA== ", 1, "abcd", Flags(STRICT, YES, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA== ", 0, "abcd", Flags(WHITE, YES, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA== ", 0, "abcd", Flags(ANY, YES, CHAR))); - - // Embedded whitespace - EXPECT_FALSE(DecodeTest("YWJjZA= =", 3, "abcd", Flags(STRICT, YES, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA= =", 0, "abcd", Flags(WHITE, YES, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA= =", 0, "abcd", Flags(ANY, YES, CHAR))); - - // Embedded non-base64 characters - EXPECT_FALSE(DecodeTest("YWJjZA=*=", 3, "abcd", Flags(STRICT, YES, CHAR))); - EXPECT_FALSE(DecodeTest("YWJjZA=*=", 3, "abcd", Flags(WHITE, YES, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA=*=", 0, "abcd", Flags(ANY, YES, CHAR))); - - // Unexpected padding characters - EXPECT_FALSE(DecodeTest("YW=JjZA==", 7, "a", Flags(STRICT, YES, CHAR))); - EXPECT_FALSE(DecodeTest("YW=JjZA==", 7, "a", Flags(WHITE, YES, CHAR))); - EXPECT_TRUE (DecodeTest("YW=JjZA==", 0, "abcd", Flags(ANY, YES, CHAR))); -} - -TEST(Base64, DecodePadOptions) { - // Padding - EXPECT_TRUE (DecodeTest("YWJjZA==", 0, "abcd", Flags(STRICT, YES, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA==", 0, "abcd", Flags(STRICT, ANY, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA==", 2, "abcd", Flags(STRICT, NO, CHAR))); - - // Incomplete padding - EXPECT_FALSE(DecodeTest("YWJjZA=", 1, "abcd", Flags(STRICT, YES, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA=", 1, "abcd", Flags(STRICT, ANY, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA=", 1, "abcd", Flags(STRICT, NO, CHAR))); - - // No padding - EXPECT_FALSE(DecodeTest("YWJjZA", 0, "abcd", Flags(STRICT, YES, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA", 0, "abcd", Flags(STRICT, ANY, CHAR))); - EXPECT_TRUE (DecodeTest("YWJjZA", 0, "abcd", Flags(STRICT, NO, CHAR))); -} - -TEST(Base64, DecodeTerminateOptions) { - // Complete quantum - EXPECT_TRUE (DecodeTest("YWJj", 0, "abc", Flags(STRICT, NO, BUFFER))); - EXPECT_TRUE (DecodeTest("YWJj", 0, "abc", Flags(STRICT, NO, CHAR))); - EXPECT_TRUE (DecodeTest("YWJj", 0, "abc", Flags(STRICT, NO, ANY))); - - // Complete quantum with trailing data - EXPECT_FALSE(DecodeTest("YWJj*", 1, "abc", Flags(STRICT, NO, BUFFER))); - EXPECT_TRUE (DecodeTest("YWJj*", 1, "abc", Flags(STRICT, NO, CHAR))); - EXPECT_TRUE (DecodeTest("YWJj*", 1, "abc", Flags(STRICT, NO, ANY))); - - // Incomplete quantum - EXPECT_FALSE(DecodeTest("YWJ", 0, "ab", Flags(STRICT, NO, BUFFER))); - EXPECT_FALSE(DecodeTest("YWJ", 0, "ab", Flags(STRICT, NO, CHAR))); - EXPECT_TRUE (DecodeTest("YWJ", 0, "ab", Flags(STRICT, NO, ANY))); -} - -TEST(Base64, GetNextBase64Char) { - // The table looks like this: - // "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - char next_char; - EXPECT_TRUE(Base64::GetNextBase64Char('A', &next_char)); - EXPECT_EQ('B', next_char); - EXPECT_TRUE(Base64::GetNextBase64Char('Z', &next_char)); - EXPECT_EQ('a', next_char); - EXPECT_TRUE(Base64::GetNextBase64Char('/', &next_char)); - EXPECT_EQ('A', next_char); - EXPECT_FALSE(Base64::GetNextBase64Char('&', &next_char)); - EXPECT_FALSE(Base64::GetNextBase64Char('Z', NULL)); -} diff --git a/webrtc/base/base_tests.gyp b/webrtc/base/base_tests.gyp deleted file mode 100644 index 406c73e1e..000000000 --- a/webrtc/base/base_tests.gyp +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. -{ - 'includes': [ '../build/common.gypi', ], - 'targets': [ - { - 'target_name': 'webrtc_base_tests_utils', - 'type': 'static_library', - 'sources': [ - 'unittest_main.cc', - # Also use this as a convenient dumping ground for misc files that are - # included by multiple targets below. - 'fakecpumonitor.h', - 'fakenetwork.h', - 'fakesslidentity.h', - 'faketaskrunner.h', - 'gunit.h', - 'testbase64.h', - 'testechoserver.h', - 'win32toolhelp.h', - ], - 'dependencies': [ - 'base.gyp:webrtc_base', - '<(DEPTH)/testing/gtest.gyp:gtest', - ], - }, - { - 'target_name': 'webrtc_base_tests', - 'type': 'executable', - 'dependencies': [ - '<(DEPTH)/testing/gtest.gyp:gtest', - 'base.gyp:webrtc_base', - 'webrtc_base_tests_utils', - ], - 'sources': [ - 'asynchttprequest_unittest.cc', - 'atomicops_unittest.cc', - 'autodetectproxy_unittest.cc', - 'bandwidthsmoother_unittest.cc', - 'base64_unittest.cc', - 'basictypes_unittest.cc', - 'bind_unittest.cc', - 'buffer_unittest.cc', - 'bytebuffer_unittest.cc', - 'byteorder_unittest.cc', - 'callback_unittest.cc', - 'cpumonitor_unittest.cc', - 'crc32_unittest.cc', - 'criticalsection_unittest.cc', - 'event_unittest.cc', - 'filelock_unittest.cc', - 'fileutils_unittest.cc', - 'helpers_unittest.cc', - 'httpbase_unittest.cc', - 'httpcommon_unittest.cc', - 'httpserver_unittest.cc', - 'ipaddress_unittest.cc', - 'logging_unittest.cc', - 'md5digest_unittest.cc', - 'messagedigest_unittest.cc', - 'messagequeue_unittest.cc', - 'multipart_unittest.cc', - 'nat_unittest.cc', - 'network_unittest.cc', - 'nullsocketserver_unittest.cc', - 'optionsfile_unittest.cc', - 'pathutils_unittest.cc', - 'physicalsocketserver_unittest.cc', - 'profiler_unittest.cc', - 'proxy_unittest.cc', - 'proxydetect_unittest.cc', - 'ratelimiter_unittest.cc', - 'ratetracker_unittest.cc', - 'referencecountedsingletonfactory_unittest.cc', - 'rollingaccumulator_unittest.cc', - 'scopedptrcollection_unittest.cc', - 'sha1digest_unittest.cc', - 'sharedexclusivelock_unittest.cc', - 'signalthread_unittest.cc', - 'sigslot_unittest.cc', - 'socket_unittest.cc', - 'socket_unittest.h', - 'socketaddress_unittest.cc', - 'stream_unittest.cc', - 'stringencode_unittest.cc', - 'stringutils_unittest.cc', - # TODO(ronghuawu): Reenable this test. - # 'systeminfo_unittest.cc', - 'task_unittest.cc', - 'testclient_unittest.cc', - 'thread_unittest.cc', - 'timeutils_unittest.cc', - 'urlencode_unittest.cc', - 'versionparsing_unittest.cc', - 'virtualsocket_unittest.cc', - # TODO(ronghuawu): Reenable this test. - # 'windowpicker_unittest.cc', - ], - 'conditions': [ - ['OS=="linux"', { - 'sources': [ - 'latebindingsymboltable_unittest.cc', - # TODO(ronghuawu): Reenable this test. - # 'linux_unittest.cc', - 'linuxfdwalk_unittest.cc', - ], - }], - ['OS=="win"', { - 'sources': [ - 'win32_unittest.cc', - 'win32regkey_unittest.cc', - 'win32socketserver_unittest.cc', - 'win32toolhelp_unittest.cc', - 'win32window_unittest.cc', - 'win32windowpicker_unittest.cc', - 'winfirewall_unittest.cc', - ], - 'sources!': [ - # TODO(ronghuawu): Fix TestUdpReadyToSendIPv6 on windows bot - # then reenable these tests. - 'physicalsocketserver_unittest.cc', - 'socket_unittest.cc', - 'win32socketserver_unittest.cc', - 'win32windowpicker_unittest.cc', - ], - }], - ['OS=="mac"', { - 'sources': [ - 'macsocketserver_unittest.cc', - 'macutils_unittest.cc', - ], - }], - ['os_posix==1', { - 'sources': [ - 'sslidentity_unittest.cc', - 'sslstreamadapter_unittest.cc', - ], - }], - ['OS=="ios" or (OS=="mac" and target_arch!="ia32")', { - 'defines': [ - 'CARBON_DEPRECATED=YES', - ], - }], - ], # conditions - }, - ], -} diff --git a/webrtc/base/basicdefs.h b/webrtc/base/basicdefs.h deleted file mode 100644 index 1dee2ae65..000000000 --- a/webrtc/base/basicdefs.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_BASICDEFS_H_ -#define WEBRTC_BASE_BASICDEFS_H_ - -#if HAVE_CONFIG_H -#include "config.h" // NOLINT -#endif - -#define ARRAY_SIZE(x) (static_cast(sizeof(x) / sizeof(x[0]))) - -#endif // WEBRTC_BASE_BASICDEFS_H_ diff --git a/webrtc/base/basictypes.h b/webrtc/base/basictypes.h deleted file mode 100644 index 8fed1bad9..000000000 --- a/webrtc/base/basictypes.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_BASICTYPES_H_ -#define WEBRTC_BASE_BASICTYPES_H_ - -#include // for NULL, size_t - -#if !(defined(_MSC_VER) && (_MSC_VER < 1600)) -#include // for uintptr_t -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" // NOLINT -#endif - -#include "webrtc/base/constructormagic.h" - -#if !defined(INT_TYPES_DEFINED) -#define INT_TYPES_DEFINED -#ifdef COMPILER_MSVC -typedef unsigned __int64 uint64; -typedef __int64 int64; -#ifndef INT64_C -#define INT64_C(x) x ## I64 -#endif -#ifndef UINT64_C -#define UINT64_C(x) x ## UI64 -#endif -#define INT64_F "I64" -#else // COMPILER_MSVC -// On Mac OS X, cssmconfig.h defines uint64 as uint64_t -// TODO(fbarchard): Use long long for compatibility with chromium on BSD/OSX. -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -typedef uint64_t uint64; -typedef int64_t int64; -#ifndef INT64_C -#define INT64_C(x) x ## LL -#endif -#ifndef UINT64_C -#define UINT64_C(x) x ## ULL -#endif -#define INT64_F "l" -#elif defined(__LP64__) -typedef unsigned long uint64; // NOLINT -typedef long int64; // NOLINT -#ifndef INT64_C -#define INT64_C(x) x ## L -#endif -#ifndef UINT64_C -#define UINT64_C(x) x ## UL -#endif -#define INT64_F "l" -#else // __LP64__ -typedef unsigned long long uint64; // NOLINT -typedef long long int64; // NOLINT -#ifndef INT64_C -#define INT64_C(x) x ## LL -#endif -#ifndef UINT64_C -#define UINT64_C(x) x ## ULL -#endif -#define INT64_F "ll" -#endif // __LP64__ -#endif // COMPILER_MSVC -typedef unsigned int uint32; -typedef int int32; -typedef unsigned short uint16; // NOLINT -typedef short int16; // NOLINT -typedef unsigned char uint8; -typedef signed char int8; -#endif // INT_TYPES_DEFINED - -// Detect compiler is for x86 or x64. -#if defined(__x86_64__) || defined(_M_X64) || \ - defined(__i386__) || defined(_M_IX86) -#define CPU_X86 1 -#endif -// Detect compiler is for arm. -#if defined(__arm__) || defined(_M_ARM) -#define CPU_ARM 1 -#endif -#if defined(CPU_X86) && defined(CPU_ARM) -#error CPU_X86 and CPU_ARM both defined. -#endif -#if !defined(ARCH_CPU_BIG_ENDIAN) && !defined(ARCH_CPU_LITTLE_ENDIAN) -// x86, arm or GCC provided __BYTE_ORDER__ macros -#if CPU_X86 || CPU_ARM || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define ARCH_CPU_LITTLE_ENDIAN -#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define ARCH_CPU_BIG_ENDIAN -#else -#error ARCH_CPU_BIG_ENDIAN or ARCH_CPU_LITTLE_ENDIAN should be defined. -#endif -#endif -#if defined(ARCH_CPU_BIG_ENDIAN) && defined(ARCH_CPU_LITTLE_ENDIAN) -#error ARCH_CPU_BIG_ENDIAN and ARCH_CPU_LITTLE_ENDIAN both defined. -#endif - -#if defined(WEBRTC_WIN) -typedef int socklen_t; -#endif - -// The following only works for C++ -#ifdef __cplusplus -namespace rtc { - template inline T _min(T a, T b) { return (a > b) ? b : a; } - template inline T _max(T a, T b) { return (a < b) ? b : a; } - - // For wait functions that take a number of milliseconds, kForever indicates - // unlimited time. - const int kForever = -1; -} - -#define ALIGNP(p, t) \ - (reinterpret_cast(((reinterpret_cast(p) + \ - ((t) - 1)) & ~((t) - 1)))) -#define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a) - 1))) - -// Note: UNUSED is also defined in common.h -#ifndef UNUSED -#define UNUSED(x) Unused(static_cast(&x)) -#define UNUSED2(x, y) Unused(static_cast(&x)); \ - Unused(static_cast(&y)) -#define UNUSED3(x, y, z) Unused(static_cast(&x)); \ - Unused(static_cast(&y)); \ - Unused(static_cast(&z)) -#define UNUSED4(x, y, z, a) Unused(static_cast(&x)); \ - Unused(static_cast(&y)); \ - Unused(static_cast(&z)); \ - Unused(static_cast(&a)) -#define UNUSED5(x, y, z, a, b) Unused(static_cast(&x)); \ - Unused(static_cast(&y)); \ - Unused(static_cast(&z)); \ - Unused(static_cast(&a)); \ - Unused(static_cast(&b)) -inline void Unused(const void*) {} -#endif // UNUSED - -// Use these to declare and define a static local variable (static T;) so that -// it is leaked so that its destructors are not called at exit. -#define LIBJINGLE_DEFINE_STATIC_LOCAL(type, name, arguments) \ - static type& name = *new type arguments - -#endif // __cplusplus -#endif // WEBRTC_BASE_BASICTYPES_H_ diff --git a/webrtc/base/basictypes_unittest.cc b/webrtc/base/basictypes_unittest.cc deleted file mode 100644 index 20515ecf9..000000000 --- a/webrtc/base/basictypes_unittest.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/basictypes.h" - -#include "webrtc/base/gunit.h" - -namespace rtc { - -TEST(BasicTypesTest, Endian) { - uint16 v16 = 0x1234u; - uint8 first_byte = *reinterpret_cast(&v16); -#if defined(ARCH_CPU_LITTLE_ENDIAN) - EXPECT_EQ(0x34u, first_byte); -#elif defined(ARCH_CPU_BIG_ENDIAN) - EXPECT_EQ(0x12u, first_byte); -#endif -} - -TEST(BasicTypesTest, SizeOfTypes) { - int8 i8 = -1; - uint8 u8 = 1u; - int16 i16 = -1; - uint16 u16 = 1u; - int32 i32 = -1; - uint32 u32 = 1u; - int64 i64 = -1; - uint64 u64 = 1u; - EXPECT_EQ(1u, sizeof(i8)); - EXPECT_EQ(1u, sizeof(u8)); - EXPECT_EQ(2u, sizeof(i16)); - EXPECT_EQ(2u, sizeof(u16)); - EXPECT_EQ(4u, sizeof(i32)); - EXPECT_EQ(4u, sizeof(u32)); - EXPECT_EQ(8u, sizeof(i64)); - EXPECT_EQ(8u, sizeof(u64)); - EXPECT_GT(0, i8); - EXPECT_LT(0u, u8); - EXPECT_GT(0, i16); - EXPECT_LT(0u, u16); - EXPECT_GT(0, i32); - EXPECT_LT(0u, u32); - EXPECT_GT(0, i64); - EXPECT_LT(0u, u64); -} - -TEST(BasicTypesTest, SizeOfConstants) { - EXPECT_EQ(8u, sizeof(INT64_C(0))); - EXPECT_EQ(8u, sizeof(UINT64_C(0))); - EXPECT_EQ(8u, sizeof(INT64_C(0x1234567887654321))); - EXPECT_EQ(8u, sizeof(UINT64_C(0x8765432112345678))); -} - -// Test CPU_ macros -#if !defined(CPU_ARM) && defined(__arm__) -#error expected CPU_ARM to be defined. -#endif -#if !defined(CPU_X86) && (defined(WEBRTC_WIN) || defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)) -#error expected CPU_X86 to be defined. -#endif -#if !defined(ARCH_CPU_LITTLE_ENDIAN) && \ - (defined(WEBRTC_WIN) || defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) || defined(CPU_X86)) -#error expected ARCH_CPU_LITTLE_ENDIAN to be defined. -#endif - -// TODO(fbarchard): Test all macros in basictypes.h - -} // namespace rtc diff --git a/webrtc/base/bind.h b/webrtc/base/bind.h deleted file mode 100644 index 2e3104edf..000000000 --- a/webrtc/base/bind.h +++ /dev/null @@ -1,587 +0,0 @@ -// This file was GENERATED by command: -// pump.py bind.h.pump -// DO NOT EDIT BY HAND!!! - -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// To generate bind.h from bind.h.pump, execute: -// /home/build/google3/third_party/gtest/scripts/pump.py bind.h.pump - -// Bind() is an overloaded function that converts method calls into function -// objects (aka functors). It captures any arguments to the method by value -// when Bind is called, producing a stateful, nullary function object. Care -// should be taken about the lifetime of objects captured by Bind(); the -// returned functor knows nothing about the lifetime of the method's object or -// any arguments passed by pointer, and calling the functor with a destroyed -// object will surely do bad things. -// -// Example usage: -// struct Foo { -// int Test1() { return 42; } -// int Test2() const { return 52; } -// int Test3(int x) { return x*x; } -// float Test4(int x, float y) { return x + y; } -// }; -// -// int main() { -// Foo foo; -// cout << rtc::Bind(&Foo::Test1, &foo)() << endl; -// cout << rtc::Bind(&Foo::Test2, &foo)() << endl; -// cout << rtc::Bind(&Foo::Test3, &foo, 3)() << endl; -// cout << rtc::Bind(&Foo::Test4, &foo, 7, 8.5f)() << endl; -// } - -#ifndef WEBRTC_BASE_BIND_H_ -#define WEBRTC_BASE_BIND_H_ - -#define NONAME - -namespace rtc { -namespace detail { -// This is needed because the template parameters in Bind can't be resolved -// if they're used both as parameters of the function pointer type and as -// parameters to Bind itself: the function pointer parameters are exact -// matches to the function prototype, but the parameters to bind have -// references stripped. This trick allows the compiler to dictate the Bind -// parameter types rather than deduce them. -template struct identity { typedef T type; }; -} // namespace detail - -template -class MethodFunctor0 { - public: - MethodFunctor0(MethodT method, ObjectT* object) - : method_(method), object_(object) {} - R operator()() const { - return (object_->*method_)(); } - private: - MethodT method_; - ObjectT* object_; -}; - -template -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 -MethodFunctor0 -Bind(FP_T(method), ObjectT* object) { - return MethodFunctor0( - method, object); -} - -#undef FP_T -#define FP_T(x) R (ObjectT::*x)() const - -template -MethodFunctor0 -Bind(FP_T(method), const ObjectT* object) { - return MethodFunctor0( - method, object); -} - -#undef FP_T -#define FP_T(x) R (*x)() - -template -Functor0 -Bind(FP_T(function)) { - return Functor0( - function); -} - -#undef FP_T - -template -class MethodFunctor1 { - public: - MethodFunctor1(MethodT method, ObjectT* object, - P1 p1) - : method_(method), object_(object), - p1_(p1) {} - R operator()() const { - return (object_->*method_)(p1_); } - private: - MethodT method_; - ObjectT* object_; - P1 p1_; -}; - -template -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 -MethodFunctor1 -Bind(FP_T(method), ObjectT* object, - typename detail::identity::type p1) { - return MethodFunctor1( - method, object, p1); -} - -#undef FP_T -#define FP_T(x) R (ObjectT::*x)(P1) const - -template -MethodFunctor1 -Bind(FP_T(method), const ObjectT* object, - typename detail::identity::type p1) { - return MethodFunctor1( - method, object, p1); -} - -#undef FP_T -#define FP_T(x) R (*x)(P1) - -template -Functor1 -Bind(FP_T(function), - typename detail::identity::type p1) { - return Functor1( - function, p1); -} - -#undef FP_T - -template -class MethodFunctor2 { - public: - MethodFunctor2(MethodT method, ObjectT* object, - P1 p1, - P2 p2) - : method_(method), object_(object), - p1_(p1), - p2_(p2) {} - R operator()() const { - return (object_->*method_)(p1_, p2_); } - private: - MethodT method_; - ObjectT* object_; - P1 p1_; - P2 p2_; -}; - -template -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 -MethodFunctor2 -Bind(FP_T(method), ObjectT* object, - typename detail::identity::type p1, - typename detail::identity::type p2) { - return MethodFunctor2( - method, object, p1, p2); -} - -#undef FP_T -#define FP_T(x) R (ObjectT::*x)(P1, P2) const - -template -MethodFunctor2 -Bind(FP_T(method), const ObjectT* object, - typename detail::identity::type p1, - typename detail::identity::type p2) { - return MethodFunctor2( - method, object, p1, p2); -} - -#undef FP_T -#define FP_T(x) R (*x)(P1, P2) - -template -Functor2 -Bind(FP_T(function), - typename detail::identity::type p1, - typename detail::identity::type p2) { - return Functor2( - function, p1, p2); -} - -#undef FP_T - -template -class MethodFunctor3 { - public: - MethodFunctor3(MethodT method, ObjectT* object, - P1 p1, - P2 p2, - P3 p3) - : method_(method), object_(object), - p1_(p1), - p2_(p2), - p3_(p3) {} - R operator()() const { - return (object_->*method_)(p1_, p2_, p3_); } - private: - MethodT method_; - ObjectT* object_; - P1 p1_; - P2 p2_; - P3 p3_; -}; - -template -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 -MethodFunctor3 -Bind(FP_T(method), ObjectT* object, - typename detail::identity::type p1, - typename detail::identity::type p2, - typename detail::identity::type p3) { - return MethodFunctor3( - method, object, p1, p2, p3); -} - -#undef FP_T -#define FP_T(x) R (ObjectT::*x)(P1, P2, P3) const - -template -MethodFunctor3 -Bind(FP_T(method), const ObjectT* object, - typename detail::identity::type p1, - typename detail::identity::type p2, - typename detail::identity::type p3) { - return MethodFunctor3( - method, object, p1, p2, p3); -} - -#undef FP_T -#define FP_T(x) R (*x)(P1, P2, P3) - -template -Functor3 -Bind(FP_T(function), - typename detail::identity::type p1, - typename detail::identity::type p2, - typename detail::identity::type p3) { - return Functor3( - function, p1, p2, p3); -} - -#undef FP_T - -template -class MethodFunctor4 { - public: - MethodFunctor4(MethodT method, ObjectT* object, - P1 p1, - P2 p2, - P3 p3, - P4 p4) - : method_(method), object_(object), - p1_(p1), - p2_(p2), - p3_(p3), - p4_(p4) {} - R operator()() const { - return (object_->*method_)(p1_, p2_, p3_, p4_); } - private: - MethodT method_; - ObjectT* object_; - P1 p1_; - P2 p2_; - P3 p3_; - P4 p4_; -}; - -template -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 -MethodFunctor4 -Bind(FP_T(method), ObjectT* object, - typename detail::identity::type p1, - typename detail::identity::type p2, - typename detail::identity::type p3, - typename detail::identity::type p4) { - return MethodFunctor4( - method, object, p1, p2, p3, p4); -} - -#undef FP_T -#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4) const - -template -MethodFunctor4 -Bind(FP_T(method), const ObjectT* object, - typename detail::identity::type p1, - typename detail::identity::type p2, - typename detail::identity::type p3, - typename detail::identity::type p4) { - return MethodFunctor4( - method, object, p1, p2, p3, p4); -} - -#undef FP_T -#define FP_T(x) R (*x)(P1, P2, P3, P4) - -template -Functor4 -Bind(FP_T(function), - typename detail::identity::type p1, - typename detail::identity::type p2, - typename detail::identity::type p3, - typename detail::identity::type p4) { - return Functor4( - function, p1, p2, p3, p4); -} - -#undef FP_T - -template -class MethodFunctor5 { - public: - MethodFunctor5(MethodT method, ObjectT* object, - P1 p1, - P2 p2, - P3 p3, - P4 p4, - P5 p5) - : method_(method), object_(object), - p1_(p1), - p2_(p2), - p3_(p3), - p4_(p4), - p5_(p5) {} - R operator()() const { - return (object_->*method_)(p1_, p2_, p3_, p4_, p5_); } - private: - MethodT method_; - ObjectT* object_; - P1 p1_; - P2 p2_; - P3 p3_; - P4 p4_; - P5 p5_; -}; - -template -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 -MethodFunctor5 -Bind(FP_T(method), ObjectT* object, - typename detail::identity::type p1, - typename detail::identity::type p2, - typename detail::identity::type p3, - typename detail::identity::type p4, - typename detail::identity::type p5) { - return MethodFunctor5( - method, object, p1, p2, p3, p4, p5); -} - -#undef FP_T -#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5) const - -template -MethodFunctor5 -Bind(FP_T(method), const ObjectT* object, - typename detail::identity::type p1, - typename detail::identity::type p2, - typename detail::identity::type p3, - typename detail::identity::type p4, - typename detail::identity::type p5) { - return MethodFunctor5( - method, object, p1, p2, p3, p4, p5); -} - -#undef FP_T -#define FP_T(x) R (*x)(P1, P2, P3, P4, P5) - -template -Functor5 -Bind(FP_T(function), - typename detail::identity::type p1, - typename detail::identity::type p2, - typename detail::identity::type p3, - typename detail::identity::type p4, - typename detail::identity::type p5) { - return Functor5( - function, p1, p2, p3, p4, p5); -} - -#undef FP_T - -} // namespace rtc - -#undef NONAME - -#endif // WEBRTC_BASE_BIND_H_ diff --git a/webrtc/base/bind.h.pump b/webrtc/base/bind.h.pump deleted file mode 100644 index b5663c45d..000000000 --- a/webrtc/base/bind.h.pump +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// To generate bind.h from bind.h.pump, execute: -// /home/build/google3/third_party/gtest/scripts/pump.py bind.h.pump - -// Bind() is an overloaded function that converts method calls into function -// objects (aka functors). It captures any arguments to the method by value -// when Bind is called, producing a stateful, nullary function object. Care -// should be taken about the lifetime of objects captured by Bind(); the -// returned functor knows nothing about the lifetime of the method's object or -// any arguments passed by pointer, and calling the functor with a destroyed -// object will surely do bad things. -// -// Example usage: -// struct Foo { -// int Test1() { return 42; } -// int Test2() const { return 52; } -// int Test3(int x) { return x*x; } -// float Test4(int x, float y) { return x + y; } -// }; -// -// int main() { -// Foo foo; -// cout << rtc::Bind(&Foo::Test1, &foo)() << endl; -// cout << rtc::Bind(&Foo::Test2, &foo)() << endl; -// cout << rtc::Bind(&Foo::Test3, &foo, 3)() << endl; -// cout << rtc::Bind(&Foo::Test4, &foo, 7, 8.5f)() << endl; -// } - -#ifndef WEBRTC_BASE_BIND_H_ -#define WEBRTC_BASE_BIND_H_ - -#define NONAME - -namespace rtc { -namespace detail { -// This is needed because the template parameters in Bind can't be resolved -// if they're used both as parameters of the function pointer type and as -// parameters to Bind itself: the function pointer parameters are exact -// matches to the function prototype, but the parameters to bind have -// references stripped. This trick allows the compiler to dictate the Bind -// parameter types rather than deduce them. -template struct identity { typedef T type; }; -} // namespace detail - -$var n = 5 -$range i 0..n -$for i [[ -$range j 1..i - -template -class MethodFunctor$i { - public: - MethodFunctor$i(MethodT method, ObjectT* object$for j [[, - P$j p$j]]) - : method_(method), object_(object)$for j [[, - p$(j)_(p$j)]] {} - R operator()() const { - return (object_->*method_)($for j , [[p$(j)_]]); } - private: - MethodT method_; - ObjectT* object_;$for j [[ - - P$j p$(j)_;]] - -}; - -template -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 -MethodFunctor$i -Bind(FP_T(method), ObjectT* object$for j [[, - typename detail::identity::type p$j]]) { - return MethodFunctor$i( - method, object$for j [[, p$j]]); -} - -#undef FP_T -#define FP_T(x) R (ObjectT::*x)($for j , [[P$j]]) const - -template -MethodFunctor$i -Bind(FP_T(method), const ObjectT* object$for j [[, - typename detail::identity::type p$j]]) { - return MethodFunctor$i( - method, object$for j [[, p$j]]); -} - -#undef FP_T -#define FP_T(x) R (*x)($for j , [[P$j]]) - -template -Functor$i -Bind(FP_T(function)$for j [[, - typename detail::identity::type p$j]]) { - return Functor$i( - function$for j [[, p$j]]); -} - -#undef FP_T - -]] - -} // namespace rtc - -#undef NONAME - -#endif // WEBRTC_BASE_BIND_H_ diff --git a/webrtc/base/bind_unittest.cc b/webrtc/base/bind_unittest.cc deleted file mode 100644 index ed8dd5cf2..000000000 --- a/webrtc/base/bind_unittest.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/bind.h" -#include "webrtc/base/gunit.h" - -namespace rtc { - -namespace { - -struct MethodBindTester { - void NullaryVoid() { ++call_count; } - int NullaryInt() { ++call_count; return 1; } - int NullaryConst() const { ++call_count; return 2; } - void UnaryVoid(int dummy) { ++call_count; } - template T Identity(T value) { ++call_count; return value; } - int UnaryByRef(int& value) const { ++call_count; return ++value; } // NOLINT - int Multiply(int a, int b) const { ++call_count; return a * b; } - 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) { - MethodBindTester object = {0}; - EXPECT_EQ(0, object.call_count); - Bind(&MethodBindTester::NullaryVoid, &object)(); - EXPECT_EQ(1, object.call_count); - EXPECT_EQ(1, Bind(&MethodBindTester::NullaryInt, &object)()); - EXPECT_EQ(2, object.call_count); - EXPECT_EQ(2, Bind(&MethodBindTester::NullaryConst, - static_cast(&object))()); - EXPECT_EQ(3, object.call_count); - Bind(&MethodBindTester::UnaryVoid, &object, 5)(); - EXPECT_EQ(4, object.call_count); - EXPECT_EQ(100, Bind(&MethodBindTester::Identity, &object, 100)()); - EXPECT_EQ(5, object.call_count); - const std::string string_value("test string"); - EXPECT_EQ(string_value, Bind(&MethodBindTester::Identity, - &object, string_value)()); - EXPECT_EQ(6, object.call_count); - int value = 11; - EXPECT_EQ(12, Bind(&MethodBindTester::UnaryByRef, &object, value)()); - EXPECT_EQ(12, value); - EXPECT_EQ(7, object.call_count); - EXPECT_EQ(56, Bind(&MethodBindTester::Multiply, &object, 7, 8)()); - 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 rtc diff --git a/webrtc/base/buffer.h b/webrtc/base/buffer.h deleted file mode 100644 index dbe7b1aa7..000000000 --- a/webrtc/base/buffer.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_BUFFER_H_ -#define WEBRTC_BASE_BUFFER_H_ - -#include - -#include "webrtc/base/scoped_ptr.h" - -namespace rtc { - -// Basic buffer class, can be grown and shrunk dynamically. -// Unlike std::string/vector, does not initialize data when expanding capacity. -class Buffer { - public: - Buffer() { - Construct(NULL, 0, 0); - } - Buffer(const void* data, size_t length) { - Construct(data, length, length); - } - Buffer(const void* data, size_t length, size_t capacity) { - Construct(data, length, capacity); - } - Buffer(const Buffer& buf) { - Construct(buf.data(), buf.length(), buf.length()); - } - - const char* data() const { return data_.get(); } - char* data() { return data_.get(); } - // TODO: should this be size(), like STL? - size_t length() const { return length_; } - size_t capacity() const { return capacity_; } - - Buffer& operator=(const Buffer& buf) { - if (&buf != this) { - Construct(buf.data(), buf.length(), buf.length()); - } - return *this; - } - bool operator==(const Buffer& buf) const { - return (length_ == buf.length() && - memcmp(data_.get(), buf.data(), length_) == 0); - } - bool operator!=(const Buffer& buf) const { - return !operator==(buf); - } - - void SetData(const void* data, size_t length) { - ASSERT(data != NULL || length == 0); - SetLength(length); - memcpy(data_.get(), data, length); - } - void AppendData(const void* data, size_t length) { - ASSERT(data != NULL || length == 0); - size_t old_length = length_; - SetLength(length_ + length); - memcpy(data_.get() + old_length, data, length); - } - void SetLength(size_t length) { - SetCapacity(length); - length_ = length; - } - void SetCapacity(size_t capacity) { - if (capacity > capacity_) { - rtc::scoped_ptr data(new char[capacity]); - memcpy(data.get(), data_.get(), length_); - data_.swap(data); - capacity_ = capacity; - } - } - - void TransferTo(Buffer* buf) { - ASSERT(buf != NULL); - buf->data_.reset(data_.release()); - buf->length_ = length_; - buf->capacity_ = capacity_; - Construct(NULL, 0, 0); - } - - protected: - void Construct(const void* data, size_t length, size_t capacity) { - data_.reset(new char[capacity_ = capacity]); - SetData(data, length); - } - - scoped_ptr data_; - size_t length_; - size_t capacity_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_BUFFER_H_ diff --git a/webrtc/base/buffer_unittest.cc b/webrtc/base/buffer_unittest.cc deleted file mode 100644 index 71b3f89e3..000000000 --- a/webrtc/base/buffer_unittest.cc +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/buffer.h" -#include "webrtc/base/gunit.h" - -namespace rtc { - -static const char kTestData[] = { - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF -}; - -TEST(BufferTest, TestConstructDefault) { - Buffer buf; - EXPECT_EQ(0U, buf.length()); - EXPECT_EQ(0U, buf.capacity()); - EXPECT_EQ(Buffer(), buf); -} - -TEST(BufferTest, TestConstructEmptyWithCapacity) { - Buffer buf(NULL, 0, 256U); - EXPECT_EQ(0U, buf.length()); - EXPECT_EQ(256U, buf.capacity()); - EXPECT_EQ(Buffer(), buf); -} - -TEST(BufferTest, TestConstructData) { - Buffer buf(kTestData, sizeof(kTestData)); - EXPECT_EQ(sizeof(kTestData), buf.length()); - EXPECT_EQ(sizeof(kTestData), buf.capacity()); - EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData))); - EXPECT_EQ(Buffer(kTestData, sizeof(kTestData)), buf); -} - -TEST(BufferTest, TestConstructDataWithCapacity) { - Buffer buf(kTestData, sizeof(kTestData), 256U); - EXPECT_EQ(sizeof(kTestData), buf.length()); - EXPECT_EQ(256U, buf.capacity()); - EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData))); - EXPECT_EQ(Buffer(kTestData, sizeof(kTestData)), buf); -} - -TEST(BufferTest, TestConstructCopy) { - Buffer buf1(kTestData, sizeof(kTestData), 256), buf2(buf1); - EXPECT_EQ(sizeof(kTestData), buf2.length()); - EXPECT_EQ(sizeof(kTestData), buf2.capacity()); // capacity isn't copied - EXPECT_EQ(0, memcmp(buf2.data(), kTestData, sizeof(kTestData))); - EXPECT_EQ(buf1, buf2); -} - -TEST(BufferTest, TestAssign) { - Buffer buf1, buf2(kTestData, sizeof(kTestData), 256); - EXPECT_NE(buf1, buf2); - buf1 = buf2; - EXPECT_EQ(sizeof(kTestData), buf1.length()); - EXPECT_EQ(sizeof(kTestData), buf1.capacity()); // capacity isn't copied - EXPECT_EQ(0, memcmp(buf1.data(), kTestData, sizeof(kTestData))); - EXPECT_EQ(buf1, buf2); -} - -TEST(BufferTest, TestSetData) { - Buffer buf; - buf.SetData(kTestData, sizeof(kTestData)); - EXPECT_EQ(sizeof(kTestData), buf.length()); - EXPECT_EQ(sizeof(kTestData), buf.capacity()); - EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData))); -} - -TEST(BufferTest, TestAppendData) { - Buffer buf(kTestData, sizeof(kTestData)); - buf.AppendData(kTestData, sizeof(kTestData)); - EXPECT_EQ(2 * sizeof(kTestData), buf.length()); - EXPECT_EQ(2 * sizeof(kTestData), buf.capacity()); - EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData))); - EXPECT_EQ(0, memcmp(buf.data() + sizeof(kTestData), - kTestData, sizeof(kTestData))); -} - -TEST(BufferTest, TestSetLengthSmaller) { - Buffer buf; - buf.SetData(kTestData, sizeof(kTestData)); - buf.SetLength(sizeof(kTestData) / 2); - EXPECT_EQ(sizeof(kTestData) / 2, buf.length()); - EXPECT_EQ(sizeof(kTestData), buf.capacity()); - EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData) / 2)); -} - -TEST(BufferTest, TestSetLengthLarger) { - Buffer buf; - buf.SetData(kTestData, sizeof(kTestData)); - buf.SetLength(sizeof(kTestData) * 2); - EXPECT_EQ(sizeof(kTestData) * 2, buf.length()); - EXPECT_EQ(sizeof(kTestData) * 2, buf.capacity()); - EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData))); -} - -TEST(BufferTest, TestSetCapacitySmaller) { - Buffer buf; - buf.SetData(kTestData, sizeof(kTestData)); - buf.SetCapacity(sizeof(kTestData) / 2); // should be ignored - EXPECT_EQ(sizeof(kTestData), buf.length()); - EXPECT_EQ(sizeof(kTestData), buf.capacity()); - EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData))); -} - -TEST(BufferTest, TestSetCapacityLarger) { - Buffer buf(kTestData, sizeof(kTestData)); - buf.SetCapacity(sizeof(kTestData) * 2); - EXPECT_EQ(sizeof(kTestData), buf.length()); - EXPECT_EQ(sizeof(kTestData) * 2, buf.capacity()); - EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData))); -} - -TEST(BufferTest, TestSetCapacityThenSetLength) { - Buffer buf(kTestData, sizeof(kTestData)); - buf.SetCapacity(sizeof(kTestData) * 4); - memcpy(buf.data() + sizeof(kTestData), kTestData, sizeof(kTestData)); - buf.SetLength(sizeof(kTestData) * 2); - EXPECT_EQ(sizeof(kTestData) * 2, buf.length()); - EXPECT_EQ(sizeof(kTestData) * 4, buf.capacity()); - EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData))); - EXPECT_EQ(0, memcmp(buf.data() + sizeof(kTestData), - kTestData, sizeof(kTestData))); -} - -TEST(BufferTest, TestTransfer) { - Buffer buf1(kTestData, sizeof(kTestData), 256U), buf2; - buf1.TransferTo(&buf2); - EXPECT_EQ(0U, buf1.length()); - EXPECT_EQ(0U, buf1.capacity()); - EXPECT_EQ(sizeof(kTestData), buf2.length()); - EXPECT_EQ(256U, buf2.capacity()); // capacity does transfer - EXPECT_EQ(0, memcmp(buf2.data(), kTestData, sizeof(kTestData))); -} - -} // namespace rtc diff --git a/webrtc/base/bytebuffer.cc b/webrtc/base/bytebuffer.cc deleted file mode 100644 index 6133759e5..000000000 --- a/webrtc/base/bytebuffer.cc +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/bytebuffer.h" - -#include -#include - -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/byteorder.h" - -namespace rtc { - -static const int DEFAULT_SIZE = 4096; - -ByteBuffer::ByteBuffer() { - Construct(NULL, DEFAULT_SIZE, ORDER_NETWORK); -} - -ByteBuffer::ByteBuffer(ByteOrder byte_order) { - Construct(NULL, DEFAULT_SIZE, byte_order); -} - -ByteBuffer::ByteBuffer(const char* bytes, size_t len) { - Construct(bytes, len, ORDER_NETWORK); -} - -ByteBuffer::ByteBuffer(const char* bytes, size_t len, ByteOrder byte_order) { - Construct(bytes, len, byte_order); -} - -ByteBuffer::ByteBuffer(const char* bytes) { - Construct(bytes, strlen(bytes), ORDER_NETWORK); -} - -void ByteBuffer::Construct(const char* bytes, size_t len, - ByteOrder byte_order) { - version_ = 0; - start_ = 0; - size_ = len; - byte_order_ = byte_order; - bytes_ = new char[size_]; - - if (bytes) { - end_ = len; - memcpy(bytes_, bytes, end_); - } else { - end_ = 0; - } -} - -ByteBuffer::~ByteBuffer() { - delete[] bytes_; -} - -bool ByteBuffer::ReadUInt8(uint8* val) { - if (!val) return false; - - return ReadBytes(reinterpret_cast(val), 1); -} - -bool ByteBuffer::ReadUInt16(uint16* val) { - if (!val) return false; - - uint16 v; - if (!ReadBytes(reinterpret_cast(&v), 2)) { - return false; - } else { - *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost16(v) : v; - return true; - } -} - -bool ByteBuffer::ReadUInt24(uint32* val) { - if (!val) return false; - - uint32 v = 0; - char* read_into = reinterpret_cast(&v); - if (byte_order_ == ORDER_NETWORK || IsHostBigEndian()) { - ++read_into; - } - - if (!ReadBytes(read_into, 3)) { - return false; - } else { - *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost32(v) : v; - return true; - } -} - -bool ByteBuffer::ReadUInt32(uint32* val) { - if (!val) return false; - - uint32 v; - if (!ReadBytes(reinterpret_cast(&v), 4)) { - return false; - } else { - *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost32(v) : v; - return true; - } -} - -bool ByteBuffer::ReadUInt64(uint64* val) { - if (!val) return false; - - uint64 v; - if (!ReadBytes(reinterpret_cast(&v), 8)) { - return false; - } else { - *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost64(v) : v; - return true; - } -} - -bool ByteBuffer::ReadString(std::string* val, size_t len) { - if (!val) return false; - - if (len > Length()) { - return false; - } else { - val->append(bytes_ + start_, len); - start_ += len; - return true; - } -} - -bool ByteBuffer::ReadBytes(char* val, size_t len) { - if (len > Length()) { - return false; - } else { - memcpy(val, bytes_ + start_, len); - start_ += len; - return true; - } -} - -void ByteBuffer::WriteUInt8(uint8 val) { - WriteBytes(reinterpret_cast(&val), 1); -} - -void ByteBuffer::WriteUInt16(uint16 val) { - uint16 v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork16(val) : val; - WriteBytes(reinterpret_cast(&v), 2); -} - -void ByteBuffer::WriteUInt24(uint32 val) { - uint32 v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork32(val) : val; - char* start = reinterpret_cast(&v); - if (byte_order_ == ORDER_NETWORK || IsHostBigEndian()) { - ++start; - } - WriteBytes(start, 3); -} - -void ByteBuffer::WriteUInt32(uint32 val) { - uint32 v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork32(val) : val; - WriteBytes(reinterpret_cast(&v), 4); -} - -void ByteBuffer::WriteUInt64(uint64 val) { - uint64 v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork64(val) : val; - WriteBytes(reinterpret_cast(&v), 8); -} - -void ByteBuffer::WriteString(const std::string& val) { - WriteBytes(val.c_str(), val.size()); -} - -void ByteBuffer::WriteBytes(const char* val, size_t len) { - memcpy(ReserveWriteBuffer(len), val, len); -} - -char* ByteBuffer::ReserveWriteBuffer(size_t len) { - if (Length() + len > Capacity()) - Resize(Length() + len); - - char* start = bytes_ + end_; - end_ += len; - return start; -} - -void ByteBuffer::Resize(size_t size) { - size_t len = _min(end_ - start_, size); - if (size <= size_) { - // Don't reallocate, just move data backwards - memmove(bytes_, bytes_ + start_, len); - } else { - // Reallocate a larger buffer. - size_ = _max(size, 3 * size_ / 2); - char* new_bytes = new char[size_]; - memcpy(new_bytes, bytes_ + start_, len); - delete [] bytes_; - bytes_ = new_bytes; - } - start_ = 0; - end_ = len; - ++version_; -} - -bool ByteBuffer::Consume(size_t size) { - if (size > Length()) - return false; - start_ += size; - return true; -} - -ByteBuffer::ReadPosition ByteBuffer::GetReadPosition() const { - return ReadPosition(start_, version_); -} - -bool ByteBuffer::SetReadPosition(const ReadPosition &position) { - if (position.version_ != version_) { - return false; - } - start_ = position.start_; - return true; -} - -void ByteBuffer::Clear() { - memset(bytes_, 0, size_); - start_ = end_ = 0; - ++version_; -} - -} // namespace rtc diff --git a/webrtc/base/bytebuffer.h b/webrtc/base/bytebuffer.h deleted file mode 100644 index 1934f418e..000000000 --- a/webrtc/base/bytebuffer.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_BYTEBUFFER_H_ -#define WEBRTC_BASE_BYTEBUFFER_H_ - -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/constructormagic.h" - -namespace rtc { - -class ByteBuffer { - public: - - enum ByteOrder { - ORDER_NETWORK = 0, // Default, use network byte order (big endian). - ORDER_HOST, // Use the native order of the host. - }; - - // |byte_order| defines order of bytes in the buffer. - ByteBuffer(); - explicit ByteBuffer(ByteOrder byte_order); - ByteBuffer(const char* bytes, size_t len); - ByteBuffer(const char* bytes, size_t len, ByteOrder byte_order); - - // Initializes buffer from a zero-terminated string. - explicit ByteBuffer(const char* bytes); - - ~ByteBuffer(); - - const char* Data() const { return bytes_ + start_; } - size_t Length() const { return end_ - start_; } - size_t Capacity() const { return size_ - start_; } - ByteOrder Order() const { return byte_order_; } - - // Read a next value from the buffer. Return false if there isn't - // enough data left for the specified type. - bool ReadUInt8(uint8* val); - bool ReadUInt16(uint16* val); - bool ReadUInt24(uint32* val); - bool ReadUInt32(uint32* val); - bool ReadUInt64(uint64* val); - bool ReadBytes(char* val, size_t len); - - // Appends next |len| bytes from the buffer to |val|. Returns false - // if there is less than |len| bytes left. - bool ReadString(std::string* val, size_t len); - - // Write value to the buffer. Resizes the buffer when it is - // neccessary. - void WriteUInt8(uint8 val); - void WriteUInt16(uint16 val); - void WriteUInt24(uint32 val); - void WriteUInt32(uint32 val); - void WriteUInt64(uint64 val); - void WriteString(const std::string& val); - void WriteBytes(const char* val, size_t len); - - // Reserves the given number of bytes and returns a char* that can be written - // into. Useful for functions that require a char* buffer and not a - // ByteBuffer. - char* ReserveWriteBuffer(size_t len); - - // Resize the buffer to the specified |size|. This invalidates any remembered - // seek positions. - void Resize(size_t size); - - // Moves current position |size| bytes forward. Returns false if - // there is less than |size| bytes left in the buffer. Consume doesn't - // permanently remove data, so remembered read positions are still valid - // after this call. - bool Consume(size_t size); - - // Clears the contents of the buffer. After this, Length() will be 0. - void Clear(); - - // Used with GetReadPosition/SetReadPosition. - class ReadPosition { - friend class ByteBuffer; - ReadPosition(size_t start, int version) - : start_(start), version_(version) { } - size_t start_; - int version_; - }; - - // Remembers the current read position for a future SetReadPosition. Any - // calls to Shift or Resize in the interim will invalidate the position. - ReadPosition GetReadPosition() const; - - // If the given position is still valid, restores that read position. - bool SetReadPosition(const ReadPosition &position); - - private: - void Construct(const char* bytes, size_t size, ByteOrder byte_order); - - char* bytes_; - size_t size_; - size_t start_; - size_t end_; - int version_; - ByteOrder byte_order_; - - // There are sensible ways to define these, but they aren't needed in our code - // base. - DISALLOW_COPY_AND_ASSIGN(ByteBuffer); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_BYTEBUFFER_H_ diff --git a/webrtc/base/bytebuffer_unittest.cc b/webrtc/base/bytebuffer_unittest.cc deleted file mode 100644 index f4b0504ef..000000000 --- a/webrtc/base/bytebuffer_unittest.cc +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/bytebuffer.h" -#include "webrtc/base/byteorder.h" -#include "webrtc/base/common.h" -#include "webrtc/base/gunit.h" - -namespace rtc { - -TEST(ByteBufferTest, TestByteOrder) { - uint16 n16 = 1; - uint32 n32 = 1; - uint64 n64 = 1; - - EXPECT_EQ(n16, NetworkToHost16(HostToNetwork16(n16))); - EXPECT_EQ(n32, NetworkToHost32(HostToNetwork32(n32))); - EXPECT_EQ(n64, NetworkToHost64(HostToNetwork64(n64))); - - if (IsHostBigEndian()) { - // The host is the network (big) endian. - EXPECT_EQ(n16, HostToNetwork16(n16)); - EXPECT_EQ(n32, HostToNetwork32(n32)); - EXPECT_EQ(n64, HostToNetwork64(n64)); - - // GetBE converts big endian to little endian here. - EXPECT_EQ(n16 >> 8, GetBE16(&n16)); - EXPECT_EQ(n32 >> 24, GetBE32(&n32)); - EXPECT_EQ(n64 >> 56, GetBE64(&n64)); - } else { - // The host is little endian. - EXPECT_NE(n16, HostToNetwork16(n16)); - EXPECT_NE(n32, HostToNetwork32(n32)); - EXPECT_NE(n64, HostToNetwork64(n64)); - - // GetBE converts little endian to big endian here. - EXPECT_EQ(GetBE16(&n16), HostToNetwork16(n16)); - EXPECT_EQ(GetBE32(&n32), HostToNetwork32(n32)); - EXPECT_EQ(GetBE64(&n64), HostToNetwork64(n64)); - - // GetBE converts little endian to big endian here. - EXPECT_EQ(n16 << 8, GetBE16(&n16)); - EXPECT_EQ(n32 << 24, GetBE32(&n32)); - EXPECT_EQ(n64 << 56, GetBE64(&n64)); - } -} - -TEST(ByteBufferTest, TestBufferLength) { - ByteBuffer buffer; - size_t size = 0; - EXPECT_EQ(size, buffer.Length()); - - buffer.WriteUInt8(1); - ++size; - EXPECT_EQ(size, buffer.Length()); - - buffer.WriteUInt16(1); - size += 2; - EXPECT_EQ(size, buffer.Length()); - - buffer.WriteUInt24(1); - size += 3; - EXPECT_EQ(size, buffer.Length()); - - buffer.WriteUInt32(1); - size += 4; - EXPECT_EQ(size, buffer.Length()); - - buffer.WriteUInt64(1); - size += 8; - EXPECT_EQ(size, buffer.Length()); - - EXPECT_TRUE(buffer.Consume(0)); - EXPECT_EQ(size, buffer.Length()); - - EXPECT_TRUE(buffer.Consume(4)); - size -= 4; - EXPECT_EQ(size, buffer.Length()); -} - -TEST(ByteBufferTest, TestGetSetReadPosition) { - ByteBuffer buffer("ABCDEF", 6); - EXPECT_EQ(6U, buffer.Length()); - ByteBuffer::ReadPosition pos(buffer.GetReadPosition()); - EXPECT_TRUE(buffer.SetReadPosition(pos)); - EXPECT_EQ(6U, buffer.Length()); - std::string read; - EXPECT_TRUE(buffer.ReadString(&read, 3)); - EXPECT_EQ("ABC", read); - EXPECT_EQ(3U, buffer.Length()); - EXPECT_TRUE(buffer.SetReadPosition(pos)); - EXPECT_EQ(6U, buffer.Length()); - read.clear(); - EXPECT_TRUE(buffer.ReadString(&read, 3)); - EXPECT_EQ("ABC", read); - EXPECT_EQ(3U, buffer.Length()); - // For a resize by writing Capacity() number of bytes. - size_t capacity = buffer.Capacity(); - buffer.ReserveWriteBuffer(buffer.Capacity()); - EXPECT_EQ(capacity + 3U, buffer.Length()); - EXPECT_FALSE(buffer.SetReadPosition(pos)); - read.clear(); - EXPECT_TRUE(buffer.ReadString(&read, 3)); - EXPECT_EQ("DEF", read); -} - -TEST(ByteBufferTest, TestReadWriteBuffer) { - ByteBuffer::ByteOrder orders[2] = { ByteBuffer::ORDER_HOST, - ByteBuffer::ORDER_NETWORK }; - for (size_t i = 0; i < ARRAY_SIZE(orders); i++) { - ByteBuffer buffer(orders[i]); - EXPECT_EQ(orders[i], buffer.Order()); - uint8 ru8; - EXPECT_FALSE(buffer.ReadUInt8(&ru8)); - - // Write and read uint8. - uint8 wu8 = 1; - buffer.WriteUInt8(wu8); - EXPECT_TRUE(buffer.ReadUInt8(&ru8)); - EXPECT_EQ(wu8, ru8); - EXPECT_EQ(0U, buffer.Length()); - - // Write and read uint16. - uint16 wu16 = (1 << 8) + 1; - buffer.WriteUInt16(wu16); - uint16 ru16; - EXPECT_TRUE(buffer.ReadUInt16(&ru16)); - EXPECT_EQ(wu16, ru16); - EXPECT_EQ(0U, buffer.Length()); - - // Write and read uint24. - uint32 wu24 = (3 << 16) + (2 << 8) + 1; - buffer.WriteUInt24(wu24); - uint32 ru24; - EXPECT_TRUE(buffer.ReadUInt24(&ru24)); - EXPECT_EQ(wu24, ru24); - EXPECT_EQ(0U, buffer.Length()); - - // Write and read uint32. - uint32 wu32 = (4 << 24) + (3 << 16) + (2 << 8) + 1; - buffer.WriteUInt32(wu32); - uint32 ru32; - EXPECT_TRUE(buffer.ReadUInt32(&ru32)); - EXPECT_EQ(wu32, ru32); - EXPECT_EQ(0U, buffer.Length()); - - // Write and read uint64. - uint32 another32 = (8 << 24) + (7 << 16) + (6 << 8) + 5; - uint64 wu64 = (static_cast(another32) << 32) + wu32; - buffer.WriteUInt64(wu64); - uint64 ru64; - EXPECT_TRUE(buffer.ReadUInt64(&ru64)); - EXPECT_EQ(wu64, ru64); - EXPECT_EQ(0U, buffer.Length()); - - // Write and read string. - std::string write_string("hello"); - buffer.WriteString(write_string); - std::string read_string; - EXPECT_TRUE(buffer.ReadString(&read_string, write_string.size())); - EXPECT_EQ(write_string, read_string); - EXPECT_EQ(0U, buffer.Length()); - - // Write and read bytes - char write_bytes[] = "foo"; - buffer.WriteBytes(write_bytes, 3); - char read_bytes[3]; - EXPECT_TRUE(buffer.ReadBytes(read_bytes, 3)); - for (int i = 0; i < 3; ++i) { - EXPECT_EQ(write_bytes[i], read_bytes[i]); - } - EXPECT_EQ(0U, buffer.Length()); - - // Write and read reserved buffer space - char* write_dst = buffer.ReserveWriteBuffer(3); - memcpy(write_dst, write_bytes, 3); - memset(read_bytes, 0, 3); - EXPECT_TRUE(buffer.ReadBytes(read_bytes, 3)); - for (int i = 0; i < 3; ++i) { - EXPECT_EQ(write_bytes[i], read_bytes[i]); - } - EXPECT_EQ(0U, buffer.Length()); - - // Write and read in order. - buffer.WriteUInt8(wu8); - buffer.WriteUInt16(wu16); - buffer.WriteUInt24(wu24); - buffer.WriteUInt32(wu32); - buffer.WriteUInt64(wu64); - EXPECT_TRUE(buffer.ReadUInt8(&ru8)); - EXPECT_EQ(wu8, ru8); - EXPECT_TRUE(buffer.ReadUInt16(&ru16)); - EXPECT_EQ(wu16, ru16); - EXPECT_TRUE(buffer.ReadUInt24(&ru24)); - EXPECT_EQ(wu24, ru24); - EXPECT_TRUE(buffer.ReadUInt32(&ru32)); - EXPECT_EQ(wu32, ru32); - EXPECT_TRUE(buffer.ReadUInt64(&ru64)); - EXPECT_EQ(wu64, ru64); - EXPECT_EQ(0U, buffer.Length()); - } -} - -} // namespace rtc diff --git a/webrtc/base/byteorder.h b/webrtc/base/byteorder.h deleted file mode 100644 index d907d9e41..000000000 --- a/webrtc/base/byteorder.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_BYTEORDER_H_ -#define WEBRTC_BASE_BYTEORDER_H_ - -#if defined(WEBRTC_POSIX) && !defined(__native_client__) -#include -#endif - -#if defined(WEBRTC_WIN) -#include -#endif - -#include "webrtc/base/basictypes.h" - -namespace rtc { - -// Reading and writing of little and big-endian numbers from memory -// TODO: Optimized versions, with direct read/writes of -// integers in host-endian format, when the platform supports it. - -inline void Set8(void* memory, size_t offset, uint8 v) { - static_cast(memory)[offset] = v; -} - -inline uint8 Get8(const void* memory, size_t offset) { - return static_cast(memory)[offset]; -} - -inline void SetBE16(void* memory, uint16 v) { - Set8(memory, 0, static_cast(v >> 8)); - Set8(memory, 1, static_cast(v >> 0)); -} - -inline void SetBE32(void* memory, uint32 v) { - Set8(memory, 0, static_cast(v >> 24)); - Set8(memory, 1, static_cast(v >> 16)); - Set8(memory, 2, static_cast(v >> 8)); - Set8(memory, 3, static_cast(v >> 0)); -} - -inline void SetBE64(void* memory, uint64 v) { - Set8(memory, 0, static_cast(v >> 56)); - Set8(memory, 1, static_cast(v >> 48)); - Set8(memory, 2, static_cast(v >> 40)); - Set8(memory, 3, static_cast(v >> 32)); - Set8(memory, 4, static_cast(v >> 24)); - Set8(memory, 5, static_cast(v >> 16)); - Set8(memory, 6, static_cast(v >> 8)); - Set8(memory, 7, static_cast(v >> 0)); -} - -inline uint16 GetBE16(const void* memory) { - return static_cast((Get8(memory, 0) << 8) | - (Get8(memory, 1) << 0)); -} - -inline uint32 GetBE32(const void* memory) { - return (static_cast(Get8(memory, 0)) << 24) | - (static_cast(Get8(memory, 1)) << 16) | - (static_cast(Get8(memory, 2)) << 8) | - (static_cast(Get8(memory, 3)) << 0); -} - -inline uint64 GetBE64(const void* memory) { - return (static_cast(Get8(memory, 0)) << 56) | - (static_cast(Get8(memory, 1)) << 48) | - (static_cast(Get8(memory, 2)) << 40) | - (static_cast(Get8(memory, 3)) << 32) | - (static_cast(Get8(memory, 4)) << 24) | - (static_cast(Get8(memory, 5)) << 16) | - (static_cast(Get8(memory, 6)) << 8) | - (static_cast(Get8(memory, 7)) << 0); -} - -inline void SetLE16(void* memory, uint16 v) { - Set8(memory, 0, static_cast(v >> 0)); - Set8(memory, 1, static_cast(v >> 8)); -} - -inline void SetLE32(void* memory, uint32 v) { - Set8(memory, 0, static_cast(v >> 0)); - Set8(memory, 1, static_cast(v >> 8)); - Set8(memory, 2, static_cast(v >> 16)); - Set8(memory, 3, static_cast(v >> 24)); -} - -inline void SetLE64(void* memory, uint64 v) { - Set8(memory, 0, static_cast(v >> 0)); - Set8(memory, 1, static_cast(v >> 8)); - Set8(memory, 2, static_cast(v >> 16)); - Set8(memory, 3, static_cast(v >> 24)); - Set8(memory, 4, static_cast(v >> 32)); - Set8(memory, 5, static_cast(v >> 40)); - Set8(memory, 6, static_cast(v >> 48)); - Set8(memory, 7, static_cast(v >> 56)); -} - -inline uint16 GetLE16(const void* memory) { - return static_cast((Get8(memory, 0) << 0) | - (Get8(memory, 1) << 8)); -} - -inline uint32 GetLE32(const void* memory) { - return (static_cast(Get8(memory, 0)) << 0) | - (static_cast(Get8(memory, 1)) << 8) | - (static_cast(Get8(memory, 2)) << 16) | - (static_cast(Get8(memory, 3)) << 24); -} - -inline uint64 GetLE64(const void* memory) { - return (static_cast(Get8(memory, 0)) << 0) | - (static_cast(Get8(memory, 1)) << 8) | - (static_cast(Get8(memory, 2)) << 16) | - (static_cast(Get8(memory, 3)) << 24) | - (static_cast(Get8(memory, 4)) << 32) | - (static_cast(Get8(memory, 5)) << 40) | - (static_cast(Get8(memory, 6)) << 48) | - (static_cast(Get8(memory, 7)) << 56); -} - -// Check if the current host is big endian. -inline bool IsHostBigEndian() { - static const int number = 1; - return 0 == *reinterpret_cast(&number); -} - -inline uint16 HostToNetwork16(uint16 n) { - uint16 result; - SetBE16(&result, n); - return result; -} - -inline uint32 HostToNetwork32(uint32 n) { - uint32 result; - SetBE32(&result, n); - return result; -} - -inline uint64 HostToNetwork64(uint64 n) { - uint64 result; - SetBE64(&result, n); - return result; -} - -inline uint16 NetworkToHost16(uint16 n) { - return GetBE16(&n); -} - -inline uint32 NetworkToHost32(uint32 n) { - return GetBE32(&n); -} - -inline uint64 NetworkToHost64(uint64 n) { - return GetBE64(&n); -} - -} // namespace rtc - -#endif // WEBRTC_BASE_BYTEORDER_H_ diff --git a/webrtc/base/byteorder_unittest.cc b/webrtc/base/byteorder_unittest.cc deleted file mode 100644 index f4e7df3b7..000000000 --- a/webrtc/base/byteorder_unittest.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/byteorder.h" - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/gunit.h" - -namespace rtc { - -// Test memory set functions put values into memory in expected order. -TEST(ByteOrderTest, TestSet) { - uint8 buf[8] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }; - Set8(buf, 0, 0xfb); - Set8(buf, 1, 0x12); - EXPECT_EQ(0xfb, buf[0]); - EXPECT_EQ(0x12, buf[1]); - SetBE16(buf, 0x1234); - EXPECT_EQ(0x12, buf[0]); - EXPECT_EQ(0x34, buf[1]); - SetLE16(buf, 0x1234); - EXPECT_EQ(0x34, buf[0]); - EXPECT_EQ(0x12, buf[1]); - SetBE32(buf, 0x12345678); - EXPECT_EQ(0x12, buf[0]); - EXPECT_EQ(0x34, buf[1]); - EXPECT_EQ(0x56, buf[2]); - EXPECT_EQ(0x78, buf[3]); - SetLE32(buf, 0x12345678); - EXPECT_EQ(0x78, buf[0]); - EXPECT_EQ(0x56, buf[1]); - EXPECT_EQ(0x34, buf[2]); - EXPECT_EQ(0x12, buf[3]); - SetBE64(buf, UINT64_C(0x0123456789abcdef)); - EXPECT_EQ(0x01, buf[0]); - EXPECT_EQ(0x23, buf[1]); - EXPECT_EQ(0x45, buf[2]); - EXPECT_EQ(0x67, buf[3]); - EXPECT_EQ(0x89, buf[4]); - EXPECT_EQ(0xab, buf[5]); - EXPECT_EQ(0xcd, buf[6]); - EXPECT_EQ(0xef, buf[7]); - SetLE64(buf, UINT64_C(0x0123456789abcdef)); - EXPECT_EQ(0xef, buf[0]); - EXPECT_EQ(0xcd, buf[1]); - EXPECT_EQ(0xab, buf[2]); - EXPECT_EQ(0x89, buf[3]); - EXPECT_EQ(0x67, buf[4]); - EXPECT_EQ(0x45, buf[5]); - EXPECT_EQ(0x23, buf[6]); - EXPECT_EQ(0x01, buf[7]); -} - -// Test memory get functions get values from memory in expected order. -TEST(ByteOrderTest, TestGet) { - uint8 buf[8]; - buf[0] = 0x01u; - buf[1] = 0x23u; - buf[2] = 0x45u; - buf[3] = 0x67u; - buf[4] = 0x89u; - buf[5] = 0xabu; - buf[6] = 0xcdu; - buf[7] = 0xefu; - EXPECT_EQ(0x01u, Get8(buf, 0)); - EXPECT_EQ(0x23u, Get8(buf, 1)); - EXPECT_EQ(0x0123u, GetBE16(buf)); - EXPECT_EQ(0x2301u, GetLE16(buf)); - EXPECT_EQ(0x01234567u, GetBE32(buf)); - EXPECT_EQ(0x67452301u, GetLE32(buf)); - EXPECT_EQ(UINT64_C(0x0123456789abcdef), GetBE64(buf)); - EXPECT_EQ(UINT64_C(0xefcdab8967452301), GetLE64(buf)); -} - -} // namespace rtc - diff --git a/webrtc/base/callback.h b/webrtc/base/callback.h deleted file mode 100644 index 949510e95..000000000 --- a/webrtc/base/callback.h +++ /dev/null @@ -1,261 +0,0 @@ -// This file was GENERATED by command: -// pump.py callback.h.pump -// DO NOT EDIT BY HAND!!! - -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// 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 -// 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 my_callback; -// cout << my_callback.empty() << endl; // true -// -// my_callback = Callback1(&sqr); -// cout << my_callback.empty() << endl; // false -// cout << my_callback(3) << endl; // 9 -// -// my_callback = Callback1(add_k); -// cout << my_callback(10) << endl; // 15 -// -// my_callback = Callback1(); -// cout << my_callback.empty() << endl; // true - -#ifndef WEBRTC_BASE_CALLBACK_H_ -#define WEBRTC_BASE_CALLBACK_H_ - -#include "webrtc/base/logging.h" -#include "webrtc/base/refcount.h" -#include "webrtc/base/scoped_ref_ptr.h" - -namespace rtc { - -template -class Callback0 { - public: - // Default copy operations are appropriate for this class. - Callback0() {} - template Callback0(const T& functor) - : helper_(new RefCountedObject< HelperImpl >(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 struct HelperImpl : Helper { - explicit HelperImpl(const T& functor) : functor_(functor) {} - virtual R Run() { - return functor_(); - } - T functor_; - }; - scoped_refptr helper_; -}; - -template -class Callback1 { - public: - // Default copy operations are appropriate for this class. - Callback1() {} - template Callback1(const T& functor) - : helper_(new RefCountedObject< HelperImpl >(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 struct HelperImpl : Helper { - explicit HelperImpl(const T& functor) : functor_(functor) {} - virtual R Run(P1 p1) { - return functor_(p1); - } - T functor_; - }; - scoped_refptr helper_; -}; - -template -class Callback2 { - public: - // Default copy operations are appropriate for this class. - Callback2() {} - template Callback2(const T& functor) - : helper_(new RefCountedObject< HelperImpl >(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 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_; -}; - -template -class Callback3 { - public: - // Default copy operations are appropriate for this class. - Callback3() {} - template Callback3(const T& functor) - : helper_(new RefCountedObject< HelperImpl >(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 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_; -}; - -template -class Callback4 { - public: - // Default copy operations are appropriate for this class. - Callback4() {} - template Callback4(const T& functor) - : helper_(new RefCountedObject< HelperImpl >(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 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_; -}; - -template -class Callback5 { - public: - // Default copy operations are appropriate for this class. - Callback5() {} - template Callback5(const T& functor) - : helper_(new RefCountedObject< HelperImpl >(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 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_; -}; -} // namespace rtc - -#endif // WEBRTC_BASE_CALLBACK_H_ diff --git a/webrtc/base/callback.h.pump b/webrtc/base/callback.h.pump deleted file mode 100644 index 86957df52..000000000 --- a/webrtc/base/callback.h.pump +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// 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 -// 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 my_callback; -// cout << my_callback.empty() << endl; // true -// -// my_callback = Callback1(&sqr); -// cout << my_callback.empty() << endl; // false -// cout << my_callback(3) << endl; // 9 -// -// my_callback = Callback1(add_k); -// cout << my_callback(10) << endl; // 15 -// -// my_callback = Callback1(); -// cout << my_callback.empty() << endl; // true - -#ifndef WEBRTC_BASE_CALLBACK_H_ -#define WEBRTC_BASE_CALLBACK_H_ - -#include "webrtc/base/refcount.h" -#include "webrtc/base/scoped_ref_ptr.h" - -namespace rtc { - -$var n = 5 -$range i 0..n -$for i [[ -$range j 1..i - -template -class Callback$i { - public: - // Default copy operations are appropriate for this class. - Callback$i() {} - template Callback$i(const T& functor) - : helper_(new RefCountedObject< HelperImpl >(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 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_; -}; - -]] -} // namespace rtc - -#endif // WEBRTC_BASE_CALLBACK_H_ diff --git a/webrtc/base/callback_unittest.cc b/webrtc/base/callback_unittest.cc deleted file mode 100644 index 66c939140..000000000 --- a/webrtc/base/callback_unittest.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/bind.h" -#include "webrtc/base/callback.h" -#include "webrtc/base/gunit.h" - -namespace rtc { - -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 cb; - EXPECT_TRUE(cb.empty()); - cb(); // Executing an empty callback should not crash. - cb = Callback0(&f); - EXPECT_FALSE(cb.empty()); - cb(); -} - -TEST(CallbackTest, IntReturn) { - Callback0 cb; - EXPECT_TRUE(cb.empty()); - cb = Callback0(&g); - EXPECT_FALSE(cb.empty()); - EXPECT_EQ(42, cb()); - EXPECT_EQ(42, cb()); -} - -TEST(CallbackTest, OneParam) { - Callback1 cb1(&h); - EXPECT_FALSE(cb1.empty()); - EXPECT_EQ(9, cb1(-3)); - EXPECT_EQ(100, cb1(10)); - - // Try clearing a callback. - cb1 = Callback1(); - EXPECT_TRUE(cb1.empty()); - - // Try a callback with a ref parameter. - Callback1 cb2(&i); - int x = 3; - cb2(x); - EXPECT_EQ(9, x); - cb2(x); - EXPECT_EQ(81, x); -} - -TEST(CallbackTest, WithBind) { - BindTester t; - Callback0 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 rtc diff --git a/webrtc/base/checks.cc b/webrtc/base/checks.cc deleted file mode 100644 index dd7183362..000000000 --- a/webrtc/base/checks.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "webrtc/base/checks.h" -#include "webrtc/base/logging.h" - -void Fatal(const char* file, int line, const char* format, ...) { - char msg[256]; - - va_list arguments; - va_start(arguments, format); - vsnprintf(msg, sizeof(msg), format, arguments); - va_end(arguments); - - LOG(LS_ERROR) << "\n\n#\n# Fatal error in " << file - << ", line " << line << "\n#" << msg - << "\n#\n"; - abort(); -} diff --git a/webrtc/base/checks.h b/webrtc/base/checks.h deleted file mode 100644 index 93f7580ed..000000000 --- a/webrtc/base/checks.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// This module contains some basic debugging facilities. -// Originally comes from shared/commandlineflags/checks.h - -#ifndef WEBRTC_BASE_CHECKS_H_ -#define WEBRTC_BASE_CHECKS_H_ - -#include - -// Prints an error message to stderr and aborts execution. -void Fatal(const char* file, int line, const char* format, ...); - - -// The UNREACHABLE macro is very useful during development. -#define UNREACHABLE() \ - Fatal(__FILE__, __LINE__, "unreachable code") - -#endif // WEBRTC_BASE_CHECKS_H_ diff --git a/webrtc/base/common.cc b/webrtc/base/common.cc deleted file mode 100644 index 8ea475b0e..000000000 --- a/webrtc/base/common.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#if WEBRTC_WIN -#define WIN32_LEAN_AND_MEAN -#include -#endif // WEBRTC_WIN - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) - -#include -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" - -////////////////////////////////////////////////////////////////////// -// Assertions -////////////////////////////////////////////////////////////////////// - -namespace rtc { - -void Break() { -#if WEBRTC_WIN - ::DebugBreak(); -#else // !WEBRTC_WIN - // On POSIX systems, SIGTRAP signals debuggers to break without killing the - // process. If a debugger isn't attached, the uncaught SIGTRAP will crash the - // app. - raise(SIGTRAP); -#endif - // If a debugger wasn't attached, we will have crashed by this point. If a - // debugger is attached, we'll continue from here. -} - -static AssertLogger custom_assert_logger_ = NULL; - -void SetCustomAssertLogger(AssertLogger logger) { - custom_assert_logger_ = logger; -} - -void LogAssert(const char* function, const char* file, int line, - const char* expression) { - if (custom_assert_logger_) { - custom_assert_logger_(function, file, line, expression); - } else { - LOG(LS_ERROR) << file << "(" << line << ")" << ": ASSERT FAILED: " - << expression << " @ " << function; - } -} - -} // namespace rtc diff --git a/webrtc/base/common.h b/webrtc/base/common.h deleted file mode 100644 index 51a5d1e2d..000000000 --- a/webrtc/base/common.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_COMMON_H_ // NOLINT -#define WEBRTC_BASE_COMMON_H_ - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/constructormagic.h" - -#if defined(_MSC_VER) -// warning C4355: 'this' : used in base member initializer list -#pragma warning(disable:4355) -#endif - -////////////////////////////////////////////////////////////////////// -// General Utilities -////////////////////////////////////////////////////////////////////// - -// Note: UNUSED is also defined in basictypes.h -#ifndef UNUSED -#define UNUSED(x) Unused(static_cast(&x)) -#define UNUSED2(x, y) Unused(static_cast(&x)); \ - Unused(static_cast(&y)) -#define UNUSED3(x, y, z) Unused(static_cast(&x)); \ - Unused(static_cast(&y)); \ - Unused(static_cast(&z)) -#define UNUSED4(x, y, z, a) Unused(static_cast(&x)); \ - Unused(static_cast(&y)); \ - Unused(static_cast(&z)); \ - Unused(static_cast(&a)) -#define UNUSED5(x, y, z, a, b) Unused(static_cast(&x)); \ - Unused(static_cast(&y)); \ - Unused(static_cast(&z)); \ - Unused(static_cast(&a)); \ - Unused(static_cast(&b)) -inline void Unused(const void*) {} -#endif // UNUSED - -#if !defined(WEBRTC_WIN) - -#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 . -#define stdmax(x, y) std::max(x, y) -#else -#define stdmax(x, y) rtc::_max(x, y) -#endif - -#define ARRAY_SIZE(x) (static_cast(sizeof(x) / sizeof(x[0]))) - -///////////////////////////////////////////////////////////////////////////// -// Assertions -///////////////////////////////////////////////////////////////////////////// - -#ifndef ENABLE_DEBUG -#define ENABLE_DEBUG _DEBUG -#endif // !defined(ENABLE_DEBUG) - -// Even for release builds, allow for the override of LogAssert. Though no -// macro is provided, this can still be used for explicit runtime asserts -// and allow applications to override the assert behavior. - -namespace rtc { - - -// 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.). -void LogAssert(const char* function, const char* file, int line, - const char* expression); - -typedef void (*AssertLogger)(const char* function, - const char* file, - int line, - const char* expression); - -// Sets a custom assert logger to be used instead of the default LogAssert -// behavior. To clear the custom assert logger, pass NULL for |logger| and the -// default behavior will be restored. Only one custom assert logger can be set -// at a time, so this should generally be set during application startup and -// only by one component. -void SetCustomAssertLogger(AssertLogger logger); - -} // namespace rtc - -#if ENABLE_DEBUG - -namespace rtc { - -inline bool Assert(bool result, const char* function, const char* file, - int line, const char* expression) { - if (!result) { - LogAssert(function, file, line, expression); - Break(); - return false; - } - return true; -} - -} // namespace rtc - -#if defined(_MSC_VER) && _MSC_VER < 1300 -#define __FUNCTION__ "" -#endif - -#ifndef ASSERT -#define ASSERT(x) \ - (void)rtc::Assert((x), __FUNCTION__, __FILE__, __LINE__, #x) -#endif - -#ifndef VERIFY -#define VERIFY(x) rtc::Assert((x), __FUNCTION__, __FILE__, __LINE__, #x) -#endif - -#else // !ENABLE_DEBUG - -namespace rtc { - -inline bool ImplicitCastToBool(bool result) { return result; } - -} // namespace rtc - -#ifndef ASSERT -#define ASSERT(x) (void)0 -#endif - -#ifndef VERIFY -#define VERIFY(x) rtc::ImplicitCastToBool(x) -#endif - -#endif // !ENABLE_DEBUG - -#define COMPILE_TIME_ASSERT(expr) char CTA_UNIQUE_NAME[expr] -#define CTA_UNIQUE_NAME CTA_MAKE_NAME(__LINE__) -#define CTA_MAKE_NAME(line) CTA_MAKE_NAME2(line) -#define CTA_MAKE_NAME2(line) constraint_ ## line - -// Forces compiler to inline, even against its better judgement. Use wisely. -#if defined(__GNUC__) -#define FORCE_INLINE __attribute__((always_inline)) -#elif defined(WEBRTC_WIN) -#define FORCE_INLINE __forceinline -#else -#define FORCE_INLINE -#endif - -// Borrowed from Chromium's base/compiler_specific.h. -// Annotate a virtual method indicating it must be overriding a virtual -// method in the parent class. -// Use like: -// virtual void foo() OVERRIDE; -#if defined(WEBRTC_WIN) -#define OVERRIDE override -#elif defined(__clang__) -// Clang defaults to C++03 and warns about using override. Squelch that. -// Intentionally no push/pop here so all users of OVERRIDE ignore the warning -// too. This is like passing -Wno-c++11-extensions, except that GCC won't die -// (because it won't see this pragma). -#pragma clang diagnostic ignored "-Wc++11-extensions" -#define OVERRIDE override -#elif defined(__GNUC__) && __cplusplus >= 201103 && \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700 -// GCC 4.7 supports explicit virtual overrides when C++11 support is enabled. -#define OVERRIDE override -#else -#define OVERRIDE -#endif - -// Annotate a function indicating the caller must examine the return value. -// Use like: -// int foo() WARN_UNUSED_RESULT; -// To explicitly ignore a result, see |ignore_result()| in . -// TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and -// libjingle are merged. -#if !defined(WARN_UNUSED_RESULT) -#if defined(__GNUC__) -#define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define WARN_UNUSED_RESULT -#endif -#endif // WARN_UNUSED_RESULT - -#endif // WEBRTC_BASE_COMMON_H_ // NOLINT diff --git a/webrtc/base/compile_assert.h b/webrtc/base/compile_assert.h deleted file mode 100644 index 6d4249c8f..000000000 --- a/webrtc/base/compile_assert.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// COMPILE_ASSERT macro, borrowed from google3/base/macros.h. -#ifndef WEBRTC_BASE_COMPILE_ASSERT_H_ -#define WEBRTC_BASE_COMPILE_ASSERT_H_ - -// The COMPILE_ASSERT macro can be used to verify that a compile time -// expression is true. For example, you could use it to verify the -// size of a static array: -// -// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, -// content_type_names_incorrect_size); -// -// or to make sure a struct is smaller than a certain size: -// -// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); -// -// The second argument to the macro is the name of the variable. If -// the expression is false, most compilers will issue a warning/error -// containing the name of the variable. - -// TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and -// libjingle are merged. -#if !defined(COMPILE_ASSERT) -template -struct CompileAssert { -}; - -#define COMPILE_ASSERT(expr, msg) \ - typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] // NOLINT -#endif // COMPILE_ASSERT - -// Implementation details of COMPILE_ASSERT: -// -// - COMPILE_ASSERT works by defining an array type that has -1 -// elements (and thus is invalid) when the expression is false. -// -// - The simpler definition -// -// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] -// -// does not work, as gcc supports variable-length arrays whose sizes -// are determined at run-time (this is gcc's extension and not part -// of the C++ standard). As a result, gcc fails to reject the -// following code with the simple definition: -// -// int foo; -// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is -// // not a compile-time constant. -// -// - By using the type CompileAssert<(bool(expr))>, we ensures that -// expr is a compile-time constant. (Template arguments must be -// determined at compile-time.) -// -// - The outer parentheses in CompileAssert<(bool(expr))> are necessary -// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written -// -// CompileAssert -// -// instead, these compilers will refuse to compile -// -// COMPILE_ASSERT(5 > 0, some_message); -// -// (They seem to think the ">" in "5 > 0" marks the end of the -// template argument list.) -// -// - The array size is (bool(expr) ? 1 : -1), instead of simply -// -// ((expr) ? 1 : -1). -// -// This is to avoid running into a bug in MS VC 7.1, which -// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. - -#endif // WEBRTC_BASE_COMPILE_ASSERT_H_ diff --git a/webrtc/base/constructormagic.h b/webrtc/base/constructormagic.h deleted file mode 100644 index c20be2b32..000000000 --- a/webrtc/base/constructormagic.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_CONSTRUCTORMAGIC_H_ -#define WEBRTC_BASE_CONSTRUCTORMAGIC_H_ - -#define DISALLOW_ASSIGN(TypeName) \ - void operator=(const TypeName&) - -// A macro to disallow the evil copy constructor and operator= functions -// This should be used in the private: declarations for a class. -// Undefine this, just in case. Some third-party includes have their own -// version. -#undef DISALLOW_COPY_AND_ASSIGN -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - DISALLOW_ASSIGN(TypeName) - -// Alternative, less-accurate legacy name. -#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ - DISALLOW_COPY_AND_ASSIGN(TypeName) - -// A macro to disallow all the implicit constructors, namely the -// default constructor, copy constructor and operator= functions. -// -// This should be used in the private: declarations for a class -// that wants to prevent anyone from instantiating it. This is -// especially useful for classes containing only static methods. -#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - DISALLOW_EVIL_CONSTRUCTORS(TypeName) - - -#endif // WEBRTC_BASE_CONSTRUCTORMAGIC_H_ diff --git a/webrtc/base/cpumonitor.cc b/webrtc/base/cpumonitor.cc deleted file mode 100644 index f5c0d063a..000000000 --- a/webrtc/base/cpumonitor.cc +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/cpumonitor.h" - -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/systeminfo.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#include -#endif - -#if defined(WEBRTC_POSIX) -#include -#endif - -#if defined(WEBRTC_MAC) -#include -#include -#include -#include -#endif // defined(WEBRTC_MAC) - -#if defined(WEBRTC_LINUX) -#include -#include -#include -#include "webrtc/base/fileutils.h" -#include "webrtc/base/pathutils.h" -#endif // defined(WEBRTC_LINUX) - -#if defined(WEBRTC_MAC) -static uint64 TimeValueTToInt64(const time_value_t &time_value) { - return rtc::kNumMicrosecsPerSec * time_value.seconds + - time_value.microseconds; -} -#endif // defined(WEBRTC_MAC) - -// How CpuSampler works -// When threads switch, the time they spent is accumulated to system counters. -// The time can be treated as user, kernel or idle. -// user time is applications. -// kernel time is the OS, including the thread switching code itself. -// typically kernel time indicates IO. -// idle time is a process that wastes time when nothing is ready to run. -// -// User time is broken down by process (application). One of the applications -// is the current process. When you add up all application times, this is -// system time. If only your application is running, system time should be the -// same as process time. -// -// All cores contribute to these accumulators. A dual core process is able to -// process twice as many cycles as a single core. The actual code efficiency -// may be worse, due to contention, but the available cycles is exactly twice -// as many, and the cpu load will reflect the efficiency. Hyperthreads behave -// the same way. The load will reflect 200%, but the actual amount of work -// completed will be much less than a true dual core. -// -// Total available performance is the sum of all accumulators. -// If you tracked this for 1 second, it would essentially give you the clock -// rate - number of cycles per second. -// Speed step / Turbo Boost is not considered, so infact more processing time -// may be available. - -namespace rtc { - -// Note Tests on Windows show 600 ms is minimum stable interval for Windows 7. -static const int32 kDefaultInterval = 950; // Slightly under 1 second. - -CpuSampler::CpuSampler() - : min_load_interval_(kDefaultInterval) -#if defined(WEBRTC_WIN) - , get_system_times_(NULL), - nt_query_system_information_(NULL), - force_fallback_(false) -#endif - { -} - -CpuSampler::~CpuSampler() { -} - -// Set minimum interval in ms between computing new load values. Default 950. -void CpuSampler::set_load_interval(int min_load_interval) { - min_load_interval_ = min_load_interval; -} - -bool CpuSampler::Init() { - sysinfo_.reset(new SystemInfo); - cpus_ = sysinfo_->GetMaxCpus(); - if (cpus_ == 0) { - return false; - } -#if defined(WEBRTC_WIN) - // Note that GetSystemTimes is available in Windows XP SP1 or later. - // http://msdn.microsoft.com/en-us/library/ms724400.aspx - // NtQuerySystemInformation is used as a fallback. - if (!force_fallback_) { - get_system_times_ = GetProcAddress(GetModuleHandle(L"kernel32.dll"), - "GetSystemTimes"); - } - nt_query_system_information_ = GetProcAddress(GetModuleHandle(L"ntdll.dll"), - "NtQuerySystemInformation"); - if ((get_system_times_ == NULL) && (nt_query_system_information_ == NULL)) { - return false; - } -#endif -#if defined(WEBRTC_LINUX) - Pathname sname("/proc/stat"); - sfile_.reset(Filesystem::OpenFile(sname, "rb")); - if (!sfile_) { - LOG_ERR(LS_ERROR) << "open proc/stat failed:"; - return false; - } - if (!sfile_->DisableBuffering()) { - LOG_ERR(LS_ERROR) << "could not disable buffering for proc/stat"; - return false; - } -#endif // defined(WEBRTC_LINUX) - GetProcessLoad(); // Initialize values. - GetSystemLoad(); - // Help next user call return valid data by recomputing load. - process_.prev_load_time_ = 0u; - system_.prev_load_time_ = 0u; - return true; -} - -float CpuSampler::UpdateCpuLoad(uint64 current_total_times, - uint64 current_cpu_times, - uint64 *prev_total_times, - uint64 *prev_cpu_times) { - float result = 0.f; - if (current_total_times < *prev_total_times || - current_cpu_times < *prev_cpu_times) { - LOG(LS_ERROR) << "Inconsistent time values are passed. ignored"; - } else { - const uint64 cpu_diff = current_cpu_times - *prev_cpu_times; - const uint64 total_diff = current_total_times - *prev_total_times; - result = (total_diff == 0ULL ? 0.f : - static_cast(1.0f * cpu_diff / total_diff)); - if (result > static_cast(cpus_)) { - result = static_cast(cpus_); - } - *prev_total_times = current_total_times; - *prev_cpu_times = current_cpu_times; - } - return result; -} - -float CpuSampler::GetSystemLoad() { - uint32 timenow = Time(); - int elapsed = static_cast(TimeDiff(timenow, system_.prev_load_time_)); - if (min_load_interval_ != 0 && system_.prev_load_time_ != 0u && - elapsed < min_load_interval_) { - return system_.prev_load_; - } -#if defined(WEBRTC_WIN) - uint64 total_times, cpu_times; - - typedef BOOL (_stdcall *GST_PROC)(LPFILETIME, LPFILETIME, LPFILETIME); - typedef NTSTATUS (WINAPI *QSI_PROC)(SYSTEM_INFORMATION_CLASS, - PVOID, ULONG, PULONG); - - GST_PROC get_system_times = reinterpret_cast(get_system_times_); - QSI_PROC nt_query_system_information = reinterpret_cast( - nt_query_system_information_); - - if (get_system_times) { - FILETIME idle_time, kernel_time, user_time; - if (!get_system_times(&idle_time, &kernel_time, &user_time)) { - LOG(LS_ERROR) << "::GetSystemTimes() failed: " << ::GetLastError(); - return 0.f; - } - // kernel_time includes Kernel idle time, so no need to - // include cpu_time as total_times - total_times = ToUInt64(kernel_time) + ToUInt64(user_time); - cpu_times = total_times - ToUInt64(idle_time); - - } else { - if (nt_query_system_information) { - ULONG returned_length = 0; - scoped_ptr processor_info( - new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[cpus_]); - nt_query_system_information( - ::SystemProcessorPerformanceInformation, - reinterpret_cast(processor_info.get()), - cpus_ * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), - &returned_length); - - if (returned_length != - (cpus_ * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))) { - LOG(LS_ERROR) << "NtQuerySystemInformation has unexpected size"; - return 0.f; - } - - uint64 current_idle = 0; - uint64 current_kernel = 0; - uint64 current_user = 0; - for (int ix = 0; ix < cpus_; ++ix) { - current_idle += processor_info[ix].IdleTime.QuadPart; - current_kernel += processor_info[ix].UserTime.QuadPart; - current_user += processor_info[ix].KernelTime.QuadPart; - } - total_times = current_kernel + current_user; - cpu_times = total_times - current_idle; - } else { - return 0.f; - } - } -#endif // WEBRTC_WIN - -#if defined(WEBRTC_MAC) - 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(&cpu_info), - &info_count)) { - LOG(LS_ERROR) << "::host_statistics() failed"; - return 0.f; - } - - const uint64 cpu_times = cpu_info.cpu_ticks[CPU_STATE_NICE] + - cpu_info.cpu_ticks[CPU_STATE_SYSTEM] + - cpu_info.cpu_ticks[CPU_STATE_USER]; - const uint64 total_times = cpu_times + cpu_info.cpu_ticks[CPU_STATE_IDLE]; -#endif // defined(WEBRTC_MAC) - -#if defined(WEBRTC_LINUX) - if (!sfile_) { - LOG(LS_ERROR) << "Invalid handle for proc/stat"; - return 0.f; - } - std::string statbuf; - sfile_->SetPosition(0); - if (!sfile_->ReadLine(&statbuf)) { - LOG_ERR(LS_ERROR) << "Could not read proc/stat file"; - return 0.f; - } - - unsigned long long user; - unsigned long long nice; - unsigned long long system; - unsigned long long idle; - if (sscanf(statbuf.c_str(), "cpu %Lu %Lu %Lu %Lu", - &user, &nice, - &system, &idle) != 4) { - LOG_ERR(LS_ERROR) << "Could not parse cpu info"; - return 0.f; - } - const uint64 cpu_times = nice + system + user; - const uint64 total_times = cpu_times + idle; -#endif // defined(WEBRTC_LINUX) - -#if defined(__native_client__) - // TODO(ryanpetrie): Implement this via PPAPI when it's available. - const uint64 cpu_times = 0; - const uint64 total_times = 0; -#endif // defined(__native_client__) - - system_.prev_load_time_ = timenow; - system_.prev_load_ = UpdateCpuLoad(total_times, - cpu_times * cpus_, - &system_.prev_total_times_, - &system_.prev_cpu_times_); - return system_.prev_load_; -} - -float CpuSampler::GetProcessLoad() { - uint32 timenow = Time(); - int elapsed = static_cast(TimeDiff(timenow, process_.prev_load_time_)); - if (min_load_interval_ != 0 && process_.prev_load_time_ != 0u && - elapsed < min_load_interval_) { - return process_.prev_load_; - } -#if defined(WEBRTC_WIN) - FILETIME current_file_time; - ::GetSystemTimeAsFileTime(¤t_file_time); - - FILETIME create_time, exit_time, kernel_time, user_time; - if (!::GetProcessTimes(::GetCurrentProcess(), - &create_time, &exit_time, &kernel_time, &user_time)) { - LOG(LS_ERROR) << "::GetProcessTimes() failed: " << ::GetLastError(); - return 0.f; - } - - const uint64 total_times = - ToUInt64(current_file_time) - ToUInt64(create_time); - const uint64 cpu_times = - (ToUInt64(kernel_time) + ToUInt64(user_time)); -#endif // WEBRTC_WIN - -#if defined(WEBRTC_POSIX) - // Common to both OSX and Linux. - struct timeval tv; - gettimeofday(&tv, NULL); - const uint64 total_times = tv.tv_sec * kNumMicrosecsPerSec + tv.tv_usec; -#endif - -#if defined(WEBRTC_MAC) - // Get live thread usage. - task_thread_times_info task_times_info; - mach_msg_type_number_t info_count = TASK_THREAD_TIMES_INFO_COUNT; - - if (KERN_SUCCESS != task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, - reinterpret_cast(&task_times_info), - &info_count)) { - LOG(LS_ERROR) << "::task_info(TASK_THREAD_TIMES_INFO) failed"; - return 0.f; - } - - // Get terminated thread usage. - task_basic_info task_term_info; - info_count = TASK_BASIC_INFO_COUNT; - if (KERN_SUCCESS != task_info(mach_task_self(), TASK_BASIC_INFO, - reinterpret_cast(&task_term_info), - &info_count)) { - LOG(LS_ERROR) << "::task_info(TASK_BASIC_INFO) failed"; - return 0.f; - } - - const uint64 cpu_times = (TimeValueTToInt64(task_times_info.user_time) + - TimeValueTToInt64(task_times_info.system_time) + - TimeValueTToInt64(task_term_info.user_time) + - TimeValueTToInt64(task_term_info.system_time)); -#endif // defined(WEBRTC_MAC) - -#if defined(WEBRTC_LINUX) - rusage usage; - if (getrusage(RUSAGE_SELF, &usage) < 0) { - LOG_ERR(LS_ERROR) << "getrusage failed"; - return 0.f; - } - - const uint64 cpu_times = - (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * kNumMicrosecsPerSec + - usage.ru_utime.tv_usec + usage.ru_stime.tv_usec; -#endif // defined(WEBRTC_LINUX) - -#if defined(__native_client__) - // TODO(ryanpetrie): Implement this via PPAPI when it's available. - const uint64 cpu_times = 0; -#endif // defined(__native_client__) - - process_.prev_load_time_ = timenow; - process_.prev_load_ = UpdateCpuLoad(total_times, - cpu_times, - &process_.prev_total_times_, - &process_.prev_cpu_times_); - return process_.prev_load_; -} - -int CpuSampler::GetMaxCpus() const { - return cpus_; -} - -int CpuSampler::GetCurrentCpus() { - return sysinfo_->GetCurCpus(); -} - -/////////////////////////////////////////////////////////////////// -// Implementation of class CpuMonitor. -CpuMonitor::CpuMonitor(Thread* thread) - : monitor_thread_(thread) { -} - -CpuMonitor::~CpuMonitor() { - Stop(); -} - -void CpuMonitor::set_thread(Thread* thread) { - ASSERT(monitor_thread_ == NULL || monitor_thread_ == thread); - monitor_thread_ = thread; -} - -bool CpuMonitor::Start(int period_ms) { - if (!monitor_thread_ || !sampler_.Init()) return false; - - monitor_thread_->SignalQueueDestroyed.connect( - this, &CpuMonitor::OnMessageQueueDestroyed); - - period_ms_ = period_ms; - monitor_thread_->PostDelayed(period_ms_, this); - - return true; -} - -void CpuMonitor::Stop() { - if (monitor_thread_) { - monitor_thread_->Clear(this); - } -} - -void CpuMonitor::OnMessage(Message* msg) { - int max_cpus = sampler_.GetMaxCpus(); - int current_cpus = sampler_.GetCurrentCpus(); - float process_load = sampler_.GetProcessLoad(); - float system_load = sampler_.GetSystemLoad(); - SignalUpdate(current_cpus, max_cpus, process_load, system_load); - - if (monitor_thread_) { - monitor_thread_->PostDelayed(period_ms_, this); - } -} - -} // namespace rtc diff --git a/webrtc/base/cpumonitor.h b/webrtc/base/cpumonitor.h deleted file mode 100644 index 39b09b380..000000000 --- a/webrtc/base/cpumonitor.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_CPUMONITOR_H_ -#define WEBRTC_BASE_CPUMONITOR_H_ - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/sigslot.h" -#if defined(WEBRTC_LINUX) -#include "webrtc/base/stream.h" -#endif // defined(WEBRTC_LINUX) - -namespace rtc { -class Thread; -class SystemInfo; - -struct CpuStats { - CpuStats() - : prev_total_times_(0), - prev_cpu_times_(0), - prev_load_(0.f), - prev_load_time_(0u) { - } - - uint64 prev_total_times_; - uint64 prev_cpu_times_; - float prev_load_; // Previous load value. - uint32 prev_load_time_; // Time previous load value was taken. -}; - -// CpuSampler samples the process and system load. -class CpuSampler { - public: - CpuSampler(); - ~CpuSampler(); - - // Initialize CpuSampler. Returns true if successful. - bool Init(); - - // Set minimum interval in ms between computing new load values. - // Default 950 ms. Set to 0 to disable interval. - void set_load_interval(int min_load_interval); - - // Return CPU load of current process as a float from 0 to 1. - float GetProcessLoad(); - - // Return CPU load of current process as a float from 0 to 1. - float GetSystemLoad(); - - // Return number of cpus. Includes hyperthreads. - int GetMaxCpus() const; - - // Return current number of cpus available to this process. - int GetCurrentCpus(); - - // For testing. Allows forcing of fallback to using NTDLL functions. - void set_force_fallback(bool fallback) { -#if defined(WEBRTC_WIN) - force_fallback_ = fallback; -#endif - } - - private: - float UpdateCpuLoad(uint64 current_total_times, - uint64 current_cpu_times, - uint64 *prev_total_times, - uint64 *prev_cpu_times); - CpuStats process_; - CpuStats system_; - int cpus_; - int min_load_interval_; // Minimum time between computing new load. - scoped_ptr sysinfo_; -#if defined(WEBRTC_WIN) - void* get_system_times_; - void* nt_query_system_information_; - bool force_fallback_; -#endif -#if defined(WEBRTC_LINUX) - // File for reading /proc/stat - scoped_ptr sfile_; -#endif // defined(WEBRTC_LINUX) -}; - -// CpuMonitor samples and signals the CPU load periodically. -class CpuMonitor - : public rtc::MessageHandler, public sigslot::has_slots<> { - public: - explicit CpuMonitor(Thread* thread); - virtual ~CpuMonitor(); - void set_thread(Thread* thread); - - bool Start(int period_ms); - void Stop(); - // Signal parameters are current cpus, max cpus, process load and system load. - sigslot::signal4 SignalUpdate; - - protected: - // Override virtual method of parent MessageHandler. - virtual void OnMessage(rtc::Message* msg); - // Clear the monitor thread and stop sending it messages if the thread goes - // away before our lifetime. - void OnMessageQueueDestroyed() { monitor_thread_ = NULL; } - - private: - Thread* monitor_thread_; - CpuSampler sampler_; - int period_ms_; - - DISALLOW_COPY_AND_ASSIGN(CpuMonitor); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_CPUMONITOR_H_ diff --git a/webrtc/base/cpumonitor_unittest.cc b/webrtc/base/cpumonitor_unittest.cc deleted file mode 100644 index 6d9af5aec..000000000 --- a/webrtc/base/cpumonitor_unittest.cc +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#endif - -#include "webrtc/base/cpumonitor.h" -#include "webrtc/base/flags.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" -#include "webrtc/base/timing.h" - -namespace rtc { - -static const int kMaxCpus = 1024; -static const int kSettleTime = 100; // Amount of time to between tests. -static const int kIdleTime = 500; // Amount of time to be idle in ms. -static const int kBusyTime = 1000; // Amount of time to be busy in ms. -static const int kLongInterval = 2000; // Interval longer than busy times - -class BusyThread : public rtc::Thread { - public: - BusyThread(double load, double duration, double interval) : - load_(load), duration_(duration), interval_(interval) { - } - virtual ~BusyThread() { - Stop(); - } - void Run() { - Timing time; - double busy_time = interval_ * load_ / 100.0; - for (;;) { - time.BusyWait(busy_time); - time.IdleWait(interval_ - busy_time); - if (duration_) { - duration_ -= interval_; - if (duration_ <= 0) { - break; - } - } - } - } - private: - double load_; - double duration_; - double interval_; -}; - -class CpuLoadListener : public sigslot::has_slots<> { - public: - CpuLoadListener() - : current_cpus_(0), - cpus_(0), - process_load_(.0f), - system_load_(.0f), - count_(0) { - } - - void OnCpuLoad(int current_cpus, int cpus, float proc_load, float sys_load) { - current_cpus_ = current_cpus; - cpus_ = cpus; - process_load_ = proc_load; - system_load_ = sys_load; - ++count_; - } - - int current_cpus() const { return current_cpus_; } - int cpus() const { return cpus_; } - float process_load() const { return process_load_; } - float system_load() const { return system_load_; } - int count() const { return count_; } - - private: - int current_cpus_; - int cpus_; - float process_load_; - float system_load_; - int count_; -}; - -// Set affinity (which cpu to run on), but respecting FLAG_affinity: -// -1 means no affinity - run on whatever cpu is available. -// 0 .. N means run on specific cpu. The tool will create N threads and call -// SetThreadAffinity on 0 to N - 1 as cpu. FLAG_affinity sets the first cpu -// so the range becomes affinity to affinity + N - 1 -// Note that this function affects Windows scheduling, effectively giving -// the thread with affinity for a specified CPU more priority on that CPU. -bool SetThreadAffinity(BusyThread* t, int cpu, int affinity) { -#if defined(WEBRTC_WIN) - if (affinity >= 0) { - return ::SetThreadAffinityMask(t->GetHandle(), - 1 << (cpu + affinity)) != FALSE; - } -#endif - return true; -} - -bool SetThreadPriority(BusyThread* t, int prio) { - if (!prio) { - return true; - } - bool ok = t->SetPriority(static_cast(prio)); - if (!ok) { - std::cout << "Error setting thread priority." << std::endl; - } - return ok; -} - -int CpuLoad(double cpuload, double duration, int numthreads, - int priority, double interval, int affinity) { - int ret = 0; - std::vector threads; - for (int i = 0; i < numthreads; ++i) { - threads.push_back(new BusyThread(cpuload, duration, interval)); - // NOTE(fbarchard): Priority must be done before Start. - if (!SetThreadPriority(threads[i], priority) || - !threads[i]->Start() || - !SetThreadAffinity(threads[i], i, affinity)) { - ret = 1; - break; - } - } - // Wait on each thread - if (ret == 0) { - for (int i = 0; i < numthreads; ++i) { - threads[i]->Stop(); - } - } - - for (int i = 0; i < numthreads; ++i) { - delete threads[i]; - } - return ret; -} - -// Make 2 CPUs busy -static void CpuTwoBusyLoop(int busytime) { - CpuLoad(100.0, busytime / 1000.0, 2, 1, 0.050, -1); -} - -// Make 1 CPUs busy -static void CpuBusyLoop(int busytime) { - CpuLoad(100.0, busytime / 1000.0, 1, 1, 0.050, -1); -} - -// Make 1 use half CPU time. -static void CpuHalfBusyLoop(int busytime) { - CpuLoad(50.0, busytime / 1000.0, 1, 1, 0.050, -1); -} - -void TestCpuSampler(bool test_proc, bool test_sys, bool force_fallback) { - CpuSampler sampler; - sampler.set_force_fallback(force_fallback); - EXPECT_TRUE(sampler.Init()); - sampler.set_load_interval(100); - int cpus = sampler.GetMaxCpus(); - - // Test1: CpuSampler under idle situation. - Thread::SleepMs(kSettleTime); - sampler.GetProcessLoad(); - sampler.GetSystemLoad(); - - Thread::SleepMs(kIdleTime); - - float proc_idle = 0.f, sys_idle = 0.f; - if (test_proc) { - proc_idle = sampler.GetProcessLoad(); - } - if (test_sys) { - sys_idle = sampler.GetSystemLoad(); - } - if (test_proc) { - LOG(LS_INFO) << "ProcessLoad Idle: " - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << proc_idle; - EXPECT_GE(proc_idle, 0.f); - EXPECT_LE(proc_idle, static_cast(cpus)); - } - if (test_sys) { - LOG(LS_INFO) << "SystemLoad Idle: " - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << sys_idle; - EXPECT_GE(sys_idle, 0.f); - EXPECT_LE(sys_idle, static_cast(cpus)); - } - - // Test2: CpuSampler with main process at 50% busy. - Thread::SleepMs(kSettleTime); - sampler.GetProcessLoad(); - sampler.GetSystemLoad(); - - CpuHalfBusyLoop(kBusyTime); - - float proc_halfbusy = 0.f, sys_halfbusy = 0.f; - if (test_proc) { - proc_halfbusy = sampler.GetProcessLoad(); - } - if (test_sys) { - sys_halfbusy = sampler.GetSystemLoad(); - } - if (test_proc) { - LOG(LS_INFO) << "ProcessLoad Halfbusy: " - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << proc_halfbusy; - EXPECT_GE(proc_halfbusy, 0.f); - EXPECT_LE(proc_halfbusy, static_cast(cpus)); - } - if (test_sys) { - LOG(LS_INFO) << "SystemLoad Halfbusy: " - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << sys_halfbusy; - EXPECT_GE(sys_halfbusy, 0.f); - EXPECT_LE(sys_halfbusy, static_cast(cpus)); - } - - // Test3: CpuSampler with main process busy. - Thread::SleepMs(kSettleTime); - sampler.GetProcessLoad(); - sampler.GetSystemLoad(); - - CpuBusyLoop(kBusyTime); - - float proc_busy = 0.f, sys_busy = 0.f; - if (test_proc) { - proc_busy = sampler.GetProcessLoad(); - } - if (test_sys) { - sys_busy = sampler.GetSystemLoad(); - } - if (test_proc) { - LOG(LS_INFO) << "ProcessLoad Busy: " - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << proc_busy; - EXPECT_GE(proc_busy, 0.f); - EXPECT_LE(proc_busy, static_cast(cpus)); - } - if (test_sys) { - LOG(LS_INFO) << "SystemLoad Busy: " - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << sys_busy; - EXPECT_GE(sys_busy, 0.f); - EXPECT_LE(sys_busy, static_cast(cpus)); - } - - // Test4: CpuSampler with 2 cpus process busy. - if (cpus >= 2) { - Thread::SleepMs(kSettleTime); - sampler.GetProcessLoad(); - sampler.GetSystemLoad(); - - CpuTwoBusyLoop(kBusyTime); - - float proc_twobusy = 0.f, sys_twobusy = 0.f; - if (test_proc) { - proc_twobusy = sampler.GetProcessLoad(); - } - if (test_sys) { - sys_twobusy = sampler.GetSystemLoad(); - } - if (test_proc) { - LOG(LS_INFO) << "ProcessLoad 2 CPU Busy:" - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << proc_twobusy; - EXPECT_GE(proc_twobusy, 0.f); - EXPECT_LE(proc_twobusy, static_cast(cpus)); - } - if (test_sys) { - LOG(LS_INFO) << "SystemLoad 2 CPU Busy: " - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << sys_twobusy; - EXPECT_GE(sys_twobusy, 0.f); - EXPECT_LE(sys_twobusy, static_cast(cpus)); - } - } - - // Test5: CpuSampler with idle process after being busy. - Thread::SleepMs(kSettleTime); - sampler.GetProcessLoad(); - sampler.GetSystemLoad(); - - Thread::SleepMs(kIdleTime); - - if (test_proc) { - proc_idle = sampler.GetProcessLoad(); - } - if (test_sys) { - sys_idle = sampler.GetSystemLoad(); - } - if (test_proc) { - LOG(LS_INFO) << "ProcessLoad Idle: " - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << proc_idle; - EXPECT_GE(proc_idle, 0.f); - EXPECT_LE(proc_idle, proc_busy); - } - if (test_sys) { - LOG(LS_INFO) << "SystemLoad Idle: " - << std::setiosflags(std::ios_base::fixed) - << std::setprecision(2) << std::setw(6) << sys_idle; - EXPECT_GE(sys_idle, 0.f); - EXPECT_LE(sys_idle, static_cast(cpus)); - } -} - -TEST(CpuMonitorTest, TestCpus) { - CpuSampler sampler; - EXPECT_TRUE(sampler.Init()); - int current_cpus = sampler.GetCurrentCpus(); - int cpus = sampler.GetMaxCpus(); - LOG(LS_INFO) << "Current Cpus: " << std::setw(9) << current_cpus; - LOG(LS_INFO) << "Maximum Cpus: " << std::setw(9) << cpus; - EXPECT_GT(cpus, 0); - EXPECT_LE(cpus, kMaxCpus); - EXPECT_GT(current_cpus, 0); - EXPECT_LE(current_cpus, cpus); -} - -#if defined(WEBRTC_WIN) -// Tests overall system CpuSampler using legacy OS fallback code if applicable. -TEST(CpuMonitorTest, TestGetSystemLoadForceFallback) { - TestCpuSampler(false, true, true); -} -#endif - -// Tests both process and system functions in use at same time. -TEST(CpuMonitorTest, TestGetBothLoad) { - TestCpuSampler(true, true, false); -} - -// Tests a query less than the interval produces the same value. -TEST(CpuMonitorTest, TestInterval) { - CpuSampler sampler; - EXPECT_TRUE(sampler.Init()); - - // Test1: Set interval to large value so sampler will not update. - sampler.set_load_interval(kLongInterval); - - sampler.GetProcessLoad(); - sampler.GetSystemLoad(); - - float proc_orig = sampler.GetProcessLoad(); - float sys_orig = sampler.GetSystemLoad(); - - Thread::SleepMs(kIdleTime); - - float proc_halftime = sampler.GetProcessLoad(); - float sys_halftime = sampler.GetSystemLoad(); - - EXPECT_EQ(proc_orig, proc_halftime); - EXPECT_EQ(sys_orig, sys_halftime); -} - -TEST(CpuMonitorTest, TestCpuMonitor) { - CpuMonitor monitor(Thread::Current()); - CpuLoadListener listener; - monitor.SignalUpdate.connect(&listener, &CpuLoadListener::OnCpuLoad); - EXPECT_TRUE(monitor.Start(10)); - // 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); - EXPECT_GE(listener.system_load(), .0f); - - monitor.Stop(); - // Wait 20 ms to ake sure all signals are delivered. - Thread::Current()->ProcessMessages(20); - int old_count = listener.count(); - Thread::Current()->ProcessMessages(20); - // Verfy no more siganls. - EXPECT_EQ(old_count, listener.count()); -} - -} // namespace rtc diff --git a/webrtc/base/crc32.cc b/webrtc/base/crc32.cc deleted file mode 100644 index d643a25a4..000000000 --- a/webrtc/base/crc32.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/crc32.h" - -#include "webrtc/base/basicdefs.h" - -namespace rtc { - -// This implementation is based on the sample implementation in RFC 1952. - -// CRC32 polynomial, in reversed form. -// See RFC 1952, or http://en.wikipedia.org/wiki/Cyclic_redundancy_check -static const uint32 kCrc32Polynomial = 0xEDB88320; -static uint32 kCrc32Table[256] = { 0 }; - -static void EnsureCrc32TableInited() { - if (kCrc32Table[ARRAY_SIZE(kCrc32Table) - 1]) - return; // already inited - for (uint32 i = 0; i < ARRAY_SIZE(kCrc32Table); ++i) { - uint32 c = i; - for (size_t j = 0; j < 8; ++j) { - if (c & 1) { - c = kCrc32Polynomial ^ (c >> 1); - } else { - c >>= 1; - } - } - kCrc32Table[i] = c; - } -} - -uint32 UpdateCrc32(uint32 start, const void* buf, size_t len) { - EnsureCrc32TableInited(); - - uint32 c = start ^ 0xFFFFFFFF; - const uint8* u = static_cast(buf); - for (size_t i = 0; i < len; ++i) { - c = kCrc32Table[(c ^ u[i]) & 0xFF] ^ (c >> 8); - } - return c ^ 0xFFFFFFFF; -} - -} // namespace rtc - diff --git a/webrtc/base/crc32.h b/webrtc/base/crc32.h deleted file mode 100644 index 99b4cac89..000000000 --- a/webrtc/base/crc32.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_CRC32_H_ -#define WEBRTC_BASE_CRC32_H_ - -#include - -#include "webrtc/base/basictypes.h" - -namespace rtc { - -// Updates a CRC32 checksum with |len| bytes from |buf|. |initial| holds the -// checksum result from the previous update; for the first call, it should be 0. -uint32 UpdateCrc32(uint32 initial, const void* buf, size_t len); - -// Computes a CRC32 checksum using |len| bytes from |buf|. -inline uint32 ComputeCrc32(const void* buf, size_t len) { - return UpdateCrc32(0, buf, len); -} -inline uint32 ComputeCrc32(const std::string& str) { - return ComputeCrc32(str.c_str(), str.size()); -} - -} // namespace rtc - -#endif // WEBRTC_BASE_CRC32_H_ diff --git a/webrtc/base/crc32_unittest.cc b/webrtc/base/crc32_unittest.cc deleted file mode 100644 index 0bfdeeea0..000000000 --- a/webrtc/base/crc32_unittest.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/crc32.h" -#include "webrtc/base/gunit.h" - -#include - -namespace rtc { - -TEST(Crc32Test, TestBasic) { - EXPECT_EQ(0U, ComputeCrc32("")); - EXPECT_EQ(0x352441C2U, ComputeCrc32("abc")); - EXPECT_EQ(0x171A3F5FU, - ComputeCrc32("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")); -} - -TEST(Crc32Test, TestMultipleUpdates) { - std::string input = - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; - uint32 c = 0; - for (size_t i = 0; i < input.size(); ++i) { - c = UpdateCrc32(c, &input[i], 1); - } - EXPECT_EQ(0x171A3F5FU, c); -} - -} // namespace rtc diff --git a/webrtc/base/criticalsection.h b/webrtc/base/criticalsection.h deleted file mode 100644 index a950a47f5..000000000 --- a/webrtc/base/criticalsection.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_CRITICALSECTION_H__ -#define WEBRTC_BASE_CRITICALSECTION_H__ - -#include "webrtc/base/constructormagic.h" - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#endif - -#if defined(WEBRTC_POSIX) -#include -#endif - -#ifdef _DEBUG -#define CS_TRACK_OWNER 1 -#endif // _DEBUG - -#if CS_TRACK_OWNER -#define TRACK_OWNER(x) x -#else // !CS_TRACK_OWNER -#define TRACK_OWNER(x) -#endif // !CS_TRACK_OWNER - -namespace rtc { - -#if defined(WEBRTC_WIN) -class CriticalSection { - public: - CriticalSection() { - InitializeCriticalSection(&crit_); - // Windows docs say 0 is not a valid thread id - TRACK_OWNER(thread_ = 0); - } - ~CriticalSection() { - DeleteCriticalSection(&crit_); - } - void Enter() { - EnterCriticalSection(&crit_); - TRACK_OWNER(thread_ = GetCurrentThreadId()); - } - bool TryEnter() { - if (TryEnterCriticalSection(&crit_) != FALSE) { - TRACK_OWNER(thread_ = GetCurrentThreadId()); - return true; - } - return false; - } - void Leave() { - TRACK_OWNER(thread_ = 0); - LeaveCriticalSection(&crit_); - } - -#if CS_TRACK_OWNER - bool CurrentThreadIsOwner() const { return thread_ == GetCurrentThreadId(); } -#endif // CS_TRACK_OWNER - - private: - CRITICAL_SECTION crit_; - TRACK_OWNER(DWORD thread_); // The section's owning thread id -}; -#endif // WEBRTC_WIN - -#if defined(WEBRTC_POSIX) -class CriticalSection { - public: - CriticalSection() { - pthread_mutexattr_t mutex_attribute; - pthread_mutexattr_init(&mutex_attribute); - pthread_mutexattr_settype(&mutex_attribute, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mutex_, &mutex_attribute); - pthread_mutexattr_destroy(&mutex_attribute); - TRACK_OWNER(thread_ = 0); - } - ~CriticalSection() { - pthread_mutex_destroy(&mutex_); - } - void Enter() { - pthread_mutex_lock(&mutex_); - TRACK_OWNER(thread_ = pthread_self()); - } - bool TryEnter() { - if (pthread_mutex_trylock(&mutex_) == 0) { - TRACK_OWNER(thread_ = pthread_self()); - return true; - } - return false; - } - void Leave() { - TRACK_OWNER(thread_ = 0); - pthread_mutex_unlock(&mutex_); - } - -#if CS_TRACK_OWNER - bool CurrentThreadIsOwner() const { return pthread_equal(thread_, pthread_self()); } -#endif // CS_TRACK_OWNER - - private: - pthread_mutex_t mutex_; - TRACK_OWNER(pthread_t thread_); -}; -#endif // WEBRTC_POSIX - -// CritScope, for serializing execution through a scope. -class CritScope { - public: - explicit CritScope(CriticalSection *pcrit) { - pcrit_ = pcrit; - pcrit_->Enter(); - } - ~CritScope() { - pcrit_->Leave(); - } - private: - CriticalSection *pcrit_; - DISALLOW_COPY_AND_ASSIGN(CritScope); -}; - -// Tries to lock a critical section on construction via -// CriticalSection::TryEnter, and unlocks on destruction if the -// lock was taken. Never blocks. -// -// IMPORTANT: Unlike CritScope, the lock may not be owned by this thread in -// subsequent code. Users *must* check locked() to determine if the -// lock was taken. If you're not calling locked(), you're doing it wrong! -class TryCritScope { - public: - explicit TryCritScope(CriticalSection *pcrit) { - pcrit_ = pcrit; - locked_ = pcrit_->TryEnter(); - } - ~TryCritScope() { - if (locked_) { - pcrit_->Leave(); - } - } - bool locked() const { - return locked_; - } - private: - CriticalSection *pcrit_; - bool locked_; - DISALLOW_COPY_AND_ASSIGN(TryCritScope); -}; - -// TODO: Move this to atomicops.h, which can't be done easily because of -// complex compile rules. -class AtomicOps { - public: -#if defined(WEBRTC_WIN) - // Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64. - static int Increment(int* i) { - return ::InterlockedIncrement(reinterpret_cast(i)); - } - static int Decrement(int* i) { - return ::InterlockedDecrement(reinterpret_cast(i)); - } -#else - static int Increment(int* i) { - return __sync_add_and_fetch(i, 1); - } - static int Decrement(int* i) { - return __sync_sub_and_fetch(i, 1); - } -#endif -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_CRITICALSECTION_H__ diff --git a/webrtc/base/criticalsection_unittest.cc b/webrtc/base/criticalsection_unittest.cc deleted file mode 100644 index e1b05cb01..000000000 --- a/webrtc/base/criticalsection_unittest.cc +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/event.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/scopedptrcollection.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -namespace { - -const int kLongTime = 10000; // 10 seconds -const int kNumThreads = 16; -const int kOperationsToRun = 1000; - -template -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 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::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 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* 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 runner(0); - ScopedPtrCollection 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 runner(kOperationsToRun * kNumThreads); - ScopedPtrCollection threads; - StartThreads(&threads, &runner); - runner.SetExpectedThreadCount(kNumThreads); - - // Release the hounds! - EXPECT_TRUE(runner.Run()); - EXPECT_EQ(0, runner.value()); -} - -} // namespace rtc diff --git a/webrtc/base/cryptstring.h b/webrtc/base/cryptstring.h deleted file mode 100644 index f43057d8f..000000000 --- a/webrtc/base/cryptstring.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef _WEBRTC_BASE_CRYPTSTRING_H_ -#define _WEBRTC_BASE_CRYPTSTRING_H_ - -#include - -#include -#include - -#include "webrtc/base/linked_ptr.h" -#include "webrtc/base/scoped_ptr.h" - -namespace rtc { - -class CryptStringImpl { -public: - virtual ~CryptStringImpl() {} - virtual size_t GetLength() const = 0; - virtual void CopyTo(char * dest, bool nullterminate) const = 0; - virtual std::string UrlEncode() const = 0; - virtual CryptStringImpl * Copy() const = 0; - virtual void CopyRawTo(std::vector * dest) const = 0; -}; - -class EmptyCryptStringImpl : public CryptStringImpl { -public: - virtual ~EmptyCryptStringImpl() {} - virtual size_t GetLength() const { return 0; } - virtual void CopyTo(char * dest, bool nullterminate) const { - if (nullterminate) { - *dest = '\0'; - } - } - virtual std::string UrlEncode() const { return ""; } - virtual CryptStringImpl * Copy() const { return new EmptyCryptStringImpl(); } - virtual void CopyRawTo(std::vector * dest) const { - dest->clear(); - } -}; - -class CryptString { -public: - CryptString() : impl_(new EmptyCryptStringImpl()) {} - size_t GetLength() const { return impl_->GetLength(); } - void CopyTo(char * dest, bool nullterminate) const { impl_->CopyTo(dest, nullterminate); } - CryptString(const CryptString & other) : impl_(other.impl_->Copy()) {} - explicit CryptString(const CryptStringImpl & impl) : impl_(impl.Copy()) {} - CryptString & operator=(const CryptString & other) { - if (this != &other) { - impl_.reset(other.impl_->Copy()); - } - return *this; - } - void Clear() { impl_.reset(new EmptyCryptStringImpl()); } - std::string UrlEncode() const { return impl_->UrlEncode(); } - void CopyRawTo(std::vector * dest) const { - return impl_->CopyRawTo(dest); - } - -private: - scoped_ptr impl_; -}; - - -// Used for constructing strings where a password is involved and we -// need to ensure that we zero memory afterwards -class FormatCryptString { -public: - FormatCryptString() { - storage_ = new char[32]; - capacity_ = 32; - length_ = 0; - storage_[0] = 0; - } - - void Append(const std::string & text) { - Append(text.data(), text.length()); - } - - void Append(const char * data, size_t length) { - EnsureStorage(length_ + length + 1); - memcpy(storage_ + length_, data, length); - length_ += length; - storage_[length_] = '\0'; - } - - void Append(const CryptString * password) { - size_t len = password->GetLength(); - EnsureStorage(length_ + len + 1); - password->CopyTo(storage_ + length_, true); - length_ += len; - } - - size_t GetLength() { - return length_; - } - - const char * GetData() { - return storage_; - } - - - // Ensures storage of at least n bytes - void EnsureStorage(size_t n) { - if (capacity_ >= n) { - return; - } - - size_t old_capacity = capacity_; - char * old_storage = storage_; - - for (;;) { - capacity_ *= 2; - if (capacity_ >= n) - break; - } - - storage_ = new char[capacity_]; - - if (old_capacity) { - memcpy(storage_, old_storage, length_); - - // zero memory in a way that an optimizer won't optimize it out - old_storage[0] = 0; - for (size_t i = 1; i < old_capacity; i++) { - old_storage[i] = old_storage[i - 1]; - } - delete[] old_storage; - } - } - - ~FormatCryptString() { - if (capacity_) { - storage_[0] = 0; - for (size_t i = 1; i < capacity_; i++) { - storage_[i] = storage_[i - 1]; - } - } - delete[] storage_; - } -private: - char * storage_; - size_t capacity_; - size_t length_; -}; - -class InsecureCryptStringImpl : public CryptStringImpl { - public: - std::string& password() { return password_; } - const std::string& password() const { return password_; } - - virtual ~InsecureCryptStringImpl() {} - virtual size_t GetLength() const { return password_.size(); } - virtual void CopyTo(char * dest, bool nullterminate) const { - memcpy(dest, password_.data(), password_.size()); - if (nullterminate) dest[password_.size()] = 0; - } - virtual std::string UrlEncode() const { return password_; } - virtual CryptStringImpl * Copy() const { - InsecureCryptStringImpl * copy = new InsecureCryptStringImpl; - copy->password() = password_; - return copy; - } - virtual void CopyRawTo(std::vector * dest) const { - dest->resize(password_.size()); - memcpy(&dest->front(), password_.data(), password_.size()); - } - private: - std::string password_; -}; - -} - -#endif // _WEBRTC_BASE_CRYPTSTRING_H_ diff --git a/webrtc/base/dbus.cc b/webrtc/base/dbus.cc deleted file mode 100644 index b8392f9a2..000000000 --- a/webrtc/base/dbus.cc +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifdef HAVE_DBUS_GLIB - -#include "webrtc/base/dbus.h" - -#include - -#include "webrtc/base/logging.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -// Avoid static object construction/destruction on startup/shutdown. -static pthread_once_t g_dbus_init_once = PTHREAD_ONCE_INIT; -static LibDBusGlibSymbolTable *g_dbus_symbol = NULL; - -// Releases DBus-Glib symbols. -static void ReleaseDBusGlibSymbol() { - if (g_dbus_symbol != NULL) { - delete g_dbus_symbol; - g_dbus_symbol = NULL; - } -} - -// Loads DBus-Glib symbols. -static void InitializeDBusGlibSymbol() { - // This is thread safe. - if (NULL == g_dbus_symbol) { - g_dbus_symbol = new LibDBusGlibSymbolTable(); - - // Loads dbus-glib - if (NULL == g_dbus_symbol || !g_dbus_symbol->Load()) { - LOG(LS_WARNING) << "Failed to load dbus-glib symbol table."; - ReleaseDBusGlibSymbol(); - } else { - // Nothing we can do if atexit() failed. Just ignore its returned value. - atexit(ReleaseDBusGlibSymbol); - } - } -} - -inline static LibDBusGlibSymbolTable *GetSymbols() { - return DBusMonitor::GetDBusGlibSymbolTable(); -} - -// Implementation of class DBusSigMessageData -DBusSigMessageData::DBusSigMessageData(DBusMessage *message) - : TypedMessageData(message) { - GetSymbols()->dbus_message_ref()(data()); -} - -DBusSigMessageData::~DBusSigMessageData() { - GetSymbols()->dbus_message_unref()(data()); -} - -// Implementation of class DBusSigFilter - -// Builds a DBus filter string from given DBus path, interface and member. -std::string DBusSigFilter::BuildFilterString(const std::string &path, - const std::string &interface, - const std::string &member) { - std::string ret(DBUS_TYPE "='" DBUS_SIGNAL "'"); - if (!path.empty()) { - ret += ("," DBUS_PATH "='"); - ret += path; - ret += "'"; - } - if (!interface.empty()) { - ret += ("," DBUS_INTERFACE "='"); - ret += interface; - ret += "'"; - } - if (!member.empty()) { - ret += ("," DBUS_MEMBER "='"); - ret += member; - ret += "'"; - } - return ret; -} - -// Forwards the message to the given instance. -DBusHandlerResult DBusSigFilter::DBusCallback(DBusConnection *dbus_conn, - DBusMessage *message, - void *instance) { - ASSERT(instance); - if (instance) { - return static_cast(instance)->Callback(message); - } - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -// Posts a message to caller thread. -DBusHandlerResult DBusSigFilter::Callback(DBusMessage *message) { - if (caller_thread_) { - caller_thread_->Post(this, DSM_SIGNAL, new DBusSigMessageData(message)); - } - // Don't "eat" the message here. Let it pop up. - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -// From MessageHandler. -void DBusSigFilter::OnMessage(Message *message) { - if (message != NULL && DSM_SIGNAL == message->message_id) { - DBusSigMessageData *msg = - static_cast(message->pdata); - if (msg) { - ProcessSignal(msg->data()); - delete msg; - } - } -} - -// Definition of private class DBusMonitoringThread. -// It creates a worker-thread to listen signals on DBus. The worker-thread will -// be running in a priate GMainLoop forever until either Stop() has been invoked -// or it hits an error. -class DBusMonitor::DBusMonitoringThread : public rtc::Thread { - public: - explicit DBusMonitoringThread(DBusMonitor *monitor, - GMainContext *context, - GMainLoop *mainloop, - std::vector *filter_list) - : monitor_(monitor), - context_(context), - mainloop_(mainloop), - connection_(NULL), - idle_source_(NULL), - filter_list_(filter_list) { - ASSERT(monitor_); - ASSERT(context_); - ASSERT(mainloop_); - ASSERT(filter_list_); - } - - virtual ~DBusMonitoringThread() { - Stop(); - } - - // Override virtual method of Thread. Context: worker-thread. - virtual void Run() { - ASSERT(NULL == connection_); - - // Setup DBus connection and start monitoring. - monitor_->OnMonitoringStatusChanged(DMS_INITIALIZING); - if (!Setup()) { - LOG(LS_ERROR) << "DBus monitoring setup failed."; - monitor_->OnMonitoringStatusChanged(DMS_FAILED); - CleanUp(); - return; - } - monitor_->OnMonitoringStatusChanged(DMS_RUNNING); - g_main_loop_run(mainloop_); - monitor_->OnMonitoringStatusChanged(DMS_STOPPED); - - // Done normally. Clean up DBus connection. - CleanUp(); - return; - } - - // Override virtual method of Thread. Context: caller-thread. - virtual void Stop() { - ASSERT(NULL == idle_source_); - // Add an idle source and let the gmainloop quit on idle. - idle_source_ = g_idle_source_new(); - if (idle_source_) { - g_source_set_callback(idle_source_, &Idle, this, NULL); - g_source_attach(idle_source_, context_); - } else { - LOG(LS_ERROR) << "g_idle_source_new() failed."; - QuitGMainloop(); // Try to quit anyway. - } - - Thread::Stop(); // Wait for the thread. - } - - private: - // Registers all DBus filters. - void RegisterAllFilters() { - ASSERT(NULL != GetSymbols()->dbus_g_connection_get_connection()( - connection_)); - - for (std::vector::iterator it = filter_list_->begin(); - it != filter_list_->end(); ++it) { - DBusSigFilter *filter = (*it); - if (!filter) { - LOG(LS_ERROR) << "DBusSigFilter list corrupted."; - continue; - } - - GetSymbols()->dbus_bus_add_match()( - GetSymbols()->dbus_g_connection_get_connection()(connection_), - filter->filter().c_str(), NULL); - - if (!GetSymbols()->dbus_connection_add_filter()( - GetSymbols()->dbus_g_connection_get_connection()(connection_), - &DBusSigFilter::DBusCallback, filter, NULL)) { - LOG(LS_ERROR) << "dbus_connection_add_filter() failed." - << "Filter: " << filter->filter(); - continue; - } - } - } - - // Unregisters all DBus filters. - void UnRegisterAllFilters() { - ASSERT(NULL != GetSymbols()->dbus_g_connection_get_connection()( - connection_)); - - for (std::vector::iterator it = filter_list_->begin(); - it != filter_list_->end(); ++it) { - DBusSigFilter *filter = (*it); - if (!filter) { - LOG(LS_ERROR) << "DBusSigFilter list corrupted."; - continue; - } - GetSymbols()->dbus_connection_remove_filter()( - GetSymbols()->dbus_g_connection_get_connection()(connection_), - &DBusSigFilter::DBusCallback, filter); - } - } - - // Sets up the monitoring thread. - bool Setup() { - g_main_context_push_thread_default(context_); - - // Start connection to dbus. - // If dbus daemon is not running, returns false immediately. - connection_ = GetSymbols()->dbus_g_bus_get_private()(monitor_->type_, - context_, NULL); - if (NULL == connection_) { - LOG(LS_ERROR) << "dbus_g_bus_get_private() unable to get connection."; - return false; - } - if (NULL == GetSymbols()->dbus_g_connection_get_connection()(connection_)) { - LOG(LS_ERROR) << "dbus_g_connection_get_connection() returns NULL. " - << "DBus daemon is probably not running."; - return false; - } - - // Application don't exit if DBus daemon die. - GetSymbols()->dbus_connection_set_exit_on_disconnect()( - GetSymbols()->dbus_g_connection_get_connection()(connection_), FALSE); - - // Connect all filters. - RegisterAllFilters(); - - return true; - } - - // Cleans up the monitoring thread. - void CleanUp() { - if (idle_source_) { - // We did an attach() with the GSource, so we need to destroy() it. - g_source_destroy(idle_source_); - // We need to unref() the GSource to end the last reference we got. - g_source_unref(idle_source_); - idle_source_ = NULL; - } - if (connection_) { - if (GetSymbols()->dbus_g_connection_get_connection()(connection_)) { - UnRegisterAllFilters(); - GetSymbols()->dbus_connection_close()( - GetSymbols()->dbus_g_connection_get_connection()(connection_)); - } - GetSymbols()->dbus_g_connection_unref()(connection_); - connection_ = NULL; - } - g_main_loop_unref(mainloop_); - mainloop_ = NULL; - g_main_context_unref(context_); - context_ = NULL; - } - - // Handles callback on Idle. We only add this source when ready to stop. - static gboolean Idle(gpointer data) { - static_cast(data)->QuitGMainloop(); - return TRUE; - } - - // We only hit this when ready to quit. - void QuitGMainloop() { - g_main_loop_quit(mainloop_); - } - - DBusMonitor *monitor_; - - GMainContext *context_; - GMainLoop *mainloop_; - DBusGConnection *connection_; - GSource *idle_source_; - - std::vector *filter_list_; -}; - -// Implementation of class DBusMonitor - -// Returns DBus-Glib symbol handle. Initialize it first if hasn't. -LibDBusGlibSymbolTable *DBusMonitor::GetDBusGlibSymbolTable() { - // This is multi-thread safe. - pthread_once(&g_dbus_init_once, InitializeDBusGlibSymbol); - - return g_dbus_symbol; -}; - -// Creates an instance of DBusMonitor -DBusMonitor *DBusMonitor::Create(DBusBusType type) { - if (NULL == DBusMonitor::GetDBusGlibSymbolTable()) { - return NULL; - } - return new DBusMonitor(type); -} - -DBusMonitor::DBusMonitor(DBusBusType type) - : type_(type), - status_(DMS_NOT_INITIALIZED), - monitoring_thread_(NULL) { - ASSERT(type_ == DBUS_BUS_SYSTEM || type_ == DBUS_BUS_SESSION); -} - -DBusMonitor::~DBusMonitor() { - StopMonitoring(); -} - -bool DBusMonitor::AddFilter(DBusSigFilter *filter) { - if (monitoring_thread_) { - return false; - } - if (!filter) { - return false; - } - filter_list_.push_back(filter); - return true; -} - -bool DBusMonitor::StartMonitoring() { - if (!monitoring_thread_) { - g_type_init(); - g_thread_init(NULL); - GetSymbols()->dbus_g_thread_init()(); - - GMainContext *context = g_main_context_new(); - if (NULL == context) { - LOG(LS_ERROR) << "g_main_context_new() failed."; - return false; - } - - GMainLoop *mainloop = g_main_loop_new(context, FALSE); - if (NULL == mainloop) { - LOG(LS_ERROR) << "g_main_loop_new() failed."; - g_main_context_unref(context); - return false; - } - - monitoring_thread_ = new DBusMonitoringThread(this, context, mainloop, - &filter_list_); - if (monitoring_thread_ == NULL) { - LOG(LS_ERROR) << "Failed to create DBus monitoring thread."; - g_main_context_unref(context); - g_main_loop_unref(mainloop); - return false; - } - monitoring_thread_->Start(); - } - return true; -} - -bool DBusMonitor::StopMonitoring() { - if (monitoring_thread_) { - monitoring_thread_->Stop(); - monitoring_thread_ = NULL; - } - return true; -} - -DBusMonitor::DBusMonitorStatus DBusMonitor::GetStatus() { - return status_; -} - -void DBusMonitor::OnMonitoringStatusChanged(DBusMonitorStatus status) { - status_ = status; -} - -#undef LATE - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB diff --git a/webrtc/base/dbus.h b/webrtc/base/dbus.h deleted file mode 100644 index fb90638bc..000000000 --- a/webrtc/base/dbus.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_DBUS_H_ -#define WEBRTC_BASE_DBUS_H_ - -#ifdef HAVE_DBUS_GLIB - -#include - -#include -#include - -#include "webrtc/base/libdbusglibsymboltable.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -#define DBUS_TYPE "type" -#define DBUS_SIGNAL "signal" -#define DBUS_PATH "path" -#define DBUS_INTERFACE "interface" -#define DBUS_MEMBER "member" - -#ifdef CHROMEOS -#define CROS_PM_PATH "/" -#define CROS_PM_INTERFACE "org.chromium.PowerManager" -#define CROS_SIG_POWERCHANGED "PowerStateChanged" -#define CROS_VALUE_SLEEP "mem" -#define CROS_VALUE_RESUME "on" -#else -#define UP_PATH "/org/freedesktop/UPower" -#define UP_INTERFACE "org.freedesktop.UPower" -#define UP_SIG_SLEEPING "Sleeping" -#define UP_SIG_RESUMING "Resuming" -#endif // CHROMEOS - -// Wraps a DBus messages. -class DBusSigMessageData : public TypedMessageData { - public: - explicit DBusSigMessageData(DBusMessage *message); - ~DBusSigMessageData(); -}; - -// DBusSigFilter is an abstract class that defines the interface of DBus -// signal handling. -// The subclasses implement ProcessSignal() for various purposes. -// When a DBus signal comes, a DSM_SIGNAL message is posted to the caller thread -// which will then invokes ProcessSignal(). -class DBusSigFilter : protected MessageHandler { - public: - enum DBusSigMessage { DSM_SIGNAL }; - - // This filter string should ususally come from BuildFilterString() - explicit DBusSigFilter(const std::string &filter) - : caller_thread_(Thread::Current()), filter_(filter) { - } - - // Builds a DBus monitor filter string from given DBus path, interface, and - // member. - // See http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html - static std::string BuildFilterString(const std::string &path, - const std::string &interface, - const std::string &member); - - // Handles callback on DBus messages by DBus system. - static DBusHandlerResult DBusCallback(DBusConnection *dbus_conn, - DBusMessage *message, - void *instance); - - // Handles callback on DBus messages to each DBusSigFilter instance. - DBusHandlerResult Callback(DBusMessage *message); - - // From MessageHandler. - virtual void OnMessage(Message *message); - - // Returns the DBus monitor filter string. - const std::string &filter() const { return filter_; } - - private: - // On caller thread. - virtual void ProcessSignal(DBusMessage *message) = 0; - - Thread *caller_thread_; - const std::string filter_; -}; - -// DBusMonitor is a class for DBus signal monitoring. -// -// The caller-thread calls AddFilter() first to add the signals that it wants to -// monitor and then calls StartMonitoring() to start the monitoring. -// This will create a worker-thread which listens on DBus connection and sends -// DBus signals back through the callback. -// The worker-thread will be running forever until either StopMonitoring() is -// called from the caller-thread or the worker-thread hit some error. -// -// Programming model: -// 1. Caller-thread: Creates an object of DBusMonitor. -// 2. Caller-thread: Calls DBusMonitor::AddFilter() one or several times. -// 3. Caller-thread: StartMonitoring(). -// ... -// 4. Worker-thread: DBus signal recieved. Post a message to caller-thread. -// 5. Caller-thread: DBusFilterBase::ProcessSignal() is invoked. -// ... -// 6. Caller-thread: StopMonitoring(). -// -// Assumption: -// AddFilter(), StartMonitoring(), and StopMonitoring() methods are called by -// a single thread. Hence, there is no need to make them thread safe. -class DBusMonitor { - public: - // Status of DBus monitoring. - enum DBusMonitorStatus { - DMS_NOT_INITIALIZED, // Not initialized. - DMS_INITIALIZING, // Initializing the monitoring thread. - DMS_RUNNING, // Monitoring. - DMS_STOPPED, // Not monitoring. Stopped normally. - DMS_FAILED, // Not monitoring. Failed. - }; - - // Returns the DBus-Glib symbol table. - // We should only use this function to access DBus-Glib symbols. - static LibDBusGlibSymbolTable *GetDBusGlibSymbolTable(); - - // Creates an instance of DBusMonitor. - static DBusMonitor *Create(DBusBusType type); - ~DBusMonitor(); - - // Adds a filter to DBusMonitor. - bool AddFilter(DBusSigFilter *filter); - - // Starts DBus message monitoring. - bool StartMonitoring(); - - // Stops DBus message monitoring. - bool StopMonitoring(); - - // Gets the status of DBus monitoring. - DBusMonitorStatus GetStatus(); - - private: - // Forward declaration. Defined in the .cc file. - class DBusMonitoringThread; - - explicit DBusMonitor(DBusBusType type); - - // Updates status_ when monitoring status has changed. - void OnMonitoringStatusChanged(DBusMonitorStatus status); - - DBusBusType type_; - DBusMonitorStatus status_; - DBusMonitoringThread *monitoring_thread_; - std::vector filter_list_; -}; - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB - -#endif // WEBRTC_BASE_DBUS_H_ diff --git a/webrtc/base/dbus_unittest.cc b/webrtc/base/dbus_unittest.cc deleted file mode 100644 index 505ddbbc8..000000000 --- a/webrtc/base/dbus_unittest.cc +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifdef HAVE_DBUS_GLIB - -#include "webrtc/base/dbus.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -#define SIG_NAME "NameAcquired" - -static const uint32 kTimeoutMs = 5000U; - -class DBusSigFilterTest : public DBusSigFilter { - public: - // DBusSigFilterTest listens on DBus service itself for "NameAcquired" signal. - // This signal should be received when the application connects to DBus - // service and gains ownership of a name. - // http://dbus.freedesktop.org/doc/dbus-specification.html - DBusSigFilterTest() - : DBusSigFilter(GetFilter()), - message_received_(false) { - } - - bool MessageReceived() { - return message_received_; - } - - private: - static std::string GetFilter() { - return rtc::DBusSigFilter::BuildFilterString("", "", SIG_NAME); - } - - // Implement virtual method of DBusSigFilter. On caller thread. - virtual void ProcessSignal(DBusMessage *message) { - EXPECT_TRUE(message != NULL); - message_received_ = true; - } - - bool message_received_; -}; - -TEST(DBusMonitorTest, StartStopStartStop) { - DBusSigFilterTest filter; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter)); - - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_NOT_INITIALIZED); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_RUNNING); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -// DBusMonitorTest listens on DBus service itself for "NameAcquired" signal. -// This signal should be received when the application connects to DBus -// service and gains ownership of a name. -// This test is to make sure that we capture the "NameAcquired" signal. -TEST(DBusMonitorTest, ReceivedNameAcquiredSignal) { - DBusSigFilterTest filter; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter)); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, ConcurrentMonitors) { - DBusSigFilterTest filter1; - rtc::scoped_ptr monitor1; - monitor1.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor1) { - EXPECT_TRUE(monitor1->AddFilter(&filter1)); - DBusSigFilterTest filter2; - rtc::scoped_ptr monitor2; - monitor2.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - EXPECT_TRUE(monitor2->AddFilter(&filter2)); - - EXPECT_TRUE(monitor1->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor1->GetStatus(), kTimeoutMs); - EXPECT_TRUE(monitor2->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor2->GetStatus(), kTimeoutMs); - - EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor2->StopMonitoring()); - EXPECT_EQ(monitor2->GetStatus(), DBusMonitor::DMS_STOPPED); - - EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor1->StopMonitoring()); - EXPECT_EQ(monitor1->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, ConcurrentFilters) { - DBusSigFilterTest filter1; - DBusSigFilterTest filter2; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter1)); - EXPECT_TRUE(monitor->AddFilter(&filter2)); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - - EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs); - - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, NoAddFilterIfRunning) { - DBusSigFilterTest filter1; - DBusSigFilterTest filter2; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter1)); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_FALSE(monitor->AddFilter(&filter2)); - - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, AddFilterAfterStop) { - DBusSigFilterTest filter1; - DBusSigFilterTest filter2; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter1)); - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - - EXPECT_TRUE(monitor->AddFilter(&filter2)); - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, StopRightAfterStart) { - DBusSigFilterTest filter; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter)); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_TRUE(monitor->StopMonitoring()); - - // Stop the monitoring thread right after it had been started. - // If the monitoring thread got a chance to receive a DBus signal, it would - // post a message to the main thread and signal the main thread wakeup. - // This message will be cleaned out automatically when the filter get - // destructed. Here we also consume the wakeup signal (if there is one) so - // that the testing (main) thread is reset to a clean state. - rtc::Thread::Current()->ProcessMessages(1); - } else { - LOG(LS_WARNING) << "DBus Monitor not started."; - } -} - -TEST(DBusSigFilter, BuildFilterString) { - EXPECT_EQ(DBusSigFilter::BuildFilterString("", "", ""), - (DBUS_TYPE "='" DBUS_SIGNAL "'")); - EXPECT_EQ(DBusSigFilter::BuildFilterString("p", "", ""), - (DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p'")); - EXPECT_EQ(DBusSigFilter::BuildFilterString("p","i", ""), - (DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p'," - DBUS_INTERFACE "='i'")); - EXPECT_EQ(DBusSigFilter::BuildFilterString("p","i","m"), - (DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p'," - DBUS_INTERFACE "='i'," DBUS_MEMBER "='m'")); -} - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB diff --git a/webrtc/base/diskcache.cc b/webrtc/base/diskcache.cc deleted file mode 100644 index f893ce73d..000000000 --- a/webrtc/base/diskcache.cc +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#endif - -#include "webrtc/base/common.h" -#include "webrtc/base/diskcache.h" -#include "webrtc/base/fileutils.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/stringutils.h" - -#ifdef _DEBUG -#define TRANSPARENT_CACHE_NAMES 1 -#else // !_DEBUG -#define TRANSPARENT_CACHE_NAMES 0 -#endif // !_DEBUG - -namespace rtc { - -class DiskCache; - -/////////////////////////////////////////////////////////////////////////////// -// DiskCacheAdapter -/////////////////////////////////////////////////////////////////////////////// - -class DiskCacheAdapter : public StreamAdapterInterface { -public: - DiskCacheAdapter(const DiskCache* cache, const std::string& id, size_t index, - StreamInterface* stream) - : StreamAdapterInterface(stream), cache_(cache), id_(id), index_(index) - { } - virtual ~DiskCacheAdapter() { - Close(); - cache_->ReleaseResource(id_, index_); - } - -private: - const DiskCache* cache_; - std::string id_; - size_t index_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// DiskCache -/////////////////////////////////////////////////////////////////////////////// - -DiskCache::DiskCache() : max_cache_(0), total_size_(0), total_accessors_(0) { -} - -DiskCache::~DiskCache() { - ASSERT(0 == total_accessors_); -} - -bool DiskCache::Initialize(const std::string& folder, size_t size) { - if (!folder_.empty() || !Filesystem::CreateFolder(folder)) - return false; - - folder_ = folder; - max_cache_ = size; - ASSERT(0 == total_size_); - - if (!InitializeEntries()) - return false; - - return CheckLimit(); -} - -bool DiskCache::Purge() { - if (folder_.empty()) - return false; - - if (total_accessors_ > 0) { - LOG_F(LS_WARNING) << "Cache files open"; - return false; - } - - if (!PurgeFiles()) - return false; - - map_.clear(); - return true; -} - -bool DiskCache::LockResource(const std::string& id) { - Entry* entry = GetOrCreateEntry(id, true); - if (LS_LOCKED == entry->lock_state) - return false; - if ((LS_UNLOCKED == entry->lock_state) && (entry->accessors > 0)) - return false; - if ((total_size_ > max_cache_) && !CheckLimit()) { - LOG_F(LS_WARNING) << "Cache overfull"; - return false; - } - entry->lock_state = LS_LOCKED; - return true; -} - -StreamInterface* DiskCache::WriteResource(const std::string& id, size_t index) { - Entry* entry = GetOrCreateEntry(id, false); - if (LS_LOCKED != entry->lock_state) - return NULL; - - size_t previous_size = 0; - std::string filename(IdToFilename(id, index)); - FileStream::GetSize(filename, &previous_size); - ASSERT(previous_size <= entry->size); - if (previous_size > entry->size) { - previous_size = entry->size; - } - - scoped_ptr file(new FileStream); - if (!file->Open(filename, "wb", NULL)) { - LOG_F(LS_ERROR) << "Couldn't create cache file"; - return NULL; - } - - entry->streams = stdmax(entry->streams, index + 1); - entry->size -= previous_size; - total_size_ -= previous_size; - - entry->accessors += 1; - total_accessors_ += 1; - return new DiskCacheAdapter(this, id, index, file.release()); -} - -bool DiskCache::UnlockResource(const std::string& id) { - Entry* entry = GetOrCreateEntry(id, false); - if (LS_LOCKED != entry->lock_state) - return false; - - if (entry->accessors > 0) { - entry->lock_state = LS_UNLOCKING; - } else { - entry->lock_state = LS_UNLOCKED; - entry->last_modified = time(0); - CheckLimit(); - } - return true; -} - -StreamInterface* DiskCache::ReadResource(const std::string& id, - size_t index) const { - const Entry* entry = GetEntry(id); - if (LS_UNLOCKED != entry->lock_state) - return NULL; - if (index >= entry->streams) - return NULL; - - scoped_ptr file(new FileStream); - if (!file->Open(IdToFilename(id, index), "rb", NULL)) - return NULL; - - entry->accessors += 1; - total_accessors_ += 1; - return new DiskCacheAdapter(this, id, index, file.release()); -} - -bool DiskCache::HasResource(const std::string& id) const { - const Entry* entry = GetEntry(id); - return (NULL != entry) && (entry->streams > 0); -} - -bool DiskCache::HasResourceStream(const std::string& id, size_t index) const { - const Entry* entry = GetEntry(id); - if ((NULL == entry) || (index >= entry->streams)) - return false; - - std::string filename = IdToFilename(id, index); - - return FileExists(filename); -} - -bool DiskCache::DeleteResource(const std::string& id) { - Entry* entry = GetOrCreateEntry(id, false); - if (!entry) - return true; - - if ((LS_UNLOCKED != entry->lock_state) || (entry->accessors > 0)) - return false; - - bool success = true; - for (size_t index = 0; index < entry->streams; ++index) { - std::string filename = IdToFilename(id, index); - - if (!FileExists(filename)) - continue; - - if (!DeleteFile(filename)) { - LOG_F(LS_ERROR) << "Couldn't remove cache file: " << filename; - success = false; - } - } - - total_size_ -= entry->size; - map_.erase(id); - return success; -} - -bool DiskCache::CheckLimit() { -#ifdef _DEBUG - // Temporary check to make sure everything is working correctly. - size_t cache_size = 0; - for (EntryMap::iterator it = map_.begin(); it != map_.end(); ++it) { - cache_size += it->second.size; - } - ASSERT(cache_size == total_size_); -#endif // _DEBUG - - // TODO: Replace this with a non-brain-dead algorithm for clearing out the - // oldest resources... something that isn't O(n^2) - while (total_size_ > max_cache_) { - EntryMap::iterator oldest = map_.end(); - for (EntryMap::iterator it = map_.begin(); it != map_.end(); ++it) { - if ((LS_UNLOCKED != it->second.lock_state) || (it->second.accessors > 0)) - continue; - oldest = it; - break; - } - if (oldest == map_.end()) { - LOG_F(LS_WARNING) << "All resources are locked!"; - return false; - } - for (EntryMap::iterator it = oldest++; it != map_.end(); ++it) { - if (it->second.last_modified < oldest->second.last_modified) { - oldest = it; - } - } - if (!DeleteResource(oldest->first)) { - LOG_F(LS_ERROR) << "Couldn't delete from cache!"; - return false; - } - } - return true; -} - -std::string DiskCache::IdToFilename(const std::string& id, size_t index) const { -#ifdef TRANSPARENT_CACHE_NAMES - // This escapes colons and other filesystem characters, so the user can't open - // special devices (like "COM1:"), or access other directories. - size_t buffer_size = id.length()*3 + 1; - char* buffer = new char[buffer_size]; - encode(buffer, buffer_size, id.data(), id.length(), - unsafe_filename_characters(), '%'); - // TODO: ASSERT(strlen(buffer) < FileSystem::MaxBasenameLength()); -#else // !TRANSPARENT_CACHE_NAMES - // We might want to just use a hash of the filename at some point, both for - // obfuscation, and to avoid both filename length and escaping issues. - ASSERT(false); -#endif // !TRANSPARENT_CACHE_NAMES - - char extension[32]; - sprintfn(extension, ARRAY_SIZE(extension), ".%u", index); - - Pathname pathname; - pathname.SetFolder(folder_); - pathname.SetBasename(buffer); - pathname.SetExtension(extension); - -#ifdef TRANSPARENT_CACHE_NAMES - delete [] buffer; -#endif // TRANSPARENT_CACHE_NAMES - - return pathname.pathname(); -} - -bool DiskCache::FilenameToId(const std::string& filename, std::string* id, - size_t* index) const { - Pathname pathname(filename); - unsigned tempdex; - if (1 != sscanf(pathname.extension().c_str(), ".%u", &tempdex)) - return false; - - *index = static_cast(tempdex); - - size_t buffer_size = pathname.basename().length() + 1; - char* buffer = new char[buffer_size]; - decode(buffer, buffer_size, pathname.basename().data(), - pathname.basename().length(), '%'); - id->assign(buffer); - delete [] buffer; - return true; -} - -DiskCache::Entry* DiskCache::GetOrCreateEntry(const std::string& id, - bool create) { - EntryMap::iterator it = map_.find(id); - if (it != map_.end()) - return &it->second; - if (!create) - return NULL; - Entry e; - e.lock_state = LS_UNLOCKED; - e.accessors = 0; - e.size = 0; - e.streams = 0; - e.last_modified = time(0); - it = map_.insert(EntryMap::value_type(id, e)).first; - return &it->second; -} - -void DiskCache::ReleaseResource(const std::string& id, size_t index) const { - const Entry* entry = GetEntry(id); - if (!entry) { - LOG_F(LS_WARNING) << "Missing cache entry"; - ASSERT(false); - return; - } - - entry->accessors -= 1; - total_accessors_ -= 1; - - if (LS_UNLOCKED != entry->lock_state) { - // This is safe, because locked resources only issue WriteResource, which - // is non-const. Think about a better way to handle it. - DiskCache* this2 = const_cast(this); - Entry* entry2 = this2->GetOrCreateEntry(id, false); - - size_t new_size = 0; - std::string filename(IdToFilename(id, index)); - FileStream::GetSize(filename, &new_size); - entry2->size += new_size; - this2->total_size_ += new_size; - - if ((LS_UNLOCKING == entry->lock_state) && (0 == entry->accessors)) { - entry2->last_modified = time(0); - entry2->lock_state = LS_UNLOCKED; - this2->CheckLimit(); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/diskcache.h b/webrtc/base/diskcache.h deleted file mode 100644 index 4ac1be15d..000000000 --- a/webrtc/base/diskcache.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_DISKCACHE_H__ -#define WEBRTC_BASE_DISKCACHE_H__ - -#include -#include - -#if defined(WEBRTC_WIN) -#undef UnlockResource -#endif // WEBRTC_WIN - -namespace rtc { - -class StreamInterface; - -/////////////////////////////////////////////////////////////////////////////// -// DiskCache - An LRU cache of streams, stored on disk. -// -// Streams are identified by a unique resource id. Multiple streams can be -// associated with each resource id, distinguished by an index. When old -// resources are flushed from the cache, all streams associated with those -// resources are removed together. -// DiskCache is designed to persist across executions of the program. It is -// safe for use from an arbitrary number of users on a single thread, but not -// from multiple threads or other processes. -/////////////////////////////////////////////////////////////////////////////// - -class DiskCache { -public: - DiskCache(); - virtual ~DiskCache(); - - bool Initialize(const std::string& folder, size_t size); - bool Purge(); - - bool LockResource(const std::string& id); - StreamInterface* WriteResource(const std::string& id, size_t index); - bool UnlockResource(const std::string& id); - - StreamInterface* ReadResource(const std::string& id, size_t index) const; - - bool HasResource(const std::string& id) const; - bool HasResourceStream(const std::string& id, size_t index) const; - bool DeleteResource(const std::string& id); - - protected: - virtual bool InitializeEntries() = 0; - virtual bool PurgeFiles() = 0; - - virtual bool FileExists(const std::string& filename) const = 0; - virtual bool DeleteFile(const std::string& filename) const = 0; - - enum LockState { LS_UNLOCKED, LS_LOCKED, LS_UNLOCKING }; - struct Entry { - LockState lock_state; - mutable size_t accessors; - size_t size; - size_t streams; - time_t last_modified; - }; - typedef std::map EntryMap; - friend class DiskCacheAdapter; - - bool CheckLimit(); - - std::string IdToFilename(const std::string& id, size_t index) const; - bool FilenameToId(const std::string& filename, std::string* id, - size_t* index) const; - - const Entry* GetEntry(const std::string& id) const { - return const_cast(this)->GetOrCreateEntry(id, false); - } - Entry* GetOrCreateEntry(const std::string& id, bool create); - - void ReleaseResource(const std::string& id, size_t index) const; - - std::string folder_; - size_t max_cache_, total_size_; - EntryMap map_; - mutable size_t total_accessors_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// CacheLock - Automatically manage locking and unlocking, with optional -// rollback semantics -/////////////////////////////////////////////////////////////////////////////// - -class CacheLock { -public: - CacheLock(DiskCache* cache, const std::string& id, bool rollback = false) - : cache_(cache), id_(id), rollback_(rollback) - { - locked_ = cache_->LockResource(id_); - } - ~CacheLock() { - if (locked_) { - cache_->UnlockResource(id_); - if (rollback_) { - cache_->DeleteResource(id_); - } - } - } - bool IsLocked() const { return locked_; } - void Commit() { rollback_ = false; } - -private: - DiskCache* cache_; - std::string id_; - bool rollback_, locked_; -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_DISKCACHE_H__ diff --git a/webrtc/base/diskcache_win32.cc b/webrtc/base/diskcache_win32.cc deleted file mode 100644 index 22012ccc1..000000000 --- a/webrtc/base/diskcache_win32.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/win32.h" -#include -#include -#include - -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/diskcache.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/stringutils.h" - -#include "webrtc/base/diskcache_win32.h" - -namespace rtc { - -bool DiskCacheWin32::InitializeEntries() { - // Note: We could store the cache information in a separate file, for faster - // initialization. Figuring it out empirically works, too. - - std::wstring path16 = ToUtf16(folder_); - path16.append(1, '*'); - - WIN32_FIND_DATA find_data; - HANDLE find_handle = FindFirstFile(path16.c_str(), &find_data); - if (find_handle != INVALID_HANDLE_VALUE) { - do { - size_t index; - std::string id; - if (!FilenameToId(ToUtf8(find_data.cFileName), &id, &index)) - continue; - - Entry* entry = GetOrCreateEntry(id, true); - entry->size += find_data.nFileSizeLow; - total_size_ += find_data.nFileSizeLow; - entry->streams = _max(entry->streams, index + 1); - FileTimeToUnixTime(find_data.ftLastWriteTime, &entry->last_modified); - - } while (FindNextFile(find_handle, &find_data)); - - FindClose(find_handle); - } - - return true; -} - -bool DiskCacheWin32::PurgeFiles() { - std::wstring path16 = ToUtf16(folder_); - path16.append(1, '*'); - path16.append(1, '\0'); - - SHFILEOPSTRUCT file_op = { 0 }; - file_op.wFunc = FO_DELETE; - file_op.pFrom = path16.c_str(); - file_op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT - | FOF_NORECURSION | FOF_FILESONLY; - if (0 != SHFileOperation(&file_op)) { - LOG_F(LS_ERROR) << "Couldn't delete cache files"; - return false; - } - - return true; -} - -bool DiskCacheWin32::FileExists(const std::string& filename) const { - DWORD result = ::GetFileAttributes(ToUtf16(filename).c_str()); - return (INVALID_FILE_ATTRIBUTES != result); -} - -bool DiskCacheWin32::DeleteFile(const std::string& filename) const { - return ::DeleteFile(ToUtf16(filename).c_str()) != 0; -} - -} diff --git a/webrtc/base/diskcache_win32.h b/webrtc/base/diskcache_win32.h deleted file mode 100644 index 42cb9b02c..000000000 --- a/webrtc/base/diskcache_win32.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_DISKCACHEWIN32_H__ -#define WEBRTC_BASE_DISKCACHEWIN32_H__ - -#include "webrtc/base/diskcache.h" - -namespace rtc { - -class DiskCacheWin32 : public DiskCache { - protected: - virtual bool InitializeEntries(); - virtual bool PurgeFiles(); - - virtual bool FileExists(const std::string& filename) const; - virtual bool DeleteFile(const std::string& filename) const; -}; - -} - -#endif // WEBRTC_BASE_DISKCACHEWIN32_H__ diff --git a/webrtc/base/dscp.h b/webrtc/base/dscp.h deleted file mode 100644 index 970ff93b9..000000000 --- a/webrtc/base/dscp.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_DSCP_H_ -#define WEBRTC_BASE_DSCP_H_ - -namespace rtc { -// Differentiated Services Code Point. -// See http://tools.ietf.org/html/rfc2474 for details. -enum DiffServCodePoint { - DSCP_NO_CHANGE = -1, - DSCP_DEFAULT = 0, // Same as DSCP_CS0 - DSCP_CS0 = 0, // The default - DSCP_CS1 = 8, // Bulk/background traffic - DSCP_AF11 = 10, - DSCP_AF12 = 12, - DSCP_AF13 = 14, - DSCP_CS2 = 16, - DSCP_AF21 = 18, - DSCP_AF22 = 20, - DSCP_AF23 = 22, - DSCP_CS3 = 24, - DSCP_AF31 = 26, - DSCP_AF32 = 28, - DSCP_AF33 = 30, - DSCP_CS4 = 32, - DSCP_AF41 = 34, // Video - DSCP_AF42 = 36, // Video - DSCP_AF43 = 38, // Video - DSCP_CS5 = 40, // Video - DSCP_EF = 46, // Voice - DSCP_CS6 = 48, // Voice - DSCP_CS7 = 56, // Control messages -}; - -} // namespace rtc - - #endif // WEBRTC_BASE_DSCP_H_ diff --git a/webrtc/base/event.cc b/webrtc/base/event.cc deleted file mode 100644 index 393142ea2..000000000 --- a/webrtc/base/event.cc +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/event.h" - -#if defined(WEBRTC_WIN) -#include -#elif defined(WEBRTC_POSIX) -#include -#include -#include -#else -#error "Must define either WEBRTC_WIN or WEBRTC_POSIX." -#endif - -namespace rtc { - -#if defined(WEBRTC_WIN) - -Event::Event(bool manual_reset, bool initially_signaled) - : is_manual_reset_(manual_reset), - is_initially_signaled_(initially_signaled) { - event_handle_ = ::CreateEvent(NULL, // Security attributes. - is_manual_reset_, - is_initially_signaled_, - NULL); // Name. - ASSERT(event_handle_ != NULL); -} - -Event::~Event() { - CloseHandle(event_handle_); -} - -void Event::Set() { - SetEvent(event_handle_); -} - -void Event::Reset() { - ResetEvent(event_handle_); -} - -bool Event::Wait(int cms) { - DWORD ms = (cms == kForever)? INFINITE : cms; - return (WaitForSingleObject(event_handle_, ms) == WAIT_OBJECT_0); -} - -#elif defined(WEBRTC_POSIX) - -Event::Event(bool manual_reset, bool initially_signaled) - : is_manual_reset_(manual_reset), - event_status_(initially_signaled) { - VERIFY(pthread_mutex_init(&event_mutex_, NULL) == 0); - VERIFY(pthread_cond_init(&event_cond_, NULL) == 0); -} - -Event::~Event() { - pthread_mutex_destroy(&event_mutex_); - pthread_cond_destroy(&event_cond_); -} - -void Event::Set() { - pthread_mutex_lock(&event_mutex_); - event_status_ = true; - pthread_cond_broadcast(&event_cond_); - pthread_mutex_unlock(&event_mutex_); -} - -void Event::Reset() { - pthread_mutex_lock(&event_mutex_); - event_status_ = false; - pthread_mutex_unlock(&event_mutex_); -} - -bool Event::Wait(int cms) { - pthread_mutex_lock(&event_mutex_); - int error = 0; - - if (cms != kForever) { - // 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); - - ts.tv_sec = tv.tv_sec + (cms / 1000); - ts.tv_nsec = tv.tv_usec * 1000 + (cms % 1000) * 1000000; - - // Handle overflow. - if (ts.tv_nsec >= 1000000000) { - ts.tv_sec++; - ts.tv_nsec -= 1000000000; - } -#endif - - 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_); - } - - // NOTE(liulk): Exactly one thread will auto-reset this event. All - // the other threads will think it's unsignaled. This seems to be - // consistent with auto-reset events in WEBRTC_WIN - if (error == 0 && !is_manual_reset_) - event_status_ = false; - - pthread_mutex_unlock(&event_mutex_); - - return (error == 0); -} - -#endif - -} // namespace rtc diff --git a/webrtc/base/event.h b/webrtc/base/event.h deleted file mode 100644 index f2691a2f8..000000000 --- a/webrtc/base/event.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_EVENT_H__ -#define WEBRTC_BASE_EVENT_H__ - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" // NOLINT: consider this a system header. -#elif defined(WEBRTC_POSIX) -#include -#else -#error "Must define either WEBRTC_WIN or WEBRTC_POSIX." -#endif - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/common.h" - -namespace rtc { - -class Event { - public: - Event(bool manual_reset, bool initially_signaled); - ~Event(); - - void Set(); - void Reset(); - bool Wait(int cms); - - private: - bool is_manual_reset_; - -#if defined(WEBRTC_WIN) - bool is_initially_signaled_; - HANDLE event_handle_; -#elif defined(WEBRTC_POSIX) - bool event_status_; - pthread_mutex_t event_mutex_; - pthread_cond_t event_cond_; -#endif -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_EVENT_H__ diff --git a/webrtc/base/event_unittest.cc b/webrtc/base/event_unittest.cc deleted file mode 100644 index 996ad2f95..000000000 --- a/webrtc/base/event_unittest.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/event.h" -#include "webrtc/base/gunit.h" - -namespace rtc { - -TEST(EventTest, InitiallySignaled) { - Event event(false, true); - ASSERT_TRUE(event.Wait(0)); -} - -TEST(EventTest, ManualReset) { - Event event(true, false); - ASSERT_FALSE(event.Wait(0)); - - event.Set(); - ASSERT_TRUE(event.Wait(0)); - ASSERT_TRUE(event.Wait(0)); - - event.Reset(); - ASSERT_FALSE(event.Wait(0)); -} - -TEST(EventTest, AutoReset) { - Event event(false, false); - ASSERT_FALSE(event.Wait(0)); - - event.Set(); - ASSERT_TRUE(event.Wait(0)); - ASSERT_FALSE(event.Wait(0)); -} - -} // namespace rtc diff --git a/webrtc/base/fakecpumonitor.h b/webrtc/base/fakecpumonitor.h deleted file mode 100644 index c6ea0f293..000000000 --- a/webrtc/base/fakecpumonitor.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_FAKECPUMONITOR_H_ -#define WEBRTC_BASE_FAKECPUMONITOR_H_ - -#include "webrtc/base/cpumonitor.h" - -namespace rtc { - -class FakeCpuMonitor : public rtc::CpuMonitor { - public: - explicit FakeCpuMonitor(Thread* thread) - : CpuMonitor(thread) { - } - ~FakeCpuMonitor() { - } - - virtual void OnMessage(rtc::Message* msg) { - } -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_FAKECPUMONITOR_H_ diff --git a/webrtc/base/fakenetwork.h b/webrtc/base/fakenetwork.h deleted file mode 100644 index 60773b409..000000000 --- a/webrtc/base/fakenetwork.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_FAKENETWORK_H_ -#define WEBRTC_BASE_FAKENETWORK_H_ - -#include -#include - -#include "webrtc/base/network.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/socketaddress.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -const int kFakeIPv4NetworkPrefixLength = 24; -const int kFakeIPv6NetworkPrefixLength = 64; - -// Fake network manager that allows us to manually specify the IPs to use. -class FakeNetworkManager : public NetworkManagerBase, - public MessageHandler { - public: - FakeNetworkManager() - : thread_(Thread::Current()), - next_index_(0), - started_(false), - sent_first_update_(false) { - } - - typedef std::vector IfaceList; - - void AddInterface(const SocketAddress& iface) { - // ensure a unique name for the interface - SocketAddress address("test" + rtc::ToString(next_index_++), 0); - address.SetResolvedIP(iface.ipaddr()); - ifaces_.push_back(address); - DoUpdateNetworks(); - } - - void RemoveInterface(const SocketAddress& iface) { - for (IfaceList::iterator it = ifaces_.begin(); - it != ifaces_.end(); ++it) { - if (it->EqualIPs(iface)) { - ifaces_.erase(it); - break; - } - } - DoUpdateNetworks(); - } - - virtual void StartUpdating() { - if (started_) { - if (sent_first_update_) - SignalNetworksChanged(); - return; - } - - started_ = true; - sent_first_update_ = false; - thread_->Post(this); - } - - virtual void StopUpdating() { - started_ = false; - } - - // MessageHandler interface. - virtual void OnMessage(Message* msg) { - DoUpdateNetworks(); - } - - private: - void DoUpdateNetworks() { - if (!started_) - return; - std::vector networks; - for (IfaceList::iterator it = ifaces_.begin(); - it != ifaces_.end(); ++it) { - int prefix_length = 0; - if (it->ipaddr().family() == AF_INET) { - prefix_length = kFakeIPv4NetworkPrefixLength; - } else if (it->ipaddr().family() == AF_INET6) { - prefix_length = kFakeIPv6NetworkPrefixLength; - } - IPAddress prefix = TruncateIP(it->ipaddr(), prefix_length); - scoped_ptr net(new Network(it->hostname(), - it->hostname(), - prefix, - prefix_length)); - net->AddIP(it->ipaddr()); - networks.push_back(net.release()); - } - bool changed; - MergeNetworkList(networks, &changed); - if (changed || !sent_first_update_) { - SignalNetworksChanged(); - sent_first_update_ = true; - } - } - - Thread* thread_; - IfaceList ifaces_; - int next_index_; - bool started_; - bool sent_first_update_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_FAKENETWORK_H_ diff --git a/webrtc/base/fakesslidentity.h b/webrtc/base/fakesslidentity.h deleted file mode 100644 index 717cb6c3b..000000000 --- a/webrtc/base/fakesslidentity.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_FAKESSLIDENTITY_H_ -#define WEBRTC_BASE_FAKESSLIDENTITY_H_ - -#include -#include - -#include "webrtc/base/messagedigest.h" -#include "webrtc/base/sslidentity.h" - -namespace rtc { - -class FakeSSLCertificate : public rtc::SSLCertificate { - public: - // 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& certs) - : data_(certs.front()), digest_algorithm_(DIGEST_SHA_1) { - std::vector::const_iterator it; - // Skip certs[0]. - for (it = certs.begin() + 1; it != certs.end(); ++it) { - certs_.push_back(FakeSSLCertificate(*it)); - } - } - virtual FakeSSLCertificate* GetReference() const { - return new FakeSSLCertificate(*this); - } - virtual std::string ToPEMString() const { - return data_; - } - virtual void ToDER(Buffer* der_buffer) const { - std::string der_string; - 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 { - *algorithm = digest_algorithm_; - return true; - } - virtual bool ComputeDigest(const std::string& algorithm, - unsigned char* digest, - size_t size, - size_t* length) const { - *length = rtc::ComputeDigest(algorithm, data_.c_str(), data_.size(), - digest, size); - return (*length != 0); - } - virtual bool GetChain(SSLCertChain** chain) const { - if (certs_.empty()) - return false; - std::vector new_certs(certs_.size()); - std::transform(certs_.begin(), certs_.end(), new_certs.begin(), DupCert); - *chain = new SSLCertChain(new_certs); - return true; - } - - private: - static FakeSSLCertificate* DupCert(FakeSSLCertificate cert) { - return cert.GetReference(); - } - std::string data_; - std::vector certs_; - std::string digest_algorithm_; -}; - -class FakeSSLIdentity : public rtc::SSLIdentity { - public: - explicit FakeSSLIdentity(const std::string& data) : cert_(data) {} - explicit FakeSSLIdentity(const FakeSSLCertificate& cert) : cert_(cert) {} - virtual FakeSSLIdentity* GetReference() const { - return new FakeSSLIdentity(*this); - } - virtual const FakeSSLCertificate& certificate() const { return cert_; } - private: - FakeSSLCertificate cert_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_FAKESSLIDENTITY_H_ diff --git a/webrtc/base/faketaskrunner.h b/webrtc/base/faketaskrunner.h deleted file mode 100644 index 5408ab8b2..000000000 --- a/webrtc/base/faketaskrunner.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// A fake TaskRunner for use in unit tests. - -#ifndef WEBRTC_BASE_FAKETASKRUNNER_H_ -#define WEBRTC_BASE_FAKETASKRUNNER_H_ - -#include "webrtc/base/taskparent.h" -#include "webrtc/base/taskrunner.h" - -namespace rtc { - -class FakeTaskRunner : public TaskRunner { - public: - FakeTaskRunner() : current_time_(0) {} - virtual ~FakeTaskRunner() {} - - virtual void WakeTasks() { RunTasks(); } - - virtual int64 CurrentTime() { - // Implement if needed. - return current_time_++; - } - - int64 current_time_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_FAKETASKRUNNER_H_ diff --git a/webrtc/base/filelock.cc b/webrtc/base/filelock.cc deleted file mode 100644 index fc921febc..000000000 --- a/webrtc/base/filelock.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/filelock.h" - -#include "webrtc/base/fileutils.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -FileLock::FileLock(const std::string& path, FileStream* file) - : path_(path), file_(file) { -} - -FileLock::~FileLock() { - MaybeUnlock(); -} - -void FileLock::Unlock() { - LOG_F(LS_INFO); - MaybeUnlock(); -} - -void FileLock::MaybeUnlock() { - if (file_) { - LOG(LS_INFO) << "Unlocking:" << path_; - file_->Close(); - Filesystem::DeleteFile(path_); - file_.reset(); - } -} - -FileLock* FileLock::TryLock(const std::string& path) { - FileStream* stream = new FileStream(); - bool ok = false; -#if defined(WEBRTC_WIN) - // Open and lock in a single operation. - ok = stream->OpenShare(path, "a", _SH_DENYRW, NULL); -#else // WEBRTC_LINUX && !WEBRTC_ANDROID and WEBRTC_MAC && !defined(WEBRTC_IOS) - ok = stream->Open(path, "a", NULL) && stream->TryLock(); -#endif - if (ok) { - return new FileLock(path, stream); - } else { - // Something failed, either we didn't succeed to open the - // file or we failed to lock it. Anyway remove the heap - // allocated object and then return NULL to indicate failure. - delete stream; - return NULL; - } -} - -} // namespace rtc diff --git a/webrtc/base/filelock.h b/webrtc/base/filelock.h deleted file mode 100644 index 46c58ea4a..000000000 --- a/webrtc/base/filelock.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_FILELOCK_H_ -#define WEBRTC_BASE_FILELOCK_H_ - -#include - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/scoped_ptr.h" - -namespace rtc { - -class FileStream; - -// Implements a very simple cross process lock based on a file. -// When Lock(...) is called we try to open/create the file in read/write -// mode without any sharing. (Or locking it with flock(...) on Unix) -// If the process crash the OS will make sure that the file descriptor -// is released and another process can accuire the lock. -// This doesn't work on ancient OSX/Linux versions if used on NFS. -// (Nfs-client before: ~2.6 and Linux Kernel < 2.6.) -class FileLock { - public: - virtual ~FileLock(); - - // Attempts to lock the file. The caller owns the returned - // lock object. Returns NULL if the file already was locked. - static FileLock* TryLock(const std::string& path); - void Unlock(); - - protected: - FileLock(const std::string& path, FileStream* file); - - private: - void MaybeUnlock(); - - std::string path_; - scoped_ptr file_; - - DISALLOW_EVIL_CONSTRUCTORS(FileLock); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_FILELOCK_H_ diff --git a/webrtc/base/filelock_unittest.cc b/webrtc/base/filelock_unittest.cc deleted file mode 100644 index eecbf07da..000000000 --- a/webrtc/base/filelock_unittest.cc +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/event.h" -#include "webrtc/base/filelock.h" -#include "webrtc/base/fileutils.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -const static std::string kLockFile = "TestLockFile"; -const static int kTimeoutMS = 5000; - -class FileLockTest : public testing::Test, public Runnable { - public: - FileLockTest() : done_(false, false), thread_lock_failed_(false) { - } - - virtual void Run(Thread* t) { - scoped_ptr lock(FileLock::TryLock(temp_file_.pathname())); - // The lock is already owned by the main thread of - // this test, therefore the TryLock(...) call should fail. - thread_lock_failed_ = lock.get() == NULL; - done_.Set(); - } - - protected: - virtual void SetUp() { - thread_lock_failed_ = false; - Filesystem::GetAppTempFolder(&temp_dir_); - temp_file_ = Pathname(temp_dir_.pathname(), kLockFile); - } - - void LockOnThread() { - locker_.Start(this); - done_.Wait(kTimeoutMS); - } - - Event done_; - Thread locker_; - bool thread_lock_failed_; - Pathname temp_dir_; - Pathname temp_file_; -}; - -TEST_F(FileLockTest, TestLockFileDeleted) { - scoped_ptr lock(FileLock::TryLock(temp_file_.pathname())); - EXPECT_TRUE(lock.get() != NULL); - EXPECT_FALSE(Filesystem::IsAbsent(temp_file_.pathname())); - lock->Unlock(); - EXPECT_TRUE(Filesystem::IsAbsent(temp_file_.pathname())); -} - -TEST_F(FileLockTest, TestLock) { - scoped_ptr lock(FileLock::TryLock(temp_file_.pathname())); - EXPECT_TRUE(lock.get() != NULL); -} - -TEST_F(FileLockTest, TestLockX2) { - scoped_ptr lock1(FileLock::TryLock(temp_file_.pathname())); - EXPECT_TRUE(lock1.get() != NULL); - - scoped_ptr lock2(FileLock::TryLock(temp_file_.pathname())); - EXPECT_TRUE(lock2.get() == NULL); -} - -TEST_F(FileLockTest, TestThreadedLock) { - scoped_ptr lock(FileLock::TryLock(temp_file_.pathname())); - EXPECT_TRUE(lock.get() != NULL); - - LockOnThread(); - EXPECT_TRUE(thread_lock_failed_); -} - -} // namespace rtc diff --git a/webrtc/base/fileutils.cc b/webrtc/base/fileutils.cc deleted file mode 100644 index 60bd0f8f4..000000000 --- a/webrtc/base/fileutils.cc +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#if defined(WEBRTC_WIN) -// TODO(grunell): Remove io.h includes when Chromium has started -// to use AEC in each source. http://crbug.com/264611. -#include -#include "webrtc/base/win32.h" -#endif - -#include "webrtc/base/pathutils.h" -#include "webrtc/base/fileutils.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/stream.h" - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32filesystem.h" -#else -#include "webrtc/base/unixfilesystem.h" -#endif - -#if !defined(WEBRTC_WIN) -#define MAX_PATH 260 -#endif - -namespace rtc { - -////////////////////////// -// Directory Iterator // -////////////////////////// - -// A DirectoryIterator is created with a given directory. It originally points -// to the first file in the directory, and can be advanecd with Next(). This -// allows you to get information about each file. - - // Constructor -DirectoryIterator::DirectoryIterator() -#ifdef WEBRTC_WIN - : handle_(INVALID_HANDLE_VALUE) { -#else - : dir_(NULL), dirent_(NULL) { -#endif -} - - // Destructor -DirectoryIterator::~DirectoryIterator() { -#if defined(WEBRTC_WIN) - if (handle_ != INVALID_HANDLE_VALUE) - ::FindClose(handle_); -#else - if (dir_) - closedir(dir_); -#endif -} - - // Starts traversing a directory. - // dir is the directory to traverse - // returns true if the directory exists and is valid -bool DirectoryIterator::Iterate(const Pathname &dir) { - directory_ = dir.pathname(); -#if defined(WEBRTC_WIN) - if (handle_ != INVALID_HANDLE_VALUE) - ::FindClose(handle_); - std::string d = dir.pathname() + '*'; - handle_ = ::FindFirstFile(ToUtf16(d).c_str(), &data_); - if (handle_ == INVALID_HANDLE_VALUE) - return false; -#else - if (dir_ != NULL) - closedir(dir_); - dir_ = ::opendir(directory_.c_str()); - if (dir_ == NULL) - return false; - dirent_ = readdir(dir_); - if (dirent_ == NULL) - return false; - - if (::stat(std::string(directory_ + Name()).c_str(), &stat_) != 0) - return false; -#endif - return true; -} - - // Advances to the next file - // returns true if there were more files in the directory. -bool DirectoryIterator::Next() { -#if defined(WEBRTC_WIN) - return ::FindNextFile(handle_, &data_) == TRUE; -#else - dirent_ = ::readdir(dir_); - if (dirent_ == NULL) - return false; - - return ::stat(std::string(directory_ + Name()).c_str(), &stat_) == 0; -#endif -} - - // returns true if the file currently pointed to is a directory -bool DirectoryIterator::IsDirectory() const { -#if defined(WEBRTC_WIN) - return (data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FALSE; -#else - return S_ISDIR(stat_.st_mode); -#endif -} - - // returns the name of the file currently pointed to -std::string DirectoryIterator::Name() const { -#if defined(WEBRTC_WIN) - return ToUtf8(data_.cFileName); -#else - assert(dirent_ != NULL); - return dirent_->d_name; -#endif -} - - // returns the size of the file currently pointed to -size_t DirectoryIterator::FileSize() const { -#if !defined(WEBRTC_WIN) - return stat_.st_size; -#else - return data_.nFileSizeLow; -#endif -} - - // returns the last modified time of this file -time_t DirectoryIterator::FileModifyTime() const { -#if defined(WEBRTC_WIN) - time_t val; - FileTimeToUnixTime(data_.ftLastWriteTime, &val); - return val; -#else - return stat_.st_mtime; -#endif -} - -FilesystemInterface* Filesystem::default_filesystem_ = NULL; - -FilesystemInterface *Filesystem::EnsureDefaultFilesystem() { - if (!default_filesystem_) { -#if defined(WEBRTC_WIN) - default_filesystem_ = new Win32Filesystem(); -#else - default_filesystem_ = new UnixFilesystem(); -#endif - } - return default_filesystem_; -} - -bool FilesystemInterface::CopyFolder(const Pathname &old_path, - const Pathname &new_path) { - bool success = true; - VERIFY(IsFolder(old_path)); - Pathname new_dir; - new_dir.SetFolder(new_path.pathname()); - Pathname old_dir; - old_dir.SetFolder(old_path.pathname()); - if (!CreateFolder(new_dir)) - return false; - DirectoryIterator *di = IterateDirectory(); - if (!di) - return false; - if (di->Iterate(old_dir.pathname())) { - do { - if (di->Name() == "." || di->Name() == "..") - continue; - Pathname source; - Pathname dest; - source.SetFolder(old_dir.pathname()); - dest.SetFolder(new_path.pathname()); - source.SetFilename(di->Name()); - dest.SetFilename(di->Name()); - if (!CopyFileOrFolder(source, dest)) - success = false; - } while (di->Next()); - } - delete di; - return success; -} - -bool FilesystemInterface::DeleteFolderContents(const Pathname &folder) { - bool success = true; - VERIFY(IsFolder(folder)); - DirectoryIterator *di = IterateDirectory(); - if (!di) - return false; - if (di->Iterate(folder)) { - do { - if (di->Name() == "." || di->Name() == "..") - continue; - Pathname subdir; - subdir.SetFolder(folder.pathname()); - if (di->IsDirectory()) { - subdir.AppendFolder(di->Name()); - if (!DeleteFolderAndContents(subdir)) { - success = false; - } - } else { - subdir.SetFilename(di->Name()); - if (!DeleteFile(subdir)) { - success = false; - } - } - } while (di->Next()); - } - delete di; - return success; -} - -bool FilesystemInterface::CleanAppTempFolder() { - Pathname path; - if (!GetAppTempFolder(&path)) - return false; - if (IsAbsent(path)) - return true; - if (!IsTemporaryPath(path)) { - ASSERT(false); - return false; - } - return DeleteFolderContents(path); -} - -Pathname Filesystem::GetCurrentDirectory() { - return EnsureDefaultFilesystem()->GetCurrentDirectory(); -} - -bool CreateUniqueFile(Pathname& path, bool create_empty) { - LOG(LS_INFO) << "Path " << path.pathname() << std::endl; - // If no folder is supplied, use the temporary folder - if (path.folder().empty()) { - Pathname temporary_path; - if (!Filesystem::GetTemporaryFolder(temporary_path, true, NULL)) { - printf("Get temp failed\n"); - return false; - } - path.SetFolder(temporary_path.pathname()); - } - - // If no filename is supplied, use a temporary name - if (path.filename().empty()) { - std::string folder(path.folder()); - std::string filename = Filesystem::TempFilename(folder, "gt"); - path.SetPathname(filename); - if (!create_empty) { - Filesystem::DeleteFile(path.pathname()); - } - return true; - } - - // Otherwise, create a unique name based on the given filename - // foo.txt -> foo-N.txt - const std::string basename = path.basename(); - const size_t MAX_VERSION = 100; - size_t version = 0; - while (version < MAX_VERSION) { - std::string pathname = path.pathname(); - - if (!Filesystem::IsFile(pathname)) { - if (create_empty) { - FileStream* fs = Filesystem::OpenFile(pathname, "w"); - delete fs; - } - return true; - } - version += 1; - char version_base[MAX_PATH]; - sprintfn(version_base, ARRAY_SIZE(version_base), "%s-%u", - basename.c_str(), version); - path.SetBasename(version_base); - } - 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(WEBRTC_WIN) - if (file == kInvalidPlatformFileValue) - return NULL; - int fd = _open_osfhandle(reinterpret_cast(file), 0); - if (fd < 0) - return NULL; - return _fdopen(fd, "w"); -#else - return fdopen(file, "w"); -#endif -} - -bool ClosePlatformFile(PlatformFile file) { -#if defined(WEBRTC_WIN) - return CloseHandle(file) != 0; -#else - return close(file); -#endif -} - -} // namespace rtc diff --git a/webrtc/base/fileutils.h b/webrtc/base/fileutils.h deleted file mode 100644 index c0a3f88c6..000000000 --- a/webrtc/base/fileutils.h +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_FILEUTILS_H_ -#define WEBRTC_BASE_FILEUTILS_H_ - -#include - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#else -#include -#include -#include -#include -#include -#endif - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/common.h" -#include "webrtc/base/scoped_ptr.h" - -namespace rtc { - -class FileStream; -class Pathname; - -////////////////////////// -// Directory Iterator // -////////////////////////// - -// A DirectoryIterator is created with a given directory. It originally points -// to the first file in the directory, and can be advanecd with Next(). This -// allows you to get information about each file. - -class DirectoryIterator { - friend class Filesystem; - public: - // Constructor - DirectoryIterator(); - // Destructor - virtual ~DirectoryIterator(); - - // Starts traversing a directory - // dir is the directory to traverse - // returns true if the directory exists and is valid - // The iterator will point to the first entry in the directory - virtual bool Iterate(const Pathname &path); - - // Advances to the next file - // returns true if there were more files in the directory. - virtual bool Next(); - - // returns true if the file currently pointed to is a directory - virtual bool IsDirectory() const; - - // returns the name of the file currently pointed to - virtual std::string Name() const; - - // returns the size of the file currently pointed to - virtual size_t FileSize() const; - - // returns the last modified time of the file currently pointed to - virtual time_t FileModifyTime() const; - - // checks whether current file is a special directory file "." or ".." - bool IsDots() const { - std::string filename(Name()); - return (filename.compare(".") == 0) || (filename.compare("..") == 0); - } - - private: - std::string directory_; -#if defined(WEBRTC_WIN) - WIN32_FIND_DATA data_; - HANDLE handle_; -#else - DIR *dir_; - struct dirent *dirent_; - struct stat stat_; -#endif -}; - -enum FileTimeType { FTT_CREATED, FTT_MODIFIED, FTT_ACCESSED }; - -class FilesystemInterface { - public: - virtual ~FilesystemInterface() {} - - // Returns a DirectoryIterator for a given pathname. - // TODO: Do fancy abstracted stuff - virtual DirectoryIterator *IterateDirectory() { - return new DirectoryIterator(); - } - - // Opens a file. Returns an open StreamInterface if function succeeds. - // Otherwise, returns NULL. - // TODO: Add an error param to indicate failure reason, similar to - // FileStream::Open - virtual FileStream *OpenFile(const Pathname &filename, - const std::string &mode) = 0; - - // Atomically creates an empty file accessible only to the current user if one - // does not already exist at the given path, otherwise fails. This is the only - // secure way to create a file in a shared temp directory (e.g., C:\Temp on - // Windows or /tmp on Linux). - // Note that if it is essential that a file be successfully created then the - // app must generate random names and retry on failure, or else it will be - // vulnerable to a trivial DoS. - virtual bool CreatePrivateFile(const Pathname &filename) = 0; - - // This will attempt to delete the path located at filename. - // It ASSERTS and returns false if the path points to a folder or a - // non-existent file. - virtual bool DeleteFile(const Pathname &filename) = 0; - - // This will attempt to delete the empty folder located at 'folder' - // It ASSERTS and returns false if the path points to a file or a non-existent - // folder. It fails normally if the folder is not empty or can otherwise - // not be deleted. - virtual bool DeleteEmptyFolder(const Pathname &folder) = 0; - - // This will call IterateDirectory, to get a directory iterator, and then - // call DeleteFolderAndContents and DeleteFile on every path contained in this - // folder. If the folder is empty, this returns true. - virtual bool DeleteFolderContents(const Pathname &folder); - - // This deletes the contents of a folder, recursively, and then deletes - // the folder itself. - virtual bool DeleteFolderAndContents(const Pathname &folder) { - return DeleteFolderContents(folder) && DeleteEmptyFolder(folder); - } - - // This will delete whatever is located at path, be it a file or a folder. - // If it is a folder, it will delete it recursively by calling - // DeleteFolderAndContents - bool DeleteFileOrFolder(const Pathname &path) { - if (IsFolder(path)) - return DeleteFolderAndContents(path); - else - return DeleteFile(path); - } - - // Creates a directory. This will call itself recursively to create /foo/bar - // even if /foo does not exist. Returns true if the function succeeds. - virtual bool CreateFolder(const Pathname &pathname) = 0; - - // This moves a file from old_path to new_path, where "old_path" is a - // plain file. This ASSERTs and returns false if old_path points to a - // directory, and returns true if the function succeeds. - // If the new path is on a different volume than the old path, this function - // will attempt to copy and, if that succeeds, delete the old path. - virtual bool MoveFolder(const Pathname &old_path, - const Pathname &new_path) = 0; - - // This moves a directory from old_path to new_path, where "old_path" is a - // directory. This ASSERTs and returns false if old_path points to a plain - // file, and returns true if the function succeeds. - // If the new path is on a different volume, this function will attempt to - // copy and if that succeeds, delete the old path. - virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path) = 0; - - // This attempts to move whatever is located at old_path to new_path, - // be it a file or folder. - bool MoveFileOrFolder(const Pathname &old_path, const Pathname &new_path) { - if (IsFile(old_path)) { - return MoveFile(old_path, new_path); - } else { - return MoveFolder(old_path, new_path); - } - } - - // This copies a file from old_path to new_path. This method ASSERTs and - // returns false if old_path is a folder, and returns true if the copy - // succeeds. - virtual bool CopyFile(const Pathname &old_path, const Pathname &new_path) = 0; - - // This copies a folder from old_path to new_path. - bool CopyFolder(const Pathname &old_path, const Pathname &new_path); - - bool CopyFileOrFolder(const Pathname &old_path, const Pathname &new_path) { - if (IsFile(old_path)) - return CopyFile(old_path, new_path); - else - return CopyFolder(old_path, new_path); - } - - // Returns true if pathname refers to a directory - virtual bool IsFolder(const Pathname& pathname) = 0; - - // Returns true if pathname refers to a file - virtual bool IsFile(const Pathname& pathname) = 0; - - // Returns true if pathname refers to no filesystem object, every parent - // directory either exists, or is also absent. - virtual bool IsAbsent(const Pathname& pathname) = 0; - - // Returns true if pathname represents a temporary location on the system. - virtual bool IsTemporaryPath(const Pathname& pathname) = 0; - - // A folder appropriate for storing temporary files (Contents are - // automatically deleted when the program exits) - virtual bool GetTemporaryFolder(Pathname &path, bool create, - const std::string *append) = 0; - - virtual std::string TempFilename(const Pathname &dir, - const std::string &prefix) = 0; - - // Determines the size of the file indicated by path. - virtual bool GetFileSize(const Pathname& path, size_t* size) = 0; - - // Determines a timestamp associated with the file indicated by path. - virtual bool GetFileTime(const Pathname& path, FileTimeType which, - time_t* time) = 0; - - // Returns the path to the running application. - // Note: This is not guaranteed to work on all platforms. Be aware of the - // limitations before using it, and robustly handle failure. - virtual bool GetAppPathname(Pathname* path) = 0; - - // Get a folder that is unique to the current application, which is suitable - // for sharing data between executions of the app. If the per_user arg is - // true, the folder is also specific to the current user. - virtual bool GetAppDataFolder(Pathname* path, bool per_user) = 0; - - // Get a temporary folder that is unique to the current user and application. - // TODO: Re-evaluate the goals of this function. We probably just need any - // directory that won't collide with another existing directory, and which - // will be cleaned up when the program exits. - virtual bool GetAppTempFolder(Pathname* path) = 0; - - // Delete the contents of the folder returned by GetAppTempFolder - bool CleanAppTempFolder(); - - virtual bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes) = 0; - - // Returns the absolute path of the current directory. - virtual Pathname GetCurrentDirectory() = 0; - - // Note: These might go into some shared config section later, but they're - // used by some methods in this interface, so we're leaving them here for now. - void SetOrganizationName(const std::string& organization) { - organization_name_ = organization; - } - void GetOrganizationName(std::string* organization) { - ASSERT(NULL != organization); - *organization = organization_name_; - } - void SetApplicationName(const std::string& application) { - application_name_ = application; - } - void GetApplicationName(std::string* application) { - ASSERT(NULL != application); - *application = application_name_; - } - - protected: - std::string organization_name_; - std::string application_name_; -}; - -class Filesystem { - public: - static FilesystemInterface *default_filesystem() { - ASSERT(default_filesystem_ != NULL); - return default_filesystem_; - } - - static void set_default_filesystem(FilesystemInterface *filesystem) { - default_filesystem_ = filesystem; - } - - static FilesystemInterface *swap_default_filesystem( - FilesystemInterface *filesystem) { - FilesystemInterface *cur = default_filesystem_; - default_filesystem_ = filesystem; - return cur; - } - - static DirectoryIterator *IterateDirectory() { - return EnsureDefaultFilesystem()->IterateDirectory(); - } - - static bool CreateFolder(const Pathname &pathname) { - return EnsureDefaultFilesystem()->CreateFolder(pathname); - } - - static FileStream *OpenFile(const Pathname &filename, - const std::string &mode) { - return EnsureDefaultFilesystem()->OpenFile(filename, mode); - } - - static bool CreatePrivateFile(const Pathname &filename) { - return EnsureDefaultFilesystem()->CreatePrivateFile(filename); - } - - static bool DeleteFile(const Pathname &filename) { - return EnsureDefaultFilesystem()->DeleteFile(filename); - } - - static bool DeleteEmptyFolder(const Pathname &folder) { - return EnsureDefaultFilesystem()->DeleteEmptyFolder(folder); - } - - static bool DeleteFolderContents(const Pathname &folder) { - return EnsureDefaultFilesystem()->DeleteFolderContents(folder); - } - - static bool DeleteFolderAndContents(const Pathname &folder) { - return EnsureDefaultFilesystem()->DeleteFolderAndContents(folder); - } - - static bool MoveFolder(const Pathname &old_path, const Pathname &new_path) { - return EnsureDefaultFilesystem()->MoveFolder(old_path, new_path); - } - - static bool MoveFile(const Pathname &old_path, const Pathname &new_path) { - return EnsureDefaultFilesystem()->MoveFile(old_path, new_path); - } - - static bool CopyFolder(const Pathname &old_path, const Pathname &new_path) { - return EnsureDefaultFilesystem()->CopyFolder(old_path, new_path); - } - - static bool CopyFile(const Pathname &old_path, const Pathname &new_path) { - return EnsureDefaultFilesystem()->CopyFile(old_path, new_path); - } - - static bool IsFolder(const Pathname& pathname) { - return EnsureDefaultFilesystem()->IsFolder(pathname); - } - - static bool IsFile(const Pathname &pathname) { - return EnsureDefaultFilesystem()->IsFile(pathname); - } - - static bool IsAbsent(const Pathname &pathname) { - return EnsureDefaultFilesystem()->IsAbsent(pathname); - } - - static bool IsTemporaryPath(const Pathname& pathname) { - return EnsureDefaultFilesystem()->IsTemporaryPath(pathname); - } - - static bool GetTemporaryFolder(Pathname &path, bool create, - const std::string *append) { - return EnsureDefaultFilesystem()->GetTemporaryFolder(path, create, append); - } - - static std::string TempFilename(const Pathname &dir, - const std::string &prefix) { - return EnsureDefaultFilesystem()->TempFilename(dir, prefix); - } - - static bool GetFileSize(const Pathname& path, size_t* size) { - return EnsureDefaultFilesystem()->GetFileSize(path, size); - } - - static bool GetFileTime(const Pathname& path, FileTimeType which, - time_t* time) { - return EnsureDefaultFilesystem()->GetFileTime(path, which, time); - } - - static bool GetAppPathname(Pathname* path) { - return EnsureDefaultFilesystem()->GetAppPathname(path); - } - - static bool GetAppDataFolder(Pathname* path, bool per_user) { - return EnsureDefaultFilesystem()->GetAppDataFolder(path, per_user); - } - - static bool GetAppTempFolder(Pathname* path) { - return EnsureDefaultFilesystem()->GetAppTempFolder(path); - } - - static bool CleanAppTempFolder() { - return EnsureDefaultFilesystem()->CleanAppTempFolder(); - } - - static bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes) { - return EnsureDefaultFilesystem()->GetDiskFreeSpace(path, freebytes); - } - - // Definition has to be in the .cc file due to returning forward-declared - // Pathname by value. - static Pathname GetCurrentDirectory(); - - static void SetOrganizationName(const std::string& organization) { - EnsureDefaultFilesystem()->SetOrganizationName(organization); - } - - static void GetOrganizationName(std::string* organization) { - EnsureDefaultFilesystem()->GetOrganizationName(organization); - } - - static void SetApplicationName(const std::string& application) { - EnsureDefaultFilesystem()->SetApplicationName(application); - } - - static void GetApplicationName(std::string* application) { - EnsureDefaultFilesystem()->GetApplicationName(application); - } - - private: - static FilesystemInterface* default_filesystem_; - - static FilesystemInterface *EnsureDefaultFilesystem(); - DISALLOW_IMPLICIT_CONSTRUCTORS(Filesystem); -}; - -class FilesystemScope{ - public: - explicit FilesystemScope(FilesystemInterface *new_fs) { - old_fs_ = Filesystem::swap_default_filesystem(new_fs); - } - ~FilesystemScope() { - Filesystem::set_default_filesystem(old_fs_); - } - private: - FilesystemInterface* old_fs_; - DISALLOW_IMPLICIT_CONSTRUCTORS(FilesystemScope); -}; - -// Generates a unique filename based on the input path. If no path component -// is specified, it uses the temporary directory. If a filename is provided, -// up to 100 variations of form basename-N.extension are tried. When -// create_empty is true, an empty file of this name is created (which -// decreases the chance of a temporary filename collision with another -// 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(WEBRTC_WIN) -typedef HANDLE PlatformFile; -const PlatformFile kInvalidPlatformFileValue = INVALID_HANDLE_VALUE; -#elif defined(WEBRTC_POSIX) -typedef int PlatformFile; -const PlatformFile kInvalidPlatformFileValue = -1; -#else -#error Unsupported platform -#endif - -FILE* FdopenPlatformFileForWriting(PlatformFile file); -bool ClosePlatformFile(PlatformFile file); - -} // namespace rtc - -#endif // WEBRTC_BASE_FILEUTILS_H_ diff --git a/webrtc/base/fileutils_mock.h b/webrtc/base/fileutils_mock.h deleted file mode 100644 index e9d20a75f..000000000 --- a/webrtc/base/fileutils_mock.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_FILEUTILS_MOCK_H_ -#define WEBRTC_BASE_FILEUTILS_MOCK_H_ - -#include -#include -#include - -#include "webrtc/base/fileutils.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -class FakeFileStream : public FileStream { - public: - explicit FakeFileStream(const std::string & contents) : - string_stream_(contents) - {} - - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - return string_stream_.Read(buffer, buffer_len, read, error); - } - - virtual void Close() { - return string_stream_.Close(); - } - virtual bool GetSize(size_t* size) const { - return string_stream_.GetSize(size); - } - - private: - StringStream string_stream_; -}; - -class FakeDirectoryIterator : public DirectoryIterator { - public: - typedef std::pair File; - - /* - * files should be sorted by directory - * put '/' at the end of file if you want it to be a directory - * - * Sample list: - * /var/dir/file1 - * /var/dir/file2 - * /var/dir/subdir1/ - * /var/dir/subdir2/ - * /var/dir2/file2 - * /var/dir3/ - * - * you can call Iterate for any path: /var, /var/dir, /var/dir2 - * unrelated files will be ignored - */ - explicit FakeDirectoryIterator(const std::vector& all_files) : - all_files_(all_files) {} - - virtual bool Iterate(const Pathname& path) { - path_iterator_ = all_files_.begin(); - path_ = path.pathname(); - - // make sure path ends end with '/' - if (path_.rfind(Pathname::DefaultFolderDelimiter()) != path_.size() - 1) - path_ += Pathname::DefaultFolderDelimiter(); - - return FakeDirectoryIterator::Search(std::string("")); - } - - virtual bool Next() { - std::string current_name = Name(); - path_iterator_++; - return FakeDirectoryIterator::Search(current_name); - } - - bool Search(const std::string& current_name) { - for (; path_iterator_ != all_files_.end(); path_iterator_++) { - if (path_iterator_->first.find(path_) == 0 - && Name().compare(current_name) != 0) { - return true; - } - } - - return false; - } - - virtual bool IsDirectory() const { - std::string sub_path = path_iterator_->first; - - return std::string::npos != - sub_path.find(Pathname::DefaultFolderDelimiter(), path_.size()); - } - - virtual std::string Name() const { - std::string sub_path = path_iterator_->first; - - // path - top level path (ex. /var/lib) - // sub_path - subpath under top level path (ex. /var/lib/dir/dir/file ) - // find shortest non-trivial common path. (ex. /var/lib/dir) - size_t start = path_.size(); - size_t end = sub_path.find(Pathname::DefaultFolderDelimiter(), start); - - if (end != std::string::npos) { - return sub_path.substr(start, end - start); - } else { - return sub_path.substr(start); - } - } - - private: - const std::vector all_files_; - - std::string path_; - std::vector::const_iterator path_iterator_; -}; - -class FakeFileSystem : public FilesystemInterface { - public: - typedef std::pair File; - - explicit FakeFileSystem(const std::vector& all_files) : - all_files_(all_files) {} - - virtual DirectoryIterator *IterateDirectory() { - return new FakeDirectoryIterator(all_files_); - } - - virtual FileStream * OpenFile( - const Pathname &filename, - const std::string &mode) { - std::vector::const_iterator i_files = all_files_.begin(); - std::string path = filename.pathname(); - - for (; i_files != all_files_.end(); i_files++) { - if (i_files->first.compare(path) == 0) { - return new FakeFileStream(i_files->second); - } - } - - return NULL; - } - - bool CreatePrivateFile(const Pathname &filename) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool DeleteFile(const Pathname &filename) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool DeleteEmptyFolder(const Pathname &folder) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool DeleteFolderContents(const Pathname &folder) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool DeleteFolderAndContents(const Pathname &folder) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool CreateFolder(const Pathname &pathname) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool MoveFolder(const Pathname &old_path, const Pathname &new_path) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool MoveFile(const Pathname &old_path, const Pathname &new_path) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool CopyFile(const Pathname &old_path, const Pathname &new_path) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool IsFolder(const Pathname &pathname) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool IsFile(const Pathname &pathname) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool IsAbsent(const Pathname &pathname) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool IsTemporaryPath(const Pathname &pathname) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool GetTemporaryFolder(Pathname &path, bool create, - const std::string *append) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - std::string TempFilename(const Pathname &dir, const std::string &prefix) { - EXPECT_TRUE(false) << "Unsupported operation"; - return std::string(); - } - bool GetFileSize(const Pathname &path, size_t *size) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool GetFileTime(const Pathname &path, FileTimeType which, - time_t* time) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool GetAppPathname(Pathname *path) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool GetAppDataFolder(Pathname *path, bool per_user) { - EXPECT_TRUE(per_user) << "Unsupported operation"; -#if defined(WEBRTC_WIN) - path->SetPathname("c:\\Users\\test_user", ""); -#else - path->SetPathname("/home/user/test_user", ""); -#endif - return true; - } - bool GetAppTempFolder(Pathname *path) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - bool GetDiskFreeSpace(const Pathname &path, int64 *freebytes) { - EXPECT_TRUE(false) << "Unsupported operation"; - return false; - } - Pathname GetCurrentDirectory() { - return Pathname(); - } - - private: - const std::vector all_files_; -}; -} // namespace rtc - -#endif // WEBRTC_BASE_FILEUTILS_MOCK_H_ diff --git a/webrtc/base/fileutils_unittest.cc b/webrtc/base/fileutils_unittest.cc deleted file mode 100644 index 9076bc787..000000000 --- a/webrtc/base/fileutils_unittest.cc +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/fileutils.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -// Make sure we can get a temp folder for the later tests. -TEST(FilesystemTest, GetTemporaryFolder) { - Pathname path; - EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL)); -} - -// Test creating a temp file, reading it back in, and deleting it. -TEST(FilesystemTest, TestOpenFile) { - Pathname path; - EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL)); - path.SetPathname(Filesystem::TempFilename(path, "ut")); - - FileStream* fs; - char buf[256]; - size_t bytes; - - fs = Filesystem::OpenFile(path, "wb"); - ASSERT_TRUE(fs != NULL); - EXPECT_EQ(SR_SUCCESS, fs->Write("test", 4, &bytes, NULL)); - EXPECT_EQ(4U, bytes); - delete fs; - - EXPECT_TRUE(Filesystem::IsFile(path)); - - fs = Filesystem::OpenFile(path, "rb"); - ASSERT_TRUE(fs != NULL); - EXPECT_EQ(SR_SUCCESS, fs->Read(buf, sizeof(buf), &bytes, NULL)); - EXPECT_EQ(4U, bytes); - delete fs; - - EXPECT_TRUE(Filesystem::DeleteFile(path)); - EXPECT_FALSE(Filesystem::IsFile(path)); -} - -// Test opening a non-existent file. -TEST(FilesystemTest, TestOpenBadFile) { - Pathname path; - EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL)); - path.SetFilename("not an actual file"); - - EXPECT_FALSE(Filesystem::IsFile(path)); - - FileStream* fs = Filesystem::OpenFile(path, "rb"); - EXPECT_FALSE(fs != NULL); -} - -// Test that CreatePrivateFile fails for existing files and succeeds for -// non-existent ones. -TEST(FilesystemTest, TestCreatePrivateFile) { - Pathname path; - EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL)); - path.SetFilename("private_file_test"); - - // First call should succeed because the file doesn't exist yet. - EXPECT_TRUE(Filesystem::CreatePrivateFile(path)); - // Next call should fail, because now it exists. - EXPECT_FALSE(Filesystem::CreatePrivateFile(path)); - - // Verify that we have permission to open the file for reading and writing. - scoped_ptr fs(Filesystem::OpenFile(path, "wb")); - EXPECT_TRUE(fs.get() != NULL); - // Have to close the file on Windows before it will let us delete it. - fs.reset(); - - // Verify that we have permission to delete the file. - EXPECT_TRUE(Filesystem::DeleteFile(path)); -} - -// Test checking for free disk space. -TEST(FilesystemTest, TestGetDiskFreeSpace) { - // Note that we should avoid picking any file/folder which could be located - // at the remotely mounted drive/device. - Pathname path; - ASSERT_TRUE(Filesystem::GetAppDataFolder(&path, true)); - - int64 free1 = 0; - EXPECT_TRUE(Filesystem::IsFolder(path)); - EXPECT_FALSE(Filesystem::IsFile(path)); - EXPECT_TRUE(Filesystem::GetDiskFreeSpace(path, &free1)); - EXPECT_GT(free1, 0); - - int64 free2 = 0; - path.AppendFolder("this_folder_doesnt_exist"); - EXPECT_FALSE(Filesystem::IsFolder(path)); - EXPECT_TRUE(Filesystem::IsAbsent(path)); - EXPECT_TRUE(Filesystem::GetDiskFreeSpace(path, &free2)); - // These should be the same disk, and disk free space should not have changed - // by more than 1% between the two calls. - EXPECT_LT(static_cast(free1 * .9), free2); - EXPECT_LT(free2, static_cast(free1 * 1.1)); - - int64 free3 = 0; - path.clear(); - EXPECT_TRUE(path.empty()); - EXPECT_TRUE(Filesystem::GetDiskFreeSpace(path, &free3)); - // Current working directory may not be where exe is. - // EXPECT_LT(static_cast(free1 * .9), free3); - // EXPECT_LT(free3, static_cast(free1 * 1.1)); - EXPECT_GT(free3, 0); -} - -// Tests that GetCurrentDirectory() returns something. -TEST(FilesystemTest, TestGetCurrentDirectory) { - EXPECT_FALSE(Filesystem::GetCurrentDirectory().empty()); -} - -// Tests that GetAppPathname returns something. -TEST(FilesystemTest, TestGetAppPathname) { - Pathname path; - EXPECT_TRUE(Filesystem::GetAppPathname(&path)); - EXPECT_FALSE(path.empty()); -} - -} // namespace rtc diff --git a/webrtc/base/firewallsocketserver.cc b/webrtc/base/firewallsocketserver.cc deleted file mode 100644 index 31c18d981..000000000 --- a/webrtc/base/firewallsocketserver.cc +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/firewallsocketserver.h" - -#include - -#include - -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -class FirewallSocket : public AsyncSocketAdapter { - public: - FirewallSocket(FirewallSocketServer* server, AsyncSocket* socket, int type) - : AsyncSocketAdapter(socket), server_(server), type_(type) { - } - - virtual int Connect(const SocketAddress& addr) { - if (type_ == SOCK_STREAM) { - if (!server_->Check(FP_TCP, GetLocalAddress(), addr)) { - LOG(LS_VERBOSE) << "FirewallSocket outbound TCP connection from " - << GetLocalAddress().ToSensitiveString() << " to " - << addr.ToSensitiveString() << " denied"; - // TODO: Handle this asynchronously. - SetError(EHOSTUNREACH); - return SOCKET_ERROR; - } - } - return AsyncSocketAdapter::Connect(addr); - } - virtual int Send(const void* pv, size_t cb) { - return SendTo(pv, cb, GetRemoteAddress()); - } - virtual int SendTo(const void* pv, size_t cb, const SocketAddress& addr) { - if (type_ == SOCK_DGRAM) { - if (!server_->Check(FP_UDP, GetLocalAddress(), addr)) { - LOG(LS_VERBOSE) << "FirewallSocket outbound UDP packet from " - << GetLocalAddress().ToSensitiveString() << " to " - << addr.ToSensitiveString() << " dropped"; - return static_cast(cb); - } - } - return AsyncSocketAdapter::SendTo(pv, cb, addr); - } - virtual int Recv(void* pv, size_t cb) { - SocketAddress addr; - return RecvFrom(pv, cb, &addr); - } - virtual int RecvFrom(void* pv, size_t cb, SocketAddress* paddr) { - if (type_ == SOCK_DGRAM) { - while (true) { - int res = AsyncSocketAdapter::RecvFrom(pv, cb, paddr); - if (res <= 0) - return res; - if (server_->Check(FP_UDP, *paddr, GetLocalAddress())) - return res; - LOG(LS_VERBOSE) << "FirewallSocket inbound UDP packet from " - << paddr->ToSensitiveString() << " to " - << GetLocalAddress().ToSensitiveString() << " dropped"; - } - } - return AsyncSocketAdapter::RecvFrom(pv, cb, paddr); - } - - virtual int Listen(int backlog) { - if (!server_->tcp_listen_enabled()) { - LOG(LS_VERBOSE) << "FirewallSocket listen attempt denied"; - return -1; - } - - return AsyncSocketAdapter::Listen(backlog); - } - virtual AsyncSocket* Accept(SocketAddress* paddr) { - SocketAddress addr; - while (AsyncSocket* sock = AsyncSocketAdapter::Accept(&addr)) { - if (server_->Check(FP_TCP, addr, GetLocalAddress())) { - if (paddr) - *paddr = addr; - return sock; - } - sock->Close(); - delete sock; - LOG(LS_VERBOSE) << "FirewallSocket inbound TCP connection from " - << addr.ToSensitiveString() << " to " - << GetLocalAddress().ToSensitiveString() << " denied"; - } - return 0; - } - - private: - FirewallSocketServer* server_; - int type_; -}; - -FirewallSocketServer::FirewallSocketServer(SocketServer* server, - FirewallManager* manager, - bool should_delete_server) - : server_(server), manager_(manager), - should_delete_server_(should_delete_server), - udp_sockets_enabled_(true), tcp_sockets_enabled_(true), - tcp_listen_enabled_(true) { - if (manager_) - manager_->AddServer(this); -} - -FirewallSocketServer::~FirewallSocketServer() { - if (manager_) - manager_->RemoveServer(this); - - if (server_ && should_delete_server_) { - delete server_; - server_ = NULL; - } -} - -void FirewallSocketServer::AddRule(bool allow, FirewallProtocol p, - FirewallDirection d, - const SocketAddress& addr) { - SocketAddress src, dst; - if (d == FD_IN) { - dst = addr; - } else { - src = addr; - } - AddRule(allow, p, src, dst); -} - - -void FirewallSocketServer::AddRule(bool allow, FirewallProtocol p, - const SocketAddress& src, - const SocketAddress& dst) { - Rule r; - r.allow = allow; - r.p = p; - r.src = src; - r.dst = dst; - CritScope scope(&crit_); - rules_.push_back(r); -} - -void FirewallSocketServer::ClearRules() { - CritScope scope(&crit_); - rules_.clear(); -} - -bool FirewallSocketServer::Check(FirewallProtocol p, - const SocketAddress& src, - const SocketAddress& dst) { - CritScope scope(&crit_); - for (size_t i = 0; i < rules_.size(); ++i) { - const Rule& r = rules_[i]; - if ((r.p != p) && (r.p != FP_ANY)) - continue; - if ((r.src.ipaddr() != src.ipaddr()) && !r.src.IsNil()) - continue; - if ((r.src.port() != src.port()) && (r.src.port() != 0)) - continue; - if ((r.dst.ipaddr() != dst.ipaddr()) && !r.dst.IsNil()) - continue; - if ((r.dst.port() != dst.port()) && (r.dst.port() != 0)) - continue; - return r.allow; - } - return true; -} - -Socket* FirewallSocketServer::CreateSocket(int type) { - return CreateSocket(AF_INET, type); -} - -Socket* FirewallSocketServer::CreateSocket(int family, int type) { - return WrapSocket(server_->CreateAsyncSocket(family, type), type); -} - -AsyncSocket* FirewallSocketServer::CreateAsyncSocket(int type) { - return CreateAsyncSocket(AF_INET, type); -} - -AsyncSocket* FirewallSocketServer::CreateAsyncSocket(int family, int type) { - return WrapSocket(server_->CreateAsyncSocket(family, type), type); -} - -AsyncSocket* FirewallSocketServer::WrapSocket(AsyncSocket* sock, int type) { - if (!sock || - (type == SOCK_STREAM && !tcp_sockets_enabled_) || - (type == SOCK_DGRAM && !udp_sockets_enabled_)) { - LOG(LS_VERBOSE) << "FirewallSocketServer socket creation denied"; - delete sock; - return NULL; - } - return new FirewallSocket(this, sock, type); -} - -FirewallManager::FirewallManager() { -} - -FirewallManager::~FirewallManager() { - assert(servers_.empty()); -} - -void FirewallManager::AddServer(FirewallSocketServer* server) { - CritScope scope(&crit_); - servers_.push_back(server); -} - -void FirewallManager::RemoveServer(FirewallSocketServer* server) { - CritScope scope(&crit_); - servers_.erase(std::remove(servers_.begin(), servers_.end(), server), - servers_.end()); -} - -void FirewallManager::AddRule(bool allow, FirewallProtocol p, - FirewallDirection d, const SocketAddress& addr) { - CritScope scope(&crit_); - for (std::vector::const_iterator it = - servers_.begin(); it != servers_.end(); ++it) { - (*it)->AddRule(allow, p, d, addr); - } -} - -void FirewallManager::ClearRules() { - CritScope scope(&crit_); - for (std::vector::const_iterator it = - servers_.begin(); it != servers_.end(); ++it) { - (*it)->ClearRules(); - } -} - -} // namespace rtc diff --git a/webrtc/base/firewallsocketserver.h b/webrtc/base/firewallsocketserver.h deleted file mode 100644 index 500b7397d..000000000 --- a/webrtc/base/firewallsocketserver.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_FIREWALLSOCKETSERVER_H_ -#define WEBRTC_BASE_FIREWALLSOCKETSERVER_H_ - -#include -#include "webrtc/base/socketserver.h" -#include "webrtc/base/criticalsection.h" - -namespace rtc { - -class FirewallManager; - -// This SocketServer shim simulates a rule-based firewall server. - -enum FirewallProtocol { FP_UDP, FP_TCP, FP_ANY }; -enum FirewallDirection { FD_IN, FD_OUT, FD_ANY }; - -class FirewallSocketServer : public SocketServer { - public: - FirewallSocketServer(SocketServer * server, - FirewallManager * manager = NULL, - bool should_delete_server = false); - virtual ~FirewallSocketServer(); - - SocketServer* socketserver() const { return server_; } - void set_socketserver(SocketServer* server) { - if (server_ && should_delete_server_) { - delete server_; - server_ = NULL; - should_delete_server_ = false; - } - server_ = server; - } - - // Settings to control whether CreateSocket or Socket::Listen succeed. - void set_udp_sockets_enabled(bool enabled) { udp_sockets_enabled_ = enabled; } - void set_tcp_sockets_enabled(bool enabled) { tcp_sockets_enabled_ = enabled; } - bool tcp_listen_enabled() const { return tcp_listen_enabled_; } - void set_tcp_listen_enabled(bool enabled) { tcp_listen_enabled_ = enabled; } - - // Rules govern the behavior of Connect/Accept/Send/Recv attempts. - void AddRule(bool allow, FirewallProtocol p = FP_ANY, - FirewallDirection d = FD_ANY, - const SocketAddress& addr = SocketAddress()); - void AddRule(bool allow, FirewallProtocol p, - const SocketAddress& src, const SocketAddress& dst); - void ClearRules(); - - bool Check(FirewallProtocol p, - const SocketAddress& src, const SocketAddress& dst); - - virtual Socket* CreateSocket(int type); - virtual Socket* CreateSocket(int family, int type); - - virtual AsyncSocket* CreateAsyncSocket(int type); - virtual AsyncSocket* CreateAsyncSocket(int family, int type); - - virtual void SetMessageQueue(MessageQueue* queue) { - server_->SetMessageQueue(queue); - } - virtual bool Wait(int cms, bool process_io) { - return server_->Wait(cms, process_io); - } - virtual void WakeUp() { - return server_->WakeUp(); - } - - Socket * WrapSocket(Socket * sock, int type); - AsyncSocket * WrapSocket(AsyncSocket * sock, int type); - - private: - SocketServer * server_; - FirewallManager * manager_; - CriticalSection crit_; - struct Rule { - bool allow; - FirewallProtocol p; - FirewallDirection d; - SocketAddress src; - SocketAddress dst; - }; - std::vector rules_; - bool should_delete_server_; - bool udp_sockets_enabled_; - bool tcp_sockets_enabled_; - bool tcp_listen_enabled_; -}; - -// FirewallManager allows you to manage firewalls in multiple threads together - -class FirewallManager { - public: - FirewallManager(); - ~FirewallManager(); - - void AddServer(FirewallSocketServer * server); - void RemoveServer(FirewallSocketServer * server); - - void AddRule(bool allow, FirewallProtocol p = FP_ANY, - FirewallDirection d = FD_ANY, - const SocketAddress& addr = SocketAddress()); - void ClearRules(); - - private: - CriticalSection crit_; - std::vector servers_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_FIREWALLSOCKETSERVER_H_ diff --git a/webrtc/base/flags.cc b/webrtc/base/flags.cc deleted file mode 100644 index bc7a83030..000000000 --- a/webrtc/base/flags.cc +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#include -#endif - -#include "webrtc/base/flags.h" - - -// ----------------------------------------------------------------------------- -// Implementation of Flag - -Flag::Flag(const char* file, const char* name, const char* comment, - Type type, void* variable, FlagValue default__) - : file_(file), - name_(name), - comment_(comment), - type_(type), - variable_(reinterpret_cast(variable)), - default_(default__) { - FlagList::Register(this); -} - - -void Flag::SetToDefault() { - // Note that we cannot simply do '*variable_ = default_;' since - // flag variables are not really of type FlagValue and thus may - // be smaller! The FlagValue union is simply 'overlayed' on top - // of a flag variable for convenient access. Since union members - // are guarantee to be aligned at the beginning, this works. - switch (type_) { - case Flag::BOOL: - variable_->b = default_.b; - return; - case Flag::INT: - variable_->i = default_.i; - return; - case Flag::FLOAT: - variable_->f = default_.f; - return; - case Flag::STRING: - variable_->s = default_.s; - return; - } - UNREACHABLE(); -} - - -static const char* Type2String(Flag::Type type) { - switch (type) { - case Flag::BOOL: return "bool"; - case Flag::INT: return "int"; - case Flag::FLOAT: return "float"; - case Flag::STRING: return "string"; - } - UNREACHABLE(); - return NULL; -} - - -static void PrintFlagValue(Flag::Type type, FlagValue* p) { - switch (type) { - case Flag::BOOL: - printf("%s", (p->b ? "true" : "false")); - return; - case Flag::INT: - printf("%d", p->i); - return; - case Flag::FLOAT: - printf("%f", p->f); - return; - case Flag::STRING: - printf("%s", p->s); - return; - } - UNREACHABLE(); -} - - -void Flag::Print(bool print_current_value) { - printf(" --%s (%s) type: %s default: ", name_, comment_, - Type2String(type_)); - PrintFlagValue(type_, &default_); - if (print_current_value) { - printf(" current value: "); - PrintFlagValue(type_, variable_); - } - printf("\n"); -} - - -// ----------------------------------------------------------------------------- -// Implementation of FlagList - -Flag* FlagList::list_ = NULL; - - -FlagList::FlagList() { - list_ = NULL; -} - -void FlagList::Print(const char* file, bool print_current_value) { - // Since flag registration is likely by file (= C++ file), - // we don't need to sort by file and still get grouped output. - const char* current = NULL; - for (Flag* f = list_; f != NULL; f = f->next()) { - if (file == NULL || file == f->file()) { - if (current != f->file()) { - printf("Flags from %s:\n", f->file()); - current = f->file(); - } - f->Print(print_current_value); - } - } -} - - -Flag* FlagList::Lookup(const char* name) { - Flag* f = list_; - while (f != NULL && strcmp(name, f->name()) != 0) - f = f->next(); - return f; -} - - -void FlagList::SplitArgument(const char* arg, - char* buffer, int buffer_size, - const char** name, const char** value, - bool* is_bool) { - *name = NULL; - *value = NULL; - *is_bool = false; - - if (*arg == '-') { - // find the begin of the flag name - arg++; // remove 1st '-' - if (*arg == '-') - arg++; // remove 2nd '-' - if (arg[0] == 'n' && arg[1] == 'o') { - arg += 2; // remove "no" - *is_bool = true; - } - *name = arg; - - // find the end of the flag name - while (*arg != '\0' && *arg != '=') - arg++; - - // get the value if any - if (*arg == '=') { - // make a copy so we can NUL-terminate flag name - int n = static_cast(arg - *name); - if (n >= buffer_size) - Fatal(__FILE__, __LINE__, "CHECK(%s) failed", "n < buffer_size"); - memcpy(buffer, *name, n * sizeof(char)); - buffer[n] = '\0'; - *name = buffer; - // get the value - *value = arg + 1; - } - } -} - - -int FlagList::SetFlagsFromCommandLine(int* argc, const char** argv, - bool remove_flags) { - // parse arguments - for (int i = 1; i < *argc; /* see below */) { - int j = i; // j > 0 - const char* arg = argv[i++]; - - // split arg into flag components - char buffer[1024]; - const char* name; - const char* value; - bool is_bool; - SplitArgument(arg, buffer, sizeof buffer, &name, &value, &is_bool); - - if (name != NULL) { - // lookup the flag - Flag* flag = Lookup(name); - if (flag == NULL) { - fprintf(stderr, "Error: unrecognized flag %s\n", arg); - return j; - } - - // if we still need a flag value, use the next argument if available - if (flag->type() != Flag::BOOL && value == NULL) { - if (i < *argc) { - value = argv[i++]; - } else { - fprintf(stderr, "Error: missing value for flag %s of type %s\n", - arg, Type2String(flag->type())); - return j; - } - } - - // set the flag - char empty[] = { '\0' }; - char* endp = empty; - switch (flag->type()) { - case Flag::BOOL: - *flag->bool_variable() = !is_bool; - break; - case Flag::INT: - *flag->int_variable() = strtol(value, &endp, 10); - break; - case Flag::FLOAT: - *flag->float_variable() = strtod(value, &endp); - break; - case Flag::STRING: - *flag->string_variable() = value; - break; - } - - // handle errors - if ((flag->type() == Flag::BOOL && value != NULL) || - (flag->type() != Flag::BOOL && is_bool) || - *endp != '\0') { - fprintf(stderr, "Error: illegal value for flag %s of type %s\n", - arg, Type2String(flag->type())); - return j; - } - - // remove the flag & value from the command - if (remove_flags) - while (j < i) - argv[j++] = NULL; - } - } - - // shrink the argument list - if (remove_flags) { - int j = 1; - for (int i = 1; i < *argc; i++) { - if (argv[i] != NULL) - argv[j++] = argv[i]; - } - *argc = j; - } - - // parsed all flags successfully - return 0; -} - -void FlagList::Register(Flag* flag) { - assert(flag != NULL && strlen(flag->name()) > 0); - if (Lookup(flag->name()) != NULL) - Fatal(flag->file(), 0, "flag %s declared twice", flag->name()); - flag->next_ = list_; - list_ = flag; -} - -#if defined(WEBRTC_WIN) -WindowsCommandLineArguments::WindowsCommandLineArguments() { - // start by getting the command line. - LPTSTR command_line = ::GetCommandLine(); - // now, convert it to a list of wide char strings. - LPWSTR *wide_argv = ::CommandLineToArgvW(command_line, &argc_); - // now allocate an array big enough to hold that many string pointers. - argv_ = new char*[argc_]; - - // iterate over the returned wide strings; - for(int i = 0; i < argc_; ++i) { - std::string s = rtc::ToUtf8(wide_argv[i], wcslen(wide_argv[i])); - char *buffer = new char[s.length() + 1]; - rtc::strcpyn(buffer, s.length() + 1, s.c_str()); - - // make sure the argv array has the right string at this point. - argv_[i] = buffer; - } - LocalFree(wide_argv); -} - -WindowsCommandLineArguments::~WindowsCommandLineArguments() { - // need to free each string in the array, and then the array. - for(int i = 0; i < argc_; i++) { - delete[] argv_[i]; - } - - delete[] argv_; -} -#endif // WEBRTC_WIN - diff --git a/webrtc/base/flags.h b/webrtc/base/flags.h deleted file mode 100644 index ac91d8ad6..000000000 --- a/webrtc/base/flags.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -// Originally comes from shared/commandlineflags/flags.h - -// Flags are defined and declared using DEFINE_xxx and DECLARE_xxx macros, -// where xxx is the flag type. Flags are referred to via FLAG_yyy, -// where yyy is the flag name. For intialization and iteration of flags, -// see the FlagList class. For full programmatic access to any -// flag, see the Flag class. -// -// The implementation only relies and basic C++ functionality -// and needs no special library or STL support. - -#ifndef WEBRTC_BASE_FLAGS_H__ -#define WEBRTC_BASE_FLAGS_H__ - -#include - -#include "webrtc/base/checks.h" -#include "webrtc/base/common.h" - -// Internal use only. -union FlagValue { - // Note: Because in C++ non-bool values are silently converted into - // bool values ('bool b = "false";' results in b == true!), we pass - // and int argument to New_BOOL as this appears to be safer - sigh. - // In particular, it prevents the (not uncommon!) bug where a bool - // flag is defined via: DEFINE_bool(flag, "false", "some comment");. - static FlagValue New_BOOL(int b) { - FlagValue v; - v.b = (b != 0); - return v; - } - - static FlagValue New_INT(int i) { - FlagValue v; - v.i = i; - return v; - } - - static FlagValue New_FLOAT(float f) { - FlagValue v; - v.f = f; - return v; - } - - static FlagValue New_STRING(const char* s) { - FlagValue v; - v.s = s; - return v; - } - - bool b; - int i; - double f; - const char* s; -}; - - -// Each flag can be accessed programmatically via a Flag object. -class Flag { - public: - enum Type { BOOL, INT, FLOAT, STRING }; - - // Internal use only. - Flag(const char* file, const char* name, const char* comment, - Type type, void* variable, FlagValue default_); - - // General flag information - const char* file() const { return file_; } - const char* name() const { return name_; } - const char* comment() const { return comment_; } - - // Flag type - Type type() const { return type_; } - - // Flag variables - bool* bool_variable() const { - assert(type_ == BOOL); - return &variable_->b; - } - - int* int_variable() const { - assert(type_ == INT); - return &variable_->i; - } - - double* float_variable() const { - assert(type_ == FLOAT); - return &variable_->f; - } - - const char** string_variable() const { - assert(type_ == STRING); - return &variable_->s; - } - - // Default values - bool bool_default() const { - assert(type_ == BOOL); - return default_.b; - } - - int int_default() const { - assert(type_ == INT); - return default_.i; - } - - double float_default() const { - assert(type_ == FLOAT); - return default_.f; - } - - const char* string_default() const { - assert(type_ == STRING); - return default_.s; - } - - // Resets a flag to its default value - void SetToDefault(); - - // Iteration support - Flag* next() const { return next_; } - - // Prints flag information. The current flag value is only printed - // if print_current_value is set. - void Print(bool print_current_value); - - private: - const char* file_; - const char* name_; - const char* comment_; - - Type type_; - FlagValue* variable_; - FlagValue default_; - - Flag* next_; - - friend class FlagList; // accesses next_ -}; - - -// Internal use only. -#define DEFINE_FLAG(type, c_type, name, default, comment) \ - /* define and initialize the flag */ \ - c_type FLAG_##name = (default); \ - /* register the flag */ \ - static Flag Flag_##name(__FILE__, #name, (comment), \ - Flag::type, &FLAG_##name, \ - FlagValue::New_##type(default)) - - -// Internal use only. -#define DECLARE_FLAG(c_type, name) \ - /* declare the external flag */ \ - extern c_type FLAG_##name - - -// Use the following macros to define a new flag: -#define DEFINE_bool(name, default, comment) \ - DEFINE_FLAG(BOOL, bool, name, default, comment) -#define DEFINE_int(name, default, comment) \ - DEFINE_FLAG(INT, int, name, default, comment) -#define DEFINE_float(name, default, comment) \ - DEFINE_FLAG(FLOAT, double, name, default, comment) -#define DEFINE_string(name, default, comment) \ - DEFINE_FLAG(STRING, const char*, name, default, comment) - - -// Use the following macros to declare a flag defined elsewhere: -#define DECLARE_bool(name) DECLARE_FLAG(bool, name) -#define DECLARE_int(name) DECLARE_FLAG(int, name) -#define DECLARE_float(name) DECLARE_FLAG(double, name) -#define DECLARE_string(name) DECLARE_FLAG(const char*, name) - - -// The global list of all flags. -class FlagList { - public: - FlagList(); - - // The NULL-terminated list of all flags. Traverse with Flag::next(). - static Flag* list() { return list_; } - - // If file != NULL, prints information for all flags defined in file; - // otherwise prints information for all flags in all files. The current - // flag value is only printed if print_current_value is set. - static void Print(const char* file, bool print_current_value); - - // Lookup a flag by name. Returns the matching flag or NULL. - static Flag* Lookup(const char* name); - - // Helper function to parse flags: Takes an argument arg and splits it into - // a flag name and flag value (or NULL if they are missing). is_bool is set - // if the arg started with "-no" or "--no". The buffer may be used to NUL- - // terminate the name, it must be large enough to hold any possible name. - static void SplitArgument(const char* arg, - char* buffer, int buffer_size, - const char** name, const char** value, - bool* is_bool); - - // Set the flag values by parsing the command line. If remove_flags - // is set, the flags and associated values are removed from (argc, - // argv). Returns 0 if no error occurred. Otherwise, returns the - // argv index > 0 for the argument where an error occurred. In that - // case, (argc, argv) will remain unchanged indepdendent of the - // remove_flags value, and no assumptions about flag settings should - // be made. - // - // The following syntax for flags is accepted (both '-' and '--' are ok): - // - // --flag (bool flags only) - // --noflag (bool flags only) - // --flag=value (non-bool flags only, no spaces around '=') - // --flag value (non-bool flags only) - static int SetFlagsFromCommandLine(int* argc, - const char** argv, - bool remove_flags); - static inline int SetFlagsFromCommandLine(int* argc, - char** argv, - bool remove_flags) { - return SetFlagsFromCommandLine(argc, const_cast(argv), - remove_flags); - } - - // Registers a new flag. Called during program initialization. Not - // thread-safe. - static void Register(Flag* flag); - - private: - static Flag* list_; -}; - -#if defined(WEBRTC_WIN) -// A helper class to translate Windows command line arguments into UTF8, -// which then allows us to just pass them to the flags system. -// This encapsulates all the work of getting the command line and translating -// it to an array of 8-bit strings; all you have to do is create one of these, -// and then call argc() and argv(). -class WindowsCommandLineArguments { - public: - WindowsCommandLineArguments(); - ~WindowsCommandLineArguments(); - - int argc() { return argc_; } - char **argv() { return argv_; } - private: - int argc_; - char **argv_; - - private: - DISALLOW_EVIL_CONSTRUCTORS(WindowsCommandLineArguments); -}; -#endif // WEBRTC_WIN - - -#endif // SHARED_COMMANDLINEFLAGS_FLAGS_H__ diff --git a/webrtc/base/genericslot.h b/webrtc/base/genericslot.h deleted file mode 100755 index 76205b33c..000000000 --- a/webrtc/base/genericslot.h +++ /dev/null @@ -1,241 +0,0 @@ -// This file was GENERATED by command: -// pump.py genericslot.h.pump -// DO NOT EDIT BY HAND!!! - -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_GENERICSLOT_H_ -#define WEBRTC_BASE_GENERICSLOT_H_ - -// To generate genericslot.h from genericslot.h.pump, execute: -// /home/build/google3/third_party/gtest/scripts/pump.py genericslot.h.pump - -// Generic-slots are pure slots that can be hooked up to signals. They're -// mainly intended to be used in tests where we want to check if a signal -// was invoked and what arguments were passed. NOTE: They do not do any -// lifetime management of the arguments received via callbacks. -// -// Example: -// /* Some signal */ -// sigslot::signal1 foo; -// -// /* We want to monitor foo in some test */ -// rtc::GenericSlot1 slot(&foo, 0); -// foo.emit(5); -// EXPECT_TRUE(slot.callback_received()); -// EXPECT_EQ(5, *(slot.arg1())); -// - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/sigslot.h" - -namespace rtc { - -template -class GenericSlot1 : public sigslot::has_slots<> { - public: - GenericSlot1(sigslot::signal1* signal, - const A1& arg1_initial) - : arg1_initial_(arg1_initial) { - Reset(); - signal->connect(this, &GenericSlot1::OnSignalCallback); - } - - void Reset() { - callback_received_ = false; - arg1_ = arg1_initial_; - } - - bool callback_received() const { return callback_received_; } - const A1& arg1() const { return arg1_; } - - private: - void OnSignalCallback(A1 arg1) { - callback_received_ = true; - arg1_ = arg1; - } - - bool callback_received_; - A1 arg1_initial_, arg1_; - - DISALLOW_COPY_AND_ASSIGN(GenericSlot1); -}; - -template -class GenericSlot2 : public sigslot::has_slots<> { - public: - GenericSlot2(sigslot::signal2* signal, - const A1& arg1_initial, const A2& arg2_initial) - : arg1_initial_(arg1_initial), arg2_initial_(arg2_initial) { - Reset(); - signal->connect(this, &GenericSlot2::OnSignalCallback); - } - - void Reset() { - callback_received_ = false; - arg1_ = arg1_initial_; - arg2_ = arg2_initial_; - } - - bool callback_received() const { return callback_received_; } - const A1& arg1() const { return arg1_; } - const A2& arg2() const { return arg2_; } - - private: - void OnSignalCallback(A1 arg1, A2 arg2) { - callback_received_ = true; - arg1_ = arg1; - arg2_ = arg2; - } - - bool callback_received_; - A1 arg1_initial_, arg1_; - A2 arg2_initial_, arg2_; - - DISALLOW_COPY_AND_ASSIGN(GenericSlot2); -}; - -template -class GenericSlot3 : public sigslot::has_slots<> { - public: - GenericSlot3(sigslot::signal3* signal, - const A1& arg1_initial, const A2& arg2_initial, - const A3& arg3_initial) - : arg1_initial_(arg1_initial), arg2_initial_(arg2_initial), - arg3_initial_(arg3_initial) { - Reset(); - signal->connect(this, &GenericSlot3::OnSignalCallback); - } - - void Reset() { - callback_received_ = false; - arg1_ = arg1_initial_; - arg2_ = arg2_initial_; - arg3_ = arg3_initial_; - } - - bool callback_received() const { return callback_received_; } - const A1& arg1() const { return arg1_; } - const A2& arg2() const { return arg2_; } - const A3& arg3() const { return arg3_; } - - private: - void OnSignalCallback(A1 arg1, A2 arg2, A3 arg3) { - callback_received_ = true; - arg1_ = arg1; - arg2_ = arg2; - arg3_ = arg3; - } - - bool callback_received_; - A1 arg1_initial_, arg1_; - A2 arg2_initial_, arg2_; - A3 arg3_initial_, arg3_; - - DISALLOW_COPY_AND_ASSIGN(GenericSlot3); -}; - -template -class GenericSlot4 : public sigslot::has_slots<> { - public: - GenericSlot4(sigslot::signal4* signal, - const A1& arg1_initial, const A2& arg2_initial, - const A3& arg3_initial, const A4& arg4_initial) - : arg1_initial_(arg1_initial), arg2_initial_(arg2_initial), - arg3_initial_(arg3_initial), arg4_initial_(arg4_initial) { - Reset(); - signal->connect(this, &GenericSlot4::OnSignalCallback); - } - - void Reset() { - callback_received_ = false; - arg1_ = arg1_initial_; - arg2_ = arg2_initial_; - arg3_ = arg3_initial_; - arg4_ = arg4_initial_; - } - - bool callback_received() const { return callback_received_; } - const A1& arg1() const { return arg1_; } - const A2& arg2() const { return arg2_; } - const A3& arg3() const { return arg3_; } - const A4& arg4() const { return arg4_; } - - private: - void OnSignalCallback(A1 arg1, A2 arg2, A3 arg3, A4 arg4) { - callback_received_ = true; - arg1_ = arg1; - arg2_ = arg2; - arg3_ = arg3; - arg4_ = arg4; - } - - bool callback_received_; - A1 arg1_initial_, arg1_; - A2 arg2_initial_, arg2_; - A3 arg3_initial_, arg3_; - A4 arg4_initial_, arg4_; - - DISALLOW_COPY_AND_ASSIGN(GenericSlot4); -}; - -template -class GenericSlot5 : public sigslot::has_slots<> { - public: - GenericSlot5(sigslot::signal5* signal, - const A1& arg1_initial, const A2& arg2_initial, - const A3& arg3_initial, const A4& arg4_initial, - const A5& arg5_initial) - : arg1_initial_(arg1_initial), arg2_initial_(arg2_initial), - arg3_initial_(arg3_initial), arg4_initial_(arg4_initial), - arg5_initial_(arg5_initial) { - Reset(); - signal->connect(this, &GenericSlot5::OnSignalCallback); - } - - void Reset() { - callback_received_ = false; - arg1_ = arg1_initial_; - arg2_ = arg2_initial_; - arg3_ = arg3_initial_; - arg4_ = arg4_initial_; - arg5_ = arg5_initial_; - } - - bool callback_received() const { return callback_received_; } - const A1& arg1() const { return arg1_; } - const A2& arg2() const { return arg2_; } - const A3& arg3() const { return arg3_; } - const A4& arg4() const { return arg4_; } - const A5& arg5() const { return arg5_; } - - private: - void OnSignalCallback(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5) { - callback_received_ = true; - arg1_ = arg1; - arg2_ = arg2; - arg3_ = arg3; - arg4_ = arg4; - arg5_ = arg5; - } - - bool callback_received_; - A1 arg1_initial_, arg1_; - A2 arg2_initial_, arg2_; - A3 arg3_initial_, arg3_; - A4 arg4_initial_, arg4_; - A5 arg5_initial_, arg5_; - - DISALLOW_COPY_AND_ASSIGN(GenericSlot5); -}; -} // namespace rtc - -#endif // WEBRTC_BASE_GENERICSLOT_H_ diff --git a/webrtc/base/genericslot.h.pump b/webrtc/base/genericslot.h.pump deleted file mode 100755 index 4d1533c58..000000000 --- a/webrtc/base/genericslot.h.pump +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_GENERICSLOT_H_ -#define WEBRTC_BASE_GENERICSLOT_H_ - -// To generate genericslot.h from genericslot.h.pump, execute: -// /home/build/google3/third_party/gtest/scripts/pump.py genericslot.h.pump - -// Generic-slots are pure slots that can be hooked up to signals. They're -// mainly intended to be used in tests where we want to check if a signal -// was invoked and what arguments were passed. NOTE: They do not do any -// lifetime management of the arguments received via callbacks. -// -// Example: -// /* Some signal */ -// sigslot::signal1 foo; -// -// /* We want to monitor foo in some test */ -// rtc::GenericSlot1 slot(&foo, 0); -// foo.emit(5); -// EXPECT_TRUE(slot.callback_received()); -// EXPECT_EQ(5, *(slot.arg1())); -// - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/sigslot.h" - -namespace rtc { - -$var n = 5 -$range i 1..n -$for i [[ -$range j 1..i - -template <$for j , [[class A$j]]> -class GenericSlot$i : public sigslot::has_slots<> { - public: - GenericSlot$i(sigslot::signal$i<$for j , [[A$j]]>* signal, - $for j , [[const A$j& arg$j[[]]_initial]]) - : $for j , [[arg$j[[]]_initial_(arg$j[[]]_initial)]] { - Reset(); - signal->connect(this, &GenericSlot$i::OnSignalCallback); - } - - void Reset() { - callback_received_ = false;$for j [[ - - arg$j[[]]_ = arg$j[[]]_initial_; ]] - - } - - bool callback_received() const { return callback_received_; }$for j [[ - - const A$j& arg$j() const { return arg$j[[]]_; }]] - - - private: - void OnSignalCallback($for j , [[A$j arg$j]]) { - callback_received_ = true;$for j [[ - - arg$j[[]]_ = arg$j;]] - - } - - bool callback_received_;$for j [[ - - A$j arg$j[[]]_initial_, arg$j[[]]_;]] - - - DISALLOW_COPY_AND_ASSIGN(GenericSlot$i); -}; - -]] -} // namespace rtc - -#endif // WEBRTC_BASE_GENERICSLOT_H_ diff --git a/webrtc/base/genericslot_unittest.cc b/webrtc/base/genericslot_unittest.cc deleted file mode 100755 index 33d7db8bf..000000000 --- a/webrtc/base/genericslot_unittest.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "webrtc/base/genericslot.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/sigslot.h" - -namespace rtc { - -TEST(GenericSlotTest, TestSlot1) { - sigslot::signal1 source1; - GenericSlot1 slot1(&source1, 1); - EXPECT_FALSE(slot1.callback_received()); - source1.emit(10); - EXPECT_TRUE(slot1.callback_received()); - EXPECT_EQ(10, slot1.arg1()); -} - -TEST(GenericSlotTest, TestSlot2) { - sigslot::signal2 source2; - GenericSlot2 slot2(&source2, 1, '0'); - EXPECT_FALSE(slot2.callback_received()); - source2.emit(10, 'x'); - EXPECT_TRUE(slot2.callback_received()); - EXPECT_EQ(10, slot2.arg1()); - EXPECT_EQ('x', slot2.arg2()); -} - -// By induction we assume the rest work too... - -} // namespace rtc diff --git a/webrtc/base/gunit.h b/webrtc/base/gunit.h deleted file mode 100644 index 9766c2c3a..000000000 --- a/webrtc/base/gunit.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_GUNIT_H_ -#define WEBRTC_BASE_GUNIT_H_ - -#include "webrtc/base/logging.h" -#include "webrtc/base/thread.h" -#if defined(WEBRTC_ANDROID) || defined(GTEST_RELATIVE_PATH) -#include "gtest/gtest.h" -#else -#include "testing/base/public/gunit.h" -#endif - -// forward declarations -namespace rtc { -class Pathname; -} - -// Wait until "ex" is true, or "timeout" expires. -#define WAIT(ex, timeout) \ - for (uint32 start = rtc::Time(); \ - !(ex) && rtc::Time() < start + timeout;) \ - rtc::Thread::Current()->ProcessMessages(1); - -// This returns the result of the test in res, so that we don't re-evaluate -// the expression in the XXXX_WAIT macros below, since that causes problems -// when the expression is only true the first time you check it. -#define WAIT_(ex, timeout, res) \ - do { \ - uint32 start = rtc::Time(); \ - res = (ex); \ - while (!res && rtc::Time() < start + timeout) { \ - rtc::Thread::Current()->ProcessMessages(1); \ - res = (ex); \ - } \ - } while (0); - -// The typical EXPECT_XXXX and ASSERT_XXXXs, but done until true or a timeout. -#define EXPECT_TRUE_WAIT(ex, timeout) \ - do { \ - bool res; \ - WAIT_(ex, timeout, res); \ - if (!res) EXPECT_TRUE(ex); \ - } while (0); - -#define EXPECT_EQ_WAIT(v1, v2, timeout) \ - do { \ - bool res; \ - WAIT_(v1 == v2, timeout, res); \ - if (!res) EXPECT_EQ(v1, v2); \ - } while (0); - -#define ASSERT_TRUE_WAIT(ex, timeout) \ - do { \ - bool res; \ - WAIT_(ex, timeout, res); \ - if (!res) ASSERT_TRUE(ex); \ - } while (0); - -#define ASSERT_EQ_WAIT(v1, v2, timeout) \ - do { \ - bool res; \ - WAIT_(v1 == v2, timeout, res); \ - if (!res) ASSERT_EQ(v1, v2); \ - } while (0); - -// Version with a "soft" timeout and a margin. This logs if the timeout is -// exceeded, but it only fails if the expression still isn't true after the -// margin time passes. -#define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \ - do { \ - bool res; \ - WAIT_(ex, timeout, res); \ - if (res) { \ - break; \ - } \ - LOG(LS_WARNING) << "Expression " << #ex << " still not true after " << \ - timeout << "ms; waiting an additional " << margin << "ms"; \ - WAIT_(ex, margin, res); \ - if (!res) { \ - EXPECT_TRUE(ex); \ - } \ - } while (0); - -rtc::Pathname GetTalkDirectory(); - -#endif // WEBRTC_BASE_GUNIT_H_ diff --git a/webrtc/base/gunit_prod.h b/webrtc/base/gunit_prod.h deleted file mode 100644 index dc39bbd0e..000000000 --- a/webrtc/base/gunit_prod.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_GUNIT_PROD_H_ -#define WEBRTC_BASE_GUNIT_PROD_H_ - -#if defined(WEBRTC_ANDROID) -// Android doesn't use gtest at all, so anything that relies on gtest should -// check this define first. -#define NO_GTEST -#elif defined (GTEST_RELATIVE_PATH) -#include "gtest/gtest_prod.h" -#else -#include "testing/base/gunit_prod.h" -#endif - -#endif // WEBRTC_BASE_GUNIT_PROD_H_ diff --git a/webrtc/base/helpers.cc b/webrtc/base/helpers.cc deleted file mode 100644 index 8b14cdfd6..000000000 --- a/webrtc/base/helpers.cc +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/helpers.h" - -#include - -#if defined(FEATURE_ENABLE_SSL) -#include "webrtc/base/sslconfig.h" -#if defined(SSL_USE_OPENSSL) -#include -#elif defined(SSL_USE_NSS_RNG) -#include "pk11func.h" -#else -#if defined(WEBRTC_WIN) -#define WIN32_LEAN_AND_MEAN -#include -#include -#endif // WEBRTC_WIN -#endif // else -#endif // FEATURE_ENABLED_SSL - -#include "webrtc/base/base64.h" -#include "webrtc/base/basictypes.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/timeutils.h" - -// Protect against max macro inclusion. -#undef max - -namespace rtc { - -// Base class for RNG implementations. -class RandomGenerator { - public: - virtual ~RandomGenerator() {} - virtual bool Init(const void* seed, size_t len) = 0; - virtual bool Generate(void* buf, size_t len) = 0; -}; - -#if defined(SSL_USE_OPENSSL) -// The OpenSSL RNG. Need to make sure it doesn't run out of entropy. -class SecureRandomGenerator : public RandomGenerator { - public: - SecureRandomGenerator() : inited_(false) { - } - ~SecureRandomGenerator() { - } - virtual bool Init(const void* seed, size_t len) { - // By default, seed from the system state. - if (!inited_) { - if (RAND_poll() <= 0) { - return false; - } - inited_ = true; - } - // Allow app data to be mixed in, if provided. - if (seed) { - RAND_seed(seed, len); - } - return true; - } - virtual bool Generate(void* buf, size_t len) { - if (!inited_ && !Init(NULL, 0)) { - return false; - } - return (RAND_bytes(reinterpret_cast(buf), len) > 0); - } - - private: - bool inited_; -}; - -#elif defined(SSL_USE_NSS_RNG) -// The NSS RNG. -class SecureRandomGenerator : public RandomGenerator { - public: - SecureRandomGenerator() {} - ~SecureRandomGenerator() {} - virtual bool Init(const void* seed, size_t len) { - return true; - } - virtual bool Generate(void* buf, size_t len) { - return (PK11_GenerateRandom(reinterpret_cast(buf), - static_cast(len)) == SECSuccess); - } -}; - -#else -#if defined(WEBRTC_WIN) -class SecureRandomGenerator : public RandomGenerator { - public: - SecureRandomGenerator() : advapi32_(NULL), rtl_gen_random_(NULL) {} - ~SecureRandomGenerator() { - FreeLibrary(advapi32_); - } - - virtual bool Init(const void* seed, size_t seed_len) { - // We don't do any additional seeding on Win32, we just use the CryptoAPI - // RNG (which is exposed as a hidden function off of ADVAPI32 so that we - // don't need to drag in all of CryptoAPI) - if (rtl_gen_random_) { - return true; - } - - advapi32_ = LoadLibrary(L"advapi32.dll"); - if (!advapi32_) { - return false; - } - - rtl_gen_random_ = reinterpret_cast( - GetProcAddress(advapi32_, "SystemFunction036")); - if (!rtl_gen_random_) { - FreeLibrary(advapi32_); - return false; - } - - return true; - } - virtual bool Generate(void* buf, size_t len) { - if (!rtl_gen_random_ && !Init(NULL, 0)) { - return false; - } - return (rtl_gen_random_(buf, static_cast(len)) != FALSE); - } - - private: - typedef BOOL (WINAPI *RtlGenRandomProc)(PVOID, ULONG); - HINSTANCE advapi32_; - 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(seed)); - } else { - srand(*reinterpret_cast(seed)); - } - return true; - } - virtual bool Generate(void* buf, size_t len) { - char* bytes = reinterpret_cast(buf); - for (size_t i = 0; i < len; ++i) { - bytes[i] = static_cast(rand()); - } - return true; - } -}; - -#else - -#error No SSL implementation has been selected! - -#endif // WEBRTC_WIN -#endif - -// A test random generator, for predictable output. -class TestRandomGenerator : public RandomGenerator { - public: - TestRandomGenerator() : seed_(7) { - } - ~TestRandomGenerator() { - } - virtual bool Init(const void* seed, size_t len) { - return true; - } - virtual bool Generate(void* buf, size_t len) { - for (size_t i = 0; i < len; ++i) { - static_cast(buf)[i] = static_cast(GetRandom()); - } - return true; - } - - private: - int GetRandom() { - return ((seed_ = seed_ * 214013L + 2531011L) >> 16) & 0x7fff; - } - int seed_; -}; - -// TODO: Use Base64::Base64Table instead. -static const char BASE64[64] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' -}; - -namespace { - -// This round about way of creating a global RNG is to safe-guard against -// indeterminant static initialization order. -scoped_ptr& GetGlobalRng() { - LIBJINGLE_DEFINE_STATIC_LOCAL(scoped_ptr, global_rng, - (new SecureRandomGenerator())); - return global_rng; -} - -RandomGenerator& Rng() { - return *GetGlobalRng(); -} - -} // namespace - -void SetRandomTestMode(bool test) { - if (!test) { - GetGlobalRng().reset(new SecureRandomGenerator()); - } else { - GetGlobalRng().reset(new TestRandomGenerator()); - } -} - -bool InitRandom(int seed) { - return InitRandom(reinterpret_cast(&seed), sizeof(seed)); -} - -bool InitRandom(const char* seed, size_t len) { - if (!Rng().Init(seed, len)) { - LOG(LS_ERROR) << "Failed to init random generator!"; - return false; - } - return true; -} - -std::string CreateRandomString(size_t len) { - std::string str; - CreateRandomString(len, &str); - return str; -} - -bool CreateRandomString(size_t len, - const char* table, int table_size, - std::string* str) { - str->clear(); - scoped_ptr bytes(new uint8[len]); - if (!Rng().Generate(bytes.get(), len)) { - LOG(LS_ERROR) << "Failed to generate random string!"; - return false; - } - str->reserve(len); - for (size_t i = 0; i < len; ++i) { - str->push_back(table[bytes[i] % table_size]); - } - return true; -} - -bool CreateRandomString(size_t len, std::string* str) { - return CreateRandomString(len, BASE64, 64, str); -} - -bool CreateRandomString(size_t len, const std::string& table, - std::string* str) { - return CreateRandomString(len, table.c_str(), - static_cast(table.size()), str); -} - -uint32 CreateRandomId() { - uint32 id; - if (!Rng().Generate(&id, sizeof(id))) { - LOG(LS_ERROR) << "Failed to generate random id!"; - } - return id; -} - -uint64 CreateRandomId64() { - return static_cast(CreateRandomId()) << 32 | CreateRandomId(); -} - -uint32 CreateRandomNonZeroId() { - uint32 id; - do { - id = CreateRandomId(); - } while (id == 0); - return id; -} - -double CreateRandomDouble() { - return CreateRandomId() / (std::numeric_limits::max() + - std::numeric_limits::epsilon()); -} - -} // namespace rtc diff --git a/webrtc/base/helpers.h b/webrtc/base/helpers.h deleted file mode 100644 index e46d12a33..000000000 --- a/webrtc/base/helpers.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_HELPERS_H_ -#define WEBRTC_BASE_HELPERS_H_ - -#include -#include "webrtc/base/basictypes.h" - -namespace rtc { - -// For testing, we can return predictable data. -void SetRandomTestMode(bool test); - -// Initializes the RNG, and seeds it with the specified entropy. -bool InitRandom(int seed); -bool InitRandom(const char* seed, size_t len); - -// Generates a (cryptographically) random string of the given length. -// We generate base64 values so that they will be printable. -// WARNING: could silently fail. Use the version below instead. -std::string CreateRandomString(size_t length); - -// Generates a (cryptographically) random string of the given length. -// We generate base64 values so that they will be printable. -// Return false if the random number generator failed. -bool CreateRandomString(size_t length, std::string* str); - -// Generates a (cryptographically) random string of the given length, -// with characters from the given table. Return false if the random -// number generator failed. -bool CreateRandomString(size_t length, const std::string& table, - std::string* str); - -// Generates a random id. -uint32 CreateRandomId(); - -// Generates a 64 bit random id. -uint64 CreateRandomId64(); - -// Generates a random id > 0. -uint32 CreateRandomNonZeroId(); - -// Generates a random double between 0.0 (inclusive) and 1.0 (exclusive). -double CreateRandomDouble(); - -} // namespace rtc - -#endif // WEBRTC_BASE_HELPERS_H_ diff --git a/webrtc/base/helpers_unittest.cc b/webrtc/base/helpers_unittest.cc deleted file mode 100644 index 7c20540c5..000000000 --- a/webrtc/base/helpers_unittest.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/helpers.h" -#include "webrtc/base/ssladapter.h" - -namespace rtc { - -class RandomTest : public testing::Test { - public: - static void SetUpTestCase() { - rtc::InitializeSSL(); - } - - static void TearDownTestCase() { - rtc::CleanupSSL(); - } -}; - -TEST_F(RandomTest, TestCreateRandomId) { - CreateRandomId(); -} - -TEST_F(RandomTest, TestCreateRandomDouble) { - for (int i = 0; i < 100; ++i) { - double r = CreateRandomDouble(); - EXPECT_GE(r, 0.0); - EXPECT_LT(r, 1.0); - } -} - -TEST_F(RandomTest, TestCreateNonZeroRandomId) { - EXPECT_NE(0U, CreateRandomNonZeroId()); -} - -TEST_F(RandomTest, TestCreateRandomString) { - std::string random = CreateRandomString(256); - EXPECT_EQ(256U, random.size()); - std::string random2; - EXPECT_TRUE(CreateRandomString(256, &random2)); - EXPECT_NE(random, random2); - EXPECT_EQ(256U, random2.size()); -} - -TEST_F(RandomTest, TestCreateRandomForTest) { - // Make sure we get the output we expect. - SetRandomTestMode(true); - EXPECT_EQ(2154761789U, CreateRandomId()); - EXPECT_EQ("h0ISP4S5SJKH/9EY", CreateRandomString(16)); - - // Reset and make sure we get the same output. - SetRandomTestMode(true); - EXPECT_EQ(2154761789U, CreateRandomId()); - EXPECT_EQ("h0ISP4S5SJKH/9EY", CreateRandomString(16)); - - // Test different character sets. - SetRandomTestMode(true); - std::string str; - EXPECT_TRUE(CreateRandomString(16, "a", &str)); - EXPECT_EQ("aaaaaaaaaaaaaaaa", str); - EXPECT_TRUE(CreateRandomString(16, "abc", &str)); - EXPECT_EQ("acbccaaaabbaacbb", str); - - // Turn off test mode for other tests. - SetRandomTestMode(false); -} - -} // namespace rtc diff --git a/webrtc/base/httpbase.cc b/webrtc/base/httpbase.cc deleted file mode 100644 index 5de2b79d7..000000000 --- a/webrtc/base/httpbase.cc +++ /dev/null @@ -1,877 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#else // !WEBRTC_WIN -#define SEC_E_CERT_EXPIRED (-2146893016) -#endif // !WEBRTC_WIN - -#include "webrtc/base/common.h" -#include "webrtc/base/httpbase.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/socket.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -////////////////////////////////////////////////////////////////////// -// Helpers -////////////////////////////////////////////////////////////////////// - -bool MatchHeader(const char* str, size_t len, HttpHeader header) { - const char* const header_str = ToString(header); - const size_t header_len = strlen(header_str); - return (len == header_len) && (_strnicmp(str, header_str, header_len) == 0); -} - -enum { - MSG_READ -}; - -////////////////////////////////////////////////////////////////////// -// HttpParser -////////////////////////////////////////////////////////////////////// - -HttpParser::HttpParser() { - reset(); -} - -HttpParser::~HttpParser() { -} - -void -HttpParser::reset() { - state_ = ST_LEADER; - chunked_ = false; - data_size_ = SIZE_UNKNOWN; -} - -HttpParser::ProcessResult -HttpParser::Process(const char* buffer, size_t len, size_t* processed, - HttpError* error) { - *processed = 0; - *error = HE_NONE; - - if (state_ >= ST_COMPLETE) { - ASSERT(false); - return PR_COMPLETE; - } - - while (true) { - if (state_ < ST_DATA) { - size_t pos = *processed; - while ((pos < len) && (buffer[pos] != '\n')) { - pos += 1; - } - if (pos >= len) { - break; // don't have a full header - } - const char* line = buffer + *processed; - size_t len = (pos - *processed); - *processed = pos + 1; - while ((len > 0) && isspace(static_cast(line[len-1]))) { - len -= 1; - } - ProcessResult result = ProcessLine(line, len, error); - LOG(LS_VERBOSE) << "Processed line, result=" << result; - - if (PR_CONTINUE != result) { - return result; - } - } else if (data_size_ == 0) { - if (chunked_) { - state_ = ST_CHUNKTERM; - } else { - return PR_COMPLETE; - } - } else { - size_t available = len - *processed; - if (available <= 0) { - break; // no more data - } - if ((data_size_ != SIZE_UNKNOWN) && (available > data_size_)) { - available = data_size_; - } - size_t read = 0; - ProcessResult result = ProcessData(buffer + *processed, available, read, - error); - LOG(LS_VERBOSE) << "Processed data, result: " << result << " read: " - << read << " err: " << error; - - if (PR_CONTINUE != result) { - return result; - } - *processed += read; - if (data_size_ != SIZE_UNKNOWN) { - data_size_ -= read; - } - } - } - - return PR_CONTINUE; -} - -HttpParser::ProcessResult -HttpParser::ProcessLine(const char* line, size_t len, HttpError* error) { - LOG_F(LS_VERBOSE) << " state: " << state_ << " line: " - << std::string(line, len) << " len: " << len << " err: " - << error; - - switch (state_) { - case ST_LEADER: - state_ = ST_HEADERS; - return ProcessLeader(line, len, error); - - case ST_HEADERS: - if (len > 0) { - const char* value = strchrn(line, len, ':'); - if (!value) { - *error = HE_PROTOCOL; - return PR_COMPLETE; - } - size_t nlen = (value - line); - const char* eol = line + len; - do { - value += 1; - } while ((value < eol) && isspace(static_cast(*value))); - size_t vlen = eol - value; - if (MatchHeader(line, nlen, HH_CONTENT_LENGTH)) { - // sscanf isn't safe with strings that aren't null-terminated, and there - // is no guarantee that |value| is. - // Create a local copy that is null-terminated. - std::string value_str(value, vlen); - unsigned int temp_size; - if (sscanf(value_str.c_str(), "%u", &temp_size) != 1) { - *error = HE_PROTOCOL; - return PR_COMPLETE; - } - data_size_ = static_cast(temp_size); - } else if (MatchHeader(line, nlen, HH_TRANSFER_ENCODING)) { - if ((vlen == 7) && (_strnicmp(value, "chunked", 7) == 0)) { - chunked_ = true; - } else if ((vlen == 8) && (_strnicmp(value, "identity", 8) == 0)) { - chunked_ = false; - } else { - *error = HE_PROTOCOL; - return PR_COMPLETE; - } - } - return ProcessHeader(line, nlen, value, vlen, error); - } else { - state_ = chunked_ ? ST_CHUNKSIZE : ST_DATA; - return ProcessHeaderComplete(chunked_, data_size_, error); - } - break; - - case ST_CHUNKSIZE: - if (len > 0) { - char* ptr = NULL; - data_size_ = strtoul(line, &ptr, 16); - if (ptr != line + len) { - *error = HE_PROTOCOL; - return PR_COMPLETE; - } - state_ = (data_size_ == 0) ? ST_TRAILERS : ST_DATA; - } else { - *error = HE_PROTOCOL; - return PR_COMPLETE; - } - break; - - case ST_CHUNKTERM: - if (len > 0) { - *error = HE_PROTOCOL; - return PR_COMPLETE; - } else { - state_ = chunked_ ? ST_CHUNKSIZE : ST_DATA; - } - break; - - case ST_TRAILERS: - if (len == 0) { - return PR_COMPLETE; - } - // *error = onHttpRecvTrailer(); - break; - - default: - ASSERT(false); - break; - } - - return PR_CONTINUE; -} - -bool -HttpParser::is_valid_end_of_input() const { - return (state_ == ST_DATA) && (data_size_ == SIZE_UNKNOWN); -} - -void -HttpParser::complete(HttpError error) { - if (state_ < ST_COMPLETE) { - state_ = ST_COMPLETE; - OnComplete(error); - } -} - -////////////////////////////////////////////////////////////////////// -// HttpBase::DocumentStream -////////////////////////////////////////////////////////////////////// - -class BlockingMemoryStream : public ExternalMemoryStream { -public: - BlockingMemoryStream(char* buffer, size_t size) - : ExternalMemoryStream(buffer, size) { } - - virtual StreamResult DoReserve(size_t size, int* error) { - return (buffer_length_ >= size) ? SR_SUCCESS : SR_BLOCK; - } -}; - -class HttpBase::DocumentStream : public StreamInterface { -public: - DocumentStream(HttpBase* base) : base_(base), error_(HE_DEFAULT) { } - - virtual StreamState GetState() const { - if (NULL == base_) - return SS_CLOSED; - if (HM_RECV == base_->mode_) - return SS_OPEN; - return SS_OPENING; - } - - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - if (!base_) { - if (error) *error = error_; - return (HE_NONE == error_) ? SR_EOS : SR_ERROR; - } - - if (HM_RECV != base_->mode_) { - return SR_BLOCK; - } - - // DoReceiveLoop writes http document data to the StreamInterface* document - // member of HttpData. In this case, we want this data to be written - // directly to our buffer. To accomplish this, we wrap our buffer with a - // StreamInterface, and replace the existing document with our wrapper. - // When the method returns, we restore the old document. Ideally, we would - // pass our StreamInterface* to DoReceiveLoop, but due to the callbacks - // of HttpParser, we would still need to store the pointer temporarily. - scoped_ptr - stream(new BlockingMemoryStream(reinterpret_cast(buffer), - buffer_len)); - - // Replace the existing document with our wrapped buffer. - base_->data_->document.swap(stream); - - // Pump the I/O loop. DoReceiveLoop is guaranteed not to attempt to - // complete the I/O process, which means that our wrapper is not in danger - // of being deleted. To ensure this, DoReceiveLoop returns true when it - // wants complete to be called. We make sure to uninstall our wrapper - // before calling complete(). - HttpError http_error; - bool complete = base_->DoReceiveLoop(&http_error); - - // Reinstall the original output document. - base_->data_->document.swap(stream); - - // If we reach the end of the receive stream, we disconnect our stream - // adapter from the HttpBase, and further calls to read will either return - // EOS or ERROR, appropriately. Finally, we call complete(). - StreamResult result = SR_BLOCK; - if (complete) { - HttpBase* base = Disconnect(http_error); - if (error) *error = error_; - result = (HE_NONE == error_) ? SR_EOS : SR_ERROR; - base->complete(http_error); - } - - // Even if we are complete, if some data was read we must return SUCCESS. - // Future Reads will return EOS or ERROR based on the error_ variable. - size_t position; - stream->GetPosition(&position); - if (position > 0) { - if (read) *read = position; - result = SR_SUCCESS; - } - return result; - } - - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error) { - if (error) *error = -1; - return SR_ERROR; - } - - virtual void Close() { - if (base_) { - HttpBase* base = Disconnect(HE_NONE); - if (HM_RECV == base->mode_ && base->http_stream_) { - // Read I/O could have been stalled on the user of this DocumentStream, - // so restart the I/O process now that we've removed ourselves. - base->http_stream_->PostEvent(SE_READ, 0); - } - } - } - - virtual bool GetAvailable(size_t* size) const { - if (!base_ || HM_RECV != base_->mode_) - return false; - size_t data_size = base_->GetDataRemaining(); - if (SIZE_UNKNOWN == data_size) - return false; - if (size) - *size = data_size; - return true; - } - - HttpBase* Disconnect(HttpError error) { - ASSERT(NULL != base_); - ASSERT(NULL != base_->doc_stream_); - HttpBase* base = base_; - base_->doc_stream_ = NULL; - base_ = NULL; - error_ = error; - return base; - } - -private: - HttpBase* base_; - HttpError error_; -}; - -////////////////////////////////////////////////////////////////////// -// HttpBase -////////////////////////////////////////////////////////////////////// - -HttpBase::HttpBase() : mode_(HM_NONE), data_(NULL), notify_(NULL), - http_stream_(NULL), doc_stream_(NULL) { -} - -HttpBase::~HttpBase() { - ASSERT(HM_NONE == mode_); -} - -bool -HttpBase::isConnected() const { - return (http_stream_ != NULL) && (http_stream_->GetState() == SS_OPEN); -} - -bool -HttpBase::attach(StreamInterface* stream) { - if ((mode_ != HM_NONE) || (http_stream_ != NULL) || (stream == NULL)) { - ASSERT(false); - return false; - } - http_stream_ = stream; - http_stream_->SignalEvent.connect(this, &HttpBase::OnHttpStreamEvent); - mode_ = (http_stream_->GetState() == SS_OPENING) ? HM_CONNECT : HM_NONE; - return true; -} - -StreamInterface* -HttpBase::detach() { - ASSERT(HM_NONE == mode_); - if (mode_ != HM_NONE) { - return NULL; - } - StreamInterface* stream = http_stream_; - http_stream_ = NULL; - if (stream) { - stream->SignalEvent.disconnect(this); - } - return stream; -} - -void -HttpBase::send(HttpData* data) { - ASSERT(HM_NONE == mode_); - if (mode_ != HM_NONE) { - return; - } else if (!isConnected()) { - OnHttpStreamEvent(http_stream_, SE_CLOSE, HE_DISCONNECTED); - return; - } - - mode_ = HM_SEND; - data_ = data; - len_ = 0; - ignore_data_ = chunk_data_ = false; - - if (data_->document) { - data_->document->SignalEvent.connect(this, &HttpBase::OnDocumentEvent); - } - - std::string encoding; - if (data_->hasHeader(HH_TRANSFER_ENCODING, &encoding) - && (encoding == "chunked")) { - chunk_data_ = true; - } - - len_ = data_->formatLeader(buffer_, sizeof(buffer_)); - len_ += strcpyn(buffer_ + len_, sizeof(buffer_) - len_, "\r\n"); - - header_ = data_->begin(); - if (header_ == data_->end()) { - // We must call this at least once, in the case where there are no headers. - queue_headers(); - } - - flush_data(); -} - -void -HttpBase::recv(HttpData* data) { - ASSERT(HM_NONE == mode_); - if (mode_ != HM_NONE) { - return; - } else if (!isConnected()) { - OnHttpStreamEvent(http_stream_, SE_CLOSE, HE_DISCONNECTED); - return; - } - - mode_ = HM_RECV; - data_ = data; - len_ = 0; - ignore_data_ = chunk_data_ = false; - - reset(); - if (doc_stream_) { - doc_stream_->SignalEvent(doc_stream_, SE_OPEN | SE_READ, 0); - } else { - read_and_process_data(); - } -} - -void -HttpBase::abort(HttpError err) { - if (mode_ != HM_NONE) { - if (http_stream_ != NULL) { - http_stream_->Close(); - } - do_complete(err); - } -} - -StreamInterface* HttpBase::GetDocumentStream() { - if (doc_stream_) - return NULL; - doc_stream_ = new DocumentStream(this); - return doc_stream_; -} - -HttpError HttpBase::HandleStreamClose(int error) { - if (http_stream_ != NULL) { - http_stream_->Close(); - } - if (error == 0) { - if ((mode_ == HM_RECV) && is_valid_end_of_input()) { - return HE_NONE; - } else { - return HE_DISCONNECTED; - } - } else if (error == SOCKET_EACCES) { - return HE_AUTH; - } else if (error == SEC_E_CERT_EXPIRED) { - return HE_CERTIFICATE_EXPIRED; - } - LOG_F(LS_ERROR) << "(" << error << ")"; - return (HM_CONNECT == mode_) ? HE_CONNECT_FAILED : HE_SOCKET_ERROR; -} - -bool HttpBase::DoReceiveLoop(HttpError* error) { - ASSERT(HM_RECV == mode_); - ASSERT(NULL != error); - - // Do to the latency between receiving read notifications from - // pseudotcpchannel, we rely on repeated calls to read in order to acheive - // ideal throughput. The number of reads is limited to prevent starving - // the caller. - - size_t loop_count = 0; - const size_t kMaxReadCount = 20; - bool process_requires_more_data = false; - do { - // The most frequent use of this function is response to new data available - // on http_stream_. Therefore, we optimize by attempting to read from the - // network first (as opposed to processing existing data first). - - if (len_ < sizeof(buffer_)) { - // Attempt to buffer more data. - size_t read; - int read_error; - StreamResult read_result = http_stream_->Read(buffer_ + len_, - sizeof(buffer_) - len_, - &read, &read_error); - switch (read_result) { - case SR_SUCCESS: - ASSERT(len_ + read <= sizeof(buffer_)); - len_ += read; - break; - case SR_BLOCK: - if (process_requires_more_data) { - // We're can't make progress until more data is available. - return false; - } - // Attempt to process the data already in our buffer. - break; - case SR_EOS: - // Clean close, with no error. Fall through to HandleStreamClose. - read_error = 0; - case SR_ERROR: - *error = HandleStreamClose(read_error); - return true; - } - } else if (process_requires_more_data) { - // We have too much unprocessed data in our buffer. This should only - // occur when a single HTTP header is longer than the buffer size (32K). - // Anything longer than that is almost certainly an error. - *error = HE_OVERFLOW; - return true; - } - - // Process data in our buffer. Process is not guaranteed to process all - // the buffered data. In particular, it will wait until a complete - // protocol element (such as http header, or chunk size) is available, - // before processing it in its entirety. Also, it is valid and sometimes - // necessary to call Process with an empty buffer, since the state machine - // may have interrupted state transitions to complete. - size_t processed; - ProcessResult process_result = Process(buffer_, len_, &processed, - error); - ASSERT(processed <= len_); - len_ -= processed; - memmove(buffer_, buffer_ + processed, len_); - switch (process_result) { - case PR_CONTINUE: - // We need more data to make progress. - process_requires_more_data = true; - break; - case PR_BLOCK: - // We're stalled on writing the processed data. - return false; - case PR_COMPLETE: - // *error already contains the correct code. - return true; - } - } while (++loop_count <= kMaxReadCount); - - LOG_F(LS_WARNING) << "danger of starvation"; - return false; -} - -void -HttpBase::read_and_process_data() { - HttpError error; - if (DoReceiveLoop(&error)) { - complete(error); - } -} - -void -HttpBase::flush_data() { - ASSERT(HM_SEND == mode_); - - // When send_required is true, no more buffering can occur without a network - // write. - bool send_required = (len_ >= sizeof(buffer_)); - - while (true) { - ASSERT(len_ <= sizeof(buffer_)); - - // HTTP is inherently sensitive to round trip latency, since a frequent use - // case is for small requests and responses to be sent back and forth, and - // the lack of pipelining forces a single request to take a minimum of the - // round trip time. As a result, it is to our benefit to pack as much data - // into each packet as possible. Thus, we defer network writes until we've - // buffered as much data as possible. - - if (!send_required && (header_ != data_->end())) { - // First, attempt to queue more header data. - send_required = queue_headers(); - } - - if (!send_required && data_->document) { - // Next, attempt to queue document data. - - const size_t kChunkDigits = 8; - size_t offset, reserve; - if (chunk_data_) { - // Reserve characters at the start for X-byte hex value and \r\n - offset = len_ + kChunkDigits + 2; - // ... and 2 characters at the end for \r\n - reserve = offset + 2; - } else { - offset = len_; - reserve = offset; - } - - if (reserve >= sizeof(buffer_)) { - send_required = true; - } else { - size_t read; - int error; - StreamResult result = data_->document->Read(buffer_ + offset, - sizeof(buffer_) - reserve, - &read, &error); - if (result == SR_SUCCESS) { - ASSERT(reserve + read <= sizeof(buffer_)); - if (chunk_data_) { - // Prepend the chunk length in hex. - // Note: sprintfn appends a null terminator, which is why we can't - // combine it with the line terminator. - sprintfn(buffer_ + len_, kChunkDigits + 1, "%.*x", - kChunkDigits, read); - // Add line terminator to the chunk length. - memcpy(buffer_ + len_ + kChunkDigits, "\r\n", 2); - // Add line terminator to the end of the chunk. - memcpy(buffer_ + offset + read, "\r\n", 2); - } - len_ = reserve + read; - } else if (result == SR_BLOCK) { - // Nothing to do but flush data to the network. - send_required = true; - } else if (result == SR_EOS) { - if (chunk_data_) { - // Append the empty chunk and empty trailers, then turn off - // chunking. - ASSERT(len_ + 5 <= sizeof(buffer_)); - memcpy(buffer_ + len_, "0\r\n\r\n", 5); - len_ += 5; - chunk_data_ = false; - } else if (0 == len_) { - // No more data to read, and no more data to write. - do_complete(); - return; - } - // Although we are done reading data, there is still data which needs - // to be flushed to the network. - send_required = true; - } else { - LOG_F(LS_ERROR) << "Read error: " << error; - do_complete(HE_STREAM); - return; - } - } - } - - if (0 == len_) { - // No data currently available to send. - if (!data_->document) { - // If there is no source document, that means we're done. - do_complete(); - } - return; - } - - size_t written; - int error; - StreamResult result = http_stream_->Write(buffer_, len_, &written, &error); - if (result == SR_SUCCESS) { - ASSERT(written <= len_); - len_ -= written; - memmove(buffer_, buffer_ + written, len_); - send_required = false; - } else if (result == SR_BLOCK) { - if (send_required) { - // Nothing more we can do until network is writeable. - return; - } - } else { - ASSERT(result == SR_ERROR); - LOG_F(LS_ERROR) << "error"; - OnHttpStreamEvent(http_stream_, SE_CLOSE, error); - return; - } - } - - ASSERT(false); -} - -bool -HttpBase::queue_headers() { - ASSERT(HM_SEND == mode_); - while (header_ != data_->end()) { - size_t len = sprintfn(buffer_ + len_, sizeof(buffer_) - len_, - "%.*s: %.*s\r\n", - header_->first.size(), header_->first.data(), - header_->second.size(), header_->second.data()); - if (len_ + len < sizeof(buffer_) - 3) { - len_ += len; - ++header_; - } else if (len_ == 0) { - LOG(WARNING) << "discarding header that is too long: " << header_->first; - ++header_; - } else { - // Not enough room for the next header, write to network first. - return true; - } - } - // End of headers - len_ += strcpyn(buffer_ + len_, sizeof(buffer_) - len_, "\r\n"); - return false; -} - -void -HttpBase::do_complete(HttpError err) { - ASSERT(mode_ != HM_NONE); - HttpMode mode = mode_; - mode_ = HM_NONE; - if (data_ && data_->document) { - data_->document->SignalEvent.disconnect(this); - } - data_ = NULL; - if ((HM_RECV == mode) && doc_stream_) { - ASSERT(HE_NONE != err); // We should have Disconnected doc_stream_ already. - DocumentStream* ds = doc_stream_; - ds->Disconnect(err); - ds->SignalEvent(ds, SE_CLOSE, err); - } - if (notify_) { - notify_->onHttpComplete(mode, err); - } -} - -// -// Stream Signals -// - -void -HttpBase::OnHttpStreamEvent(StreamInterface* stream, int events, int error) { - ASSERT(stream == http_stream_); - if ((events & SE_OPEN) && (mode_ == HM_CONNECT)) { - do_complete(); - return; - } - - if ((events & SE_WRITE) && (mode_ == HM_SEND)) { - flush_data(); - return; - } - - if ((events & SE_READ) && (mode_ == HM_RECV)) { - if (doc_stream_) { - doc_stream_->SignalEvent(doc_stream_, SE_READ, 0); - } else { - read_and_process_data(); - } - return; - } - - if ((events & SE_CLOSE) == 0) - return; - - HttpError http_error = HandleStreamClose(error); - if (mode_ == HM_RECV) { - complete(http_error); - } else if (mode_ != HM_NONE) { - do_complete(http_error); - } else if (notify_) { - notify_->onHttpClosed(http_error); - } -} - -void -HttpBase::OnDocumentEvent(StreamInterface* stream, int events, int error) { - ASSERT(stream == data_->document.get()); - if ((events & SE_WRITE) && (mode_ == HM_RECV)) { - read_and_process_data(); - return; - } - - if ((events & SE_READ) && (mode_ == HM_SEND)) { - flush_data(); - return; - } - - if (events & SE_CLOSE) { - LOG_F(LS_ERROR) << "Read error: " << error; - do_complete(HE_STREAM); - return; - } -} - -// -// HttpParser Implementation -// - -HttpParser::ProcessResult -HttpBase::ProcessLeader(const char* line, size_t len, HttpError* error) { - *error = data_->parseLeader(line, len); - return (HE_NONE == *error) ? PR_CONTINUE : PR_COMPLETE; -} - -HttpParser::ProcessResult -HttpBase::ProcessHeader(const char* name, size_t nlen, const char* value, - size_t vlen, HttpError* error) { - std::string sname(name, nlen), svalue(value, vlen); - data_->addHeader(sname, svalue); - return PR_CONTINUE; -} - -HttpParser::ProcessResult -HttpBase::ProcessHeaderComplete(bool chunked, size_t& data_size, - HttpError* error) { - StreamInterface* old_docstream = doc_stream_; - if (notify_) { - *error = notify_->onHttpHeaderComplete(chunked, data_size); - // The request must not be aborted as a result of this callback. - ASSERT(NULL != data_); - } - if ((HE_NONE == *error) && data_->document) { - data_->document->SignalEvent.connect(this, &HttpBase::OnDocumentEvent); - } - if (HE_NONE != *error) { - return PR_COMPLETE; - } - if (old_docstream != doc_stream_) { - // Break out of Process loop, since our I/O model just changed. - return PR_BLOCK; - } - return PR_CONTINUE; -} - -HttpParser::ProcessResult -HttpBase::ProcessData(const char* data, size_t len, size_t& read, - HttpError* error) { - if (ignore_data_ || !data_->document) { - read = len; - return PR_CONTINUE; - } - int write_error = 0; - switch (data_->document->Write(data, len, &read, &write_error)) { - case SR_SUCCESS: - return PR_CONTINUE; - case SR_BLOCK: - return PR_BLOCK; - case SR_EOS: - LOG_F(LS_ERROR) << "Unexpected EOS"; - *error = HE_STREAM; - return PR_COMPLETE; - case SR_ERROR: - default: - LOG_F(LS_ERROR) << "Write error: " << write_error; - *error = HE_STREAM; - return PR_COMPLETE; - } -} - -void -HttpBase::OnComplete(HttpError err) { - LOG_F(LS_VERBOSE); - do_complete(err); -} - -} // namespace rtc diff --git a/webrtc/base/httpbase.h b/webrtc/base/httpbase.h deleted file mode 100644 index 424a61f9f..000000000 --- a/webrtc/base/httpbase.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -#ifndef WEBRTC_BASE_HTTPBASE_H__ -#define WEBRTC_BASE_HTTPBASE_H__ - -#include "webrtc/base/httpcommon.h" - -namespace rtc { - -class StreamInterface; - -/////////////////////////////////////////////////////////////////////////////// -// HttpParser - Parses an HTTP stream provided via Process and end_of_input, and -// generates events for: -// Structural Elements: Leader, Headers, Document Data -// Events: End of Headers, End of Document, Errors -/////////////////////////////////////////////////////////////////////////////// - -class HttpParser { -public: - enum ProcessResult { PR_CONTINUE, PR_BLOCK, PR_COMPLETE }; - HttpParser(); - virtual ~HttpParser(); - - void reset(); - ProcessResult Process(const char* buffer, size_t len, size_t* processed, - HttpError* error); - bool is_valid_end_of_input() const; - void complete(HttpError err); - - size_t GetDataRemaining() const { return data_size_; } - -protected: - ProcessResult ProcessLine(const char* line, size_t len, HttpError* error); - - // HttpParser Interface - virtual ProcessResult ProcessLeader(const char* line, size_t len, - HttpError* error) = 0; - virtual ProcessResult ProcessHeader(const char* name, size_t nlen, - const char* value, size_t vlen, - HttpError* error) = 0; - virtual ProcessResult ProcessHeaderComplete(bool chunked, size_t& data_size, - HttpError* error) = 0; - virtual ProcessResult ProcessData(const char* data, size_t len, size_t& read, - HttpError* error) = 0; - virtual void OnComplete(HttpError err) = 0; - -private: - enum State { - ST_LEADER, ST_HEADERS, - ST_CHUNKSIZE, ST_CHUNKTERM, ST_TRAILERS, - ST_DATA, ST_COMPLETE - } state_; - bool chunked_; - size_t data_size_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// IHttpNotify -/////////////////////////////////////////////////////////////////////////////// - -enum HttpMode { HM_NONE, HM_CONNECT, HM_RECV, HM_SEND }; - -class IHttpNotify { -public: - virtual ~IHttpNotify() {} - virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) = 0; - virtual void onHttpComplete(HttpMode mode, HttpError err) = 0; - virtual void onHttpClosed(HttpError err) = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// -// HttpBase - Provides a state machine for implementing HTTP-based components. -// Attach HttpBase to a StreamInterface which represents a bidirectional HTTP -// stream, and then call send() or recv() to initiate sending or receiving one -// side of an HTTP transaction. By default, HttpBase operates as an I/O pump, -// moving data from the HTTP stream to the HttpData object and vice versa. -// However, it can also operate in stream mode, in which case the user of the -// stream interface drives I/O via calls to Read(). -/////////////////////////////////////////////////////////////////////////////// - -class HttpBase -: private HttpParser, - public sigslot::has_slots<> -{ -public: - HttpBase(); - virtual ~HttpBase(); - - void notify(IHttpNotify* notify) { notify_ = notify; } - bool attach(StreamInterface* stream); - StreamInterface* stream() { return http_stream_; } - StreamInterface* detach(); - bool isConnected() const; - - void send(HttpData* data); - void recv(HttpData* data); - void abort(HttpError err); - - HttpMode mode() const { return mode_; } - - void set_ignore_data(bool ignore) { ignore_data_ = ignore; } - bool ignore_data() const { return ignore_data_; } - - // Obtaining this stream puts HttpBase into stream mode until the stream - // is closed. HttpBase can only expose one open stream interface at a time. - // Further calls will return NULL. - StreamInterface* GetDocumentStream(); - -protected: - // Do cleanup when the http stream closes (error may be 0 for a clean - // shutdown), and return the error code to signal. - HttpError HandleStreamClose(int error); - - // DoReceiveLoop acts as a data pump, pulling data from the http stream, - // pushing it through the HttpParser, and then populating the HttpData object - // based on the callbacks from the parser. One of the most interesting - // callbacks is ProcessData, which provides the actual http document body. - // This data is then written to the HttpData::document. As a result, data - // flows from the network to the document, with some incidental protocol - // parsing in between. - // Ideally, we would pass in the document* to DoReceiveLoop, to more easily - // support GetDocumentStream(). However, since the HttpParser is callback - // driven, we are forced to store the pointer somewhere until the callback - // is triggered. - // Returns true if the received document has finished, and - // HttpParser::complete should be called. - bool DoReceiveLoop(HttpError* err); - - void read_and_process_data(); - void flush_data(); - bool queue_headers(); - void do_complete(HttpError err = HE_NONE); - - void OnHttpStreamEvent(StreamInterface* stream, int events, int error); - void OnDocumentEvent(StreamInterface* stream, int events, int error); - - // HttpParser Interface - virtual ProcessResult ProcessLeader(const char* line, size_t len, - HttpError* error); - virtual ProcessResult ProcessHeader(const char* name, size_t nlen, - const char* value, size_t vlen, - HttpError* error); - virtual ProcessResult ProcessHeaderComplete(bool chunked, size_t& data_size, - HttpError* error); - virtual ProcessResult ProcessData(const char* data, size_t len, size_t& read, - HttpError* error); - virtual void OnComplete(HttpError err); - -private: - class DocumentStream; - friend class DocumentStream; - - enum { kBufferSize = 32 * 1024 }; - - HttpMode mode_; - HttpData* data_; - IHttpNotify* notify_; - StreamInterface* http_stream_; - DocumentStream* doc_stream_; - char buffer_[kBufferSize]; - size_t len_; - - bool ignore_data_, chunk_data_; - HttpData::const_iterator header_; -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_HTTPBASE_H__ diff --git a/webrtc/base/httpbase_unittest.cc b/webrtc/base/httpbase_unittest.cc deleted file mode 100644 index 6dab0c9ac..000000000 --- a/webrtc/base/httpbase_unittest.cc +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/httpbase.h" -#include "webrtc/base/testutils.h" - -namespace rtc { - -const char* const kHttpResponse = - "HTTP/1.1 200\r\n" - "Connection: Keep-Alive\r\n" - "Content-Type: text/plain\r\n" - "Proxy-Authorization: 42\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n" - "00000008\r\n" - "Goodbye!\r\n" - "0\r\n\r\n"; - -const char* const kHttpEmptyResponse = - "HTTP/1.1 200\r\n" - "Connection: Keep-Alive\r\n" - "Content-Length: 0\r\n" - "Proxy-Authorization: 42\r\n" - "\r\n"; - -const char* const kHttpResponsePrefix = - "HTTP/1.1 200\r\n" - "Connection: Keep-Alive\r\n" - "Content-Type: text/plain\r\n" - "Proxy-Authorization: 42\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n" - "8\r\n" - "Goodbye!\r\n"; - -class HttpBaseTest : public testing::Test, public IHttpNotify { -public: - enum EventType { E_HEADER_COMPLETE, E_COMPLETE, E_CLOSED }; - struct Event { - EventType event; - bool chunked; - size_t data_size; - HttpMode mode; - HttpError err; - }; - HttpBaseTest() : mem(NULL), obtain_stream(false), http_stream(NULL) { } - - virtual void SetUp() { } - virtual void TearDown() { - delete http_stream; - // Avoid an ASSERT, in case a test doesn't clean up properly - base.abort(HE_NONE); - } - - virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) { - LOG_F(LS_VERBOSE) << "chunked: " << chunked << " size: " << data_size; - Event e = { E_HEADER_COMPLETE, chunked, data_size, HM_NONE, HE_NONE}; - events.push_back(e); - if (obtain_stream) { - ObtainDocumentStream(); - } - return HE_NONE; - } - virtual void onHttpComplete(HttpMode mode, HttpError err) { - LOG_F(LS_VERBOSE) << "mode: " << mode << " err: " << err; - Event e = { E_COMPLETE, false, 0, mode, err }; - events.push_back(e); - } - virtual void onHttpClosed(HttpError err) { - LOG_F(LS_VERBOSE) << "err: " << err; - Event e = { E_CLOSED, false, 0, HM_NONE, err }; - events.push_back(e); - } - - void SetupSource(const char* response); - - void VerifyHeaderComplete(size_t event_count, bool empty_doc); - void VerifyDocumentContents(const char* expected_data, - size_t expected_length = SIZE_UNKNOWN); - - void ObtainDocumentStream(); - void VerifyDocumentStreamIsOpening(); - void VerifyDocumentStreamOpenEvent(); - void ReadDocumentStreamData(const char* expected_data); - void VerifyDocumentStreamIsEOS(); - - void SetupDocument(const char* response); - void VerifySourceContents(const char* expected_data, - size_t expected_length = SIZE_UNKNOWN); - - void VerifyTransferComplete(HttpMode mode, HttpError error); - - HttpBase base; - MemoryStream* mem; - HttpResponseData data; - - // The source of http data, and source events - testing::StreamSource src; - std::vector events; - - // Document stream, and stream events - bool obtain_stream; - StreamInterface* http_stream; - testing::StreamSink sink; -}; - -void HttpBaseTest::SetupSource(const char* http_data) { - LOG_F(LS_VERBOSE) << "Enter"; - - src.SetState(SS_OPENING); - src.QueueString(http_data); - - base.notify(this); - base.attach(&src); - EXPECT_TRUE(events.empty()); - - src.SetState(SS_OPEN); - ASSERT_EQ(1U, events.size()); - EXPECT_EQ(E_COMPLETE, events[0].event); - EXPECT_EQ(HM_CONNECT, events[0].mode); - EXPECT_EQ(HE_NONE, events[0].err); - events.clear(); - - mem = new MemoryStream; - data.document.reset(mem); - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::VerifyHeaderComplete(size_t event_count, bool empty_doc) { - LOG_F(LS_VERBOSE) << "Enter"; - - ASSERT_EQ(event_count, events.size()); - EXPECT_EQ(E_HEADER_COMPLETE, events[0].event); - - std::string header; - EXPECT_EQ(HVER_1_1, data.version); - EXPECT_EQ(static_cast(HC_OK), data.scode); - EXPECT_TRUE(data.hasHeader(HH_PROXY_AUTHORIZATION, &header)); - EXPECT_EQ("42", header); - EXPECT_TRUE(data.hasHeader(HH_CONNECTION, &header)); - EXPECT_EQ("Keep-Alive", header); - - if (empty_doc) { - EXPECT_FALSE(events[0].chunked); - EXPECT_EQ(0U, events[0].data_size); - - EXPECT_TRUE(data.hasHeader(HH_CONTENT_LENGTH, &header)); - EXPECT_EQ("0", header); - } else { - EXPECT_TRUE(events[0].chunked); - EXPECT_EQ(SIZE_UNKNOWN, events[0].data_size); - - EXPECT_TRUE(data.hasHeader(HH_CONTENT_TYPE, &header)); - EXPECT_EQ("text/plain", header); - EXPECT_TRUE(data.hasHeader(HH_TRANSFER_ENCODING, &header)); - EXPECT_EQ("chunked", header); - } - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::VerifyDocumentContents(const char* expected_data, - size_t expected_length) { - LOG_F(LS_VERBOSE) << "Enter"; - - if (SIZE_UNKNOWN == expected_length) { - expected_length = strlen(expected_data); - } - EXPECT_EQ(mem, data.document.get()); - - size_t length; - mem->GetSize(&length); - EXPECT_EQ(expected_length, length); - EXPECT_TRUE(0 == memcmp(expected_data, mem->GetBuffer(), length)); - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::ObtainDocumentStream() { - LOG_F(LS_VERBOSE) << "Enter"; - EXPECT_FALSE(http_stream); - http_stream = base.GetDocumentStream(); - ASSERT_TRUE(NULL != http_stream); - sink.Monitor(http_stream); - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::VerifyDocumentStreamIsOpening() { - LOG_F(LS_VERBOSE) << "Enter"; - ASSERT_TRUE(NULL != http_stream); - EXPECT_EQ(0, sink.Events(http_stream)); - EXPECT_EQ(SS_OPENING, http_stream->GetState()); - - size_t read = 0; - char buffer[5] = { 0 }; - EXPECT_EQ(SR_BLOCK, http_stream->Read(buffer, sizeof(buffer), &read, NULL)); - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::VerifyDocumentStreamOpenEvent() { - LOG_F(LS_VERBOSE) << "Enter"; - - ASSERT_TRUE(NULL != http_stream); - EXPECT_EQ(SE_OPEN | SE_READ, sink.Events(http_stream)); - EXPECT_EQ(SS_OPEN, http_stream->GetState()); - - // HTTP headers haven't arrived yet - EXPECT_EQ(0U, events.size()); - EXPECT_EQ(static_cast(HC_INTERNAL_SERVER_ERROR), data.scode); - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::ReadDocumentStreamData(const char* expected_data) { - LOG_F(LS_VERBOSE) << "Enter"; - - ASSERT_TRUE(NULL != http_stream); - EXPECT_EQ(SS_OPEN, http_stream->GetState()); - - // Pump the HTTP I/O using Read, and verify the results. - size_t verified_length = 0; - const size_t expected_length = strlen(expected_data); - while (verified_length < expected_length) { - size_t read = 0; - char buffer[5] = { 0 }; - size_t amt_to_read = _min(expected_length - verified_length, sizeof(buffer)); - EXPECT_EQ(SR_SUCCESS, http_stream->Read(buffer, amt_to_read, &read, NULL)); - EXPECT_EQ(amt_to_read, read); - EXPECT_TRUE(0 == memcmp(expected_data + verified_length, buffer, read)); - verified_length += read; - } - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::VerifyDocumentStreamIsEOS() { - LOG_F(LS_VERBOSE) << "Enter"; - - ASSERT_TRUE(NULL != http_stream); - size_t read = 0; - char buffer[5] = { 0 }; - EXPECT_EQ(SR_EOS, http_stream->Read(buffer, sizeof(buffer), &read, NULL)); - EXPECT_EQ(SS_CLOSED, http_stream->GetState()); - - // When EOS is caused by Read, we don't expect SE_CLOSE - EXPECT_EQ(0, sink.Events(http_stream)); - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::SetupDocument(const char* document_data) { - LOG_F(LS_VERBOSE) << "Enter"; - src.SetState(SS_OPEN); - - base.notify(this); - base.attach(&src); - EXPECT_TRUE(events.empty()); - - if (document_data) { - // Note: we could just call data.set_success("text/plain", mem), but that - // won't allow us to use the chunked transfer encoding. - mem = new MemoryStream(document_data); - data.document.reset(mem); - data.setHeader(HH_CONTENT_TYPE, "text/plain"); - data.setHeader(HH_TRANSFER_ENCODING, "chunked"); - } else { - data.setHeader(HH_CONTENT_LENGTH, "0"); - } - data.scode = HC_OK; - data.setHeader(HH_PROXY_AUTHORIZATION, "42"); - data.setHeader(HH_CONNECTION, "Keep-Alive"); - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::VerifySourceContents(const char* expected_data, - size_t expected_length) { - LOG_F(LS_VERBOSE) << "Enter"; - if (SIZE_UNKNOWN == expected_length) { - expected_length = strlen(expected_data); - } - std::string contents = src.ReadData(); - EXPECT_EQ(expected_length, contents.length()); - EXPECT_TRUE(0 == memcmp(expected_data, contents.data(), expected_length)); - LOG_F(LS_VERBOSE) << "Exit"; -} - -void HttpBaseTest::VerifyTransferComplete(HttpMode mode, HttpError error) { - LOG_F(LS_VERBOSE) << "Enter"; - // Verify that http operation has completed - ASSERT_TRUE(events.size() > 0); - size_t last_event = events.size() - 1; - EXPECT_EQ(E_COMPLETE, events[last_event].event); - EXPECT_EQ(mode, events[last_event].mode); - EXPECT_EQ(error, events[last_event].err); - LOG_F(LS_VERBOSE) << "Exit"; -} - -// -// Tests -// - -TEST_F(HttpBaseTest, SupportsSend) { - // Queue response document - SetupDocument("Goodbye!"); - - // Begin send - base.send(&data); - - // Send completed successfully - VerifyTransferComplete(HM_SEND, HE_NONE); - VerifySourceContents(kHttpResponse); -} - -TEST_F(HttpBaseTest, SupportsSendNoDocument) { - // Queue response document - SetupDocument(NULL); - - // Begin send - base.send(&data); - - // Send completed successfully - VerifyTransferComplete(HM_SEND, HE_NONE); - VerifySourceContents(kHttpEmptyResponse); -} - -TEST_F(HttpBaseTest, SignalsCompleteOnInterruptedSend) { - // This test is attempting to expose a bug that occurs when a particular - // base objects is used for receiving, and then used for sending. In - // particular, the HttpParser state is different after receiving. Simulate - // that here. - SetupSource(kHttpResponse); - base.recv(&data); - VerifyTransferComplete(HM_RECV, HE_NONE); - - src.Clear(); - data.clear(true); - events.clear(); - base.detach(); - - // Queue response document - SetupDocument("Goodbye!"); - - // Prevent entire response from being sent - const size_t kInterruptedLength = strlen(kHttpResponse) - 1; - src.SetWriteBlock(kInterruptedLength); - - // Begin send - base.send(&data); - - // Document is mostly complete, but no completion signal yet. - EXPECT_TRUE(events.empty()); - VerifySourceContents(kHttpResponse, kInterruptedLength); - - src.SetState(SS_CLOSED); - - // Send completed with disconnect error, and no additional data. - VerifyTransferComplete(HM_SEND, HE_DISCONNECTED); - EXPECT_TRUE(src.ReadData().empty()); -} - -TEST_F(HttpBaseTest, SupportsReceiveViaDocumentPush) { - // Queue response document - SetupSource(kHttpResponse); - - // Begin receive - base.recv(&data); - - // Document completed successfully - VerifyHeaderComplete(2, false); - VerifyTransferComplete(HM_RECV, HE_NONE); - VerifyDocumentContents("Goodbye!"); -} - -TEST_F(HttpBaseTest, SupportsReceiveViaStreamPull) { - // Switch to pull mode - ObtainDocumentStream(); - VerifyDocumentStreamIsOpening(); - - // Queue response document - SetupSource(kHttpResponse); - VerifyDocumentStreamIsOpening(); - - // Begin receive - base.recv(&data); - - // Pull document data - VerifyDocumentStreamOpenEvent(); - ReadDocumentStreamData("Goodbye!"); - VerifyDocumentStreamIsEOS(); - - // Document completed successfully - VerifyHeaderComplete(2, false); - VerifyTransferComplete(HM_RECV, HE_NONE); - VerifyDocumentContents(""); -} - -TEST_F(HttpBaseTest, DISABLED_AllowsCloseStreamBeforeDocumentIsComplete) { - - // TODO: Remove extra logging once test failure is understood - int old_sev = rtc::LogMessage::GetLogToDebug(); - rtc::LogMessage::LogToDebug(LS_VERBOSE); - - - // Switch to pull mode - ObtainDocumentStream(); - VerifyDocumentStreamIsOpening(); - - // Queue response document - SetupSource(kHttpResponse); - VerifyDocumentStreamIsOpening(); - - // Begin receive - base.recv(&data); - - // Pull some of the data - VerifyDocumentStreamOpenEvent(); - ReadDocumentStreamData("Goodb"); - - // We've seen the header by now - VerifyHeaderComplete(1, false); - - // Close the pull stream, this will transition back to push I/O. - http_stream->Close(); - Thread::Current()->ProcessMessages(0); - - // Remainder of document completed successfully - VerifyTransferComplete(HM_RECV, HE_NONE); - VerifyDocumentContents("ye!"); - - rtc::LogMessage::LogToDebug(old_sev); -} - -TEST_F(HttpBaseTest, AllowsGetDocumentStreamInResponseToHttpHeader) { - // Queue response document - SetupSource(kHttpResponse); - - // Switch to pull mode in response to header arrival - obtain_stream = true; - - // Begin receive - base.recv(&data); - - // We've already seen the header, but not data has arrived - VerifyHeaderComplete(1, false); - VerifyDocumentContents(""); - - // Pull the document data - ReadDocumentStreamData("Goodbye!"); - VerifyDocumentStreamIsEOS(); - - // Document completed successfully - VerifyTransferComplete(HM_RECV, HE_NONE); - VerifyDocumentContents(""); -} - -TEST_F(HttpBaseTest, AllowsGetDocumentStreamWithEmptyDocumentBody) { - // Queue empty response document - SetupSource(kHttpEmptyResponse); - - // Switch to pull mode in response to header arrival - obtain_stream = true; - - // Begin receive - base.recv(&data); - - // We've already seen the header, but not data has arrived - VerifyHeaderComplete(1, true); - VerifyDocumentContents(""); - - // The document is still open, until we attempt to read - ASSERT_TRUE(NULL != http_stream); - EXPECT_EQ(SS_OPEN, http_stream->GetState()); - - // Attempt to read data, and discover EOS - VerifyDocumentStreamIsEOS(); - - // Document completed successfully - VerifyTransferComplete(HM_RECV, HE_NONE); - VerifyDocumentContents(""); -} - -TEST_F(HttpBaseTest, SignalsDocumentStreamCloseOnUnexpectedClose) { - // Switch to pull mode - ObtainDocumentStream(); - VerifyDocumentStreamIsOpening(); - - // Queue response document - SetupSource(kHttpResponsePrefix); - VerifyDocumentStreamIsOpening(); - - // Begin receive - base.recv(&data); - - // Pull document data - VerifyDocumentStreamOpenEvent(); - ReadDocumentStreamData("Goodbye!"); - - // Simulate unexpected close - src.SetState(SS_CLOSED); - - // Observe error event on document stream - EXPECT_EQ(testing::SSE_ERROR, sink.Events(http_stream)); - - // Future reads give an error - int error = 0; - char buffer[5] = { 0 }; - EXPECT_EQ(SR_ERROR, http_stream->Read(buffer, sizeof(buffer), NULL, &error)); - EXPECT_EQ(HE_DISCONNECTED, error); - - // Document completed with error - VerifyHeaderComplete(2, false); - VerifyTransferComplete(HM_RECV, HE_DISCONNECTED); - VerifyDocumentContents(""); -} - -} // namespace rtc diff --git a/webrtc/base/httpclient.cc b/webrtc/base/httpclient.cc deleted file mode 100644 index 625677210..000000000 --- a/webrtc/base/httpclient.cc +++ /dev/null @@ -1,829 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/httpcommon-inl.h" - -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/common.h" -#include "webrtc/base/diskcache.h" -#include "webrtc/base/httpclient.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/socketstream.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -////////////////////////////////////////////////////////////////////// -// Helpers -////////////////////////////////////////////////////////////////////// - -namespace { - -const size_t kCacheHeader = 0; -const size_t kCacheBody = 1; - -// Convert decimal string to integer -bool HttpStringToUInt(const std::string& str, size_t* val) { - ASSERT(NULL != val); - char* eos = NULL; - *val = strtoul(str.c_str(), &eos, 10); - return (*eos == '\0'); -} - -bool HttpShouldCache(const HttpTransaction& t) { - bool verb_allows_cache = (t.request.verb == HV_GET) - || (t.request.verb == HV_HEAD); - bool is_range_response = t.response.hasHeader(HH_CONTENT_RANGE, NULL); - bool has_expires = t.response.hasHeader(HH_EXPIRES, NULL); - bool request_allows_cache = - has_expires || (std::string::npos != t.request.path.find('?')); - bool response_allows_cache = - has_expires || HttpCodeIsCacheable(t.response.scode); - - bool may_cache = verb_allows_cache - && request_allows_cache - && response_allows_cache - && !is_range_response; - - std::string value; - if (t.response.hasHeader(HH_CACHE_CONTROL, &value)) { - HttpAttributeList directives; - HttpParseAttributes(value.data(), value.size(), directives); - // Response Directives Summary: - // public - always cacheable - // private - do not cache in a shared cache - // no-cache - may cache, but must revalidate whether fresh or stale - // no-store - sensitive information, do not cache or store in any way - // max-age - supplants Expires for staleness - // s-maxage - use as max-age for shared caches, ignore otherwise - // must-revalidate - may cache, but must revalidate after stale - // proxy-revalidate - shared cache must revalidate - if (HttpHasAttribute(directives, "no-store", NULL)) { - may_cache = false; - } else if (HttpHasAttribute(directives, "public", NULL)) { - may_cache = true; - } - } - return may_cache; -} - -enum HttpCacheState { - HCS_FRESH, // In cache, may use - HCS_STALE, // In cache, must revalidate - HCS_NONE // Not in cache -}; - -HttpCacheState HttpGetCacheState(const HttpTransaction& t) { - // Temporaries - std::string s_temp; - time_t u_temp; - - // Current time - size_t now = time(0); - - HttpAttributeList cache_control; - if (t.response.hasHeader(HH_CACHE_CONTROL, &s_temp)) { - HttpParseAttributes(s_temp.data(), s_temp.size(), cache_control); - } - - // Compute age of cache document - time_t date; - if (!t.response.hasHeader(HH_DATE, &s_temp) - || !HttpDateToSeconds(s_temp, &date)) - return HCS_NONE; - - // TODO: Timestamp when cache request sent and response received? - time_t request_time = date; - time_t response_time = date; - - time_t apparent_age = 0; - if (response_time > date) { - apparent_age = response_time - date; - } - - size_t corrected_received_age = apparent_age; - size_t i_temp; - if (t.response.hasHeader(HH_AGE, &s_temp) - && HttpStringToUInt(s_temp, (&i_temp))) { - u_temp = static_cast(i_temp); - corrected_received_age = stdmax(apparent_age, u_temp); - } - - size_t response_delay = response_time - request_time; - size_t corrected_initial_age = corrected_received_age + response_delay; - size_t resident_time = now - response_time; - size_t current_age = corrected_initial_age + resident_time; - - // Compute lifetime of document - size_t lifetime; - if (HttpHasAttribute(cache_control, "max-age", &s_temp)) { - lifetime = atoi(s_temp.c_str()); - } else if (t.response.hasHeader(HH_EXPIRES, &s_temp) - && HttpDateToSeconds(s_temp, &u_temp)) { - lifetime = u_temp - date; - } else if (t.response.hasHeader(HH_LAST_MODIFIED, &s_temp) - && HttpDateToSeconds(s_temp, &u_temp)) { - // TODO: Issue warning 113 if age > 24 hours - lifetime = static_cast(now - u_temp) / 10; - } else { - return HCS_STALE; - } - - return (lifetime > current_age) ? HCS_FRESH : HCS_STALE; -} - -enum HttpValidatorStrength { - HVS_NONE, - HVS_WEAK, - HVS_STRONG -}; - -HttpValidatorStrength -HttpRequestValidatorLevel(const HttpRequestData& request) { - if (HV_GET != request.verb) - return HVS_STRONG; - return request.hasHeader(HH_RANGE, NULL) ? HVS_STRONG : HVS_WEAK; -} - -HttpValidatorStrength -HttpResponseValidatorLevel(const HttpResponseData& response) { - std::string value; - if (response.hasHeader(HH_ETAG, &value)) { - bool is_weak = (strnicmp(value.c_str(), "W/", 2) == 0); - return is_weak ? HVS_WEAK : HVS_STRONG; - } - if (response.hasHeader(HH_LAST_MODIFIED, &value)) { - time_t last_modified, date; - if (HttpDateToSeconds(value, &last_modified) - && response.hasHeader(HH_DATE, &value) - && HttpDateToSeconds(value, &date) - && (last_modified + 60 < date)) { - return HVS_STRONG; - } - return HVS_WEAK; - } - return HVS_NONE; -} - -std::string GetCacheID(const HttpRequestData& request) { - std::string id, url; - id.append(ToString(request.verb)); - id.append("_"); - request.getAbsoluteUri(&url); - id.append(url); - return id; -} - -} // anonymous namespace - -////////////////////////////////////////////////////////////////////// -// Public Helpers -////////////////////////////////////////////////////////////////////// - -bool HttpWriteCacheHeaders(const HttpResponseData* response, - StreamInterface* output, size_t* size) { - size_t length = 0; - // Write all unknown and end-to-end headers to a cache file - for (HttpData::const_iterator it = response->begin(); - it != response->end(); ++it) { - HttpHeader header; - if (FromString(header, it->first) && !HttpHeaderIsEndToEnd(header)) - continue; - length += it->first.length() + 2 + it->second.length() + 2; - if (!output) - continue; - std::string formatted_header(it->first); - formatted_header.append(": "); - formatted_header.append(it->second); - formatted_header.append("\r\n"); - StreamResult result = output->WriteAll(formatted_header.data(), - formatted_header.length(), - NULL, NULL); - if (SR_SUCCESS != result) { - return false; - } - } - if (output && (SR_SUCCESS != output->WriteAll("\r\n", 2, NULL, NULL))) { - return false; - } - length += 2; - if (size) - *size = length; - return true; -} - -bool HttpReadCacheHeaders(StreamInterface* input, HttpResponseData* response, - HttpData::HeaderCombine combine) { - while (true) { - std::string formatted_header; - StreamResult result = input->ReadLine(&formatted_header); - if ((SR_EOS == result) || (1 == formatted_header.size())) { - break; - } - if (SR_SUCCESS != result) { - return false; - } - size_t end_of_name = formatted_header.find(':'); - if (std::string::npos == end_of_name) { - LOG_F(LS_WARNING) << "Malformed cache header"; - continue; - } - size_t start_of_value = end_of_name + 1; - size_t end_of_value = formatted_header.length(); - while ((start_of_value < end_of_value) - && isspace(formatted_header[start_of_value])) - ++start_of_value; - while ((start_of_value < end_of_value) - && isspace(formatted_header[end_of_value-1])) - --end_of_value; - size_t value_length = end_of_value - start_of_value; - - std::string name(formatted_header.substr(0, end_of_name)); - std::string value(formatted_header.substr(start_of_value, value_length)); - response->changeHeader(name, value, combine); - } - return true; -} - -////////////////////////////////////////////////////////////////////// -// HttpClient -////////////////////////////////////////////////////////////////////// - -const size_t kDefaultRetries = 1; -const size_t kMaxRedirects = 5; - -HttpClient::HttpClient(const std::string& agent, StreamPool* pool, - HttpTransaction* transaction) - : agent_(agent), pool_(pool), - transaction_(transaction), free_transaction_(false), - retries_(kDefaultRetries), attempt_(0), redirects_(0), - redirect_action_(REDIRECT_DEFAULT), - uri_form_(URI_DEFAULT), cache_(NULL), cache_state_(CS_READY), - resolver_(NULL) { - base_.notify(this); - if (NULL == transaction_) { - free_transaction_ = true; - transaction_ = new HttpTransaction; - } -} - -HttpClient::~HttpClient() { - base_.notify(NULL); - base_.abort(HE_SHUTDOWN); - if (resolver_) { - resolver_->Destroy(false); - } - release(); - if (free_transaction_) - delete transaction_; -} - -void HttpClient::reset() { - server_.Clear(); - request().clear(true); - response().clear(true); - context_.reset(); - redirects_ = 0; - base_.abort(HE_OPERATION_CANCELLED); -} - -void HttpClient::OnResolveResult(AsyncResolverInterface* resolver) { - if (resolver != resolver_) { - return; - } - int error = resolver_->GetError(); - server_ = resolver_->address(); - resolver_->Destroy(false); - resolver_ = NULL; - if (error != 0) { - LOG(LS_ERROR) << "Error " << error << " resolving name: " - << server_; - onHttpComplete(HM_CONNECT, HE_CONNECT_FAILED); - } else { - connect(); - } -} - -void HttpClient::StartDNSLookup() { - resolver_ = new AsyncResolver(); - resolver_->SignalDone.connect(this, &HttpClient::OnResolveResult); - resolver_->Start(server_); -} - -void HttpClient::set_server(const SocketAddress& address) { - server_ = address; - // Setting 'Host' here allows it to be overridden before starting the request, - // if necessary. - request().setHeader(HH_HOST, HttpAddress(server_, false), true); -} - -StreamInterface* HttpClient::GetDocumentStream() { - return base_.GetDocumentStream(); -} - -void HttpClient::start() { - if (base_.mode() != HM_NONE) { - // call reset() to abort an in-progress request - ASSERT(false); - return; - } - - ASSERT(!IsCacheActive()); - - if (request().hasHeader(HH_TRANSFER_ENCODING, NULL)) { - // Exact size must be known on the client. Instead of using chunked - // encoding, wrap data with auto-caching file or memory stream. - ASSERT(false); - return; - } - - attempt_ = 0; - - // If no content has been specified, using length of 0. - request().setHeader(HH_CONTENT_LENGTH, "0", false); - - if (!agent_.empty()) { - request().setHeader(HH_USER_AGENT, agent_, false); - } - - UriForm uri_form = uri_form_; - if (PROXY_HTTPS == proxy_.type) { - // Proxies require absolute form - uri_form = URI_ABSOLUTE; - request().version = HVER_1_0; - request().setHeader(HH_PROXY_CONNECTION, "Keep-Alive", false); - } else { - request().setHeader(HH_CONNECTION, "Keep-Alive", false); - } - - if (URI_ABSOLUTE == uri_form) { - // Convert to absolute uri form - std::string url; - if (request().getAbsoluteUri(&url)) { - request().path = url; - } else { - LOG(LS_WARNING) << "Couldn't obtain absolute uri"; - } - } else if (URI_RELATIVE == uri_form) { - // Convert to relative uri form - std::string host, path; - if (request().getRelativeUri(&host, &path)) { - request().setHeader(HH_HOST, host); - request().path = path; - } else { - LOG(LS_WARNING) << "Couldn't obtain relative uri"; - } - } - - if ((NULL != cache_) && CheckCache()) { - return; - } - - connect(); -} - -void HttpClient::connect() { - int stream_err; - if (server_.IsUnresolvedIP()) { - StartDNSLookup(); - return; - } - StreamInterface* stream = pool_->RequestConnectedStream(server_, &stream_err); - if (stream == NULL) { - ASSERT(0 != stream_err); - LOG(LS_ERROR) << "RequestConnectedStream error: " << stream_err; - onHttpComplete(HM_CONNECT, HE_CONNECT_FAILED); - } else { - base_.attach(stream); - if (stream->GetState() == SS_OPEN) { - base_.send(&transaction_->request); - } - } -} - -void HttpClient::prepare_get(const std::string& url) { - reset(); - Url purl(url); - set_server(SocketAddress(purl.host(), purl.port())); - request().verb = HV_GET; - request().path = purl.full_path(); -} - -void HttpClient::prepare_post(const std::string& url, - const std::string& content_type, - StreamInterface* request_doc) { - reset(); - Url purl(url); - set_server(SocketAddress(purl.host(), purl.port())); - request().verb = HV_POST; - request().path = purl.full_path(); - request().setContent(content_type, request_doc); -} - -void HttpClient::release() { - if (StreamInterface* stream = base_.detach()) { - pool_->ReturnConnectedStream(stream); - } -} - -bool HttpClient::ShouldRedirect(std::string* location) const { - // TODO: Unittest redirection. - if ((REDIRECT_NEVER == redirect_action_) - || !HttpCodeIsRedirection(response().scode) - || !response().hasHeader(HH_LOCATION, location) - || (redirects_ >= kMaxRedirects)) - return false; - return (REDIRECT_ALWAYS == redirect_action_) - || (HC_SEE_OTHER == response().scode) - || (HV_HEAD == request().verb) - || (HV_GET == request().verb); -} - -bool HttpClient::BeginCacheFile() { - ASSERT(NULL != cache_); - ASSERT(CS_READY == cache_state_); - - std::string id = GetCacheID(request()); - CacheLock lock(cache_, id, true); - if (!lock.IsLocked()) { - LOG_F(LS_WARNING) << "Couldn't lock cache"; - return false; - } - - if (HE_NONE != WriteCacheHeaders(id)) { - return false; - } - - scoped_ptr stream(cache_->WriteResource(id, kCacheBody)); - if (!stream) { - LOG_F(LS_ERROR) << "Couldn't open body cache"; - return false; - } - lock.Commit(); - - // Let's secretly replace the response document with Folgers Crystals, - // er, StreamTap, so that we can mirror the data to our cache. - StreamInterface* output = response().document.release(); - if (!output) { - output = new NullStream; - } - StreamTap* tap = new StreamTap(output, stream.release()); - response().document.reset(tap); - return true; -} - -HttpError HttpClient::WriteCacheHeaders(const std::string& id) { - scoped_ptr stream(cache_->WriteResource(id, kCacheHeader)); - if (!stream) { - LOG_F(LS_ERROR) << "Couldn't open header cache"; - return HE_CACHE; - } - - if (!HttpWriteCacheHeaders(&transaction_->response, stream.get(), NULL)) { - LOG_F(LS_ERROR) << "Couldn't write header cache"; - return HE_CACHE; - } - - return HE_NONE; -} - -void HttpClient::CompleteCacheFile() { - // Restore previous response document - StreamTap* tap = static_cast(response().document.release()); - response().document.reset(tap->Detach()); - - int error; - StreamResult result = tap->GetTapResult(&error); - - // Delete the tap and cache stream (which completes cache unlock) - delete tap; - - if (SR_SUCCESS != result) { - LOG(LS_ERROR) << "Cache file error: " << error; - cache_->DeleteResource(GetCacheID(request())); - } -} - -bool HttpClient::CheckCache() { - ASSERT(NULL != cache_); - ASSERT(CS_READY == cache_state_); - - std::string id = GetCacheID(request()); - if (!cache_->HasResource(id)) { - // No cache file available - return false; - } - - HttpError error = ReadCacheHeaders(id, true); - - if (HE_NONE == error) { - switch (HttpGetCacheState(*transaction_)) { - case HCS_FRESH: - // Cache content is good, read from cache - break; - case HCS_STALE: - // Cache content may be acceptable. Issue a validation request. - if (PrepareValidate()) { - return false; - } - // Couldn't validate, fall through. - case HCS_NONE: - // Cache content is not useable. Issue a regular request. - response().clear(false); - return false; - } - } - - if (HE_NONE == error) { - error = ReadCacheBody(id); - cache_state_ = CS_READY; - } - - if (HE_CACHE == error) { - LOG_F(LS_WARNING) << "Cache failure, continuing with normal request"; - response().clear(false); - return false; - } - - SignalHttpClientComplete(this, error); - return true; -} - -HttpError HttpClient::ReadCacheHeaders(const std::string& id, bool override) { - scoped_ptr stream(cache_->ReadResource(id, kCacheHeader)); - if (!stream) { - return HE_CACHE; - } - - HttpData::HeaderCombine combine = - override ? HttpData::HC_REPLACE : HttpData::HC_AUTO; - - if (!HttpReadCacheHeaders(stream.get(), &transaction_->response, combine)) { - LOG_F(LS_ERROR) << "Error reading cache headers"; - return HE_CACHE; - } - - response().scode = HC_OK; - return HE_NONE; -} - -HttpError HttpClient::ReadCacheBody(const std::string& id) { - cache_state_ = CS_READING; - - HttpError error = HE_NONE; - - size_t data_size; - scoped_ptr stream(cache_->ReadResource(id, kCacheBody)); - if (!stream || !stream->GetAvailable(&data_size)) { - LOG_F(LS_ERROR) << "Unavailable cache body"; - error = HE_CACHE; - } else { - error = OnHeaderAvailable(false, false, data_size); - } - - if ((HE_NONE == error) - && (HV_HEAD != request().verb) - && response().document) { - char buffer[1024 * 64]; - StreamResult result = Flow(stream.get(), buffer, ARRAY_SIZE(buffer), - response().document.get()); - if (SR_SUCCESS != result) { - error = HE_STREAM; - } - } - - return error; -} - -bool HttpClient::PrepareValidate() { - ASSERT(CS_READY == cache_state_); - // At this point, request() contains the pending request, and response() - // contains the cached response headers. Reformat the request to validate - // the cached content. - HttpValidatorStrength vs_required = HttpRequestValidatorLevel(request()); - HttpValidatorStrength vs_available = HttpResponseValidatorLevel(response()); - if (vs_available < vs_required) { - return false; - } - std::string value; - if (response().hasHeader(HH_ETAG, &value)) { - request().addHeader(HH_IF_NONE_MATCH, value); - } - if (response().hasHeader(HH_LAST_MODIFIED, &value)) { - request().addHeader(HH_IF_MODIFIED_SINCE, value); - } - response().clear(false); - cache_state_ = CS_VALIDATING; - return true; -} - -HttpError HttpClient::CompleteValidate() { - ASSERT(CS_VALIDATING == cache_state_); - - std::string id = GetCacheID(request()); - - // Merge cached headers with new headers - HttpError error = ReadCacheHeaders(id, false); - if (HE_NONE != error) { - // Rewrite merged headers to cache - CacheLock lock(cache_, id); - error = WriteCacheHeaders(id); - } - if (HE_NONE != error) { - error = ReadCacheBody(id); - } - return error; -} - -HttpError HttpClient::OnHeaderAvailable(bool ignore_data, bool chunked, - size_t data_size) { - // If we are ignoring the data, this is an intermediate header. - // TODO: don't signal intermediate headers. Instead, do all header-dependent - // processing now, and either set up the next request, or fail outright. - // TODO: by default, only write response documents with a success code. - SignalHeaderAvailable(this, !ignore_data, ignore_data ? 0 : data_size); - if (!ignore_data && !chunked && (data_size != SIZE_UNKNOWN) - && response().document) { - // Attempt to pre-allocate space for the downloaded data. - if (!response().document->ReserveSize(data_size)) { - return HE_OVERFLOW; - } - } - return HE_NONE; -} - -// -// HttpBase Implementation -// - -HttpError HttpClient::onHttpHeaderComplete(bool chunked, size_t& data_size) { - if (CS_VALIDATING == cache_state_) { - if (HC_NOT_MODIFIED == response().scode) { - return CompleteValidate(); - } - // Should we remove conditional headers from request? - cache_state_ = CS_READY; - cache_->DeleteResource(GetCacheID(request())); - // Continue processing response as normal - } - - ASSERT(!IsCacheActive()); - if ((request().verb == HV_HEAD) || !HttpCodeHasBody(response().scode)) { - // HEAD requests and certain response codes contain no body - data_size = 0; - } - if (ShouldRedirect(NULL) - || ((HC_PROXY_AUTHENTICATION_REQUIRED == response().scode) - && (PROXY_HTTPS == proxy_.type))) { - // We're going to issue another request, so ignore the incoming data. - base_.set_ignore_data(true); - } - - HttpError error = OnHeaderAvailable(base_.ignore_data(), chunked, data_size); - if (HE_NONE != error) { - return error; - } - - if ((NULL != cache_) - && !base_.ignore_data() - && HttpShouldCache(*transaction_)) { - if (BeginCacheFile()) { - cache_state_ = CS_WRITING; - } - } - return HE_NONE; -} - -void HttpClient::onHttpComplete(HttpMode mode, HttpError err) { - if (((HE_DISCONNECTED == err) || (HE_CONNECT_FAILED == err) - || (HE_SOCKET_ERROR == err)) - && (HC_INTERNAL_SERVER_ERROR == response().scode) - && (attempt_ < retries_)) { - // If the response code has not changed from the default, then we haven't - // received anything meaningful from the server, so we are eligible for a - // retry. - ++attempt_; - if (request().document && !request().document->Rewind()) { - // Unable to replay the request document. - err = HE_STREAM; - } else { - release(); - connect(); - return; - } - } else if (err != HE_NONE) { - // fall through - } else if (mode == HM_CONNECT) { - base_.send(&transaction_->request); - return; - } else if ((mode == HM_SEND) || HttpCodeIsInformational(response().scode)) { - // If you're interested in informational headers, catch - // SignalHeaderAvailable. - base_.recv(&transaction_->response); - return; - } else { - if (!HttpShouldKeepAlive(response())) { - LOG(LS_VERBOSE) << "HttpClient: closing socket"; - base_.stream()->Close(); - } - std::string location; - if (ShouldRedirect(&location)) { - Url purl(location); - set_server(SocketAddress(purl.host(), purl.port())); - request().path = purl.full_path(); - if (response().scode == HC_SEE_OTHER) { - request().verb = HV_GET; - request().clearHeader(HH_CONTENT_TYPE); - request().clearHeader(HH_CONTENT_LENGTH); - request().document.reset(); - } else if (request().document && !request().document->Rewind()) { - // Unable to replay the request document. - ASSERT(REDIRECT_ALWAYS == redirect_action_); - err = HE_STREAM; - } - if (err == HE_NONE) { - ++redirects_; - context_.reset(); - response().clear(false); - release(); - start(); - return; - } - } else if ((HC_PROXY_AUTHENTICATION_REQUIRED == response().scode) - && (PROXY_HTTPS == proxy_.type)) { - std::string authorization, auth_method; - HttpData::const_iterator begin = response().begin(HH_PROXY_AUTHENTICATE); - HttpData::const_iterator end = response().end(HH_PROXY_AUTHENTICATE); - for (HttpData::const_iterator it = begin; it != end; ++it) { - HttpAuthContext *context = context_.get(); - HttpAuthResult res = HttpAuthenticate( - it->second.data(), it->second.size(), - proxy_.address, - ToString(request().verb), request().path, - proxy_.username, proxy_.password, - context, authorization, auth_method); - context_.reset(context); - if (res == HAR_RESPONSE) { - request().setHeader(HH_PROXY_AUTHORIZATION, authorization); - if (request().document && !request().document->Rewind()) { - err = HE_STREAM; - } else { - // Explicitly do not reset the HttpAuthContext - response().clear(false); - // TODO: Reuse socket when authenticating? - release(); - start(); - return; - } - } else if (res == HAR_IGNORE) { - LOG(INFO) << "Ignoring Proxy-Authenticate: " << auth_method; - continue; - } else { - break; - } - } - } - } - if (CS_WRITING == cache_state_) { - CompleteCacheFile(); - cache_state_ = CS_READY; - } else if (CS_READING == cache_state_) { - cache_state_ = CS_READY; - } - release(); - SignalHttpClientComplete(this, err); -} - -void HttpClient::onHttpClosed(HttpError err) { - // This shouldn't occur, since we return the stream to the pool upon command - // completion. - ASSERT(false); -} - -////////////////////////////////////////////////////////////////////// -// HttpClientDefault -////////////////////////////////////////////////////////////////////// - -HttpClientDefault::HttpClientDefault(SocketFactory* factory, - const std::string& agent, - HttpTransaction* transaction) - : ReuseSocketPool(factory ? factory : Thread::Current()->socketserver()), - HttpClient(agent, NULL, transaction) { - set_pool(this); -} - -////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/httpclient.h b/webrtc/base/httpclient.h deleted file mode 100644 index b634b9345..000000000 --- a/webrtc/base/httpclient.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_HTTPCLIENT_H__ -#define WEBRTC_BASE_HTTPCLIENT_H__ - -#include "webrtc/base/common.h" -#include "webrtc/base/httpbase.h" -#include "webrtc/base/nethelpers.h" -#include "webrtc/base/proxyinfo.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/socketaddress.h" -#include "webrtc/base/socketpool.h" - -namespace rtc { - -////////////////////////////////////////////////////////////////////// -// Client-specific http utilities -////////////////////////////////////////////////////////////////////// - -// Write cache-relevant response headers to output stream. If size is non-null, -// it contains the length of the output in bytes. output may be null if only -// the length is desired. -bool HttpWriteCacheHeaders(const HttpResponseData* response, - StreamInterface* output, size_t* size); -// Read cached headers from a stream, and them merge them into the response -// object using the specified combine operation. -bool HttpReadCacheHeaders(StreamInterface* input, - HttpResponseData* response, - HttpData::HeaderCombine combine); - -////////////////////////////////////////////////////////////////////// -// HttpClient -// Implements an HTTP 1.1 client. -////////////////////////////////////////////////////////////////////// - -class DiskCache; -class HttpClient; -class IPNetPool; - -class SignalThread; -// What to do: Define STRICT_HTTP_ERROR=1 in your makefile. Use HttpError in -// your code (HttpErrorType should only be used for code that is shared -// with groups which have not yet migrated). -#if STRICT_HTTP_ERROR -typedef HttpError HttpErrorType; -#else // !STRICT_HTTP_ERROR -typedef int HttpErrorType; -#endif // !STRICT_HTTP_ERROR - -class HttpClient : private IHttpNotify, public sigslot::has_slots<> { -public: - // If HttpRequestData and HttpResponseData objects are provided, they must - // be freed by the caller. Otherwise, an internal object is allocated. - HttpClient(const std::string& agent, StreamPool* pool, - HttpTransaction* transaction = NULL); - virtual ~HttpClient(); - - void set_pool(StreamPool* pool) { pool_ = pool; } - - void set_agent(const std::string& agent) { agent_ = agent; } - const std::string& agent() const { return agent_; } - - void set_proxy(const ProxyInfo& proxy) { proxy_ = proxy; } - const ProxyInfo& proxy() const { return proxy_; } - - // Request retries occur when the connection closes before the beginning of - // an http response is received. In these cases, the http server may have - // timed out the keepalive connection before it received our request. Note - // that if a request document cannot be rewound, no retry is made. The - // default is 1. - void set_request_retries(size_t retries) { retries_ = retries; } - size_t request_retries() const { return retries_; } - - enum RedirectAction { REDIRECT_DEFAULT, REDIRECT_ALWAYS, REDIRECT_NEVER }; - void set_redirect_action(RedirectAction action) { redirect_action_ = action; } - RedirectAction redirect_action() const { return redirect_action_; } - // Deprecated - void set_fail_redirect(bool fail_redirect) { - redirect_action_ = REDIRECT_NEVER; - } - bool fail_redirect() const { return (REDIRECT_NEVER == redirect_action_); } - - enum UriForm { URI_DEFAULT, URI_ABSOLUTE, URI_RELATIVE }; - void set_uri_form(UriForm form) { uri_form_ = form; } - UriForm uri_form() const { return uri_form_; } - - void set_cache(DiskCache* cache) { ASSERT(!IsCacheActive()); cache_ = cache; } - bool cache_enabled() const { return (NULL != cache_); } - - // reset clears the server, request, and response structures. It will also - // abort an active request. - void reset(); - - void set_server(const SocketAddress& address); - const SocketAddress& server() const { return server_; } - - // Note: in order for HttpClient to retry a POST in response to - // an authentication challenge, a redirect response, or socket disconnection, - // the request document must support 'replaying' by calling Rewind() on it. - // In the case where just a subset of a stream should be used as the request - // document, the stream may be wrapped with the StreamSegment adapter. - HttpTransaction* transaction() { return transaction_; } - const HttpTransaction* transaction() const { return transaction_; } - HttpRequestData& request() { return transaction_->request; } - const HttpRequestData& request() const { return transaction_->request; } - HttpResponseData& response() { return transaction_->response; } - const HttpResponseData& response() const { return transaction_->response; } - - // convenience methods - void prepare_get(const std::string& url); - void prepare_post(const std::string& url, const std::string& content_type, - StreamInterface* request_doc); - - // Convert HttpClient to a pull-based I/O model. - StreamInterface* GetDocumentStream(); - - // After you finish setting up your request, call start. - void start(); - - // Signalled when the header has finished downloading, before the document - // content is processed. You may change the response document in response - // to this signal. The second parameter indicates whether this is an - // intermediate (false) or final (true) header. An intermediate header is - // one that generates another request, such as a redirect or authentication - // challenge. The third parameter indicates the length of the response - // document, or else SIZE_UNKNOWN. Note: Do NOT abort the request in response - // to this signal. - sigslot::signal3 SignalHeaderAvailable; - // Signalled when the current request finishes. On success, err is 0. - sigslot::signal2 SignalHttpClientComplete; - -protected: - void connect(); - void release(); - - bool ShouldRedirect(std::string* location) const; - - bool BeginCacheFile(); - HttpError WriteCacheHeaders(const std::string& id); - void CompleteCacheFile(); - - bool CheckCache(); - HttpError ReadCacheHeaders(const std::string& id, bool override); - HttpError ReadCacheBody(const std::string& id); - - bool PrepareValidate(); - HttpError CompleteValidate(); - - HttpError OnHeaderAvailable(bool ignore_data, bool chunked, size_t data_size); - - void StartDNSLookup(); - void OnResolveResult(AsyncResolverInterface* resolver); - - // IHttpNotify Interface - virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size); - virtual void onHttpComplete(HttpMode mode, HttpError err); - virtual void onHttpClosed(HttpError err); - -private: - enum CacheState { CS_READY, CS_WRITING, CS_READING, CS_VALIDATING }; - bool IsCacheActive() const { return (cache_state_ > CS_READY); } - - std::string agent_; - StreamPool* pool_; - HttpBase base_; - SocketAddress server_; - ProxyInfo proxy_; - HttpTransaction* transaction_; - bool free_transaction_; - size_t retries_, attempt_, redirects_; - RedirectAction redirect_action_; - UriForm uri_form_; - scoped_ptr context_; - DiskCache* cache_; - CacheState cache_state_; - AsyncResolverInterface* resolver_; -}; - -////////////////////////////////////////////////////////////////////// -// HttpClientDefault - Default implementation of HttpClient -////////////////////////////////////////////////////////////////////// - -class HttpClientDefault : public ReuseSocketPool, public HttpClient { -public: - HttpClientDefault(SocketFactory* factory, const std::string& agent, - HttpTransaction* transaction = NULL); -}; - -////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_HTTPCLIENT_H__ diff --git a/webrtc/base/httpcommon-inl.h b/webrtc/base/httpcommon-inl.h deleted file mode 100644 index 2f525ce79..000000000 --- a/webrtc/base/httpcommon-inl.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_HTTPCOMMON_INL_H__ -#define WEBRTC_BASE_HTTPCOMMON_INL_H__ - -#include "webrtc/base/common.h" -#include "webrtc/base/httpcommon.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// Url -/////////////////////////////////////////////////////////////////////////////// - -template -void Url::do_set_url(const CTYPE* val, size_t len) { - if (ascnicmp(val, "http://", 7) == 0) { - val += 7; len -= 7; - secure_ = false; - } else if (ascnicmp(val, "https://", 8) == 0) { - val += 8; len -= 8; - secure_ = true; - } else { - clear(); - return; - } - const CTYPE* path = strchrn(val, len, static_cast('/')); - if (!path) { - path = val + len; - } - size_t address_length = (path - val); - do_set_address(val, address_length); - do_set_full_path(path, len - address_length); -} - -template -void Url::do_set_address(const CTYPE* val, size_t len) { - if (const CTYPE* at = strchrn(val, len, static_cast('@'))) { - // Everything before the @ is a user:password combo, so skip it. - len -= at - val + 1; - val = at + 1; - } - if (const CTYPE* colon = strchrn(val, len, static_cast(':'))) { - host_.assign(val, colon - val); - // Note: In every case, we're guaranteed that colon is followed by a null, - // or non-numeric character. - port_ = static_cast(::strtoul(colon + 1, NULL, 10)); - // TODO: Consider checking for invalid data following port number. - } else { - host_.assign(val, len); - port_ = HttpDefaultPort(secure_); - } -} - -template -void Url::do_set_full_path(const CTYPE* val, size_t len) { - const CTYPE* query = strchrn(val, len, static_cast('?')); - if (!query) { - query = val + len; - } - size_t path_length = (query - val); - if (0 == path_length) { - // TODO: consider failing in this case. - path_.assign(1, static_cast('/')); - } else { - ASSERT(val[0] == static_cast('/')); - path_.assign(val, path_length); - } - query_.assign(query, len - path_length); -} - -template -void Url::do_get_url(string* val) const { - CTYPE protocol[9]; - asccpyn(protocol, ARRAY_SIZE(protocol), secure_ ? "https://" : "http://"); - val->append(protocol); - do_get_address(val); - do_get_full_path(val); -} - -template -void Url::do_get_address(string* val) const { - val->append(host_); - if (port_ != HttpDefaultPort(secure_)) { - CTYPE format[5], port[32]; - asccpyn(format, ARRAY_SIZE(format), ":%hu"); - sprintfn(port, ARRAY_SIZE(port), format, port_); - val->append(port); - } -} - -template -void Url::do_get_full_path(string* val) const { - val->append(path_); - val->append(query_); -} - -template -bool Url::get_attribute(const string& name, string* value) const { - if (query_.empty()) - return false; - - std::string::size_type pos = query_.find(name, 1); - if (std::string::npos == pos) - return false; - - pos += name.length() + 1; - if ((pos > query_.length()) || (static_cast('=') != query_[pos-1])) - return false; - - std::string::size_type end = query_.find(static_cast('&'), pos); - if (std::string::npos == end) { - end = query_.length(); - } - value->assign(query_.substr(pos, end - pos)); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_HTTPCOMMON_INL_H__ diff --git a/webrtc/base/httpcommon.cc b/webrtc/base/httpcommon.cc deleted file mode 100644 index 095cdafef..000000000 --- a/webrtc/base/httpcommon.cc +++ /dev/null @@ -1,1045 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#if defined(WEBRTC_WIN) -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#define SECURITY_WIN32 -#include -#endif - -#include "webrtc/base/httpcommon-inl.h" - -#include "webrtc/base/base64.h" -#include "webrtc/base/common.h" -#include "webrtc/base/cryptstring.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/socketaddress.h" -#include "webrtc/base/stringdigest.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/stringutils.h" - -namespace rtc { - -#if defined(WEBRTC_WIN) -extern const ConstantLabel SECURITY_ERRORS[]; -#endif - -////////////////////////////////////////////////////////////////////// -// Enum - TODO: expose globally later? -////////////////////////////////////////////////////////////////////// - -bool find_string(size_t& index, const std::string& needle, - const char* const haystack[], size_t max_index) { - for (index=0; index -struct Enum { - static const char** Names; - static size_t Size; - - static inline const char* Name(E val) { return Names[val]; } - static inline bool Parse(E& val, const std::string& name) { - size_t index; - if (!find_string(index, name, Names, Size)) - return false; - val = static_cast(index); - return true; - } - - E val; - - inline operator E&() { return val; } - inline Enum& operator=(E rhs) { val = rhs; return *this; } - - inline const char* name() const { return Name(val); } - inline bool assign(const std::string& name) { return Parse(val, name); } - inline Enum& operator=(const std::string& rhs) { assign(rhs); return *this; } -}; - -#define ENUM(e,n) \ - template<> const char** Enum::Names = n; \ - template<> size_t Enum::Size = sizeof(n)/sizeof(n[0]) - -////////////////////////////////////////////////////////////////////// -// HttpCommon -////////////////////////////////////////////////////////////////////// - -static const char* kHttpVersions[HVER_LAST+1] = { - "1.0", "1.1", "Unknown" -}; -ENUM(HttpVersion, kHttpVersions); - -static const char* kHttpVerbs[HV_LAST+1] = { - "GET", "POST", "PUT", "DELETE", "CONNECT", "HEAD" -}; -ENUM(HttpVerb, kHttpVerbs); - -static const char* kHttpHeaders[HH_LAST+1] = { - "Age", - "Cache-Control", - "Connection", - "Content-Disposition", - "Content-Length", - "Content-Range", - "Content-Type", - "Cookie", - "Date", - "ETag", - "Expires", - "Host", - "If-Modified-Since", - "If-None-Match", - "Keep-Alive", - "Last-Modified", - "Location", - "Proxy-Authenticate", - "Proxy-Authorization", - "Proxy-Connection", - "Range", - "Set-Cookie", - "TE", - "Trailers", - "Transfer-Encoding", - "Upgrade", - "User-Agent", - "WWW-Authenticate", -}; -ENUM(HttpHeader, kHttpHeaders); - -const char* ToString(HttpVersion version) { - return Enum::Name(version); -} - -bool FromString(HttpVersion& version, const std::string& str) { - return Enum::Parse(version, str); -} - -const char* ToString(HttpVerb verb) { - return Enum::Name(verb); -} - -bool FromString(HttpVerb& verb, const std::string& str) { - return Enum::Parse(verb, str); -} - -const char* ToString(HttpHeader header) { - return Enum::Name(header); -} - -bool FromString(HttpHeader& header, const std::string& str) { - return Enum::Parse(header, str); -} - -bool HttpCodeHasBody(uint32 code) { - return !HttpCodeIsInformational(code) - && (code != HC_NO_CONTENT) && (code != HC_NOT_MODIFIED); -} - -bool HttpCodeIsCacheable(uint32 code) { - switch (code) { - case HC_OK: - case HC_NON_AUTHORITATIVE: - case HC_PARTIAL_CONTENT: - case HC_MULTIPLE_CHOICES: - case HC_MOVED_PERMANENTLY: - case HC_GONE: - return true; - default: - return false; - } -} - -bool HttpHeaderIsEndToEnd(HttpHeader header) { - switch (header) { - case HH_CONNECTION: - case HH_KEEP_ALIVE: - case HH_PROXY_AUTHENTICATE: - case HH_PROXY_AUTHORIZATION: - case HH_PROXY_CONNECTION: // Note part of RFC... this is non-standard header - case HH_TE: - case HH_TRAILERS: - case HH_TRANSFER_ENCODING: - case HH_UPGRADE: - return false; - default: - return true; - } -} - -bool HttpHeaderIsCollapsible(HttpHeader header) { - switch (header) { - case HH_SET_COOKIE: - case HH_PROXY_AUTHENTICATE: - case HH_WWW_AUTHENTICATE: - return false; - default: - return true; - } -} - -bool HttpShouldKeepAlive(const HttpData& data) { - std::string connection; - if ((data.hasHeader(HH_PROXY_CONNECTION, &connection) - || data.hasHeader(HH_CONNECTION, &connection))) { - return (_stricmp(connection.c_str(), "Keep-Alive") == 0); - } - return (data.version >= HVER_1_1); -} - -namespace { - -inline bool IsEndOfAttributeName(size_t pos, size_t len, const char * data) { - if (pos >= len) - return true; - if (isspace(static_cast(data[pos]))) - return true; - // The reason for this complexity is that some attributes may contain trailing - // equal signs (like base64 tokens in Negotiate auth headers) - if ((pos+1 < len) && (data[pos] == '=') && - !isspace(static_cast(data[pos+1])) && - (data[pos+1] != '=')) { - return true; - } - return false; -} - -// TODO: unittest for EscapeAttribute and HttpComposeAttributes. - -std::string EscapeAttribute(const std::string& attribute) { - const size_t kMaxLength = attribute.length() * 2 + 1; - char* buffer = STACK_ARRAY(char, kMaxLength); - size_t len = escape(buffer, kMaxLength, attribute.data(), attribute.length(), - "\"", '\\'); - return std::string(buffer, len); -} - -} // anonymous namespace - -void HttpComposeAttributes(const HttpAttributeList& attributes, char separator, - std::string* composed) { - std::stringstream ss; - for (size_t i=0; i 0) { - ss << separator << " "; - } - ss << attributes[i].first; - if (!attributes[i].second.empty()) { - ss << "=\"" << EscapeAttribute(attributes[i].second) << "\""; - } - } - *composed = ss.str(); -} - -void HttpParseAttributes(const char * data, size_t len, - HttpAttributeList& attributes) { - size_t pos = 0; - while (true) { - // Skip leading whitespace - while ((pos < len) && isspace(static_cast(data[pos]))) { - ++pos; - } - - // End of attributes? - if (pos >= len) - return; - - // Find end of attribute name - size_t start = pos; - while (!IsEndOfAttributeName(pos, len, data)) { - ++pos; - } - - HttpAttribute attribute; - attribute.first.assign(data + start, data + pos); - - // Attribute has value? - if ((pos < len) && (data[pos] == '=')) { - ++pos; // Skip '=' - // Check if quoted value - if ((pos < len) && (data[pos] == '"')) { - while (++pos < len) { - if (data[pos] == '"') { - ++pos; - break; - } - if ((data[pos] == '\\') && (pos + 1 < len)) - ++pos; - attribute.second.append(1, data[pos]); - } - } else { - while ((pos < len) && - !isspace(static_cast(data[pos])) && - (data[pos] != ',')) { - attribute.second.append(1, data[pos++]); - } - } - } - - attributes.push_back(attribute); - if ((pos < len) && (data[pos] == ',')) ++pos; // Skip ',' - } -} - -bool HttpHasAttribute(const HttpAttributeList& attributes, - const std::string& name, - std::string* value) { - for (HttpAttributeList::const_iterator it = attributes.begin(); - it != attributes.end(); ++it) { - if (it->first == name) { - if (value) { - *value = it->second; - } - return true; - } - } - return false; -} - -bool HttpHasNthAttribute(HttpAttributeList& attributes, - size_t index, - std::string* name, - std::string* value) { - if (index >= attributes.size()) - return false; - - if (name) - *name = attributes[index].first; - if (value) - *value = attributes[index].second; - return true; -} - -bool HttpDateToSeconds(const std::string& date, time_t* seconds) { - const char* const kTimeZones[] = { - "UT", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", "PDT", - "A", "B", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", - "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y" - }; - const int kTimeZoneOffsets[] = { - 0, 0, -5, -4, -6, -5, -7, -6, -8, -7, - -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 - }; - - ASSERT(NULL != seconds); - struct tm tval; - memset(&tval, 0, sizeof(tval)); - char month[4], zone[6]; - memset(month, 0, sizeof(month)); - memset(zone, 0, sizeof(zone)); - - if (7 != sscanf(date.c_str(), "%*3s, %d %3s %d %d:%d:%d %5c", - &tval.tm_mday, month, &tval.tm_year, - &tval.tm_hour, &tval.tm_min, &tval.tm_sec, zone)) { - return false; - } - switch (toupper(month[2])) { - case 'N': tval.tm_mon = (month[1] == 'A') ? 0 : 5; break; - case 'B': tval.tm_mon = 1; break; - case 'R': tval.tm_mon = (month[0] == 'M') ? 2 : 3; break; - case 'Y': tval.tm_mon = 4; break; - case 'L': tval.tm_mon = 6; break; - case 'G': tval.tm_mon = 7; break; - case 'P': tval.tm_mon = 8; break; - case 'T': tval.tm_mon = 9; break; - case 'V': tval.tm_mon = 10; break; - case 'C': tval.tm_mon = 11; break; - } - tval.tm_year -= 1900; - size_t gmt, non_gmt = mktime(&tval); - if ((zone[0] == '+') || (zone[0] == '-')) { - if (!isdigit(zone[1]) || !isdigit(zone[2]) - || !isdigit(zone[3]) || !isdigit(zone[4])) { - return false; - } - int hours = (zone[1] - '0') * 10 + (zone[2] - '0'); - int minutes = (zone[3] - '0') * 10 + (zone[4] - '0'); - int offset = (hours * 60 + minutes) * 60; - gmt = non_gmt + ((zone[0] == '+') ? offset : -offset); - } else { - size_t zindex; - if (!find_string(zindex, zone, kTimeZones, ARRAY_SIZE(kTimeZones))) { - return false; - } - gmt = non_gmt + kTimeZoneOffsets[zindex] * 60 * 60; - } - // TODO: Android should support timezone, see b/2441195 -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID) || defined(BSD) - tm *tm_for_timezone = localtime((time_t *)&gmt); - *seconds = gmt + tm_for_timezone->tm_gmtoff; -#else - *seconds = gmt - timezone; -#endif - return true; -} - -std::string HttpAddress(const SocketAddress& address, bool secure) { - return (address.port() == HttpDefaultPort(secure)) - ? address.hostname() : address.ToString(); -} - -////////////////////////////////////////////////////////////////////// -// HttpData -////////////////////////////////////////////////////////////////////// - -void -HttpData::clear(bool release_document) { - // Clear headers first, since releasing a document may have far-reaching - // effects. - headers_.clear(); - if (release_document) { - document.reset(); - } -} - -void -HttpData::copy(const HttpData& src) { - headers_ = src.headers_; -} - -void -HttpData::changeHeader(const std::string& name, const std::string& value, - HeaderCombine combine) { - if (combine == HC_AUTO) { - HttpHeader header; - // Unrecognized headers are collapsible - combine = !FromString(header, name) || HttpHeaderIsCollapsible(header) - ? HC_YES : HC_NO; - } else if (combine == HC_REPLACE) { - headers_.erase(name); - combine = HC_NO; - } - // At this point, combine is one of (YES, NO, NEW) - if (combine != HC_NO) { - HeaderMap::iterator it = headers_.find(name); - if (it != headers_.end()) { - if (combine == HC_YES) { - it->second.append(","); - it->second.append(value); - } - return; - } - } - headers_.insert(HeaderMap::value_type(name, value)); -} - -size_t HttpData::clearHeader(const std::string& name) { - return headers_.erase(name); -} - -HttpData::iterator HttpData::clearHeader(iterator header) { - iterator deprecated = header++; - headers_.erase(deprecated); - return header; -} - -bool -HttpData::hasHeader(const std::string& name, std::string* value) const { - HeaderMap::const_iterator it = headers_.find(name); - if (it == headers_.end()) { - return false; - } else if (value) { - *value = it->second; - } - return true; -} - -void HttpData::setContent(const std::string& content_type, - StreamInterface* document) { - setHeader(HH_CONTENT_TYPE, content_type); - setDocumentAndLength(document); -} - -void HttpData::setDocumentAndLength(StreamInterface* document) { - // TODO: Consider calling Rewind() here? - ASSERT(!hasHeader(HH_CONTENT_LENGTH, NULL)); - ASSERT(!hasHeader(HH_TRANSFER_ENCODING, NULL)); - ASSERT(document != NULL); - this->document.reset(document); - size_t content_length = 0; - if (this->document->GetAvailable(&content_length)) { - char buffer[32]; - sprintfn(buffer, sizeof(buffer), "%d", content_length); - setHeader(HH_CONTENT_LENGTH, buffer); - } else { - setHeader(HH_TRANSFER_ENCODING, "chunked"); - } -} - -// -// HttpRequestData -// - -void -HttpRequestData::clear(bool release_document) { - verb = HV_GET; - path.clear(); - HttpData::clear(release_document); -} - -void -HttpRequestData::copy(const HttpRequestData& src) { - verb = src.verb; - path = src.path; - HttpData::copy(src); -} - -size_t -HttpRequestData::formatLeader(char* buffer, size_t size) const { - ASSERT(path.find(' ') == std::string::npos); - return sprintfn(buffer, size, "%s %.*s HTTP/%s", ToString(verb), path.size(), - path.data(), ToString(version)); -} - -HttpError -HttpRequestData::parseLeader(const char* line, size_t len) { - unsigned int vmajor, vminor; - int vend, dstart, dend; - // sscanf isn't safe with strings that aren't null-terminated, and there is - // no guarantee that |line| is. Create a local copy that is null-terminated. - std::string line_str(line, len); - line = line_str.c_str(); - if ((sscanf(line, "%*s%n %n%*s%n HTTP/%u.%u", - &vend, &dstart, &dend, &vmajor, &vminor) != 2) - || (vmajor != 1)) { - return HE_PROTOCOL; - } - if (vminor == 0) { - version = HVER_1_0; - } else if (vminor == 1) { - version = HVER_1_1; - } else { - return HE_PROTOCOL; - } - std::string sverb(line, vend); - if (!FromString(verb, sverb.c_str())) { - return HE_PROTOCOL; // !?! HC_METHOD_NOT_SUPPORTED? - } - path.assign(line + dstart, line + dend); - return HE_NONE; -} - -bool HttpRequestData::getAbsoluteUri(std::string* uri) const { - if (HV_CONNECT == verb) - return false; - Url url(path); - if (url.valid()) { - uri->assign(path); - return true; - } - std::string host; - if (!hasHeader(HH_HOST, &host)) - return false; - url.set_address(host); - url.set_full_path(path); - uri->assign(url.url()); - return url.valid(); -} - -bool HttpRequestData::getRelativeUri(std::string* host, - std::string* path) const -{ - if (HV_CONNECT == verb) - return false; - Url url(this->path); - if (url.valid()) { - host->assign(url.address()); - path->assign(url.full_path()); - return true; - } - if (!hasHeader(HH_HOST, host)) - return false; - path->assign(this->path); - return true; -} - -// -// HttpResponseData -// - -void -HttpResponseData::clear(bool release_document) { - scode = HC_INTERNAL_SERVER_ERROR; - message.clear(); - HttpData::clear(release_document); -} - -void -HttpResponseData::copy(const HttpResponseData& src) { - scode = src.scode; - message = src.message; - HttpData::copy(src); -} - -void -HttpResponseData::set_success(uint32 scode) { - this->scode = scode; - message.clear(); - setHeader(HH_CONTENT_LENGTH, "0", false); -} - -void -HttpResponseData::set_success(const std::string& content_type, - StreamInterface* document, - uint32 scode) { - this->scode = scode; - message.erase(message.begin(), message.end()); - setContent(content_type, document); -} - -void -HttpResponseData::set_redirect(const std::string& location, uint32 scode) { - this->scode = scode; - message.clear(); - setHeader(HH_LOCATION, location); - setHeader(HH_CONTENT_LENGTH, "0", false); -} - -void -HttpResponseData::set_error(uint32 scode) { - this->scode = scode; - message.clear(); - setHeader(HH_CONTENT_LENGTH, "0", false); -} - -size_t -HttpResponseData::formatLeader(char* buffer, size_t size) const { - size_t len = sprintfn(buffer, size, "HTTP/%s %lu", ToString(version), scode); - if (!message.empty()) { - len += sprintfn(buffer + len, size - len, " %.*s", - message.size(), message.data()); - } - return len; -} - -HttpError -HttpResponseData::parseLeader(const char* line, size_t len) { - size_t pos = 0; - unsigned int vmajor, vminor, temp_scode; - int temp_pos; - // sscanf isn't safe with strings that aren't null-terminated, and there is - // no guarantee that |line| is. Create a local copy that is null-terminated. - std::string line_str(line, len); - line = line_str.c_str(); - if (sscanf(line, "HTTP %u%n", - &temp_scode, &temp_pos) == 1) { - // This server's response has no version. :( NOTE: This happens for every - // response to requests made from Chrome plugins, regardless of the server's - // behaviour. - LOG(LS_VERBOSE) << "HTTP version missing from response"; - version = HVER_UNKNOWN; - } else if ((sscanf(line, "HTTP/%u.%u %u%n", - &vmajor, &vminor, &temp_scode, &temp_pos) == 3) - && (vmajor == 1)) { - // This server's response does have a version. - if (vminor == 0) { - version = HVER_1_0; - } else if (vminor == 1) { - version = HVER_1_1; - } else { - return HE_PROTOCOL; - } - } else { - return HE_PROTOCOL; - } - scode = temp_scode; - pos = static_cast(temp_pos); - while ((pos < len) && isspace(static_cast(line[pos]))) ++pos; - message.assign(line + pos, len - pos); - return HE_NONE; -} - -////////////////////////////////////////////////////////////////////// -// Http Authentication -////////////////////////////////////////////////////////////////////// - -#define TEST_DIGEST 0 -#if TEST_DIGEST -/* -const char * const DIGEST_CHALLENGE = - "Digest realm=\"testrealm@host.com\"," - " qop=\"auth,auth-int\"," - " nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\"," - " opaque=\"5ccc069c403ebaf9f0171e9517f40e41\""; -const char * const DIGEST_METHOD = "GET"; -const char * const DIGEST_URI = - "/dir/index.html";; -const char * const DIGEST_CNONCE = - "0a4f113b"; -const char * const DIGEST_RESPONSE = - "6629fae49393a05397450978507c4ef1"; -//user_ = "Mufasa"; -//pass_ = "Circle Of Life"; -*/ -const char * const DIGEST_CHALLENGE = - "Digest realm=\"Squid proxy-caching web server\"," - " nonce=\"Nny4QuC5PwiSDixJ\"," - " qop=\"auth\"," - " stale=false"; -const char * const DIGEST_URI = - "/"; -const char * const DIGEST_CNONCE = - "6501d58e9a21cee1e7b5fec894ded024"; -const char * const DIGEST_RESPONSE = - "edffcb0829e755838b073a4a42de06bc"; -#endif - -std::string quote(const std::string& str) { - std::string result; - result.push_back('"'); - for (size_t i=0; iauth_method != auth_method)) - return HAR_IGNORE; - - // BASIC - if (_stricmp(auth_method.c_str(), "basic") == 0) { - if (context) - return HAR_CREDENTIALS; // Bad credentials - if (username.empty()) - return HAR_CREDENTIALS; // Missing credentials - - context = new HttpAuthContext(auth_method); - - // TODO: convert sensitive to a secure buffer that gets securely deleted - //std::string decoded = username + ":" + password; - size_t len = username.size() + password.GetLength() + 2; - char * sensitive = new char[len]; - size_t pos = strcpyn(sensitive, len, username.data(), username.size()); - pos += strcpyn(sensitive + pos, len - pos, ":"); - password.CopyTo(sensitive + pos, true); - - response = auth_method; - response.append(" "); - // TODO: create a sensitive-source version of Base64::encode - response.append(Base64::Encode(sensitive)); - memset(sensitive, 0, len); - delete [] sensitive; - return HAR_RESPONSE; - } - - // DIGEST - if (_stricmp(auth_method.c_str(), "digest") == 0) { - if (context) - return HAR_CREDENTIALS; // Bad credentials - if (username.empty()) - return HAR_CREDENTIALS; // Missing credentials - - context = new HttpAuthContext(auth_method); - - std::string cnonce, ncount; -#if TEST_DIGEST - method = DIGEST_METHOD; - uri = DIGEST_URI; - cnonce = DIGEST_CNONCE; -#else - char buffer[256]; - sprintf(buffer, "%d", static_cast(time(0))); - cnonce = MD5(buffer); -#endif - ncount = "00000001"; - - std::string realm, nonce, qop, opaque; - HttpHasAttribute(args, "realm", &realm); - HttpHasAttribute(args, "nonce", &nonce); - bool has_qop = HttpHasAttribute(args, "qop", &qop); - bool has_opaque = HttpHasAttribute(args, "opaque", &opaque); - - // TODO: convert sensitive to be secure buffer - //std::string A1 = username + ":" + realm + ":" + password; - size_t len = username.size() + realm.size() + password.GetLength() + 3; - char * sensitive = new char[len]; // A1 - size_t pos = strcpyn(sensitive, len, username.data(), username.size()); - pos += strcpyn(sensitive + pos, len - pos, ":"); - pos += strcpyn(sensitive + pos, len - pos, realm.c_str()); - pos += strcpyn(sensitive + pos, len - pos, ":"); - password.CopyTo(sensitive + pos, true); - - std::string A2 = method + ":" + uri; - std::string middle; - if (has_qop) { - qop = "auth"; - middle = nonce + ":" + ncount + ":" + cnonce + ":" + qop; - } else { - middle = nonce; - } - std::string HA1 = MD5(sensitive); - memset(sensitive, 0, len); - delete [] sensitive; - std::string HA2 = MD5(A2); - std::string dig_response = MD5(HA1 + ":" + middle + ":" + HA2); - -#if TEST_DIGEST - ASSERT(strcmp(dig_response.c_str(), DIGEST_RESPONSE) == 0); -#endif - - std::stringstream ss; - ss << auth_method; - ss << " username=" << quote(username); - ss << ", realm=" << quote(realm); - ss << ", nonce=" << quote(nonce); - ss << ", uri=" << quote(uri); - if (has_qop) { - ss << ", qop=" << qop; - ss << ", nc=" << ncount; - ss << ", cnonce=" << quote(cnonce); - } - ss << ", response=\"" << dig_response << "\""; - if (has_opaque) { - ss << ", opaque=" << quote(opaque); - } - response = ss.str(); - return HAR_RESPONSE; - } - -#if defined(WEBRTC_WIN) -#if 1 - bool want_negotiate = (_stricmp(auth_method.c_str(), "negotiate") == 0); - bool want_ntlm = (_stricmp(auth_method.c_str(), "ntlm") == 0); - // SPNEGO & NTLM - if (want_negotiate || want_ntlm) { - const size_t MAX_MESSAGE = 12000, MAX_SPN = 256; - char out_buf[MAX_MESSAGE], spn[MAX_SPN]; - -#if 0 // Requires funky windows versions - DWORD len = MAX_SPN; - if (DsMakeSpn("HTTP", server.HostAsURIString().c_str(), NULL, - server.port(), - 0, &len, spn) != ERROR_SUCCESS) { - LOG_F(WARNING) << "(Negotiate) - DsMakeSpn failed"; - return HAR_IGNORE; - } -#else - sprintfn(spn, MAX_SPN, "HTTP/%s", server.ToString().c_str()); -#endif - - SecBuffer out_sec; - out_sec.pvBuffer = out_buf; - out_sec.cbBuffer = sizeof(out_buf); - out_sec.BufferType = SECBUFFER_TOKEN; - - SecBufferDesc out_buf_desc; - out_buf_desc.ulVersion = 0; - out_buf_desc.cBuffers = 1; - out_buf_desc.pBuffers = &out_sec; - - const ULONG NEG_FLAGS_DEFAULT = - //ISC_REQ_ALLOCATE_MEMORY - ISC_REQ_CONFIDENTIALITY - //| ISC_REQ_EXTENDED_ERROR - //| ISC_REQ_INTEGRITY - | ISC_REQ_REPLAY_DETECT - | ISC_REQ_SEQUENCE_DETECT - //| ISC_REQ_STREAM - //| ISC_REQ_USE_SUPPLIED_CREDS - ; - - ::TimeStamp lifetime; - SECURITY_STATUS ret = S_OK; - ULONG ret_flags = 0, flags = NEG_FLAGS_DEFAULT; - - bool specify_credentials = !username.empty(); - size_t steps = 0; - - //uint32 now = Time(); - - NegotiateAuthContext * neg = static_cast(context); - if (neg) { - const size_t max_steps = 10; - if (++neg->steps >= max_steps) { - LOG(WARNING) << "AsyncHttpsProxySocket::Authenticate(Negotiate) too many retries"; - return HAR_ERROR; - } - steps = neg->steps; - - std::string challenge, decoded_challenge; - if (HttpHasNthAttribute(args, 1, &challenge, NULL) - && Base64::Decode(challenge, Base64::DO_STRICT, - &decoded_challenge, NULL)) { - SecBuffer in_sec; - in_sec.pvBuffer = const_cast(decoded_challenge.data()); - in_sec.cbBuffer = static_cast(decoded_challenge.size()); - in_sec.BufferType = SECBUFFER_TOKEN; - - SecBufferDesc in_buf_desc; - in_buf_desc.ulVersion = 0; - in_buf_desc.cBuffers = 1; - in_buf_desc.pBuffers = &in_sec; - - ret = InitializeSecurityContextA(&neg->cred, &neg->ctx, spn, flags, 0, SECURITY_NATIVE_DREP, &in_buf_desc, 0, &neg->ctx, &out_buf_desc, &ret_flags, &lifetime); - //LOG(INFO) << "$$$ InitializeSecurityContext @ " << TimeSince(now); - if (FAILED(ret)) { - LOG(LS_ERROR) << "InitializeSecurityContext returned: " - << ErrorName(ret, SECURITY_ERRORS); - return HAR_ERROR; - } - } else if (neg->specified_credentials) { - // Try again with default credentials - specify_credentials = false; - delete context; - context = neg = 0; - } else { - return HAR_CREDENTIALS; - } - } - - if (!neg) { - unsigned char userbuf[256], passbuf[256], domainbuf[16]; - SEC_WINNT_AUTH_IDENTITY_A auth_id, * pauth_id = 0; - if (specify_credentials) { - memset(&auth_id, 0, sizeof(auth_id)); - size_t len = password.GetLength()+1; - char * sensitive = new char[len]; - password.CopyTo(sensitive, true); - std::string::size_type pos = username.find('\\'); - if (pos == std::string::npos) { - auth_id.UserLength = static_cast( - _min(sizeof(userbuf) - 1, username.size())); - memcpy(userbuf, username.c_str(), auth_id.UserLength); - userbuf[auth_id.UserLength] = 0; - auth_id.DomainLength = 0; - domainbuf[auth_id.DomainLength] = 0; - auth_id.PasswordLength = static_cast( - _min(sizeof(passbuf) - 1, password.GetLength())); - memcpy(passbuf, sensitive, auth_id.PasswordLength); - passbuf[auth_id.PasswordLength] = 0; - } else { - auth_id.UserLength = static_cast( - _min(sizeof(userbuf) - 1, username.size() - pos - 1)); - memcpy(userbuf, username.c_str() + pos + 1, auth_id.UserLength); - userbuf[auth_id.UserLength] = 0; - auth_id.DomainLength = static_cast( - _min(sizeof(domainbuf) - 1, pos)); - memcpy(domainbuf, username.c_str(), auth_id.DomainLength); - domainbuf[auth_id.DomainLength] = 0; - auth_id.PasswordLength = static_cast( - _min(sizeof(passbuf) - 1, password.GetLength())); - memcpy(passbuf, sensitive, auth_id.PasswordLength); - passbuf[auth_id.PasswordLength] = 0; - } - memset(sensitive, 0, len); - delete [] sensitive; - auth_id.User = userbuf; - auth_id.Domain = domainbuf; - auth_id.Password = passbuf; - auth_id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; - pauth_id = &auth_id; - LOG(LS_VERBOSE) << "Negotiate protocol: Using specified credentials"; - } else { - LOG(LS_VERBOSE) << "Negotiate protocol: Using default credentials"; - } - - CredHandle cred; - ret = AcquireCredentialsHandleA(0, want_negotiate ? NEGOSSP_NAME_A : NTLMSP_NAME_A, SECPKG_CRED_OUTBOUND, 0, pauth_id, 0, 0, &cred, &lifetime); - //LOG(INFO) << "$$$ AcquireCredentialsHandle @ " << TimeSince(now); - if (ret != SEC_E_OK) { - LOG(LS_ERROR) << "AcquireCredentialsHandle error: " - << ErrorName(ret, SECURITY_ERRORS); - return HAR_IGNORE; - } - - //CSecBufferBundle<5, CSecBufferBase::FreeSSPI> sb_out; - - CtxtHandle ctx; - ret = InitializeSecurityContextA(&cred, 0, spn, flags, 0, SECURITY_NATIVE_DREP, 0, 0, &ctx, &out_buf_desc, &ret_flags, &lifetime); - //LOG(INFO) << "$$$ InitializeSecurityContext @ " << TimeSince(now); - if (FAILED(ret)) { - LOG(LS_ERROR) << "InitializeSecurityContext returned: " - << ErrorName(ret, SECURITY_ERRORS); - FreeCredentialsHandle(&cred); - return HAR_IGNORE; - } - - ASSERT(!context); - context = neg = new NegotiateAuthContext(auth_method, cred, ctx); - neg->specified_credentials = specify_credentials; - neg->steps = steps; - } - - if ((ret == SEC_I_COMPLETE_NEEDED) || (ret == SEC_I_COMPLETE_AND_CONTINUE)) { - ret = CompleteAuthToken(&neg->ctx, &out_buf_desc); - //LOG(INFO) << "$$$ CompleteAuthToken @ " << TimeSince(now); - LOG(LS_VERBOSE) << "CompleteAuthToken returned: " - << ErrorName(ret, SECURITY_ERRORS); - if (FAILED(ret)) { - return HAR_ERROR; - } - } - - //LOG(INFO) << "$$$ NEGOTIATE took " << TimeSince(now) << "ms"; - - std::string decoded(out_buf, out_buf + out_sec.cbBuffer); - response = auth_method; - response.append(" "); - response.append(Base64::Encode(decoded)); - return HAR_RESPONSE; - } -#endif -#endif // WEBRTC_WIN - - return HAR_IGNORE; -} - -////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/httpcommon.h b/webrtc/base/httpcommon.h deleted file mode 100644 index c43a9e276..000000000 --- a/webrtc/base/httpcommon.h +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_HTTPCOMMON_H__ -#define WEBRTC_BASE_HTTPCOMMON_H__ - -#include -#include -#include -#include "webrtc/base/basictypes.h" -#include "webrtc/base/common.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -class CryptString; -class SocketAddress; - -////////////////////////////////////////////////////////////////////// -// Constants -////////////////////////////////////////////////////////////////////// - -enum HttpCode { - HC_OK = 200, - HC_NON_AUTHORITATIVE = 203, - HC_NO_CONTENT = 204, - HC_PARTIAL_CONTENT = 206, - - HC_MULTIPLE_CHOICES = 300, - HC_MOVED_PERMANENTLY = 301, - HC_FOUND = 302, - HC_SEE_OTHER = 303, - HC_NOT_MODIFIED = 304, - HC_MOVED_TEMPORARILY = 307, - - HC_BAD_REQUEST = 400, - HC_UNAUTHORIZED = 401, - HC_FORBIDDEN = 403, - HC_NOT_FOUND = 404, - HC_PROXY_AUTHENTICATION_REQUIRED = 407, - HC_GONE = 410, - - HC_INTERNAL_SERVER_ERROR = 500, - HC_NOT_IMPLEMENTED = 501, - HC_SERVICE_UNAVAILABLE = 503, -}; - -enum HttpVersion { - HVER_1_0, HVER_1_1, HVER_UNKNOWN, - HVER_LAST = HVER_UNKNOWN -}; - -enum HttpVerb { - HV_GET, HV_POST, HV_PUT, HV_DELETE, HV_CONNECT, HV_HEAD, - HV_LAST = HV_HEAD -}; - -enum HttpError { - HE_NONE, - HE_PROTOCOL, // Received non-valid HTTP data - HE_DISCONNECTED, // Connection closed unexpectedly - HE_OVERFLOW, // Received too much data for internal buffers - HE_CONNECT_FAILED, // The socket failed to connect. - HE_SOCKET_ERROR, // An error occurred on a connected socket - HE_SHUTDOWN, // Http object is being destroyed - HE_OPERATION_CANCELLED, // Connection aborted locally - HE_AUTH, // Proxy Authentication Required - HE_CERTIFICATE_EXPIRED, // During SSL negotiation - HE_STREAM, // Problem reading or writing to the document - HE_CACHE, // Problem reading from cache - HE_DEFAULT -}; - -enum HttpHeader { - HH_AGE, - HH_CACHE_CONTROL, - HH_CONNECTION, - HH_CONTENT_DISPOSITION, - HH_CONTENT_LENGTH, - HH_CONTENT_RANGE, - HH_CONTENT_TYPE, - HH_COOKIE, - HH_DATE, - HH_ETAG, - HH_EXPIRES, - HH_HOST, - HH_IF_MODIFIED_SINCE, - HH_IF_NONE_MATCH, - HH_KEEP_ALIVE, - HH_LAST_MODIFIED, - HH_LOCATION, - HH_PROXY_AUTHENTICATE, - HH_PROXY_AUTHORIZATION, - HH_PROXY_CONNECTION, - HH_RANGE, - HH_SET_COOKIE, - HH_TE, - HH_TRAILERS, - HH_TRANSFER_ENCODING, - HH_UPGRADE, - HH_USER_AGENT, - HH_WWW_AUTHENTICATE, - HH_LAST = HH_WWW_AUTHENTICATE -}; - -const uint16 HTTP_DEFAULT_PORT = 80; -const uint16 HTTP_SECURE_PORT = 443; - -////////////////////////////////////////////////////////////////////// -// Utility Functions -////////////////////////////////////////////////////////////////////// - -inline HttpError mkerr(HttpError err, HttpError def_err = HE_DEFAULT) { - return (err != HE_NONE) ? err : def_err; -} - -const char* ToString(HttpVersion version); -bool FromString(HttpVersion& version, const std::string& str); - -const char* ToString(HttpVerb verb); -bool FromString(HttpVerb& verb, const std::string& str); - -const char* ToString(HttpHeader header); -bool FromString(HttpHeader& header, const std::string& str); - -inline bool HttpCodeIsInformational(uint32 code) { return ((code / 100) == 1); } -inline bool HttpCodeIsSuccessful(uint32 code) { return ((code / 100) == 2); } -inline bool HttpCodeIsRedirection(uint32 code) { return ((code / 100) == 3); } -inline bool HttpCodeIsClientError(uint32 code) { return ((code / 100) == 4); } -inline bool HttpCodeIsServerError(uint32 code) { return ((code / 100) == 5); } - -bool HttpCodeHasBody(uint32 code); -bool HttpCodeIsCacheable(uint32 code); -bool HttpHeaderIsEndToEnd(HttpHeader header); -bool HttpHeaderIsCollapsible(HttpHeader header); - -struct HttpData; -bool HttpShouldKeepAlive(const HttpData& data); - -typedef std::pair HttpAttribute; -typedef std::vector HttpAttributeList; -void HttpComposeAttributes(const HttpAttributeList& attributes, char separator, - std::string* composed); -void HttpParseAttributes(const char * data, size_t len, - HttpAttributeList& attributes); -bool HttpHasAttribute(const HttpAttributeList& attributes, - const std::string& name, - std::string* value); -bool HttpHasNthAttribute(HttpAttributeList& attributes, - size_t index, - std::string* name, - std::string* value); - -// Convert RFC1123 date (DoW, DD Mon YYYY HH:MM:SS TZ) to unix timestamp -bool HttpDateToSeconds(const std::string& date, time_t* seconds); - -inline uint16 HttpDefaultPort(bool secure) { - return secure ? HTTP_SECURE_PORT : HTTP_DEFAULT_PORT; -} - -// Returns the http server notation for a given address -std::string HttpAddress(const SocketAddress& address, bool secure); - -// functional for insensitive std::string compare -struct iless { - bool operator()(const std::string& lhs, const std::string& rhs) const { - return (::_stricmp(lhs.c_str(), rhs.c_str()) < 0); - } -}; - -// put quotes around a string and escape any quotes inside it -std::string quote(const std::string& str); - -////////////////////////////////////////////////////////////////////// -// Url -////////////////////////////////////////////////////////////////////// - -template -class Url { -public: - typedef typename Traits::string string; - - // TODO: Implement Encode/Decode - static int Encode(const CTYPE* source, CTYPE* destination, size_t len); - static int Encode(const string& source, string& destination); - static int Decode(const CTYPE* source, CTYPE* destination, size_t len); - static int Decode(const string& source, string& destination); - - Url(const string& url) { do_set_url(url.c_str(), url.size()); } - Url(const string& path, const string& host, uint16 port = HTTP_DEFAULT_PORT) - : host_(host), port_(port), secure_(HTTP_SECURE_PORT == port) - { set_full_path(path); } - - bool valid() const { return !host_.empty(); } - void clear() { - host_.clear(); - port_ = HTTP_DEFAULT_PORT; - secure_ = false; - path_.assign(1, static_cast('/')); - query_.clear(); - } - - void set_url(const string& val) { - do_set_url(val.c_str(), val.size()); - } - string url() const { - string val; do_get_url(&val); return val; - } - - void set_address(const string& val) { - do_set_address(val.c_str(), val.size()); - } - string address() const { - string val; do_get_address(&val); return val; - } - - void set_full_path(const string& val) { - do_set_full_path(val.c_str(), val.size()); - } - string full_path() const { - string val; do_get_full_path(&val); return val; - } - - void set_host(const string& val) { host_ = val; } - const string& host() const { return host_; } - - void set_port(uint16 val) { port_ = val; } - uint16 port() const { return port_; } - - void set_secure(bool val) { secure_ = val; } - bool secure() const { return secure_; } - - void set_path(const string& val) { - if (val.empty()) { - path_.assign(1, static_cast('/')); - } else { - ASSERT(val[0] == static_cast('/')); - path_ = val; - } - } - const string& path() const { return path_; } - - void set_query(const string& val) { - ASSERT(val.empty() || (val[0] == static_cast('?'))); - query_ = val; - } - const string& query() const { return query_; } - - bool get_attribute(const string& name, string* value) const; - -private: - void do_set_url(const CTYPE* val, size_t len); - void do_set_address(const CTYPE* val, size_t len); - void do_set_full_path(const CTYPE* val, size_t len); - - void do_get_url(string* val) const; - void do_get_address(string* val) const; - void do_get_full_path(string* val) const; - - string host_, path_, query_; - uint16 port_; - bool secure_; -}; - -////////////////////////////////////////////////////////////////////// -// HttpData -////////////////////////////////////////////////////////////////////// - -struct HttpData { - typedef std::multimap HeaderMap; - typedef HeaderMap::const_iterator const_iterator; - typedef HeaderMap::iterator iterator; - - HttpVersion version; - scoped_ptr document; - - HttpData() : version(HVER_1_1) { } - - enum HeaderCombine { HC_YES, HC_NO, HC_AUTO, HC_REPLACE, HC_NEW }; - void changeHeader(const std::string& name, const std::string& value, - HeaderCombine combine); - inline void addHeader(const std::string& name, const std::string& value, - bool append = true) { - changeHeader(name, value, append ? HC_AUTO : HC_NO); - } - inline void setHeader(const std::string& name, const std::string& value, - bool overwrite = true) { - changeHeader(name, value, overwrite ? HC_REPLACE : HC_NEW); - } - // Returns count of erased headers - size_t clearHeader(const std::string& name); - // Returns iterator to next header - iterator clearHeader(iterator header); - - // keep in mind, this may not do what you want in the face of multiple headers - bool hasHeader(const std::string& name, std::string* value) const; - - inline const_iterator begin() const { - return headers_.begin(); - } - inline const_iterator end() const { - return headers_.end(); - } - inline iterator begin() { - return headers_.begin(); - } - inline iterator end() { - return headers_.end(); - } - inline const_iterator begin(const std::string& name) const { - return headers_.lower_bound(name); - } - inline const_iterator end(const std::string& name) const { - return headers_.upper_bound(name); - } - inline iterator begin(const std::string& name) { - return headers_.lower_bound(name); - } - inline iterator end(const std::string& name) { - return headers_.upper_bound(name); - } - - // Convenience methods using HttpHeader - inline void changeHeader(HttpHeader header, const std::string& value, - HeaderCombine combine) { - changeHeader(ToString(header), value, combine); - } - inline void addHeader(HttpHeader header, const std::string& value, - bool append = true) { - addHeader(ToString(header), value, append); - } - inline void setHeader(HttpHeader header, const std::string& value, - bool overwrite = true) { - setHeader(ToString(header), value, overwrite); - } - inline void clearHeader(HttpHeader header) { - clearHeader(ToString(header)); - } - inline bool hasHeader(HttpHeader header, std::string* value) const { - return hasHeader(ToString(header), value); - } - inline const_iterator begin(HttpHeader header) const { - return headers_.lower_bound(ToString(header)); - } - inline const_iterator end(HttpHeader header) const { - return headers_.upper_bound(ToString(header)); - } - inline iterator begin(HttpHeader header) { - return headers_.lower_bound(ToString(header)); - } - inline iterator end(HttpHeader header) { - return headers_.upper_bound(ToString(header)); - } - - void setContent(const std::string& content_type, StreamInterface* document); - void setDocumentAndLength(StreamInterface* document); - - virtual size_t formatLeader(char* buffer, size_t size) const = 0; - virtual HttpError parseLeader(const char* line, size_t len) = 0; - -protected: - virtual ~HttpData() { } - void clear(bool release_document); - void copy(const HttpData& src); - -private: - HeaderMap headers_; -}; - -struct HttpRequestData : public HttpData { - HttpVerb verb; - std::string path; - - HttpRequestData() : verb(HV_GET) { } - - void clear(bool release_document); - void copy(const HttpRequestData& src); - - virtual size_t formatLeader(char* buffer, size_t size) const; - virtual HttpError parseLeader(const char* line, size_t len); - - bool getAbsoluteUri(std::string* uri) const; - bool getRelativeUri(std::string* host, std::string* path) const; -}; - -struct HttpResponseData : public HttpData { - uint32 scode; - std::string message; - - HttpResponseData() : scode(HC_INTERNAL_SERVER_ERROR) { } - void clear(bool release_document); - void copy(const HttpResponseData& src); - - // Convenience methods - void set_success(uint32 scode = HC_OK); - void set_success(const std::string& content_type, StreamInterface* document, - uint32 scode = HC_OK); - void set_redirect(const std::string& location, - uint32 scode = HC_MOVED_TEMPORARILY); - void set_error(uint32 scode); - - virtual size_t formatLeader(char* buffer, size_t size) const; - virtual HttpError parseLeader(const char* line, size_t len); -}; - -struct HttpTransaction { - HttpRequestData request; - HttpResponseData response; -}; - -////////////////////////////////////////////////////////////////////// -// Http Authentication -////////////////////////////////////////////////////////////////////// - -struct HttpAuthContext { - std::string auth_method; - HttpAuthContext(const std::string& auth) : auth_method(auth) { } - virtual ~HttpAuthContext() { } -}; - -enum HttpAuthResult { HAR_RESPONSE, HAR_IGNORE, HAR_CREDENTIALS, HAR_ERROR }; - -// 'context' is used by this function to record information between calls. -// Start by passing a null pointer, then pass the same pointer each additional -// call. When the authentication attempt is finished, delete the context. -HttpAuthResult HttpAuthenticate( - const char * challenge, size_t len, - const SocketAddress& server, - const std::string& method, const std::string& uri, - const std::string& username, const CryptString& password, - HttpAuthContext *& context, std::string& response, std::string& auth_method); - -////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_HTTPCOMMON_H__ diff --git a/webrtc/base/httpcommon_unittest.cc b/webrtc/base/httpcommon_unittest.cc deleted file mode 100644 index 10e378987..000000000 --- a/webrtc/base/httpcommon_unittest.cc +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/httpcommon-inl.h" -#include "webrtc/base/httpcommon.h" - -namespace rtc { - -#define TEST_PROTOCOL "http://" -#define TEST_HOST "www.google.com" -#define TEST_PATH "/folder/file.html" -#define TEST_QUERY "?query=x&attr=y" -#define TEST_URL TEST_PROTOCOL TEST_HOST TEST_PATH TEST_QUERY - -TEST(Url, DecomposesUrls) { - Url url(TEST_URL); - EXPECT_TRUE(url.valid()); - EXPECT_FALSE(url.secure()); - EXPECT_STREQ(TEST_HOST, url.host().c_str()); - EXPECT_EQ(80, url.port()); - EXPECT_STREQ(TEST_PATH, url.path().c_str()); - EXPECT_STREQ(TEST_QUERY, url.query().c_str()); - EXPECT_STREQ(TEST_HOST, url.address().c_str()); - EXPECT_STREQ(TEST_PATH TEST_QUERY, url.full_path().c_str()); - EXPECT_STREQ(TEST_URL, url.url().c_str()); -} - -TEST(Url, ComposesUrls) { - // Set in constructor - Url url(TEST_PATH TEST_QUERY, TEST_HOST, 80); - EXPECT_TRUE(url.valid()); - EXPECT_FALSE(url.secure()); - EXPECT_STREQ(TEST_HOST, url.host().c_str()); - EXPECT_EQ(80, url.port()); - EXPECT_STREQ(TEST_PATH, url.path().c_str()); - EXPECT_STREQ(TEST_QUERY, url.query().c_str()); - EXPECT_STREQ(TEST_HOST, url.address().c_str()); - EXPECT_STREQ(TEST_PATH TEST_QUERY, url.full_path().c_str()); - EXPECT_STREQ(TEST_URL, url.url().c_str()); - - url.clear(); - EXPECT_FALSE(url.valid()); - EXPECT_FALSE(url.secure()); - EXPECT_STREQ("", url.host().c_str()); - EXPECT_EQ(80, url.port()); - EXPECT_STREQ("/", url.path().c_str()); - EXPECT_STREQ("", url.query().c_str()); - - // Set component-wise - url.set_host(TEST_HOST); - url.set_port(80); - url.set_path(TEST_PATH); - url.set_query(TEST_QUERY); - EXPECT_TRUE(url.valid()); - EXPECT_FALSE(url.secure()); - EXPECT_STREQ(TEST_HOST, url.host().c_str()); - EXPECT_EQ(80, url.port()); - EXPECT_STREQ(TEST_PATH, url.path().c_str()); - EXPECT_STREQ(TEST_QUERY, url.query().c_str()); - EXPECT_STREQ(TEST_HOST, url.address().c_str()); - EXPECT_STREQ(TEST_PATH TEST_QUERY, url.full_path().c_str()); - EXPECT_STREQ(TEST_URL, url.url().c_str()); -} - -TEST(Url, EnsuresNonEmptyPath) { - Url url(TEST_PROTOCOL TEST_HOST); - EXPECT_TRUE(url.valid()); - EXPECT_STREQ("/", url.path().c_str()); - - url.clear(); - EXPECT_STREQ("/", url.path().c_str()); - url.set_path(""); - EXPECT_STREQ("/", url.path().c_str()); - - url.clear(); - EXPECT_STREQ("/", url.path().c_str()); - url.set_full_path(""); - EXPECT_STREQ("/", url.path().c_str()); -} - -TEST(Url, GetQueryAttributes) { - Url url(TEST_URL); - std::string value; - EXPECT_TRUE(url.get_attribute("query", &value)); - EXPECT_STREQ("x", value.c_str()); - value.clear(); - EXPECT_TRUE(url.get_attribute("attr", &value)); - EXPECT_STREQ("y", value.c_str()); - value.clear(); - EXPECT_FALSE(url.get_attribute("Query", &value)); - EXPECT_TRUE(value.empty()); -} - -TEST(Url, SkipsUserAndPassword) { - Url url("https://mail.google.com:pwd@badsite.com:12345/asdf"); - EXPECT_TRUE(url.valid()); - EXPECT_TRUE(url.secure()); - EXPECT_STREQ("badsite.com", url.host().c_str()); - EXPECT_EQ(12345, url.port()); - EXPECT_STREQ("/asdf", url.path().c_str()); - EXPECT_STREQ("badsite.com:12345", url.address().c_str()); -} - -TEST(Url, SkipsUser) { - Url url("https://mail.google.com@badsite.com:12345/asdf"); - EXPECT_TRUE(url.valid()); - EXPECT_TRUE(url.secure()); - EXPECT_STREQ("badsite.com", url.host().c_str()); - EXPECT_EQ(12345, url.port()); - EXPECT_STREQ("/asdf", url.path().c_str()); - EXPECT_STREQ("badsite.com:12345", url.address().c_str()); -} - -TEST(HttpResponseData, parseLeaderHttp1_0) { - static const char kResponseString[] = "HTTP/1.0 200 OK"; - HttpResponseData response; - EXPECT_EQ(HE_NONE, response.parseLeader(kResponseString, - sizeof(kResponseString) - 1)); - EXPECT_EQ(HVER_1_0, response.version); - EXPECT_EQ(200U, response.scode); -} - -TEST(HttpResponseData, parseLeaderHttp1_1) { - static const char kResponseString[] = "HTTP/1.1 200 OK"; - HttpResponseData response; - EXPECT_EQ(HE_NONE, response.parseLeader(kResponseString, - sizeof(kResponseString) - 1)); - EXPECT_EQ(HVER_1_1, response.version); - EXPECT_EQ(200U, response.scode); -} - -TEST(HttpResponseData, parseLeaderHttpUnknown) { - static const char kResponseString[] = "HTTP 200 OK"; - HttpResponseData response; - EXPECT_EQ(HE_NONE, response.parseLeader(kResponseString, - sizeof(kResponseString) - 1)); - EXPECT_EQ(HVER_UNKNOWN, response.version); - EXPECT_EQ(200U, response.scode); -} - -TEST(HttpResponseData, parseLeaderHttpFailure) { - static const char kResponseString[] = "HTTP/1.1 503 Service Unavailable"; - HttpResponseData response; - EXPECT_EQ(HE_NONE, response.parseLeader(kResponseString, - sizeof(kResponseString) - 1)); - EXPECT_EQ(HVER_1_1, response.version); - EXPECT_EQ(503U, response.scode); -} - -TEST(HttpResponseData, parseLeaderHttpInvalid) { - static const char kResponseString[] = "Durrrrr, what's HTTP?"; - HttpResponseData response; - EXPECT_EQ(HE_PROTOCOL, response.parseLeader(kResponseString, - sizeof(kResponseString) - 1)); -} - -} // namespace rtc diff --git a/webrtc/base/httprequest.cc b/webrtc/base/httprequest.cc deleted file mode 100644 index 9ce2377e8..000000000 --- a/webrtc/base/httprequest.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/httprequest.h" - -#include "webrtc/base/common.h" -#include "webrtc/base/firewallsocketserver.h" -#include "webrtc/base/httpclient.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/physicalsocketserver.h" -#include "webrtc/base/socketadapters.h" -#include "webrtc/base/socketpool.h" -#include "webrtc/base/ssladapter.h" - -using namespace rtc; - -/////////////////////////////////////////////////////////////////////////////// -// HttpMonitor -/////////////////////////////////////////////////////////////////////////////// - -HttpMonitor::HttpMonitor(SocketServer *ss) { - ASSERT(Thread::Current() != NULL); - ss_ = ss; - reset(); -} - -void HttpMonitor::Connect(HttpClient *http) { - http->SignalHttpClientComplete.connect(this, - &HttpMonitor::OnHttpClientComplete); -} - -void HttpMonitor::OnHttpClientComplete(HttpClient * http, HttpErrorType error) { - complete_ = true; - error_ = error; - ss_->WakeUp(); -} - -/////////////////////////////////////////////////////////////////////////////// -// HttpRequest -/////////////////////////////////////////////////////////////////////////////// - -const int kDefaultHTTPTimeout = 30 * 1000; // 30 sec - -HttpRequest::HttpRequest(const std::string &user_agent) - : firewall_(0), port_(80), secure_(false), - timeout_(kDefaultHTTPTimeout), fail_redirect_(false), - client_(user_agent.c_str(), NULL), error_(HE_NONE) { -} - -void HttpRequest::Send() { - // TODO: Rewrite this to use the thread's native socket server, and a more - // natural flow? - - PhysicalSocketServer physical; - SocketServer * ss = &physical; - if (firewall_) { - ss = new FirewallSocketServer(ss, firewall_); - } - - SslSocketFactory factory(ss, client_.agent()); - factory.SetProxy(proxy_); - if (secure_) - factory.UseSSL(host_.c_str()); - - //factory.SetLogging("HttpRequest"); - - ReuseSocketPool pool(&factory); - client_.set_pool(&pool); - - bool transparent_proxy = (port_ == 80) && ((proxy_.type == PROXY_HTTPS) || - (proxy_.type == PROXY_UNKNOWN)); - - if (transparent_proxy) { - client_.set_proxy(proxy_); - } - client_.set_fail_redirect(fail_redirect_); - - SocketAddress server(host_, port_); - client_.set_server(server); - - LOG(LS_INFO) << "HttpRequest start: " << host_ + client_.request().path; - - HttpMonitor monitor(ss); - monitor.Connect(&client_); - client_.start(); - ss->Wait(timeout_, true); - if (!monitor.done()) { - LOG(LS_INFO) << "HttpRequest request timed out"; - client_.reset(); - return; - } - - set_error(monitor.error()); - if (error_) { - LOG(LS_INFO) << "HttpRequest request error: " << error_; - return; - } - - std::string value; - if (client_.response().hasHeader(HH_LOCATION, &value)) { - response_redirect_ = value.c_str(); - } -} diff --git a/webrtc/base/httprequest.h b/webrtc/base/httprequest.h deleted file mode 100644 index 37983324c..000000000 --- a/webrtc/base/httprequest.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef _HTTPREQUEST_H_ -#define _HTTPREQUEST_H_ - -#include "webrtc/base/httpclient.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/proxyinfo.h" -#include "webrtc/base/socketserver.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/sslsocketfactory.h" // Deprecated include - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// HttpRequest -/////////////////////////////////////////////////////////////////////////////// - -class FirewallManager; -class MemoryStream; - -class HttpRequest { -public: - HttpRequest(const std::string &user_agent); - - void Send(); - - void set_proxy(const ProxyInfo& proxy) { - proxy_ = proxy; - } - void set_firewall(FirewallManager * firewall) { - firewall_ = firewall; - } - - // The DNS name of the host to connect to. - const std::string& host() { return host_; } - void set_host(const std::string& host) { host_ = host; } - - // The port to connect to on the target host. - int port() { return port_; } - void set_port(int port) { port_ = port; } - - // Whether the request should use SSL. - bool secure() { return secure_; } - void set_secure(bool secure) { secure_ = secure; } - - // Returns the redirect when redirection occurs - const std::string& response_redirect() { return response_redirect_; } - - // Time to wait on the download, in ms. Default is 5000 (5s) - int timeout() { return timeout_; } - void set_timeout(int timeout) { timeout_ = timeout; } - - // Fail redirects to allow analysis of redirect urls, etc. - bool fail_redirect() const { return fail_redirect_; } - void set_fail_redirect(bool fail_redirect) { fail_redirect_ = fail_redirect; } - - HttpRequestData& request() { return client_.request(); } - HttpResponseData& response() { return client_.response(); } - HttpErrorType error() { return error_; } - -protected: - void set_error(HttpErrorType error) { error_ = error; } - -private: - ProxyInfo proxy_; - FirewallManager * firewall_; - std::string host_; - int port_; - bool secure_; - int timeout_; - bool fail_redirect_; - HttpClient client_; - HttpErrorType error_; - std::string response_redirect_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// HttpMonitor -/////////////////////////////////////////////////////////////////////////////// - -class HttpMonitor : public sigslot::has_slots<> { -public: - HttpMonitor(SocketServer *ss); - - void reset() { - complete_ = false; - error_ = HE_DEFAULT; - } - - bool done() const { return complete_; } - HttpErrorType error() const { return error_; } - - void Connect(HttpClient* http); - void OnHttpClientComplete(HttpClient * http, HttpErrorType error); - -private: - bool complete_; - HttpErrorType error_; - SocketServer *ss_; -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc_ - -#endif // _HTTPREQUEST_H_ diff --git a/webrtc/base/httpserver.cc b/webrtc/base/httpserver.cc deleted file mode 100644 index caa58efc2..000000000 --- a/webrtc/base/httpserver.cc +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/httpcommon-inl.h" - -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/common.h" -#include "webrtc/base/httpserver.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/socketstream.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// HttpServer -/////////////////////////////////////////////////////////////////////////////// - -HttpServer::HttpServer() : next_connection_id_(1), closing_(false) { -} - -HttpServer::~HttpServer() { - if (closing_) { - LOG(LS_WARNING) << "HttpServer::CloseAll has not completed"; - } - for (ConnectionMap::iterator it = connections_.begin(); - it != connections_.end(); - ++it) { - StreamInterface* stream = it->second->EndProcess(); - delete stream; - delete it->second; - } -} - -int -HttpServer::HandleConnection(StreamInterface* stream) { - int connection_id = next_connection_id_++; - ASSERT(connection_id != HTTP_INVALID_CONNECTION_ID); - Connection* connection = new Connection(connection_id, this); - connections_.insert(ConnectionMap::value_type(connection_id, connection)); - connection->BeginProcess(stream); - return connection_id; -} - -void -HttpServer::Respond(HttpServerTransaction* transaction) { - int connection_id = transaction->connection_id(); - if (Connection* connection = Find(connection_id)) { - connection->Respond(transaction); - } else { - delete transaction; - // We may be tempted to SignalHttpComplete, but that implies that a - // connection still exists. - } -} - -void -HttpServer::Close(int connection_id, bool force) { - if (Connection* connection = Find(connection_id)) { - connection->InitiateClose(force); - } -} - -void -HttpServer::CloseAll(bool force) { - if (connections_.empty()) { - SignalCloseAllComplete(this); - return; - } - closing_ = true; - std::list connections; - for (ConnectionMap::const_iterator it = connections_.begin(); - it != connections_.end(); ++it) { - connections.push_back(it->second); - } - for (std::list::const_iterator it = connections.begin(); - it != connections.end(); ++it) { - (*it)->InitiateClose(force); - } -} - -HttpServer::Connection* -HttpServer::Find(int connection_id) { - ConnectionMap::iterator it = connections_.find(connection_id); - if (it == connections_.end()) - return NULL; - return it->second; -} - -void -HttpServer::Remove(int connection_id) { - ConnectionMap::iterator it = connections_.find(connection_id); - if (it == connections_.end()) { - ASSERT(false); - return; - } - Connection* connection = it->second; - connections_.erase(it); - SignalConnectionClosed(this, connection_id, connection->EndProcess()); - delete connection; - if (closing_ && connections_.empty()) { - closing_ = false; - SignalCloseAllComplete(this); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// HttpServer::Connection -/////////////////////////////////////////////////////////////////////////////// - -HttpServer::Connection::Connection(int connection_id, HttpServer* server) - : connection_id_(connection_id), server_(server), - current_(NULL), signalling_(false), close_(false) { -} - -HttpServer::Connection::~Connection() { - // It's possible that an object hosted inside this transaction signalled - // an event which caused the connection to close. - Thread::Current()->Dispose(current_); -} - -void -HttpServer::Connection::BeginProcess(StreamInterface* stream) { - base_.notify(this); - base_.attach(stream); - current_ = new HttpServerTransaction(connection_id_); - if (base_.mode() != HM_CONNECT) - base_.recv(¤t_->request); -} - -StreamInterface* -HttpServer::Connection::EndProcess() { - base_.notify(NULL); - base_.abort(HE_DISCONNECTED); - return base_.detach(); -} - -void -HttpServer::Connection::Respond(HttpServerTransaction* transaction) { - ASSERT(current_ == NULL); - current_ = transaction; - if (current_->response.begin() == current_->response.end()) { - current_->response.set_error(HC_INTERNAL_SERVER_ERROR); - } - bool keep_alive = HttpShouldKeepAlive(current_->request); - current_->response.setHeader(HH_CONNECTION, - keep_alive ? "Keep-Alive" : "Close", - false); - close_ = !HttpShouldKeepAlive(current_->response); - base_.send(¤t_->response); -} - -void -HttpServer::Connection::InitiateClose(bool force) { - bool request_in_progress = (HM_SEND == base_.mode()) || (NULL == current_); - if (!signalling_ && (force || !request_in_progress)) { - server_->Remove(connection_id_); - } else { - close_ = true; - } -} - -// -// IHttpNotify Implementation -// - -HttpError -HttpServer::Connection::onHttpHeaderComplete(bool chunked, size_t& data_size) { - if (data_size == SIZE_UNKNOWN) { - data_size = 0; - } - ASSERT(current_ != NULL); - bool custom_document = false; - server_->SignalHttpRequestHeader(server_, current_, &custom_document); - if (!custom_document) { - current_->request.document.reset(new MemoryStream); - } - return HE_NONE; -} - -void -HttpServer::Connection::onHttpComplete(HttpMode mode, HttpError err) { - if (mode == HM_SEND) { - ASSERT(current_ != NULL); - signalling_ = true; - server_->SignalHttpRequestComplete(server_, current_, err); - signalling_ = false; - if (close_) { - // Force a close - err = HE_DISCONNECTED; - } - } - if (err != HE_NONE) { - server_->Remove(connection_id_); - } else if (mode == HM_CONNECT) { - base_.recv(¤t_->request); - } else if (mode == HM_RECV) { - ASSERT(current_ != NULL); - // TODO: do we need this? - //request_.document_->rewind(); - HttpServerTransaction* transaction = current_; - current_ = NULL; - server_->SignalHttpRequest(server_, transaction); - } else if (mode == HM_SEND) { - Thread::Current()->Dispose(current_->response.document.release()); - current_->request.clear(true); - current_->response.clear(true); - base_.recv(¤t_->request); - } else { - ASSERT(false); - } -} - -void -HttpServer::Connection::onHttpClosed(HttpError err) { - UNUSED(err); - server_->Remove(connection_id_); -} - -/////////////////////////////////////////////////////////////////////////////// -// HttpListenServer -/////////////////////////////////////////////////////////////////////////////// - -HttpListenServer::HttpListenServer() { - SignalConnectionClosed.connect(this, &HttpListenServer::OnConnectionClosed); -} - -HttpListenServer::~HttpListenServer() { -} - -int HttpListenServer::Listen(const SocketAddress& address) { - AsyncSocket* sock = - Thread::Current()->socketserver()->CreateAsyncSocket(address.family(), - SOCK_STREAM); - if (!sock) { - return SOCKET_ERROR; - } - listener_.reset(sock); - listener_->SignalReadEvent.connect(this, &HttpListenServer::OnReadEvent); - if ((listener_->Bind(address) != SOCKET_ERROR) && - (listener_->Listen(5) != SOCKET_ERROR)) - return 0; - return listener_->GetError(); -} - -bool HttpListenServer::GetAddress(SocketAddress* address) const { - if (!listener_) { - return false; - } - *address = listener_->GetLocalAddress(); - return !address->IsNil(); -} - -void HttpListenServer::StopListening() { - if (listener_) { - listener_->Close(); - } -} - -void HttpListenServer::OnReadEvent(AsyncSocket* socket) { - ASSERT(socket == listener_.get()); - ASSERT(listener_); - AsyncSocket* incoming = listener_->Accept(NULL); - if (incoming) { - StreamInterface* stream = new SocketStream(incoming); - //stream = new LoggingAdapter(stream, LS_VERBOSE, "HttpServer", false); - HandleConnection(stream); - } -} - -void HttpListenServer::OnConnectionClosed(HttpServer* server, - int connection_id, - StreamInterface* stream) { - Thread::Current()->Dispose(stream); -} - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/httpserver.h b/webrtc/base/httpserver.h deleted file mode 100644 index 77de615fe..000000000 --- a/webrtc/base/httpserver.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_HTTPSERVER_H__ -#define WEBRTC_BASE_HTTPSERVER_H__ - -#include -#include "webrtc/base/httpbase.h" - -namespace rtc { - -class AsyncSocket; -class HttpServer; -class SocketAddress; - -////////////////////////////////////////////////////////////////////// -// HttpServer -////////////////////////////////////////////////////////////////////// - -const int HTTP_INVALID_CONNECTION_ID = 0; - -struct HttpServerTransaction : public HttpTransaction { -public: - HttpServerTransaction(int id) : connection_id_(id) { } - int connection_id() const { return connection_id_; } - -private: - int connection_id_; -}; - -class HttpServer { -public: - HttpServer(); - virtual ~HttpServer(); - - int HandleConnection(StreamInterface* stream); - // Due to sigslot issues, we can't destroy some streams at an arbitrary time. - sigslot::signal3 SignalConnectionClosed; - - // This signal occurs when the HTTP request headers have been received, but - // before the request body is written to the request document. By default, - // the request document is a MemoryStream. By handling this signal, the - // document can be overridden, in which case the third signal argument should - // be set to true. In the case where the request body should be ignored, - // the document can be set to NULL. Note that the transaction object is still - // owened by the HttpServer at this point. - sigslot::signal3 - SignalHttpRequestHeader; - - // An HTTP request has been made, and is available in the transaction object. - // Populate the transaction's response, and then return the object via the - // Respond method. Note that during this time, ownership of the transaction - // object is transferred, so it may be passed between threads, although - // respond must be called on the server's active thread. - sigslot::signal2 SignalHttpRequest; - void Respond(HttpServerTransaction* transaction); - - // If you want to know when a request completes, listen to this event. - sigslot::signal3 - SignalHttpRequestComplete; - - // Stop processing the connection indicated by connection_id. - // Unless force is true, the server will complete sending a response that is - // in progress. - void Close(int connection_id, bool force); - void CloseAll(bool force); - - // After calling CloseAll, this event is signalled to indicate that all - // outstanding connections have closed. - sigslot::signal1 SignalCloseAllComplete; - -private: - class Connection : private IHttpNotify { - public: - Connection(int connection_id, HttpServer* server); - virtual ~Connection(); - - void BeginProcess(StreamInterface* stream); - StreamInterface* EndProcess(); - - void Respond(HttpServerTransaction* transaction); - void InitiateClose(bool force); - - // IHttpNotify Interface - virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size); - virtual void onHttpComplete(HttpMode mode, HttpError err); - virtual void onHttpClosed(HttpError err); - - int connection_id_; - HttpServer* server_; - HttpBase base_; - HttpServerTransaction* current_; - bool signalling_, close_; - }; - - Connection* Find(int connection_id); - void Remove(int connection_id); - - friend class Connection; - typedef std::map ConnectionMap; - - ConnectionMap connections_; - int next_connection_id_; - bool closing_; -}; - -////////////////////////////////////////////////////////////////////// - -class HttpListenServer : public HttpServer, public sigslot::has_slots<> { -public: - HttpListenServer(); - virtual ~HttpListenServer(); - - int Listen(const SocketAddress& address); - bool GetAddress(SocketAddress* address) const; - void StopListening(); - -private: - void OnReadEvent(AsyncSocket* socket); - void OnConnectionClosed(HttpServer* server, int connection_id, - StreamInterface* stream); - - scoped_ptr listener_; -}; - -////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_HTTPSERVER_H__ diff --git a/webrtc/base/httpserver_unittest.cc b/webrtc/base/httpserver_unittest.cc deleted file mode 100644 index 0c653cbb9..000000000 --- a/webrtc/base/httpserver_unittest.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/httpserver.h" -#include "webrtc/base/testutils.h" - -using namespace testing; - -namespace rtc { - -namespace { - const char* const kRequest = - "GET /index.html HTTP/1.1\r\n" - "Host: localhost\r\n" - "\r\n"; - - struct HttpServerMonitor : public sigslot::has_slots<> { - HttpServerTransaction* transaction; - bool server_closed, connection_closed; - - HttpServerMonitor(HttpServer* server) - : transaction(NULL), server_closed(false), connection_closed(false) { - server->SignalCloseAllComplete.connect(this, - &HttpServerMonitor::OnClosed); - server->SignalHttpRequest.connect(this, &HttpServerMonitor::OnRequest); - server->SignalHttpRequestComplete.connect(this, - &HttpServerMonitor::OnRequestComplete); - server->SignalConnectionClosed.connect(this, - &HttpServerMonitor::OnConnectionClosed); - } - void OnRequest(HttpServer*, HttpServerTransaction* t) { - ASSERT_FALSE(transaction); - transaction = t; - transaction->response.set_success(); - transaction->response.setHeader(HH_CONNECTION, "Close"); - } - void OnRequestComplete(HttpServer*, HttpServerTransaction* t, int) { - ASSERT_EQ(transaction, t); - transaction = NULL; - } - void OnClosed(HttpServer*) { - server_closed = true; - } - void OnConnectionClosed(HttpServer*, int, StreamInterface* stream) { - connection_closed = true; - delete stream; - } - }; - - void CreateClientConnection(HttpServer& server, - HttpServerMonitor& monitor, - bool send_request) { - StreamSource* client = new StreamSource; - client->SetState(SS_OPEN); - server.HandleConnection(client); - EXPECT_FALSE(monitor.server_closed); - EXPECT_FALSE(monitor.transaction); - - if (send_request) { - // Simulate a request - client->QueueString(kRequest); - EXPECT_FALSE(monitor.server_closed); - } - } -} // anonymous namespace - -TEST(HttpServer, DoesNotSignalCloseUnlessCloseAllIsCalled) { - HttpServer server; - HttpServerMonitor monitor(&server); - // Add an active client connection - CreateClientConnection(server, monitor, true); - // Simulate a response - ASSERT_TRUE(NULL != monitor.transaction); - server.Respond(monitor.transaction); - EXPECT_FALSE(monitor.transaction); - // Connection has closed, but no server close signal - EXPECT_FALSE(monitor.server_closed); - EXPECT_TRUE(monitor.connection_closed); -} - -TEST(HttpServer, SignalsCloseWhenNoConnectionsAreActive) { - HttpServer server; - HttpServerMonitor monitor(&server); - // Add an idle client connection - CreateClientConnection(server, monitor, false); - // Perform graceful close - server.CloseAll(false); - // Connections have all closed - EXPECT_TRUE(monitor.server_closed); - EXPECT_TRUE(monitor.connection_closed); -} - -TEST(HttpServer, SignalsCloseAfterGracefulCloseAll) { - HttpServer server; - HttpServerMonitor monitor(&server); - // Add an active client connection - CreateClientConnection(server, monitor, true); - // Initiate a graceful close - server.CloseAll(false); - EXPECT_FALSE(monitor.server_closed); - // Simulate a response - ASSERT_TRUE(NULL != monitor.transaction); - server.Respond(monitor.transaction); - EXPECT_FALSE(monitor.transaction); - // Connections have all closed - EXPECT_TRUE(monitor.server_closed); - EXPECT_TRUE(monitor.connection_closed); -} - -TEST(HttpServer, SignalsCloseAfterForcedCloseAll) { - HttpServer server; - HttpServerMonitor monitor(&server); - // Add an active client connection - CreateClientConnection(server, monitor, true); - // Initiate a forceful close - server.CloseAll(true); - // Connections have all closed - EXPECT_TRUE(monitor.server_closed); - EXPECT_TRUE(monitor.connection_closed); -} - -} // namespace rtc diff --git a/webrtc/base/ifaddrs-android.cc b/webrtc/base/ifaddrs-android.cc deleted file mode 100644 index 5d022a79a..000000000 --- a/webrtc/base/ifaddrs-android.cc +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_ANDROID) -#include "webrtc/base/ifaddrs-android.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct netlinkrequest { - nlmsghdr header; - ifaddrmsg msg; -}; - -namespace { -const int kMaxReadSize = 4096; -}; - -int set_ifname(struct ifaddrs* ifaddr, int interface) { - char buf[IFNAMSIZ] = {0}; - char* name = if_indextoname(interface, buf); - if (name == NULL) { - return -1; - } - ifaddr->ifa_name = new char[strlen(name) + 1]; - strncpy(ifaddr->ifa_name, name, strlen(name) + 1); - return 0; -} - -int set_flags(struct ifaddrs* ifaddr) { - int fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd == -1) { - return -1; - } - ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1); - int rc = ioctl(fd, SIOCGIFFLAGS, &ifr); - close(fd); - if (rc == -1) { - return -1; - } - ifaddr->ifa_flags = ifr.ifr_flags; - return 0; -} - -int set_addresses(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* data, - size_t len) { - if (msg->ifa_family == AF_INET) { - sockaddr_in* sa = new sockaddr_in; - sa->sin_family = AF_INET; - memcpy(&sa->sin_addr, data, len); - ifaddr->ifa_addr = reinterpret_cast(sa); - } else if (msg->ifa_family == AF_INET6) { - sockaddr_in6* sa = new sockaddr_in6; - sa->sin6_family = AF_INET6; - sa->sin6_scope_id = msg->ifa_index; - memcpy(&sa->sin6_addr, data, len); - ifaddr->ifa_addr = reinterpret_cast(sa); - } else { - return -1; - } - return 0; -} - -int make_prefixes(struct ifaddrs* ifaddr, int family, int prefixlen) { - char* prefix = NULL; - if (family == AF_INET) { - sockaddr_in* mask = new sockaddr_in; - mask->sin_family = AF_INET; - memset(&mask->sin_addr, 0, sizeof(in_addr)); - ifaddr->ifa_netmask = reinterpret_cast(mask); - if (prefixlen > 32) { - prefixlen = 32; - } - prefix = reinterpret_cast(&mask->sin_addr); - } else if (family == AF_INET6) { - sockaddr_in6* mask = new sockaddr_in6; - mask->sin6_family = AF_INET6; - memset(&mask->sin6_addr, 0, sizeof(in6_addr)); - ifaddr->ifa_netmask = reinterpret_cast(mask); - if (prefixlen > 128) { - prefixlen = 128; - } - prefix = reinterpret_cast(&mask->sin6_addr); - } else { - return -1; - } - for (int i = 0; i < (prefixlen / 8); i++) { - *prefix++ = 0xFF; - } - char remainder = 0xff; - remainder <<= (8 - prefixlen % 8); - *prefix = remainder; - return 0; -} - -int populate_ifaddrs(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* bytes, - size_t len) { - if (set_ifname(ifaddr, msg->ifa_index) != 0) { - return -1; - } - if (set_flags(ifaddr) != 0) { - return -1; - } - if (set_addresses(ifaddr, msg, bytes, len) != 0) { - return -1; - } - if (make_prefixes(ifaddr, msg->ifa_family, msg->ifa_prefixlen) != 0) { - return -1; - } - return 0; -} - -int getifaddrs(struct ifaddrs** result) { - int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (fd < 0) { - return -1; - } - - netlinkrequest ifaddr_request; - memset(&ifaddr_request, 0, sizeof(ifaddr_request)); - ifaddr_request.header.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST; - ifaddr_request.header.nlmsg_type = RTM_GETADDR; - ifaddr_request.header.nlmsg_len = NLMSG_LENGTH(sizeof(ifaddrmsg)); - - ssize_t count = send(fd, &ifaddr_request, ifaddr_request.header.nlmsg_len, 0); - if (static_cast(count) != ifaddr_request.header.nlmsg_len) { - close(fd); - return -1; - } - struct ifaddrs* start = NULL; - struct ifaddrs* current = NULL; - char buf[kMaxReadSize]; - ssize_t amount_read = recv(fd, &buf, kMaxReadSize, 0); - while (amount_read > 0) { - nlmsghdr* header = reinterpret_cast(&buf[0]); - size_t header_size = static_cast(amount_read); - for ( ; NLMSG_OK(header, header_size); - header = NLMSG_NEXT(header, header_size)) { - switch (header->nlmsg_type) { - case NLMSG_DONE: - // Success. Return. - *result = start; - close(fd); - return 0; - case NLMSG_ERROR: - close(fd); - freeifaddrs(start); - return -1; - case RTM_NEWADDR: { - ifaddrmsg* address_msg = - reinterpret_cast(NLMSG_DATA(header)); - rtattr* rta = IFA_RTA(address_msg); - ssize_t payload_len = IFA_PAYLOAD(header); - while (RTA_OK(rta, payload_len)) { - if (rta->rta_type == IFA_ADDRESS) { - int family = address_msg->ifa_family; - if (family == AF_INET || family == AF_INET6) { - ifaddrs* newest = new ifaddrs; - memset(newest, 0, sizeof(ifaddrs)); - if (current) { - current->ifa_next = newest; - } else { - start = newest; - } - if (populate_ifaddrs(newest, address_msg, RTA_DATA(rta), - RTA_PAYLOAD(rta)) != 0) { - freeifaddrs(start); - *result = NULL; - return -1; - } - current = newest; - } - } - rta = RTA_NEXT(rta, payload_len); - } - break; - } - } - } - amount_read = recv(fd, &buf, kMaxReadSize, 0); - } - close(fd); - freeifaddrs(start); - return -1; -} - -void freeifaddrs(struct ifaddrs* addrs) { - struct ifaddrs* last = NULL; - struct ifaddrs* cursor = addrs; - while (cursor) { - delete[] cursor->ifa_name; - delete cursor->ifa_addr; - delete cursor->ifa_netmask; - last = cursor; - cursor = cursor->ifa_next; - delete last; - } -} -#endif // defined(WEBRTC_ANDROID) diff --git a/webrtc/base/ifaddrs-android.h b/webrtc/base/ifaddrs-android.h deleted file mode 100644 index c8671e08f..000000000 --- a/webrtc/base/ifaddrs-android.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_IFADDRS_ANDROID_H_ -#define WEBRTC_BASE_IFADDRS_ANDROID_H_ - -#include -#include -// Implementation of getifaddrs for Android. -// Fills out a list of ifaddr structs (see below) which contain information -// about every network interface available on the host. -// See 'man getifaddrs' on Linux or OS X (nb: it is not a POSIX function). -struct ifaddrs { - struct ifaddrs* ifa_next; - char* ifa_name; - unsigned int ifa_flags; - struct sockaddr* ifa_addr; - struct sockaddr* ifa_netmask; - // Real ifaddrs has broadcast, point to point and data members. - // We don't need them (yet?). -}; - -int getifaddrs(struct ifaddrs** result); -void freeifaddrs(struct ifaddrs* addrs); - -#endif // WEBRTC_BASE_IFADDRS_ANDROID_H_ diff --git a/webrtc/base/iosfilesystem.mm b/webrtc/base/iosfilesystem.mm deleted file mode 100644 index eb4bbecd5..000000000 --- a/webrtc/base/iosfilesystem.mm +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// 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 -#import -#include - -#include "webrtc/base/common.h" -#include "webrtc/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(rtc::Pathname* path) { - NSProcessInfo *pInfo = [NSProcessInfo processInfo]; - NSString* argv0 = [[pInfo arguments] objectAtIndex:0]; - path->SetPathname([argv0 UTF8String]); -} diff --git a/webrtc/base/ipaddress.cc b/webrtc/base/ipaddress.cc deleted file mode 100644 index 4441e16f6..000000000 --- a/webrtc/base/ipaddress.cc +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_POSIX) -#include -#include -#include -#ifdef OPENBSD -#include -#endif -#ifndef __native_client__ -#include -#endif -#include -#include -#include -#endif - -#include - -#include "webrtc/base/ipaddress.h" -#include "webrtc/base/byteorder.h" -#include "webrtc/base/nethelpers.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/win32.h" - -namespace rtc { - -// Prefixes used for categorizing IPv6 addresses. -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 k6BonePrefix = {{{0x3f, 0xfe, 0}}}; - -bool IPAddress::strip_sensitive_ = false; - -static bool IsPrivateV4(uint32 ip); -static in_addr ExtractMappedAddress(const in6_addr& addr); - -uint32 IPAddress::v4AddressAsHostOrderInteger() const { - if (family_ == AF_INET) { - return NetworkToHost32(u_.ip4.s_addr); - } else { - return 0; - } -} - -size_t IPAddress::Size() const { - switch (family_) { - case AF_INET: - return sizeof(in_addr); - case AF_INET6: - return sizeof(in6_addr); - } - return 0; -} - - -bool IPAddress::operator==(const IPAddress &other) const { - if (family_ != other.family_) { - return false; - } - if (family_ == AF_INET) { - return memcmp(&u_.ip4, &other.u_.ip4, sizeof(u_.ip4)) == 0; - } - if (family_ == AF_INET6) { - return memcmp(&u_.ip6, &other.u_.ip6, sizeof(u_.ip6)) == 0; - } - return family_ == AF_UNSPEC; -} - -bool IPAddress::operator!=(const IPAddress &other) const { - return !((*this) == other); -} - -bool IPAddress::operator >(const IPAddress &other) const { - return (*this) != other && !((*this) < other); -} - -bool IPAddress::operator <(const IPAddress &other) const { - // IPv4 is 'less than' IPv6 - if (family_ != other.family_) { - if (family_ == AF_UNSPEC) { - return true; - } - if (family_ == AF_INET && other.family_ == AF_INET6) { - return true; - } - return false; - } - // Comparing addresses of the same family. - switch (family_) { - case AF_INET: { - return NetworkToHost32(u_.ip4.s_addr) < - NetworkToHost32(other.u_.ip4.s_addr); - } - case AF_INET6: { - return memcmp(&u_.ip6.s6_addr, &other.u_.ip6.s6_addr, 16) < 0; - } - } - // Catches AF_UNSPEC and invalid addresses. - return false; -} - -std::ostream& operator<<(std::ostream& os, const IPAddress& ip) { - os << ip.ToString(); - return os; -} - -in6_addr IPAddress::ipv6_address() const { - return u_.ip6; -} - -in_addr IPAddress::ipv4_address() const { - return u_.ip4; -} - -std::string IPAddress::ToString() const { - if (family_ != AF_INET && family_ != AF_INET6) { - return std::string(); - } - char buf[INET6_ADDRSTRLEN] = {0}; - const void* src = &u_.ip4; - if (family_ == AF_INET6) { - src = &u_.ip6; - } - if (!rtc::inet_ntop(family_, src, buf, sizeof(buf))) { - return std::string(); - } - return std::string(buf); -} - -std::string IPAddress::ToSensitiveString() const { - if (!strip_sensitive_) - return ToString(); - - switch (family_) { - case AF_INET: { - std::string address = ToString(); - size_t find_pos = address.rfind('.'); - if (find_pos == std::string::npos) - return std::string(); - address.resize(find_pos); - address += ".x"; - return address; - } - case AF_INET6: { - // TODO(grunell): Return a string of format 1:2:3:x:x:x:x:x or such - // instead of zeroing out. - return TruncateIP(*this, 128 - 80).ToString(); - } - } - return std::string(); -} - -IPAddress IPAddress::Normalized() const { - if (family_ != AF_INET6) { - return *this; - } - if (!IPIsV4Mapped(*this)) { - return *this; - } - in_addr addr = ExtractMappedAddress(u_.ip6); - return IPAddress(addr); -} - -IPAddress IPAddress::AsIPv6Address() const { - if (family_ != AF_INET) { - return *this; - } - in6_addr v6addr = kV4MappedPrefix; - ::memcpy(&v6addr.s6_addr[12], &u_.ip4.s_addr, sizeof(u_.ip4.s_addr)); - return IPAddress(v6addr); -} - -void IPAddress::set_strip_sensitive(bool enable) { - strip_sensitive_ = enable; -} - - -bool IsPrivateV4(uint32 ip_in_host_order) { - return ((ip_in_host_order >> 24) == 127) || - ((ip_in_host_order >> 24) == 10) || - ((ip_in_host_order >> 20) == ((172 << 4) | 1)) || - ((ip_in_host_order >> 16) == ((192 << 8) | 168)) || - ((ip_in_host_order >> 16) == ((169 << 8) | 254)); -} - -in_addr ExtractMappedAddress(const in6_addr& in6) { - in_addr ipv4; - ::memcpy(&ipv4.s_addr, &in6.s6_addr[12], sizeof(ipv4.s_addr)); - return ipv4; -} - -bool IPFromAddrInfo(struct addrinfo* info, IPAddress* out) { - if (!info || !info->ai_addr) { - return false; - } - if (info->ai_addr->sa_family == AF_INET) { - sockaddr_in* addr = reinterpret_cast(info->ai_addr); - *out = IPAddress(addr->sin_addr); - return true; - } else if (info->ai_addr->sa_family == AF_INET6) { - sockaddr_in6* addr = reinterpret_cast(info->ai_addr); - *out = IPAddress(addr->sin6_addr); - return true; - } - return false; -} - -bool IPFromString(const std::string& str, IPAddress* out) { - if (!out) { - return false; - } - in_addr addr; - if (rtc::inet_pton(AF_INET, str.c_str(), &addr) == 0) { - in6_addr addr6; - if (rtc::inet_pton(AF_INET6, str.c_str(), &addr6) == 0) { - *out = IPAddress(); - return false; - } - *out = IPAddress(addr6); - } else { - *out = IPAddress(addr); - } - return true; -} - -bool IPIsAny(const IPAddress& ip) { - switch (ip.family()) { - case AF_INET: - return ip == IPAddress(INADDR_ANY); - case AF_INET6: - return ip == IPAddress(in6addr_any); - case AF_UNSPEC: - return false; - } - return false; -} - -bool IPIsLoopback(const IPAddress& ip) { - switch (ip.family()) { - case AF_INET: { - return ip == IPAddress(INADDR_LOOPBACK); - } - case AF_INET6: { - return ip == IPAddress(in6addr_loopback); - } - } - return false; -} - -bool IPIsPrivate(const IPAddress& ip) { - switch (ip.family()) { - case AF_INET: { - return IsPrivateV4(ip.v4AddressAsHostOrderInteger()); - } - case AF_INET6: { - in6_addr v6 = ip.ipv6_address(); - return (v6.s6_addr[0] == 0xFE && v6.s6_addr[1] == 0x80) || - IPIsLoopback(ip); - } - } - return false; -} - -bool IPIsUnspec(const IPAddress& ip) { - return ip.family() == AF_UNSPEC; -} - -size_t HashIP(const IPAddress& ip) { - switch (ip.family()) { - case AF_INET: { - return ip.ipv4_address().s_addr; - } - case AF_INET6: { - in6_addr v6addr = ip.ipv6_address(); - const uint32* v6_as_ints = - reinterpret_cast(&v6addr.s6_addr); - return v6_as_ints[0] ^ v6_as_ints[1] ^ v6_as_ints[2] ^ v6_as_ints[3]; - } - } - return 0; -} - -IPAddress TruncateIP(const IPAddress& ip, int length) { - if (length < 0) { - return IPAddress(); - } - if (ip.family() == AF_INET) { - if (length > 31) { - return ip; - } - if (length == 0) { - return IPAddress(INADDR_ANY); - } - int mask = (0xFFFFFFFF << (32 - length)); - uint32 host_order_ip = NetworkToHost32(ip.ipv4_address().s_addr); - in_addr masked; - masked.s_addr = HostToNetwork32(host_order_ip & mask); - return IPAddress(masked); - } else if (ip.family() == AF_INET6) { - if (length > 127) { - return ip; - } - if (length == 0) { - return IPAddress(in6addr_any); - } - in6_addr v6addr = ip.ipv6_address(); - int position = length / 32; - int inner_length = 32 - (length - (position * 32)); - // Note: 64bit mask constant needed to allow possible 32-bit left shift. - uint32 inner_mask = 0xFFFFFFFFLL << inner_length; - uint32* v6_as_ints = - reinterpret_cast(&v6addr.s6_addr); - for (int i = 0; i < 4; ++i) { - if (i == position) { - uint32 host_order_inner = NetworkToHost32(v6_as_ints[i]); - v6_as_ints[i] = HostToNetwork32(host_order_inner & inner_mask); - } else if (i > position) { - v6_as_ints[i] = 0; - } - } - return IPAddress(v6addr); - } - return IPAddress(); -} - -int CountIPMaskBits(IPAddress mask) { - uint32 word_to_count = 0; - int bits = 0; - switch (mask.family()) { - case AF_INET: { - word_to_count = NetworkToHost32(mask.ipv4_address().s_addr); - break; - } - case AF_INET6: { - in6_addr v6addr = mask.ipv6_address(); - const uint32* v6_as_ints = - reinterpret_cast(&v6addr.s6_addr); - int i = 0; - for (; i < 4; ++i) { - if (v6_as_ints[i] != 0xFFFFFFFF) { - break; - } - } - if (i < 4) { - word_to_count = NetworkToHost32(v6_as_ints[i]); - } - bits = (i * 32); - break; - } - default: { - return 0; - } - } - if (word_to_count == 0) { - return bits; - } - - // Public domain bit-twiddling hack from: - // http://graphics.stanford.edu/~seander/bithacks.html - // Counts the trailing 0s in the word. - unsigned int zeroes = 32; - word_to_count &= -static_cast(word_to_count); - if (word_to_count) zeroes--; - if (word_to_count & 0x0000FFFF) zeroes -= 16; - if (word_to_count & 0x00FF00FF) zeroes -= 8; - if (word_to_count & 0x0F0F0F0F) zeroes -= 4; - if (word_to_count & 0x33333333) zeroes -= 2; - if (word_to_count & 0x55555555) zeroes -= 1; - - return bits + (32 - zeroes); -} - -bool IPIsHelper(const IPAddress& ip, const in6_addr& tomatch, int length) { - // Helper method for checking IP prefix matches (but only on whole byte - // lengths). Length is in bits. - in6_addr addr = ip.ipv6_address(); - return ::memcmp(&addr, &tomatch, (length >> 3)) == 0; -} - -bool IPIs6Bone(const IPAddress& ip) { - return IPIsHelper(ip, k6BonePrefix, 16); -} - -bool IPIs6To4(const IPAddress& ip) { - return IPIsHelper(ip, k6To4Prefix, 16); -} - -bool IPIsSiteLocal(const IPAddress& ip) { - // Can't use the helper because the prefix is 10 bits. - in6_addr addr = ip.ipv6_address(); - return addr.s6_addr[0] == 0xFE && (addr.s6_addr[1] & 0xC0) == 0xC0; -} - -bool IPIsULA(const IPAddress& ip) { - // Can't use the helper because the prefix is 7 bits. - in6_addr addr = ip.ipv6_address(); - return (addr.s6_addr[0] & 0xFE) == 0xFC; -} - -bool IPIsTeredo(const IPAddress& ip) { - return IPIsHelper(ip, kTeredoPrefix, 32); -} - -bool IPIsV4Compatibility(const IPAddress& ip) { - return IPIsHelper(ip, kV4CompatibilityPrefix, 96); -} - -bool IPIsV4Mapped(const IPAddress& ip) { - return IPIsHelper(ip, kV4MappedPrefix, 96); -} - -int IPAddressPrecedence(const IPAddress& ip) { - // Precedence values from RFC 3484-bis. Prefers native v4 over 6to4/Teredo. - if (ip.family() == AF_INET) { - return 30; - } else if (ip.family() == AF_INET6) { - if (IPIsLoopback(ip)) { - return 60; - } else if (IPIsULA(ip)) { - return 50; - } else if (IPIsV4Mapped(ip)) { - return 30; - } else if (IPIs6To4(ip)) { - return 20; - } else if (IPIsTeredo(ip)) { - return 10; - } else if (IPIsV4Compatibility(ip) || IPIsSiteLocal(ip) || IPIs6Bone(ip)) { - return 1; - } else { - // A 'normal' IPv6 address. - return 40; - } - } - return 0; -} - -} // Namespace talk base diff --git a/webrtc/base/ipaddress.h b/webrtc/base/ipaddress.h deleted file mode 100644 index e7d649acb..000000000 --- a/webrtc/base/ipaddress.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_IPADDRESS_H_ -#define WEBRTC_BASE_IPADDRESS_H_ - -#if defined(WEBRTC_POSIX) -#include -#include -#include -#include -#endif -#if defined(WEBRTC_WIN) -#include -#include -#endif -#include -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/byteorder.h" -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#endif - -namespace rtc { - -// Version-agnostic IP address class, wraps a union of in_addr and in6_addr. -class IPAddress { - public: - IPAddress() : family_(AF_UNSPEC) { - ::memset(&u_, 0, sizeof(u_)); - } - - explicit IPAddress(const in_addr &ip4) : family_(AF_INET) { - memset(&u_, 0, sizeof(u_)); - u_.ip4 = ip4; - } - - explicit IPAddress(const in6_addr &ip6) : family_(AF_INET6) { - u_.ip6 = ip6; - } - - explicit IPAddress(uint32 ip_in_host_byte_order) : family_(AF_INET) { - memset(&u_, 0, sizeof(u_)); - u_.ip4.s_addr = HostToNetwork32(ip_in_host_byte_order); - } - - IPAddress(const IPAddress &other) : family_(other.family_) { - ::memcpy(&u_, &other.u_, sizeof(u_)); - } - - ~IPAddress() {} - - const IPAddress & operator=(const IPAddress &other) { - family_ = other.family_; - ::memcpy(&u_, &other.u_, sizeof(u_)); - return *this; - } - - bool operator==(const IPAddress &other) const; - bool operator!=(const IPAddress &other) const; - bool operator <(const IPAddress &other) const; - bool operator >(const IPAddress &other) const; - friend std::ostream& operator<<(std::ostream& os, const IPAddress& addr); - - int family() const { return family_; } - in_addr ipv4_address() const; - in6_addr ipv6_address() const; - - // Returns the number of bytes needed to store the raw address. - size_t Size() const; - - // Wraps inet_ntop. - std::string ToString() const; - - // Same as ToString but anonymizes it by hiding the last part. - std::string ToSensitiveString() const; - - // Returns an unmapped address from a possibly-mapped address. - // Returns the same address if this isn't a mapped address. - IPAddress Normalized() const; - - // Returns this address as an IPv6 address. - // Maps v4 addresses (as ::ffff:a.b.c.d), returns v6 addresses unchanged. - IPAddress AsIPv6Address() const; - - // For socketaddress' benefit. Returns the IP in host byte order. - uint32 v4AddressAsHostOrderInteger() const; - - static void set_strip_sensitive(bool enable); - - private: - int family_; - union { - in_addr ip4; - in6_addr ip6; - } u_; - - static bool strip_sensitive_; -}; - -bool IPFromAddrInfo(struct addrinfo* info, IPAddress* out); -bool IPFromString(const std::string& str, IPAddress* out); -bool IPIsAny(const IPAddress& ip); -bool IPIsLoopback(const IPAddress& ip); -bool IPIsPrivate(const IPAddress& ip); -bool IPIsUnspec(const IPAddress& ip); -size_t HashIP(const IPAddress& ip); - -// These are only really applicable for IPv6 addresses. -bool IPIs6Bone(const IPAddress& ip); -bool IPIs6To4(const IPAddress& ip); -bool IPIsSiteLocal(const IPAddress& ip); -bool IPIsTeredo(const IPAddress& ip); -bool IPIsULA(const IPAddress& ip); -bool IPIsV4Compatibility(const IPAddress& ip); -bool IPIsV4Mapped(const IPAddress& ip); - -// Returns the precedence value for this IP as given in RFC3484. -int IPAddressPrecedence(const IPAddress& ip); - -// Returns 'ip' truncated to be 'length' bits long. -IPAddress TruncateIP(const IPAddress& ip, int length); - -// Returns the number of contiguously set bits, counting from the MSB in network -// byte order, in this IPAddress. Bits after the first 0 encountered are not -// counted. -int CountIPMaskBits(IPAddress mask); - -} // namespace rtc - -#endif // WEBRTC_BASE_IPADDRESS_H_ diff --git a/webrtc/base/ipaddress_unittest.cc b/webrtc/base/ipaddress_unittest.cc deleted file mode 100644 index 657595f68..000000000 --- a/webrtc/base/ipaddress_unittest.cc +++ /dev/null @@ -1,859 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/ipaddress.h" - -namespace rtc { - -static const unsigned int kIPv4AddrSize = 4; -static const unsigned int kIPv6AddrSize = 16; -static const unsigned int kIPv4RFC1918Addr = 0xC0A80701; -static const unsigned int kIPv4PublicAddr = 0x01020304; -static const in6_addr kIPv6LinkLocalAddr = {{{0xfe, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0xbe, 0x30, 0x5b, 0xff, - 0xfe, 0xe5, 0x00, 0xc3}}}; -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 kIPv4MappedAnyAddr = {{{0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00}}}; -static const in6_addr kIPv4MappedRFC1918Addr = {{{0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, - 0xc0, 0xa8, 0x07, 0x01}}}; -static const in6_addr kIPv4MappedPublicAddr = {{{0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, - 0x01, 0x02, 0x03, 0x04}}}; - -static const std::string kIPv4AnyAddrString = "0.0.0.0"; -static const std::string kIPv4LoopbackAddrString = "127.0.0.1"; -static const std::string kIPv4RFC1918AddrString = "192.168.7.1"; -static const std::string kIPv4PublicAddrString = "1.2.3.4"; -static const std::string kIPv4PublicAddrAnonymizedString = "1.2.3.x"; -static const std::string kIPv6AnyAddrString = "::"; -static const std::string kIPv6LoopbackAddrString = "::1"; -static const std::string kIPv6LinkLocalAddrString = "fe80::be30:5bff:fee5:c3"; -static const std::string kIPv6PublicAddrString = - "2401:fa00:4:1000:be30:5bff:fee5:c3"; -static const std::string kIPv6PublicAddrAnonymizedString = "2401:fa00:4::"; -static const std::string kIPv4MappedAnyAddrString = "::ffff:0:0"; -static const std::string kIPv4MappedRFC1918AddrString = "::ffff:c0a8:701"; -static const std::string kIPv4MappedLoopbackAddrString = "::ffff:7f00:1"; -static const std::string kIPv4MappedPublicAddrString = "::ffff:102:0304"; -static const std::string kIPv4MappedV4StyleAddrString = "::ffff:192.168.7.1"; - -static const std::string kIPv4BrokenString1 = "192.168.7."; -static const std::string kIPv4BrokenString2 = "192.168.7.1.1"; -static const std::string kIPv4BrokenString3 = "192.168.7.1:80"; -static const std::string kIPv4BrokenString4 = "192.168.7.ONE"; -static const std::string kIPv4BrokenString5 = "-192.168.7.1"; -static const std::string kIPv4BrokenString6 = "256.168.7.1"; -static const std::string kIPv6BrokenString1 = "2401:fa00:4:1000:be30"; -static const std::string kIPv6BrokenString2 = - "2401:fa00:4:1000:be30:5bff:fee5:c3:1"; -static const std::string kIPv6BrokenString3 = - "[2401:fa00:4:1000:be30:5bff:fee5:c3]:1"; -static const std::string kIPv6BrokenString4 = - "2401::4::be30"; -static const std::string kIPv6BrokenString5 = - "2401:::4:fee5:be30"; -static const std::string kIPv6BrokenString6 = - "2401f:fa00:4:1000:be30:5bff:fee5:c3"; -static const std::string kIPv6BrokenString7 = - "2401:ga00:4:1000:be30:5bff:fee5:c3"; -static const std::string kIPv6BrokenString8 = - "2401:fa000:4:1000:be30:5bff:fee5:c3"; -static const std::string kIPv6BrokenString9 = - "2401:fal0:4:1000:be30:5bff:fee5:c3"; -static const std::string kIPv6BrokenString10 = - "::ffff:192.168.7."; -static const std::string kIPv6BrokenString11 = - "::ffff:192.168.7.1.1.1"; -static const std::string kIPv6BrokenString12 = - "::fffe:192.168.7.1"; -static const std::string kIPv6BrokenString13 = - "::ffff:192.168.7.ff"; -static const std::string kIPv6BrokenString14 = - "0x2401:fa00:4:1000:be30:5bff:fee5:c3"; - -bool AreEqual(const IPAddress& addr, - const IPAddress& addr2) { - if ((IPIsAny(addr) != IPIsAny(addr2)) || - (IPIsLoopback(addr) != IPIsLoopback(addr2)) || - (IPIsPrivate(addr) != IPIsPrivate(addr2)) || - (HashIP(addr) != HashIP(addr2)) || - (addr.Size() != addr2.Size()) || - (addr.family() != addr2.family()) || - (addr.ToString() != addr2.ToString())) { - return false; - } - in_addr v4addr, v4addr2; - v4addr = addr.ipv4_address(); - v4addr2 = addr2.ipv4_address(); - if (0 != memcmp(&v4addr, &v4addr2, sizeof(v4addr))) { - return false; - } - in6_addr v6addr, v6addr2; - v6addr = addr.ipv6_address(); - v6addr2 = addr2.ipv6_address(); - if (0 != memcmp(&v6addr, &v6addr2, sizeof(v6addr))) { - return false; - } - return true; -} - -bool BrokenIPStringFails(const std::string& broken) { - IPAddress addr(0); // Intentionally make it v4. - if (IPFromString(kIPv4BrokenString1, &addr)) { - return false; - } - return addr.family() == AF_UNSPEC; -} - -bool CheckMaskCount(const std::string& mask, int expected_length) { - IPAddress addr; - return IPFromString(mask, &addr) && - (expected_length == CountIPMaskBits(addr)); -} - -bool TryInvalidMaskCount(const std::string& mask) { - // We don't care about the result at all, but we do want to know if - // CountIPMaskBits is going to crash or infinite loop or something. - IPAddress addr; - if (!IPFromString(mask, &addr)) { - return false; - } - CountIPMaskBits(addr); - return true; -} - -bool CheckTruncateIP(const std::string& initial, int truncate_length, - const std::string& expected_result) { - IPAddress addr, expected; - IPFromString(initial, &addr); - IPFromString(expected_result, &expected); - IPAddress truncated = TruncateIP(addr, truncate_length); - return truncated == expected; -} - -TEST(IPAddressTest, TestDefaultCtor) { - IPAddress addr; - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_FALSE(IPIsPrivate(addr)); - - EXPECT_EQ(0U, addr.Size()); - EXPECT_EQ(AF_UNSPEC, addr.family()); - EXPECT_EQ("", addr.ToString()); -} - -TEST(IPAddressTest, TestInAddrCtor) { - in_addr v4addr; - - // Test V4 Any address. - v4addr.s_addr = INADDR_ANY; - IPAddress addr(v4addr); - EXPECT_TRUE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_FALSE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv4AddrSize, addr.Size()); - EXPECT_EQ(kIPv4AnyAddrString, addr.ToString()); - - // Test a V4 loopback address. - v4addr.s_addr = htonl(INADDR_LOOPBACK); - addr = IPAddress(v4addr); - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_TRUE(IPIsLoopback(addr)); - EXPECT_TRUE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv4AddrSize, addr.Size()); - EXPECT_EQ(kIPv4LoopbackAddrString, addr.ToString()); - - // Test an RFC1918 address. - v4addr.s_addr = htonl(kIPv4RFC1918Addr); - addr = IPAddress(v4addr); - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_TRUE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv4AddrSize, addr.Size()); - EXPECT_EQ(kIPv4RFC1918AddrString, addr.ToString()); - - // Test a 'normal' v4 address. - v4addr.s_addr = htonl(kIPv4PublicAddr); - addr = IPAddress(v4addr); - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_FALSE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv4AddrSize, addr.Size()); - EXPECT_EQ(kIPv4PublicAddrString, addr.ToString()); -} - -TEST(IPAddressTest, TestInAddr6Ctor) { - // Test v6 empty. - IPAddress addr(in6addr_any); - EXPECT_TRUE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_FALSE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv6AddrSize, addr.Size()); - EXPECT_EQ(kIPv6AnyAddrString, addr.ToString()); - - // Test v6 loopback. - addr = IPAddress(in6addr_loopback); - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_TRUE(IPIsLoopback(addr)); - EXPECT_TRUE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv6AddrSize, addr.Size()); - EXPECT_EQ(kIPv6LoopbackAddrString, addr.ToString()); - - // Test v6 link-local. - addr = IPAddress(kIPv6LinkLocalAddr); - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_TRUE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv6AddrSize, addr.Size()); - EXPECT_EQ(kIPv6LinkLocalAddrString, addr.ToString()); - - // Test v6 global address. - addr = IPAddress(kIPv6PublicAddr); - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_FALSE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv6AddrSize, addr.Size()); - EXPECT_EQ(kIPv6PublicAddrString, addr.ToString()); -} - -TEST(IPAddressTest, TestUint32Ctor) { - // Test V4 Any address. - IPAddress addr(0); - EXPECT_TRUE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_FALSE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv4AddrSize, addr.Size()); - EXPECT_EQ(kIPv4AnyAddrString, addr.ToString()); - - // Test a V4 loopback address. - addr = IPAddress(INADDR_LOOPBACK); - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_TRUE(IPIsLoopback(addr)); - EXPECT_TRUE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv4AddrSize, addr.Size()); - EXPECT_EQ(kIPv4LoopbackAddrString, addr.ToString()); - - // Test an RFC1918 address. - addr = IPAddress(kIPv4RFC1918Addr); - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_TRUE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv4AddrSize, addr.Size()); - EXPECT_EQ(kIPv4RFC1918AddrString, addr.ToString()); - - // Test a 'normal' v4 address. - addr = IPAddress(kIPv4PublicAddr); - EXPECT_FALSE(IPIsAny(addr)); - EXPECT_FALSE(IPIsLoopback(addr)); - EXPECT_FALSE(IPIsPrivate(addr)); - EXPECT_EQ(kIPv4AddrSize, addr.Size()); - EXPECT_EQ(kIPv4PublicAddrString, addr.ToString()); -} - -TEST(IPAddressTest, TestCopyCtor) { - in_addr v4addr; - v4addr.s_addr = htonl(kIPv4PublicAddr); - IPAddress addr(v4addr); - IPAddress addr2(addr); - - EXPECT_PRED2(AreEqual, addr, addr2); - - addr = IPAddress(INADDR_ANY); - addr2 = IPAddress(addr); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr = IPAddress(INADDR_LOOPBACK); - addr2 = IPAddress(addr); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr = IPAddress(kIPv4PublicAddr); - addr2 = IPAddress(addr); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr = IPAddress(kIPv4RFC1918Addr); - addr2 = IPAddress(addr); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr = IPAddress(in6addr_any); - addr2 = IPAddress(addr); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr = IPAddress(in6addr_loopback); - addr2 = IPAddress(addr); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr = IPAddress(kIPv6LinkLocalAddr); - addr2 = IPAddress(addr); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr = IPAddress(kIPv6PublicAddr); - addr2 = IPAddress(addr); - EXPECT_PRED2(AreEqual, addr, addr2); -} - -TEST(IPAddressTest, TestEquality) { - // Check v4 equality - in_addr v4addr, v4addr2; - v4addr.s_addr = htonl(kIPv4PublicAddr); - v4addr2.s_addr = htonl(kIPv4PublicAddr + 1); - IPAddress addr(v4addr); - IPAddress addr2(v4addr2); - IPAddress addr3(v4addr); - - EXPECT_TRUE(addr == addr); - EXPECT_TRUE(addr2 == addr2); - EXPECT_TRUE(addr3 == addr3); - EXPECT_TRUE(addr == addr3); - EXPECT_TRUE(addr3 == addr); - EXPECT_FALSE(addr2 == addr); - EXPECT_FALSE(addr2 == addr3); - EXPECT_FALSE(addr == addr2); - EXPECT_FALSE(addr3 == addr2); - - // Check v6 equality - IPAddress addr4(kIPv6PublicAddr); - IPAddress addr5(kIPv6LinkLocalAddr); - IPAddress addr6(kIPv6PublicAddr); - - EXPECT_TRUE(addr4 == addr4); - EXPECT_TRUE(addr5 == addr5); - EXPECT_TRUE(addr4 == addr6); - EXPECT_TRUE(addr6 == addr4); - EXPECT_FALSE(addr4 == addr5); - EXPECT_FALSE(addr5 == addr4); - EXPECT_FALSE(addr6 == addr5); - EXPECT_FALSE(addr5 == addr6); - - // Check v4/v6 cross-equality - EXPECT_FALSE(addr == addr4); - EXPECT_FALSE(addr == addr5); - EXPECT_FALSE(addr == addr6); - EXPECT_FALSE(addr4 == addr); - EXPECT_FALSE(addr5 == addr); - EXPECT_FALSE(addr6 == addr); - EXPECT_FALSE(addr2 == addr4); - EXPECT_FALSE(addr2 == addr5); - EXPECT_FALSE(addr2 == addr6); - EXPECT_FALSE(addr4 == addr2); - EXPECT_FALSE(addr5 == addr2); - EXPECT_FALSE(addr6 == addr2); - EXPECT_FALSE(addr3 == addr4); - EXPECT_FALSE(addr3 == addr5); - EXPECT_FALSE(addr3 == addr6); - EXPECT_FALSE(addr4 == addr3); - EXPECT_FALSE(addr5 == addr3); - EXPECT_FALSE(addr6 == addr3); - - // Special cases: loopback and any. - // They're special but they're still not equal. - IPAddress v4loopback(htonl(INADDR_LOOPBACK)); - IPAddress v6loopback(in6addr_loopback); - EXPECT_FALSE(v4loopback == v6loopback); - - IPAddress v4any(0); - IPAddress v6any(in6addr_any); - EXPECT_FALSE(v4any == v6any); -} - -TEST(IPAddressTest, TestComparison) { - // Defined in 'ascending' order. - // v6 > v4, and intra-family sorting is purely numerical - IPAddress addr0; // AF_UNSPEC - IPAddress addr1(INADDR_ANY); // 0.0.0.0 - IPAddress addr2(kIPv4PublicAddr); // 1.2.3.4 - IPAddress addr3(INADDR_LOOPBACK); // 127.0.0.1 - IPAddress addr4(kIPv4RFC1918Addr); // 192.168.7.1. - IPAddress addr5(in6addr_any); // :: - IPAddress addr6(in6addr_loopback); // ::1 - IPAddress addr7(kIPv6PublicAddr); // 2401.... - IPAddress addr8(kIPv6LinkLocalAddr); // fe80.... - - EXPECT_TRUE(addr0 < addr1); - EXPECT_TRUE(addr1 < addr2); - EXPECT_TRUE(addr2 < addr3); - EXPECT_TRUE(addr3 < addr4); - EXPECT_TRUE(addr4 < addr5); - EXPECT_TRUE(addr5 < addr6); - EXPECT_TRUE(addr6 < addr7); - EXPECT_TRUE(addr7 < addr8); - - EXPECT_FALSE(addr0 > addr1); - EXPECT_FALSE(addr1 > addr2); - EXPECT_FALSE(addr2 > addr3); - EXPECT_FALSE(addr3 > addr4); - EXPECT_FALSE(addr4 > addr5); - EXPECT_FALSE(addr5 > addr6); - EXPECT_FALSE(addr6 > addr7); - EXPECT_FALSE(addr7 > addr8); - - EXPECT_FALSE(addr0 > addr0); - EXPECT_FALSE(addr1 > addr1); - EXPECT_FALSE(addr2 > addr2); - EXPECT_FALSE(addr3 > addr3); - EXPECT_FALSE(addr4 > addr4); - EXPECT_FALSE(addr5 > addr5); - EXPECT_FALSE(addr6 > addr6); - EXPECT_FALSE(addr7 > addr7); - EXPECT_FALSE(addr8 > addr8); - - EXPECT_FALSE(addr0 < addr0); - EXPECT_FALSE(addr1 < addr1); - EXPECT_FALSE(addr2 < addr2); - EXPECT_FALSE(addr3 < addr3); - EXPECT_FALSE(addr4 < addr4); - EXPECT_FALSE(addr5 < addr5); - EXPECT_FALSE(addr6 < addr6); - EXPECT_FALSE(addr7 < addr7); - EXPECT_FALSE(addr8 < addr8); -} - -TEST(IPAddressTest, TestFromString) { - IPAddress addr; - IPAddress addr2; - addr2 = IPAddress(INADDR_ANY); - - EXPECT_TRUE(IPFromString(kIPv4AnyAddrString, &addr)); - EXPECT_EQ(addr.ToString(), kIPv4AnyAddrString); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr2 = IPAddress(INADDR_LOOPBACK); - EXPECT_TRUE(IPFromString(kIPv4LoopbackAddrString, &addr)); - EXPECT_EQ(addr.ToString(), kIPv4LoopbackAddrString); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr2 = IPAddress(kIPv4RFC1918Addr); - EXPECT_TRUE(IPFromString(kIPv4RFC1918AddrString, &addr)); - EXPECT_EQ(addr.ToString(), kIPv4RFC1918AddrString); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr2 = IPAddress(kIPv4PublicAddr); - EXPECT_TRUE(IPFromString(kIPv4PublicAddrString, &addr)); - EXPECT_EQ(addr.ToString(), kIPv4PublicAddrString); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr2 = IPAddress(in6addr_any); - EXPECT_TRUE(IPFromString(kIPv6AnyAddrString, &addr)); - EXPECT_EQ(addr.ToString(), kIPv6AnyAddrString); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr2 = IPAddress(in6addr_loopback); - EXPECT_TRUE(IPFromString(kIPv6LoopbackAddrString, &addr)); - EXPECT_EQ(addr.ToString(), kIPv6LoopbackAddrString); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr2 = IPAddress(kIPv6LinkLocalAddr); - EXPECT_TRUE(IPFromString(kIPv6LinkLocalAddrString, &addr)); - EXPECT_EQ(addr.ToString(), kIPv6LinkLocalAddrString); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr2 = IPAddress(kIPv6PublicAddr); - EXPECT_TRUE(IPFromString(kIPv6PublicAddrString, &addr)); - EXPECT_EQ(addr.ToString(), kIPv6PublicAddrString); - EXPECT_PRED2(AreEqual, addr, addr2); - - addr2 = IPAddress(kIPv4MappedRFC1918Addr); - EXPECT_TRUE(IPFromString(kIPv4MappedV4StyleAddrString, &addr)); - EXPECT_PRED2(AreEqual, addr, addr2); - - // Broken cases, should set addr to AF_UNSPEC. - EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString1); - EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString2); - EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString3); - EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString4); - EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString5); - EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString6); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString1); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString2); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString3); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString4); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString5); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString6); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString7); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString8); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString9); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString10); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString11); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString12); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString13); - EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString14); -} - -TEST(IPAddressTest, TestIPFromAddrInfo) { - struct sockaddr_in expected4; - struct sockaddr_in6 expected6; - struct addrinfo test_info; - struct addrinfo next_info; - memset(&next_info, 'A', sizeof(next_info)); - test_info.ai_next = &next_info; - // Check that we can get an IPv4 address out. - test_info.ai_addr = reinterpret_cast(&expected4); - expected4.sin_addr.s_addr = HostToNetwork32(kIPv4PublicAddr); - expected4.sin_family = AF_INET; - IPAddress expected(kIPv4PublicAddr); - IPAddress addr; - EXPECT_TRUE(IPFromAddrInfo(&test_info, &addr)); - EXPECT_EQ(expected, addr); - // Check that we can get an IPv6 address out. - expected6.sin6_addr = kIPv6PublicAddr; - expected6.sin6_family = AF_INET6; - expected = IPAddress(kIPv6PublicAddr); - test_info.ai_addr = reinterpret_cast(&expected6); - EXPECT_TRUE(IPFromAddrInfo(&test_info, &addr)); - EXPECT_EQ(expected, addr); - // Check that unspec fails. - expected6.sin6_family = AF_UNSPEC; - EXPECT_FALSE(IPFromAddrInfo(&test_info, &addr)); - // Check a zeroed out addrinfo doesn't crash us. - memset(&next_info, 0, sizeof(next_info)); - EXPECT_FALSE(IPFromAddrInfo(&next_info, &addr)); -} - -TEST(IPAddressTest, TestIsPrivate) { - EXPECT_FALSE(IPIsPrivate(IPAddress(INADDR_ANY))); - EXPECT_FALSE(IPIsPrivate(IPAddress(kIPv4PublicAddr))); - EXPECT_FALSE(IPIsPrivate(IPAddress(in6addr_any))); - EXPECT_FALSE(IPIsPrivate(IPAddress(kIPv6PublicAddr))); - EXPECT_FALSE(IPIsPrivate(IPAddress(kIPv4MappedAnyAddr))); - EXPECT_FALSE(IPIsPrivate(IPAddress(kIPv4MappedPublicAddr))); - - EXPECT_TRUE(IPIsPrivate(IPAddress(kIPv4RFC1918Addr))); - EXPECT_TRUE(IPIsPrivate(IPAddress(INADDR_LOOPBACK))); - EXPECT_TRUE(IPIsPrivate(IPAddress(in6addr_loopback))); - EXPECT_TRUE(IPIsPrivate(IPAddress(kIPv6LinkLocalAddr))); -} - -TEST(IPAddressTest, TestIsLoopback) { - EXPECT_FALSE(IPIsLoopback(IPAddress(INADDR_ANY))); - EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4PublicAddr))); - EXPECT_FALSE(IPIsLoopback(IPAddress(in6addr_any))); - EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv6PublicAddr))); - EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4MappedAnyAddr))); - EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4MappedPublicAddr))); - - EXPECT_TRUE(IPIsLoopback(IPAddress(INADDR_LOOPBACK))); - EXPECT_TRUE(IPIsLoopback(IPAddress(in6addr_loopback))); -} - -TEST(IPAddressTest, TestNormalized) { - // Check normalizing a ::ffff:a.b.c.d address. - IPAddress addr; - EXPECT_TRUE(IPFromString(kIPv4MappedV4StyleAddrString, &addr)); - IPAddress addr2(kIPv4RFC1918Addr); - addr = addr.Normalized(); - EXPECT_EQ(addr2, addr); - - // Check normalizing a ::ffff:aabb:ccdd address. - addr = IPAddress(kIPv4MappedPublicAddr); - addr2 = IPAddress(kIPv4PublicAddr); - addr = addr.Normalized(); - EXPECT_EQ(addr, addr2); - - // Check that a non-mapped v6 addresses isn't altered. - addr = IPAddress(kIPv6PublicAddr); - addr2 = IPAddress(kIPv6PublicAddr); - addr = addr.Normalized(); - EXPECT_EQ(addr, addr2); - - // Check that addresses that look a bit like mapped addresses aren't altered - EXPECT_TRUE(IPFromString("fe80::ffff:0102:0304", &addr)); - addr2 = addr; - addr = addr.Normalized(); - EXPECT_EQ(addr, addr2); - EXPECT_TRUE(IPFromString("::0102:0304", &addr)); - addr2 = addr; - addr = addr.Normalized(); - EXPECT_EQ(addr, addr2); - // This string should 'work' as an IP address but is not a mapped address, - // so it shouldn't change on normalization. - EXPECT_TRUE(IPFromString("::192.168.7.1", &addr)); - addr2 = addr; - addr = addr.Normalized(); - EXPECT_EQ(addr, addr2); - - // Check that v4 addresses aren't altered. - addr = IPAddress(htonl(kIPv4PublicAddr)); - addr2 = IPAddress(htonl(kIPv4PublicAddr)); - addr = addr.Normalized(); - EXPECT_EQ(addr, addr2); -} - -TEST(IPAddressTest, TestAsIPv6Address) { - IPAddress addr(kIPv4PublicAddr); - IPAddress addr2(kIPv4MappedPublicAddr); - addr = addr.AsIPv6Address(); - EXPECT_EQ(addr, addr2); - - addr = IPAddress(kIPv4MappedPublicAddr); - addr2 = IPAddress(kIPv4MappedPublicAddr); - addr = addr.AsIPv6Address(); - EXPECT_EQ(addr, addr2); - - addr = IPAddress(kIPv6PublicAddr); - addr2 = IPAddress(kIPv6PublicAddr); - addr = addr.AsIPv6Address(); - EXPECT_EQ(addr, addr2); -} - -TEST(IPAddressTest, TestCountIPMaskBits) { - IPAddress mask; - // IPv4 on byte boundaries - EXPECT_PRED2(CheckMaskCount, "255.255.255.255", 32); - EXPECT_PRED2(CheckMaskCount, "255.255.255.0", 24); - EXPECT_PRED2(CheckMaskCount, "255.255.0.0", 16); - EXPECT_PRED2(CheckMaskCount, "255.0.0.0", 8); - EXPECT_PRED2(CheckMaskCount, "0.0.0.0", 0); - - // IPv4 not on byte boundaries - EXPECT_PRED2(CheckMaskCount, "128.0.0.0", 1); - EXPECT_PRED2(CheckMaskCount, "224.0.0.0", 3); - EXPECT_PRED2(CheckMaskCount, "255.248.0.0", 13); - EXPECT_PRED2(CheckMaskCount, "255.255.224.0", 19); - EXPECT_PRED2(CheckMaskCount, "255.255.255.252", 30); - - // V6 on byte boundaries - EXPECT_PRED2(CheckMaskCount, "::", 0); - EXPECT_PRED2(CheckMaskCount, "ff00::", 8); - EXPECT_PRED2(CheckMaskCount, "ffff::", 16); - EXPECT_PRED2(CheckMaskCount, "ffff:ff00::", 24); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff::", 32); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ff00::", 40); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff::", 48); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ff00::", 56); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff::", 64); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ff00::", 72); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff::", 80); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ff00::", 88); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff::", 96); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:ff00:0000", 104); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0000", 112); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00", 120); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128); - - // V6 not on byte boundaries. - EXPECT_PRED2(CheckMaskCount, "8000::", 1); - EXPECT_PRED2(CheckMaskCount, "ff80::", 9); - EXPECT_PRED2(CheckMaskCount, "ffff:fe00::", 23); - EXPECT_PRED2(CheckMaskCount, "ffff:fffe::", 31); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:e000::", 35); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffe0::", 43); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:f800::", 53); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:fff8::", 61); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:fc00::", 70); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:fffc::", 78); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:8000::", 81); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ff80::", 89); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:fe00::", 103); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:fffe:0000", 111); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fc00", 118); - EXPECT_PRED2(CheckMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc", 126); - - // Non-contiguous ranges. These are invalid but lets test them - // to make sure they don't crash anything or infinite loop or something. - EXPECT_PRED1(TryInvalidMaskCount, "217.0.0.0"); - EXPECT_PRED1(TryInvalidMaskCount, "255.185.0.0"); - EXPECT_PRED1(TryInvalidMaskCount, "255.255.251.0"); - EXPECT_PRED1(TryInvalidMaskCount, "255.255.251.255"); - EXPECT_PRED1(TryInvalidMaskCount, "255.255.254.201"); - EXPECT_PRED1(TryInvalidMaskCount, "::1"); - EXPECT_PRED1(TryInvalidMaskCount, "fe80::1"); - EXPECT_PRED1(TryInvalidMaskCount, "ff80::1"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff::1"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ff00:1::1"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff::ffff:1"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ff00:1::"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff::ff00"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff:ff00:1234::"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff:ffff:0012::ffff"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff:ffff:ff01::"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff:ffff:ffff:7f00::"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff:ffff:ffff:ff7a::"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:7f00:0000"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:ff70:0000"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0211"); - EXPECT_PRED1(TryInvalidMaskCount, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff7f"); -} - -TEST(IPAddressTest, TestTruncateIP) { - EXPECT_PRED3(CheckTruncateIP, "255.255.255.255", 24, "255.255.255.0"); - EXPECT_PRED3(CheckTruncateIP, "255.255.255.255", 16, "255.255.0.0"); - EXPECT_PRED3(CheckTruncateIP, "255.255.255.255", 8, "255.0.0.0"); - EXPECT_PRED3(CheckTruncateIP, "202.67.7.255", 24, "202.67.7.0"); - EXPECT_PRED3(CheckTruncateIP, "202.129.65.205", 16, "202.129.0.0"); - EXPECT_PRED3(CheckTruncateIP, "55.25.2.77", 8, "55.0.0.0"); - EXPECT_PRED3(CheckTruncateIP, "74.128.99.254", 1, "0.0.0.0"); - EXPECT_PRED3(CheckTruncateIP, "106.55.99.254", 3, "96.0.0.0"); - EXPECT_PRED3(CheckTruncateIP, "172.167.53.222", 13, "172.160.0.0"); - EXPECT_PRED3(CheckTruncateIP, "255.255.224.0", 18, "255.255.192.0"); - EXPECT_PRED3(CheckTruncateIP, "255.255.255.252", 28, "255.255.255.240"); - - EXPECT_PRED3(CheckTruncateIP, "fe80:1111:2222:3333:4444:5555:6666:7777", 1, - "8000::"); - EXPECT_PRED3(CheckTruncateIP, "fff0:1111:2222:3333:4444:5555:6666:7777", 9, - "ff80::"); - EXPECT_PRED3(CheckTruncateIP, "ffff:ff80:1111:2222:3333:4444:5555:6666", 23, - "ffff:fe00::"); - EXPECT_PRED3(CheckTruncateIP, "ffff:ff80:1111:2222:3333:4444:5555:6666", 32, - "ffff:ff80::"); - EXPECT_PRED3(CheckTruncateIP, "2400:f9af:e456:1111:2222:3333:4444:5555", 35, - "2400:f9af:e000::"); - EXPECT_PRED3(CheckTruncateIP, "9999:1111:2233:4444:5555:6666:7777:8888", 53, - "9999:1111:2233:4000::"); - EXPECT_PRED3(CheckTruncateIP, "9999:1111:2233:4567:5555:6666:7777:8888", 64, - "9999:1111:2233:4567::"); - EXPECT_PRED3(CheckTruncateIP, "1111:2222:3333:4444:5555:6666:7777:8888", 68, - "1111:2222:3333:4444:5000::"); - EXPECT_PRED3(CheckTruncateIP, "1111:2222:3333:4444:5555:6666:7777:8888", 92, - "1111:2222:3333:4444:5555:6660::"); - EXPECT_PRED3(CheckTruncateIP, "1111:2222:3333:4444:5555:6666:7777:8888", 96, - "1111:2222:3333:4444:5555:6666::"); - EXPECT_PRED3(CheckTruncateIP, "1111:2222:3333:4444:5555:6666:7777:8888", 105, - "1111:2222:3333:4444:5555:6666:7700::"); - EXPECT_PRED3(CheckTruncateIP, "1111:2222:3333:4444:5555:6666:7777:8888", 124, - "1111:2222:3333:4444:5555:6666:7777:8880"); - - // Slightly degenerate cases - EXPECT_PRED3(CheckTruncateIP, "202.165.33.127", 32, "202.165.33.127"); - EXPECT_PRED3(CheckTruncateIP, "235.105.77.12", 0, "0.0.0.0"); - EXPECT_PRED3(CheckTruncateIP, "1111:2222:3333:4444:5555:6666:7777:8888", 128, - "1111:2222:3333:4444:5555:6666:7777:8888"); - EXPECT_PRED3(CheckTruncateIP, "1111:2222:3333:4444:5555:6666:7777:8888", 0, - "::"); -} - -TEST(IPAddressTest, TestCategorizeIPv6) { - // Test determining if an IPAddress is 6Bone/6To4/Teredo/etc. - // IPv4 address, should be none of these (not even v4compat/v4mapped). - IPAddress v4_addr(kIPv4PublicAddr); - EXPECT_FALSE(IPIs6Bone(v4_addr)); - EXPECT_FALSE(IPIs6To4(v4_addr)); - EXPECT_FALSE(IPIsSiteLocal(v4_addr)); - EXPECT_FALSE(IPIsTeredo(v4_addr)); - EXPECT_FALSE(IPIsULA(v4_addr)); - EXPECT_FALSE(IPIsV4Compatibility(v4_addr)); - EXPECT_FALSE(IPIsV4Mapped(v4_addr)); - // Linklocal (fe80::/16) adddress; should be none of these. - IPAddress linklocal_addr(kIPv6LinkLocalAddr); - EXPECT_FALSE(IPIs6Bone(linklocal_addr)); - EXPECT_FALSE(IPIs6To4(linklocal_addr)); - EXPECT_FALSE(IPIsSiteLocal(linklocal_addr)); - EXPECT_FALSE(IPIsTeredo(linklocal_addr)); - EXPECT_FALSE(IPIsULA(linklocal_addr)); - EXPECT_FALSE(IPIsV4Compatibility(linklocal_addr)); - EXPECT_FALSE(IPIsV4Mapped(linklocal_addr)); - // 'Normal' IPv6 address, should also be none of these. - IPAddress normal_addr(kIPv6PublicAddr); - EXPECT_FALSE(IPIs6Bone(normal_addr)); - EXPECT_FALSE(IPIs6To4(normal_addr)); - EXPECT_FALSE(IPIsSiteLocal(normal_addr)); - EXPECT_FALSE(IPIsTeredo(normal_addr)); - EXPECT_FALSE(IPIsULA(normal_addr)); - EXPECT_FALSE(IPIsV4Compatibility(normal_addr)); - EXPECT_FALSE(IPIsV4Mapped(normal_addr)); - // IPv4 mapped address (::ffff:123.123.123.123) - IPAddress v4mapped_addr(kIPv4MappedPublicAddr); - EXPECT_TRUE(IPIsV4Mapped(v4mapped_addr)); - EXPECT_FALSE(IPIsV4Compatibility(v4mapped_addr)); - EXPECT_FALSE(IPIs6Bone(v4mapped_addr)); - EXPECT_FALSE(IPIs6To4(v4mapped_addr)); - EXPECT_FALSE(IPIsSiteLocal(v4mapped_addr)); - EXPECT_FALSE(IPIsTeredo(v4mapped_addr)); - EXPECT_FALSE(IPIsULA(v4mapped_addr)); - // IPv4 compatibility address (::123.123.123.123) - IPAddress v4compat_addr; - IPFromString("::192.168.7.1", &v4compat_addr); - EXPECT_TRUE(IPIsV4Compatibility(v4compat_addr)); - EXPECT_FALSE(IPIs6Bone(v4compat_addr)); - EXPECT_FALSE(IPIs6To4(v4compat_addr)); - EXPECT_FALSE(IPIsSiteLocal(v4compat_addr)); - EXPECT_FALSE(IPIsTeredo(v4compat_addr)); - EXPECT_FALSE(IPIsULA(v4compat_addr)); - EXPECT_FALSE(IPIsV4Mapped(v4compat_addr)); - // 6Bone address (3FFE::/16) - IPAddress sixbone_addr; - IPFromString("3FFE:123:456::789:123", &sixbone_addr); - EXPECT_TRUE(IPIs6Bone(sixbone_addr)); - EXPECT_FALSE(IPIs6To4(sixbone_addr)); - EXPECT_FALSE(IPIsSiteLocal(sixbone_addr)); - EXPECT_FALSE(IPIsTeredo(sixbone_addr)); - EXPECT_FALSE(IPIsULA(sixbone_addr)); - EXPECT_FALSE(IPIsV4Mapped(sixbone_addr)); - EXPECT_FALSE(IPIsV4Compatibility(sixbone_addr)); - // Unique Local Address (FC::/7) - IPAddress ula_addr; - IPFromString("FC00:123:456::789:123", &ula_addr); - EXPECT_TRUE(IPIsULA(ula_addr)); - EXPECT_FALSE(IPIs6Bone(ula_addr)); - EXPECT_FALSE(IPIs6To4(ula_addr)); - EXPECT_FALSE(IPIsSiteLocal(ula_addr)); - EXPECT_FALSE(IPIsTeredo(ula_addr)); - EXPECT_FALSE(IPIsV4Mapped(ula_addr)); - EXPECT_FALSE(IPIsV4Compatibility(ula_addr)); - // 6To4 Address (2002::/16) - IPAddress sixtofour_addr; - IPFromString("2002:123:456::789:123", &sixtofour_addr); - EXPECT_TRUE(IPIs6To4(sixtofour_addr)); - EXPECT_FALSE(IPIs6Bone(sixtofour_addr)); - EXPECT_FALSE(IPIsSiteLocal(sixtofour_addr)); - EXPECT_FALSE(IPIsTeredo(sixtofour_addr)); - EXPECT_FALSE(IPIsULA(sixtofour_addr)); - EXPECT_FALSE(IPIsV4Compatibility(sixtofour_addr)); - EXPECT_FALSE(IPIsV4Mapped(sixtofour_addr)); - // Site Local address (FEC0::/10) - IPAddress sitelocal_addr; - IPFromString("FEC0:123:456::789:123", &sitelocal_addr); - EXPECT_TRUE(IPIsSiteLocal(sitelocal_addr)); - EXPECT_FALSE(IPIs6Bone(sitelocal_addr)); - EXPECT_FALSE(IPIs6To4(sitelocal_addr)); - EXPECT_FALSE(IPIsTeredo(sitelocal_addr)); - EXPECT_FALSE(IPIsULA(sitelocal_addr)); - EXPECT_FALSE(IPIsV4Compatibility(sitelocal_addr)); - EXPECT_FALSE(IPIsV4Mapped(sitelocal_addr)); - // Teredo Address (2001:0000::/32) - IPAddress teredo_addr; - IPFromString("2001:0000:123:456::789:123", &teredo_addr); - EXPECT_TRUE(IPIsTeredo(teredo_addr)); - EXPECT_FALSE(IPIsSiteLocal(teredo_addr)); - EXPECT_FALSE(IPIs6Bone(teredo_addr)); - EXPECT_FALSE(IPIs6To4(teredo_addr)); - EXPECT_FALSE(IPIsULA(teredo_addr)); - EXPECT_FALSE(IPIsV4Compatibility(teredo_addr)); - EXPECT_FALSE(IPIsV4Mapped(teredo_addr)); -} - -TEST(IPAddressTest, TestToSensitiveString) { - IPAddress addr_v4 = IPAddress(kIPv4PublicAddr); - EXPECT_EQ(kIPv4PublicAddrString, addr_v4.ToString()); - EXPECT_EQ(kIPv4PublicAddrString, addr_v4.ToSensitiveString()); - IPAddress::set_strip_sensitive(true); - EXPECT_EQ(kIPv4PublicAddrString, addr_v4.ToString()); - EXPECT_EQ(kIPv4PublicAddrAnonymizedString, addr_v4.ToSensitiveString()); - IPAddress::set_strip_sensitive(false); - - IPAddress addr_v6 = IPAddress(kIPv6PublicAddr); - EXPECT_EQ(kIPv6PublicAddrString, addr_v6.ToString()); - EXPECT_EQ(kIPv6PublicAddrString, addr_v6.ToSensitiveString()); - IPAddress::set_strip_sensitive(true); - EXPECT_EQ(kIPv6PublicAddrString, addr_v6.ToString()); - EXPECT_EQ(kIPv6PublicAddrAnonymizedString, addr_v6.ToSensitiveString()); - IPAddress::set_strip_sensitive(false); -} - -} // namespace rtc diff --git a/webrtc/base/json.cc b/webrtc/base/json.cc deleted file mode 100644 index 49a051c01..000000000 --- a/webrtc/base/json.cc +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/json.h" - -#include -#include -#include - -#include - -bool GetStringFromJson(const Json::Value& in, std::string* out) { - if (!in.isString()) { - std::ostringstream s; - if (in.isBool()) { - s << std::boolalpha << in.asBool(); - } else if (in.isInt()) { - s << in.asInt(); - } else if (in.isUInt()) { - s << in.asUInt(); - } else if (in.isDouble()) { - s << in.asDouble(); - } else { - return false; - } - *out = s.str(); - } else { - *out = in.asString(); - } - return true; -} - -bool GetIntFromJson(const Json::Value& in, int* out) { - bool ret; - if (!in.isString()) { - ret = in.isConvertibleTo(Json::intValue); - if (ret) { - *out = in.asInt(); - } - } else { - long val; // NOLINT - const char* c_str = in.asCString(); - char* end_ptr; - errno = 0; - val = strtol(c_str, &end_ptr, 10); // NOLINT - ret = (end_ptr != c_str && *end_ptr == '\0' && !errno && - val >= INT_MIN && val <= INT_MAX); - *out = val; - } - return ret; -} - -bool GetUIntFromJson(const Json::Value& in, unsigned int* out) { - bool ret; - if (!in.isString()) { - ret = in.isConvertibleTo(Json::uintValue); - if (ret) { - *out = in.asUInt(); - } - } else { - unsigned long val; // NOLINT - const char* c_str = in.asCString(); - char* end_ptr; - errno = 0; - val = strtoul(c_str, &end_ptr, 10); // NOLINT - ret = (end_ptr != c_str && *end_ptr == '\0' && !errno && - val <= UINT_MAX); - *out = val; - } - return ret; -} - -bool GetBoolFromJson(const Json::Value& in, bool* out) { - bool ret; - if (!in.isString()) { - ret = in.isConvertibleTo(Json::booleanValue); - if (ret) { - *out = in.asBool(); - } - } else { - if (in.asString() == "true") { - *out = true; - ret = true; - } else if (in.asString() == "false") { - *out = false; - ret = true; - } else { - ret = false; - } - } - return ret; -} - -bool GetDoubleFromJson(const Json::Value& in, double* out) { - bool ret; - if (!in.isString()) { - ret = in.isConvertibleTo(Json::realValue); - if (ret) { - *out = in.asDouble(); - } - } else { - double val; - const char* c_str = in.asCString(); - char* end_ptr; - errno = 0; - val = strtod(c_str, &end_ptr); - ret = (end_ptr != c_str && *end_ptr == '\0' && !errno); - *out = val; - } - return ret; -} - -namespace { -template -bool JsonArrayToVector(const Json::Value& value, - bool (*getter)(const Json::Value& in, T* out), - std::vector *vec) { - vec->clear(); - if (!value.isArray()) { - return false; - } - - for (Json::Value::ArrayIndex i = 0; i < value.size(); ++i) { - T val; - if (!getter(value[i], &val)) { - return false; - } - vec->push_back(val); - } - - return true; -} -// Trivial getter helper -bool GetValueFromJson(const Json::Value& in, Json::Value* out) { - *out = in; - return true; -} -} // unnamed namespace - -bool JsonArrayToValueVector(const Json::Value& in, - std::vector* out) { - return JsonArrayToVector(in, GetValueFromJson, out); -} - -bool JsonArrayToIntVector(const Json::Value& in, - std::vector* out) { - return JsonArrayToVector(in, GetIntFromJson, out); -} - -bool JsonArrayToUIntVector(const Json::Value& in, - std::vector* out) { - return JsonArrayToVector(in, GetUIntFromJson, out); -} - -bool JsonArrayToStringVector(const Json::Value& in, - std::vector* out) { - return JsonArrayToVector(in, GetStringFromJson, out); -} - -bool JsonArrayToBoolVector(const Json::Value& in, - std::vector* out) { - return JsonArrayToVector(in, GetBoolFromJson, out); -} - -bool JsonArrayToDoubleVector(const Json::Value& in, - std::vector* out) { - return JsonArrayToVector(in, GetDoubleFromJson, out); -} - -namespace { -template -Json::Value VectorToJsonArray(const std::vector& vec) { - Json::Value result(Json::arrayValue); - for (size_t i = 0; i < vec.size(); ++i) { - result.append(Json::Value(vec[i])); - } - return result; -} -} // unnamed namespace - -Json::Value ValueVectorToJsonArray(const std::vector& in) { - return VectorToJsonArray(in); -} - -Json::Value IntVectorToJsonArray(const std::vector& in) { - return VectorToJsonArray(in); -} - -Json::Value UIntVectorToJsonArray(const std::vector& in) { - return VectorToJsonArray(in); -} - -Json::Value StringVectorToJsonArray(const std::vector& in) { - return VectorToJsonArray(in); -} - -Json::Value BoolVectorToJsonArray(const std::vector& in) { - return VectorToJsonArray(in); -} - -Json::Value DoubleVectorToJsonArray(const std::vector& in) { - return VectorToJsonArray(in); -} - -bool GetValueFromJsonArray(const Json::Value& in, size_t n, - Json::Value* out) { - if (!in.isArray() || !in.isValidIndex(static_cast(n))) { - return false; - } - - *out = in[static_cast(n)]; - return true; -} - -bool GetIntFromJsonArray(const Json::Value& in, size_t n, - int* out) { - Json::Value x; - return GetValueFromJsonArray(in, n, &x) && GetIntFromJson(x, out); -} - -bool GetUIntFromJsonArray(const Json::Value& in, size_t n, - unsigned int* out) { - Json::Value x; - return GetValueFromJsonArray(in, n, &x) && GetUIntFromJson(x, out); -} - -bool GetStringFromJsonArray(const Json::Value& in, size_t n, - std::string* out) { - Json::Value x; - return GetValueFromJsonArray(in, n, &x) && GetStringFromJson(x, out); -} - -bool GetBoolFromJsonArray(const Json::Value& in, size_t n, - bool* out) { - Json::Value x; - return GetValueFromJsonArray(in, n, &x) && GetBoolFromJson(x, out); -} - -bool GetDoubleFromJsonArray(const Json::Value& in, size_t n, - double* out) { - Json::Value x; - return GetValueFromJsonArray(in, n, &x) && GetDoubleFromJson(x, out); -} - -bool GetValueFromJsonObject(const Json::Value& in, const std::string& k, - Json::Value* out) { - if (!in.isObject() || !in.isMember(k)) { - return false; - } - - *out = in[k]; - return true; -} - -bool GetIntFromJsonObject(const Json::Value& in, const std::string& k, - int* out) { - Json::Value x; - return GetValueFromJsonObject(in, k, &x) && GetIntFromJson(x, out); -} - -bool GetUIntFromJsonObject(const Json::Value& in, const std::string& k, - unsigned int* out) { - Json::Value x; - return GetValueFromJsonObject(in, k, &x) && GetUIntFromJson(x, out); -} - -bool GetStringFromJsonObject(const Json::Value& in, const std::string& k, - std::string* out) { - Json::Value x; - return GetValueFromJsonObject(in, k, &x) && GetStringFromJson(x, out); -} - -bool GetBoolFromJsonObject(const Json::Value& in, const std::string& k, - bool* out) { - Json::Value x; - return GetValueFromJsonObject(in, k, &x) && GetBoolFromJson(x, out); -} - -bool GetDoubleFromJsonObject(const Json::Value& in, const std::string& k, - double* out) { - Json::Value x; - return GetValueFromJsonObject(in, k, &x) && GetDoubleFromJson(x, out); -} - -std::string JsonValueToString(const Json::Value& json) { - Json::FastWriter w; - std::string value = w.write(json); - return value.substr(0, value.size() - 1); // trim trailing newline -} diff --git a/webrtc/base/json.h b/webrtc/base/json.h deleted file mode 100644 index fe41ac805..000000000 --- a/webrtc/base/json.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_JSON_H_ -#define WEBRTC_BASE_JSON_H_ - -#include -#include - -#if !defined(WEBRTC_CHROMIUM_BUILD) -#include "json/json.h" -#else -#include "third_party/jsoncpp/json.h" -#endif - -// TODO: Move to rtc namespace - -/////////////////////////////////////////////////////////////////////////////// -// JSON Helpers -/////////////////////////////////////////////////////////////////////////////// - -// Robust conversion operators, better than the ones in JsonCpp. -bool GetIntFromJson(const Json::Value& in, int* out); -bool GetUIntFromJson(const Json::Value& in, unsigned int* out); -bool GetStringFromJson(const Json::Value& in, std::string* out); -bool GetBoolFromJson(const Json::Value& in, bool* out); -bool GetDoubleFromJson(const Json::Value& in, double* out); - -// Pull values out of a JSON array. -bool GetValueFromJsonArray(const Json::Value& in, size_t n, - Json::Value* out); -bool GetIntFromJsonArray(const Json::Value& in, size_t n, - int* out); -bool GetUIntFromJsonArray(const Json::Value& in, size_t n, - unsigned int* out); -bool GetStringFromJsonArray(const Json::Value& in, size_t n, - std::string* out); -bool GetBoolFromJsonArray(const Json::Value& in, size_t n, - bool* out); -bool GetDoubleFromJsonArray(const Json::Value& in, size_t n, - double* out); - -// Convert json arrays to std::vector -bool JsonArrayToValueVector(const Json::Value& in, - std::vector* out); -bool JsonArrayToIntVector(const Json::Value& in, - std::vector* out); -bool JsonArrayToUIntVector(const Json::Value& in, - std::vector* out); -bool JsonArrayToStringVector(const Json::Value& in, - std::vector* out); -bool JsonArrayToBoolVector(const Json::Value& in, - std::vector* out); -bool JsonArrayToDoubleVector(const Json::Value& in, - std::vector* out); - -// Convert std::vector to json array -Json::Value ValueVectorToJsonArray(const std::vector& in); -Json::Value IntVectorToJsonArray(const std::vector& in); -Json::Value UIntVectorToJsonArray(const std::vector& in); -Json::Value StringVectorToJsonArray(const std::vector& in); -Json::Value BoolVectorToJsonArray(const std::vector& in); -Json::Value DoubleVectorToJsonArray(const std::vector& in); - -// Pull values out of a JSON object. -bool GetValueFromJsonObject(const Json::Value& in, const std::string& k, - Json::Value* out); -bool GetIntFromJsonObject(const Json::Value& in, const std::string& k, - int* out); -bool GetUIntFromJsonObject(const Json::Value& in, const std::string& k, - unsigned int* out); -bool GetStringFromJsonObject(const Json::Value& in, const std::string& k, - std::string* out); -bool GetBoolFromJsonObject(const Json::Value& in, const std::string& k, - bool* out); -bool GetDoubleFromJsonObject(const Json::Value& in, const std::string& k, - double* out); - -// Writes out a Json value as a string. -std::string JsonValueToString(const Json::Value& json); - -#endif // WEBRTC_BASE_JSON_H_ diff --git a/webrtc/base/json_unittest.cc b/webrtc/base/json_unittest.cc deleted file mode 100644 index e7e58227b..000000000 --- a/webrtc/base/json_unittest.cc +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "webrtc/base/gunit.h" -#include "webrtc/base/json.h" - -static Json::Value in_s("foo"); -static Json::Value in_sn("99"); -static Json::Value in_si("-99"); -static Json::Value in_sb("true"); -static Json::Value in_sd("1.2"); -static Json::Value in_n(12); -static Json::Value in_i(-12); -static Json::Value in_u(34U); -static Json::Value in_b(true); -static Json::Value in_d(1.2); -static Json::Value big_sn("12345678901234567890"); -static Json::Value big_si("-12345678901234567890"); -static Json::Value big_u(0xFFFFFFFF); -static Json::Value bad_a(Json::arrayValue); -static Json::Value bad_o(Json::objectValue); - -TEST(JsonTest, GetString) { - std::string out; - EXPECT_TRUE(GetStringFromJson(in_s, &out)); - EXPECT_EQ("foo", out); - EXPECT_TRUE(GetStringFromJson(in_sn, &out)); - EXPECT_EQ("99", out); - EXPECT_TRUE(GetStringFromJson(in_si, &out)); - EXPECT_EQ("-99", out); - EXPECT_TRUE(GetStringFromJson(in_i, &out)); - EXPECT_EQ("-12", out); - EXPECT_TRUE(GetStringFromJson(in_n, &out)); - EXPECT_EQ("12", out); - EXPECT_TRUE(GetStringFromJson(in_u, &out)); - EXPECT_EQ("34", out); - EXPECT_TRUE(GetStringFromJson(in_b, &out)); - EXPECT_EQ("true", out); - // Not supported here yet. - EXPECT_FALSE(GetStringFromJson(bad_a, &out)); - EXPECT_FALSE(GetStringFromJson(bad_o, &out)); -} - -TEST(JsonTest, GetInt) { - int out; - EXPECT_TRUE(GetIntFromJson(in_sn, &out)); - EXPECT_EQ(99, out); - EXPECT_TRUE(GetIntFromJson(in_si, &out)); - EXPECT_EQ(-99, out); - EXPECT_TRUE(GetIntFromJson(in_n, &out)); - EXPECT_EQ(12, out); - EXPECT_TRUE(GetIntFromJson(in_i, &out)); - EXPECT_EQ(-12, out); - EXPECT_TRUE(GetIntFromJson(in_u, &out)); - EXPECT_EQ(34, out); - EXPECT_TRUE(GetIntFromJson(in_b, &out)); - EXPECT_EQ(1, out); - EXPECT_FALSE(GetIntFromJson(in_s, &out)); - EXPECT_FALSE(GetIntFromJson(big_sn, &out)); - EXPECT_FALSE(GetIntFromJson(big_si, &out)); - EXPECT_FALSE(GetIntFromJson(big_u, &out)); - EXPECT_FALSE(GetIntFromJson(bad_a, &out)); - EXPECT_FALSE(GetIntFromJson(bad_o, &out)); -} - -TEST(JsonTest, GetUInt) { - unsigned int out; - EXPECT_TRUE(GetUIntFromJson(in_sn, &out)); - EXPECT_EQ(99U, out); - EXPECT_TRUE(GetUIntFromJson(in_n, &out)); - EXPECT_EQ(12U, out); - EXPECT_TRUE(GetUIntFromJson(in_u, &out)); - EXPECT_EQ(34U, out); - EXPECT_TRUE(GetUIntFromJson(in_b, &out)); - EXPECT_EQ(1U, out); - EXPECT_TRUE(GetUIntFromJson(big_u, &out)); - EXPECT_EQ(0xFFFFFFFFU, out); - EXPECT_FALSE(GetUIntFromJson(in_s, &out)); - // TODO: Fail reading negative strings. - // EXPECT_FALSE(GetUIntFromJson(in_si, &out)); - EXPECT_FALSE(GetUIntFromJson(in_i, &out)); - EXPECT_FALSE(GetUIntFromJson(big_sn, &out)); - EXPECT_FALSE(GetUIntFromJson(big_si, &out)); - EXPECT_FALSE(GetUIntFromJson(bad_a, &out)); - EXPECT_FALSE(GetUIntFromJson(bad_o, &out)); -} - -TEST(JsonTest, GetBool) { - bool out; - EXPECT_TRUE(GetBoolFromJson(in_sb, &out)); - EXPECT_EQ(true, out); - EXPECT_TRUE(GetBoolFromJson(in_n, &out)); - EXPECT_EQ(true, out); - EXPECT_TRUE(GetBoolFromJson(in_i, &out)); - EXPECT_EQ(true, out); - EXPECT_TRUE(GetBoolFromJson(in_u, &out)); - EXPECT_EQ(true, out); - EXPECT_TRUE(GetBoolFromJson(in_b, &out)); - EXPECT_EQ(true, out); - EXPECT_TRUE(GetBoolFromJson(big_u, &out)); - EXPECT_EQ(true, out); - EXPECT_FALSE(GetBoolFromJson(in_s, &out)); - EXPECT_FALSE(GetBoolFromJson(in_sn, &out)); - EXPECT_FALSE(GetBoolFromJson(in_si, &out)); - EXPECT_FALSE(GetBoolFromJson(big_sn, &out)); - EXPECT_FALSE(GetBoolFromJson(big_si, &out)); - EXPECT_FALSE(GetBoolFromJson(bad_a, &out)); - EXPECT_FALSE(GetBoolFromJson(bad_o, &out)); -} - -TEST(JsonTest, GetDouble) { - double out; - EXPECT_TRUE(GetDoubleFromJson(in_sn, &out)); - EXPECT_EQ(99, out); - EXPECT_TRUE(GetDoubleFromJson(in_si, &out)); - EXPECT_EQ(-99, out); - EXPECT_TRUE(GetDoubleFromJson(in_sd, &out)); - EXPECT_EQ(1.2, out); - EXPECT_TRUE(GetDoubleFromJson(in_n, &out)); - EXPECT_EQ(12, out); - EXPECT_TRUE(GetDoubleFromJson(in_i, &out)); - EXPECT_EQ(-12, out); - EXPECT_TRUE(GetDoubleFromJson(in_u, &out)); - EXPECT_EQ(34, out); - EXPECT_TRUE(GetDoubleFromJson(in_b, &out)); - EXPECT_EQ(1, out); - EXPECT_TRUE(GetDoubleFromJson(in_d, &out)); - EXPECT_EQ(1.2, out); - EXPECT_FALSE(GetDoubleFromJson(in_s, &out)); -} - -TEST(JsonTest, GetFromArray) { - Json::Value a, out; - a.append(in_s); - a.append(in_i); - a.append(in_u); - a.append(in_b); - EXPECT_TRUE(GetValueFromJsonArray(a, 0, &out)); - EXPECT_TRUE(GetValueFromJsonArray(a, 3, &out)); - EXPECT_FALSE(GetValueFromJsonArray(a, 99, &out)); - EXPECT_FALSE(GetValueFromJsonArray(a, 0xFFFFFFFF, &out)); -} - -TEST(JsonTest, GetFromObject) { - Json::Value o, out; - o["string"] = in_s; - o["int"] = in_i; - o["uint"] = in_u; - o["bool"] = in_b; - EXPECT_TRUE(GetValueFromJsonObject(o, "int", &out)); - EXPECT_TRUE(GetValueFromJsonObject(o, "bool", &out)); - EXPECT_FALSE(GetValueFromJsonObject(o, "foo", &out)); - EXPECT_FALSE(GetValueFromJsonObject(o, "", &out)); -} - -namespace { -template -std::vector VecOf3(const T& a, const T& b, const T& c) { - std::vector in; - in.push_back(a); - in.push_back(b); - in.push_back(c); - return in; -} -template -Json::Value JsonVecOf3(const T& a, const T& b, const T& c) { - Json::Value in(Json::arrayValue); - in.append(a); - in.append(b); - in.append(c); - return in; -} -} // unnamed namespace - -TEST(JsonTest, ValueVectorToFromArray) { - std::vector in = VecOf3("a", "b", "c"); - Json::Value out = ValueVectorToJsonArray(in); - EXPECT_EQ(in.size(), out.size()); - for (Json::Value::ArrayIndex i = 0; i < in.size(); ++i) { - EXPECT_EQ(in[i].asString(), out[i].asString()); - } - Json::Value inj = JsonVecOf3("a", "b", "c"); - EXPECT_EQ(inj, out); - std::vector outj; - EXPECT_TRUE(JsonArrayToValueVector(inj, &outj)); - for (Json::Value::ArrayIndex i = 0; i < in.size(); i++) { - EXPECT_EQ(in[i], outj[i]); - } -} - -TEST(JsonTest, IntVectorToFromArray) { - std::vector in = VecOf3(1, 2, 3); - Json::Value out = IntVectorToJsonArray(in); - EXPECT_EQ(in.size(), out.size()); - for (Json::Value::ArrayIndex i = 0; i < in.size(); ++i) { - EXPECT_EQ(in[i], out[i].asInt()); - } - Json::Value inj = JsonVecOf3(1, 2, 3); - EXPECT_EQ(inj, out); - std::vector outj; - EXPECT_TRUE(JsonArrayToIntVector(inj, &outj)); - for (Json::Value::ArrayIndex i = 0; i < in.size(); i++) { - EXPECT_EQ(in[i], outj[i]); - } -} - -TEST(JsonTest, UIntVectorToFromArray) { - std::vector in = VecOf3(1, 2, 3); - Json::Value out = UIntVectorToJsonArray(in); - EXPECT_EQ(in.size(), out.size()); - for (Json::Value::ArrayIndex i = 0; i < in.size(); ++i) { - EXPECT_EQ(in[i], out[i].asUInt()); - } - Json::Value inj = JsonVecOf3(1, 2, 3); - EXPECT_EQ(inj, out); - std::vector outj; - EXPECT_TRUE(JsonArrayToUIntVector(inj, &outj)); - for (Json::Value::ArrayIndex i = 0; i < in.size(); i++) { - EXPECT_EQ(in[i], outj[i]); - } -} - -TEST(JsonTest, StringVectorToFromArray) { - std::vector in = VecOf3("a", "b", "c"); - Json::Value out = StringVectorToJsonArray(in); - EXPECT_EQ(in.size(), out.size()); - for (Json::Value::ArrayIndex i = 0; i < in.size(); ++i) { - EXPECT_EQ(in[i], out[i].asString()); - } - Json::Value inj = JsonVecOf3("a", "b", "c"); - EXPECT_EQ(inj, out); - std::vector outj; - EXPECT_TRUE(JsonArrayToStringVector(inj, &outj)); - for (Json::Value::ArrayIndex i = 0; i < in.size(); i++) { - EXPECT_EQ(in[i], outj[i]); - } -} - -TEST(JsonTest, BoolVectorToFromArray) { - std::vector in = VecOf3(false, true, false); - Json::Value out = BoolVectorToJsonArray(in); - EXPECT_EQ(in.size(), out.size()); - for (Json::Value::ArrayIndex i = 0; i < in.size(); ++i) { - EXPECT_EQ(in[i], out[i].asBool()); - } - Json::Value inj = JsonVecOf3(false, true, false); - EXPECT_EQ(inj, out); - std::vector outj; - EXPECT_TRUE(JsonArrayToBoolVector(inj, &outj)); - for (Json::Value::ArrayIndex i = 0; i < in.size(); i++) { - EXPECT_EQ(in[i], outj[i]); - } -} - -TEST(JsonTest, DoubleVectorToFromArray) { - std::vector in = VecOf3(1.0, 2.0, 3.0); - Json::Value out = DoubleVectorToJsonArray(in); - EXPECT_EQ(in.size(), out.size()); - for (Json::Value::ArrayIndex i = 0; i < in.size(); ++i) { - EXPECT_EQ(in[i], out[i].asDouble()); - } - Json::Value inj = JsonVecOf3(1.0, 2.0, 3.0); - EXPECT_EQ(inj, out); - std::vector outj; - EXPECT_TRUE(JsonArrayToDoubleVector(inj, &outj)); - for (Json::Value::ArrayIndex i = 0; i < in.size(); i++) { - EXPECT_EQ(in[i], outj[i]); - } -} diff --git a/webrtc/base/latebindingsymboltable.cc b/webrtc/base/latebindingsymboltable.cc deleted file mode 100644 index 1896bd0f9..000000000 --- a/webrtc/base/latebindingsymboltable.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/latebindingsymboltable.h" - -#if defined(WEBRTC_POSIX) -#include -#endif - -#include "webrtc/base/logging.h" - -namespace rtc { - -#if defined(WEBRTC_POSIX) -static const DllHandle kInvalidDllHandle = NULL; -#else -#error Not implemented -#endif - -static const char *GetDllError() { -#if defined(WEBRTC_POSIX) - const char *err = dlerror(); - if (err) { - return err; - } else { - return "No error"; - } -#else -#error Not implemented -#endif -} - -static bool LoadSymbol(DllHandle handle, - const char *symbol_name, - void **symbol) { -#if defined(WEBRTC_POSIX) - *symbol = dlsym(handle, symbol_name); - const char *err = dlerror(); - if (err) { - LOG(LS_ERROR) << "Error loading symbol " << symbol_name << ": " << err; - return false; - } else if (!*symbol) { - // ELF allows for symbols to be NULL, but that should never happen for our - // usage. - LOG(LS_ERROR) << "Symbol " << symbol_name << " is NULL"; - return false; - } - return true; -#else -#error Not implemented -#endif -} - -LateBindingSymbolTable::LateBindingSymbolTable(const TableInfo *info, - void **table) - : info_(info), - table_(table), - handle_(kInvalidDllHandle), - undefined_symbols_(false) { - ClearSymbols(); -} - -LateBindingSymbolTable::~LateBindingSymbolTable() { - Unload(); -} - -bool LateBindingSymbolTable::IsLoaded() const { - return handle_ != kInvalidDllHandle; -} - -bool LateBindingSymbolTable::Load() { - ASSERT(info_->dll_name != NULL); - return LoadFromPath(info_->dll_name); -} - -bool LateBindingSymbolTable::LoadFromPath(const char *dll_path) { - if (IsLoaded()) { - return true; - } - if (undefined_symbols_) { - // We do not attempt to load again because repeated attempts are not - // likely to succeed and DLL loading is costly. - LOG(LS_ERROR) << "We know there are undefined symbols"; - return false; - } - -#if defined(WEBRTC_POSIX) - handle_ = dlopen(dll_path, - // RTLD_NOW front-loads symbol resolution so that errors are - // caught early instead of causing a process abort later. - // RTLD_LOCAL prevents other modules from automatically - // seeing symbol definitions in the newly-loaded tree. This - // is necessary for same-named symbols in different ABI - // versions of the same library to not explode. - RTLD_NOW|RTLD_LOCAL -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - // RTLD_DEEPBIND makes symbol dependencies in the - // newly-loaded tree prefer to resolve to definitions within - // that tree (the default on OS X). This is necessary for - // same-named symbols in different ABI versions of the same - // library to not explode. - |RTLD_DEEPBIND -#endif - ); // NOLINT -#else -#error Not implemented -#endif - - if (handle_ == kInvalidDllHandle) { - LOG(LS_WARNING) << "Can't load " << dll_path << ": " - << GetDllError(); - return false; - } -#if defined(WEBRTC_POSIX) - // Clear any old errors. - dlerror(); -#endif - for (int i = 0; i < info_->num_symbols; ++i) { - if (!LoadSymbol(handle_, info_->symbol_names[i], &table_[i])) { - undefined_symbols_ = true; - Unload(); - return false; - } - } - return true; -} - -void LateBindingSymbolTable::Unload() { - if (!IsLoaded()) { - return; - } - -#if defined(WEBRTC_POSIX) - if (dlclose(handle_) != 0) { - LOG(LS_ERROR) << GetDllError(); - } -#else -#error Not implemented -#endif - - handle_ = kInvalidDllHandle; - ClearSymbols(); -} - -void LateBindingSymbolTable::ClearSymbols() { - memset(table_, 0, sizeof(void *) * info_->num_symbols); -} - -} // namespace rtc diff --git a/webrtc/base/latebindingsymboltable.cc.def b/webrtc/base/latebindingsymboltable.cc.def deleted file mode 100644 index 6ddb2ae62..000000000 --- a/webrtc/base/latebindingsymboltable.cc.def +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// This file is a supermacro -// (see http://wanderinghorse.net/computing/papers/supermacros_cpp.html) to -// expand a definition of a late-binding symbol table class. -// -// Arguments: -// LATE_BINDING_SYMBOL_TABLE_CLASS_NAME: Name of the class to generate. -// LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST: List of symbols to load from the DLL, -// as an X-Macro list (see http://www.drdobbs.com/blogs/cpp/228700289). -// LATE_BINDING_SYMBOL_TABLE_DLL_NAME: String literal for the DLL file name to -// load. -// -// From a .cc file, include the header file containing your call to the .h.def -// supermacro, and then call this supermacro (optionally from inside the -// namespace for the class to generate, if any). Example: -// -// #include "myclassname.h" -// -// namespace foo { -// -// #define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME MY_CLASS_NAME -// #define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST MY_SYMBOLS_LIST -// #define LATE_BINDING_SYMBOL_TABLE_DLL_NAME "libdll.so.n" -// #include "webrtc/base/latebindingsymboltable.cc.def" -// -// } - -#ifndef LATE_BINDING_SYMBOL_TABLE_CLASS_NAME -#error You must define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME -#endif - -#ifndef LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST -#error You must define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST -#endif - -#ifndef LATE_BINDING_SYMBOL_TABLE_DLL_NAME -#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 ::rtc::LateBindingSymbolTable::TableInfo - LATE_BINDING_SYMBOL_TABLE_CLASS_NAME::kTableInfo = { - LATE_BINDING_SYMBOL_TABLE_DLL_NAME, - SYMBOL_TABLE_SIZE, - LATE_BINDING_SYMBOL_TABLE_CLASS_NAME::kSymbolNames -}; - -LATE_BINDING_SYMBOL_TABLE_CLASS_NAME::LATE_BINDING_SYMBOL_TABLE_CLASS_NAME() - : ::rtc::LateBindingSymbolTable(&kTableInfo, table_) {} - -LATE_BINDING_SYMBOL_TABLE_CLASS_NAME::~LATE_BINDING_SYMBOL_TABLE_CLASS_NAME() {} - -#undef LATE_BINDING_SYMBOL_TABLE_CLASS_NAME -#undef LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST -#undef LATE_BINDING_SYMBOL_TABLE_DLL_NAME diff --git a/webrtc/base/latebindingsymboltable.h b/webrtc/base/latebindingsymboltable.h deleted file mode 100644 index c1f535cd2..000000000 --- a/webrtc/base/latebindingsymboltable.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_LATEBINDINGSYMBOLTABLE_H_ -#define WEBRTC_BASE_LATEBINDINGSYMBOLTABLE_H_ - -#include - -#include "webrtc/base/common.h" - -namespace rtc { - -#if defined(WEBRTC_POSIX) -typedef void *DllHandle; -#else -#error Not implemented for this platform -#endif - -// This is the base class for "symbol table" classes to simplify the dynamic -// loading of symbols from DLLs. Currently the implementation only supports -// Linux and OS X, and pure C symbols (or extern "C" symbols that wrap C++ -// functions). Sub-classes for specific DLLs are generated via the "supermacro" -// files latebindingsymboltable.h.def and latebindingsymboltable.cc.def. See -// talk/sound/pulseaudiosymboltable.(h|cc) for an example. -class LateBindingSymbolTable { - public: - struct TableInfo { - const char *dll_name; - int num_symbols; - // Array of size num_symbols. - const char *const *symbol_names; - }; - - LateBindingSymbolTable(const TableInfo *info, void **table); - ~LateBindingSymbolTable(); - - bool IsLoaded() const; - // Loads the DLL and the symbol table. Returns true iff the DLL and symbol - // table loaded successfully. - bool Load(); - // Like load, but allows overriding the dll path for when the dll path is - // dynamic. - bool LoadFromPath(const char *dll_path); - void Unload(); - - // Gets the raw OS handle to the DLL. Be careful what you do with it. - DllHandle GetDllHandle() const { return handle_; } - - private: - void ClearSymbols(); - - const TableInfo *info_; - void **table_; - DllHandle handle_; - bool undefined_symbols_; - - DISALLOW_COPY_AND_ASSIGN(LateBindingSymbolTable); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_LATEBINDINGSYMBOLTABLE_H_ diff --git a/webrtc/base/latebindingsymboltable.h.def b/webrtc/base/latebindingsymboltable.h.def deleted file mode 100644 index 39b515fbd..000000000 --- a/webrtc/base/latebindingsymboltable.h.def +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// This file is a supermacro -// (see http://wanderinghorse.net/computing/papers/supermacros_cpp.html) to -// expand a declaration of a late-binding symbol table class. -// -// Arguments: -// LATE_BINDING_SYMBOL_TABLE_CLASS_NAME: Name of the class to generate. -// LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST: List of symbols to load from the DLL, -// as an X-Macro list (see http://www.drdobbs.com/blogs/cpp/228700289). -// -// From a .h file, include the header(s) for the DLL to late-bind and the -// latebindingsymboltable.h header, and then call this supermacro (optionally -// from inside the namespace for the class to generate, if any). Example: -// -// #include -// -// #include "webrtc/base/latebindingsymboltable.h" -// -// namespace foo { -// -// #define MY_CLASS_NAME DesiredClassName -// #define MY_SYMBOLS_LIST X(acos) X(sin) X(tan) -// -// #define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME MY_CLASS_NAME -// #define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST MY_SYMBOLS_LIST -// #include "webrtc/base/latebindingsymboltable.h.def" -// -// } - -#ifndef WEBRTC_BASE_LATEBINDINGSYMBOLTABLE_H_ -#error You must first include latebindingsymboltable.h -#endif - -#ifndef LATE_BINDING_SYMBOL_TABLE_CLASS_NAME -#error You must define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME -#endif - -#ifndef LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST -#error You must define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST -#endif - -class LATE_BINDING_SYMBOL_TABLE_CLASS_NAME : - public ::rtc::LateBindingSymbolTable { - public: - LATE_BINDING_SYMBOL_TABLE_CLASS_NAME(); - ~LATE_BINDING_SYMBOL_TABLE_CLASS_NAME(); - -#define X(sym) \ - typeof(&::sym) sym() const { \ - ASSERT(::rtc::LateBindingSymbolTable::IsLoaded()); \ - return reinterpret_cast(table_[SYMBOL_TABLE_INDEX_##sym]); \ - } -LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST -#undef X - - private: - enum { -#define X(sym) \ - SYMBOL_TABLE_INDEX_##sym, -LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST -#undef X - SYMBOL_TABLE_SIZE - }; - - static const ::rtc::LateBindingSymbolTable::TableInfo kTableInfo; - static const char *const kSymbolNames[]; - - void *table_[SYMBOL_TABLE_SIZE]; - - DISALLOW_COPY_AND_ASSIGN(LATE_BINDING_SYMBOL_TABLE_CLASS_NAME); -}; - -#undef LATE_BINDING_SYMBOL_TABLE_CLASS_NAME -#undef LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST diff --git a/webrtc/base/latebindingsymboltable_unittest.cc b/webrtc/base/latebindingsymboltable_unittest.cc deleted file mode 100644 index 30ebd17cb..000000000 --- a/webrtc/base/latebindingsymboltable_unittest.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) -#include -#endif - -#include "webrtc/base/gunit.h" -#include "webrtc/base/latebindingsymboltable.h" - -namespace rtc { - -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - -#define LIBM_SYMBOLS_CLASS_NAME LibmTestSymbolTable -#define LIBM_SYMBOLS_LIST \ - X(acos) \ - X(sin) \ - X(tan) - -#define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME LIBM_SYMBOLS_CLASS_NAME -#define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST LIBM_SYMBOLS_LIST -#include "webrtc/base/latebindingsymboltable.h.def" - -#define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME LIBM_SYMBOLS_CLASS_NAME -#define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST LIBM_SYMBOLS_LIST -#define LATE_BINDING_SYMBOL_TABLE_DLL_NAME "libm.so.6" -#include "webrtc/base/latebindingsymboltable.cc.def" - -TEST(LateBindingSymbolTable, libm) { - LibmTestSymbolTable table; - EXPECT_FALSE(table.IsLoaded()); - ASSERT_TRUE(table.Load()); - EXPECT_TRUE(table.IsLoaded()); - EXPECT_EQ(table.acos()(0.5), acos(0.5)); - EXPECT_EQ(table.sin()(0.5), sin(0.5)); - EXPECT_EQ(table.tan()(0.5), tan(0.5)); - // It would be nice to check that the addresses are the same, but the nature - // of dynamic linking and relocation makes them actually be different. - table.Unload(); - EXPECT_FALSE(table.IsLoaded()); -} - -#else -#error Not implemented -#endif - -} // namespace rtc diff --git a/webrtc/base/libdbusglibsymboltable.cc b/webrtc/base/libdbusglibsymboltable.cc deleted file mode 100644 index ad51064bc..000000000 --- a/webrtc/base/libdbusglibsymboltable.cc +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifdef HAVE_DBUS_GLIB - -#include "webrtc/base/libdbusglibsymboltable.h" - -namespace rtc { - -#define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME LIBDBUS_GLIB_CLASS_NAME -#define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST LIBDBUS_GLIB_SYMBOLS_LIST -#define LATE_BINDING_SYMBOL_TABLE_DLL_NAME "libdbus-glib-1.so.2" -#include "webrtc/base/latebindingsymboltable.cc.def" - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB diff --git a/webrtc/base/libdbusglibsymboltable.h b/webrtc/base/libdbusglibsymboltable.h deleted file mode 100644 index b87b4c174..000000000 --- a/webrtc/base/libdbusglibsymboltable.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_LIBDBUSGLIBSYMBOLTABLE_H_ -#define WEBRTC_BASE_LIBDBUSGLIBSYMBOLTABLE_H_ - -#ifdef HAVE_DBUS_GLIB - -#include -#include - -#include "webrtc/base/latebindingsymboltable.h" - -namespace rtc { - -#define LIBDBUS_GLIB_CLASS_NAME LibDBusGlibSymbolTable -// The libdbus-glib symbols we need, as an X-Macro list. -// This list must contain precisely every libdbus-glib function that is used in -// dbus.cc. -#define LIBDBUS_GLIB_SYMBOLS_LIST \ - X(dbus_bus_add_match) \ - X(dbus_connection_add_filter) \ - X(dbus_connection_close) \ - X(dbus_connection_remove_filter) \ - X(dbus_connection_set_exit_on_disconnect) \ - X(dbus_g_bus_get) \ - X(dbus_g_bus_get_private) \ - X(dbus_g_connection_get_connection) \ - X(dbus_g_connection_unref) \ - X(dbus_g_thread_init) \ - X(dbus_message_get_interface) \ - X(dbus_message_get_member) \ - X(dbus_message_get_path) \ - X(dbus_message_get_type) \ - X(dbus_message_iter_get_arg_type) \ - X(dbus_message_iter_get_basic) \ - X(dbus_message_iter_init) \ - X(dbus_message_ref) \ - X(dbus_message_unref) - -#define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME LIBDBUS_GLIB_CLASS_NAME -#define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST LIBDBUS_GLIB_SYMBOLS_LIST -#include "webrtc/base/latebindingsymboltable.h.def" - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB - -#endif // WEBRTC_BASE_LIBDBUSGLIBSYMBOLTABLE_H_ diff --git a/webrtc/base/linked_ptr.h b/webrtc/base/linked_ptr.h deleted file mode 100644 index 65e5a00ec..000000000 --- a/webrtc/base/linked_ptr.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * linked_ptr - simple reference linked pointer - * (like reference counting, just using a linked list of the references - * instead of their count.) - * - * The implementation stores three pointers for every linked_ptr, but - * does not allocate anything on the free store. - */ - -#ifndef WEBRTC_BASE_LINKED_PTR_H__ -#define WEBRTC_BASE_LINKED_PTR_H__ - -namespace rtc { - -/* For ANSI-challenged compilers, you may want to #define - * NO_MEMBER_TEMPLATES, explicit or mutable */ -#define NO_MEMBER_TEMPLATES - -template class linked_ptr -{ -public: - -#ifndef NO_MEMBER_TEMPLATES -# define TEMPLATE_FUNCTION template - TEMPLATE_FUNCTION friend class linked_ptr; -#else -# define TEMPLATE_FUNCTION - typedef X Y; -#endif - - typedef X element_type; - - explicit linked_ptr(X* p = 0) throw() - : itsPtr(p) {itsPrev = itsNext = this;} - ~linked_ptr() - {release();} - linked_ptr(const linked_ptr& r) throw() - {acquire(r);} - linked_ptr& operator=(const linked_ptr& r) - { - if (this != &r) { - release(); - acquire(r); - } - return *this; - } - -#ifndef NO_MEMBER_TEMPLATES - template friend class linked_ptr; - template linked_ptr(const linked_ptr& r) throw() - {acquire(r);} - template linked_ptr& operator=(const linked_ptr& r) - { - if (this != &r) { - release(); - acquire(r); - } - return *this; - } -#endif // NO_MEMBER_TEMPLATES - - X& operator*() const throw() {return *itsPtr;} - X* operator->() const throw() {return itsPtr;} - X* get() const throw() {return itsPtr;} - bool unique() const throw() {return itsPrev ? itsPrev==this : true;} - -private: - X* itsPtr; - mutable const linked_ptr* itsPrev; - mutable const linked_ptr* itsNext; - - void acquire(const linked_ptr& r) throw() - { // insert this to the list - itsPtr = r.itsPtr; - itsNext = r.itsNext; - itsNext->itsPrev = this; - itsPrev = &r; -#ifndef mutable - r.itsNext = this; -#else // for ANSI-challenged compilers - (const_cast*>(&r))->itsNext = this; -#endif - } - -#ifndef NO_MEMBER_TEMPLATES - template void acquire(const linked_ptr& r) throw() - { // insert this to the list - itsPtr = r.itsPtr; - itsNext = r.itsNext; - itsNext->itsPrev = this; - itsPrev = &r; -#ifndef mutable - r.itsNext = this; -#else // for ANSI-challenged compilers - (const_cast*>(&r))->itsNext = this; -#endif - } -#endif // NO_MEMBER_TEMPLATES - - void release() - { // erase this from the list, delete if unique - if (unique()) delete itsPtr; - else { - itsPrev->itsNext = itsNext; - itsNext->itsPrev = itsPrev; - itsPrev = itsNext = 0; - } - itsPtr = 0; - } -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_LINKED_PTR_H__ - diff --git a/webrtc/base/linux.cc b/webrtc/base/linux.cc deleted file mode 100644 index b95854353..000000000 --- a/webrtc/base/linux.cc +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_LINUX) -#include "webrtc/base/linux.h" - -#include - -#include -#include -#include - -#include -#include - -#include "webrtc/base/stringencode.h" - -namespace rtc { - -static const char kCpuInfoFile[] = "/proc/cpuinfo"; -static const char kCpuMaxFreqFile[] = - "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"; - -ProcCpuInfo::ProcCpuInfo() { -} - -ProcCpuInfo::~ProcCpuInfo() { -} - -bool ProcCpuInfo::LoadFromSystem() { - ConfigParser procfs; - if (!procfs.Open(kCpuInfoFile)) { - return false; - } - return procfs.Parse(§ions_); -}; - -bool ProcCpuInfo::GetSectionCount(size_t* count) { - if (sections_.empty()) { - return false; - } - if (count) { - *count = sections_.size(); - } - return true; -} - -bool ProcCpuInfo::GetNumCpus(int* num) { - if (sections_.empty()) { - return false; - } - int total_cpus = 0; -#if defined(__arm__) - // Count the number of blocks that have a "processor" key defined. On ARM, - // there may be extra blocks of information that aren't per-processor. - size_t section_count = sections_.size(); - for (size_t i = 0; i < section_count; ++i) { - int processor_id; - if (GetSectionIntValue(i, "processor", &processor_id)) { - ++total_cpus; - } - } - // Single core ARM systems don't include "processor" keys at all, so return - // that we have a single core if we didn't find any explicitly above. - if (total_cpus == 0) { - total_cpus = 1; - } -#else - // On X86, there is exactly one info section per processor. - total_cpus = static_cast(sections_.size()); -#endif - if (num) { - *num = total_cpus; - } - return true; -} - -bool ProcCpuInfo::GetNumPhysicalCpus(int* num) { - if (sections_.empty()) { - return false; - } - // TODO: /proc/cpuinfo only reports cores that are currently - // _online_, so this may underreport the number of physical cores. -#if defined(__arm__) - // ARM (currently) has no hyperthreading, so just return the same value - // as GetNumCpus. - return GetNumCpus(num); -#else - int total_cores = 0; - std::set physical_ids; - size_t section_count = sections_.size(); - for (size_t i = 0; i < section_count; ++i) { - int physical_id; - int cores; - // Count the cores for the physical id only if we have not counted the id. - if (GetSectionIntValue(i, "physical id", &physical_id) && - GetSectionIntValue(i, "cpu cores", &cores) && - physical_ids.find(physical_id) == physical_ids.end()) { - physical_ids.insert(physical_id); - total_cores += cores; - } - } - - if (num) { - *num = total_cores; - } - return true; -#endif -} - -bool ProcCpuInfo::GetCpuFamily(int* id) { - int cpu_family = 0; - -#if defined(__arm__) - // On some ARM platforms, there is no 'cpu family' in '/proc/cpuinfo'. But - // there is 'CPU Architecture' which can be used as 'cpu family'. - // See http://en.wikipedia.org/wiki/ARM_architecture for a good list of - // ARM cpu families, architectures, and their mappings. - // There may be multiple sessions that aren't per-processor. We need to scan - // through each session until we find the first 'CPU architecture'. - size_t section_count = sections_.size(); - for (size_t i = 0; i < section_count; ++i) { - if (GetSectionIntValue(i, "CPU architecture", &cpu_family)) { - // We returns the first one (if there are multiple entries). - break; - }; - } -#else - GetSectionIntValue(0, "cpu family", &cpu_family); -#endif - if (id) { - *id = cpu_family; - } - return true; -} - -bool ProcCpuInfo::GetSectionStringValue(size_t section_num, - const std::string& key, - std::string* result) { - if (section_num >= sections_.size()) { - return false; - } - ConfigParser::SimpleMap::iterator iter = sections_[section_num].find(key); - if (iter == sections_[section_num].end()) { - return false; - } - *result = iter->second; - return true; -} - -bool ProcCpuInfo::GetSectionIntValue(size_t section_num, - const std::string& key, - int* result) { - if (section_num >= sections_.size()) { - return false; - } - ConfigParser::SimpleMap::iterator iter = sections_[section_num].find(key); - if (iter == sections_[section_num].end()) { - return false; - } - return FromString(iter->second, result); -} - -ConfigParser::ConfigParser() {} - -ConfigParser::~ConfigParser() {} - -bool ConfigParser::Open(const std::string& filename) { - FileStream* fs = new FileStream(); - if (!fs->Open(filename, "r", NULL)) { - return false; - } - instream_.reset(fs); - return true; -} - -void ConfigParser::Attach(StreamInterface* stream) { - instream_.reset(stream); -} - -bool ConfigParser::Parse(MapVector* key_val_pairs) { - // Parses the file and places the found key-value pairs into key_val_pairs. - SimpleMap section; - while (ParseSection(§ion)) { - key_val_pairs->push_back(section); - section.clear(); - } - return (!key_val_pairs->empty()); -} - -bool ConfigParser::ParseSection(SimpleMap* key_val_pair) { - // Parses the next section in the filestream and places the found key-value - // pairs into key_val_pair. - std::string key, value; - while (ParseLine(&key, &value)) { - (*key_val_pair)[key] = value; - } - return (!key_val_pair->empty()); -} - -bool ConfigParser::ParseLine(std::string* key, std::string* value) { - // Parses the next line in the filestream and places the found key-value - // pair into key and val. - std::string line; - if ((instream_->ReadLine(&line)) == SR_EOS) { - return false; - } - std::vector tokens; - if (2 != split(line, ':', &tokens)) { - return false; - } - // Removes whitespace at the end of Key name - size_t pos = tokens[0].length() - 1; - while ((pos > 0) && isspace(tokens[0][pos])) { - pos--; - } - tokens[0].erase(pos + 1); - // Removes whitespace at the start of value - pos = 0; - while (pos < tokens[1].length() && isspace(tokens[1][pos])) { - pos++; - } - tokens[1].erase(0, pos); - *key = tokens[0]; - *value = tokens[1]; - return true; -} - -#if !defined(WEBRTC_CHROMIUM_BUILDs) -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; - if (uname(&buf) < 0) { - LOG_ERR(LS_ERROR) << "Can't call uname()"; - return std::string(); - } - std::ostringstream sstr; - sstr << buf.sysname << " " - << buf.release << " " - << buf.version << " " - << buf.machine; - return sstr.str(); -} - -int ReadCpuMaxFreq() { - FileStream fs; - std::string str; - int freq = -1; - if (!fs.Open(kCpuMaxFreqFile, "r", NULL) || - SR_SUCCESS != fs.ReadLine(&str) || - !FromString(str, &freq)) { - return -1; - } - return freq; -} - -} // namespace rtc - -#endif // defined(WEBRTC_LINUX) diff --git a/webrtc/base/linux.h b/webrtc/base/linux.h deleted file mode 100644 index 8f601878f..000000000 --- a/webrtc/base/linux.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_LINUX_H_ -#define WEBRTC_BASE_LINUX_H_ - -#if defined(WEBRTC_LINUX) -#include -#include -#include - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -////////////////////////////////////////////////////////////////////////////// -// ConfigParser parses a FileStream of an ".ini."-type format into a map. -////////////////////////////////////////////////////////////////////////////// - -// Sample Usage: -// ConfigParser parser; -// ConfigParser::MapVector key_val_pairs; -// if (parser.Open(inifile) && parser.Parse(&key_val_pairs)) { -// for (int section_num=0; i < key_val_pairs.size(); ++section_num) { -// std::string val1 = key_val_pairs[section_num][key1]; -// std::string val2 = key_val_pairs[section_num][key2]; -// // Do something with valn; -// } -// } - -class ConfigParser { - public: - typedef std::map SimpleMap; - typedef std::vector MapVector; - - ConfigParser(); - virtual ~ConfigParser(); - - virtual bool Open(const std::string& filename); - virtual void Attach(StreamInterface* stream); - virtual bool Parse(MapVector* key_val_pairs); - virtual bool ParseSection(SimpleMap* key_val_pair); - virtual bool ParseLine(std::string* key, std::string* value); - - private: - scoped_ptr instream_; -}; - -////////////////////////////////////////////////////////////////////////////// -// ProcCpuInfo reads CPU info from the /proc subsystem on any *NIX platform. -////////////////////////////////////////////////////////////////////////////// - -// Sample Usage: -// ProcCpuInfo proc_info; -// int no_of_cpu; -// if (proc_info.LoadFromSystem()) { -// std::string out_str; -// proc_info.GetNumCpus(&no_of_cpu); -// proc_info.GetCpuStringValue(0, "vendor_id", &out_str); -// } -// } - -class ProcCpuInfo { - public: - ProcCpuInfo(); - virtual ~ProcCpuInfo(); - - // Reads the proc subsystem's cpu info into memory. If this fails, this - // returns false; if it succeeds, it returns true. - virtual bool LoadFromSystem(); - - // Obtains the number of logical CPU threads and places the value num. - virtual bool GetNumCpus(int* num); - - // Obtains the number of physical CPU cores and places the value num. - virtual bool GetNumPhysicalCpus(int* num); - - // Obtains the CPU family id. - virtual bool GetCpuFamily(int* id); - - // Obtains the number of sections in /proc/cpuinfo, which may be greater - // than the number of CPUs (e.g. on ARM) - virtual bool GetSectionCount(size_t* count); - - // Looks for the CPU proc item with the given name for the given section - // number and places the string value in result. - virtual bool GetSectionStringValue(size_t section_num, const std::string& key, - std::string* result); - - // Looks for the CPU proc item with the given name for the given section - // number and places the int value in result. - virtual bool GetSectionIntValue(size_t section_num, const std::string& key, - int* result); - - private: - ConfigParser::MapVector sections_; -}; - -#if !defined(WEBRTC_CHROMIUM_BUILDs) -// 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(); - -// Returns the content (int) of -// /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq -// Returns -1 on error. -int ReadCpuMaxFreq(); - -} // namespace rtc - -#endif // defined(WEBRTC_LINUX) -#endif // WEBRTC_BASE_LINUX_H_ diff --git a/webrtc/base/linux_unittest.cc b/webrtc/base/linux_unittest.cc deleted file mode 100644 index c65ef071c..000000000 --- a/webrtc/base/linux_unittest.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "webrtc/base/linux.h" -#include "webrtc/base/fileutils.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/gunit.h" - -namespace rtc { - -// These tests running on ARM are fairly specific to the output of the tegra2 -// ARM processor, and so may fail on other ARM-based systems. -TEST(ProcCpuInfo, GetProcInfo) { - ProcCpuInfo proc_info; - EXPECT_TRUE(proc_info.LoadFromSystem()); - - int out_cpus = 0; - EXPECT_TRUE(proc_info.GetNumCpus(&out_cpus)); - LOG(LS_INFO) << "GetNumCpus: " << out_cpus; - EXPECT_GT(out_cpus, 0); - - int out_cpus_phys = 0; - EXPECT_TRUE(proc_info.GetNumPhysicalCpus(&out_cpus_phys)); - LOG(LS_INFO) << "GetNumPhysicalCpus: " << out_cpus_phys; - EXPECT_GT(out_cpus_phys, 0); - EXPECT_LE(out_cpus_phys, out_cpus); - - int out_family = 0; - EXPECT_TRUE(proc_info.GetCpuFamily(&out_family)); - LOG(LS_INFO) << "cpu family: " << out_family; - EXPECT_GE(out_family, 4); - -#if defined(__arm__) - std::string out_processor; - EXPECT_TRUE(proc_info.GetSectionStringValue(0, "Processor", &out_processor)); - LOG(LS_INFO) << "Processor: " << out_processor; - EXPECT_NE(std::string::npos, out_processor.find("ARM")); - - // Most other info, such as model, stepping, vendor, etc. - // is missing on ARM systems. -#else - int out_model = 0; - EXPECT_TRUE(proc_info.GetSectionIntValue(0, "model", &out_model)); - LOG(LS_INFO) << "model: " << out_model; - - int out_stepping = 0; - EXPECT_TRUE(proc_info.GetSectionIntValue(0, "stepping", &out_stepping)); - LOG(LS_INFO) << "stepping: " << out_stepping; - - int out_processor = 0; - EXPECT_TRUE(proc_info.GetSectionIntValue(0, "processor", &out_processor)); - LOG(LS_INFO) << "processor: " << out_processor; - EXPECT_EQ(0, out_processor); - - std::string out_str; - EXPECT_TRUE(proc_info.GetSectionStringValue(0, "vendor_id", &out_str)); - LOG(LS_INFO) << "vendor_id: " << out_str; - EXPECT_FALSE(out_str.empty()); -#endif -} - -TEST(ConfigParser, ParseConfig) { - ConfigParser parser; - MemoryStream *test_stream = new MemoryStream( - "Key1: Value1\n" - "Key2\t: Value2\n" - "Key3:Value3\n" - "\n" - "Key1:Value1\n"); - ConfigParser::MapVector key_val_pairs; - parser.Attach(test_stream); - EXPECT_EQ(true, parser.Parse(&key_val_pairs)); - EXPECT_EQ(2U, key_val_pairs.size()); - EXPECT_EQ("Value1", key_val_pairs[0]["Key1"]); - EXPECT_EQ("Value2", key_val_pairs[0]["Key2"]); - EXPECT_EQ("Value3", key_val_pairs[0]["Key3"]); - EXPECT_EQ("Value1", key_val_pairs[1]["Key1"]); - key_val_pairs.clear(); - EXPECT_EQ(true, parser.Open("/proc/cpuinfo")); - EXPECT_EQ(true, parser.Parse(&key_val_pairs)); -} - -#if !defined(WEBRTC_CHROMIUM_BUILDs) -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()); -} - -} // namespace rtc diff --git a/webrtc/base/linuxfdwalk.c b/webrtc/base/linuxfdwalk.c deleted file mode 100644 index ae60cc524..000000000 --- a/webrtc/base/linuxfdwalk.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include - -#include "webrtc/base/linuxfdwalk.h" - -// Parses a file descriptor number in base 10, requiring the strict format used -// in /proc/*/fd. Returns the value, or -1 if not a valid string. -static int parse_fd(const char *s) { - if (!*s) { - // Empty string is invalid. - return -1; - } - int val = 0; - do { - if (*s < '0' || *s > '9') { - // Non-numeric characters anywhere are invalid. - return -1; - } - int digit = *s++ - '0'; - val = val * 10 + digit; - } while (*s); - return val; -} - -int fdwalk(void (*func)(void *, int), void *opaque) { - DIR *dir = opendir("/proc/self/fd"); - if (!dir) { - return -1; - } - int opendirfd = dirfd(dir); - int parse_errors = 0; - struct dirent *ent; - // Have to clear errno to distinguish readdir() completion from failure. - while (errno = 0, (ent = readdir(dir)) != NULL) { - if (strcmp(ent->d_name, ".") == 0 || - strcmp(ent->d_name, "..") == 0) { - continue; - } - // We avoid atoi or strtol because those are part of libc and they involve - // locale stuff, which is probably not safe from a post-fork context in a - // multi-threaded app. - int fd = parse_fd(ent->d_name); - if (fd < 0) { - parse_errors = 1; - continue; - } - if (fd != opendirfd) { - (*func)(opaque, fd); - } - } - int saved_errno = errno; - if (closedir(dir) < 0) { - if (!saved_errno) { - // Return the closedir error. - return -1; - } - // Else ignore it because we have a more relevant error to return. - } - if (saved_errno) { - errno = saved_errno; - return -1; - } else if (parse_errors) { - errno = EBADF; - return -1; - } else { - return 0; - } -} diff --git a/webrtc/base/linuxfdwalk.h b/webrtc/base/linuxfdwalk.h deleted file mode 100644 index fe5a6977d..000000000 --- a/webrtc/base/linuxfdwalk.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_LINUXFDWALK_H_ -#define WEBRTC_BASE_LINUXFDWALK_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// Linux port of SunOS's fdwalk(3) call. It loops over all open file descriptors -// and calls func on each one. Additionally, it is safe to use from the child -// of a fork that hasn't exec'ed yet, so you can use it to close all open file -// descriptors prior to exec'ing a daemon. -// The return value is 0 if successful, or else -1 and errno is set. The -// possible errors include any error that can be returned by opendir(), -// readdir(), or closedir(), plus EBADF if there are problems parsing the -// contents of /proc/self/fd. -// The file descriptors that are enumerated will not include the file descriptor -// used for the enumeration itself. -int fdwalk(void (*func)(void *, int), void *opaque); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // WEBRTC_BASE_LINUXFDWALK_H_ diff --git a/webrtc/base/linuxfdwalk_unittest.cc b/webrtc/base/linuxfdwalk_unittest.cc deleted file mode 100644 index bba48e887..000000000 --- a/webrtc/base/linuxfdwalk_unittest.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/linuxfdwalk.h" - -#include -#include -#include -#include - -static const int kArbitraryLargeFdNumber = 424; - -static void FdCheckVisitor(void *data, int fd) { - std::set *fds = static_cast *>(data); - EXPECT_EQ(1U, fds->erase(fd)); -} - -static void FdEnumVisitor(void *data, int fd) { - std::set *fds = static_cast *>(data); - EXPECT_TRUE(fds->insert(fd).second); -} - -// Checks that the set of open fds is exactly the given list. -static void CheckOpenFdList(std::set fds) { - EXPECT_EQ(0, fdwalk(&FdCheckVisitor, &fds)); - EXPECT_EQ(0U, fds.size()); -} - -static void GetOpenFdList(std::set *fds) { - fds->clear(); - EXPECT_EQ(0, fdwalk(&FdEnumVisitor, fds)); -} - -TEST(LinuxFdWalk, TestFdWalk) { - std::set fds; - GetOpenFdList(&fds); - std::ostringstream str; - // I have observed that the open set when starting a test is [0, 6]. Leaked - // fds would change that, but so can (e.g.) running under a debugger, so we - // can't really do an EXPECT. :( - str << "File descriptors open in test executable:"; - for (std::set::const_iterator i = fds.begin(); i != fds.end(); ++i) { - str << " " << *i; - } - LOG(LS_INFO) << str.str(); - // Open some files. - int fd1 = open("/dev/null", O_RDONLY); - EXPECT_LE(0, fd1); - int fd2 = open("/dev/null", O_WRONLY); - EXPECT_LE(0, fd2); - int fd3 = open("/dev/null", O_RDWR); - EXPECT_LE(0, fd3); - int fd4 = dup2(fd3, kArbitraryLargeFdNumber); - EXPECT_LE(0, fd4); - EXPECT_TRUE(fds.insert(fd1).second); - EXPECT_TRUE(fds.insert(fd2).second); - EXPECT_TRUE(fds.insert(fd3).second); - EXPECT_TRUE(fds.insert(fd4).second); - CheckOpenFdList(fds); - EXPECT_EQ(0, close(fd1)); - EXPECT_EQ(0, close(fd2)); - EXPECT_EQ(0, close(fd3)); - EXPECT_EQ(0, close(fd4)); -} diff --git a/webrtc/base/linuxwindowpicker.cc b/webrtc/base/linuxwindowpicker.cc deleted file mode 100644 index 56d565e55..000000000 --- a/webrtc/base/linuxwindowpicker.cc +++ /dev/null @@ -1,818 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/linuxwindowpicker.h" - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "webrtc/base/logging.h" - -namespace rtc { - -// Convenience wrapper for XGetWindowProperty results. -template -class XWindowProperty { - public: - XWindowProperty(Display* display, Window window, Atom property) - : data_(NULL) { - const int kBitsPerByte = 8; - Atom actual_type; - int actual_format; - unsigned long bytes_after; // NOLINT: type required by XGetWindowProperty - int status = XGetWindowProperty(display, window, property, 0L, ~0L, False, - AnyPropertyType, &actual_type, - &actual_format, &size_, - &bytes_after, &data_); - succeeded_ = (status == Success); - if (!succeeded_) { - data_ = NULL; // Ensure nothing is freed. - } else if (sizeof(PropertyType) * kBitsPerByte != actual_format) { - LOG(LS_WARNING) << "Returned type size differs from " - "requested type size."; - succeeded_ = false; - // We still need to call XFree in this case, so leave data_ alone. - } - if (!succeeded_) { - size_ = 0; - } - } - - ~XWindowProperty() { - if (data_) { - XFree(data_); - } - } - - bool succeeded() const { return succeeded_; } - size_t size() const { return size_; } - const PropertyType* data() const { - return reinterpret_cast(data_); - } - PropertyType* data() { - return reinterpret_cast(data_); - } - - private: - bool succeeded_; - unsigned long size_; // NOLINT: type required by XGetWindowProperty - unsigned char* data_; - - DISALLOW_COPY_AND_ASSIGN(XWindowProperty); -}; - -// Stupid X11. It seems none of the synchronous returns codes from X11 calls -// are meaningful unless an asynchronous error handler is configured. This -// RAII class registers and unregisters an X11 error handler. -class XErrorSuppressor { - public: - explicit XErrorSuppressor(Display* display) - : display_(display), original_error_handler_(NULL) { - SuppressX11Errors(); - } - ~XErrorSuppressor() { - UnsuppressX11Errors(); - } - - private: - static int ErrorHandler(Display* display, XErrorEvent* e) { - char buf[256]; - XGetErrorText(display, e->error_code, buf, sizeof buf); - LOG(LS_WARNING) << "Received X11 error \"" << buf << "\" for request code " - << static_cast(e->request_code); - return 0; - } - - void SuppressX11Errors() { - XFlush(display_); - XSync(display_, False); - original_error_handler_ = XSetErrorHandler(&ErrorHandler); - } - - void UnsuppressX11Errors() { - XFlush(display_); - XSync(display_, False); - XErrorHandler handler = XSetErrorHandler(original_error_handler_); - if (handler != &ErrorHandler) { - LOG(LS_WARNING) << "Unbalanced XSetErrorHandler() calls detected. " - << "Final error handler may not be what you expect!"; - } - original_error_handler_ = NULL; - } - - Display* display_; - XErrorHandler original_error_handler_; - - DISALLOW_COPY_AND_ASSIGN(XErrorSuppressor); -}; - -// Hiding all X11 specifics inside its own class. This to avoid -// conflicts between talk and X11 header declarations. -class XWindowEnumerator { - public: - XWindowEnumerator() - : display_(NULL), - has_composite_extension_(false), - has_render_extension_(false) { - } - - ~XWindowEnumerator() { - if (display_ != NULL) { - XCloseDisplay(display_); - } - } - - bool Init() { - if (display_ != NULL) { - // Already initialized. - return true; - } - display_ = XOpenDisplay(NULL); - if (display_ == NULL) { - LOG(LS_ERROR) << "Failed to open display."; - return false; - } - - XErrorSuppressor error_suppressor(display_); - - wm_state_ = XInternAtom(display_, "WM_STATE", True); - net_wm_icon_ = XInternAtom(display_, "_NET_WM_ICON", False); - - int event_base, error_base, major_version, minor_version; - if (XCompositeQueryExtension(display_, &event_base, &error_base) && - XCompositeQueryVersion(display_, &major_version, &minor_version) && - // XCompositeNameWindowPixmap() requires version 0.2 - (major_version > 0 || minor_version >= 2)) { - has_composite_extension_ = true; - } else { - LOG(LS_INFO) << "Xcomposite extension not available or too old."; - } - - if (XRenderQueryExtension(display_, &event_base, &error_base) && - XRenderQueryVersion(display_, &major_version, &minor_version) && - // XRenderSetPictureTransform() requires version 0.6 - (major_version > 0 || minor_version >= 6)) { - has_render_extension_ = true; - } else { - LOG(LS_INFO) << "Xrender extension not available or too old."; - } - return true; - } - - bool EnumerateWindows(WindowDescriptionList* descriptions) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - int num_screens = XScreenCount(display_); - bool result = false; - for (int i = 0; i < num_screens; ++i) { - if (EnumerateScreenWindows(descriptions, i)) { - // We know we succeded on at least one screen. - result = true; - } - } - return result; - } - - bool EnumerateDesktops(DesktopDescriptionList* descriptions) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - Window default_root_window = XDefaultRootWindow(display_); - int num_screens = XScreenCount(display_); - for (int i = 0; i < num_screens; ++i) { - Window root_window = XRootWindow(display_, i); - DesktopId id(DesktopId(root_window, i)); - // TODO: Figure out an appropriate desktop title. - DesktopDescription desc(id, ""); - desc.set_primary(root_window == default_root_window); - descriptions->push_back(desc); - } - return num_screens > 0; - } - - bool IsVisible(const WindowId& id) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - XWindowAttributes attr; - if (!XGetWindowAttributes(display_, id.id(), &attr)) { - LOG(LS_ERROR) << "XGetWindowAttributes() failed"; - return false; - } - return attr.map_state == IsViewable; - } - - bool MoveToFront(const WindowId& id) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - unsigned int num_children; - Window* children; - Window parent; - Window root; - - // Find root window to pass event to. - int status = XQueryTree(display_, id.id(), &root, &parent, &children, - &num_children); - if (status == 0) { - LOG(LS_WARNING) << "Failed to query for child windows."; - return false; - } - if (children != NULL) { - XFree(children); - } - - // Move the window to front. - XRaiseWindow(display_, id.id()); - - // Some window managers (e.g., metacity in GNOME) consider it illegal to - // raise a window without also giving it input focus with - // _NET_ACTIVE_WINDOW, so XRaiseWindow() on its own isn't enough. - Atom atom = XInternAtom(display_, "_NET_ACTIVE_WINDOW", True); - if (atom != None) { - XEvent xev; - long event_mask; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.window = id.id(); - xev.xclient.message_type = atom; - - // The format member is set to 8, 16, or 32 and specifies whether the - // data should be viewed as a list of bytes, shorts, or longs. - xev.xclient.format = 32; - - xev.xclient.data.l[0] = 0; - xev.xclient.data.l[1] = 0; - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - - event_mask = SubstructureRedirectMask | SubstructureNotifyMask; - - XSendEvent(display_, root, False, event_mask, &xev); - } - XFlush(display_); - return true; - } - - uint8* GetWindowIcon(const WindowId& id, int* width, int* height) { - if (!Init()) { - return NULL; - } - XErrorSuppressor error_suppressor(display_); - Atom ret_type; - int format; - unsigned long length, bytes_after, size; - unsigned char* data = NULL; - - // Find out the size of the icon data. - if (XGetWindowProperty( - display_, id.id(), net_wm_icon_, 0, 0, False, XA_CARDINAL, - &ret_type, &format, &length, &size, &data) == Success && - data) { - XFree(data); - } else { - LOG(LS_ERROR) << "Failed to get size of the icon."; - return NULL; - } - // Get the icon data, the format is one uint32 each for width and height, - // followed by the actual pixel data. - if (size >= 2 && - XGetWindowProperty( - display_, id.id(), net_wm_icon_, 0, size, False, XA_CARDINAL, - &ret_type, &format, &length, &bytes_after, &data) == Success && - data) { - uint32* data_ptr = reinterpret_cast(data); - int w, h; - w = data_ptr[0]; - h = data_ptr[1]; - if (size < static_cast(w * h + 2)) { - XFree(data); - LOG(LS_ERROR) << "Not a vaild icon."; - return NULL; - } - uint8* rgba = - ArgbToRgba(&data_ptr[2], 0, 0, w, h, w, h, true); - XFree(data); - *width = w; - *height = h; - return rgba; - } else { - LOG(LS_ERROR) << "Failed to get window icon data."; - return NULL; - } - } - - uint8* GetWindowThumbnail(const WindowId& id, int width, int height) { - if (!Init()) { - return NULL; - } - - if (!has_composite_extension_) { - // Without the Xcomposite extension we would only get a good thumbnail if - // the whole window is visible on screen and not covered by any - // other window. This is not something we want so instead, just - // bail out. - LOG(LS_INFO) << "No Xcomposite extension detected."; - return NULL; - } - XErrorSuppressor error_suppressor(display_); - - Window root; - int x; - int y; - unsigned int src_width; - unsigned int src_height; - unsigned int border_width; - unsigned int depth; - - // In addition to needing X11 server-side support for Xcomposite, it - // actually needs to be turned on for this window in order to get a good - // thumbnail. If the user has modern hardware/drivers but isn't using a - // compositing window manager, that won't be the case. Here we - // automatically turn it on for shareable windows so that we can get - // thumbnails. We used to avoid it because the transition is visually ugly, - // but recent window managers don't always redirect windows which led to - // no thumbnails at all, which is a worse experience. - - // Redirect drawing to an offscreen buffer (ie, turn on compositing). - // X11 remembers what has requested this and will turn it off for us when - // we exit. - XCompositeRedirectWindow(display_, id.id(), CompositeRedirectAutomatic); - Pixmap src_pixmap = XCompositeNameWindowPixmap(display_, id.id()); - if (!src_pixmap) { - // Even if the backing pixmap doesn't exist, this still should have - // succeeded and returned a valid handle (it just wouldn't be a handle to - // anything). So this is a real error path. - LOG(LS_ERROR) << "XCompositeNameWindowPixmap() failed"; - return NULL; - } - if (!XGetGeometry(display_, src_pixmap, &root, &x, &y, - &src_width, &src_height, &border_width, - &depth)) { - // If the window does not actually have a backing pixmap, this is the path - // that will "fail", so it's a warning rather than an error. - LOG(LS_WARNING) << "XGetGeometry() failed (probably composite is not in " - << "use)"; - XFreePixmap(display_, src_pixmap); - return NULL; - } - - // If we get to here, then composite is in use for this window and it has a - // valid backing pixmap. - - XWindowAttributes attr; - if (!XGetWindowAttributes(display_, id.id(), &attr)) { - LOG(LS_ERROR) << "XGetWindowAttributes() failed"; - XFreePixmap(display_, src_pixmap); - return NULL; - } - - uint8* data = GetDrawableThumbnail(src_pixmap, - attr.visual, - src_width, - src_height, - width, - height); - XFreePixmap(display_, src_pixmap); - return data; - } - - int GetNumDesktops() { - if (!Init()) { - return -1; - } - - return XScreenCount(display_); - } - - uint8* GetDesktopThumbnail(const DesktopId& id, int width, int height) { - if (!Init()) { - return NULL; - } - XErrorSuppressor error_suppressor(display_); - - Window root_window = id.id(); - XWindowAttributes attr; - if (!XGetWindowAttributes(display_, root_window, &attr)) { - LOG(LS_ERROR) << "XGetWindowAttributes() failed"; - return NULL; - } - - return GetDrawableThumbnail(root_window, - attr.visual, - attr.width, - attr.height, - width, - height); - } - - bool GetDesktopDimensions(const DesktopId& id, int* width, int* height) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - XWindowAttributes attr; - if (!XGetWindowAttributes(display_, id.id(), &attr)) { - LOG(LS_ERROR) << "XGetWindowAttributes() failed"; - return false; - } - *width = attr.width; - *height = attr.height; - return true; - } - - private: - uint8* GetDrawableThumbnail(Drawable src_drawable, - Visual* visual, - int src_width, - int src_height, - int dst_width, - int dst_height) { - if (!has_render_extension_) { - // Without the Xrender extension we would have to read the full window and - // scale it down in our process. Xrender is over a decade old so we aren't - // going to expend effort to support that situation. We still need to - // check though because probably some virtual VNC displays are in this - // category. - LOG(LS_INFO) << "No Xrender extension detected."; - return NULL; - } - - XRenderPictFormat* format = XRenderFindVisualFormat(display_, - visual); - if (!format) { - LOG(LS_ERROR) << "XRenderFindVisualFormat() failed"; - return NULL; - } - - // Create a picture to reference the window pixmap. - XRenderPictureAttributes pa; - pa.subwindow_mode = IncludeInferiors; // Don't clip child widgets - Picture src = XRenderCreatePicture(display_, - src_drawable, - format, - CPSubwindowMode, - &pa); - if (!src) { - LOG(LS_ERROR) << "XRenderCreatePicture() failed"; - return NULL; - } - - // Create a picture to reference the destination pixmap. - Pixmap dst_pixmap = XCreatePixmap(display_, - src_drawable, - dst_width, - dst_height, - format->depth); - if (!dst_pixmap) { - LOG(LS_ERROR) << "XCreatePixmap() failed"; - XRenderFreePicture(display_, src); - return NULL; - } - - Picture dst = XRenderCreatePicture(display_, dst_pixmap, format, 0, NULL); - if (!dst) { - LOG(LS_ERROR) << "XRenderCreatePicture() failed"; - XFreePixmap(display_, dst_pixmap); - XRenderFreePicture(display_, src); - return NULL; - } - - // Clear the background. - XRenderColor transparent = {0}; - XRenderFillRectangle(display_, - PictOpSrc, - dst, - &transparent, - 0, - 0, - dst_width, - dst_height); - - // Calculate how much we need to scale the image. - double scale_x = static_cast(dst_width) / - static_cast(src_width); - double scale_y = static_cast(dst_height) / - static_cast(src_height); - double scale = rtc::_min(scale_y, scale_x); - - int scaled_width = round(src_width * scale); - int scaled_height = round(src_height * scale); - - // Render the thumbnail centered on both axis. - int centered_x = (dst_width - scaled_width) / 2; - int centered_y = (dst_height - scaled_height) / 2; - - // Scaling matrix - XTransform xform = { { - { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) }, - { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) }, - { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(scale) } - } }; - XRenderSetPictureTransform(display_, src, &xform); - - // Apply filter to smooth out the image. - XRenderSetPictureFilter(display_, src, FilterBest, NULL, 0); - - // Render the image to the destination picture. - XRenderComposite(display_, - PictOpSrc, - src, - None, - dst, - 0, - 0, - 0, - 0, - centered_x, - centered_y, - scaled_width, - scaled_height); - - // Get the pixel data from the X server. TODO: XGetImage - // might be slow here, compare with ShmGetImage. - XImage* image = XGetImage(display_, - dst_pixmap, - 0, - 0, - dst_width, - dst_height, - AllPlanes, ZPixmap); - uint8* data = ArgbToRgba(reinterpret_cast(image->data), - centered_x, - centered_y, - scaled_width, - scaled_height, - dst_width, - dst_height, - false); - XDestroyImage(image); - XRenderFreePicture(display_, dst); - XFreePixmap(display_, dst_pixmap); - XRenderFreePicture(display_, src); - return data; - } - - uint8* ArgbToRgba(uint32* argb_data, int x, int y, int w, int h, - int stride_x, int stride_y, bool has_alpha) { - uint8* p; - int len = stride_x * stride_y * 4; - uint8* data = new uint8[len]; - memset(data, 0, len); - p = data + 4 * (y * stride_x + x); - for (int i = 0; i < h; ++i) { - for (int j = 0; j < w; ++j) { - uint32 argb; - uint32 rgba; - argb = argb_data[stride_x * (y + i) + x + j]; - rgba = (argb << 8) | (argb >> 24); - *p = rgba >> 24; - ++p; - *p = (rgba >> 16) & 0xff; - ++p; - *p = (rgba >> 8) & 0xff; - ++p; - *p = has_alpha ? rgba & 0xFF : 0xFF; - ++p; - } - p += (stride_x - w) * 4; - } - return data; - } - - bool EnumerateScreenWindows(WindowDescriptionList* descriptions, int screen) { - Window parent; - Window *children; - int status; - unsigned int num_children; - Window root_window = XRootWindow(display_, screen); - status = XQueryTree(display_, root_window, &root_window, &parent, &children, - &num_children); - if (status == 0) { - LOG(LS_ERROR) << "Failed to query for child windows."; - return false; - } - for (unsigned int i = 0; i < num_children; ++i) { - // Iterate in reverse order to display windows from front to back. -#ifdef CHROMEOS - // TODO(jhorwich): Short-term fix for crbug.com/120229: Don't need to - // filter, just return all windows and let the picker scan through them. - Window app_window = children[num_children - 1 - i]; -#else - Window app_window = GetApplicationWindow(children[num_children - 1 - i]); -#endif - if (app_window && - !LinuxWindowPicker::IsDesktopElement(display_, app_window)) { - std::string title; - if (GetWindowTitle(app_window, &title)) { - WindowId id(app_window); - WindowDescription desc(id, title); - descriptions->push_back(desc); - } - } - } - if (children != NULL) { - XFree(children); - } - return true; - } - - bool GetWindowTitle(Window window, std::string* title) { - int status; - bool result = false; - XTextProperty window_name; - window_name.value = NULL; - if (window) { - status = XGetWMName(display_, window, &window_name); - if (status && window_name.value && window_name.nitems) { - int cnt; - char **list = NULL; - status = Xutf8TextPropertyToTextList(display_, &window_name, &list, - &cnt); - if (status >= Success && cnt && *list) { - if (cnt > 1) { - LOG(LS_INFO) << "Window has " << cnt - << " text properties, only using the first one."; - } - *title = *list; - result = true; - } - if (list != NULL) { - XFreeStringList(list); - } - } - if (window_name.value != NULL) { - XFree(window_name.value); - } - } - return result; - } - - Window GetApplicationWindow(Window window) { - Window root, parent; - Window app_window = 0; - Window *children; - unsigned int num_children; - Atom type = None; - int format; - unsigned long nitems, after; - unsigned char *data; - - int ret = XGetWindowProperty(display_, window, - wm_state_, 0L, 2, - False, wm_state_, &type, &format, - &nitems, &after, &data); - if (ret != Success) { - LOG(LS_ERROR) << "XGetWindowProperty failed with return code " << ret - << " for window " << window << "."; - return 0; - } - if (type != None) { - int64 state = static_cast(*data); - XFree(data); - return state == NormalState ? window : 0; - } - XFree(data); - if (!XQueryTree(display_, window, &root, &parent, &children, - &num_children)) { - LOG(LS_ERROR) << "Failed to query for child windows although window" - << "does not have a valid WM_STATE."; - return 0; - } - for (unsigned int i = 0; i < num_children; ++i) { - app_window = GetApplicationWindow(children[i]); - if (app_window) { - break; - } - } - if (children != NULL) { - XFree(children); - } - return app_window; - } - - Atom wm_state_; - Atom net_wm_icon_; - Display* display_; - bool has_composite_extension_; - bool has_render_extension_; -}; - -LinuxWindowPicker::LinuxWindowPicker() : enumerator_(new XWindowEnumerator()) { -} - -LinuxWindowPicker::~LinuxWindowPicker() { -} - -bool LinuxWindowPicker::IsDesktopElement(_XDisplay* display, Window window) { - if (window == 0) { - LOG(LS_WARNING) << "Zero is never a valid window."; - return false; - } - - // First look for _NET_WM_WINDOW_TYPE. The standard - // (http://standards.freedesktop.org/wm-spec/latest/ar01s05.html#id2760306) - // says this hint *should* be present on all windows, and we use the existence - // of _NET_WM_WINDOW_TYPE_NORMAL in the property to indicate a window is not - // a desktop element (that is, only "normal" windows should be shareable). - Atom window_type_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE", True); - XWindowProperty window_type(display, window, window_type_atom); - if (window_type.succeeded() && window_type.size() > 0) { - Atom normal_window_type_atom = XInternAtom( - display, "_NET_WM_WINDOW_TYPE_NORMAL", True); - uint32_t* end = window_type.data() + window_type.size(); - bool is_normal = (end != std::find( - window_type.data(), end, normal_window_type_atom)); - return !is_normal; - } - - // Fall back on using the hint. - XClassHint class_hint; - Status s = XGetClassHint(display, window, &class_hint); - bool result = false; - if (s == 0) { - // No hints, assume this is a normal application window. - return result; - } - static const std::string gnome_panel("gnome-panel"); - static const std::string desktop_window("desktop_window"); - - if (gnome_panel.compare(class_hint.res_name) == 0 || - desktop_window.compare(class_hint.res_name) == 0) { - result = true; - } - XFree(class_hint.res_name); - XFree(class_hint.res_class); - return result; -} - -bool LinuxWindowPicker::Init() { - return enumerator_->Init(); -} - -bool LinuxWindowPicker::GetWindowList(WindowDescriptionList* descriptions) { - return enumerator_->EnumerateWindows(descriptions); -} - -bool LinuxWindowPicker::GetDesktopList(DesktopDescriptionList* descriptions) { - return enumerator_->EnumerateDesktops(descriptions); -} - -bool LinuxWindowPicker::IsVisible(const WindowId& id) { - return enumerator_->IsVisible(id); -} - -bool LinuxWindowPicker::MoveToFront(const WindowId& id) { - return enumerator_->MoveToFront(id); -} - - -uint8* LinuxWindowPicker::GetWindowIcon(const WindowId& id, int* width, - int* height) { - return enumerator_->GetWindowIcon(id, width, height); -} - -uint8* LinuxWindowPicker::GetWindowThumbnail(const WindowId& id, int width, - int height) { - return enumerator_->GetWindowThumbnail(id, width, height); -} - -int LinuxWindowPicker::GetNumDesktops() { - return enumerator_->GetNumDesktops(); -} - -uint8* LinuxWindowPicker::GetDesktopThumbnail(const DesktopId& id, - int width, - int height) { - return enumerator_->GetDesktopThumbnail(id, width, height); -} - -bool LinuxWindowPicker::GetDesktopDimensions(const DesktopId& id, int* width, - int* height) { - return enumerator_->GetDesktopDimensions(id, width, height); -} - -} // namespace rtc diff --git a/webrtc/base/linuxwindowpicker.h b/webrtc/base/linuxwindowpicker.h deleted file mode 100644 index f87b15081..000000000 --- a/webrtc/base/linuxwindowpicker.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_LINUXWINDOWPICKER_H_ -#define WEBRTC_BASE_LINUXWINDOWPICKER_H_ - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/windowpicker.h" - -// Avoid include . -struct _XDisplay; -typedef unsigned long Window; - -namespace rtc { - -class XWindowEnumerator; - -class LinuxWindowPicker : public WindowPicker { - public: - LinuxWindowPicker(); - ~LinuxWindowPicker(); - - static bool IsDesktopElement(_XDisplay* display, Window window); - - virtual bool Init(); - virtual bool IsVisible(const WindowId& id); - virtual bool MoveToFront(const WindowId& id); - virtual bool GetWindowList(WindowDescriptionList* descriptions); - virtual bool GetDesktopList(DesktopDescriptionList* descriptions); - virtual bool GetDesktopDimensions(const DesktopId& id, int* width, - int* height); - uint8* GetWindowIcon(const WindowId& id, int* width, int* height); - uint8* GetWindowThumbnail(const WindowId& id, int width, int height); - int GetNumDesktops(); - uint8* GetDesktopThumbnail(const DesktopId& id, int width, int height); - - private: - scoped_ptr enumerator_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_LINUXWINDOWPICKER_H_ diff --git a/webrtc/base/linuxwindowpicker_unittest.cc b/webrtc/base/linuxwindowpicker_unittest.cc deleted file mode 100644 index c2276ccd6..000000000 --- a/webrtc/base/linuxwindowpicker_unittest.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/linuxwindowpicker.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/testutils.h" -#include "webrtc/base/windowpicker.h" - -#if !defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) -#error Only for Linux -#endif - -namespace rtc { - -TEST(LinuxWindowPickerTest, TestGetWindowList) { - MAYBE_SKIP_SCREENCAST_TEST(); - LinuxWindowPicker window_picker; - WindowDescriptionList descriptions; - window_picker.Init(); - window_picker.GetWindowList(&descriptions); -} - -TEST(LinuxWindowPickerTest, TestGetDesktopList) { - MAYBE_SKIP_SCREENCAST_TEST(); - LinuxWindowPicker window_picker; - DesktopDescriptionList descriptions; - EXPECT_TRUE(window_picker.Init()); - EXPECT_TRUE(window_picker.GetDesktopList(&descriptions)); - EXPECT_TRUE(descriptions.size() > 0); -} - -} // namespace rtc diff --git a/webrtc/base/logging.cc b/webrtc/base/logging.cc deleted file mode 100644 index a417ed6c2..000000000 --- a/webrtc/base/logging.cc +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_WIN) -#define WIN32_LEAN_AND_MEAN -#include -#define snprintf _snprintf -#undef ERROR // wingdi.h -#endif - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include -#elif defined(WEBRTC_ANDROID) -#include -static const char kLibjingle[] = "libjingle"; -// Android has a 1024 limit on log inputs. We use 60 chars as an -// approx for the header/tag portion. -// See android/system/core/liblog/logd_write.c -static const int kMaxLogLineSize = 1024 - 60; -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) || WEBRTC_ANDROID - -#include - -#include -#include -#include -#include - -#include "webrtc/base/logging.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { - -///////////////////////////////////////////////////////////////////////////// -// Constant Labels -///////////////////////////////////////////////////////////////////////////// - -const char * FindLabel(int value, const ConstantLabel entries[]) { - for (int i = 0; entries[i].label; ++i) { - if (value == entries[i].value) { - return entries[i].label; - } - } - return 0; -} - -std::string ErrorName(int err, const ConstantLabel * err_table) { - if (err == 0) - return "No error"; - - if (err_table != 0) { - if (const char * value = FindLabel(err, err_table)) - return value; - } - - char buffer[16]; - snprintf(buffer, sizeof(buffer), "0x%08x", err); - return buffer; -} - -///////////////////////////////////////////////////////////////////////////// -// LogMessage -///////////////////////////////////////////////////////////////////////////// - -const int LogMessage::NO_LOGGING = LS_ERROR + 1; - -#if _DEBUG -static const int LOG_DEFAULT = LS_INFO; -#else // !_DEBUG -static const int LOG_DEFAULT = LogMessage::NO_LOGGING; -#endif // !_DEBUG - -// Global lock for log subsystem, only needed to serialize access to streams_. -CriticalSection LogMessage::crit_; - -// By default, release builds don't log, debug builds at info level -int LogMessage::min_sev_ = LOG_DEFAULT; -int LogMessage::dbg_sev_ = LOG_DEFAULT; - -// Don't bother printing context for the ubiquitous INFO log messages -int LogMessage::ctx_sev_ = LS_WARNING; - -// The list of logging streams currently configured. -// Note: we explicitly do not clean this up, because of the uncertain ordering -// of destructors at program exit. Let the person who sets the stream trigger -// cleanup by setting to NULL, or let it leak (safe at program exit). -LogMessage::StreamList LogMessage::streams_; - -// Boolean options default to false (0) -bool LogMessage::thread_, LogMessage::timestamp_; - -// If we're in diagnostic mode, we'll be explicitly set that way; default=false. -bool LogMessage::is_diagnostic_mode_ = false; - -LogMessage::LogMessage(const char* file, int line, LoggingSeverity sev, - LogErrorContext err_ctx, int err, const char* module) - : severity_(sev), - warn_slow_logs_delay_(WARN_SLOW_LOGS_DELAY) { - if (timestamp_) { - uint32 time = TimeSince(LogStartTime()); - // Also ensure WallClockStartTime is initialized, so that it matches - // LogStartTime. - WallClockStartTime(); - print_stream_ << "[" << std::setfill('0') << std::setw(3) << (time / 1000) - << ":" << std::setw(3) << (time % 1000) << std::setfill(' ') - << "] "; - } - - if (thread_) { -#if defined(WEBRTC_WIN) - DWORD id = GetCurrentThreadId(); - print_stream_ << "[" << std::hex << id << std::dec << "] "; -#endif // WEBRTC_WIN - } - - if (severity_ >= ctx_sev_) { - print_stream_ << Describe(sev) << "(" << DescribeFile(file) - << ":" << line << "): "; - } - - if (err_ctx != ERRCTX_NONE) { - std::ostringstream tmp; - tmp << "[0x" << std::setfill('0') << std::hex << std::setw(8) << err << "]"; - switch (err_ctx) { - case ERRCTX_ERRNO: - tmp << " " << strerror(err); - break; -#if WEBRTC_WIN - case ERRCTX_HRESULT: { - char msgbuf[256]; - DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM; - HMODULE hmod = GetModuleHandleA(module); - if (hmod) - flags |= FORMAT_MESSAGE_FROM_HMODULE; - if (DWORD len = FormatMessageA( - flags, hmod, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - msgbuf, sizeof(msgbuf) / sizeof(msgbuf[0]), NULL)) { - while ((len > 0) && - isspace(static_cast(msgbuf[len-1]))) { - msgbuf[--len] = 0; - } - tmp << " " << msgbuf; - } - break; - } -#endif // WEBRTC_WIN -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - case ERRCTX_OSSTATUS: { - tmp << " " << nonnull(GetMacOSStatusErrorString(err), "Unknown error"); - if (const char* desc = GetMacOSStatusCommentString(err)) { - tmp << ": " << desc; - } - break; - } -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) - default: - break; - } - extra_ = tmp.str(); - } -} - -LogMessage::~LogMessage() { - if (!extra_.empty()) - print_stream_ << " : " << extra_; - print_stream_ << std::endl; - - const std::string& str = print_stream_.str(); - if (severity_ >= dbg_sev_) { - OutputToDebug(str, severity_); - } - - uint32 before = Time(); - // Must lock streams_ before accessing - CritScope cs(&crit_); - for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { - if (severity_ >= it->second) { - OutputToStream(it->first, str); - } - } - uint32 delay = TimeSince(before); - if (delay >= warn_slow_logs_delay_) { - LogMessage slow_log_warning = - rtc::LogMessage(__FILE__, __LINE__, LS_WARNING); - // If our warning is slow, we don't want to warn about it, because - // that would lead to inifinite recursion. So, give a really big - // number for the delay threshold. - slow_log_warning.warn_slow_logs_delay_ = UINT_MAX; - slow_log_warning.stream() << "Slow log: took " << delay << "ms to write " - << str.size() << " bytes."; - } -} - -uint32 LogMessage::LogStartTime() { - static const uint32 g_start = Time(); - return g_start; -} - -uint32 LogMessage::WallClockStartTime() { - static const uint32 g_start_wallclock = time(NULL); - return g_start_wallclock; -} - -void LogMessage::LogContext(int min_sev) { - ctx_sev_ = min_sev; -} - -void LogMessage::LogThreads(bool on) { - thread_ = on; -} - -void LogMessage::LogTimestamps(bool on) { - timestamp_ = on; -} - -void LogMessage::LogToDebug(int min_sev) { - dbg_sev_ = min_sev; - UpdateMinLogSeverity(); -} - -void LogMessage::LogToStream(StreamInterface* stream, int min_sev) { - CritScope cs(&crit_); - // Discard and delete all previously installed streams - for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { - delete it->first; - } - streams_.clear(); - // Install the new stream, if specified - if (stream) { - AddLogToStream(stream, min_sev); - } -} - -int LogMessage::GetLogToStream(StreamInterface* stream) { - CritScope cs(&crit_); - int sev = NO_LOGGING; - for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { - if (!stream || stream == it->first) { - sev = _min(sev, it->second); - } - } - return sev; -} - -void LogMessage::AddLogToStream(StreamInterface* stream, int min_sev) { - CritScope cs(&crit_); - streams_.push_back(std::make_pair(stream, min_sev)); - UpdateMinLogSeverity(); -} - -void LogMessage::RemoveLogToStream(StreamInterface* stream) { - CritScope cs(&crit_); - for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { - if (stream == it->first) { - streams_.erase(it); - break; - } - } - UpdateMinLogSeverity(); -} - -void LogMessage::ConfigureLogging(const char* params, const char* filename) { - int current_level = LS_VERBOSE; - int debug_level = GetLogToDebug(); - int file_level = GetLogToStream(); - - std::vector tokens; - tokenize(params, ' ', &tokens); - - for (size_t i = 0; i < tokens.size(); ++i) { - if (tokens[i].empty()) - continue; - - // Logging features - if (tokens[i] == "tstamp") { - LogTimestamps(); - } else if (tokens[i] == "thread") { - LogThreads(); - - // Logging levels - } else if (tokens[i] == "sensitive") { - current_level = LS_SENSITIVE; - } else if (tokens[i] == "verbose") { - current_level = LS_VERBOSE; - } else if (tokens[i] == "info") { - current_level = LS_INFO; - } else if (tokens[i] == "warning") { - current_level = LS_WARNING; - } else if (tokens[i] == "error") { - current_level = LS_ERROR; - } else if (tokens[i] == "none") { - current_level = NO_LOGGING; - - // Logging targets - } else if (tokens[i] == "file") { - file_level = current_level; - } else if (tokens[i] == "debug") { - debug_level = current_level; - } - } - -#if defined(WEBRTC_WIN) - if ((NO_LOGGING != debug_level) && !::IsDebuggerPresent()) { - // First, attempt to attach to our parent's console... so if you invoke - // from the command line, we'll see the output there. Otherwise, create - // our own console window. - // Note: These methods fail if a console already exists, which is fine. - bool success = false; - typedef BOOL (WINAPI* PFN_AttachConsole)(DWORD); - if (HINSTANCE kernel32 = ::LoadLibrary(L"kernel32.dll")) { - // AttachConsole is defined on WinXP+. - if (PFN_AttachConsole attach_console = reinterpret_cast - (::GetProcAddress(kernel32, "AttachConsole"))) { - success = (FALSE != attach_console(ATTACH_PARENT_PROCESS)); - } - ::FreeLibrary(kernel32); - } - if (!success) { - ::AllocConsole(); - } - } -#endif // WEBRTC_WIN - - LogToDebug(debug_level); - -#if !defined(__native_client__) // No logging to file in NaCl. - scoped_ptr stream; - if (NO_LOGGING != file_level) { - stream.reset(new FileStream); - if (!stream->Open(filename, "wb", NULL) || !stream->DisableBuffering()) { - stream.reset(); - } - } - - LogToStream(stream.release(), file_level); -#endif -} - -int LogMessage::ParseLogSeverity(const std::string& value) { - int level = NO_LOGGING; - if (value == "LS_SENSITIVE") { - level = LS_SENSITIVE; - } else if (value == "LS_VERBOSE") { - level = LS_VERBOSE; - } else if (value == "LS_INFO") { - level = LS_INFO; - } else if (value == "LS_WARNING") { - level = LS_WARNING; - } else if (value == "LS_ERROR") { - level = LS_ERROR; - } else if (isdigit(value[0])) { - level = atoi(value.c_str()); // NOLINT - } - return level; -} - -void LogMessage::UpdateMinLogSeverity() { - int min_sev = dbg_sev_; - for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { - min_sev = _min(dbg_sev_, it->second); - } - min_sev_ = min_sev; -} - -const char* LogMessage::Describe(LoggingSeverity sev) { - switch (sev) { - case LS_SENSITIVE: return "Sensitive"; - case LS_VERBOSE: return "Verbose"; - case LS_INFO: return "Info"; - case LS_WARNING: return "Warning"; - case LS_ERROR: return "Error"; - default: return ""; - } -} - -const char* LogMessage::DescribeFile(const char* file) { - const char* end1 = ::strrchr(file, '/'); - const char* end2 = ::strrchr(file, '\\'); - if (!end1 && !end2) - return file; - else - return (end1 > end2) ? end1 + 1 : end2 + 1; -} - -void LogMessage::OutputToDebug(const std::string& str, - LoggingSeverity severity) { - bool log_to_stderr = true; -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && (!defined(DEBUG) || defined(NDEBUG)) - // On the Mac, all stderr output goes to the Console log and causes clutter. - // So in opt builds, don't log to stderr unless the user specifically sets - // a preference to do so. - CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, - "logToStdErr", - kCFStringEncodingUTF8); - CFStringRef domain = CFBundleGetIdentifier(CFBundleGetMainBundle()); - if (key != NULL && domain != NULL) { - Boolean exists_and_is_valid; - Boolean should_log = - CFPreferencesGetAppBooleanValue(key, domain, &exists_and_is_valid); - // If the key doesn't exist or is invalid or is false, we will not log to - // stderr. - log_to_stderr = exists_and_is_valid && should_log; - } - if (key != NULL) { - CFRelease(key); - } -#endif -#if defined(WEBRTC_WIN) - // Always log to the debugger. - // Perhaps stderr should be controlled by a preference, as on Mac? - OutputDebugStringA(str.c_str()); - if (log_to_stderr) { - // This handles dynamically allocated consoles, too. - if (HANDLE error_handle = ::GetStdHandle(STD_ERROR_HANDLE)) { - log_to_stderr = false; - DWORD written = 0; - ::WriteFile(error_handle, str.data(), static_cast(str.size()), - &written, 0); - } - } -#endif // WEBRTC_WIN -#if defined(WEBRTC_ANDROID) - // Android's logging facility uses severity to log messages but we - // need to map libjingle's severity levels to Android ones first. - // Also write to stderr which maybe available to executable started - // from the shell. - int prio; - switch (severity) { - case LS_SENSITIVE: - __android_log_write(ANDROID_LOG_INFO, kLibjingle, "SENSITIVE"); - if (log_to_stderr) { - fprintf(stderr, "SENSITIVE"); - fflush(stderr); - } - return; - case LS_VERBOSE: - prio = ANDROID_LOG_VERBOSE; - break; - case LS_INFO: - prio = ANDROID_LOG_INFO; - break; - case LS_WARNING: - prio = ANDROID_LOG_WARN; - break; - case LS_ERROR: - prio = ANDROID_LOG_ERROR; - break; - default: - prio = ANDROID_LOG_UNKNOWN; - } - - int size = str.size(); - int line = 0; - int idx = 0; - const int max_lines = size / kMaxLogLineSize + 1; - if (max_lines == 1) { - __android_log_print(prio, kLibjingle, "%.*s", size, str.c_str()); - } else { - while (size > 0) { - const int len = std::min(size, kMaxLogLineSize); - // Use the size of the string in the format (str may have \0 in the - // middle). - __android_log_print(prio, kLibjingle, "[%d/%d] %.*s", - line + 1, max_lines, - len, str.c_str() + idx); - idx += len; - size -= len; - ++line; - } - } -#endif // WEBRTC_ANDROID - if (log_to_stderr) { - fprintf(stderr, "%s", str.c_str()); - fflush(stderr); - } -} - -void LogMessage::OutputToStream(StreamInterface* stream, - const std::string& str) { - // If write isn't fully successful, what are we going to do, log it? :) - stream->WriteAll(str.data(), str.size(), NULL, NULL); -} - -////////////////////////////////////////////////////////////////////// -// Logging Helpers -////////////////////////////////////////////////////////////////////// - -void LogMultiline(LoggingSeverity level, const char* label, bool input, - const void* data, size_t len, bool hex_mode, - LogMultilineState* state) { - if (!LOG_CHECK_LEVEL_V(level)) - return; - - const char * direction = (input ? " << " : " >> "); - - // NULL data means to flush our count of unprintable characters. - if (!data) { - if (state && state->unprintable_count_[input]) { - LOG_V(level) << label << direction << "## " - << state->unprintable_count_[input] - << " consecutive unprintable ##"; - state->unprintable_count_[input] = 0; - } - return; - } - - // The ctype classification functions want unsigned chars. - const unsigned char* udata = static_cast(data); - - if (hex_mode) { - const size_t LINE_SIZE = 24; - char hex_line[LINE_SIZE * 9 / 4 + 2], asc_line[LINE_SIZE + 1]; - while (len > 0) { - memset(asc_line, ' ', sizeof(asc_line)); - memset(hex_line, ' ', sizeof(hex_line)); - size_t line_len = _min(len, LINE_SIZE); - for (size_t i = 0; i < line_len; ++i) { - unsigned char ch = udata[i]; - asc_line[i] = isprint(ch) ? ch : '.'; - hex_line[i*2 + i/4] = hex_encode(ch >> 4); - hex_line[i*2 + i/4 + 1] = hex_encode(ch & 0xf); - } - asc_line[sizeof(asc_line)-1] = 0; - hex_line[sizeof(hex_line)-1] = 0; - LOG_V(level) << label << direction - << asc_line << " " << hex_line << " "; - udata += line_len; - len -= line_len; - } - return; - } - - size_t consecutive_unprintable = state ? state->unprintable_count_[input] : 0; - - const unsigned char* end = udata + len; - while (udata < end) { - const unsigned char* line = udata; - const unsigned char* end_of_line = strchrn(udata, - end - udata, - '\n'); - if (!end_of_line) { - udata = end_of_line = end; - } else { - udata = end_of_line + 1; - } - - bool is_printable = true; - - // If we are in unprintable mode, we need to see a line of at least - // kMinPrintableLine characters before we'll switch back. - const ptrdiff_t kMinPrintableLine = 4; - if (consecutive_unprintable && ((end_of_line - line) < kMinPrintableLine)) { - is_printable = false; - } else { - // Determine if the line contains only whitespace and printable - // characters. - bool is_entirely_whitespace = true; - for (const unsigned char* pos = line; pos < end_of_line; ++pos) { - if (isspace(*pos)) - continue; - is_entirely_whitespace = false; - if (!isprint(*pos)) { - is_printable = false; - break; - } - } - // Treat an empty line following unprintable data as unprintable. - if (consecutive_unprintable && is_entirely_whitespace) { - is_printable = false; - } - } - if (!is_printable) { - consecutive_unprintable += (udata - line); - continue; - } - // Print out the current line, but prefix with a count of prior unprintable - // characters. - if (consecutive_unprintable) { - LOG_V(level) << label << direction << "## " << consecutive_unprintable - << " consecutive unprintable ##"; - consecutive_unprintable = 0; - } - // Strip off trailing whitespace. - while ((end_of_line > line) && isspace(*(end_of_line-1))) { - --end_of_line; - } - // Filter out any private data - std::string substr(reinterpret_cast(line), end_of_line - line); - std::string::size_type pos_private = substr.find("Email"); - if (pos_private == std::string::npos) { - pos_private = substr.find("Passwd"); - } - if (pos_private == std::string::npos) { - LOG_V(level) << label << direction << substr; - } else { - LOG_V(level) << label << direction << "## omitted for privacy ##"; - } - } - - if (state) { - state->unprintable_count_[input] = consecutive_unprintable; - } -} - -////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/logging.h b/webrtc/base/logging.h deleted file mode 100644 index 91d61b3e9..000000000 --- a/webrtc/base/logging.h +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// LOG(...) an ostream target that can be used to send formatted -// output to a variety of logging targets, such as debugger console, stderr, -// file, or any StreamInterface. -// The severity level passed as the first argument to the LOGging -// functions is used as a filter, to limit the verbosity of the logging. -// Static members of LogMessage documented below are used to control the -// verbosity and target of the output. -// There are several variations on the LOG macro which facilitate logging -// of common error conditions, detailed below. - -// LOG(sev) logs the given stream at severity "sev", which must be a -// compile-time constant of the LoggingSeverity type, without the namespace -// prefix. -// LOG_V(sev) Like LOG(), but sev is a run-time variable of the LoggingSeverity -// type (basically, it just doesn't prepend the namespace). -// LOG_F(sev) Like LOG(), but includes the name of the current function. -// LOG_T(sev) Like LOG(), but includes the this pointer. -// LOG_T_F(sev) Like LOG_F(), but includes the this pointer. -// LOG_GLE(M)(sev [, mod]) attempt to add a string description of the -// HRESULT returned by GetLastError. The "M" variant allows searching of a -// DLL's string table for the error description. -// LOG_ERRNO(sev) attempts to add a string description of an errno-derived -// error. errno and associated facilities exist on both Windows and POSIX, -// but on Windows they only apply to the C/C++ runtime. -// LOG_ERR(sev) is an alias for the platform's normal error system, i.e. _GLE on -// Windows and _ERRNO on POSIX. -// (The above three also all have _EX versions that let you specify the error -// code, rather than using the last one.) -// LOG_E(sev, ctx, err, ...) logs a detailed error interpreted using the -// specified context. -// LOG_CHECK_LEVEL(sev) (and LOG_CHECK_LEVEL_V(sev)) can be used as a test -// before performing expensive or sensitive operations whose sole purpose is -// to output logging data at the desired level. -// Lastly, PLOG(sev, err) is an alias for LOG_ERR_EX. - -#ifndef WEBRTC_BASE_LOGGING_H_ -#define WEBRTC_BASE_LOGGING_H_ - -#ifdef HAVE_CONFIG_H -#include "config.h" // NOLINT -#endif - -#include -#include -#include -#include -#include "webrtc/base/basictypes.h" -#include "webrtc/base/criticalsection.h" - -namespace rtc { - -class StreamInterface; - -/////////////////////////////////////////////////////////////////////////////// -// ConstantLabel can be used to easily generate string names from constant -// values. This can be useful for logging descriptive names of error messages. -// Usage: -// const ConstantLabel LIBRARY_ERRORS[] = { -// KLABEL(SOME_ERROR), -// KLABEL(SOME_OTHER_ERROR), -// ... -// LASTLABEL -// } -// -// int err = LibraryFunc(); -// LOG(LS_ERROR) << "LibraryFunc returned: " -// << ErrorName(err, LIBRARY_ERRORS); - -struct ConstantLabel { int value; const char * label; }; -#define KLABEL(x) { x, #x } -#define TLABEL(x, y) { x, y } -#define LASTLABEL { 0, 0 } - -const char * FindLabel(int value, const ConstantLabel entries[]); -std::string ErrorName(int err, const ConstantLabel* err_table); - -////////////////////////////////////////////////////////////////////// - -// Note that the non-standard LoggingSeverity aliases exist because they are -// still in broad use. The meanings of the levels are: -// LS_SENSITIVE: Information which should only be logged with the consent -// of the user, due to privacy concerns. -// LS_VERBOSE: This level is for data which we do not want to appear in the -// normal debug log, but should appear in diagnostic logs. -// LS_INFO: Chatty level used in debugging for all sorts of things, the default -// in debug builds. -// LS_WARNING: Something that may warrant investigation. -// LS_ERROR: Something that should not have occurred. -enum LoggingSeverity { LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR, - INFO = LS_INFO, - WARNING = LS_WARNING, - LERROR = LS_ERROR }; - -// LogErrorContext assists in interpreting the meaning of an error value. -enum LogErrorContext { - ERRCTX_NONE, - ERRCTX_ERRNO, // System-local errno - ERRCTX_HRESULT, // Windows HRESULT - ERRCTX_OSSTATUS, // MacOS OSStatus - - // Abbreviations for LOG_E macro - ERRCTX_EN = ERRCTX_ERRNO, // LOG_E(sev, EN, x) - ERRCTX_HR = ERRCTX_HRESULT, // LOG_E(sev, HR, x) - ERRCTX_OS = ERRCTX_OSSTATUS, // LOG_E(sev, OS, x) -}; - -class LogMessage { - public: - static const int NO_LOGGING; - static const uint32 WARN_SLOW_LOGS_DELAY = 50; // ms - - LogMessage(const char* file, int line, LoggingSeverity sev, - LogErrorContext err_ctx = ERRCTX_NONE, int err = 0, - const char* module = NULL); - ~LogMessage(); - - static inline bool Loggable(LoggingSeverity sev) { return (sev >= min_sev_); } - std::ostream& stream() { return print_stream_; } - - // Returns the time at which this function was called for the first time. - // The time will be used as the logging start time. - // If this is not called externally, the LogMessage ctor also calls it, in - // which case the logging start time will be the time of the first LogMessage - // instance is created. - static uint32 LogStartTime(); - - // Returns the wall clock equivalent of |LogStartTime|, in seconds from the - // epoch. - static uint32 WallClockStartTime(); - - // These are attributes which apply to all logging channels - // LogContext: Display the file and line number of the message - static void LogContext(int min_sev); - // LogThreads: Display the thread identifier of the current thread - static void LogThreads(bool on = true); - // LogTimestamps: Display the elapsed time of the program - static void LogTimestamps(bool on = true); - - // These are the available logging channels - // Debug: Debug console on Windows, otherwise stderr - static void LogToDebug(int min_sev); - static int GetLogToDebug() { return dbg_sev_; } - - // Stream: Any non-blocking stream interface. LogMessage takes ownership of - // the stream. Multiple streams may be specified by using AddLogToStream. - // LogToStream is retained for backwards compatibility; when invoked, it - // will discard any previously set streams and install the specified stream. - // GetLogToStream gets the severity for the specified stream, of if none - // is specified, the minimum stream severity. - // RemoveLogToStream removes the specified stream, without destroying it. - static void LogToStream(StreamInterface* stream, int min_sev); - static int GetLogToStream(StreamInterface* stream = NULL); - static void AddLogToStream(StreamInterface* stream, int min_sev); - static void RemoveLogToStream(StreamInterface* stream); - - // Testing against MinLogSeverity allows code to avoid potentially expensive - // logging operations by pre-checking the logging level. - static int GetMinLogSeverity() { return min_sev_; } - - static void SetDiagnosticMode(bool f) { is_diagnostic_mode_ = f; } - static bool IsDiagnosticMode() { return is_diagnostic_mode_; } - - // Parses the provided parameter stream to configure the options above. - // Useful for configuring logging from the command line. If file logging - // is enabled, it is output to the specified filename. - static void ConfigureLogging(const char* params, const char* filename); - - // Convert the string to a LS_ value; also accept numeric values. - static int ParseLogSeverity(const std::string& value); - - private: - typedef std::list > StreamList; - - // Updates min_sev_ appropriately when debug sinks change. - static void UpdateMinLogSeverity(); - - // These assist in formatting some parts of the debug output. - static const char* Describe(LoggingSeverity sev); - static const char* DescribeFile(const char* file); - - // These write out the actual log messages. - static void OutputToDebug(const std::string& msg, LoggingSeverity severity_); - static void OutputToStream(StreamInterface* stream, const std::string& msg); - - // The ostream that buffers the formatted message before output - std::ostringstream print_stream_; - - // The severity level of this message - LoggingSeverity severity_; - - // String data generated in the constructor, that should be appended to - // the message before output. - std::string extra_; - - // If time it takes to write to stream is more than this, log one - // additional warning about it. - uint32 warn_slow_logs_delay_; - - // Global lock for the logging subsystem - static CriticalSection crit_; - - // dbg_sev_ is the thresholds for those output targets - // min_sev_ is the minimum (most verbose) of those levels, and is used - // as a short-circuit in the logging macros to identify messages that won't - // be logged. - // ctx_sev_ is the minimum level at which file context is displayed - static int min_sev_, dbg_sev_, ctx_sev_; - - // The output streams and their associated severities - static StreamList streams_; - - // Flags for formatting options - static bool thread_, timestamp_; - - // are we in diagnostic mode (as defined by the app)? - static bool is_diagnostic_mode_; - - DISALLOW_EVIL_CONSTRUCTORS(LogMessage); -}; - -////////////////////////////////////////////////////////////////////// -// Logging Helpers -////////////////////////////////////////////////////////////////////// - -class LogMultilineState { - public: - size_t unprintable_count_[2]; - LogMultilineState() { - unprintable_count_[0] = unprintable_count_[1] = 0; - } -}; - -// When possible, pass optional state variable to track various data across -// multiple calls to LogMultiline. Otherwise, pass NULL. -void LogMultiline(LoggingSeverity level, const char* label, bool input, - const void* data, size_t len, bool hex_mode, - LogMultilineState* state); - -////////////////////////////////////////////////////////////////////// -// Macros which automatically disable logging when LOGGING == 0 -////////////////////////////////////////////////////////////////////// - -// If LOGGING is not explicitly defined, default to enabled in debug mode -#if !defined(LOGGING) -#if defined(_DEBUG) && !defined(NDEBUG) -#define LOGGING 1 -#else -#define LOGGING 0 -#endif -#endif // !defined(LOGGING) - -#ifndef LOG -#if LOGGING - -// The following non-obvious technique for implementation of a -// conditional log stream was stolen from google3/base/logging.h. - -// This class is used to explicitly ignore values in the conditional -// logging macros. This avoids compiler warnings like "value computed -// is not used" and "statement has no effect". - -class LogMessageVoidify { - public: - LogMessageVoidify() { } - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(std::ostream&) { } -}; - -#define LOG_SEVERITY_PRECONDITION(sev) \ - !(rtc::LogMessage::Loggable(sev)) \ - ? (void) 0 \ - : rtc::LogMessageVoidify() & - -#define LOG(sev) \ - LOG_SEVERITY_PRECONDITION(rtc::sev) \ - rtc::LogMessage(__FILE__, __LINE__, rtc::sev).stream() - -// The _V version is for when a variable is passed in. It doesn't do the -// namespace concatination. -#define LOG_V(sev) \ - LOG_SEVERITY_PRECONDITION(sev) \ - rtc::LogMessage(__FILE__, __LINE__, sev).stream() - -// The _F version prefixes the message with the current function name. -#if (defined(__GNUC__) && defined(_DEBUG)) || defined(WANT_PRETTY_LOG_F) -#define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": " -#define LOG_T_F(sev) LOG(sev) << this << ": " << __PRETTY_FUNCTION__ << ": " -#else -#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": " -#define LOG_T_F(sev) LOG(sev) << this << ": " << __FUNCTION__ << ": " -#endif - -#define LOG_CHECK_LEVEL(sev) \ - rtc::LogCheckLevel(rtc::sev) -#define LOG_CHECK_LEVEL_V(sev) \ - rtc::LogCheckLevel(sev) -inline bool LogCheckLevel(LoggingSeverity sev) { - return (LogMessage::GetMinLogSeverity() <= sev); -} - -#define LOG_E(sev, ctx, err, ...) \ - LOG_SEVERITY_PRECONDITION(rtc::sev) \ - rtc::LogMessage(__FILE__, __LINE__, rtc::sev, \ - rtc::ERRCTX_ ## ctx, err , ##__VA_ARGS__) \ - .stream() - -#define LOG_T(sev) LOG(sev) << this << ": " - -#else // !LOGGING - -// Hopefully, the compiler will optimize away some of this code. -// Note: syntax of "1 ? (void)0 : LogMessage" was causing errors in g++, -// converted to "while (false)" -#define LOG(sev) \ - while (false)rtc:: LogMessage(NULL, 0, rtc::sev).stream() -#define LOG_V(sev) \ - while (false) rtc::LogMessage(NULL, 0, sev).stream() -#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": " -#define LOG_CHECK_LEVEL(sev) \ - false -#define LOG_CHECK_LEVEL_V(sev) \ - false - -#define LOG_E(sev, ctx, err, ...) \ - while (false) rtc::LogMessage(__FILE__, __LINE__, rtc::sev, \ - rtc::ERRCTX_ ## ctx, err , ##__VA_ARGS__) \ - .stream() - -#define LOG_T(sev) LOG(sev) << this << ": " -#define LOG_T_F(sev) LOG(sev) << this << ": " << __FUNCTION__ << -#endif // !LOGGING - -#define LOG_ERRNO_EX(sev, err) \ - LOG_E(sev, ERRNO, err) -#define LOG_ERRNO(sev) \ - LOG_ERRNO_EX(sev, errno) - -#if defined(WEBRTC_WIN) -#define LOG_GLE_EX(sev, err) \ - LOG_E(sev, HRESULT, err) -#define LOG_GLE(sev) \ - LOG_GLE_EX(sev, GetLastError()) -#define LOG_GLEM(sev, mod) \ - LOG_E(sev, HRESULT, GetLastError(), mod) -#define LOG_ERR_EX(sev, err) \ - LOG_GLE_EX(sev, err) -#define LOG_ERR(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 defined(WEBRTC_POSIX) -#define LOG_ERR_EX(sev, err) \ - LOG_ERRNO_EX(sev, err) -#define LOG_ERR(sev) \ - LOG_ERRNO(sev) -#define LAST_SYSTEM_ERROR \ - (errno) -#endif // WEBRTC_WIN - -#define PLOG(sev, err) \ - LOG_ERR_EX(sev, err) - -// TODO(?): Add an "assert" wrapper that logs in the same manner. - -#endif // LOG - -} // namespace rtc - -#endif // WEBRTC_BASE_LOGGING_H_ diff --git a/webrtc/base/logging_unittest.cc b/webrtc/base/logging_unittest.cc deleted file mode 100644 index 59630d746..000000000 --- a/webrtc/base/logging_unittest.cc +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/fileutils.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -// Test basic logging operation. We should get the INFO log but not the VERBOSE. -// We should restore the correct global state at the end. -TEST(LogTest, SingleStream) { - int sev = LogMessage::GetLogToStream(NULL); - - std::string str; - StringStream stream(str); - LogMessage::AddLogToStream(&stream, LS_INFO); - EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream)); - - LOG(LS_INFO) << "INFO"; - LOG(LS_VERBOSE) << "VERBOSE"; - EXPECT_NE(std::string::npos, str.find("INFO")); - EXPECT_EQ(std::string::npos, str.find("VERBOSE")); - - LogMessage::RemoveLogToStream(&stream); - EXPECT_EQ(LogMessage::NO_LOGGING, LogMessage::GetLogToStream(&stream)); - - EXPECT_EQ(sev, LogMessage::GetLogToStream(NULL)); -} - -// Test using multiple log streams. The INFO stream should get the INFO message, -// the VERBOSE stream should get the INFO and the VERBOSE. -// We should restore the correct global state at the end. -TEST(LogTest, MultipleStreams) { - int sev = LogMessage::GetLogToStream(NULL); - - std::string str1, str2; - StringStream stream1(str1), stream2(str2); - LogMessage::AddLogToStream(&stream1, LS_INFO); - LogMessage::AddLogToStream(&stream2, LS_VERBOSE); - EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream1)); - EXPECT_EQ(LS_VERBOSE, LogMessage::GetLogToStream(&stream2)); - - LOG(LS_INFO) << "INFO"; - LOG(LS_VERBOSE) << "VERBOSE"; - - EXPECT_NE(std::string::npos, str1.find("INFO")); - EXPECT_EQ(std::string::npos, str1.find("VERBOSE")); - EXPECT_NE(std::string::npos, str2.find("INFO")); - EXPECT_NE(std::string::npos, str2.find("VERBOSE")); - - LogMessage::RemoveLogToStream(&stream2); - LogMessage::RemoveLogToStream(&stream1); - EXPECT_EQ(LogMessage::NO_LOGGING, LogMessage::GetLogToStream(&stream2)); - EXPECT_EQ(LogMessage::NO_LOGGING, LogMessage::GetLogToStream(&stream1)); - - EXPECT_EQ(sev, LogMessage::GetLogToStream(NULL)); -} - -// Ensure we don't crash when adding/removing streams while threads are going. -// We should restore the correct global state at the end. -class LogThread : public Thread { - public: - virtual ~LogThread() { - Stop(); - } - - private: - void Run() { - // LS_SENSITIVE to avoid cluttering up any real logging going on - LOG(LS_SENSITIVE) << "LOG"; - } -}; - -TEST(LogTest, MultipleThreads) { - int sev = LogMessage::GetLogToStream(NULL); - - LogThread thread1, thread2, thread3; - thread1.Start(); - thread2.Start(); - thread3.Start(); - - NullStream stream1, stream2, stream3; - for (int i = 0; i < 1000; ++i) { - LogMessage::AddLogToStream(&stream1, LS_INFO); - LogMessage::AddLogToStream(&stream2, LS_VERBOSE); - LogMessage::AddLogToStream(&stream3, LS_SENSITIVE); - LogMessage::RemoveLogToStream(&stream1); - LogMessage::RemoveLogToStream(&stream2); - LogMessage::RemoveLogToStream(&stream3); - } - - EXPECT_EQ(sev, LogMessage::GetLogToStream(NULL)); -} - - -TEST(LogTest, WallClockStartTime) { - uint32 time = LogMessage::WallClockStartTime(); - // Expect the time to be in a sensible range, e.g. > 2012-01-01. - EXPECT_GT(time, 1325376000u); -} - -// Test the time required to write 1000 80-character logs to an unbuffered file. -TEST(LogTest, Perf) { - Pathname path; - EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL)); - path.SetPathname(Filesystem::TempFilename(path, "ut")); - - FileStream stream; - EXPECT_TRUE(stream.Open(path.pathname(), "wb", NULL)); - stream.DisableBuffering(); - LogMessage::AddLogToStream(&stream, LS_SENSITIVE); - - uint32 start = Time(), finish; - std::string message('X', 80); - for (int i = 0; i < 1000; ++i) { - LOG(LS_SENSITIVE) << message; - } - finish = Time(); - - LogMessage::RemoveLogToStream(&stream); - stream.Close(); - Filesystem::DeleteFile(path); - - LOG(LS_INFO) << "Average log time: " << TimeDiff(finish, start) << " us"; -} - -} // namespace rtc diff --git a/webrtc/base/macasyncsocket.cc b/webrtc/base/macasyncsocket.cc deleted file mode 100644 index ee982ffff..000000000 --- a/webrtc/base/macasyncsocket.cc +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -// -// MacAsyncSocket is a kind of AsyncSocket. It does not support the SOCK_DGRAM -// type (yet). It works asynchronously, which means that users of this socket -// should connect to the various events declared in asyncsocket.h to receive -// notifications about this socket. It uses CFSockets for signals, but prefers -// the basic bsd socket operations rather than their CFSocket wrappers when -// possible. - -#include -#include - -#include "webrtc/base/macasyncsocket.h" - -#include "webrtc/base/logging.h" -#include "webrtc/base/macsocketserver.h" - -namespace rtc { - -static const int kCallbackFlags = kCFSocketReadCallBack | - kCFSocketConnectCallBack | - kCFSocketWriteCallBack; - -MacAsyncSocket::MacAsyncSocket(MacBaseSocketServer* ss, int family) - : ss_(ss), - socket_(NULL), - native_socket_(INVALID_SOCKET), - source_(NULL), - current_callbacks_(0), - disabled_(false), - error_(0), - state_(CS_CLOSED), - resolver_(NULL) { - Initialize(family); -} - -MacAsyncSocket::~MacAsyncSocket() { - Close(); -} - -// Returns the address to which the socket is bound. If the socket is not -// bound, then the any-address is returned. -SocketAddress MacAsyncSocket::GetLocalAddress() const { - SocketAddress address; - - // The CFSocket doesn't pick up on implicit binds from the connect call. - // Calling bind in before connect explicitly causes errors, so just query - // the underlying bsd socket. - sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); - int result = ::getsockname(native_socket_, - reinterpret_cast(&addr), &addrlen); - if (result >= 0) { - SocketAddressFromSockAddrStorage(addr, &address); - } - return address; -} - -// Returns the address to which the socket is connected. If the socket is not -// connected, then the any-address is returned. -SocketAddress MacAsyncSocket::GetRemoteAddress() const { - SocketAddress address; - - // Use native_socket for consistency with GetLocalAddress. - sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); - int result = ::getpeername(native_socket_, - reinterpret_cast(&addr), &addrlen); - if (result >= 0) { - SocketAddressFromSockAddrStorage(addr, &address); - } - return address; -} - -// Bind the socket to a local address. -int MacAsyncSocket::Bind(const SocketAddress& address) { - sockaddr_storage saddr = {0}; - size_t len = address.ToSockAddrStorage(&saddr); - int err = ::bind(native_socket_, reinterpret_cast(&saddr), len); - if (err == SOCKET_ERROR) error_ = errno; - return err; -} - -void MacAsyncSocket::OnResolveResult(SignalThread* thread) { - if (thread != resolver_) { - return; - } - int error = resolver_->GetError(); - if (error == 0) { - error = DoConnect(resolver_->address()); - } else { - Close(); - } - if (error) { - error_ = error; - SignalCloseEvent(this, error_); - } -} - -// Connect to a remote address. -int MacAsyncSocket::Connect(const SocketAddress& addr) { - // TODO(djw): Consolidate all the connect->resolve->doconnect implementations. - if (state_ != CS_CLOSED) { - SetError(EALREADY); - return SOCKET_ERROR; - } - if (addr.IsUnresolved()) { - LOG(LS_VERBOSE) << "Resolving addr in MacAsyncSocket::Connect"; - resolver_ = new AsyncResolver(); - resolver_->SignalWorkDone.connect(this, - &MacAsyncSocket::OnResolveResult); - resolver_->Start(addr); - state_ = CS_CONNECTING; - return 0; - } - return DoConnect(addr); -} - -int MacAsyncSocket::DoConnect(const SocketAddress& addr) { - if (!valid()) { - Initialize(addr.family()); - if (!valid()) - return SOCKET_ERROR; - } - - sockaddr_storage saddr; - size_t len = addr.ToSockAddrStorage(&saddr); - int result = ::connect(native_socket_, reinterpret_cast(&saddr), - len); - - if (result != SOCKET_ERROR) { - state_ = CS_CONNECTED; - } else { - error_ = errno; - if (error_ == EINPROGRESS) { - state_ = CS_CONNECTING; - result = 0; - } - } - return result; -} - -// Send to the remote end we're connected to. -int MacAsyncSocket::Send(const void* buffer, size_t length) { - if (!valid()) { - return SOCKET_ERROR; - } - - int sent = ::send(native_socket_, buffer, length, 0); - - if (sent == SOCKET_ERROR) { - error_ = errno; - - if (IsBlocking()) { - // Reenable the writable callback (once), since we are flow controlled. - CFSocketEnableCallBacks(socket_, kCallbackFlags); - current_callbacks_ = kCallbackFlags; - } - } - return sent; -} - -// Send to the given address. We may or may not be connected to anyone. -int MacAsyncSocket::SendTo(const void* buffer, size_t length, - const SocketAddress& address) { - if (!valid()) { - return SOCKET_ERROR; - } - - sockaddr_storage saddr; - size_t len = address.ToSockAddrStorage(&saddr); - int sent = ::sendto(native_socket_, buffer, length, 0, - reinterpret_cast(&saddr), len); - - if (sent == SOCKET_ERROR) { - error_ = errno; - } - - return sent; -} - -// Read data received from the remote end we're connected to. -int MacAsyncSocket::Recv(void* buffer, size_t length) { - int received = ::recv(native_socket_, reinterpret_cast(buffer), - length, 0); - if (received == SOCKET_ERROR) error_ = errno; - - // Recv should only be called when there is data to read - ASSERT((received != 0) || (length == 0)); - return received; -} - -// Read data received from any remote party -int MacAsyncSocket::RecvFrom(void* buffer, size_t length, - SocketAddress* out_addr) { - sockaddr_storage saddr; - socklen_t addr_len = sizeof(saddr); - int received = ::recvfrom(native_socket_, reinterpret_cast(buffer), - length, 0, reinterpret_cast(&saddr), - &addr_len); - if (received >= 0 && out_addr != NULL) { - SocketAddressFromSockAddrStorage(saddr, out_addr); - } else if (received == SOCKET_ERROR) { - error_ = errno; - } - return received; -} - -int MacAsyncSocket::Listen(int backlog) { - if (!valid()) { - return SOCKET_ERROR; - } - - int res = ::listen(native_socket_, backlog); - if (res != SOCKET_ERROR) - state_ = CS_CONNECTING; - else - error_ = errno; - - return res; -} - -MacAsyncSocket* MacAsyncSocket::Accept(SocketAddress* out_addr) { - sockaddr_storage saddr; - socklen_t addr_len = sizeof(saddr); - - int socket_fd = ::accept(native_socket_, reinterpret_cast(&saddr), - &addr_len); - if (socket_fd == INVALID_SOCKET) { - error_ = errno; - return NULL; - } - - MacAsyncSocket* s = new MacAsyncSocket(ss_, saddr.ss_family, socket_fd); - if (s && s->valid()) { - s->state_ = CS_CONNECTED; - if (out_addr) - SocketAddressFromSockAddrStorage(saddr, out_addr); - } else { - delete s; - s = NULL; - } - return s; -} - -int MacAsyncSocket::Close() { - if (source_ != NULL) { - CFRunLoopSourceInvalidate(source_); - CFRelease(source_); - if (ss_) ss_->UnregisterSocket(this); - source_ = NULL; - } - - if (socket_ != NULL) { - CFSocketInvalidate(socket_); - CFRelease(socket_); - socket_ = NULL; - } - - if (resolver_) { - resolver_->Destroy(false); - resolver_ = NULL; - } - - native_socket_ = INVALID_SOCKET; // invalidates the socket - error_ = 0; - state_ = CS_CLOSED; - return 0; -} - -int MacAsyncSocket::EstimateMTU(uint16* mtu) { - ASSERT(false && "NYI"); - return -1; -} - -int MacAsyncSocket::GetError() const { - return error_; -} - -void MacAsyncSocket::SetError(int error) { - error_ = error; -} - -Socket::ConnState MacAsyncSocket::GetState() const { - return state_; -} - -int MacAsyncSocket::GetOption(Option opt, int* value) { - ASSERT(false && "NYI"); - return -1; -} - -int MacAsyncSocket::SetOption(Option opt, int value) { - ASSERT(false && "NYI"); - return -1; -} - -void MacAsyncSocket::EnableCallbacks() { - if (valid()) { - disabled_ = false; - CFSocketEnableCallBacks(socket_, current_callbacks_); - } -} - -void MacAsyncSocket::DisableCallbacks() { - if (valid()) { - disabled_ = true; - CFSocketDisableCallBacks(socket_, kCallbackFlags); - } -} - -MacAsyncSocket::MacAsyncSocket(MacBaseSocketServer* ss, int family, - int native_socket) - : ss_(ss), - socket_(NULL), - native_socket_(native_socket), - source_(NULL), - current_callbacks_(0), - disabled_(false), - error_(0), - state_(CS_CLOSED), - resolver_(NULL) { - Initialize(family); -} - -// Create a new socket, wrapping the native socket if provided or creating one -// otherwise. In case of any failure, consume the native socket. We assume the -// wrapped socket is in the closed state. If this is not the case you must -// update the state_ field for this socket yourself. -void MacAsyncSocket::Initialize(int family) { - CFSocketContext ctx = { 0 }; - ctx.info = this; - - // First create the CFSocket - CFSocketRef cf_socket = NULL; - bool res = false; - if (native_socket_ == INVALID_SOCKET) { - cf_socket = CFSocketCreate(kCFAllocatorDefault, - family, SOCK_STREAM, IPPROTO_TCP, - kCallbackFlags, MacAsyncSocketCallBack, &ctx); - } else { - cf_socket = CFSocketCreateWithNative(kCFAllocatorDefault, - native_socket_, kCallbackFlags, - MacAsyncSocketCallBack, &ctx); - } - - if (cf_socket) { - res = true; - socket_ = cf_socket; - native_socket_ = CFSocketGetNative(cf_socket); - current_callbacks_ = kCallbackFlags; - } - - if (res) { - // Make the underlying socket asynchronous - res = (-1 != ::fcntl(native_socket_, F_SETFL, - ::fcntl(native_socket_, F_GETFL, 0) | O_NONBLOCK)); - } - - if (res) { - // Add this socket to the run loop, at priority 1 so that it will be - // queued behind any pending signals. - source_ = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket_, 1); - res = (source_ != NULL); - if (!res) errno = EINVAL; - } - - if (res) { - if (ss_) ss_->RegisterSocket(this); - CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopCommonModes); - } - - if (!res) { - int error = errno; - Close(); // Clears error_. - error_ = error; - } -} - -// Call CFRelease on the result when done using it -CFDataRef MacAsyncSocket::CopyCFAddress(const SocketAddress& address) { - sockaddr_storage saddr; - size_t len = address.ToSockAddrStorage(&saddr); - - const UInt8* bytes = reinterpret_cast(&saddr); - - CFDataRef cf_address = CFDataCreate(kCFAllocatorDefault, - bytes, len); - - ASSERT(cf_address != NULL); - return cf_address; -} - -void MacAsyncSocket::MacAsyncSocketCallBack(CFSocketRef s, - CFSocketCallBackType callbackType, - CFDataRef address, - const void* data, - void* info) { - MacAsyncSocket* this_socket = - reinterpret_cast(info); - ASSERT(this_socket != NULL && this_socket->socket_ == s); - - // Don't signal any socket messages if the socketserver is not listening on - // them. When we are reenabled they will be requeued and will fire again. - if (this_socket->disabled_) - return; - - switch (callbackType) { - case kCFSocketReadCallBack: - // This callback is invoked in one of 3 situations: - // 1. A new connection is waiting to be accepted. - // 2. The remote end closed the connection (a recv will return 0). - // 3. Data is available to read. - // 4. The connection closed unhappily (recv will return -1). - if (this_socket->state_ == CS_CONNECTING) { - // Case 1. - this_socket->SignalReadEvent(this_socket); - } else { - char ch, amt; - amt = ::recv(this_socket->native_socket_, &ch, 1, MSG_PEEK); - if (amt == 0) { - // Case 2. - this_socket->state_ = CS_CLOSED; - - // Disable additional callbacks or we will signal close twice. - CFSocketDisableCallBacks(this_socket->socket_, kCFSocketReadCallBack); - this_socket->current_callbacks_ &= ~kCFSocketReadCallBack; - this_socket->SignalCloseEvent(this_socket, 0); - } else if (amt > 0) { - // Case 3. - this_socket->SignalReadEvent(this_socket); - } else { - // Case 4. - int error = errno; - if (error == EAGAIN) { - // Observed in practice. Let's hope it's a spurious or out of date - // signal, since we just eat it. - } else { - this_socket->error_ = error; - this_socket->SignalCloseEvent(this_socket, error); - } - } - } - break; - - case kCFSocketConnectCallBack: - if (data != NULL) { - // An error occured in the background while connecting - this_socket->error_ = errno; - this_socket->state_ = CS_CLOSED; - this_socket->SignalCloseEvent(this_socket, this_socket->error_); - } else { - this_socket->state_ = CS_CONNECTED; - this_socket->SignalConnectEvent(this_socket); - } - break; - - case kCFSocketWriteCallBack: - // Update our callback tracking. Write doesn't reenable, so it's off now. - this_socket->current_callbacks_ &= ~kCFSocketWriteCallBack; - this_socket->SignalWriteEvent(this_socket); - break; - - default: - ASSERT(false && "Invalid callback type for socket"); - } -} - -} // namespace rtc diff --git a/webrtc/base/macasyncsocket.h b/webrtc/base/macasyncsocket.h deleted file mode 100644 index bf8386546..000000000 --- a/webrtc/base/macasyncsocket.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -// MacAsyncSocket is a kind of AsyncSocket. It only creates sockets -// of the TCP type, and does not (yet) support listen and accept. It works -// asynchronously, which means that users of this socket should connect to -// the various events declared in asyncsocket.h to receive notifications about -// this socket. - -#ifndef WEBRTC_BASE_MACASYNCSOCKET_H__ -#define WEBRTC_BASE_MACASYNCSOCKET_H__ - -#include - -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/nethelpers.h" - -namespace rtc { - -class MacBaseSocketServer; - -class MacAsyncSocket : public AsyncSocket, public sigslot::has_slots<> { - public: - MacAsyncSocket(MacBaseSocketServer* ss, int family); - virtual ~MacAsyncSocket(); - - bool valid() const { return source_ != NULL; } - - // Socket interface - virtual SocketAddress GetLocalAddress() const; - virtual SocketAddress GetRemoteAddress() const; - virtual int Bind(const SocketAddress& addr); - virtual int Connect(const SocketAddress& addr); - virtual int Send(const void* buffer, size_t length); - virtual int SendTo(const void* buffer, size_t length, - const SocketAddress& addr); - virtual int Recv(void* buffer, size_t length); - virtual int RecvFrom(void* buffer, size_t length, SocketAddress* out_addr); - virtual int Listen(int backlog); - virtual MacAsyncSocket* Accept(SocketAddress* out_addr); - virtual int Close(); - virtual int GetError() const; - virtual void SetError(int error); - virtual ConnState GetState() const; - virtual int EstimateMTU(uint16* mtu); - virtual int GetOption(Option opt, int* value); - virtual int SetOption(Option opt, int value); - - // For the MacBaseSocketServer to disable callbacks when process_io is false. - void EnableCallbacks(); - void DisableCallbacks(); - - protected: - void OnResolveResult(SignalThread* thread); - int DoConnect(const SocketAddress& addr); - - private: - // Creates an async socket from an existing bsd socket - MacAsyncSocket(MacBaseSocketServer* ss, int family, int native_socket); - - // Attaches the socket to the CFRunloop and sets the wrapped bsd socket - // to async mode - void Initialize(int family); - - // Translate the SocketAddress into a CFDataRef to pass to CF socket - // functions. Caller must call CFRelease on the result when done. - static CFDataRef CopyCFAddress(const SocketAddress& address); - - // Callback for the underlying CFSocketRef. - static void MacAsyncSocketCallBack(CFSocketRef s, - CFSocketCallBackType callbackType, - CFDataRef address, - const void* data, - void* info); - - MacBaseSocketServer* ss_; - CFSocketRef socket_; - int native_socket_; - CFRunLoopSourceRef source_; - int current_callbacks_; - bool disabled_; - int error_; - ConnState state_; - AsyncResolver* resolver_; - - DISALLOW_EVIL_CONSTRUCTORS(MacAsyncSocket); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_MACASYNCSOCKET_H__ diff --git a/webrtc/base/maccocoasocketserver.h b/webrtc/base/maccocoasocketserver.h deleted file mode 100644 index d5deac153..000000000 --- a/webrtc/base/maccocoasocketserver.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// A libjingle compatible SocketServer for OSX/iOS/Cocoa. - -#ifndef WEBRTC_BASE_MACCOCOASOCKETSERVER_H_ -#define WEBRTC_BASE_MACCOCOASOCKETSERVER_H_ - -#include "webrtc/base/macsocketserver.h" - -#ifdef __OBJC__ -@class NSTimer, MacCocoaSocketServerHelperRtc; -#else -class NSTimer; -class MacCocoaSocketServerHelperRtc; -#endif - -namespace rtc { - -// A socketserver implementation that wraps the main cocoa -// application loop accessed through [NSApp run]. -class MacCocoaSocketServer : public MacBaseSocketServer { - public: - explicit MacCocoaSocketServer(); - virtual ~MacCocoaSocketServer(); - - virtual bool Wait(int cms, bool process_io); - virtual void WakeUp(); - - private: - MacCocoaSocketServerHelperRtc* helper_; - NSTimer* timer_; // Weak. - // The count of how many times we're inside the NSApplication main loop. - int run_count_; - - DISALLOW_EVIL_CONSTRUCTORS(MacCocoaSocketServer); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_MACCOCOASOCKETSERVER_H_ diff --git a/webrtc/base/maccocoasocketserver.mm b/webrtc/base/maccocoasocketserver.mm deleted file mode 100644 index 123ffdc52..000000000 --- a/webrtc/base/maccocoasocketserver.mm +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#import "webrtc/base/maccocoasocketserver.h" - -#import -#import -#include - -#include "webrtc/base/scoped_autorelease_pool.h" - -// MacCocoaSocketServerHelperRtc serves as a delegate to NSMachPort or a target for -// a timeout. -@interface MacCocoaSocketServerHelperRtc : NSObject { - // This is a weak reference. This works fine since the - // rtc::MacCocoaSocketServer owns this object. - rtc::MacCocoaSocketServer* socketServer_; // Weak. -} -@end - -@implementation MacCocoaSocketServerHelperRtc -- (id)initWithSocketServer:(rtc::MacCocoaSocketServer*)ss { - self = [super init]; - if (self) { - socketServer_ = ss; - } - return self; -} - -- (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 rtc { - -MacCocoaSocketServer::MacCocoaSocketServer() { - helper_ = [[MacCocoaSocketServerHelperRtc alloc] initWithSocketServer:this]; - timer_ = nil; - run_count_ = 0; - - // Initialize the shared NSApplication - [NSApplication sharedApplication]; -} - -MacCocoaSocketServer::~MacCocoaSocketServer() { - [timer_ invalidate]; - [timer_ release]; - [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) { - rtc::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 - // we disable each one's callbacks. - EnableSocketCallbacks(false); - } - - if (kForever != cms) { - // Install a timer that fires wakeup after cms has elapsed. - timer_ = - [NSTimer scheduledTimerWithTimeInterval:cms / 1000.0 - target:helper_ - selector:@selector(timerFired:) - userInfo:nil - repeats:NO]; - [timer_ retain]; - } - - // 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 - // missing ones while they were disabled. - EnableSocketCallbacks(true); - } - - 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() { - if (timer_ != nil) { - [timer_ invalidate]; - [timer_ release]; - timer_ = nil; - } - - // [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 rtc diff --git a/webrtc/base/maccocoasocketserver_unittest.mm b/webrtc/base/maccocoasocketserver_unittest.mm deleted file mode 100644 index 932b4a14f..000000000 --- a/webrtc/base/maccocoasocketserver_unittest.mm +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/maccocoasocketserver.h" - -namespace rtc { - -class WakeThread : public Thread { - public: - WakeThread(SocketServer* ss) : ss_(ss) { - } - virtual ~WakeThread() { - Stop(); - } - void Run() { - ss_->WakeUp(); - } - private: - SocketServer* ss_; -}; - -// Test that MacCocoaSocketServer::Wait works as expected. -TEST(MacCocoaSocketServer, TestWait) { - MacCocoaSocketServer server; - uint32 start = Time(); - server.Wait(1000, true); - EXPECT_GE(TimeSince(start), 1000); -} - -// Test that MacCocoaSocketServer::Wakeup works as expected. -TEST(MacCocoaSocketServer, TestWakeup) { - MacCFSocketServer server; - WakeThread thread(&server); - uint32 start = Time(); - thread.Start(); - server.Wait(10000, true); - EXPECT_LT(TimeSince(start), 10000); -} - -} // namespace rtc diff --git a/webrtc/base/maccocoathreadhelper.h b/webrtc/base/maccocoathreadhelper.h deleted file mode 100644 index 255d081ce..000000000 --- a/webrtc/base/maccocoathreadhelper.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Helper function for using Cocoa with Posix threads. This header should be -// included from C/C++ files that want to use some Cocoa functionality without -// using the .mm extension (mostly for files that are compiled on multiple -// platforms). - -#ifndef WEBRTC_BASE_MACCOCOATHREADHELPER_H__ -#define WEBRTC_BASE_MACCOCOATHREADHELPER_H__ - -namespace rtc { - -// Cocoa must be "put into multithreading mode" before Cocoa functionality can -// be used on POSIX threads. This function does that. -void InitCocoaMultiThreading(); - -} // namespace rtc - -#endif // WEBRTC_BASE_MACCOCOATHREADHELPER_H__ diff --git a/webrtc/base/maccocoathreadhelper.mm b/webrtc/base/maccocoathreadhelper.mm deleted file mode 100644 index 7bf9e9206..000000000 --- a/webrtc/base/maccocoathreadhelper.mm +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -// Helper function for using Cocoa with Posix threading. - -#import -#import - -#import "webrtc/base/maccocoathreadhelper.h" - -namespace rtc { - -// Cocoa must be "put into multithreading mode" before Cocoa functionality can -// be used on POSIX threads. The way to do that is to spawn one thread that may -// immediately exit. -void InitCocoaMultiThreading() { - if ([NSThread isMultiThreaded] == NO) { - // The sole purpose of this autorelease pool is to avoid a console - // message on Leopard that tells us we're autoreleasing the thread - // with no autorelease pool in place; we can't set up an autorelease - // pool before this, because this is executed from an initializer, - // which is run before main. This means we leak an autorelease pool, - // and one thread, and if other objects are set up in initializers after - // this they'll be silently added to this pool and never released. - - // Doing NSAutoreleasePool* hack = [[NSAutoreleasePool alloc] init]; - // causes unused variable error. - NSAutoreleasePool* hack; - hack = [[NSAutoreleasePool alloc] init]; - [NSThread detachNewThreadSelector:@selector(class) - toTarget:[NSObject class] - withObject:nil]; - } - - assert([NSThread isMultiThreaded]); -} - -} // namespace rtc diff --git a/webrtc/base/macconversion.cc b/webrtc/base/macconversion.cc deleted file mode 100644 index 75d11a803..000000000 --- a/webrtc/base/macconversion.cc +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - -#include - -#include "webrtc/base/logging.h" -#include "webrtc/base/macconversion.h" - -bool p_convertHostCFStringRefToCPPString( - const CFStringRef cfstr, std::string& cppstr) { - bool result = false; - - // First this must be non-null, - if (NULL != cfstr) { - // it must actually *be* a CFString, and not something just masquerading - // as one, - if (CFGetTypeID(cfstr) == CFStringGetTypeID()) { - // and we must be able to get the characters out of it. - // (The cfstr owns this buffer; it came from somewhere else, - // so someone else gets to take care of getting rid of the cfstr, - // and then this buffer will go away automatically.) - unsigned length = CFStringGetLength(cfstr); - char* buf = new char[1 + length]; - if (CFStringGetCString(cfstr, buf, 1 + length, kCFStringEncodingASCII)) { - if (strlen(buf) == length) { - cppstr.assign(buf); - result = true; - } - } - delete [] buf; - } - } - - return result; -} - -bool p_convertCFNumberToInt(CFNumberRef cfn, int* i) { - bool converted = false; - - // It must not be null. - if (NULL != cfn) { - // It must actually *be* a CFNumber and not something just masquerading - // as one. - if (CFGetTypeID(cfn) == CFNumberGetTypeID()) { - CFNumberType ntype = CFNumberGetType(cfn); - switch (ntype) { - case kCFNumberSInt8Type: - SInt8 sint8; - converted = CFNumberGetValue(cfn, ntype, static_cast(&sint8)); - if (converted) *i = static_cast(sint8); - break; - case kCFNumberSInt16Type: - SInt16 sint16; - converted = CFNumberGetValue(cfn, ntype, static_cast(&sint16)); - if (converted) *i = static_cast(sint16); - break; - case kCFNumberSInt32Type: - SInt32 sint32; - converted = CFNumberGetValue(cfn, ntype, static_cast(&sint32)); - if (converted) *i = static_cast(sint32); - break; - case kCFNumberSInt64Type: - SInt64 sint64; - converted = CFNumberGetValue(cfn, ntype, static_cast(&sint64)); - if (converted) *i = static_cast(sint64); - break; - case kCFNumberFloat32Type: - Float32 float32; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&float32)); - if (converted) *i = static_cast(float32); - break; - case kCFNumberFloat64Type: - Float64 float64; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&float64)); - if (converted) *i = static_cast(float64); - break; - case kCFNumberCharType: - char charvalue; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&charvalue)); - if (converted) *i = static_cast(charvalue); - break; - case kCFNumberShortType: - short shortvalue; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&shortvalue)); - if (converted) *i = static_cast(shortvalue); - break; - case kCFNumberIntType: - int intvalue; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&intvalue)); - if (converted) *i = static_cast(intvalue); - break; - case kCFNumberLongType: - long longvalue; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&longvalue)); - if (converted) *i = static_cast(longvalue); - break; - case kCFNumberLongLongType: - long long llvalue; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&llvalue)); - if (converted) *i = static_cast(llvalue); - break; - case kCFNumberFloatType: - float floatvalue; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&floatvalue)); - if (converted) *i = static_cast(floatvalue); - break; - case kCFNumberDoubleType: - double doublevalue; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&doublevalue)); - if (converted) *i = static_cast(doublevalue); - break; - case kCFNumberCFIndexType: - CFIndex cfindex; - converted = CFNumberGetValue(cfn, ntype, - static_cast(&cfindex)); - if (converted) *i = static_cast(cfindex); - break; - default: - LOG(LS_ERROR) << "got unknown type."; - break; - } - } - } - - return converted; -} - -bool p_isCFNumberTrue(CFNumberRef cfn) { - // We assume it's false until proven otherwise. - bool result = false; - int asInt; - bool converted = p_convertCFNumberToInt(cfn, &asInt); - - if (converted && (0 != asInt)) { - result = true; - } - - return result; -} - -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) diff --git a/webrtc/base/macconversion.h b/webrtc/base/macconversion.h deleted file mode 100644 index a96ed2298..000000000 --- a/webrtc/base/macconversion.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_MACCONVERSION_H_ -#define WEBRTC_BASE_MACCONVERSION_H_ - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - -#include - -#include - -// given a CFStringRef, attempt to convert it to a C++ string. -// returns true if it succeeds, false otherwise. -// We can safely assume, given our context, that the string is -// going to be in ASCII, because it will either be an IP address, -// or a domain name, which is guaranteed to be ASCII-representable. -bool p_convertHostCFStringRefToCPPString(const CFStringRef cfstr, - std::string& cppstr); - -// Convert the CFNumber to an integer, putting the integer in the location -// given, and returhing true, if the conversion succeeds. -// If given a NULL or a non-CFNumber, returns false. -// This is pretty aggresive about trying to convert to int. -bool p_convertCFNumberToInt(CFNumberRef cfn, int* i); - -// given a CFNumberRef, determine if it represents a true value. -bool p_isCFNumberTrue(CFNumberRef cfn); - -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) - -#endif // WEBRTC_BASE_MACCONVERSION_H_ diff --git a/webrtc/base/macsocketserver.cc b/webrtc/base/macsocketserver.cc deleted file mode 100644 index c7ab6e44d..000000000 --- a/webrtc/base/macsocketserver.cc +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -#include "webrtc/base/macsocketserver.h" - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/macasyncsocket.h" -#include "webrtc/base/macutils.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// MacBaseSocketServer -/////////////////////////////////////////////////////////////////////////////// - -MacBaseSocketServer::MacBaseSocketServer() { -} - -MacBaseSocketServer::~MacBaseSocketServer() { -} - -AsyncSocket* MacBaseSocketServer::CreateAsyncSocket(int type) { - return CreateAsyncSocket(AF_INET, type); -} - -AsyncSocket* MacBaseSocketServer::CreateAsyncSocket(int family, int type) { - if (SOCK_STREAM != type) - return NULL; - - MacAsyncSocket* socket = new MacAsyncSocket(this, family); - if (!socket->valid()) { - delete socket; - return NULL; - } - return socket; -} - -void MacBaseSocketServer::RegisterSocket(MacAsyncSocket* s) { - sockets_.insert(s); -} - -void MacBaseSocketServer::UnregisterSocket(MacAsyncSocket* s) { - VERIFY(1 == sockets_.erase(s)); // found 1 -} - -bool MacBaseSocketServer::SetPosixSignalHandler(int signum, - void (*handler)(int)) { - Dispatcher* dispatcher = signal_dispatcher(); - if (!PhysicalSocketServer::SetPosixSignalHandler(signum, handler)) { - return false; - } - - // Only register the FD once, when the first custom handler is installed. - if (!dispatcher && (dispatcher = signal_dispatcher())) { - CFFileDescriptorContext ctx = { 0 }; - ctx.info = this; - - CFFileDescriptorRef desc = CFFileDescriptorCreate( - kCFAllocatorDefault, - dispatcher->GetDescriptor(), - false, - &MacBaseSocketServer::FileDescriptorCallback, - &ctx); - if (!desc) { - return false; - } - - CFFileDescriptorEnableCallBacks(desc, kCFFileDescriptorReadCallBack); - CFRunLoopSourceRef ref = - CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, desc, 0); - - if (!ref) { - CFRelease(desc); - return false; - } - - CFRunLoopAddSource(CFRunLoopGetCurrent(), ref, kCFRunLoopCommonModes); - CFRelease(desc); - CFRelease(ref); - } - - return true; -} - -// Used to disable socket events from waking our message queue when -// process_io is false. Does not disable signal event handling though. -void MacBaseSocketServer::EnableSocketCallbacks(bool enable) { - for (std::set::iterator it = sockets().begin(); - it != sockets().end(); ++it) { - if (enable) { - (*it)->EnableCallbacks(); - } else { - (*it)->DisableCallbacks(); - } - } -} - -void MacBaseSocketServer::FileDescriptorCallback(CFFileDescriptorRef fd, - CFOptionFlags flags, - void* context) { - MacBaseSocketServer* this_ss = - reinterpret_cast(context); - ASSERT(this_ss); - Dispatcher* signal_dispatcher = this_ss->signal_dispatcher(); - ASSERT(signal_dispatcher); - - signal_dispatcher->OnPreEvent(DE_READ); - signal_dispatcher->OnEvent(DE_READ, 0); - CFFileDescriptorEnableCallBacks(fd, kCFFileDescriptorReadCallBack); -} - - -/////////////////////////////////////////////////////////////////////////////// -// MacCFSocketServer -/////////////////////////////////////////////////////////////////////////////// - -void WakeUpCallback(void* info) { - MacCFSocketServer* server = static_cast(info); - ASSERT(NULL != server); - server->OnWakeUpCallback(); -} - -MacCFSocketServer::MacCFSocketServer() - : run_loop_(CFRunLoopGetCurrent()), - wake_up_(NULL) { - CFRunLoopSourceContext ctx; - memset(&ctx, 0, sizeof(ctx)); - ctx.info = this; - ctx.perform = &WakeUpCallback; - wake_up_ = CFRunLoopSourceCreate(NULL, 0, &ctx); - ASSERT(NULL != wake_up_); - if (wake_up_) { - CFRunLoopAddSource(run_loop_, wake_up_, kCFRunLoopCommonModes); - } -} - -MacCFSocketServer::~MacCFSocketServer() { - if (wake_up_) { - CFRunLoopSourceInvalidate(wake_up_); - CFRelease(wake_up_); - } -} - -bool MacCFSocketServer::Wait(int cms, bool process_io) { - ASSERT(CFRunLoopGetCurrent() == run_loop_); - - if (!process_io && cms == 0) { - // No op. - return true; - } - - if (!process_io) { - // No way to listen to common modes and not get socket events, unless - // we disable each one's callbacks. - EnableSocketCallbacks(false); - } - - SInt32 result; - if (kForever == cms) { - do { - // Would prefer to run in a custom mode that only listens to wake_up, - // but we have qtkit sending work to the main thread which is effectively - // blocked here, causing deadlock. Thus listen to the common modes. - // TODO: If QTKit becomes thread safe, do the above. - result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10000000, false); - } while (result != kCFRunLoopRunFinished && result != kCFRunLoopRunStopped); - } else { - // TODO: In the case of 0ms wait, this will only process one event, so we - // may want to loop until it returns TimedOut. - CFTimeInterval seconds = cms / 1000.0; - result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, false); - } - - if (!process_io) { - // Reenable them. Hopefully this won't cause spurious callbacks or - // missing ones while they were disabled. - EnableSocketCallbacks(true); - } - - if (kCFRunLoopRunFinished == result) { - return false; - } - return true; -} - -void MacCFSocketServer::WakeUp() { - if (wake_up_) { - CFRunLoopSourceSignal(wake_up_); - CFRunLoopWakeUp(run_loop_); - } -} - -void MacCFSocketServer::OnWakeUpCallback() { - ASSERT(run_loop_ == CFRunLoopGetCurrent()); - CFRunLoopStop(run_loop_); -} - -/////////////////////////////////////////////////////////////////////////////// -// MacCarbonSocketServer -/////////////////////////////////////////////////////////////////////////////// -#ifndef CARBON_DEPRECATED - -const UInt32 kEventClassSocketServer = 'MCSS'; -const UInt32 kEventWakeUp = 'WAKE'; -const EventTypeSpec kEventWakeUpSpec[] = { - { kEventClassSocketServer, kEventWakeUp } -}; - -std::string DecodeEvent(EventRef event) { - std::string str; - DecodeFourChar(::GetEventClass(event), &str); - str.push_back(':'); - DecodeFourChar(::GetEventKind(event), &str); - return str; -} - -MacCarbonSocketServer::MacCarbonSocketServer() - : event_queue_(GetCurrentEventQueue()), wake_up_(NULL) { - VERIFY(noErr == CreateEvent(NULL, kEventClassSocketServer, kEventWakeUp, 0, - kEventAttributeUserEvent, &wake_up_)); -} - -MacCarbonSocketServer::~MacCarbonSocketServer() { - if (wake_up_) { - ReleaseEvent(wake_up_); - } -} - -bool MacCarbonSocketServer::Wait(int cms, bool process_io) { - ASSERT(GetCurrentEventQueue() == event_queue_); - - // Listen to all events if we're processing I/O. - // Only listen for our wakeup event if we're not. - UInt32 num_types = 0; - const EventTypeSpec* events = NULL; - if (!process_io) { - num_types = GetEventTypeCount(kEventWakeUpSpec); - events = kEventWakeUpSpec; - } - - EventTargetRef target = GetEventDispatcherTarget(); - EventTimeout timeout = - (kForever == cms) ? kEventDurationForever : cms / 1000.0; - EventTimeout end_time = GetCurrentEventTime() + timeout; - - bool done = false; - while (!done) { - EventRef event; - OSStatus result = ReceiveNextEvent(num_types, events, timeout, true, - &event); - if (noErr == result) { - if (wake_up_ != event) { - LOG_F(LS_VERBOSE) << "Dispatching event: " << DecodeEvent(event); - result = SendEventToEventTarget(event, target); - if ((noErr != result) && (eventNotHandledErr != result)) { - LOG_E(LS_ERROR, OS, result) << "SendEventToEventTarget"; - } - } else { - done = true; - } - ReleaseEvent(event); - } else if (eventLoopTimedOutErr == result) { - ASSERT(cms != kForever); - done = true; - } else if (eventLoopQuitErr == result) { - // Ignore this... we get spurious quits for a variety of reasons. - LOG_E(LS_VERBOSE, OS, result) << "ReceiveNextEvent"; - } else { - // Some strange error occurred. Log it. - LOG_E(LS_WARNING, OS, result) << "ReceiveNextEvent"; - return false; - } - if (kForever != cms) { - timeout = end_time - GetCurrentEventTime(); - } - } - return true; -} - -void MacCarbonSocketServer::WakeUp() { - if (!IsEventInQueue(event_queue_, wake_up_)) { - RetainEvent(wake_up_); - OSStatus result = PostEventToQueue(event_queue_, wake_up_, - kEventPriorityStandard); - if (noErr != result) { - LOG_E(LS_ERROR, OS, result) << "PostEventToQueue"; - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// MacCarbonAppSocketServer -/////////////////////////////////////////////////////////////////////////////// - -MacCarbonAppSocketServer::MacCarbonAppSocketServer() - : event_queue_(GetCurrentEventQueue()) { - // Install event handler - VERIFY(noErr == InstallApplicationEventHandler( - NewEventHandlerUPP(WakeUpEventHandler), 1, kEventWakeUpSpec, this, - &event_handler_)); - - // Install a timer and set it idle to begin with. - VERIFY(noErr == InstallEventLoopTimer(GetMainEventLoop(), - kEventDurationForever, - kEventDurationForever, - NewEventLoopTimerUPP(TimerHandler), - this, - &timer_)); -} - -MacCarbonAppSocketServer::~MacCarbonAppSocketServer() { - RemoveEventLoopTimer(timer_); - RemoveEventHandler(event_handler_); -} - -OSStatus MacCarbonAppSocketServer::WakeUpEventHandler( - EventHandlerCallRef next, EventRef event, void *data) { - QuitApplicationEventLoop(); - return noErr; -} - -void MacCarbonAppSocketServer::TimerHandler( - EventLoopTimerRef timer, void *data) { - QuitApplicationEventLoop(); -} - -bool MacCarbonAppSocketServer::Wait(int cms, bool process_io) { - if (!process_io && cms == 0) { - // No op. - return true; - } - if (kForever != cms) { - // Start a timer. - OSStatus error = - SetEventLoopTimerNextFireTime(timer_, cms / 1000.0); - if (error != noErr) { - LOG(LS_ERROR) << "Failed setting next fire time."; - } - } - if (!process_io) { - // No way to listen to common modes and not get socket events, unless - // we disable each one's callbacks. - EnableSocketCallbacks(false); - } - RunApplicationEventLoop(); - if (!process_io) { - // Reenable them. Hopefully this won't cause spurious callbacks or - // missing ones while they were disabled. - EnableSocketCallbacks(true); - } - return true; -} - -void MacCarbonAppSocketServer::WakeUp() { - // TODO: No-op if there's already a WakeUp in flight. - EventRef wake_up; - VERIFY(noErr == CreateEvent(NULL, kEventClassSocketServer, kEventWakeUp, 0, - kEventAttributeUserEvent, &wake_up)); - OSStatus result = PostEventToQueue(event_queue_, wake_up, - kEventPriorityStandard); - if (noErr != result) { - LOG_E(LS_ERROR, OS, result) << "PostEventToQueue"; - } - ReleaseEvent(wake_up); -} - -#endif -} // namespace rtc diff --git a/webrtc/base/macsocketserver.h b/webrtc/base/macsocketserver.h deleted file mode 100644 index 8eebac6c6..000000000 --- a/webrtc/base/macsocketserver.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef WEBRTC_BASE_MACSOCKETSERVER_H__ -#define WEBRTC_BASE_MACSOCKETSERVER_H__ - -#include -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) // Invalid on IOS -#include -#endif -#include "webrtc/base/physicalsocketserver.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// MacBaseSocketServer -/////////////////////////////////////////////////////////////////////////////// -class MacAsyncSocket; - -class MacBaseSocketServer : public PhysicalSocketServer { - public: - MacBaseSocketServer(); - virtual ~MacBaseSocketServer(); - - // SocketServer Interface - virtual Socket* CreateSocket(int type) { return NULL; } - virtual Socket* CreateSocket(int family, int type) { return NULL; } - - virtual AsyncSocket* CreateAsyncSocket(int type); - virtual AsyncSocket* CreateAsyncSocket(int family, int type); - - virtual bool Wait(int cms, bool process_io) = 0; - virtual void WakeUp() = 0; - - void RegisterSocket(MacAsyncSocket* socket); - void UnregisterSocket(MacAsyncSocket* socket); - - // PhysicalSocketServer Overrides - virtual bool SetPosixSignalHandler(int signum, void (*handler)(int)); - - protected: - void EnableSocketCallbacks(bool enable); - const std::set& sockets() { - return sockets_; - } - - private: - static void FileDescriptorCallback(CFFileDescriptorRef ref, - CFOptionFlags flags, - void* context); - - std::set sockets_; -}; - -// Core Foundation implementation of the socket server. While idle it -// will run the current CF run loop. When the socket server has work -// to do the run loop will be paused. Does not support Carbon or Cocoa -// UI interaction. -class MacCFSocketServer : public MacBaseSocketServer { - public: - MacCFSocketServer(); - virtual ~MacCFSocketServer(); - - // SocketServer Interface - virtual bool Wait(int cms, bool process_io); - virtual void WakeUp(); - void OnWakeUpCallback(); - - private: - CFRunLoopRef run_loop_; - CFRunLoopSourceRef wake_up_; -}; - -#ifndef CARBON_DEPRECATED - -/////////////////////////////////////////////////////////////////////////////// -// MacCarbonSocketServer -/////////////////////////////////////////////////////////////////////////////// - -// Interacts with the Carbon event queue. While idle it will block, -// waiting for events. When the socket server has work to do, it will -// post a 'wake up' event to the queue, causing the thread to exit the -// event loop until the next call to Wait. Other events are dispatched -// to their target. Supports Carbon and Cocoa UI interaction. -class MacCarbonSocketServer : public MacBaseSocketServer { - public: - MacCarbonSocketServer(); - virtual ~MacCarbonSocketServer(); - - // SocketServer Interface - virtual bool Wait(int cms, bool process_io); - virtual void WakeUp(); - - private: - EventQueueRef event_queue_; - EventRef wake_up_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// MacCarbonAppSocketServer -/////////////////////////////////////////////////////////////////////////////// - -// Runs the Carbon application event loop on the current thread while -// idle. When the socket server has work to do, it will post an event -// to the queue, causing the thread to exit the event loop until the -// next call to Wait. Other events are automatically dispatched to -// their target. -class MacCarbonAppSocketServer : public MacBaseSocketServer { - public: - MacCarbonAppSocketServer(); - virtual ~MacCarbonAppSocketServer(); - - // SocketServer Interface - virtual bool Wait(int cms, bool process_io); - virtual void WakeUp(); - - private: - static OSStatus WakeUpEventHandler(EventHandlerCallRef next, EventRef event, - void *data); - static void TimerHandler(EventLoopTimerRef timer, void *data); - - EventQueueRef event_queue_; - EventHandlerRef event_handler_; - EventLoopTimerRef timer_; -}; - -#endif -} // namespace rtc - -#endif // WEBRTC_BASE_MACSOCKETSERVER_H__ diff --git a/webrtc/base/macsocketserver_unittest.cc b/webrtc/base/macsocketserver_unittest.cc deleted file mode 100644 index e98be918c..000000000 --- a/webrtc/base/macsocketserver_unittest.cc +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/socket_unittest.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/macsocketserver.h" - -namespace rtc { - -class WakeThread : public Thread { - public: - WakeThread(SocketServer* ss) : ss_(ss) { - } - virtual ~WakeThread() { - Stop(); - } - void Run() { - ss_->WakeUp(); - } - private: - SocketServer* ss_; -}; - -#ifndef CARBON_DEPRECATED - -// Test that MacCFSocketServer::Wait works as expected. -TEST(MacCFSocketServerTest, TestWait) { - MacCFSocketServer server; - uint32 start = Time(); - server.Wait(1000, true); - EXPECT_GE(TimeSince(start), 1000); -} - -// Test that MacCFSocketServer::Wakeup works as expected. -TEST(MacCFSocketServerTest, TestWakeup) { - MacCFSocketServer server; - WakeThread thread(&server); - uint32 start = Time(); - thread.Start(); - server.Wait(10000, true); - EXPECT_LT(TimeSince(start), 10000); -} - -// Test that MacCarbonSocketServer::Wait works as expected. -TEST(MacCarbonSocketServerTest, TestWait) { - MacCarbonSocketServer server; - uint32 start = Time(); - server.Wait(1000, true); - EXPECT_GE(TimeSince(start), 1000); -} - -// Test that MacCarbonSocketServer::Wakeup works as expected. -TEST(MacCarbonSocketServerTest, TestWakeup) { - MacCarbonSocketServer server; - WakeThread thread(&server); - uint32 start = Time(); - thread.Start(); - server.Wait(10000, true); - EXPECT_LT(TimeSince(start), 10000); -} - -// Test that MacCarbonAppSocketServer::Wait works as expected. -TEST(MacCarbonAppSocketServerTest, TestWait) { - MacCarbonAppSocketServer server; - uint32 start = Time(); - server.Wait(1000, true); - EXPECT_GE(TimeSince(start), 1000); -} - -// Test that MacCarbonAppSocketServer::Wakeup works as expected. -TEST(MacCarbonAppSocketServerTest, TestWakeup) { - MacCarbonAppSocketServer server; - WakeThread thread(&server); - uint32 start = Time(); - thread.Start(); - server.Wait(10000, true); - EXPECT_LT(TimeSince(start), 10000); -} - -#endif - -// Test that MacAsyncSocket passes all the generic Socket tests. -class MacAsyncSocketTest : public SocketTest { - protected: - MacAsyncSocketTest() - : server_(CreateSocketServer()), - scope_(server_.get()) {} - // Override for other implementations of MacBaseSocketServer. - virtual MacBaseSocketServer* CreateSocketServer() { - return new MacCFSocketServer(); - }; - rtc::scoped_ptr server_; - SocketServerScope scope_; -}; - -TEST_F(MacAsyncSocketTest, TestConnectIPv4) { - SocketTest::TestConnectIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestConnectIPv6) { - SocketTest::TestConnectIPv6(); -} - -TEST_F(MacAsyncSocketTest, TestConnectWithDnsLookupIPv4) { - SocketTest::TestConnectWithDnsLookupIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestConnectWithDnsLookupIPv6) { - SocketTest::TestConnectWithDnsLookupIPv6(); -} - -// BUG=https://code.google.com/p/webrtc/issues/detail?id=2272 -TEST_F(MacAsyncSocketTest, DISABLED_TestConnectFailIPv4) { - SocketTest::TestConnectFailIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestConnectFailIPv6) { - SocketTest::TestConnectFailIPv6(); -} - -// Reenable once we have mac async dns -TEST_F(MacAsyncSocketTest, DISABLED_TestConnectWithDnsLookupFailIPv4) { - SocketTest::TestConnectWithDnsLookupFailIPv4(); -} - -TEST_F(MacAsyncSocketTest, DISABLED_TestConnectWithDnsLookupFailIPv6) { - SocketTest::TestConnectWithDnsLookupFailIPv6(); -} - -TEST_F(MacAsyncSocketTest, TestConnectWithClosedSocketIPv4) { - SocketTest::TestConnectWithClosedSocketIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestConnectWithClosedSocketIPv6) { - SocketTest::TestConnectWithClosedSocketIPv6(); -} - -// Flaky at the moment (10% failure rate). Seems the client doesn't get -// signalled in a timely manner... -TEST_F(MacAsyncSocketTest, DISABLED_TestServerCloseDuringConnectIPv4) { - SocketTest::TestServerCloseDuringConnectIPv4(); -} - -TEST_F(MacAsyncSocketTest, DISABLED_TestServerCloseDuringConnectIPv6) { - SocketTest::TestServerCloseDuringConnectIPv6(); -} -// Flaky at the moment (0.5% failure rate). Seems the client doesn't get -// signalled in a timely manner... -TEST_F(MacAsyncSocketTest, TestClientCloseDuringConnectIPv4) { - SocketTest::TestClientCloseDuringConnectIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestClientCloseDuringConnectIPv6) { - SocketTest::TestClientCloseDuringConnectIPv6(); -} - -TEST_F(MacAsyncSocketTest, TestServerCloseIPv4) { - SocketTest::TestServerCloseIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestServerCloseIPv6) { - SocketTest::TestServerCloseIPv6(); -} - -TEST_F(MacAsyncSocketTest, TestCloseInClosedCallbackIPv4) { - SocketTest::TestCloseInClosedCallbackIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestCloseInClosedCallbackIPv6) { - SocketTest::TestCloseInClosedCallbackIPv6(); -} - -TEST_F(MacAsyncSocketTest, TestSocketServerWaitIPv4) { - SocketTest::TestSocketServerWaitIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestSocketServerWaitIPv6) { - SocketTest::TestSocketServerWaitIPv6(); -} - -TEST_F(MacAsyncSocketTest, TestTcpIPv4) { - SocketTest::TestTcpIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestTcpIPv6) { - SocketTest::TestTcpIPv6(); -} - -TEST_F(MacAsyncSocketTest, TestSingleFlowControlCallbackIPv4) { - SocketTest::TestSingleFlowControlCallbackIPv4(); -} - -TEST_F(MacAsyncSocketTest, TestSingleFlowControlCallbackIPv6) { - SocketTest::TestSingleFlowControlCallbackIPv6(); -} - -TEST_F(MacAsyncSocketTest, DISABLED_TestUdpIPv4) { - SocketTest::TestUdpIPv4(); -} - -TEST_F(MacAsyncSocketTest, DISABLED_TestUdpIPv6) { - SocketTest::TestUdpIPv6(); -} - -TEST_F(MacAsyncSocketTest, DISABLED_TestGetSetOptionsIPv4) { - SocketTest::TestGetSetOptionsIPv4(); -} - -TEST_F(MacAsyncSocketTest, DISABLED_TestGetSetOptionsIPv6) { - SocketTest::TestGetSetOptionsIPv6(); -} - -#ifndef CARBON_DEPRECATED -class MacCarbonAppAsyncSocketTest : public MacAsyncSocketTest { - virtual MacBaseSocketServer* CreateSocketServer() { - return new MacCarbonAppSocketServer(); - }; -}; - -TEST_F(MacCarbonAppAsyncSocketTest, TestSocketServerWaitIPv4) { - SocketTest::TestSocketServerWaitIPv4(); -} - -TEST_F(MacCarbonAppAsyncSocketTest, TestSocketServerWaitIPv6) { - SocketTest::TestSocketServerWaitIPv6(); -} -#endif -} // namespace rtc diff --git a/webrtc/base/macutils.cc b/webrtc/base/macutils.cc deleted file mode 100644 index 6e436d4a8..000000000 --- a/webrtc/base/macutils.cc +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/macutils.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/stringutils.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// - -bool ToUtf8(const CFStringRef str16, std::string* str8) { - if ((NULL == str16) || (NULL == str8)) { - return false; - } - size_t maxlen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str16), - kCFStringEncodingUTF8) + 1; - scoped_ptr buffer(new char[maxlen]); - if (!buffer || !CFStringGetCString(str16, buffer.get(), maxlen, - kCFStringEncodingUTF8)) { - return false; - } - str8->assign(buffer.get()); - return true; -} - -bool ToUtf16(const std::string& str8, CFStringRef* str16) { - if (NULL == str16) { - return false; - } - *str16 = CFStringCreateWithBytes(kCFAllocatorDefault, - reinterpret_cast(str8.data()), - str8.length(), kCFStringEncodingUTF8, - false); - return NULL != *str16; -} - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -void DecodeFourChar(UInt32 fc, std::string* out) { - std::stringstream ss; - ss << '\''; - bool printable = true; - for (int i = 3; i >= 0; --i) { - char ch = (fc >> (8 * i)) & 0xFF; - if (isprint(static_cast(ch))) { - ss << ch; - } else { - printable = false; - break; - } - } - if (printable) { - ss << '\''; - } else { - ss.str(""); - ss << "0x" << std::hex << fc; - } - out->append(ss.str()); -} - -static bool GetGestalt(OSType ostype, int* value) { - ASSERT(NULL != value); - SInt32 native_value; - OSStatus result = Gestalt(ostype, &native_value); - if (noErr == result) { - *value = native_value; - return true; - } - std::string str; - DecodeFourChar(ostype, &str); - LOG_E(LS_ERROR, OS, result) << "Gestalt(" << str << ")"; - return false; -} - -bool GetOSVersion(int* major, int* minor, int* bugfix) { - ASSERT(major && minor && bugfix); - if (!GetGestalt(gestaltSystemVersion, major)) { - return false; - } - if (*major < 0x1040) { - *bugfix = *major & 0xF; - *minor = (*major >> 4) & 0xF; - *major = (*major >> 8); - return true; - } - return GetGestalt(gestaltSystemVersionMajor, major) && - GetGestalt(gestaltSystemVersionMinor, minor) && - GetGestalt(gestaltSystemVersionBugFix, bugfix); -} - -MacOSVersionName GetOSVersionName() { - int major = 0, minor = 0, bugfix = 0; - if (!GetOSVersion(&major, &minor, &bugfix)) { - return kMacOSUnknown; - } - if (major > 10) { - return kMacOSNewer; - } - if ((major < 10) || (minor < 3)) { - return kMacOSOlder; - } - switch (minor) { - case 3: - return kMacOSPanther; - case 4: - return kMacOSTiger; - case 5: - return kMacOSLeopard; - case 6: - return kMacOSSnowLeopard; - case 7: - return kMacOSLion; - case 8: - return kMacOSMountainLion; - case 9: - return kMacOSMavericks; - } - return kMacOSNewer; -} - -bool GetQuickTimeVersion(std::string* out) { - int ver; - if (!GetGestalt(gestaltQuickTimeVersion, &ver)) { - return false; - } - - std::stringstream ss; - ss << std::hex << ver; - *out = ss.str(); - return true; -} - -bool RunAppleScript(const std::string& script) { - // TODO(thaloun): Add a .mm file that contains something like this: - // NSString source from script - // NSAppleScript* appleScript = [[NSAppleScript alloc] initWithSource:&source] - // if (appleScript != nil) { - // [appleScript executeAndReturnError:nil] - // [appleScript release] -#ifndef CARBON_DEPRECATED - ComponentInstance component = NULL; - AEDesc script_desc; - AEDesc result_data; - OSStatus err; - OSAID script_id, result_id; - - AECreateDesc(typeNull, NULL, 0, &script_desc); - AECreateDesc(typeNull, NULL, 0, &result_data); - script_id = kOSANullScript; - result_id = kOSANullScript; - - component = OpenDefaultComponent(kOSAComponentType, typeAppleScript); - if (component == NULL) { - LOG(LS_ERROR) << "Failed opening Apple Script component"; - return false; - } - err = AECreateDesc(typeUTF8Text, script.data(), script.size(), &script_desc); - if (err != noErr) { - CloseComponent(component); - LOG(LS_ERROR) << "Failed creating Apple Script description"; - return false; - } - - err = OSACompile(component, &script_desc, kOSAModeCanInteract, &script_id); - if (err != noErr) { - AEDisposeDesc(&script_desc); - if (script_id != kOSANullScript) { - OSADispose(component, script_id); - } - CloseComponent(component); - LOG(LS_ERROR) << "Error compiling Apple Script"; - return false; - } - - err = OSAExecute(component, script_id, kOSANullScript, kOSAModeCanInteract, - &result_id); - - if (err == errOSAScriptError) { - LOG(LS_ERROR) << "Error when executing Apple Script: " << script; - AECreateDesc(typeNull, NULL, 0, &result_data); - OSAScriptError(component, kOSAErrorMessage, typeChar, &result_data); - int len = AEGetDescDataSize(&result_data); - char* data = (char*) malloc(len); - if (data != NULL) { - err = AEGetDescData(&result_data, data, len); - LOG(LS_ERROR) << "Script error: " << data; - } - AEDisposeDesc(&script_desc); - AEDisposeDesc(&result_data); - return false; - } - AEDisposeDesc(&script_desc); - if (script_id != kOSANullScript) { - OSADispose(component, script_id); - } - if (result_id != kOSANullScript) { - OSADispose(component, result_id); - } - CloseComponent(component); - return true; -#else - // TODO(thaloun): Support applescripts with the NSAppleScript API. - return false; -#endif // CARBON_DEPRECATED -} -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/macutils.h b/webrtc/base/macutils.h deleted file mode 100644 index 35c3d1870..000000000 --- a/webrtc/base/macutils.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_MACUTILS_H__ -#define WEBRTC_BASE_MACUTILS_H__ - -#include -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include -#endif -#include - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// - -// Note that some of these functions work for both iOS and Mac OS X. The ones -// that are specific to Mac are #ifdef'ed as such. - -bool ToUtf8(const CFStringRef str16, std::string* str8); -bool ToUtf16(const std::string& str8, CFStringRef* str16); - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -void DecodeFourChar(UInt32 fc, std::string* out); - -enum MacOSVersionName { - kMacOSUnknown, // ??? - kMacOSOlder, // 10.2- - kMacOSPanther, // 10.3 - kMacOSTiger, // 10.4 - kMacOSLeopard, // 10.5 - kMacOSSnowLeopard, // 10.6 - kMacOSLion, // 10.7 - kMacOSMountainLion, // 10.8 - kMacOSMavericks, // 10.9 - kMacOSNewer, // 10.10+ -}; - -bool GetOSVersion(int* major, int* minor, int* bugfix); -MacOSVersionName GetOSVersionName(); -bool GetQuickTimeVersion(std::string* version); - -// Runs the given apple script. Only supports scripts that does not -// require user interaction. -bool RunAppleScript(const std::string& script); -#endif - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_MACUTILS_H__ diff --git a/webrtc/base/macutils_unittest.cc b/webrtc/base/macutils_unittest.cc deleted file mode 100644 index 7150bf355..000000000 --- a/webrtc/base/macutils_unittest.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/macutils.h" - -TEST(MacUtilsTest, GetOsVersionName) { - rtc::MacOSVersionName ver = rtc::GetOSVersionName(); - LOG(LS_INFO) << "GetOsVersionName " << ver; - EXPECT_NE(rtc::kMacOSUnknown, ver); -} - -TEST(MacUtilsTest, GetQuickTimeVersion) { - std::string version; - EXPECT_TRUE(rtc::GetQuickTimeVersion(&version)); - LOG(LS_INFO) << "GetQuickTimeVersion " << version; -} - -TEST(MacUtilsTest, RunAppleScriptCompileError) { - std::string script("set value to to 5"); - EXPECT_FALSE(rtc::RunAppleScript(script)); -} - -TEST(MacUtilsTest, RunAppleScriptRuntimeError) { - std::string script("set value to 5 / 0"); - EXPECT_FALSE(rtc::RunAppleScript(script)); -} - -#ifdef CARBON_DEPRECATED -TEST(MacUtilsTest, DISABLED_RunAppleScriptSuccess) { -#else -TEST(MacUtilsTest, RunAppleScriptSuccess) { -#endif - std::string script("set value to 5"); - EXPECT_TRUE(rtc::RunAppleScript(script)); -} diff --git a/webrtc/base/macwindowpicker.cc b/webrtc/base/macwindowpicker.cc deleted file mode 100644 index bb97d20f1..000000000 --- a/webrtc/base/macwindowpicker.cc +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "webrtc/base/macwindowpicker.h" - -#include -#include -#include - -#include "webrtc/base/logging.h" -#include "webrtc/base/macutils.h" - -namespace rtc { - -static const char* kCoreGraphicsName = - "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" - "CoreGraphics.framework/CoreGraphics"; - -static const char* kWindowListCopyWindowInfo = "CGWindowListCopyWindowInfo"; -static const char* kWindowListCreateDescriptionFromArray = - "CGWindowListCreateDescriptionFromArray"; - -// Function pointer for holding the CGWindowListCopyWindowInfo function. -typedef CFArrayRef(*CGWindowListCopyWindowInfoProc)(CGWindowListOption, - CGWindowID); - -// Function pointer for holding the CGWindowListCreateDescriptionFromArray -// function. -typedef CFArrayRef(*CGWindowListCreateDescriptionFromArrayProc)(CFArrayRef); - -MacWindowPicker::MacWindowPicker() : lib_handle_(NULL), get_window_list_(NULL), - get_window_list_desc_(NULL) { -} - -MacWindowPicker::~MacWindowPicker() { - if (lib_handle_ != NULL) { - dlclose(lib_handle_); - } -} - -bool MacWindowPicker::Init() { - // TODO: If this class grows to use more dynamically functions - // from the CoreGraphics framework, consider using - // webrtc/base/latebindingsymboltable.h. - lib_handle_ = dlopen(kCoreGraphicsName, RTLD_NOW); - if (lib_handle_ == NULL) { - LOG(LS_ERROR) << "Could not load CoreGraphics"; - return false; - } - - get_window_list_ = dlsym(lib_handle_, kWindowListCopyWindowInfo); - get_window_list_desc_ = - dlsym(lib_handle_, kWindowListCreateDescriptionFromArray); - if (get_window_list_ == NULL || get_window_list_desc_ == NULL) { - // The CGWindowListCopyWindowInfo and the - // CGWindowListCreateDescriptionFromArray functions was introduced - // in Leopard(10.5) so this is a normal failure on Tiger. - LOG(LS_INFO) << "Failed to load Core Graphics symbols"; - dlclose(lib_handle_); - lib_handle_ = NULL; - return false; - } - - return true; -} - -bool MacWindowPicker::IsVisible(const WindowId& id) { - // Init if we're not already inited. - if (get_window_list_desc_ == NULL && !Init()) { - return false; - } - CGWindowID ids[1]; - ids[0] = id.id(); - CFArrayRef window_id_array = - CFArrayCreate(NULL, reinterpret_cast(&ids), 1, NULL); - - CFArrayRef window_array = - reinterpret_cast( - get_window_list_desc_)(window_id_array); - if (window_array == NULL || 0 == CFArrayGetCount(window_array)) { - // Could not find the window. It might have been closed. - LOG(LS_INFO) << "Window not found"; - CFRelease(window_id_array); - return false; - } - - CFDictionaryRef window = reinterpret_cast( - CFArrayGetValueAtIndex(window_array, 0)); - CFBooleanRef is_visible = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowIsOnscreen)); - - // Check that the window is visible. If not we might crash. - bool visible = false; - if (is_visible != NULL) { - visible = CFBooleanGetValue(is_visible); - } - CFRelease(window_id_array); - CFRelease(window_array); - return visible; -} - -bool MacWindowPicker::MoveToFront(const WindowId& id) { - // Init if we're not already initialized. - if (get_window_list_desc_ == NULL && !Init()) { - return false; - } - CGWindowID ids[1]; - ids[0] = id.id(); - CFArrayRef window_id_array = - CFArrayCreate(NULL, reinterpret_cast(&ids), 1, NULL); - - CFArrayRef window_array = - reinterpret_cast( - get_window_list_desc_)(window_id_array); - if (window_array == NULL || 0 == CFArrayGetCount(window_array)) { - // Could not find the window. It might have been closed. - LOG(LS_INFO) << "Window not found"; - CFRelease(window_id_array); - return false; - } - - CFDictionaryRef window = reinterpret_cast( - CFArrayGetValueAtIndex(window_array, 0)); - CFStringRef window_name_ref = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowName)); - CFNumberRef application_pid = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowOwnerPID)); - - int pid_val; - CFNumberGetValue(application_pid, kCFNumberIntType, &pid_val); - std::string window_name; - ToUtf8(window_name_ref, &window_name); - - // Build an applescript that sets the selected window to front - // within the application. Then set the application to front. - bool result = true; - std::stringstream ss; - ss << "tell application \"System Events\"\n" - << "set proc to the first item of (every process whose unix id is " - << pid_val - << ")\n" - << "tell proc to perform action \"AXRaise\" of window \"" - << window_name - << "\"\n" - << "set the frontmost of proc to true\n" - << "end tell"; - if (!RunAppleScript(ss.str())) { - // This might happen to for example X applications where the X - // server spawns of processes with their own PID but the X server - // is still registered as owner to the application windows. As a - // workaround, we put the X server process to front, meaning that - // all X applications will show up. The drawback with this - // workaround is that the application that we really wanted to set - // to front might be behind another X application. - ProcessSerialNumber psn; - pid_t pid = pid_val; - int res = GetProcessForPID(pid, &psn); - if (res != 0) { - LOG(LS_ERROR) << "Failed getting process for pid"; - result = false; - } - res = SetFrontProcess(&psn); - if (res != 0) { - LOG(LS_ERROR) << "Failed setting process to front"; - result = false; - } - } - CFRelease(window_id_array); - CFRelease(window_array); - return result; -} - -bool MacWindowPicker::GetDesktopList(DesktopDescriptionList* descriptions) { - const uint32_t kMaxDisplays = 128; - CGDirectDisplayID active_displays[kMaxDisplays]; - uint32_t display_count = 0; - - CGError err = CGGetActiveDisplayList(kMaxDisplays, - active_displays, - &display_count); - if (err != kCGErrorSuccess) { - LOG_E(LS_ERROR, OS, err) << "Failed to enumerate the active displays."; - return false; - } - for (uint32_t i = 0; i < display_count; ++i) { - DesktopId id(active_displays[i], static_cast(i)); - // TODO: Figure out an appropriate desktop title. - DesktopDescription desc(id, ""); - desc.set_primary(CGDisplayIsMain(id.id())); - descriptions->push_back(desc); - } - return display_count > 0; -} - -bool MacWindowPicker::GetDesktopDimensions(const DesktopId& id, - int* width, - int* height) { - *width = CGDisplayPixelsWide(id.id()); - *height = CGDisplayPixelsHigh(id.id()); - return true; -} - -bool MacWindowPicker::GetWindowList(WindowDescriptionList* descriptions) { - // Init if we're not already inited. - if (get_window_list_ == NULL && !Init()) { - return false; - } - - // Only get onscreen, non-desktop windows. - CFArrayRef window_array = - reinterpret_cast(get_window_list_)( - kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, - kCGNullWindowID); - if (window_array == NULL) { - return false; - } - - // Check windows to make sure they have an id, title, and use window layer 0. - CFIndex i; - CFIndex count = CFArrayGetCount(window_array); - for (i = 0; i < count; ++i) { - CFDictionaryRef window = reinterpret_cast( - CFArrayGetValueAtIndex(window_array, i)); - CFStringRef window_title = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowName)); - CFNumberRef window_id = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowNumber)); - CFNumberRef window_layer = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowLayer)); - if (window_title != NULL && window_id != NULL && window_layer != NULL) { - std::string title_str; - int id_val, layer_val; - ToUtf8(window_title, &title_str); - CFNumberGetValue(window_id, kCFNumberIntType, &id_val); - CFNumberGetValue(window_layer, kCFNumberIntType, &layer_val); - - // Discard windows without a title. - if (layer_val == 0 && title_str.length() > 0) { - WindowId id(static_cast(id_val)); - WindowDescription desc(id, title_str); - descriptions->push_back(desc); - } - } - } - - CFRelease(window_array); - return true; -} - -} // namespace rtc diff --git a/webrtc/base/macwindowpicker.h b/webrtc/base/macwindowpicker.h deleted file mode 100644 index 9a44747d2..000000000 --- a/webrtc/base/macwindowpicker.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef WEBRTC_BASE_MACWINDOWPICKER_H_ -#define WEBRTC_BASE_MACWINDOWPICKER_H_ - -#include "webrtc/base/windowpicker.h" - -namespace rtc { - -class MacWindowPicker : public WindowPicker { - public: - MacWindowPicker(); - ~MacWindowPicker(); - virtual bool Init(); - virtual bool IsVisible(const WindowId& id); - virtual bool MoveToFront(const WindowId& id); - virtual bool GetWindowList(WindowDescriptionList* descriptions); - virtual bool GetDesktopList(DesktopDescriptionList* descriptions); - virtual bool GetDesktopDimensions(const DesktopId& id, int* width, - int* height); - - private: - void* lib_handle_; - void* get_window_list_; - void* get_window_list_desc_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_MACWINDOWPICKER_H_ diff --git a/webrtc/base/macwindowpicker_unittest.cc b/webrtc/base/macwindowpicker_unittest.cc deleted file mode 100644 index 7140f0231..000000000 --- a/webrtc/base/macwindowpicker_unittest.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/macutils.h" -#include "webrtc/base/macwindowpicker.h" -#include "webrtc/base/windowpicker.h" - -#if !defined(WEBRTC_MAC) || defined(WEBRTC_IOS) -#error Only for WEBRTC_MAC && !WEBRTC_IOS -#endif - -namespace rtc { - -bool IsLeopardOrLater() { - return GetOSVersionName() >= kMacOSLeopard; -} - -// Test that this works on new versions and fails acceptably on old versions. -TEST(MacWindowPickerTest, TestGetWindowList) { - MacWindowPicker picker, picker2; - WindowDescriptionList descriptions; - if (IsLeopardOrLater()) { - EXPECT_TRUE(picker.Init()); - EXPECT_TRUE(picker.GetWindowList(&descriptions)); - EXPECT_TRUE(picker2.GetWindowList(&descriptions)); // Init is optional - } else { - EXPECT_FALSE(picker.Init()); - EXPECT_FALSE(picker.GetWindowList(&descriptions)); - EXPECT_FALSE(picker2.GetWindowList(&descriptions)); - } -} - -// TODO: Add verification of the actual parsing, ie, add -// functionality to inject a fake get_window_array function which -// provide a pre-constructed list of windows. - -} // namespace rtc diff --git a/webrtc/base/mathutils.h b/webrtc/base/mathutils.h deleted file mode 100644 index e2b21261d..000000000 --- a/webrtc/base/mathutils.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2005 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_MATHUTILS_H_ -#define WEBRTC_BASE_MATHUTILS_H_ - -#include - -#ifndef M_PI -#define M_PI 3.14159265359f -#endif - -#endif // WEBRTC_BASE_MATHUTILS_H_ diff --git a/webrtc/base/md5.cc b/webrtc/base/md5.cc deleted file mode 100644 index a4f28d730..000000000 --- a/webrtc/base/md5.cc +++ /dev/null @@ -1,218 +0,0 @@ -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ - -// Changes from original C code: -// Ported to C++, type casting, Google code style. - -#include "webrtc/base/md5.h" - -// TODO: Avoid memcmpy - hash directly from memory. -#include // for memcpy(). - -#include "webrtc/base/byteorder.h" // for ARCH_CPU_LITTLE_ENDIAN. - -#ifdef ARCH_CPU_LITTLE_ENDIAN -#define ByteReverse(buf, len) // Nothing. -#else // ARCH_CPU_BIG_ENDIAN -static void ByteReverse(uint32* buf, int len) { - for (int i = 0; i < len; ++i) { - buf[i] = rtc::GetLE32(&buf[i]); - } -} -#endif - -// Start MD5 accumulation. Set bit count to 0 and buffer to mysterious -// initialization constants. -void MD5Init(MD5Context* ctx) { - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -// Update context to reflect the concatenation of another buffer full of bytes. -void MD5Update(MD5Context* ctx, const uint8* buf, size_t len) { - // Update bitcount. - uint32 t = ctx->bits[0]; - if ((ctx->bits[0] = t + (static_cast(len) << 3)) < t) { - ctx->bits[1]++; // Carry from low to high. - } - ctx->bits[1] += static_cast(len >> 29); - t = (t >> 3) & 0x3f; // Bytes already in shsInfo->data. - - // Handle any leading odd-sized chunks. - if (t) { - uint8* p = reinterpret_cast(ctx->in) + t; - - t = 64-t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - ByteReverse(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - buf += t; - len -= t; - } - - // Process data in 64-byte chunks. - while (len >= 64) { - memcpy(ctx->in, buf, 64); - ByteReverse(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - buf += 64; - len -= 64; - } - - // Handle any remaining bytes of data. - memcpy(ctx->in, buf, len); -} - -// Final wrapup - pad to 64-byte boundary with the bit pattern. -// 1 0* (64-bit count of bits processed, MSB-first) -void MD5Final(MD5Context* ctx, uint8 digest[16]) { - // Compute number of bytes mod 64. - uint32 count = (ctx->bits[0] >> 3) & 0x3F; - - // Set the first char of padding to 0x80. This is safe since there is - // always at least one byte free. - uint8* p = reinterpret_cast(ctx->in) + count; - *p++ = 0x80; - - // Bytes of padding needed to make 64 bytes. - count = 64 - 1 - count; - - // Pad out to 56 mod 64. - if (count < 8) { - // Two lots of padding: Pad the first block to 64 bytes. - memset(p, 0, count); - ByteReverse(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - - // Now fill the next block with 56 bytes. - memset(ctx->in, 0, 56); - } else { - // Pad block to 56 bytes. - memset(p, 0, count - 8); - } - ByteReverse(ctx->in, 14); - - // Append length in bits and transform. - ctx->in[14] = ctx->bits[0]; - ctx->in[15] = ctx->bits[1]; - - MD5Transform(ctx->buf, ctx->in); - ByteReverse(ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(*ctx)); // In case it's sensitive. -} - -// The four core functions - F1 is optimized somewhat. -// #define F1(x, y, z) (x & y | ~x & z) -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -// This is the central step in the MD5 algorithm. -#define MD5STEP(f, w, x, y, z, data, s) \ - (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x) - -// The core of the MD5 algorithm, this alters an existing MD5 hash to -// reflect the addition of 16 longwords of new data. MD5Update blocks -// the data and converts bytes into longwords for this routine. -void MD5Transform(uint32 buf[4], const uint32 in[16]) { - uint32 a = buf[0]; - uint32 b = buf[1]; - uint32 c = buf[2]; - uint32 d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[ 2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[ 7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[ 5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[ 3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[ 1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[ 8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[ 6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[ 4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[ 2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[ 9] + 0xeb86d391, 21); - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} diff --git a/webrtc/base/md5.h b/webrtc/base/md5.h deleted file mode 100644 index fc563b764..000000000 --- a/webrtc/base/md5.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This is the header file for the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - * - */ - -// Changes(fbarchard): Ported to C++ and Google style guide. -// Made context first parameter in MD5Final for consistency with Sha1. - -#ifndef WEBRTC_BASE_MD5_H_ -#define WEBRTC_BASE_MD5_H_ - -#include "webrtc/base/basictypes.h" - -// Canonical name for a MD5 context structure, used in many crypto libs. -typedef struct MD5Context MD5_CTX; - -struct MD5Context { - uint32 buf[4]; - uint32 bits[2]; - uint32 in[16]; -}; - -void MD5Init(MD5Context* context); -void MD5Update(MD5Context* context, const uint8* data, size_t len); -void MD5Final(MD5Context* context, uint8 digest[16]); -void MD5Transform(uint32 buf[4], const uint32 in[16]); - -#endif // WEBRTC_BASE_MD5_H_ diff --git a/webrtc/base/md5digest.h b/webrtc/base/md5digest.h deleted file mode 100644 index 5e8580222..000000000 --- a/webrtc/base/md5digest.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_MD5DIGEST_H_ -#define WEBRTC_BASE_MD5DIGEST_H_ - -#include "webrtc/base/md5.h" -#include "webrtc/base/messagedigest.h" - -namespace rtc { - -// A simple wrapper for our MD5 implementation. -class Md5Digest : public MessageDigest { - public: - enum { kSize = 16 }; - Md5Digest() { - MD5Init(&ctx_); - } - virtual size_t Size() const { - return kSize; - } - virtual void Update(const void* buf, size_t len) { - MD5Update(&ctx_, static_cast(buf), len); - } - virtual size_t Finish(void* buf, size_t len) { - if (len < kSize) { - return 0; - } - MD5Final(&ctx_, static_cast(buf)); - MD5Init(&ctx_); // Reset for next use. - return kSize; - } - private: - MD5_CTX ctx_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_MD5DIGEST_H_ diff --git a/webrtc/base/md5digest_unittest.cc b/webrtc/base/md5digest_unittest.cc deleted file mode 100644 index 67c62db62..000000000 --- a/webrtc/base/md5digest_unittest.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/md5digest.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/stringencode.h" - -namespace rtc { - -std::string Md5(const std::string& input) { - Md5Digest md5; - return ComputeDigest(&md5, input); -} - -TEST(Md5DigestTest, TestSize) { - Md5Digest md5; - EXPECT_EQ(16, static_cast(Md5Digest::kSize)); - EXPECT_EQ(16U, md5.Size()); -} - -TEST(Md5DigestTest, TestBasic) { - // These are the standard MD5 test vectors from RFC 1321. - EXPECT_EQ("d41d8cd98f00b204e9800998ecf8427e", Md5("")); - EXPECT_EQ("0cc175b9c0f1b6a831c399e269772661", Md5("a")); - EXPECT_EQ("900150983cd24fb0d6963f7d28e17f72", Md5("abc")); - EXPECT_EQ("f96b697d7cb7938d525a2f31aaf161d0", Md5("message digest")); - EXPECT_EQ("c3fcd3d76192e4007dfb496cca67e13b", - Md5("abcdefghijklmnopqrstuvwxyz")); -} - -TEST(Md5DigestTest, TestMultipleUpdates) { - Md5Digest md5; - std::string input = "abcdefghijklmnopqrstuvwxyz"; - char output[Md5Digest::kSize]; - for (size_t i = 0; i < input.size(); ++i) { - md5.Update(&input[i], 1); - } - EXPECT_EQ(md5.Size(), md5.Finish(output, sizeof(output))); - EXPECT_EQ("c3fcd3d76192e4007dfb496cca67e13b", - hex_encode(output, sizeof(output))); -} - -TEST(Md5DigestTest, TestReuse) { - Md5Digest md5; - std::string input = "message digest"; - EXPECT_EQ("f96b697d7cb7938d525a2f31aaf161d0", ComputeDigest(&md5, input)); - input = "abcdefghijklmnopqrstuvwxyz"; - EXPECT_EQ("c3fcd3d76192e4007dfb496cca67e13b", ComputeDigest(&md5, input)); -} - -TEST(Md5DigestTest, TestBufferTooSmall) { - Md5Digest md5; - std::string input = "abcdefghijklmnopqrstuvwxyz"; - char output[Md5Digest::kSize - 1]; - md5.Update(input.c_str(), input.size()); - EXPECT_EQ(0U, md5.Finish(output, sizeof(output))); -} - -TEST(Md5DigestTest, TestBufferConst) { - Md5Digest md5; - const int kLongSize = 1000000; - std::string input(kLongSize, '\0'); - for (int i = 0; i < kLongSize; ++i) { - input[i] = static_cast(i); - } - md5.Update(input.c_str(), input.size()); - for (int i = 0; i < kLongSize; ++i) { - EXPECT_EQ(static_cast(i), input[i]); - } -} - -} // namespace rtc diff --git a/webrtc/base/messagedigest.cc b/webrtc/base/messagedigest.cc deleted file mode 100644 index dc3e1006a..000000000 --- a/webrtc/base/messagedigest.cc +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/messagedigest.h" - -#include - -#include "webrtc/base/sslconfig.h" -#if SSL_USE_OPENSSL -#include "webrtc/base/openssldigest.h" -#else -#include "webrtc/base/md5digest.h" -#include "webrtc/base/sha1digest.h" -#endif -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/stringencode.h" - -namespace rtc { - -// From RFC 4572. -const char DIGEST_MD5[] = "md5"; -const char DIGEST_SHA_1[] = "sha-1"; -const char DIGEST_SHA_224[] = "sha-224"; -const char DIGEST_SHA_256[] = "sha-256"; -const char DIGEST_SHA_384[] = "sha-384"; -const char DIGEST_SHA_512[] = "sha-512"; - -static const size_t kBlockSize = 64; // valid for SHA-256 and down - -MessageDigest* MessageDigestFactory::Create(const std::string& alg) { -#if SSL_USE_OPENSSL - MessageDigest* digest = new OpenSSLDigest(alg); - if (digest->Size() == 0) { // invalid algorithm - delete digest; - digest = NULL; - } - return digest; -#else - MessageDigest* digest = NULL; - if (alg == DIGEST_MD5) { - digest = new Md5Digest(); - } else if (alg == DIGEST_SHA_1) { - digest = new Sha1Digest(); - } - return digest; -#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); - return digest->Finish(output, out_len); -} - -size_t ComputeDigest(const std::string& alg, const void* input, size_t in_len, - void* output, size_t out_len) { - scoped_ptr digest(MessageDigestFactory::Create(alg)); - return (digest) ? - ComputeDigest(digest.get(), input, in_len, output, out_len) : - 0; -} - -std::string ComputeDigest(MessageDigest* digest, const std::string& input) { - scoped_ptr output(new char[digest->Size()]); - ComputeDigest(digest, input.data(), input.size(), - output.get(), digest->Size()); - return hex_encode(output.get(), digest->Size()); -} - -bool ComputeDigest(const std::string& alg, const std::string& input, - std::string* output) { - scoped_ptr digest(MessageDigestFactory::Create(alg)); - if (!digest) { - return false; - } - *output = ComputeDigest(digest.get(), input); - return true; -} - -std::string ComputeDigest(const std::string& alg, const std::string& input) { - std::string output; - ComputeDigest(alg, input, &output); - return output; -} - -// Compute a RFC 2104 HMAC: H(K XOR opad, H(K XOR ipad, text)) -size_t ComputeHmac(MessageDigest* digest, - const void* key, size_t key_len, - const void* input, size_t in_len, - void* output, size_t out_len) { - // We only handle algorithms with a 64-byte blocksize. - // TODO: Add BlockSize() method to MessageDigest. - size_t block_len = kBlockSize; - if (digest->Size() > 32) { - return 0; - } - // Copy the key to a block-sized buffer to simplify padding. - // If the key is longer than a block, hash it and use the result instead. - scoped_ptr new_key(new uint8[block_len]); - if (key_len > block_len) { - ComputeDigest(digest, key, key_len, new_key.get(), block_len); - memset(new_key.get() + digest->Size(), 0, block_len - digest->Size()); - } else { - memcpy(new_key.get(), key, key_len); - memset(new_key.get() + key_len, 0, block_len - key_len); - } - // Set up the padding from the key, salting appropriately for each padding. - scoped_ptr o_pad(new uint8[block_len]), i_pad(new uint8[block_len]); - for (size_t i = 0; i < block_len; ++i) { - o_pad[i] = 0x5c ^ new_key[i]; - i_pad[i] = 0x36 ^ new_key[i]; - } - // Inner hash; hash the inner padding, and then the input buffer. - scoped_ptr inner(new uint8[digest->Size()]); - digest->Update(i_pad.get(), block_len); - digest->Update(input, in_len); - digest->Finish(inner.get(), digest->Size()); - // Outer hash; hash the outer padding, and then the result of the inner hash. - digest->Update(o_pad.get(), block_len); - digest->Update(inner.get(), digest->Size()); - return digest->Finish(output, out_len); -} - -size_t ComputeHmac(const std::string& alg, const void* key, size_t key_len, - const void* input, size_t in_len, - void* output, size_t out_len) { - scoped_ptr digest(MessageDigestFactory::Create(alg)); - if (!digest) { - return 0; - } - return ComputeHmac(digest.get(), key, key_len, - input, in_len, output, out_len); -} - -std::string ComputeHmac(MessageDigest* digest, const std::string& key, - const std::string& input) { - scoped_ptr output(new char[digest->Size()]); - ComputeHmac(digest, key.data(), key.size(), - input.data(), input.size(), output.get(), digest->Size()); - return hex_encode(output.get(), digest->Size()); -} - -bool ComputeHmac(const std::string& alg, const std::string& key, - const std::string& input, std::string* output) { - scoped_ptr digest(MessageDigestFactory::Create(alg)); - if (!digest) { - return false; - } - *output = ComputeHmac(digest.get(), key, input); - return true; -} - -std::string ComputeHmac(const std::string& alg, const std::string& key, - const std::string& input) { - std::string output; - ComputeHmac(alg, key, input, &output); - return output; -} - -} // namespace rtc diff --git a/webrtc/base/messagedigest.h b/webrtc/base/messagedigest.h deleted file mode 100644 index 5cfcb4772..000000000 --- a/webrtc/base/messagedigest.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_MESSAGEDIGEST_H_ -#define WEBRTC_BASE_MESSAGEDIGEST_H_ - -#include - -namespace rtc { - -// Definitions for the digest algorithms. -extern const char DIGEST_MD5[]; -extern const char DIGEST_SHA_1[]; -extern const char DIGEST_SHA_224[]; -extern const char DIGEST_SHA_256[]; -extern const char DIGEST_SHA_384[]; -extern const char DIGEST_SHA_512[]; - -// A general class for computing hashes. -class MessageDigest { - public: - enum { kMaxSize = 64 }; // Maximum known size (SHA-512) - virtual ~MessageDigest() {} - // Returns the digest output size (e.g. 16 bytes for MD5). - virtual size_t Size() const = 0; - // Updates the digest with |len| bytes from |buf|. - virtual void Update(const void* buf, size_t len) = 0; - // Outputs the digest value to |buf| with length |len|. - // Returns the number of bytes written, i.e., Size(). - virtual size_t Finish(void* buf, size_t len) = 0; -}; - -// A factory class for creating digest objects. -class MessageDigestFactory { - public: - 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 -// implementation, and outputs the hash to the buffer |output|, which is -// |out_len| bytes long. Returns the number of bytes written to |output| if -// successful, or 0 if |out_len| was too small. -size_t ComputeDigest(MessageDigest* digest, const void* input, size_t in_len, - void* output, size_t out_len); -// Like the previous function, but creates a digest implementation based on -// the desired digest name |alg|, e.g. DIGEST_SHA_1. Returns 0 if there is no -// digest with the given name. -size_t ComputeDigest(const std::string& alg, const void* input, size_t in_len, - void* output, size_t out_len); -// Computes the hash of |input| using the |digest| hash implementation, and -// returns it as a hex-encoded string. -std::string ComputeDigest(MessageDigest* digest, const std::string& input); -// Like the previous function, but creates a digest implementation based on -// the desired digest name |alg|, e.g. DIGEST_SHA_1. Returns empty string if -// there is no digest with the given name. -std::string ComputeDigest(const std::string& alg, const std::string& input); -// Like the previous function, but returns an explicit result code. -bool ComputeDigest(const std::string& alg, const std::string& input, - std::string* output); - -// Shorthand way to compute a hex-encoded hash using MD5. -inline std::string MD5(const std::string& input) { - return ComputeDigest(DIGEST_MD5, input); -} - -// Functions to compute RFC 2104 HMACs. - -// Computes the HMAC of |in_len| bytes of |input|, using the |digest| hash -// implementation and |key_len| bytes of |key| to key the HMAC, and outputs -// the HMAC to the buffer |output|, which is |out_len| bytes long. Returns the -// number of bytes written to |output| if successful, or 0 if |out_len| was too -// small. -size_t ComputeHmac(MessageDigest* digest, const void* key, size_t key_len, - const void* input, size_t in_len, - void* output, size_t out_len); -// Like the previous function, but creates a digest implementation based on -// the desired digest name |alg|, e.g. DIGEST_SHA_1. Returns 0 if there is no -// digest with the given name. -size_t ComputeHmac(const std::string& alg, const void* key, size_t key_len, - const void* input, size_t in_len, - void* output, size_t out_len); -// Computes the HMAC of |input| using the |digest| hash implementation and |key| -// to key the HMAC, and returns it as a hex-encoded string. -std::string ComputeHmac(MessageDigest* digest, const std::string& key, - const std::string& input); -// Like the previous function, but creates a digest implementation based on -// the desired digest name |alg|, e.g. DIGEST_SHA_1. Returns empty string if -// there is no digest with the given name. -std::string ComputeHmac(const std::string& alg, const std::string& key, - const std::string& input); -// Like the previous function, but returns an explicit result code. -bool ComputeHmac(const std::string& alg, const std::string& key, - const std::string& input, std::string* output); - -} // namespace rtc - -#endif // WEBRTC_BASE_MESSAGEDIGEST_H_ diff --git a/webrtc/base/messagedigest_unittest.cc b/webrtc/base/messagedigest_unittest.cc deleted file mode 100644 index 86cf688ce..000000000 --- a/webrtc/base/messagedigest_unittest.cc +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/messagedigest.h" -#include "webrtc/base/stringencode.h" - -namespace rtc { - -// Test vectors from RFC 1321. -TEST(MessageDigestTest, TestMd5Digest) { - // Test the string versions of the APIs. - EXPECT_EQ("d41d8cd98f00b204e9800998ecf8427e", - ComputeDigest(DIGEST_MD5, "")); - EXPECT_EQ("900150983cd24fb0d6963f7d28e17f72", - ComputeDigest(DIGEST_MD5, "abc")); - EXPECT_EQ("c3fcd3d76192e4007dfb496cca67e13b", - ComputeDigest(DIGEST_MD5, "abcdefghijklmnopqrstuvwxyz")); - - // Test the raw buffer versions of the APIs; also check output buffer size. - char output[16]; - EXPECT_EQ(sizeof(output), - ComputeDigest(DIGEST_MD5, "abc", 3, output, sizeof(output))); - EXPECT_EQ("900150983cd24fb0d6963f7d28e17f72", - hex_encode(output, sizeof(output))); - EXPECT_EQ(0U, - ComputeDigest(DIGEST_MD5, "abc", 3, output, sizeof(output) - 1)); -} - -// Test vectors from RFC 3174. -TEST(MessageDigestTest, TestSha1Digest) { - // Test the string versions of the APIs. - EXPECT_EQ("da39a3ee5e6b4b0d3255bfef95601890afd80709", - ComputeDigest(DIGEST_SHA_1, "")); - EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", - ComputeDigest(DIGEST_SHA_1, "abc")); - EXPECT_EQ("84983e441c3bd26ebaae4aa1f95129e5e54670f1", - ComputeDigest(DIGEST_SHA_1, - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")); - - // Test the raw buffer versions of the APIs; also check output buffer size. - char output[20]; - EXPECT_EQ(sizeof(output), - ComputeDigest(DIGEST_SHA_1, "abc", 3, output, sizeof(output))); - EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", - hex_encode(output, sizeof(output))); - EXPECT_EQ(0U, - ComputeDigest(DIGEST_SHA_1, "abc", 3, output, sizeof(output) - 1)); -} - -// Test that we fail properly if a bad digest algorithm is specified. -TEST(MessageDigestTest, TestBadDigest) { - std::string output; - EXPECT_FALSE(ComputeDigest("sha-9000", "abc", &output)); - EXPECT_EQ("", ComputeDigest("sha-9000", "abc")); -} - -// Test vectors from RFC 2202. -TEST(MessageDigestTest, TestMd5Hmac) { - // Test the string versions of the APIs. - EXPECT_EQ("9294727a3638bb1c13f48ef8158bfc9d", - ComputeHmac(DIGEST_MD5, std::string(16, '\x0b'), "Hi There")); - EXPECT_EQ("750c783e6ab0b503eaa86e310a5db738", - ComputeHmac(DIGEST_MD5, "Jefe", "what do ya want for nothing?")); - EXPECT_EQ("56be34521d144c88dbb8c733f0e8b3f6", - ComputeHmac(DIGEST_MD5, std::string(16, '\xaa'), - std::string(50, '\xdd'))); - EXPECT_EQ("697eaf0aca3a3aea3a75164746ffaa79", - ComputeHmac(DIGEST_MD5, - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", - std::string(50, '\xcd'))); - EXPECT_EQ("56461ef2342edc00f9bab995690efd4c", - ComputeHmac(DIGEST_MD5, std::string(16, '\x0c'), - "Test With Truncation")); - EXPECT_EQ("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd", - ComputeHmac(DIGEST_MD5, std::string(80, '\xaa'), - "Test Using Larger Than Block-Size Key - Hash Key First")); - EXPECT_EQ("6f630fad67cda0ee1fb1f562db3aa53e", - ComputeHmac(DIGEST_MD5, std::string(80, '\xaa'), - "Test Using Larger Than Block-Size Key and Larger " - "Than One Block-Size Data")); - - // Test the raw buffer versions of the APIs; also check output buffer size. - std::string key(16, '\x0b'); - std::string input("Hi There"); - char output[16]; - EXPECT_EQ(sizeof(output), - ComputeHmac(DIGEST_MD5, key.c_str(), key.size(), - input.c_str(), input.size(), output, sizeof(output))); - EXPECT_EQ("9294727a3638bb1c13f48ef8158bfc9d", - hex_encode(output, sizeof(output))); - EXPECT_EQ(0U, - ComputeHmac(DIGEST_MD5, key.c_str(), key.size(), - input.c_str(), input.size(), output, sizeof(output) - 1)); -} - -// Test vectors from RFC 2202. -TEST(MessageDigestTest, TestSha1Hmac) { - // Test the string versions of the APIs. - EXPECT_EQ("b617318655057264e28bc0b6fb378c8ef146be00", - ComputeHmac(DIGEST_SHA_1, std::string(20, '\x0b'), "Hi There")); - EXPECT_EQ("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79", - ComputeHmac(DIGEST_SHA_1, "Jefe", "what do ya want for nothing?")); - EXPECT_EQ("125d7342b9ac11cd91a39af48aa17b4f63f175d3", - ComputeHmac(DIGEST_SHA_1, std::string(20, '\xaa'), - std::string(50, '\xdd'))); - EXPECT_EQ("4c9007f4026250c6bc8414f9bf50c86c2d7235da", - ComputeHmac(DIGEST_SHA_1, - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", - std::string(50, '\xcd'))); - EXPECT_EQ("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04", - ComputeHmac(DIGEST_SHA_1, std::string(20, '\x0c'), - "Test With Truncation")); - EXPECT_EQ("aa4ae5e15272d00e95705637ce8a3b55ed402112", - ComputeHmac(DIGEST_SHA_1, std::string(80, '\xaa'), - "Test Using Larger Than Block-Size Key - Hash Key First")); - EXPECT_EQ("e8e99d0f45237d786d6bbaa7965c7808bbff1a91", - ComputeHmac(DIGEST_SHA_1, std::string(80, '\xaa'), - "Test Using Larger Than Block-Size Key and Larger " - "Than One Block-Size Data")); - - // Test the raw buffer versions of the APIs; also check output buffer size. - std::string key(20, '\x0b'); - std::string input("Hi There"); - char output[20]; - EXPECT_EQ(sizeof(output), - ComputeHmac(DIGEST_SHA_1, key.c_str(), key.size(), - input.c_str(), input.size(), output, sizeof(output))); - EXPECT_EQ("b617318655057264e28bc0b6fb378c8ef146be00", - hex_encode(output, sizeof(output))); - EXPECT_EQ(0U, - ComputeHmac(DIGEST_SHA_1, key.c_str(), key.size(), - input.c_str(), input.size(), output, sizeof(output) - 1)); -} - -TEST(MessageDigestTest, TestBadHmac) { - std::string output; - EXPECT_FALSE(ComputeHmac("sha-9000", "key", "abc", &output)); - EXPECT_EQ("", ComputeHmac("sha-9000", "key", "abc")); -} - -} // namespace rtc diff --git a/webrtc/base/messagehandler.cc b/webrtc/base/messagehandler.cc deleted file mode 100644 index be5bb7f8f..000000000 --- a/webrtc/base/messagehandler.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/messagequeue.h" - -namespace rtc { - -MessageHandler::~MessageHandler() { - MessageQueueManager::Clear(this); -} - -} // namespace rtc diff --git a/webrtc/base/messagehandler.h b/webrtc/base/messagehandler.h deleted file mode 100644 index 123c85097..000000000 --- a/webrtc/base/messagehandler.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_MESSAGEHANDLER_H_ -#define WEBRTC_BASE_MESSAGEHANDLER_H_ - -#include "webrtc/base/constructormagic.h" - -namespace rtc { - -struct Message; - -// Messages get dispatched to a MessageHandler - -class MessageHandler { - public: - virtual ~MessageHandler(); - virtual void OnMessage(Message* msg) = 0; - - protected: - MessageHandler() {} - - private: - DISALLOW_COPY_AND_ASSIGN(MessageHandler); -}; - -// Helper class to facilitate executing a functor on a thread. -template -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 FunctorMessageHandler : public MessageHandler { - public: - explicit FunctorMessageHandler(const FunctorT& functor) - : functor_(functor) {} - virtual void OnMessage(Message* msg) { - functor_(); - } - void result() const {} - - private: - FunctorT functor_; -}; - - -} // namespace rtc - -#endif // WEBRTC_BASE_MESSAGEHANDLER_H_ diff --git a/webrtc/base/messagequeue.cc b/webrtc/base/messagequeue.cc deleted file mode 100644 index bf31a0596..000000000 --- a/webrtc/base/messagequeue.cc +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_POSIX) -#include -#endif - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/messagequeue.h" -#if defined(__native_client__) -#include "webrtc/base/nullsocketserver.h" -typedef rtc::NullSocketServer DefaultSocketServer; -#else -#include "webrtc/base/physicalsocketserver.h" -typedef rtc::PhysicalSocketServer DefaultSocketServer; -#endif - -namespace rtc { - -const uint32 kMaxMsgLatency = 150; // 150 ms - -//------------------------------------------------------------------ -// MessageQueueManager - -MessageQueueManager* MessageQueueManager::instance_ = NULL; - -MessageQueueManager* MessageQueueManager::Instance() { - // Note: This is not thread safe, but it is first called before threads are - // spawned. - if (!instance_) - instance_ = new MessageQueueManager; - return instance_; -} - -bool MessageQueueManager::IsInitialized() { - return instance_ != NULL; -} - -MessageQueueManager::MessageQueueManager() { -} - -MessageQueueManager::~MessageQueueManager() { -} - -void MessageQueueManager::Add(MessageQueue *message_queue) { - return Instance()->AddInternal(message_queue); -} -void MessageQueueManager::AddInternal(MessageQueue *message_queue) { - // MessageQueueManager methods should be non-reentrant, so we - // ASSERT that is the case. If any of these ASSERT, please - // contact bpm or jbeda. - ASSERT(!crit_.CurrentThreadIsOwner()); - CritScope cs(&crit_); - message_queues_.push_back(message_queue); -} - -void MessageQueueManager::Remove(MessageQueue *message_queue) { - // If there isn't a message queue manager instance, then there isn't a queue - // to remove. - if (!instance_) return; - return Instance()->RemoveInternal(message_queue); -} -void MessageQueueManager::RemoveInternal(MessageQueue *message_queue) { - ASSERT(!crit_.CurrentThreadIsOwner()); // See note above. - // If this is the last MessageQueue, destroy the manager as well so that - // we don't leak this object at program shutdown. As mentioned above, this is - // not thread-safe, but this should only happen at program termination (when - // the ThreadManager is destroyed, and threads are no longer active). - bool destroy = false; - { - CritScope cs(&crit_); - std::vector::iterator iter; - iter = std::find(message_queues_.begin(), message_queues_.end(), - message_queue); - if (iter != message_queues_.end()) { - message_queues_.erase(iter); - } - destroy = message_queues_.empty(); - } - if (destroy) { - instance_ = NULL; - delete this; - } -} - -void MessageQueueManager::Clear(MessageHandler *handler) { - // If there isn't a message queue manager instance, then there aren't any - // queues to remove this handler from. - if (!instance_) return; - return Instance()->ClearInternal(handler); -} -void MessageQueueManager::ClearInternal(MessageHandler *handler) { - ASSERT(!crit_.CurrentThreadIsOwner()); // See note above. - CritScope cs(&crit_); - std::vector::iterator iter; - for (iter = message_queues_.begin(); iter != message_queues_.end(); iter++) - (*iter)->Clear(handler); -} - -//------------------------------------------------------------------ -// MessageQueue - -MessageQueue::MessageQueue(SocketServer* ss) - : ss_(ss), fStop_(false), fPeekKeep_(false), active_(false), - dmsgq_next_num_(0) { - if (!ss_) { - // Currently, MessageQueue holds a socket server, and is the base class for - // Thread. It seems like it makes more sense for Thread to hold the socket - // 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 DefaultSocketServer()); - ss_ = default_ss_.get(); - } - ss_->SetMessageQueue(this); -} - -MessageQueue::~MessageQueue() { - // The signal is done from here to ensure - // that it always gets called when the queue - // is going away. - SignalQueueDestroyed(); - if (active_) { - MessageQueueManager::Remove(this); - Clear(NULL); - } - if (ss_) { - ss_->SetMessageQueue(NULL); - } -} - -void MessageQueue::set_socketserver(SocketServer* ss) { - ss_ = ss ? ss : default_ss_.get(); - ss_->SetMessageQueue(this); -} - -void MessageQueue::Quit() { - fStop_ = true; - ss_->WakeUp(); -} - -bool MessageQueue::IsQuitting() { - return fStop_; -} - -void MessageQueue::Restart() { - fStop_ = false; -} - -bool MessageQueue::Peek(Message *pmsg, int cmsWait) { - if (fPeekKeep_) { - *pmsg = msgPeek_; - return true; - } - if (!Get(pmsg, cmsWait)) - return false; - msgPeek_ = *pmsg; - fPeekKeep_ = true; - return true; -} - -bool MessageQueue::Get(Message *pmsg, int cmsWait, bool process_io) { - // Return and clear peek if present - // Always return the peek if it exists so there is Peek/Get symmetry - - if (fPeekKeep_) { - *pmsg = msgPeek_; - fPeekKeep_ = false; - return true; - } - - // Get w/wait + timer scan / dispatch + socket / event multiplexer dispatch - - int cmsTotal = cmsWait; - int cmsElapsed = 0; - uint32 msStart = Time(); - uint32 msCurrent = msStart; - while (true) { - // Check for sent messages - ReceiveSends(); - - // Check for posted events - int cmsDelayNext = kForever; - bool first_pass = true; - while (true) { - // All queue operations need to be locked, but nothing else in this loop - // (specifically handling disposed message) can happen inside the crit. - // Otherwise, disposed MessageHandlers will cause deadlocks. - { - CritScope cs(&crit_); - // On the first pass, check for delayed messages that have been - // triggered and calculate the next trigger time. - if (first_pass) { - first_pass = false; - while (!dmsgq_.empty()) { - if (TimeIsLater(msCurrent, dmsgq_.top().msTrigger_)) { - cmsDelayNext = TimeDiff(dmsgq_.top().msTrigger_, msCurrent); - break; - } - msgq_.push_back(dmsgq_.top().msg_); - dmsgq_.pop(); - } - } - // Pull a message off the message queue, if available. - if (msgq_.empty()) { - break; - } else { - *pmsg = msgq_.front(); - msgq_.pop_front(); - } - } // crit_ is released here. - - // Log a warning for time-sensitive messages that we're late to deliver. - if (pmsg->ts_sensitive) { - int32 delay = TimeDiff(msCurrent, pmsg->ts_sensitive); - if (delay > 0) { - LOG_F(LS_WARNING) << "id: " << pmsg->message_id << " delay: " - << (delay + kMaxMsgLatency) << "ms"; - } - } - // If this was a dispose message, delete it and skip it. - if (MQID_DISPOSE == pmsg->message_id) { - ASSERT(NULL == pmsg->phandler); - delete pmsg->pdata; - *pmsg = Message(); - continue; - } - return true; - } - - if (fStop_) - break; - - // Which is shorter, the delay wait or the asked wait? - - int cmsNext; - if (cmsWait == kForever) { - cmsNext = cmsDelayNext; - } else { - cmsNext = _max(0, cmsTotal - cmsElapsed); - if ((cmsDelayNext != kForever) && (cmsDelayNext < cmsNext)) - cmsNext = cmsDelayNext; - } - - // Wait and multiplex in the meantime - if (!ss_->Wait(cmsNext, process_io)) - return false; - - // If the specified timeout expired, return - - msCurrent = Time(); - cmsElapsed = TimeDiff(msCurrent, msStart); - if (cmsWait != kForever) { - if (cmsElapsed >= cmsWait) - return false; - } - } - return false; -} - -void MessageQueue::ReceiveSends() { -} - -void MessageQueue::Post(MessageHandler *phandler, uint32 id, - MessageData *pdata, bool time_sensitive) { - if (fStop_) - return; - - // Keep thread safe - // Add the message to the end of the queue - // Signal for the multiplexer to return - - CritScope cs(&crit_); - EnsureActive(); - Message msg; - msg.phandler = phandler; - msg.message_id = id; - msg.pdata = pdata; - if (time_sensitive) { - msg.ts_sensitive = Time() + kMaxMsgLatency; - } - msgq_.push_back(msg); - ss_->WakeUp(); -} - -void MessageQueue::DoDelayPost(int cmsDelay, uint32 tstamp, - MessageHandler *phandler, uint32 id, MessageData* pdata) { - if (fStop_) - return; - - // Keep thread safe - // Add to the priority queue. Gets sorted soonest first. - // Signal for the multiplexer to return. - - CritScope cs(&crit_); - EnsureActive(); - Message msg; - msg.phandler = phandler; - msg.message_id = id; - msg.pdata = pdata; - DelayedMessage dmsg(cmsDelay, tstamp, dmsgq_next_num_, msg); - dmsgq_.push(dmsg); - // If this message queue processes 1 message every millisecond for 50 days, - // we will wrap this number. Even then, only messages with identical times - // will be misordered, and then only briefly. This is probably ok. - VERIFY(0 != ++dmsgq_next_num_); - ss_->WakeUp(); -} - -int MessageQueue::GetDelay() { - CritScope cs(&crit_); - - if (!msgq_.empty()) - return 0; - - if (!dmsgq_.empty()) { - int delay = TimeUntil(dmsgq_.top().msTrigger_); - if (delay < 0) - delay = 0; - return delay; - } - - return kForever; -} - -void MessageQueue::Clear(MessageHandler *phandler, uint32 id, - MessageList* removed) { - CritScope cs(&crit_); - - // Remove messages with phandler - - if (fPeekKeep_ && msgPeek_.Match(phandler, id)) { - if (removed) { - removed->push_back(msgPeek_); - } else { - delete msgPeek_.pdata; - } - fPeekKeep_ = false; - } - - // Remove from ordered message queue - - for (MessageList::iterator it = msgq_.begin(); it != msgq_.end();) { - if (it->Match(phandler, id)) { - if (removed) { - removed->push_back(*it); - } else { - delete it->pdata; - } - it = msgq_.erase(it); - } else { - ++it; - } - } - - // Remove from priority queue. Not directly iterable, so use this approach - - PriorityQueue::container_type::iterator new_end = dmsgq_.container().begin(); - for (PriorityQueue::container_type::iterator it = new_end; - it != dmsgq_.container().end(); ++it) { - if (it->msg_.Match(phandler, id)) { - if (removed) { - removed->push_back(it->msg_); - } else { - delete it->msg_.pdata; - } - } else { - *new_end++ = *it; - } - } - dmsgq_.container().erase(new_end, dmsgq_.container().end()); - dmsgq_.reheap(); -} - -void MessageQueue::Dispatch(Message *pmsg) { - pmsg->phandler->OnMessage(pmsg); -} - -void MessageQueue::EnsureActive() { - ASSERT(crit_.CurrentThreadIsOwner()); - if (!active_) { - active_ = true; - MessageQueueManager::Add(this); - } -} - -} // namespace rtc diff --git a/webrtc/base/messagequeue.h b/webrtc/base/messagequeue.h deleted file mode 100644 index 958a39eb9..000000000 --- a/webrtc/base/messagequeue.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_MESSAGEQUEUE_H_ -#define WEBRTC_BASE_MESSAGEQUEUE_H_ - -#include - -#include -#include -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/scoped_ref_ptr.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/socketserver.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { - -struct Message; -class MessageQueue; - -// MessageQueueManager does cleanup of of message queues - -class MessageQueueManager { - public: - static void Add(MessageQueue *message_queue); - static void Remove(MessageQueue *message_queue); - static void Clear(MessageHandler *handler); - - // For testing purposes, we expose whether or not the MessageQueueManager - // instance has been initialized. It has no other use relative to the rest of - // the functions of this class, which auto-initialize the underlying - // MessageQueueManager instance when necessary. - static bool IsInitialized(); - - private: - static MessageQueueManager* Instance(); - - MessageQueueManager(); - ~MessageQueueManager(); - - void AddInternal(MessageQueue *message_queue); - void RemoveInternal(MessageQueue *message_queue); - void ClearInternal(MessageHandler *handler); - - static MessageQueueManager* instance_; - // This list contains 'active' MessageQueues. - std::vector message_queues_; - CriticalSection crit_; -}; - -// Derive from this for specialized data -// App manages lifetime, except when messages are purged - -class MessageData { - public: - MessageData() {} - virtual ~MessageData() {} -}; - -template -class TypedMessageData : public MessageData { - public: - explicit TypedMessageData(const T& data) : data_(data) { } - const T& data() const { return data_; } - T& data() { return data_; } - private: - T data_; -}; - -// Like TypedMessageData, but for pointers that require a delete. -template -class ScopedMessageData : public MessageData { - public: - explicit ScopedMessageData(T* data) : data_(data) { } - const scoped_ptr& data() const { return data_; } - scoped_ptr& data() { return data_; } - private: - scoped_ptr data_; -}; - -// Like ScopedMessageData, but for reference counted pointers. -template -class ScopedRefMessageData : public MessageData { - public: - explicit ScopedRefMessageData(T* data) : data_(data) { } - const scoped_refptr& data() const { return data_; } - scoped_refptr& data() { return data_; } - private: - scoped_refptr data_; -}; - -template -inline MessageData* WrapMessageData(const T& data) { - return new TypedMessageData(data); -} - -template -inline const T& UseMessageData(MessageData* data) { - return static_cast< TypedMessageData* >(data)->data(); -} - -template -class DisposeData : public MessageData { - public: - explicit DisposeData(T* data) : data_(data) { } - virtual ~DisposeData() { delete data_; } - private: - T* data_; -}; - -const uint32 MQID_ANY = static_cast(-1); -const uint32 MQID_DISPOSE = static_cast(-2); - -// No destructor - -struct Message { - Message() { - memset(this, 0, sizeof(*this)); - } - inline bool Match(MessageHandler* handler, uint32 id) const { - return (handler == NULL || handler == phandler) - && (id == MQID_ANY || id == message_id); - } - MessageHandler *phandler; - uint32 message_id; - MessageData *pdata; - uint32 ts_sensitive; -}; - -typedef std::list MessageList; - -// DelayedMessage goes into a priority queue, sorted by trigger time. Messages -// with the same trigger time are processed in num_ (FIFO) order. - -class DelayedMessage { - public: - DelayedMessage(int delay, uint32 trigger, uint32 num, const Message& msg) - : cmsDelay_(delay), msTrigger_(trigger), num_(num), msg_(msg) { } - - bool operator< (const DelayedMessage& dmsg) const { - return (dmsg.msTrigger_ < msTrigger_) - || ((dmsg.msTrigger_ == msTrigger_) && (dmsg.num_ < num_)); - } - - int cmsDelay_; // for debugging - uint32 msTrigger_; - uint32 num_; - Message msg_; -}; - -class MessageQueue { - public: - explicit MessageQueue(SocketServer* ss = NULL); - virtual ~MessageQueue(); - - SocketServer* socketserver() { return ss_; } - void set_socketserver(SocketServer* ss); - - // Note: The behavior of MessageQueue has changed. When a MQ is stopped, - // futher Posts and Sends will fail. However, any pending Sends and *ready* - // Posts (as opposed to unexpired delayed Posts) will be delivered before - // Get (or Peek) returns false. By guaranteeing delivery of those messages, - // we eliminate the race condition when an MessageHandler and MessageQueue - // may be destroyed independently of each other. - virtual void Quit(); - virtual bool IsQuitting(); - virtual void Restart(); - - // Get() will process I/O until: - // 1) A message is available (returns true) - // 2) cmsWait seconds have elapsed (returns false) - // 3) Stop() is called (returns false) - virtual bool Get(Message *pmsg, int cmsWait = kForever, - bool process_io = true); - virtual bool Peek(Message *pmsg, int cmsWait = 0); - virtual void Post(MessageHandler *phandler, uint32 id = 0, - MessageData *pdata = NULL, bool time_sensitive = false); - virtual void PostDelayed(int cmsDelay, MessageHandler *phandler, - uint32 id = 0, MessageData *pdata = NULL) { - return DoDelayPost(cmsDelay, TimeAfter(cmsDelay), phandler, id, pdata); - } - virtual void PostAt(uint32 tstamp, MessageHandler *phandler, - uint32 id = 0, MessageData *pdata = NULL) { - return DoDelayPost(TimeUntil(tstamp), tstamp, phandler, id, pdata); - } - virtual void Clear(MessageHandler *phandler, uint32 id = MQID_ANY, - MessageList* removed = NULL); - virtual void Dispatch(Message *pmsg); - virtual void ReceiveSends(); - - // Amount of time until the next message can be retrieved - virtual int GetDelay(); - - bool empty() const { return size() == 0u; } - size_t size() const { - CritScope cs(&crit_); // msgq_.size() is not thread safe. - return msgq_.size() + dmsgq_.size() + (fPeekKeep_ ? 1u : 0u); - } - - // Internally posts a message which causes the doomed object to be deleted - template void Dispose(T* doomed) { - if (doomed) { - Post(NULL, MQID_DISPOSE, new DisposeData(doomed)); - } - } - - // When this signal is sent out, any references to this queue should - // no longer be used. - sigslot::signal0<> SignalQueueDestroyed; - - protected: - class PriorityQueue : public std::priority_queue { - public: - container_type& container() { return c; } - void reheap() { make_heap(c.begin(), c.end(), comp); } - }; - - void EnsureActive(); - void DoDelayPost(int cmsDelay, uint32 tstamp, MessageHandler *phandler, - uint32 id, MessageData* pdata); - - // The SocketServer is not owned by MessageQueue. - SocketServer* ss_; - // If a server isn't supplied in the constructor, use this one. - scoped_ptr default_ss_; - 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_; - mutable CriticalSection crit_; - - private: - DISALLOW_COPY_AND_ASSIGN(MessageQueue); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_MESSAGEQUEUE_H_ diff --git a/webrtc/base/messagequeue_unittest.cc b/webrtc/base/messagequeue_unittest.cc deleted file mode 100644 index 78024e0b2..000000000 --- a/webrtc/base/messagequeue_unittest.cc +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/messagequeue.h" - -#include "webrtc/base/bind.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" -#include "webrtc/base/nullsocketserver.h" - -using namespace rtc; - -class MessageQueueTest: public testing::Test, public MessageQueue { - public: - bool IsLocked_Worker() { - if (!crit_.TryEnter()) { - return true; - } - crit_.Leave(); - return false; - } - bool IsLocked() { - // We have to do this on a worker thread, or else the TryEnter will - // succeed, since our critical sections are reentrant. - Thread worker; - worker.Start(); - return worker.Invoke( - rtc::Bind(&MessageQueueTest::IsLocked_Worker, this)); - } -}; - -struct DeletedLockChecker { - DeletedLockChecker(MessageQueueTest* test, bool* was_locked, bool* deleted) - : test(test), was_locked(was_locked), deleted(deleted) { } - ~DeletedLockChecker() { - *deleted = true; - *was_locked = test->IsLocked(); - } - MessageQueueTest* test; - bool* was_locked; - bool* deleted; -}; - -static void DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder( - MessageQueue* q) { - EXPECT_TRUE(q != NULL); - TimeStamp now = Time(); - q->PostAt(now, NULL, 3); - q->PostAt(now - 2, NULL, 0); - q->PostAt(now - 1, NULL, 1); - q->PostAt(now, NULL, 4); - q->PostAt(now - 1, NULL, 2); - - Message msg; - for (size_t i=0; i<5; ++i) { - memset(&msg, 0, sizeof(msg)); - EXPECT_TRUE(q->Get(&msg, 0)); - EXPECT_EQ(i, msg.message_id); - } - - EXPECT_FALSE(q->Get(&msg, 0)); // No more messages -} - -TEST_F(MessageQueueTest, - DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder) { - MessageQueue q; - DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(&q); - NullSocketServer nullss; - MessageQueue q_nullss(&nullss); - DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(&q_nullss); -} - -TEST_F(MessageQueueTest, DisposeNotLocked) { - bool was_locked = true; - bool deleted = false; - DeletedLockChecker* d = new DeletedLockChecker(this, &was_locked, &deleted); - Dispose(d); - Message msg; - EXPECT_FALSE(Get(&msg, 0)); - EXPECT_TRUE(deleted); - EXPECT_FALSE(was_locked); -} - -class DeletedMessageHandler : public MessageHandler { - public: - explicit DeletedMessageHandler(bool* deleted) : deleted_(deleted) { } - ~DeletedMessageHandler() { - *deleted_ = true; - } - void OnMessage(Message* msg) { } - private: - bool* deleted_; -}; - -TEST_F(MessageQueueTest, DiposeHandlerWithPostedMessagePending) { - bool deleted = false; - DeletedMessageHandler *handler = new DeletedMessageHandler(&deleted); - // First, post a dispose. - Dispose(handler); - // Now, post a message, which should *not* be returned by Get(). - Post(handler, 1); - Message msg; - EXPECT_FALSE(Get(&msg, 0)); - EXPECT_TRUE(deleted); -} - -struct UnwrapMainThreadScope { - UnwrapMainThreadScope() : rewrap_(Thread::Current() != NULL) { - if (rewrap_) ThreadManager::Instance()->UnwrapCurrentThread(); - } - ~UnwrapMainThreadScope() { - if (rewrap_) ThreadManager::Instance()->WrapCurrentThread(); - } - private: - bool rewrap_; -}; - -TEST(MessageQueueManager, Clear) { - UnwrapMainThreadScope s; - if (MessageQueueManager::IsInitialized()) { - LOG(LS_INFO) << "Unable to run MessageQueueManager::Clear test, since the " - << "MessageQueueManager was already initialized by some " - << "other test in this run."; - return; - } - bool deleted = false; - DeletedMessageHandler* handler = new DeletedMessageHandler(&deleted); - delete handler; - EXPECT_TRUE(deleted); - EXPECT_FALSE(MessageQueueManager::IsInitialized()); -} diff --git a/webrtc/base/move.h b/webrtc/base/move.h deleted file mode 100644 index 6d59cc583..000000000 --- a/webrtc/base/move.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef THIRD_PARTY_WEBRTC_FILES_WEBRTC_BASE_MOVE_H_ -#define THIRD_PARTY_WEBRTC_FILES_WEBRTC_BASE_MOVE_H_ - -// Macro with the boilerplate that makes a type move-only in C++03. -// -// USAGE -// -// This macro should be used instead of DISALLOW_COPY_AND_ASSIGN to create -// a "move-only" type. Unlike DISALLOW_COPY_AND_ASSIGN, this macro should be -// the first line in a class declaration. -// -// A class using this macro must call .Pass() (or somehow be an r-value already) -// before it can be: -// -// * Passed as a function argument -// * Used as the right-hand side of an assignment -// * Returned from a function -// -// Each class will still need to define their own "move constructor" and "move -// operator=" to make this useful. Here's an example of the macro, the move -// constructor, and the move operator= from the scoped_ptr class: -// -// template -// class scoped_ptr { -// TALK_MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) -// public: -// scoped_ptr(RValue& other) : ptr_(other.release()) { } -// scoped_ptr& operator=(RValue& other) { -// swap(other); -// return *this; -// } -// }; -// -// Note that the constructor must NOT be marked explicit. -// -// For consistency, the second parameter to the macro should always be RValue -// unless you have a strong reason to do otherwise. It is only exposed as a -// macro parameter so that the move constructor and move operator= don't look -// like they're using a phantom type. -// -// -// HOW THIS WORKS -// -// For a thorough explanation of this technique, see: -// -// http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Move_Constructor -// -// The summary is that we take advantage of 2 properties: -// -// 1) non-const references will not bind to r-values. -// 2) C++ can apply one user-defined conversion when initializing a -// variable. -// -// The first lets us disable the copy constructor and assignment operator -// by declaring private version of them with a non-const reference parameter. -// -// For l-values, direct initialization still fails like in -// DISALLOW_COPY_AND_ASSIGN because the copy constructor and assignment -// operators are private. -// -// For r-values, the situation is different. The copy constructor and -// assignment operator are not viable due to (1), so we are trying to call -// a non-existent constructor and non-existing operator= rather than a private -// one. Since we have not committed an error quite yet, we can provide an -// alternate conversion sequence and a constructor. We add -// -// * a private struct named "RValue" -// * a user-defined conversion "operator RValue()" -// * a "move constructor" and "move operator=" that take the RValue& as -// their sole parameter. -// -// Only r-values will trigger this sequence and execute our "move constructor" -// or "move operator=." L-values will match the private copy constructor and -// operator= first giving a "private in this context" error. This combination -// gives us a move-only type. -// -// For signaling a destructive transfer of data from an l-value, we provide a -// method named Pass() which creates an r-value for the current instance -// triggering the move constructor or move operator=. -// -// Other ways to get r-values is to use the result of an expression like a -// function call. -// -// Here's an example with comments explaining what gets triggered where: -// -// class Foo { -// TALK_MOVE_ONLY_TYPE_FOR_CPP_03(Foo, RValue); -// -// public: -// ... API ... -// Foo(RValue other); // Move constructor. -// Foo& operator=(RValue rhs); // Move operator= -// }; -// -// Foo MakeFoo(); // Function that returns a Foo. -// -// Foo f; -// Foo f_copy(f); // ERROR: Foo(Foo&) is private in this context. -// Foo f_assign; -// f_assign = f; // ERROR: operator=(Foo&) is private in this context. -// -// -// Foo f(MakeFoo()); // R-value so alternate conversion executed. -// Foo f_copy(f.Pass()); // R-value so alternate conversion executed. -// f = f_copy.Pass(); // R-value so alternate conversion executed. -// -// -// IMPLEMENTATION SUBTLETIES WITH RValue -// -// The RValue struct is just a container for a pointer back to the original -// object. It should only ever be created as a temporary, and no external -// class should ever declare it or use it in a parameter. -// -// It is tempting to want to use the RValue type in function parameters, but -// excluding the limited usage here for the move constructor and move -// operator=, doing so would mean that the function could take both r-values -// and l-values equially which is unexpected. See COMPARED To Boost.Move for -// more details. -// -// An alternate, and incorrect, implementation of the RValue class used by -// Boost.Move makes RValue a fieldless child of the move-only type. RValue& -// is then used in place of RValue in the various operators. The RValue& is -// "created" by doing *reinterpret_cast(this). This has the appeal -// of never creating a temporary RValue struct even with optimizations -// disabled. Also, by virtue of inheritance you can treat the RValue -// reference as if it were the move-only type itself. Unfortunately, -// using the result of this reinterpret_cast<> is actually undefined behavior -// due to C++98 5.2.10.7. In certain compilers (e.g., NaCl) the optimizer -// will generate non-working code. -// -// In optimized builds, both implementations generate the same assembly so we -// choose the one that adheres to the standard. -// -// -// COMPARED TO C++11 -// -// In C++11, you would implement this functionality using an r-value reference -// and our .Pass() method would be replaced with a call to std::move(). -// -// This emulation also has a deficiency where it uses up the single -// user-defined conversion allowed by C++ during initialization. This can -// cause problems in some API edge cases. For instance, in scoped_ptr, it is -// impossible to make a function "void Foo(scoped_ptr p)" accept a -// value of type scoped_ptr even if you add a constructor to -// scoped_ptr<> that would make it look like it should work. C++11 does not -// have this deficiency. -// -// -// COMPARED TO Boost.Move -// -// Our implementation similar to Boost.Move, but we keep the RValue struct -// private to the move-only type, and we don't use the reinterpret_cast<> hack. -// -// In Boost.Move, RValue is the boost::rv<> template. This type can be used -// when writing APIs like: -// -// void MyFunc(boost::rv& f) -// -// that can take advantage of rv<> to avoid extra copies of a type. However you -// would still be able to call this version of MyFunc with an l-value: -// -// Foo f; -// MyFunc(f); // Uh oh, we probably just destroyed |f| w/o calling Pass(). -// -// unless someone is very careful to also declare a parallel override like: -// -// void MyFunc(const Foo& f) -// -// that would catch the l-values first. This was declared unsafe in C++11 and -// a C++11 compiler will explicitly fail MyFunc(f). Unfortunately, we cannot -// ensure this in C++03. -// -// Since we have no need for writing such APIs yet, our implementation keeps -// RValue private and uses a .Pass() method to do the conversion instead of -// trying to write a version of "std::move()." Writing an API like std::move() -// would require the RValue struct to be public. -// -// -// CAVEATS -// -// If you include a move-only type as a field inside a class that does not -// explicitly declare a copy constructor, the containing class's implicit -// copy constructor will change from Containing(const Containing&) to -// Containing(Containing&). This can cause some unexpected errors. -// -// http://llvm.org/bugs/show_bug.cgi?id=11528 -// -// The workaround is to explicitly declare your copy constructor. -// -#define TALK_MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \ - private: \ - struct rvalue_type { \ - explicit rvalue_type(type* object) : object(object) {} \ - type* object; \ - }; \ - type(type&); \ - void operator=(type&); \ - public: \ - operator rvalue_type() { return rvalue_type(this); } \ - type Pass() { return type(rvalue_type(this)); } \ - private: - -#endif // THIRD_PARTY_WEBRTC_FILES_WEBRTC_BASE_MOVE_H_ diff --git a/webrtc/base/multipart.cc b/webrtc/base/multipart.cc deleted file mode 100644 index 0d73880e4..000000000 --- a/webrtc/base/multipart.cc +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -#include "webrtc/base/common.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/multipart.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// MultipartStream -/////////////////////////////////////////////////////////////////////////////// - -MultipartStream::MultipartStream(const std::string& type, - const std::string& boundary) - : type_(type), - boundary_(boundary), - adding_(true), - current_(0), - position_(0) { - // The content type should be multipart/*. - ASSERT(0 == strncmp(type_.c_str(), "multipart/", 10)); -} - -MultipartStream::~MultipartStream() { - Close(); -} - -void MultipartStream::GetContentType(std::string* content_type) { - ASSERT(NULL != content_type); - content_type->assign(type_); - content_type->append("; boundary="); - content_type->append(boundary_); -} - -bool MultipartStream::AddPart(StreamInterface* data_stream, - const std::string& content_disposition, - const std::string& content_type) { - if (!AddPart("", content_disposition, content_type)) - return false; - parts_.push_back(data_stream); - data_stream->SignalEvent.connect(this, &MultipartStream::OnEvent); - return true; -} - -bool MultipartStream::AddPart(const std::string& data, - const std::string& content_disposition, - const std::string& content_type) { - ASSERT(adding_); - if (!adding_) - return false; - std::stringstream ss; - if (!parts_.empty()) { - ss << "\r\n"; - } - ss << "--" << boundary_ << "\r\n"; - if (!content_disposition.empty()) { - ss << ToString(HH_CONTENT_DISPOSITION) << ": " - << content_disposition << "\r\n"; - } - if (!content_type.empty()) { - ss << ToString(HH_CONTENT_TYPE) << ": " - << content_type << "\r\n"; - } - ss << "\r\n" << data; - parts_.push_back(new MemoryStream(ss.str().data(), ss.str().size())); - return true; -} - -void MultipartStream::EndParts() { - ASSERT(adding_); - if (!adding_) - return; - - std::stringstream ss; - if (!parts_.empty()) { - ss << "\r\n"; - } - ss << "--" << boundary_ << "--" << "\r\n"; - parts_.push_back(new MemoryStream(ss.str().data(), ss.str().size())); - - ASSERT(0 == current_); - ASSERT(0 == position_); - adding_ = false; - SignalEvent(this, SE_OPEN | SE_READ, 0); -} - -size_t MultipartStream::GetPartSize(const std::string& data, - const std::string& content_disposition, - const std::string& content_type) const { - size_t size = 0; - if (!parts_.empty()) { - size += 2; // for "\r\n"; - } - size += boundary_.size() + 4; // for "--boundary_\r\n"; - if (!content_disposition.empty()) { - // for ToString(HH_CONTENT_DISPOSITION): content_disposition\r\n - size += std::string(ToString(HH_CONTENT_DISPOSITION)).size() + 2 + - content_disposition.size() + 2; - } - if (!content_type.empty()) { - // for ToString(HH_CONTENT_TYPE): content_type\r\n - size += std::string(ToString(HH_CONTENT_TYPE)).size() + 2 + - content_type.size() + 2; - } - size += 2 + data.size(); // for \r\ndata - return size; -} - -size_t MultipartStream::GetEndPartSize() const { - size_t size = 0; - if (!parts_.empty()) { - size += 2; // for "\r\n"; - } - size += boundary_.size() + 6; // for "--boundary_--\r\n"; - return size; -} - -// -// StreamInterface -// - -StreamState MultipartStream::GetState() const { - if (adding_) { - return SS_OPENING; - } - return (current_ < parts_.size()) ? SS_OPEN : SS_CLOSED; -} - -StreamResult MultipartStream::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - if (adding_) { - return SR_BLOCK; - } - size_t local_read; - if (!read) read = &local_read; - while (current_ < parts_.size()) { - StreamResult result = parts_[current_]->Read(buffer, buffer_len, read, - error); - if (SR_EOS != result) { - if (SR_SUCCESS == result) { - position_ += *read; - } - return result; - } - ++current_; - } - return SR_EOS; -} - -StreamResult MultipartStream::Write(const void* data, size_t data_len, - size_t* written, int* error) { - if (error) { - *error = -1; - } - return SR_ERROR; -} - -void MultipartStream::Close() { - for (size_t i = 0; i < parts_.size(); ++i) { - delete parts_[i]; - } - parts_.clear(); - adding_ = false; - current_ = 0; - position_ = 0; -} - -bool MultipartStream::SetPosition(size_t position) { - if (adding_) { - return false; - } - size_t part_size, part_offset = 0; - for (size_t i = 0; i < parts_.size(); ++i) { - if (!parts_[i]->GetSize(&part_size)) { - return false; - } - if (part_offset + part_size > position) { - for (size_t j = i+1; j < _min(parts_.size(), current_+1); ++j) { - if (!parts_[j]->Rewind()) { - return false; - } - } - if (!parts_[i]->SetPosition(position - part_offset)) { - return false; - } - current_ = i; - position_ = position; - return true; - } - part_offset += part_size; - } - return false; -} - -bool MultipartStream::GetPosition(size_t* position) const { - if (position) { - *position = position_; - } - return true; -} - -bool MultipartStream::GetSize(size_t* size) const { - size_t part_size, total_size = 0; - for (size_t i = 0; i < parts_.size(); ++i) { - if (!parts_[i]->GetSize(&part_size)) { - return false; - } - total_size += part_size; - } - if (size) { - *size = total_size; - } - return true; -} - -bool MultipartStream::GetAvailable(size_t* size) const { - if (adding_) { - return false; - } - size_t part_size, total_size = 0; - for (size_t i = current_; i < parts_.size(); ++i) { - if (!parts_[i]->GetAvailable(&part_size)) { - return false; - } - total_size += part_size; - } - if (size) { - *size = total_size; - } - return true; -} - -// -// StreamInterface Slots -// - -void MultipartStream::OnEvent(StreamInterface* stream, int events, int error) { - if (adding_ || (current_ >= parts_.size()) || (parts_[current_] != stream)) { - return; - } - SignalEvent(this, events, error); -} - -} // namespace rtc diff --git a/webrtc/base/multipart.h b/webrtc/base/multipart.h deleted file mode 100644 index a41f596ff..000000000 --- a/webrtc/base/multipart.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_MULTIPART_H__ -#define WEBRTC_BASE_MULTIPART_H__ - -#include -#include - -#include "webrtc/base/sigslot.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// MultipartStream - Implements an RFC2046 multipart stream by concatenating -// the supplied parts together, and adding the correct boundaries. -/////////////////////////////////////////////////////////////////////////////// - -class MultipartStream : public StreamInterface, public sigslot::has_slots<> { - public: - MultipartStream(const std::string& type, const std::string& boundary); - virtual ~MultipartStream(); - - void GetContentType(std::string* content_type); - - // Note: If content_disposition and/or content_type are the empty string, - // they will be omitted. - bool AddPart(StreamInterface* data_stream, - const std::string& content_disposition, - const std::string& content_type); - bool AddPart(const std::string& data, - const std::string& content_disposition, - const std::string& content_type); - void EndParts(); - - // Calculates the size of a part before actually adding the part. - size_t GetPartSize(const std::string& data, - const std::string& content_disposition, - const std::string& content_type) const; - size_t GetEndPartSize() const; - - // StreamInterface - virtual StreamState GetState() const; - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - virtual void Close(); - virtual bool SetPosition(size_t position); - virtual bool GetPosition(size_t* position) const; - virtual bool GetSize(size_t* size) const; - virtual bool GetAvailable(size_t* size) const; - - private: - typedef std::vector PartList; - - // StreamInterface Slots - void OnEvent(StreamInterface* stream, int events, int error); - - std::string type_, boundary_; - PartList parts_; - bool adding_; - size_t current_; // The index into parts_ of the current read position. - size_t position_; // The current read position in bytes. - - DISALLOW_COPY_AND_ASSIGN(MultipartStream); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_MULTIPART_H__ diff --git a/webrtc/base/multipart_unittest.cc b/webrtc/base/multipart_unittest.cc deleted file mode 100644 index 38e111493..000000000 --- a/webrtc/base/multipart_unittest.cc +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/helpers.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/multipart.h" - -namespace rtc { - -static const std::string kTestMultipartBoundary = "123456789987654321"; -static const std::string kTestContentType = - "multipart/form-data; boundary=123456789987654321"; -static const char kTestData[] = "This is a test."; -static const char kTestStreamContent[] = "This is a test stream."; - -TEST(MultipartTest, TestBasicOperations) { - MultipartStream multipart("multipart/form-data", kTestMultipartBoundary); - std::string content_type; - multipart.GetContentType(&content_type); - EXPECT_EQ(kTestContentType, content_type); - - EXPECT_EQ(rtc::SS_OPENING, multipart.GetState()); - - // The multipart stream contains only --boundary--\r\n - size_t end_part_size = multipart.GetEndPartSize(); - multipart.EndParts(); - EXPECT_EQ(rtc::SS_OPEN, multipart.GetState()); - size_t size; - EXPECT_TRUE(multipart.GetSize(&size)); - EXPECT_EQ(end_part_size, size); - - // Write is not supported. - EXPECT_EQ(rtc::SR_ERROR, - multipart.Write(kTestData, sizeof(kTestData), NULL, NULL)); - - multipart.Close(); - EXPECT_EQ(rtc::SS_CLOSED, multipart.GetState()); - EXPECT_TRUE(multipart.GetSize(&size)); - EXPECT_EQ(0U, size); -} - -TEST(MultipartTest, TestAddAndRead) { - MultipartStream multipart("multipart/form-data", kTestMultipartBoundary); - - size_t part_size = - multipart.GetPartSize(kTestData, "form-data; name=\"text\"", "text"); - EXPECT_TRUE(multipart.AddPart(kTestData, "form-data; name=\"text\"", "text")); - size_t size; - EXPECT_TRUE(multipart.GetSize(&size)); - EXPECT_EQ(part_size, size); - - rtc::scoped_ptr stream( - new rtc::MemoryStream(kTestStreamContent)); - size_t stream_size = 0; - EXPECT_TRUE(stream->GetSize(&stream_size)); - part_size += - multipart.GetPartSize("", "form-data; name=\"stream\"", "stream"); - part_size += stream_size; - - EXPECT_TRUE(multipart.AddPart( - new rtc::MemoryStream(kTestStreamContent), - "form-data; name=\"stream\"", - "stream")); - EXPECT_TRUE(multipart.GetSize(&size)); - EXPECT_EQ(part_size, size); - - // In adding state, block read. - char buffer[1024]; - EXPECT_EQ(rtc::SR_BLOCK, - multipart.Read(buffer, sizeof(buffer), NULL, NULL)); - // Write is not supported. - EXPECT_EQ(rtc::SR_ERROR, - multipart.Write(buffer, sizeof(buffer), NULL, NULL)); - - part_size += multipart.GetEndPartSize(); - multipart.EndParts(); - EXPECT_TRUE(multipart.GetSize(&size)); - EXPECT_EQ(part_size, size); - - // Read the multipart stream into StringStream - std::string str; - rtc::StringStream str_stream(str); - EXPECT_EQ(rtc::SR_SUCCESS, - Flow(&multipart, buffer, sizeof(buffer), &str_stream)); - EXPECT_EQ(size, str.length()); - - // Search three boundaries and two parts in the order. - size_t pos = 0; - pos = str.find(kTestMultipartBoundary); - EXPECT_NE(std::string::npos, pos); - pos += kTestMultipartBoundary.length(); - - pos = str.find(kTestData, pos); - EXPECT_NE(std::string::npos, pos); - pos += sizeof(kTestData); - - pos = str.find(kTestMultipartBoundary, pos); - EXPECT_NE(std::string::npos, pos); - pos += kTestMultipartBoundary.length(); - - pos = str.find(kTestStreamContent, pos); - EXPECT_NE(std::string::npos, pos); - pos += sizeof(kTestStreamContent); - - pos = str.find(kTestMultipartBoundary, pos); - EXPECT_NE(std::string::npos, pos); - pos += kTestMultipartBoundary.length(); - - pos = str.find(kTestMultipartBoundary, pos); - EXPECT_EQ(std::string::npos, pos); -} - -} // namespace rtc diff --git a/webrtc/base/nat_unittest.cc b/webrtc/base/nat_unittest.cc deleted file mode 100644 index 8b9d8a150..000000000 --- a/webrtc/base/nat_unittest.cc +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/natserver.h" -#include "webrtc/base/natsocketfactory.h" -#include "webrtc/base/nethelpers.h" -#include "webrtc/base/network.h" -#include "webrtc/base/physicalsocketserver.h" -#include "webrtc/base/testclient.h" -#include "webrtc/base/virtualsocketserver.h" - -using namespace rtc; - -bool CheckReceive( - TestClient* client, bool should_receive, const char* buf, size_t size) { - return (should_receive) ? - client->CheckNextPacket(buf, size, 0) : - client->CheckNoPacket(); -} - -TestClient* CreateTestClient( - SocketFactory* factory, const SocketAddress& local_addr) { - AsyncUDPSocket* socket = AsyncUDPSocket::Create(factory, local_addr); - return new TestClient(socket); -} - -// Tests that when sending from internal_addr to external_addrs through the -// NAT type specified by nat_type, all external addrs receive the sent packet -// and, if exp_same is true, all use the same mapped-address on the NAT. -void TestSend( - SocketServer* internal, const SocketAddress& internal_addr, - SocketServer* external, const SocketAddress external_addrs[4], - NATType nat_type, bool exp_same) { - Thread th_int(internal); - Thread th_ext(external); - - SocketAddress server_addr = internal_addr; - server_addr.SetPort(0); // Auto-select a port - NATServer* nat = new NATServer( - nat_type, internal, server_addr, external, external_addrs[0]); - NATSocketFactory* natsf = new NATSocketFactory(internal, - nat->internal_address()); - - TestClient* in = CreateTestClient(natsf, internal_addr); - TestClient* out[4]; - for (int i = 0; i < 4; i++) - out[i] = CreateTestClient(external, external_addrs[i]); - - th_int.Start(); - th_ext.Start(); - - const char* buf = "filter_test"; - size_t len = strlen(buf); - - in->SendTo(buf, len, out[0]->address()); - SocketAddress trans_addr; - EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); - - for (int i = 1; i < 4; i++) { - in->SendTo(buf, len, out[i]->address()); - SocketAddress trans_addr2; - EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2)); - bool are_same = (trans_addr == trans_addr2); - ASSERT_EQ(are_same, exp_same) << "same translated address"; - ASSERT_NE(AF_UNSPEC, trans_addr.family()); - ASSERT_NE(AF_UNSPEC, trans_addr2.family()); - } - - th_int.Stop(); - th_ext.Stop(); - - delete nat; - delete natsf; - delete in; - for (int i = 0; i < 4; i++) - delete out[i]; -} - -// Tests that when sending from external_addrs to internal_addr, the packet -// is delivered according to the specified filter_ip and filter_port rules. -void TestRecv( - SocketServer* internal, const SocketAddress& internal_addr, - SocketServer* external, const SocketAddress external_addrs[4], - NATType nat_type, bool filter_ip, bool filter_port) { - Thread th_int(internal); - Thread th_ext(external); - - SocketAddress server_addr = internal_addr; - server_addr.SetPort(0); // Auto-select a port - NATServer* nat = new NATServer( - nat_type, internal, server_addr, external, external_addrs[0]); - NATSocketFactory* natsf = new NATSocketFactory(internal, - nat->internal_address()); - - TestClient* in = CreateTestClient(natsf, internal_addr); - TestClient* out[4]; - for (int i = 0; i < 4; i++) - out[i] = CreateTestClient(external, external_addrs[i]); - - th_int.Start(); - th_ext.Start(); - - const char* buf = "filter_test"; - size_t len = strlen(buf); - - in->SendTo(buf, len, out[0]->address()); - SocketAddress trans_addr; - EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); - - out[1]->SendTo(buf, len, trans_addr); - EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len)); - - out[2]->SendTo(buf, len, trans_addr); - EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len)); - - out[3]->SendTo(buf, len, trans_addr); - EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len)); - - th_int.Stop(); - th_ext.Stop(); - - delete nat; - delete natsf; - delete in; - for (int i = 0; i < 4; i++) - delete out[i]; -} - -// Tests that NATServer allocates bindings properly. -void TestBindings( - SocketServer* internal, const SocketAddress& internal_addr, - SocketServer* external, const SocketAddress external_addrs[4]) { - TestSend(internal, internal_addr, external, external_addrs, - NAT_OPEN_CONE, true); - TestSend(internal, internal_addr, external, external_addrs, - NAT_ADDR_RESTRICTED, true); - TestSend(internal, internal_addr, external, external_addrs, - NAT_PORT_RESTRICTED, true); - TestSend(internal, internal_addr, external, external_addrs, - NAT_SYMMETRIC, false); -} - -// Tests that NATServer filters packets properly. -void TestFilters( - SocketServer* internal, const SocketAddress& internal_addr, - SocketServer* external, const SocketAddress external_addrs[4]) { - TestRecv(internal, internal_addr, external, external_addrs, - NAT_OPEN_CONE, false, false); - TestRecv(internal, internal_addr, external, external_addrs, - NAT_ADDR_RESTRICTED, true, false); - TestRecv(internal, internal_addr, external, external_addrs, - NAT_PORT_RESTRICTED, true, true); - TestRecv(internal, internal_addr, external, external_addrs, - NAT_SYMMETRIC, true, true); -} - -bool TestConnectivity(const SocketAddress& src, const IPAddress& dst) { - // The physical NAT tests require connectivity to the selected ip from the - // internal address used for the NAT. Things like firewalls can break that, so - // check to see if it's worth even trying with this ip. - scoped_ptr pss(new PhysicalSocketServer()); - scoped_ptr client(pss->CreateAsyncSocket(src.family(), - SOCK_DGRAM)); - scoped_ptr server(pss->CreateAsyncSocket(src.family(), - SOCK_DGRAM)); - if (client->Bind(SocketAddress(src.ipaddr(), 0)) != 0 || - server->Bind(SocketAddress(dst, 0)) != 0) { - return false; - } - const char* buf = "hello other socket"; - size_t len = strlen(buf); - int sent = client->SendTo(buf, len, server->GetLocalAddress()); - SocketAddress addr; - const size_t kRecvBufSize = 64; - char recvbuf[kRecvBufSize]; - Thread::Current()->SleepMs(100); - int received = server->RecvFrom(recvbuf, kRecvBufSize, &addr); - return received == sent && ::memcmp(buf, recvbuf, len) == 0; -} - -void TestPhysicalInternal(const SocketAddress& int_addr) { - BasicNetworkManager network_manager; - network_manager.set_ipv6_enabled(true); - network_manager.StartUpdating(); - // Process pending messages so the network list is updated. - Thread::Current()->ProcessMessages(0); - - std::vector networks; - network_manager.GetNetworks(&networks); - if (networks.empty()) { - LOG(LS_WARNING) << "Not enough network adapters for test."; - return; - } - - SocketAddress ext_addr1(int_addr); - SocketAddress ext_addr2; - // Find an available IP with matching family. The test breaks if int_addr - // can't talk to ip, so check for connectivity as well. - for (std::vector::iterator it = networks.begin(); - it != networks.end(); ++it) { - const IPAddress& ip = (*it)->ip(); - if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) { - ext_addr2.SetIP(ip); - break; - } - } - if (ext_addr2.IsNil()) { - LOG(LS_WARNING) << "No available IP of same family as " << int_addr; - return; - } - - LOG(LS_INFO) << "selected ip " << ext_addr2.ipaddr(); - - SocketAddress ext_addrs[4] = { - SocketAddress(ext_addr1), - SocketAddress(ext_addr2), - SocketAddress(ext_addr1), - SocketAddress(ext_addr2) - }; - - scoped_ptr int_pss(new PhysicalSocketServer()); - scoped_ptr ext_pss(new PhysicalSocketServer()); - - TestBindings(int_pss.get(), int_addr, ext_pss.get(), ext_addrs); - TestFilters(int_pss.get(), int_addr, ext_pss.get(), ext_addrs); -} - -TEST(NatTest, TestPhysicalIPv4) { - TestPhysicalInternal(SocketAddress("127.0.0.1", 0)); -} - -TEST(NatTest, TestPhysicalIPv6) { - if (HasIPv6Enabled()) { - TestPhysicalInternal(SocketAddress("::1", 0)); - } else { - LOG(LS_WARNING) << "No IPv6, skipping"; - } -} - -class TestVirtualSocketServer : public VirtualSocketServer { - public: - explicit TestVirtualSocketServer(SocketServer* ss) - : VirtualSocketServer(ss), - ss_(ss) {} - // Expose this publicly - IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); } - - private: - scoped_ptr ss_; -}; - -void TestVirtualInternal(int family) { - scoped_ptr int_vss(new TestVirtualSocketServer( - new PhysicalSocketServer())); - scoped_ptr ext_vss(new TestVirtualSocketServer( - new PhysicalSocketServer())); - - SocketAddress int_addr; - SocketAddress ext_addrs[4]; - int_addr.SetIP(int_vss->GetNextIP(family)); - ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.family())); - ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.family())); - ext_addrs[2].SetIP(ext_addrs[0].ipaddr()); - ext_addrs[3].SetIP(ext_addrs[1].ipaddr()); - - TestBindings(int_vss.get(), int_addr, ext_vss.get(), ext_addrs); - TestFilters(int_vss.get(), int_addr, ext_vss.get(), ext_addrs); -} - -TEST(NatTest, TestVirtualIPv4) { - TestVirtualInternal(AF_INET); -} - -TEST(NatTest, TestVirtualIPv6) { - if (HasIPv6Enabled()) { - TestVirtualInternal(AF_INET6); - } else { - LOG(LS_WARNING) << "No IPv6, skipping"; - } -} - -// TODO: Finish this test -class NatTcpTest : public testing::Test, public sigslot::has_slots<> { - public: - NatTcpTest() : connected_(false) {} - virtual void SetUp() { - int_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer()); - ext_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer()); - nat_ = new NATServer(NAT_OPEN_CONE, int_vss_, SocketAddress(), - ext_vss_, SocketAddress()); - natsf_ = new NATSocketFactory(int_vss_, nat_->internal_address()); - } - void OnConnectEvent(AsyncSocket* socket) { - connected_ = true; - } - void OnAcceptEvent(AsyncSocket* socket) { - accepted_ = server_->Accept(NULL); - } - void OnCloseEvent(AsyncSocket* socket, int error) { - } - void ConnectEvents() { - server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent); - client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent); - } - TestVirtualSocketServer* int_vss_; - TestVirtualSocketServer* ext_vss_; - NATServer* nat_; - NATSocketFactory* natsf_; - AsyncSocket* client_; - AsyncSocket* server_; - AsyncSocket* accepted_; - bool connected_; -}; - -TEST_F(NatTcpTest, DISABLED_TestConnectOut) { - server_ = ext_vss_->CreateAsyncSocket(SOCK_STREAM); - server_->Bind(SocketAddress()); - server_->Listen(5); - - client_ = int_vss_->CreateAsyncSocket(SOCK_STREAM); - EXPECT_GE(0, client_->Bind(SocketAddress())); - EXPECT_GE(0, client_->Connect(server_->GetLocalAddress())); - - - ConnectEvents(); - - EXPECT_TRUE_WAIT(connected_, 1000); - EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress()); - EXPECT_EQ(client_->GetRemoteAddress(), accepted_->GetLocalAddress()); - EXPECT_EQ(client_->GetLocalAddress(), accepted_->GetRemoteAddress()); - - client_->Close(); -} -//#endif diff --git a/webrtc/base/natserver.cc b/webrtc/base/natserver.cc deleted file mode 100644 index 0ce04d70b..000000000 --- a/webrtc/base/natserver.cc +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/natsocketfactory.h" -#include "webrtc/base/natserver.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -RouteCmp::RouteCmp(NAT* nat) : symmetric(nat->IsSymmetric()) { -} - -size_t RouteCmp::operator()(const SocketAddressPair& r) const { - size_t h = r.source().Hash(); - if (symmetric) - h ^= r.destination().Hash(); - return h; -} - -bool RouteCmp::operator()( - const SocketAddressPair& r1, const SocketAddressPair& r2) const { - if (r1.source() < r2.source()) - return true; - if (r2.source() < r1.source()) - return false; - if (symmetric && (r1.destination() < r2.destination())) - return true; - if (symmetric && (r2.destination() < r1.destination())) - return false; - return false; -} - -AddrCmp::AddrCmp(NAT* nat) - : use_ip(nat->FiltersIP()), use_port(nat->FiltersPort()) { -} - -size_t AddrCmp::operator()(const SocketAddress& a) const { - size_t h = 0; - if (use_ip) - h ^= HashIP(a.ipaddr()); - if (use_port) - h ^= a.port() | (a.port() << 16); - return h; -} - -bool AddrCmp::operator()( - const SocketAddress& a1, const SocketAddress& a2) const { - if (use_ip && (a1.ipaddr() < a2.ipaddr())) - return true; - if (use_ip && (a2.ipaddr() < a1.ipaddr())) - return false; - if (use_port && (a1.port() < a2.port())) - return true; - if (use_port && (a2.port() < a1.port())) - return false; - return false; -} - -NATServer::NATServer( - NATType type, SocketFactory* internal, const SocketAddress& internal_addr, - SocketFactory* external, const SocketAddress& external_ip) - : external_(external), external_ip_(external_ip.ipaddr(), 0) { - nat_ = NAT::Create(type); - - server_socket_ = AsyncUDPSocket::Create(internal, internal_addr); - server_socket_->SignalReadPacket.connect(this, &NATServer::OnInternalPacket); - - int_map_ = new InternalMap(RouteCmp(nat_)); - ext_map_ = new ExternalMap(); -} - -NATServer::~NATServer() { - for (InternalMap::iterator iter = int_map_->begin(); - iter != int_map_->end(); - iter++) - delete iter->second; - - delete nat_; - delete server_socket_; - delete int_map_; - delete ext_map_; -} - -void NATServer::OnInternalPacket( - AsyncPacketSocket* socket, const char* buf, size_t size, - const SocketAddress& addr, const PacketTime& packet_time) { - - // Read the intended destination from the wire. - SocketAddress dest_addr; - size_t length = UnpackAddressFromNAT(buf, size, &dest_addr); - - // Find the translation for these addresses (allocating one if necessary). - SocketAddressPair route(addr, dest_addr); - InternalMap::iterator iter = int_map_->find(route); - if (iter == int_map_->end()) { - Translate(route); - iter = int_map_->find(route); - } - ASSERT(iter != int_map_->end()); - - // Allow the destination to send packets back to the source. - iter->second->WhitelistInsert(dest_addr); - - // Send the packet to its intended destination. - rtc::PacketOptions options; - iter->second->socket->SendTo(buf + length, size - length, dest_addr, options); -} - -void NATServer::OnExternalPacket( - AsyncPacketSocket* socket, const char* buf, size_t size, - const SocketAddress& remote_addr, const PacketTime& packet_time) { - - SocketAddress local_addr = socket->GetLocalAddress(); - - // Find the translation for this addresses. - ExternalMap::iterator iter = ext_map_->find(local_addr); - ASSERT(iter != ext_map_->end()); - - // Allow the NAT to reject this packet. - if (ShouldFilterOut(iter->second, remote_addr)) { - LOG(LS_INFO) << "Packet from " << remote_addr.ToSensitiveString() - << " was filtered out by the NAT."; - return; - } - - // Forward this packet to the internal address. - // First prepend the address in a quasi-STUN format. - scoped_ptr real_buf(new char[size + kNATEncodedIPv6AddressSize]); - size_t addrlength = PackAddressForNAT(real_buf.get(), - size + kNATEncodedIPv6AddressSize, - remote_addr); - // Copy the data part after the address. - rtc::PacketOptions options; - memcpy(real_buf.get() + addrlength, buf, size); - server_socket_->SendTo(real_buf.get(), size + addrlength, - iter->second->route.source(), options); -} - -void NATServer::Translate(const SocketAddressPair& route) { - AsyncUDPSocket* socket = AsyncUDPSocket::Create(external_, external_ip_); - - if (!socket) { - LOG(LS_ERROR) << "Couldn't find a free port!"; - return; - } - - TransEntry* entry = new TransEntry(route, socket, nat_); - (*int_map_)[route] = entry; - (*ext_map_)[socket->GetLocalAddress()] = entry; - socket->SignalReadPacket.connect(this, &NATServer::OnExternalPacket); -} - -bool NATServer::ShouldFilterOut(TransEntry* entry, - const SocketAddress& ext_addr) { - return entry->WhitelistContains(ext_addr); -} - -NATServer::TransEntry::TransEntry( - const SocketAddressPair& r, AsyncUDPSocket* s, NAT* nat) - : route(r), socket(s) { - whitelist = new AddressSet(AddrCmp(nat)); -} - -NATServer::TransEntry::~TransEntry() { - delete whitelist; - delete socket; -} - -void NATServer::TransEntry::WhitelistInsert(const SocketAddress& addr) { - CritScope cs(&crit_); - whitelist->insert(addr); -} - -bool NATServer::TransEntry::WhitelistContains(const SocketAddress& ext_addr) { - CritScope cs(&crit_); - return whitelist->find(ext_addr) == whitelist->end(); -} - -} // namespace rtc diff --git a/webrtc/base/natserver.h b/webrtc/base/natserver.h deleted file mode 100644 index 1db77dacf..000000000 --- a/webrtc/base/natserver.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NATSERVER_H_ -#define WEBRTC_BASE_NATSERVER_H_ - -#include -#include - -#include "webrtc/base/asyncudpsocket.h" -#include "webrtc/base/socketaddresspair.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/socketfactory.h" -#include "webrtc/base/nattypes.h" - -namespace rtc { - -// Change how routes (socketaddress pairs) are compared based on the type of -// NAT. The NAT server maintains a hashtable of the routes that it knows -// about. So these affect which routes are treated the same. -struct RouteCmp { - explicit RouteCmp(NAT* nat); - size_t operator()(const SocketAddressPair& r) const; - bool operator()( - const SocketAddressPair& r1, const SocketAddressPair& r2) const; - - bool symmetric; -}; - -// Changes how addresses are compared based on the filtering rules of the NAT. -struct AddrCmp { - explicit AddrCmp(NAT* nat); - size_t operator()(const SocketAddress& r) const; - bool operator()(const SocketAddress& r1, const SocketAddress& r2) const; - - bool use_ip; - bool use_port; -}; - -// Implements the NAT device. It listens for packets on the internal network, -// translates them, and sends them out over the external network. - -const int NAT_SERVER_PORT = 4237; - -class NATServer : public sigslot::has_slots<> { - public: - NATServer( - NATType type, SocketFactory* internal, const SocketAddress& internal_addr, - SocketFactory* external, const SocketAddress& external_ip); - ~NATServer(); - - SocketAddress internal_address() const { - return server_socket_->GetLocalAddress(); - } - - // Packets received on one of the networks. - void OnInternalPacket(AsyncPacketSocket* socket, const char* buf, - size_t size, const SocketAddress& addr, - const PacketTime& packet_time); - void OnExternalPacket(AsyncPacketSocket* socket, const char* buf, - size_t size, const SocketAddress& remote_addr, - const PacketTime& packet_time); - - private: - typedef std::set AddressSet; - - /* Records a translation and the associated external socket. */ - struct TransEntry { - TransEntry(const SocketAddressPair& r, AsyncUDPSocket* s, NAT* nat); - ~TransEntry(); - - void WhitelistInsert(const SocketAddress& addr); - bool WhitelistContains(const SocketAddress& ext_addr); - - SocketAddressPair route; - AsyncUDPSocket* socket; - AddressSet* whitelist; - CriticalSection crit_; - }; - - typedef std::map InternalMap; - typedef std::map ExternalMap; - - /* Creates a new entry that translates the given route. */ - void Translate(const SocketAddressPair& route); - - /* Determines whether the NAT would filter out a packet from this address. */ - bool ShouldFilterOut(TransEntry* entry, const SocketAddress& ext_addr); - - NAT* nat_; - SocketFactory* internal_; - SocketFactory* external_; - SocketAddress external_ip_; - AsyncUDPSocket* server_socket_; - AsyncSocket* tcp_server_socket_; - InternalMap* int_map_; - ExternalMap* ext_map_; - DISALLOW_EVIL_CONSTRUCTORS(NATServer); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_NATSERVER_H_ diff --git a/webrtc/base/natserver_main.cc b/webrtc/base/natserver_main.cc deleted file mode 100644 index 3ad2113a6..000000000 --- a/webrtc/base/natserver_main.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/natserver.h" -#include "webrtc/base/host.h" -#include "webrtc/base/physicalsocketserver.h" - -using namespace rtc; - -int main(int argc, char* argv[]) { - if (argc != 3) { - std::cerr << "usage: natserver " << std::endl; - exit(1); - } - - SocketAddress internal = SocketAddress(argv[1]); - SocketAddress external = SocketAddress(argv[2]); - if (internal.EqualIPs(external)) { - std::cerr << "internal and external IPs must differ" << std::endl; - exit(1); - } - - Thread* pthMain = Thread::Current(); - PhysicalSocketServer* ss = new PhysicalSocketServer(); - pthMain->set_socketserver(ss); - NATServer* server = new NATServer(NAT_OPEN_CONE, ss, internal, ss, external); - server = server; - - pthMain->Run(); - return 0; -} diff --git a/webrtc/base/natsocketfactory.cc b/webrtc/base/natsocketfactory.cc deleted file mode 100644 index b5ae67b25..000000000 --- a/webrtc/base/natsocketfactory.cc +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/natsocketfactory.h" - -#include "webrtc/base/logging.h" -#include "webrtc/base/natserver.h" -#include "webrtc/base/virtualsocketserver.h" - -namespace rtc { - -// Packs the given socketaddress into the buffer in buf, in the quasi-STUN -// format that the natserver uses. -// Returns 0 if an invalid address is passed. -size_t PackAddressForNAT(char* buf, size_t buf_size, - const SocketAddress& remote_addr) { - const IPAddress& ip = remote_addr.ipaddr(); - int family = ip.family(); - buf[0] = 0; - buf[1] = family; - // Writes the port. - *(reinterpret_cast(&buf[2])) = HostToNetwork16(remote_addr.port()); - if (family == AF_INET) { - ASSERT(buf_size >= kNATEncodedIPv4AddressSize); - in_addr v4addr = ip.ipv4_address(); - memcpy(&buf[4], &v4addr, kNATEncodedIPv4AddressSize - 4); - return kNATEncodedIPv4AddressSize; - } else if (family == AF_INET6) { - ASSERT(buf_size >= kNATEncodedIPv6AddressSize); - in6_addr v6addr = ip.ipv6_address(); - memcpy(&buf[4], &v6addr, kNATEncodedIPv6AddressSize - 4); - return kNATEncodedIPv6AddressSize; - } - return 0U; -} - -// Decodes the remote address from a packet that has been encoded with the nat's -// quasi-STUN format. Returns the length of the address (i.e., the offset into -// data where the original packet starts). -size_t UnpackAddressFromNAT(const char* buf, size_t buf_size, - SocketAddress* remote_addr) { - ASSERT(buf_size >= 8); - ASSERT(buf[0] == 0); - int family = buf[1]; - uint16 port = NetworkToHost16(*(reinterpret_cast(&buf[2]))); - if (family == AF_INET) { - const in_addr* v4addr = reinterpret_cast(&buf[4]); - *remote_addr = SocketAddress(IPAddress(*v4addr), port); - return kNATEncodedIPv4AddressSize; - } else if (family == AF_INET6) { - ASSERT(buf_size >= 20); - const in6_addr* v6addr = reinterpret_cast(&buf[4]); - *remote_addr = SocketAddress(IPAddress(*v6addr), port); - return kNATEncodedIPv6AddressSize; - } - return 0U; -} - - -// NATSocket -class NATSocket : public AsyncSocket, public sigslot::has_slots<> { - public: - explicit NATSocket(NATInternalSocketFactory* sf, int family, int type) - : sf_(sf), family_(family), type_(type), connected_(false), - socket_(NULL), buf_(NULL), size_(0) { - } - - virtual ~NATSocket() { - delete socket_; - delete[] buf_; - } - - virtual SocketAddress GetLocalAddress() const { - return (socket_) ? socket_->GetLocalAddress() : SocketAddress(); - } - - virtual SocketAddress GetRemoteAddress() const { - return remote_addr_; // will be NIL if not connected - } - - virtual int Bind(const SocketAddress& addr) { - if (socket_) { // already bound, bubble up error - return -1; - } - - int result; - socket_ = sf_->CreateInternalSocket(family_, type_, addr, &server_addr_); - result = (socket_) ? socket_->Bind(addr) : -1; - if (result >= 0) { - socket_->SignalConnectEvent.connect(this, &NATSocket::OnConnectEvent); - socket_->SignalReadEvent.connect(this, &NATSocket::OnReadEvent); - socket_->SignalWriteEvent.connect(this, &NATSocket::OnWriteEvent); - socket_->SignalCloseEvent.connect(this, &NATSocket::OnCloseEvent); - } else { - server_addr_.Clear(); - delete socket_; - socket_ = NULL; - } - - return result; - } - - virtual int Connect(const SocketAddress& addr) { - if (!socket_) { // socket must be bound, for now - return -1; - } - - int result = 0; - if (type_ == SOCK_STREAM) { - result = socket_->Connect(server_addr_.IsNil() ? addr : server_addr_); - } else { - connected_ = true; - } - - if (result >= 0) { - remote_addr_ = addr; - } - - return result; - } - - virtual int Send(const void* data, size_t size) { - ASSERT(connected_); - return SendTo(data, size, remote_addr_); - } - - virtual int SendTo(const void* data, size_t size, const SocketAddress& addr) { - ASSERT(!connected_ || addr == remote_addr_); - if (server_addr_.IsNil() || type_ == SOCK_STREAM) { - return socket_->SendTo(data, size, addr); - } - // This array will be too large for IPv4 packets, but only by 12 bytes. - scoped_ptr buf(new char[size + kNATEncodedIPv6AddressSize]); - size_t addrlength = PackAddressForNAT(buf.get(), - size + kNATEncodedIPv6AddressSize, - addr); - size_t encoded_size = size + addrlength; - memcpy(buf.get() + addrlength, data, size); - int result = socket_->SendTo(buf.get(), encoded_size, server_addr_); - if (result >= 0) { - ASSERT(result == static_cast(encoded_size)); - result = result - static_cast(addrlength); - } - return result; - } - - virtual int Recv(void* data, size_t size) { - SocketAddress addr; - return RecvFrom(data, size, &addr); - } - - virtual int RecvFrom(void* data, size_t size, SocketAddress *out_addr) { - if (server_addr_.IsNil() || type_ == SOCK_STREAM) { - return socket_->RecvFrom(data, size, out_addr); - } - // Make sure we have enough room to read the requested amount plus the - // largest possible header address. - SocketAddress remote_addr; - Grow(size + kNATEncodedIPv6AddressSize); - - // Read the packet from the socket. - int result = socket_->RecvFrom(buf_, size_, &remote_addr); - if (result >= 0) { - ASSERT(remote_addr == server_addr_); - - // TODO: we need better framing so we know how many bytes we can - // return before we need to read the next address. For UDP, this will be - // fine as long as the reader always reads everything in the packet. - ASSERT((size_t)result < size_); - - // Decode the wire packet into the actual results. - SocketAddress real_remote_addr; - size_t addrlength = - UnpackAddressFromNAT(buf_, result, &real_remote_addr); - memcpy(data, buf_ + addrlength, result - addrlength); - - // Make sure this packet should be delivered before returning it. - if (!connected_ || (real_remote_addr == remote_addr_)) { - if (out_addr) - *out_addr = real_remote_addr; - result = result - static_cast(addrlength); - } else { - LOG(LS_ERROR) << "Dropping packet from unknown remote address: " - << real_remote_addr.ToString(); - result = 0; // Tell the caller we didn't read anything - } - } - - return result; - } - - virtual int Close() { - int result = 0; - if (socket_) { - result = socket_->Close(); - if (result >= 0) { - connected_ = false; - remote_addr_ = SocketAddress(); - delete socket_; - socket_ = NULL; - } - } - return result; - } - - virtual int Listen(int backlog) { - return socket_->Listen(backlog); - } - virtual AsyncSocket* Accept(SocketAddress *paddr) { - return socket_->Accept(paddr); - } - virtual int GetError() const { - return socket_->GetError(); - } - virtual void SetError(int error) { - socket_->SetError(error); - } - virtual ConnState GetState() const { - return connected_ ? CS_CONNECTED : CS_CLOSED; - } - virtual int EstimateMTU(uint16* mtu) { - return socket_->EstimateMTU(mtu); - } - virtual int GetOption(Option opt, int* value) { - return socket_->GetOption(opt, value); - } - virtual int SetOption(Option opt, int value) { - return socket_->SetOption(opt, value); - } - - void OnConnectEvent(AsyncSocket* socket) { - // If we're NATed, we need to send a request with the real addr to use. - ASSERT(socket == socket_); - if (server_addr_.IsNil()) { - connected_ = true; - SignalConnectEvent(this); - } else { - SendConnectRequest(); - } - } - void OnReadEvent(AsyncSocket* socket) { - // If we're NATed, we need to process the connect reply. - ASSERT(socket == socket_); - if (type_ == SOCK_STREAM && !server_addr_.IsNil() && !connected_) { - HandleConnectReply(); - } else { - SignalReadEvent(this); - } - } - void OnWriteEvent(AsyncSocket* socket) { - ASSERT(socket == socket_); - SignalWriteEvent(this); - } - void OnCloseEvent(AsyncSocket* socket, int error) { - ASSERT(socket == socket_); - SignalCloseEvent(this, error); - } - - private: - // Makes sure the buffer is at least the given size. - void Grow(size_t new_size) { - if (size_ < new_size) { - delete[] buf_; - size_ = new_size; - buf_ = new char[size_]; - } - } - - // Sends the destination address to the server to tell it to connect. - void SendConnectRequest() { - char buf[256]; - size_t length = PackAddressForNAT(buf, ARRAY_SIZE(buf), remote_addr_); - socket_->Send(buf, length); - } - - // Handles the byte sent back from the server and fires the appropriate event. - void HandleConnectReply() { - char code; - socket_->Recv(&code, sizeof(code)); - if (code == 0) { - SignalConnectEvent(this); - } else { - Close(); - SignalCloseEvent(this, code); - } - } - - NATInternalSocketFactory* sf_; - int family_; - int type_; - bool connected_; - SocketAddress remote_addr_; - SocketAddress server_addr_; // address of the NAT server - AsyncSocket* socket_; - char* buf_; - size_t size_; -}; - -// NATSocketFactory -NATSocketFactory::NATSocketFactory(SocketFactory* factory, - const SocketAddress& nat_addr) - : factory_(factory), nat_addr_(nat_addr) { -} - -Socket* NATSocketFactory::CreateSocket(int type) { - return CreateSocket(AF_INET, type); -} - -Socket* NATSocketFactory::CreateSocket(int family, int type) { - return new NATSocket(this, family, type); -} - -AsyncSocket* NATSocketFactory::CreateAsyncSocket(int type) { - return CreateAsyncSocket(AF_INET, type); -} - -AsyncSocket* NATSocketFactory::CreateAsyncSocket(int family, int type) { - return new NATSocket(this, family, type); -} - -AsyncSocket* NATSocketFactory::CreateInternalSocket(int family, int type, - const SocketAddress& local_addr, SocketAddress* nat_addr) { - *nat_addr = nat_addr_; - return factory_->CreateAsyncSocket(family, type); -} - -// NATSocketServer -NATSocketServer::NATSocketServer(SocketServer* server) - : server_(server), msg_queue_(NULL) { -} - -NATSocketServer::Translator* NATSocketServer::GetTranslator( - const SocketAddress& ext_ip) { - return nats_.Get(ext_ip); -} - -NATSocketServer::Translator* NATSocketServer::AddTranslator( - const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) { - // Fail if a translator already exists with this extternal address. - if (nats_.Get(ext_ip)) - return NULL; - - return nats_.Add(ext_ip, new Translator(this, type, int_ip, server_, ext_ip)); -} - -void NATSocketServer::RemoveTranslator( - const SocketAddress& ext_ip) { - nats_.Remove(ext_ip); -} - -Socket* NATSocketServer::CreateSocket(int type) { - return CreateSocket(AF_INET, type); -} - -Socket* NATSocketServer::CreateSocket(int family, int type) { - return new NATSocket(this, family, type); -} - -AsyncSocket* NATSocketServer::CreateAsyncSocket(int type) { - return CreateAsyncSocket(AF_INET, type); -} - -AsyncSocket* NATSocketServer::CreateAsyncSocket(int family, int type) { - return new NATSocket(this, family, type); -} - -AsyncSocket* NATSocketServer::CreateInternalSocket(int family, int type, - const SocketAddress& local_addr, SocketAddress* nat_addr) { - AsyncSocket* socket = NULL; - Translator* nat = nats_.FindClient(local_addr); - if (nat) { - socket = nat->internal_factory()->CreateAsyncSocket(family, type); - *nat_addr = (type == SOCK_STREAM) ? - nat->internal_tcp_address() : nat->internal_address(); - } else { - socket = server_->CreateAsyncSocket(family, type); - } - return socket; -} - -// NATSocketServer::Translator -NATSocketServer::Translator::Translator( - NATSocketServer* server, NATType type, const SocketAddress& int_ip, - SocketFactory* ext_factory, const SocketAddress& ext_ip) - : server_(server) { - // Create a new private network, and a NATServer running on the private - // network that bridges to the external network. Also tell the private - // network to use the same message queue as us. - VirtualSocketServer* internal_server = new VirtualSocketServer(server_); - internal_server->SetMessageQueue(server_->queue()); - internal_factory_.reset(internal_server); - nat_server_.reset(new NATServer(type, internal_server, int_ip, - ext_factory, ext_ip)); -} - - -NATSocketServer::Translator* NATSocketServer::Translator::GetTranslator( - const SocketAddress& ext_ip) { - return nats_.Get(ext_ip); -} - -NATSocketServer::Translator* NATSocketServer::Translator::AddTranslator( - const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) { - // Fail if a translator already exists with this extternal address. - if (nats_.Get(ext_ip)) - return NULL; - - AddClient(ext_ip); - return nats_.Add(ext_ip, - new Translator(server_, type, int_ip, server_, ext_ip)); -} -void NATSocketServer::Translator::RemoveTranslator( - const SocketAddress& ext_ip) { - nats_.Remove(ext_ip); - RemoveClient(ext_ip); -} - -bool NATSocketServer::Translator::AddClient( - const SocketAddress& int_ip) { - // Fail if a client already exists with this internal address. - if (clients_.find(int_ip) != clients_.end()) - return false; - - clients_.insert(int_ip); - return true; -} - -void NATSocketServer::Translator::RemoveClient( - const SocketAddress& int_ip) { - std::set::iterator it = clients_.find(int_ip); - if (it != clients_.end()) { - clients_.erase(it); - } -} - -NATSocketServer::Translator* NATSocketServer::Translator::FindClient( - const SocketAddress& int_ip) { - // See if we have the requested IP, or any of our children do. - return (clients_.find(int_ip) != clients_.end()) ? - this : nats_.FindClient(int_ip); -} - -// NATSocketServer::TranslatorMap -NATSocketServer::TranslatorMap::~TranslatorMap() { - for (TranslatorMap::iterator it = begin(); it != end(); ++it) { - delete it->second; - } -} - -NATSocketServer::Translator* NATSocketServer::TranslatorMap::Get( - const SocketAddress& ext_ip) { - TranslatorMap::iterator it = find(ext_ip); - return (it != end()) ? it->second : NULL; -} - -NATSocketServer::Translator* NATSocketServer::TranslatorMap::Add( - const SocketAddress& ext_ip, Translator* nat) { - (*this)[ext_ip] = nat; - return nat; -} - -void NATSocketServer::TranslatorMap::Remove( - const SocketAddress& ext_ip) { - TranslatorMap::iterator it = find(ext_ip); - if (it != end()) { - delete it->second; - erase(it); - } -} - -NATSocketServer::Translator* NATSocketServer::TranslatorMap::FindClient( - const SocketAddress& int_ip) { - Translator* nat = NULL; - for (TranslatorMap::iterator it = begin(); it != end() && !nat; ++it) { - nat = it->second->FindClient(int_ip); - } - return nat; -} - -} // namespace rtc diff --git a/webrtc/base/natsocketfactory.h b/webrtc/base/natsocketfactory.h deleted file mode 100644 index 6a8e20fe1..000000000 --- a/webrtc/base/natsocketfactory.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NATSOCKETFACTORY_H_ -#define WEBRTC_BASE_NATSOCKETFACTORY_H_ - -#include -#include -#include - -#include "webrtc/base/natserver.h" -#include "webrtc/base/socketaddress.h" -#include "webrtc/base/socketserver.h" - -namespace rtc { - -const size_t kNATEncodedIPv4AddressSize = 8U; -const size_t kNATEncodedIPv6AddressSize = 20U; - -// Used by the NAT socket implementation. -class NATInternalSocketFactory { - public: - virtual ~NATInternalSocketFactory() {} - virtual AsyncSocket* CreateInternalSocket(int family, int type, - const SocketAddress& local_addr, SocketAddress* nat_addr) = 0; -}; - -// Creates sockets that will send all traffic through a NAT, using an existing -// NATServer instance running at nat_addr. The actual data is sent using sockets -// from a socket factory, given to the constructor. -class NATSocketFactory : public SocketFactory, public NATInternalSocketFactory { - public: - NATSocketFactory(SocketFactory* factory, const SocketAddress& nat_addr); - - // SocketFactory implementation - virtual Socket* CreateSocket(int type); - virtual Socket* CreateSocket(int family, int type); - virtual AsyncSocket* CreateAsyncSocket(int type); - virtual AsyncSocket* CreateAsyncSocket(int family, int type); - - // NATInternalSocketFactory implementation - virtual AsyncSocket* CreateInternalSocket(int family, int type, - const SocketAddress& local_addr, SocketAddress* nat_addr); - - private: - SocketFactory* factory_; - SocketAddress nat_addr_; - DISALLOW_EVIL_CONSTRUCTORS(NATSocketFactory); -}; - -// Creates sockets that will send traffic through a NAT depending on what -// address they bind to. This can be used to simulate a client on a NAT sending -// to a client that is not behind a NAT. -// Note that the internal addresses of clients must be unique. This is because -// there is only one socketserver per thread, and the Bind() address is used to -// figure out which NAT (if any) the socket should talk to. -// -// Example with 3 NATs (2 cascaded), and 3 clients. -// ss->AddTranslator("1.2.3.4", "192.168.0.1", NAT_ADDR_RESTRICTED); -// ss->AddTranslator("99.99.99.99", "10.0.0.1", NAT_SYMMETRIC)-> -// AddTranslator("10.0.0.2", "192.168.1.1", NAT_OPEN_CONE); -// ss->GetTranslator("1.2.3.4")->AddClient("1.2.3.4", "192.168.0.2"); -// ss->GetTranslator("99.99.99.99")->AddClient("10.0.0.3"); -// ss->GetTranslator("99.99.99.99")->GetTranslator("10.0.0.2")-> -// AddClient("192.168.1.2"); -class NATSocketServer : public SocketServer, public NATInternalSocketFactory { - public: - class Translator; - // holds a list of NATs - class TranslatorMap : private std::map { - public: - ~TranslatorMap(); - Translator* Get(const SocketAddress& ext_ip); - Translator* Add(const SocketAddress& ext_ip, Translator*); - void Remove(const SocketAddress& ext_ip); - Translator* FindClient(const SocketAddress& int_ip); - }; - - // a specific NAT - class Translator { - public: - Translator(NATSocketServer* server, NATType type, - const SocketAddress& int_addr, SocketFactory* ext_factory, - const SocketAddress& ext_addr); - - SocketFactory* internal_factory() { return internal_factory_.get(); } - SocketAddress internal_address() const { - return nat_server_->internal_address(); - } - SocketAddress internal_tcp_address() const { - return SocketAddress(); // nat_server_->internal_tcp_address(); - } - - Translator* GetTranslator(const SocketAddress& ext_ip); - Translator* AddTranslator(const SocketAddress& ext_ip, - const SocketAddress& int_ip, NATType type); - void RemoveTranslator(const SocketAddress& ext_ip); - - bool AddClient(const SocketAddress& int_ip); - void RemoveClient(const SocketAddress& int_ip); - - // Looks for the specified client in this or a child NAT. - Translator* FindClient(const SocketAddress& int_ip); - - private: - NATSocketServer* server_; - scoped_ptr internal_factory_; - scoped_ptr nat_server_; - TranslatorMap nats_; - std::set clients_; - }; - - explicit NATSocketServer(SocketServer* ss); - - SocketServer* socketserver() { return server_; } - MessageQueue* queue() { return msg_queue_; } - - Translator* GetTranslator(const SocketAddress& ext_ip); - Translator* AddTranslator(const SocketAddress& ext_ip, - const SocketAddress& int_ip, NATType type); - void RemoveTranslator(const SocketAddress& ext_ip); - - // SocketServer implementation - virtual Socket* CreateSocket(int type); - virtual Socket* CreateSocket(int family, int type); - - virtual AsyncSocket* CreateAsyncSocket(int type); - virtual AsyncSocket* CreateAsyncSocket(int family, int type); - - virtual void SetMessageQueue(MessageQueue* queue) { - msg_queue_ = queue; - server_->SetMessageQueue(queue); - } - virtual bool Wait(int cms, bool process_io) { - return server_->Wait(cms, process_io); - } - virtual void WakeUp() { - server_->WakeUp(); - } - - // NATInternalSocketFactory implementation - virtual AsyncSocket* CreateInternalSocket(int family, int type, - const SocketAddress& local_addr, SocketAddress* nat_addr); - - private: - SocketServer* server_; - MessageQueue* msg_queue_; - TranslatorMap nats_; - DISALLOW_EVIL_CONSTRUCTORS(NATSocketServer); -}; - -// Free-standing NAT helper functions. -size_t PackAddressForNAT(char* buf, size_t buf_size, - const SocketAddress& remote_addr); -size_t UnpackAddressFromNAT(const char* buf, size_t buf_size, - SocketAddress* remote_addr); -} // namespace rtc - -#endif // WEBRTC_BASE_NATSOCKETFACTORY_H_ diff --git a/webrtc/base/nattypes.cc b/webrtc/base/nattypes.cc deleted file mode 100644 index fedb78dc5..000000000 --- a/webrtc/base/nattypes.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/nattypes.h" - -namespace rtc { - -class SymmetricNAT : public NAT { -public: - bool IsSymmetric() { return true; } - bool FiltersIP() { return true; } - bool FiltersPort() { return true; } -}; - -class OpenConeNAT : public NAT { -public: - bool IsSymmetric() { return false; } - bool FiltersIP() { return false; } - bool FiltersPort() { return false; } -}; - -class AddressRestrictedNAT : public NAT { -public: - bool IsSymmetric() { return false; } - bool FiltersIP() { return true; } - bool FiltersPort() { return false; } -}; - -class PortRestrictedNAT : public NAT { -public: - bool IsSymmetric() { return false; } - bool FiltersIP() { return true; } - bool FiltersPort() { return true; } -}; - -NAT* NAT::Create(NATType type) { - switch (type) { - case NAT_OPEN_CONE: return new OpenConeNAT(); - case NAT_ADDR_RESTRICTED: return new AddressRestrictedNAT(); - case NAT_PORT_RESTRICTED: return new PortRestrictedNAT(); - case NAT_SYMMETRIC: return new SymmetricNAT(); - default: assert(0); return 0; - } -} - -} // namespace rtc diff --git a/webrtc/base/nattypes.h b/webrtc/base/nattypes.h deleted file mode 100644 index 27e4b2f45..000000000 --- a/webrtc/base/nattypes.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NATTYPE_H__ -#define WEBRTC_BASE_NATTYPE_H__ - -namespace rtc { - -/* Identifies each type of NAT that can be simulated. */ -enum NATType { - NAT_OPEN_CONE, - NAT_ADDR_RESTRICTED, - NAT_PORT_RESTRICTED, - NAT_SYMMETRIC -}; - -// Implements the rules for each specific type of NAT. -class NAT { -public: - virtual ~NAT() { } - - // Determines whether this NAT uses both source and destination address when - // checking whether a mapping already exists. - virtual bool IsSymmetric() = 0; - - // Determines whether this NAT drops packets received from a different IP - // the one last sent to. - virtual bool FiltersIP() = 0; - - // Determines whether this NAT drops packets received from a different port - // the one last sent to. - virtual bool FiltersPort() = 0; - - // Returns an implementation of the given type of NAT. - static NAT* Create(NATType type); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_NATTYPE_H__ diff --git a/webrtc/base/nethelpers.cc b/webrtc/base/nethelpers.cc deleted file mode 100644 index 5d4802dfd..000000000 --- a/webrtc/base/nethelpers.cc +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/nethelpers.h" - -#if defined(WEBRTC_WIN) -#include -#include -#include "webrtc/base/win32.h" -#endif - -#include "webrtc/base/byteorder.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/signalthread.h" - -namespace rtc { - -int ResolveHostname(const std::string& hostname, int family, - std::vector* addresses) { -#ifdef __native_client__ - ASSERT(false); - LOG(LS_WARNING) << "ResolveHostname() is not implemented for NaCl"; - return -1; -#else // __native_client__ - if (!addresses) { - return -1; - } - addresses->clear(); - struct addrinfo* result = NULL; - struct addrinfo hints = {0}; - // TODO(djw): For now this is IPv4 only so existing users remain unaffected. - hints.ai_family = AF_INET; - hints.ai_flags = AI_ADDRCONFIG; - int ret = getaddrinfo(hostname.c_str(), NULL, &hints, &result); - if (ret != 0) { - return ret; - } - struct addrinfo* cursor = result; - for (; cursor; cursor = cursor->ai_next) { - if (family == AF_UNSPEC || cursor->ai_family == family) { - IPAddress ip; - if (IPFromAddrInfo(cursor, &ip)) { - addresses->push_back(ip); - } - } - } - freeaddrinfo(result); - return 0; -#endif // !__native_client__ -} - -// AsyncResolver -AsyncResolver::AsyncResolver() : error_(-1) { -} - -void AsyncResolver::Start(const SocketAddress& addr) { - addr_ = addr; - // SignalThred Start will kickoff the resolve process. - SignalThread::Start(); -} - -bool AsyncResolver::GetResolvedAddress(int family, SocketAddress* addr) const { - if (error_ != 0 || addresses_.empty()) - return false; - - *addr = addr_; - for (size_t i = 0; i < addresses_.size(); ++i) { - if (family == addresses_[i].family()) { - addr->SetResolvedIP(addresses_[i]); - return true; - } - } - return false; -} - -void AsyncResolver::DoWork() { - error_ = ResolveHostname(addr_.hostname().c_str(), addr_.family(), - &addresses_); -} - -void AsyncResolver::OnWorkDone() { - SignalDone(this); -} - -const char* inet_ntop(int af, const void *src, char* dst, socklen_t size) { -#if defined(WEBRTC_WIN) - return win32_inet_ntop(af, src, dst, size); -#else - return ::inet_ntop(af, src, dst, size); -#endif -} - -int inet_pton(int af, const char* src, void *dst) { -#if defined(WEBRTC_WIN) - return win32_inet_pton(af, src, dst); -#else - return ::inet_pton(af, src, dst); -#endif -} - -bool HasIPv6Enabled() { -#if !defined(WEBRTC_WIN) - // We only need to check this for Windows XP (so far). - return true; -#else - if (IsWindowsVistaOrLater()) { - return true; - } - if (!IsWindowsXpOrLater()) { - return false; - } - DWORD protbuff_size = 4096; - scoped_ptr protocols; - LPWSAPROTOCOL_INFOW protocol_infos = NULL; - int requested_protocols[2] = {AF_INET6, 0}; - - int err = 0; - int ret = 0; - // Check for protocols in a do-while loop until we provide a buffer large - // enough. (WSCEnumProtocols sets protbuff_size to its desired value). - // It is extremely unlikely that this will loop more than once. - do { - protocols.reset(new char[protbuff_size]); - protocol_infos = reinterpret_cast(protocols.get()); - ret = WSCEnumProtocols(requested_protocols, protocol_infos, - &protbuff_size, &err); - } while (ret == SOCKET_ERROR && err == WSAENOBUFS); - - if (ret == SOCKET_ERROR) { - return false; - } - - // Even if ret is positive, check specifically for IPv6. - // Non-IPv6 enabled WinXP will still return a RAW protocol. - for (int i = 0; i < ret; ++i) { - if (protocol_infos[i].iAddressFamily == AF_INET6) { - return true; - } - } - return false; -#endif -} -} // namespace rtc diff --git a/webrtc/base/nethelpers.h b/webrtc/base/nethelpers.h deleted file mode 100644 index d39400c2f..000000000 --- a/webrtc/base/nethelpers.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NETHELPERS_H_ -#define WEBRTC_BASE_NETHELPERS_H_ - -#if defined(WEBRTC_POSIX) -#include -#include -#elif WEBRTC_WIN -#include // NOLINT -#endif - -#include - -#include "webrtc/base/asyncresolverinterface.h" -#include "webrtc/base/signalthread.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/socketaddress.h" - -namespace rtc { - -class AsyncResolverTest; - -// AsyncResolver will perform async DNS resolution, signaling the result on -// the SignalDone from AsyncResolverInterface when the operation completes. -class AsyncResolver : public SignalThread, public AsyncResolverInterface { - public: - AsyncResolver(); - virtual ~AsyncResolver() {} - - virtual void Start(const SocketAddress& addr); - virtual bool GetResolvedAddress(int family, SocketAddress* addr) const; - virtual int GetError() const { return error_; } - virtual void Destroy(bool wait) { SignalThread::Destroy(wait); } - - const std::vector& addresses() const { return addresses_; } - void set_error(int error) { error_ = error; } - - protected: - virtual void DoWork(); - virtual void OnWorkDone(); - - private: - SocketAddress addr_; - std::vector addresses_; - int error_; -}; - -// rtc namespaced wrappers for inet_ntop and inet_pton so we can avoid -// the windows-native versions of these. -const char* inet_ntop(int af, const void *src, char* dst, socklen_t size); -int inet_pton(int af, const char* src, void *dst); - -bool HasIPv6Enabled(); -} // namespace rtc - -#endif // WEBRTC_BASE_NETHELPERS_H_ diff --git a/webrtc/base/network.cc b/webrtc/base/network.cc deleted file mode 100644 index d94c69eae..000000000 --- a/webrtc/base/network.cc +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "webrtc/base/network.h" - -#if defined(WEBRTC_POSIX) -// linux/if.h can't be included at the same time as the posix sys/if.h, and -// it's transitively required by linux/route.h, so include that version on -// linux instead of the standard posix one. -#if defined(WEBRTC_LINUX) -#include -#include -#elif !defined(__native_client__) -#include -#endif -#include -#include -#include -#include -#include - -#if defined(WEBRTC_ANDROID) -#include "webrtc/base/ifaddrs-android.h" -#elif !defined(__native_client__) -#include -#endif - -#endif // WEBRTC_POSIX - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#include -#endif - -#include - -#include - -#include "webrtc/base/logging.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/socket.h" // includes something that makes windows happy -#include "webrtc/base/stream.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/thread.h" - -namespace rtc { -namespace { - -const uint32 kUpdateNetworksMessage = 1; -const uint32 kSignalNetworksMessage = 2; - -// Fetch list of networks every two seconds. -const int kNetworksUpdateIntervalMs = 2000; - -const int kHighestNetworkPreference = 127; - -bool CompareNetworks(const Network* a, const Network* b) { - if (a->prefix_length() == b->prefix_length()) { - if (a->name() == b->name()) { - return a->prefix() < b->prefix(); - } - } - 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() { -} - -NetworkManager::~NetworkManager() { -} - -NetworkManagerBase::NetworkManagerBase() : ipv6_enabled_(true) { -} - -NetworkManagerBase::~NetworkManagerBase() { - for (NetworkMap::iterator i = networks_map_.begin(); - i != networks_map_.end(); ++i) { - delete i->second; - } -} - -void NetworkManagerBase::GetNetworks(NetworkList* result) const { - *result = networks_; -} - -void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks, - bool* changed) { - // Sort the list so that we can detect when it changes. - typedef std::pair > address_list; - std::map address_map; - NetworkList list(new_networks); - NetworkList merged_list; - std::sort(list.begin(), list.end(), CompareNetworks); - - *changed = false; - - if (networks_.size() != list.size()) - *changed = true; - - // First, build a set of network-keys to the ipaddresses. - for (uint32 i = 0; i < list.size(); ++i) { - bool might_add_to_merged_list = false; - std::string key = MakeNetworkKey(list[i]->name(), - list[i]->prefix(), - list[i]->prefix_length()); - if (address_map.find(key) == address_map.end()) { - address_map[key] = address_list(list[i], std::vector()); - might_add_to_merged_list = true; - } - const std::vector& addresses = list[i]->GetIPs(); - address_list& current_list = address_map[key]; - for (std::vector::const_iterator it = addresses.begin(); - it != addresses.end(); - ++it) { - current_list.second.push_back(*it); - } - if (!might_add_to_merged_list) { - delete list[i]; - } - } - - // Next, look for existing network objects to re-use. - for (std::map::iterator it = address_map.begin(); - it != address_map.end(); - ++it) { - const std::string& key = it->first; - Network* net = it->second.first; - NetworkMap::iterator existing = networks_map_.find(key); - if (existing == networks_map_.end()) { - // This network is new. Place it in the network map. - merged_list.push_back(net); - networks_map_[key] = net; - *changed = true; - } else { - // This network exists in the map already. Reset its IP addresses. - *changed = existing->second->SetIPs(it->second.second, *changed); - merged_list.push_back(existing->second); - if (existing->second != net) { - delete net; - } - } - } - 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() - : thread_(NULL), sent_first_update_(false), start_count_(0), - ignore_non_default_routes_(false) { -} - -BasicNetworkManager::~BasicNetworkManager() { -} - -#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(WEBRTC_POSIX) -void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces, - bool include_ignored, - NetworkList* networks) const { - NetworkMap current_networks; - for (struct ifaddrs* cursor = interfaces; - cursor != NULL; cursor = cursor->ifa_next) { - IPAddress prefix; - IPAddress mask; - IPAddress ip; - int scope_id = 0; - - // Some interfaces may not have address assigned. - if (!cursor->ifa_addr || !cursor->ifa_netmask) - continue; - - switch (cursor->ifa_addr->sa_family) { - case AF_INET: { - ip = IPAddress( - reinterpret_cast(cursor->ifa_addr)->sin_addr); - mask = IPAddress( - reinterpret_cast(cursor->ifa_netmask)->sin_addr); - break; - } - case AF_INET6: { - if (ipv6_enabled()) { - ip = IPAddress( - reinterpret_cast(cursor->ifa_addr)->sin6_addr); - mask = IPAddress( - reinterpret_cast(cursor->ifa_netmask)->sin6_addr); - scope_id = - reinterpret_cast(cursor->ifa_addr)->sin6_scope_id; - break; - } else { - continue; - } - } - default: { - continue; - } - } - - int prefix_length = CountIPMaskBits(mask); - prefix = TruncateIP(ip, prefix_length); - std::string key = MakeNetworkKey(std::string(cursor->ifa_name), - prefix, prefix_length); - NetworkMap::iterator existing_network = current_networks.find(key); - if (existing_network == current_networks.end()) { - scoped_ptr network(new Network(cursor->ifa_name, - cursor->ifa_name, - prefix, - prefix_length)); - network->set_scope_id(scope_id); - network->AddIP(ip); - bool ignored = ((cursor->ifa_flags & IFF_LOOPBACK) || - IsIgnoredNetwork(*network)); - network->set_ignored(ignored); - if (include_ignored || !network->ignored()) { - networks->push_back(network.release()); - } - } else { - (*existing_network).second->AddIP(ip); - } - } -} - -bool BasicNetworkManager::CreateNetworks(bool include_ignored, - NetworkList* networks) const { - struct ifaddrs* interfaces; - int error = getifaddrs(&interfaces); - if (error != 0) { - LOG_ERR(LERROR) << "getifaddrs failed to gather interface data: " << error; - return false; - } - - ConvertIfAddrs(interfaces, include_ignored, networks); - - freeifaddrs(interfaces); - return true; -} - -#elif defined(WEBRTC_WIN) - -unsigned int GetPrefix(PIP_ADAPTER_PREFIX prefixlist, - const IPAddress& ip, IPAddress* prefix) { - IPAddress current_prefix; - IPAddress best_prefix; - unsigned int best_length = 0; - while (prefixlist) { - // Look for the longest matching prefix in the prefixlist. - if (prefixlist->Address.lpSockaddr == NULL || - prefixlist->Address.lpSockaddr->sa_family != ip.family()) { - prefixlist = prefixlist->Next; - continue; - } - switch (prefixlist->Address.lpSockaddr->sa_family) { - case AF_INET: { - sockaddr_in* v4_addr = - reinterpret_cast(prefixlist->Address.lpSockaddr); - current_prefix = IPAddress(v4_addr->sin_addr); - break; - } - case AF_INET6: { - sockaddr_in6* v6_addr = - reinterpret_cast(prefixlist->Address.lpSockaddr); - current_prefix = IPAddress(v6_addr->sin6_addr); - break; - } - default: { - prefixlist = prefixlist->Next; - continue; - } - } - if (TruncateIP(ip, prefixlist->PrefixLength) == current_prefix && - prefixlist->PrefixLength > best_length) { - best_prefix = current_prefix; - best_length = prefixlist->PrefixLength; - } - prefixlist = prefixlist->Next; - } - *prefix = best_prefix; - return best_length; -} - -bool BasicNetworkManager::CreateNetworks(bool include_ignored, - NetworkList* networks) const { - NetworkMap current_networks; - // MSDN recommends a 15KB buffer for the first try at GetAdaptersAddresses. - size_t buffer_size = 16384; - scoped_ptr adapter_info(new char[buffer_size]); - PIP_ADAPTER_ADDRESSES adapter_addrs = - reinterpret_cast(adapter_info.get()); - int adapter_flags = (GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_ANYCAST | - GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_INCLUDE_PREFIX); - int ret = 0; - do { - adapter_info.reset(new char[buffer_size]); - adapter_addrs = reinterpret_cast(adapter_info.get()); - ret = GetAdaptersAddresses(AF_UNSPEC, adapter_flags, - 0, adapter_addrs, - reinterpret_cast(&buffer_size)); - } while (ret == ERROR_BUFFER_OVERFLOW); - if (ret != ERROR_SUCCESS) { - return false; - } - int count = 0; - while (adapter_addrs) { - if (adapter_addrs->OperStatus == IfOperStatusUp) { - PIP_ADAPTER_UNICAST_ADDRESS address = adapter_addrs->FirstUnicastAddress; - PIP_ADAPTER_PREFIX prefixlist = adapter_addrs->FirstPrefix; - std::string name; - std::string description; -#ifdef _DEBUG - name = ToUtf8(adapter_addrs->FriendlyName, - wcslen(adapter_addrs->FriendlyName)); -#endif - description = ToUtf8(adapter_addrs->Description, - wcslen(adapter_addrs->Description)); - for (; address; address = address->Next) { -#ifndef _DEBUG - name = rtc::ToString(count); -#endif - - IPAddress ip; - int scope_id = 0; - scoped_ptr network; - switch (address->Address.lpSockaddr->sa_family) { - case AF_INET: { - sockaddr_in* v4_addr = - reinterpret_cast(address->Address.lpSockaddr); - ip = IPAddress(v4_addr->sin_addr); - break; - } - case AF_INET6: { - if (ipv6_enabled()) { - sockaddr_in6* v6_addr = - reinterpret_cast(address->Address.lpSockaddr); - scope_id = v6_addr->sin6_scope_id; - ip = IPAddress(v6_addr->sin6_addr); - break; - } else { - continue; - } - } - default: { - continue; - } - } - - IPAddress prefix; - int prefix_length = GetPrefix(prefixlist, ip, &prefix); - std::string key = MakeNetworkKey(name, prefix, prefix_length); - NetworkMap::iterator existing_network = current_networks.find(key); - if (existing_network == current_networks.end()) { - scoped_ptr network(new Network(name, - description, - prefix, - prefix_length)); - network->set_scope_id(scope_id); - network->AddIP(ip); - bool ignore = ((adapter_addrs->IfType == IF_TYPE_SOFTWARE_LOOPBACK) || - IsIgnoredNetwork(*network)); - network->set_ignored(ignore); - if (include_ignored || !network->ignored()) { - networks->push_back(network.release()); - } - } else { - (*existing_network).second->AddIP(ip); - } - } - // Count is per-adapter - all 'Networks' created from the same - // adapter need to have the same name. - ++count; - } - adapter_addrs = adapter_addrs->Next; - } - return true; -} -#endif // WEBRTC_WIN - -#if defined(WEBRTC_LINUX) -bool IsDefaultRoute(const std::string& network_name) { - FileStream fs; - if (!fs.Open("/proc/net/route", "r", NULL)) { - LOG(LS_WARNING) << "Couldn't read /proc/net/route, skipping default " - << "route check (assuming everything is a default route)."; - return true; - } else { - std::string line; - while (fs.ReadLine(&line) == SR_SUCCESS) { - char iface_name[256]; - unsigned int iface_ip, iface_gw, iface_mask, iface_flags; - if (sscanf(line.c_str(), - "%255s %8X %8X %4X %*d %*u %*d %8X", - iface_name, &iface_ip, &iface_gw, - &iface_flags, &iface_mask) == 5 && - network_name == iface_name && - iface_mask == 0 && - (iface_flags & (RTF_UP | RTF_HOST)) == RTF_UP) { - return true; - } - } - } - return false; -} -#endif - -bool BasicNetworkManager::IsIgnoredNetwork(const Network& network) const { - // Ignore networks on the explicit ignore list. - for (size_t i = 0; i < network_ignore_list_.size(); ++i) { - if (network.name() == network_ignore_list_[i]) { - return true; - } - } -#if defined(WEBRTC_POSIX) - // Filter out VMware interfaces, typically named vmnet1 and vmnet8 - if (strncmp(network.name().c_str(), "vmnet", 5) == 0 || - strncmp(network.name().c_str(), "vnic", 4) == 0) { - return true; - } -#if defined(WEBRTC_LINUX) - // Make sure this is a default route, if we're ignoring non-defaults. - if (ignore_non_default_routes_ && !IsDefaultRoute(network.name())) { - return true; - } -#endif -#elif defined(WEBRTC_WIN) - // Ignore any HOST side vmware adapters with a description like: - // VMware Virtual Ethernet Adapter for VMnet1 - // but don't ignore any GUEST side adapters with a description like: - // VMware Accelerated AMD PCNet Adapter #2 - if (strstr(network.description().c_str(), "VMnet") != NULL) { - return true; - } -#endif - - // Ignore any networks with a 0.x.y.z IP - if (network.prefix().family() == AF_INET) { - return (network.prefix().v4AddressAsHostOrderInteger() < 0x01000000); - } - return false; -} - -void BasicNetworkManager::StartUpdating() { - thread_ = Thread::Current(); - if (start_count_) { - // If network interfaces are already discovered and signal is sent, - // we should trigger network signal immediately for the new clients - // to start allocating ports. - if (sent_first_update_) - thread_->Post(this, kSignalNetworksMessage); - } else { - thread_->Post(this, kUpdateNetworksMessage); - } - ++start_count_; -} - -void BasicNetworkManager::StopUpdating() { - ASSERT(Thread::Current() == thread_); - if (!start_count_) - return; - - --start_count_; - if (!start_count_) { - thread_->Clear(this); - sent_first_update_ = false; - } -} - -void BasicNetworkManager::OnMessage(Message* msg) { - switch (msg->message_id) { - case kUpdateNetworksMessage: { - DoUpdateNetworks(); - break; - } - case kSignalNetworksMessage: { - SignalNetworksChanged(); - break; - } - default: - ASSERT(false); - } -} - -void BasicNetworkManager::DoUpdateNetworks() { - if (!start_count_) - return; - - ASSERT(Thread::Current() == thread_); - - NetworkList list; - if (!CreateNetworks(false, &list)) { - SignalError(); - } else { - bool changed; - MergeNetworkList(list, &changed); - if (changed || !sent_first_update_) { - SignalNetworksChanged(); - sent_first_update_ = true; - } - } - - thread_->PostDelayed(kNetworksUpdateIntervalMs, this, kUpdateNetworksMessage); -} - -void BasicNetworkManager::DumpNetworks(bool include_ignored) { - NetworkList list; - CreateNetworks(include_ignored, &list); - LOG(LS_INFO) << "NetworkManager detected " << list.size() << " networks:"; - for (size_t i = 0; i < list.size(); ++i) { - const Network* network = list[i]; - if (!network->ignored() || include_ignored) { - LOG(LS_INFO) << network->ToString() << ": " - << network->description() - << ((network->ignored()) ? ", Ignored" : ""); - } - } - // Release the network list created previously. - // Do this in a seperated for loop for better readability. - for (size_t i = 0; i < list.size(); ++i) { - delete list[i]; - } -} - -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), - 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 { - std::stringstream ss; - // 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_ - << ":" << AdapterTypeToString(type_) << "]"; - return ss.str(); -} - -// Sets the addresses of this network. Returns true if the address set changed. -// Change detection is short circuited if the changed argument is true. -bool Network::SetIPs(const std::vector& ips, bool changed) { - changed = changed || ips.size() != ips_.size(); - // Detect changes with a nested loop; n-squared but we expect on the order - // of 2-3 addresses per network. - for (std::vector::const_iterator it = ips.begin(); - !changed && it != ips.end(); - ++it) { - bool found = false; - for (std::vector::iterator inner_it = ips_.begin(); - !found && inner_it != ips_.end(); - ++inner_it) { - if (*it == *inner_it) { - found = true; - } - } - changed = !found; - } - ips_ = ips; - return changed; -} - -} // namespace rtc diff --git a/webrtc/base/network.h b/webrtc/base/network.h deleted file mode 100644 index 855b1b74a..000000000 --- a/webrtc/base/network.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NETWORK_H_ -#define WEBRTC_BASE_NETWORK_H_ - -#include -#include -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/ipaddress.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/sigslot.h" - -#if defined(WEBRTC_POSIX) -struct ifaddrs; -#endif // defined(WEBRTC_POSIX) - -namespace rtc { - -class Network; -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 { - public: - typedef std::vector NetworkList; - - NetworkManager(); - virtual ~NetworkManager(); - - // Called when network list is updated. - sigslot::signal0<> SignalNetworksChanged; - - // Indicates a failure when getting list of network interfaces. - sigslot::signal0<> SignalError; - - // Start/Stop monitoring of network interfaces - // list. SignalNetworksChanged or SignalError is emitted immidiately - // after StartUpdating() is called. After that SignalNetworksChanged - // is emitted wheneven list of networks changes. - virtual void StartUpdating() = 0; - virtual void StopUpdating() = 0; - - // Returns the current list of networks available on this machine. - // UpdateNetworks() must be called before this method is called. - // It makes sure that repeated calls return the same object for a - // given network, so that quality is tracked appropriately. Does not - // include ignored networks. - virtual void GetNetworks(NetworkList* networks) const = 0; - - // Dumps a list of networks available to LS_INFO. - virtual void DumpNetworks(bool include_ignored) {} -}; - -// Base class for NetworkManager implementations. -class NetworkManagerBase : public NetworkManager { - public: - NetworkManagerBase(); - virtual ~NetworkManagerBase(); - - virtual void GetNetworks(std::vector* networks) const; - bool ipv6_enabled() const { return ipv6_enabled_; } - void set_ipv6_enabled(bool enabled) { ipv6_enabled_ = enabled; } - - protected: - typedef std::map NetworkMap; - // Updates |networks_| with the networks listed in |list|. If - // |network_map_| already has a Network object for a network listed - // in the |list| then it is reused. Accept ownership of the Network - // objects in the |list|. |changed| will be set to true if there is - // any change in the network list. - void MergeNetworkList(const NetworkList& list, bool* changed); - - private: - friend class NetworkTest; - void DoUpdateNetworks(); - - NetworkList networks_; - NetworkMap networks_map_; - bool ipv6_enabled_; -}; - -// Basic implementation of the NetworkManager interface that gets list -// of networks using OS APIs. -class BasicNetworkManager : public NetworkManagerBase, - public MessageHandler { - public: - BasicNetworkManager(); - virtual ~BasicNetworkManager(); - - virtual void StartUpdating(); - virtual void StopUpdating(); - - // Logs the available networks. - virtual void DumpNetworks(bool include_ignored); - - // MessageHandler interface. - virtual void OnMessage(Message* msg); - bool started() { return start_count_ > 0; } - - // Sets the network ignore list, which is empty by default. Any network on - // the ignore list will be filtered from network enumeration results. - void set_network_ignore_list(const std::vector& list) { - network_ignore_list_ = list; - } -#if defined(WEBRTC_LINUX) - // Sets the flag for ignoring non-default routes. - void set_ignore_non_default_routes(bool value) { - ignore_non_default_routes_ = true; - } -#endif - - protected: -#if defined(WEBRTC_POSIX) - // Separated from CreateNetworks for tests. - void ConvertIfAddrs(ifaddrs* interfaces, - bool include_ignored, - NetworkList* networks) const; -#endif // defined(WEBRTC_POSIX) - - // Creates a network object for each network available on the machine. - bool CreateNetworks(bool include_ignored, NetworkList* networks) const; - - // Determines if a network should be ignored. - bool IsIgnoredNetwork(const Network& network) const; - - private: - friend class NetworkTest; - - void DoUpdateNetworks(); - - Thread* thread_; - bool sent_first_update_; - int start_count_; - std::vector network_ignore_list_; - bool ignore_non_default_routes_; -}; - -// Represents a Unix-type network interface, with a name and single address. -class Network { - public: - 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_; } - - // Returns the OS-assigned name for this network. This is useful for - // debugging but should not be sent over the wire (for privacy reasons). - const std::string& description() const { return description_; } - - // Returns the prefix for this network. - const IPAddress& prefix() const { return prefix_; } - // 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. - // Returns an unset IP if this network has no active addresses. - IPAddress ip() const { - if (ips_.size() == 0) { - return IPAddress(); - } - return ips_.at(0); - } - // Adds an active IP address to this network. Does not check for duplicates. - void AddIP(const IPAddress& ip) { ips_.push_back(ip); } - - // Sets the network's IP address list. Returns true if new IP addresses were - // detected. Passing true to already_changed skips this check. - bool SetIPs(const std::vector& ips, bool already_changed); - // Get the list of IP Addresses associated with this network. - const std::vector& GetIPs() { return ips_;} - // Clear the network's list of addresses. - void ClearIPs() { ips_.clear(); } - - // Returns the scope-id of the network's address. - // Should only be relevant for link-local IPv6 addresses. - int scope_id() const { return scope_id_; } - void set_scope_id(int id) { scope_id_ = id; } - - // Indicates whether this network should be ignored, perhaps because - // the IP is 0, or the interface is one we know is invalid. - 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: - std::string name_; - std::string description_; - IPAddress prefix_; - int prefix_length_; - std::string key_; - std::vector ips_; - int scope_id_; - bool ignored_; - AdapterType type_; - int preference_; - - friend class NetworkManager; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_NETWORK_H_ diff --git a/webrtc/base/network_unittest.cc b/webrtc/base/network_unittest.cc deleted file mode 100644 index 431f8b4ea..000000000 --- a/webrtc/base/network_unittest.cc +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/network.h" - -#include -#if defined(WEBRTC_POSIX) -#include -#if !defined(WEBRTC_ANDROID) -#include -#else -#include "webrtc/base/ifaddrs-android.h" -#endif -#endif -#include "webrtc/base/gunit.h" -#if defined(WEBRTC_WIN) -#include "webrtc/base/logging.h" // For LOG_GLE -#endif - -namespace rtc { - -class NetworkTest : public testing::Test, public sigslot::has_slots<> { - public: - NetworkTest() : callback_called_(false) {} - - void OnNetworksChanged() { - callback_called_ = true; - } - - void MergeNetworkList(BasicNetworkManager& network_manager, - const NetworkManager::NetworkList& list, - bool* changed ) { - network_manager.MergeNetworkList(list, changed); - } - - bool IsIgnoredNetwork(BasicNetworkManager& network_manager, - const Network& network) { - return network_manager.IsIgnoredNetwork(network); - } - - NetworkManager::NetworkList GetNetworks( - const BasicNetworkManager& network_manager, bool include_ignored) { - NetworkManager::NetworkList list; - network_manager.CreateNetworks(include_ignored, &list); - return list; - } - -#if defined(WEBRTC_POSIX) - // Separated from CreateNetworks for tests. - static void CallConvertIfAddrs(const BasicNetworkManager& network_manager, - struct ifaddrs* interfaces, - bool include_ignored, - NetworkManager::NetworkList* networks) { - network_manager.ConvertIfAddrs(interfaces, include_ignored, networks); - } -#endif // defined(WEBRTC_POSIX) - - protected: - bool callback_called_; -}; - -// Test that the Network ctor works properly. -TEST_F(NetworkTest, TestNetworkConstruct) { - Network ipv4_network1("test_eth0", "Test Network Adapter 1", - IPAddress(0x12345600U), 24); - EXPECT_EQ("test_eth0", ipv4_network1.name()); - EXPECT_EQ("Test Network Adapter 1", ipv4_network1.description()); - EXPECT_EQ(IPAddress(0x12345600U), ipv4_network1.prefix()); - EXPECT_EQ(24, ipv4_network1.prefix_length()); - EXPECT_FALSE(ipv4_network1.ignored()); -} - -// Tests that our ignore function works properly. -TEST_F(NetworkTest, TestNetworkIgnore) { - Network ipv4_network1("test_eth0", "Test Network Adapter 1", - IPAddress(0x12345600U), 24); - Network ipv4_network2("test_eth1", "Test Network Adapter 2", - IPAddress(0x00010000U), 16); - BasicNetworkManager network_manager; - EXPECT_FALSE(IsIgnoredNetwork(network_manager, ipv4_network1)); - EXPECT_TRUE(IsIgnoredNetwork(network_manager, ipv4_network2)); -} - -TEST_F(NetworkTest, TestIgnoreList) { - Network ignore_me("ignore_me", "Ignore me please!", - IPAddress(0x12345600U), 24); - Network include_me("include_me", "Include me please!", - IPAddress(0x12345600U), 24); - BasicNetworkManager network_manager; - EXPECT_FALSE(IsIgnoredNetwork(network_manager, ignore_me)); - EXPECT_FALSE(IsIgnoredNetwork(network_manager, include_me)); - std::vector ignore_list; - ignore_list.push_back("ignore_me"); - network_manager.set_network_ignore_list(ignore_list); - EXPECT_TRUE(IsIgnoredNetwork(network_manager, ignore_me)); - EXPECT_FALSE(IsIgnoredNetwork(network_manager, include_me)); -} - -// Test is failing on Windows opt: b/11288214 -TEST_F(NetworkTest, DISABLED_TestCreateNetworks) { - BasicNetworkManager manager; - NetworkManager::NetworkList result = GetNetworks(manager, true); - // We should be able to bind to any addresses we find. - NetworkManager::NetworkList::iterator it; - for (it = result.begin(); - it != result.end(); - ++it) { - sockaddr_storage storage; - memset(&storage, 0, sizeof(storage)); - IPAddress ip = (*it)->ip(); - SocketAddress bindaddress(ip, 0); - bindaddress.SetScopeID((*it)->scope_id()); - // TODO(thaloun): Use rtc::AsyncSocket once it supports IPv6. - int fd = static_cast(socket(ip.family(), SOCK_STREAM, IPPROTO_TCP)); - if (fd > 0) { - size_t ipsize = bindaddress.ToSockAddrStorage(&storage); - EXPECT_GE(ipsize, 0U); - int success = ::bind(fd, - reinterpret_cast(&storage), - static_cast(ipsize)); -#if defined(WEBRTC_WIN) - if (success) LOG_GLE(LS_ERROR) << "Socket bind failed."; -#endif - EXPECT_EQ(0, success); -#if defined(WEBRTC_WIN) - closesocket(fd); -#else - close(fd); -#endif - } - delete (*it); - } -} - -// Test that UpdateNetworks succeeds. -TEST_F(NetworkTest, TestUpdateNetworks) { - BasicNetworkManager manager; - manager.SignalNetworksChanged.connect( - static_cast(this), &NetworkTest::OnNetworksChanged); - manager.StartUpdating(); - Thread::Current()->ProcessMessages(0); - EXPECT_TRUE(callback_called_); - callback_called_ = false; - // Callback should be triggered immediately when StartUpdating - // is called, after network update signal is already sent. - manager.StartUpdating(); - EXPECT_TRUE(manager.started()); - Thread::Current()->ProcessMessages(0); - EXPECT_TRUE(callback_called_); - manager.StopUpdating(); - EXPECT_TRUE(manager.started()); - manager.StopUpdating(); - EXPECT_FALSE(manager.started()); - manager.StopUpdating(); - EXPECT_FALSE(manager.started()); - callback_called_ = false; - // Callback should be triggered immediately after StartUpdating is called - // when start_count_ is reset to 0. - manager.StartUpdating(); - Thread::Current()->ProcessMessages(0); - EXPECT_TRUE(callback_called_); -} - -// Verify that MergeNetworkList() merges network lists properly. -TEST_F(NetworkTest, TestBasicMergeNetworkList) { - Network ipv4_network1("test_eth0", "Test Network Adapter 1", - IPAddress(0x12345600U), 24); - Network ipv4_network2("test_eth1", "Test Network Adapter 2", - IPAddress(0x00010000U), 16); - ipv4_network1.AddIP(IPAddress(0x12345678)); - ipv4_network2.AddIP(IPAddress(0x00010004)); - BasicNetworkManager manager; - - // Add ipv4_network1 to the list of networks. - NetworkManager::NetworkList list; - list.push_back(new Network(ipv4_network1)); - bool changed; - MergeNetworkList(manager, list, &changed); - EXPECT_TRUE(changed); - list.clear(); - - manager.GetNetworks(&list); - EXPECT_EQ(1U, list.size()); - EXPECT_EQ(ipv4_network1.ToString(), list[0]->ToString()); - Network* net1 = list[0]; - list.clear(); - - // Replace ipv4_network1 with ipv4_network2. - list.push_back(new Network(ipv4_network2)); - MergeNetworkList(manager, list, &changed); - EXPECT_TRUE(changed); - list.clear(); - - manager.GetNetworks(&list); - EXPECT_EQ(1U, list.size()); - EXPECT_EQ(ipv4_network2.ToString(), list[0]->ToString()); - Network* net2 = list[0]; - list.clear(); - - // Add Network2 back. - list.push_back(new Network(ipv4_network1)); - list.push_back(new Network(ipv4_network2)); - MergeNetworkList(manager, list, &changed); - EXPECT_TRUE(changed); - list.clear(); - - // Verify that we get previous instances of Network objects. - manager.GetNetworks(&list); - EXPECT_EQ(2U, list.size()); - EXPECT_TRUE((net1 == list[0] && net2 == list[1]) || - (net1 == list[1] && net2 == list[0])); - list.clear(); - - // Call MergeNetworkList() again and verify that we don't get update - // notification. - list.push_back(new Network(ipv4_network2)); - list.push_back(new Network(ipv4_network1)); - MergeNetworkList(manager, list, &changed); - EXPECT_FALSE(changed); - list.clear(); - - // Verify that we get previous instances of Network objects. - manager.GetNetworks(&list); - EXPECT_EQ(2U, list.size()); - EXPECT_TRUE((net1 == list[0] && net2 == list[1]) || - (net1 == list[1] && net2 == list[0])); - list.clear(); -} - -// Sets up some test IPv6 networks and appends them to list. -// Four networks are added - public and link local, for two interfaces. -void SetupNetworks(NetworkManager::NetworkList* list) { - IPAddress ip; - IPAddress prefix; - EXPECT_TRUE(IPFromString("fe80::1234:5678:abcd:ef12", &ip)); - EXPECT_TRUE(IPFromString("fe80::", &prefix)); - // First, fake link-locals. - Network ipv6_eth0_linklocalnetwork("test_eth0", "Test NetworkAdapter 1", - prefix, 64); - ipv6_eth0_linklocalnetwork.AddIP(ip); - EXPECT_TRUE(IPFromString("fe80::5678:abcd:ef12:3456", &ip)); - Network ipv6_eth1_linklocalnetwork("test_eth1", "Test NetworkAdapter 2", - prefix, 64); - ipv6_eth1_linklocalnetwork.AddIP(ip); - // Public networks: - EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c3", &ip)); - prefix = TruncateIP(ip, 64); - Network ipv6_eth0_publicnetwork1_ip1("test_eth0", "Test NetworkAdapter 1", - prefix, 64); - ipv6_eth0_publicnetwork1_ip1.AddIP(ip); - 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 1", - prefix, 64); - ipv6_eth1_publicnetwork1_ip1.AddIP(ip); - list->push_back(new Network(ipv6_eth0_linklocalnetwork)); - list->push_back(new Network(ipv6_eth1_linklocalnetwork)); - list->push_back(new Network(ipv6_eth0_publicnetwork1_ip1)); - list->push_back(new Network(ipv6_eth1_publicnetwork1_ip1)); -} - -// Test that the basic network merging case works. -TEST_F(NetworkTest, TestIPv6MergeNetworkList) { - BasicNetworkManager manager; - manager.SignalNetworksChanged.connect( - static_cast(this), &NetworkTest::OnNetworksChanged); - NetworkManager::NetworkList original_list; - SetupNetworks(&original_list); - bool changed = false; - MergeNetworkList(manager, original_list, &changed); - EXPECT_TRUE(changed); - NetworkManager::NetworkList list; - manager.GetNetworks(&list); - EXPECT_EQ(original_list.size(), list.size()); - // Verify that the original members are in the merged list. - for (NetworkManager::NetworkList::iterator it = original_list.begin(); - it != original_list.end(); ++it) { - EXPECT_NE(list.end(), std::find(list.begin(), list.end(), *it)); - } -} - -// Tests that when two network lists that describe the same set of networks are -// merged, that the changed callback is not called, and that the original -// objects remain in the result list. -TEST_F(NetworkTest, TestNoChangeMerge) { - BasicNetworkManager manager; - manager.SignalNetworksChanged.connect( - static_cast(this), &NetworkTest::OnNetworksChanged); - NetworkManager::NetworkList original_list; - SetupNetworks(&original_list); - bool changed = false; - MergeNetworkList(manager, original_list, &changed); - EXPECT_TRUE(changed); - // Second list that describes the same networks but with new objects. - NetworkManager::NetworkList second_list; - SetupNetworks(&second_list); - changed = false; - MergeNetworkList(manager, second_list, &changed); - EXPECT_FALSE(changed); - NetworkManager::NetworkList resulting_list; - manager.GetNetworks(&resulting_list); - EXPECT_EQ(original_list.size(), resulting_list.size()); - // Verify that the original members are in the merged list. - for (NetworkManager::NetworkList::iterator it = original_list.begin(); - it != original_list.end(); ++it) { - EXPECT_NE(resulting_list.end(), - std::find(resulting_list.begin(), resulting_list.end(), *it)); - } - // Doublecheck that the new networks aren't in the list. - for (NetworkManager::NetworkList::iterator it = second_list.begin(); - it != second_list.end(); ++it) { - EXPECT_EQ(resulting_list.end(), - std::find(resulting_list.begin(), resulting_list.end(), *it)); - } -} - -// Test that we can merge a network that is the same as another network but with -// a different IP. The original network should remain in the list, but have its -// IP changed. -TEST_F(NetworkTest, MergeWithChangedIP) { - BasicNetworkManager manager; - manager.SignalNetworksChanged.connect( - static_cast(this), &NetworkTest::OnNetworksChanged); - NetworkManager::NetworkList original_list; - SetupNetworks(&original_list); - // Make a network that we're going to change. - IPAddress ip; - EXPECT_TRUE(IPFromString("2401:fa01:4:1000:be30:faa:fee:faa", &ip)); - IPAddress prefix = TruncateIP(ip, 64); - Network* network_to_change = new Network("test_eth0", - "Test Network Adapter 1", - prefix, 64); - Network* changed_network = new Network(*network_to_change); - network_to_change->AddIP(ip); - IPAddress changed_ip; - EXPECT_TRUE(IPFromString("2401:fa01:4:1000:be30:f00:f00:f00", &changed_ip)); - changed_network->AddIP(changed_ip); - original_list.push_back(network_to_change); - bool changed = false; - MergeNetworkList(manager, original_list, &changed); - NetworkManager::NetworkList second_list; - SetupNetworks(&second_list); - second_list.push_back(changed_network); - changed = false; - MergeNetworkList(manager, second_list, &changed); - EXPECT_TRUE(changed); - NetworkManager::NetworkList list; - manager.GetNetworks(&list); - EXPECT_EQ(original_list.size(), list.size()); - // Make sure the original network is still in the merged list. - EXPECT_NE(list.end(), - std::find(list.begin(), list.end(), network_to_change)); - EXPECT_EQ(changed_ip, network_to_change->GetIPs().at(0)); -} - -// Testing a similar case to above, but checking that a network can be updated -// with additional IPs (not just a replacement). -TEST_F(NetworkTest, TestMultipleIPMergeNetworkList) { - BasicNetworkManager manager; - manager.SignalNetworksChanged.connect( - static_cast(this), &NetworkTest::OnNetworksChanged); - NetworkManager::NetworkList original_list; - SetupNetworks(&original_list); - bool changed = false; - MergeNetworkList(manager, original_list, &changed); - EXPECT_TRUE(changed); - IPAddress ip; - IPAddress check_ip; - IPAddress prefix; - // Add a second IP to the public network on eth0 (2401:fa00:4:1000/64). - EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c6", &ip)); - prefix = TruncateIP(ip, 64); - Network ipv6_eth0_publicnetwork1_ip2("test_eth0", "Test NetworkAdapter 1", - prefix, 64); - // This is the IP that already existed in the public network on eth0. - EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c3", &check_ip)); - ipv6_eth0_publicnetwork1_ip2.AddIP(ip); - original_list.push_back(new Network(ipv6_eth0_publicnetwork1_ip2)); - changed = false; - MergeNetworkList(manager, original_list, &changed); - EXPECT_TRUE(changed); - // There should still be four networks. - NetworkManager::NetworkList list; - manager.GetNetworks(&list); - EXPECT_EQ(4U, list.size()); - // Check the gathered IPs. - int matchcount = 0; - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - if ((*it)->ToString() == original_list[2]->ToString()) { - ++matchcount; - EXPECT_EQ(1, matchcount); - // This should be the same network object as before. - EXPECT_EQ((*it), original_list[2]); - // But with two addresses now. - EXPECT_EQ(2U, (*it)->GetIPs().size()); - EXPECT_NE((*it)->GetIPs().end(), - std::find((*it)->GetIPs().begin(), - (*it)->GetIPs().end(), - check_ip)); - EXPECT_NE((*it)->GetIPs().end(), - std::find((*it)->GetIPs().begin(), - (*it)->GetIPs().end(), - ip)); - } else { - // Check the IP didn't get added anywhere it wasn't supposed to. - EXPECT_EQ((*it)->GetIPs().end(), - std::find((*it)->GetIPs().begin(), - (*it)->GetIPs().end(), - ip)); - } - } -} - -// Test that merge correctly distinguishes multiple networks on an interface. -TEST_F(NetworkTest, TestMultiplePublicNetworksOnOneInterfaceMerge) { - BasicNetworkManager manager; - manager.SignalNetworksChanged.connect( - static_cast(this), &NetworkTest::OnNetworksChanged); - NetworkManager::NetworkList original_list; - SetupNetworks(&original_list); - bool changed = false; - MergeNetworkList(manager, original_list, &changed); - EXPECT_TRUE(changed); - IPAddress ip; - IPAddress prefix; - // A second network for eth0. - EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:5bff:fee5:c3", &ip)); - prefix = TruncateIP(ip, 64); - Network ipv6_eth0_publicnetwork2_ip1("test_eth0", "Test NetworkAdapter 1", - prefix, 64); - ipv6_eth0_publicnetwork2_ip1.AddIP(ip); - original_list.push_back(new Network(ipv6_eth0_publicnetwork2_ip1)); - changed = false; - MergeNetworkList(manager, original_list, &changed); - EXPECT_TRUE(changed); - // There should be five networks now. - NetworkManager::NetworkList list; - manager.GetNetworks(&list); - EXPECT_EQ(5U, list.size()); - // Check the resulting addresses. - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - if ((*it)->prefix() == ipv6_eth0_publicnetwork2_ip1.prefix() && - (*it)->name() == ipv6_eth0_publicnetwork2_ip1.name()) { - // Check the new network has 1 IP and that it's the correct one. - EXPECT_EQ(1U, (*it)->GetIPs().size()); - EXPECT_EQ(ip, (*it)->GetIPs().at(0)); - } else { - // Check the IP didn't get added anywhere it wasn't supposed to. - EXPECT_EQ((*it)->GetIPs().end(), - std::find((*it)->GetIPs().begin(), - (*it)->GetIPs().end(), - ip)); - } - } -} - -// Test that DumpNetworks works. -TEST_F(NetworkTest, TestDumpNetworks) { - BasicNetworkManager manager; - manager.DumpNetworks(true); -} - -// Test that we can toggle IPv6 on and off. -TEST_F(NetworkTest, TestIPv6Toggle) { - BasicNetworkManager manager; - bool ipv6_found = false; - NetworkManager::NetworkList list; -#if !defined(WEBRTC_WIN) - // There should be at least one IPv6 network (fe80::/64 should be in there). - // TODO(thaloun): Disabling this test on windows for the moment as the test - // machines don't seem to have IPv6 installed on them at all. - manager.set_ipv6_enabled(true); - list = GetNetworks(manager, true); - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - if ((*it)->prefix().family() == AF_INET6) { - ipv6_found = true; - break; - } - } - EXPECT_TRUE(ipv6_found); - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - delete (*it); - } -#endif - ipv6_found = false; - manager.set_ipv6_enabled(false); - list = GetNetworks(manager, true); - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - if ((*it)->prefix().family() == AF_INET6) { - ipv6_found = true; - break; - } - } - EXPECT_FALSE(ipv6_found); - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - delete (*it); - } -} - -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(WEBRTC_POSIX) -// Verify that we correctly handle interfaces with no address. -TEST_F(NetworkTest, TestConvertIfAddrsNoAddress) { - ifaddrs list; - memset(&list, 0, sizeof(list)); - list.ifa_name = const_cast("test_iface"); - - NetworkManager::NetworkList result; - BasicNetworkManager manager; - CallConvertIfAddrs(manager, &list, true, &result); - EXPECT_TRUE(result.empty()); -} -#endif // defined(WEBRTC_POSIX) - -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) -// If you want to test non-default routes, you can do the following on a linux -// machine: -// 1) Load the dummy network driver: -// sudo modprobe dummy -// sudo ifconfig dummy0 127.0.0.1 -// 2) Run this test and confirm the output says it found a dummy route (and -// passes). -// 3) When done: -// sudo rmmmod dummy -TEST_F(NetworkTest, TestIgnoreNonDefaultRoutes) { - BasicNetworkManager manager; - NetworkManager::NetworkList list; - list = GetNetworks(manager, false); - bool found_dummy = false; - LOG(LS_INFO) << "Looking for dummy network: "; - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - LOG(LS_INFO) << " Network name: " << (*it)->name(); - found_dummy |= (*it)->name().find("dummy0") != std::string::npos; - } - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - delete (*it); - } - if (!found_dummy) { - LOG(LS_INFO) << "No dummy found, quitting."; - return; - } - LOG(LS_INFO) << "Found dummy, running again while ignoring non-default " - << "routes."; - manager.set_ignore_non_default_routes(true); - list = GetNetworks(manager, false); - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - LOG(LS_INFO) << " Network name: " << (*it)->name(); - EXPECT_TRUE((*it)->name().find("dummy0") == std::string::npos); - } - for (NetworkManager::NetworkList::iterator it = list.begin(); - it != list.end(); ++it) { - delete (*it); - } -} -#endif - -} // namespace rtc diff --git a/webrtc/base/nssidentity.cc b/webrtc/base/nssidentity.cc deleted file mode 100644 index 77635a2fc..000000000 --- a/webrtc/base/nssidentity.cc +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#if HAVE_NSS_SSL_H - -#include "webrtc/base/nssidentity.h" - -#include "cert.h" -#include "cryptohi.h" -#include "keyhi.h" -#include "nss.h" -#include "pk11pub.h" -#include "sechash.h" - -#include "webrtc/base/logging.h" -#include "webrtc/base/helpers.h" -#include "webrtc/base/nssstreamadapter.h" -#include "webrtc/base/safe_conversions.h" - -namespace rtc { - -// 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_); - if (pubkey_) - SECKEY_DestroyPublicKey(pubkey_); -} - -NSSKeyPair *NSSKeyPair::Generate() { - SECKEYPrivateKey *privkey = NULL; - SECKEYPublicKey *pubkey = NULL; - PK11RSAGenParams rsaparams; - rsaparams.keySizeInBits = 1024; - rsaparams.pe = 0x010001; // 65537 -- a common RSA public exponent. - - privkey = PK11_GenerateKeyPair(NSSContext::GetSlot(), - CKM_RSA_PKCS_KEY_PAIR_GEN, - &rsaparams, &pubkey, PR_FALSE /*permanent*/, - PR_FALSE /*sensitive*/, NULL); - if (!privkey) { - LOG(LS_ERROR) << "Couldn't generate key pair"; - return NULL; - } - - return new NSSKeyPair(privkey, pubkey); -} - -// Just make a copy. -NSSKeyPair *NSSKeyPair::GetReference() { - SECKEYPrivateKey *privkey = SECKEY_CopyPrivateKey(privkey_); - if (!privkey) - return NULL; - - SECKEYPublicKey *pubkey = SECKEY_CopyPublicKey(pubkey_); - if (!pubkey) { - SECKEY_DestroyPrivateKey(privkey); - return NULL; - } - - return new NSSKeyPair(privkey, pubkey); -} - -NSSCertificate::NSSCertificate(CERTCertificate* cert) - : certificate_(CERT_DupCertificate(cert)) { - ASSERT(certificate_ != NULL); -} - -static void DeleteCert(SSLCertificate* cert) { - delete cert; -} - -NSSCertificate::NSSCertificate(CERTCertList* cert_list) { - // Copy the first cert into certificate_. - CERTCertListNode* node = CERT_LIST_HEAD(cert_list); - certificate_ = CERT_DupCertificate(node->cert); - - // Put any remaining certificates into the chain. - node = CERT_LIST_NEXT(node); - std::vector certs; - for (; !CERT_LIST_END(node, cert_list); node = CERT_LIST_NEXT(node)) { - certs.push_back(new NSSCertificate(node->cert)); - } - - if (!certs.empty()) - chain_.reset(new SSLCertChain(certs)); - - // The SSLCertChain constructor copies its input, so now we have to delete - // the originals. - std::for_each(certs.begin(), certs.end(), DeleteCert); -} - -NSSCertificate::NSSCertificate(CERTCertificate* cert, SSLCertChain* chain) - : certificate_(CERT_DupCertificate(cert)) { - ASSERT(certificate_ != NULL); - if (chain) - chain_.reset(chain->Copy()); -} - - -NSSCertificate *NSSCertificate::FromPEMString(const std::string &pem_string) { - std::string der; - if (!SSLIdentity::PemToDer(kPemTypeCertificate, pem_string, &der)) - return NULL; - - SECItem der_cert; - der_cert.data = reinterpret_cast(const_cast( - der.data())); - der_cert.len = checked_cast(der.size()); - CERTCertificate *cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), - &der_cert, NULL, PR_FALSE, PR_TRUE); - - if (!cert) - return NULL; - - NSSCertificate* ret = new NSSCertificate(cert); - CERT_DestroyCertificate(cert); - return ret; -} - -NSSCertificate *NSSCertificate::GetReference() const { - return new NSSCertificate(certificate_, chain_.get()); -} - -std::string NSSCertificate::ToPEMString() const { - return SSLIdentity::DerToPem(kPemTypeCertificate, - certificate_->derCert.data, - certificate_->derCert.len); -} - -void NSSCertificate::ToDER(Buffer* der_buffer) const { - der_buffer->SetData(certificate_->derCert.data, certificate_->derCert.len); -} - -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)) - return false; - - *length = ho->length; - - return true; -} - -bool NSSCertificate::GetSignatureDigestAlgorithm(std::string* algorithm) const { - // The function sec_DecodeSigAlg in NSS provides this mapping functionality. - // Unfortunately it is private, so the functionality must be duplicated here. - // See https://bugzilla.mozilla.org/show_bug.cgi?id=925165 . - SECOidTag sig_alg = SECOID_GetAlgorithmTag(&certificate_->signature); - switch (sig_alg) { - case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: - *algorithm = DIGEST_MD5; - break; - case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: - case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: - case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE: - case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: - case SEC_OID_MISSI_DSS: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_DSS_OLD: - *algorithm = DIGEST_SHA_1; - break; - case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: - case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: - case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST: - *algorithm = DIGEST_SHA_224; - break; - case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: - case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: - case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST: - *algorithm = DIGEST_SHA_256; - break; - case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: - case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: - *algorithm = DIGEST_SHA_384; - break; - case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: - case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: - *algorithm = DIGEST_SHA_512; - break; - default: - // Unknown algorithm. There are several unhandled options that are less - // common and more complex. - algorithm->clear(); - return false; - } - return true; -} - -bool NSSCertificate::ComputeDigest(const std::string& algorithm, - unsigned char* digest, - size_t size, - size_t* length) const { - const SECHashObject *ho; - - if (!GetDigestObject(algorithm, &ho)) - return false; - - if (size < ho->length) // Sanity check for fit - return false; - - SECStatus rv = HASH_HashBuf(ho->type, digest, - certificate_->derCert.data, - certificate_->derCert.len); - if (rv != SECSuccess) - return false; - - *length = ho->length; - - return true; -} - -bool NSSCertificate::GetChain(SSLCertChain** chain) const { - if (!chain_) - return false; - - *chain = chain_->Copy(); - return true; -} - -bool NSSCertificate::Equals(const NSSCertificate *tocompare) const { - if (!certificate_->derCert.len) - return false; - if (!tocompare->certificate_->derCert.len) - return false; - - if (certificate_->derCert.len != tocompare->certificate_->derCert.len) - return false; - - return memcmp(certificate_->derCert.data, - tocompare->certificate_->derCert.data, - certificate_->derCert.len) == 0; -} - - -bool NSSCertificate::GetDigestObject(const std::string &algorithm, - const SECHashObject **hop) { - const SECHashObject *ho; - HASH_HashType hash_type; - - if (algorithm == DIGEST_SHA_1) { - hash_type = HASH_AlgSHA1; - // HASH_AlgSHA224 is not supported in the chromium linux build system. -#if 0 - } else if (algorithm == DIGEST_SHA_224) { - hash_type = HASH_AlgSHA224; -#endif - } else if (algorithm == DIGEST_SHA_256) { - hash_type = HASH_AlgSHA256; - } else if (algorithm == DIGEST_SHA_384) { - hash_type = HASH_AlgSHA384; - } else if (algorithm == DIGEST_SHA_512) { - hash_type = HASH_AlgSHA512; - } else { - return false; - } - - ho = HASH_GetHashObject(hash_type); - - ASSERT(ho->length >= 20); // Can't happen - *hop = ho; - - return true; -} - - -NSSIdentity* NSSIdentity::GenerateInternal(const SSLIdentityParams& params) { - std::string subject_name_string = "CN=" + params.common_name; - CERTName *subject_name = CERT_AsciiToName( - const_cast(subject_name_string.c_str())); - NSSIdentity *identity = NULL; - CERTSubjectPublicKeyInfo *spki = NULL; - CERTCertificateRequest *certreq = NULL; - CERTValidity *validity = NULL; - CERTCertificate *certificate = NULL; - NSSKeyPair *keypair = NSSKeyPair::Generate(); - SECItem inner_der; - SECStatus rv; - PLArenaPool* arena; - SECItem signed_cert; - PRTime now = PR_Now(); - PRTime not_before = - now + static_cast(params.not_before) * PR_USEC_PER_SEC; - PRTime not_after = - now + static_cast(params.not_after) * PR_USEC_PER_SEC; - - inner_der.len = 0; - inner_der.data = NULL; - - if (!keypair) { - LOG(LS_ERROR) << "Couldn't generate key pair"; - goto fail; - } - - if (!subject_name) { - LOG(LS_ERROR) << "Couldn't convert subject name " << subject_name; - goto fail; - } - - spki = SECKEY_CreateSubjectPublicKeyInfo(keypair->pubkey()); - if (!spki) { - LOG(LS_ERROR) << "Couldn't create SPKI"; - goto fail; - } - - certreq = CERT_CreateCertificateRequest(subject_name, spki, NULL); - if (!certreq) { - LOG(LS_ERROR) << "Couldn't create certificate signing request"; - goto fail; - } - - validity = CERT_CreateValidity(not_before, not_after); - if (!validity) { - LOG(LS_ERROR) << "Couldn't create validity"; - goto fail; - } - - unsigned long serial; - // Note: This serial in principle could collide, but it's unlikely - rv = PK11_GenerateRandom(reinterpret_cast(&serial), - sizeof(serial)); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Couldn't generate random serial"; - goto fail; - } - - certificate = CERT_CreateCertificate(serial, subject_name, validity, certreq); - if (!certificate) { - LOG(LS_ERROR) << "Couldn't create certificate"; - goto fail; - } - - arena = certificate->arena; - - rv = SECOID_SetAlgorithmID(arena, &certificate->signature, - SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, NULL); - if (rv != SECSuccess) - goto fail; - - // Set version to X509v3. - *(certificate->version.data) = 2; - certificate->version.len = 1; - - if (!SEC_ASN1EncodeItem(arena, &inner_der, certificate, - SEC_ASN1_GET(CERT_CertificateTemplate))) - goto fail; - - rv = SEC_DerSignData(arena, &signed_cert, inner_der.data, inner_der.len, - keypair->privkey(), - SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Couldn't sign certificate"; - goto fail; - } - certificate->derCert = signed_cert; - - identity = new NSSIdentity(keypair, new NSSCertificate(certificate)); - - goto done; - - fail: - delete keypair; - - done: - if (certificate) CERT_DestroyCertificate(certificate); - if (subject_name) CERT_DestroyName(subject_name); - if (spki) SECKEY_DestroySubjectPublicKeyInfo(spki); - if (certreq) CERT_DestroyCertificateRequest(certreq); - if (validity) CERT_DestroyValidity(validity); - 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; - if (!SSLIdentity::PemToDer( - kPemTypeRsaPrivateKey, private_key, &private_key_der)) - return NULL; - - SECItem private_key_item; - private_key_item.data = reinterpret_cast( - const_cast(private_key_der.c_str())); - private_key_item.len = checked_cast(private_key_der.size()); - - const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | - KU_DIGITAL_SIGNATURE; - - SECKEYPrivateKey* privkey = NULL; - SECStatus rv = - PK11_ImportDERPrivateKeyInfoAndReturnKey(NSSContext::GetSlot(), - &private_key_item, - NULL, NULL, PR_FALSE, PR_FALSE, - key_usage, &privkey, NULL); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Couldn't import private key"; - return NULL; - } - - SECKEYPublicKey *pubkey = SECKEY_ConvertToPublicKey(privkey); - if (rv != SECSuccess) { - SECKEY_DestroyPrivateKey(privkey); - LOG(LS_ERROR) << "Couldn't convert private key to public key"; - return NULL; - } - - // Assign to a scoped_ptr so we don't leak on error. - scoped_ptr keypair(new NSSKeyPair(privkey, pubkey)); - - scoped_ptr cert(NSSCertificate::FromPEMString(certificate)); - if (!cert) { - LOG(LS_ERROR) << "Couldn't parse certificate"; - return NULL; - } - - // TODO(ekr@rtfm.com): Check the public key against the certificate. - - return new NSSIdentity(keypair.release(), cert.release()); -} - -NSSIdentity *NSSIdentity::GetReference() const { - NSSKeyPair *keypair = keypair_->GetReference(); - if (!keypair) - return NULL; - - NSSCertificate *certificate = certificate_->GetReference(); - if (!certificate) { - delete keypair; - return NULL; - } - - return new NSSIdentity(keypair, certificate); -} - - -NSSCertificate &NSSIdentity::certificate() const { - return *certificate_; -} - - -} // rtc namespace - -#endif // HAVE_NSS_SSL_H - diff --git a/webrtc/base/nssidentity.h b/webrtc/base/nssidentity.h deleted file mode 100644 index 2c56c002b..000000000 --- a/webrtc/base/nssidentity.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NSSIDENTITY_H_ -#define WEBRTC_BASE_NSSIDENTITY_H_ - -#include - -#include "cert.h" -#include "nspr.h" -#include "hasht.h" -#include "keythi.h" - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/sslidentity.h" - -namespace rtc { - -class NSSKeyPair { - public: - NSSKeyPair(SECKEYPrivateKey* privkey, SECKEYPublicKey* pubkey) : - privkey_(privkey), pubkey_(pubkey) {} - ~NSSKeyPair(); - - // Generate a 1024-bit RSA key pair. - static NSSKeyPair* Generate(); - NSSKeyPair* GetReference(); - - SECKEYPrivateKey* privkey() const { return privkey_; } - SECKEYPublicKey * pubkey() const { return pubkey_; } - - private: - SECKEYPrivateKey* privkey_; - SECKEYPublicKey* pubkey_; - - DISALLOW_EVIL_CONSTRUCTORS(NSSKeyPair); -}; - - -class NSSCertificate : public SSLCertificate { - public: - static NSSCertificate* FromPEMString(const std::string& pem_string); - // The caller retains ownership of the argument to all the constructors, - // and the constructor makes a copy. - explicit NSSCertificate(CERTCertificate* cert); - explicit NSSCertificate(CERTCertList* cert_list); - virtual ~NSSCertificate() { - if (certificate_) - CERT_DestroyCertificate(certificate_); - } - - virtual NSSCertificate* GetReference() const; - - virtual std::string ToPEMString() const; - - virtual void ToDER(Buffer* der_buffer) const; - - virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const; - - virtual bool ComputeDigest(const std::string& algorithm, - 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, size_t* length); - - // Comparison. Only the certificate itself is considered, not the chain. - bool Equals(const NSSCertificate* tocompare) const; - - private: - NSSCertificate(CERTCertificate* cert, SSLCertChain* chain); - static bool GetDigestObject(const std::string& algorithm, - const SECHashObject** hash_object); - - CERTCertificate* certificate_; - scoped_ptr chain_; - - DISALLOW_EVIL_CONSTRUCTORS(NSSCertificate); -}; - -// Represents a SSL key pair and certificate for NSS. -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() { - LOG(LS_INFO) << "Destroying NSS identity"; - } - - virtual NSSIdentity* GetReference() const; - virtual NSSCertificate& certificate() const; - - NSSKeyPair* keypair() const { return keypair_.get(); } - - private: - NSSIdentity(NSSKeyPair* keypair, NSSCertificate* cert) : - keypair_(keypair), certificate_(cert) {} - - static NSSIdentity* GenerateInternal(const SSLIdentityParams& params); - - rtc::scoped_ptr keypair_; - rtc::scoped_ptr certificate_; - - DISALLOW_EVIL_CONSTRUCTORS(NSSIdentity); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_NSSIDENTITY_H_ diff --git a/webrtc/base/nssstreamadapter.cc b/webrtc/base/nssstreamadapter.cc deleted file mode 100644 index 1d06c1c4f..000000000 --- a/webrtc/base/nssstreamadapter.cc +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#if HAVE_NSS_SSL_H - -#include "webrtc/base/nssstreamadapter.h" - -#include "keyhi.h" -#include "nspr.h" -#include "nss.h" -#include "pk11pub.h" -#include "secerr.h" - -#ifdef NSS_SSL_RELATIVE_PATH -#include "ssl.h" -#include "sslerr.h" -#include "sslproto.h" -#else -#include "net/third_party/nss/ssl/ssl.h" -#include "net/third_party/nss/ssl/sslerr.h" -#include "net/third_party/nss/ssl/sslproto.h" -#endif - -#include "webrtc/base/nssidentity.h" -#include "webrtc/base/safe_conversions.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -PRDescIdentity NSSStreamAdapter::nspr_layer_identity = PR_INVALID_IO_LAYER; - -#define UNIMPLEMENTED \ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); \ - LOG(LS_ERROR) \ - << "Call to unimplemented function "<< __FUNCTION__; ASSERT(false) - -#ifdef SRTP_AES128_CM_HMAC_SHA1_80 -#define HAVE_DTLS_SRTP -#endif - -#ifdef HAVE_DTLS_SRTP -// SRTP cipher suite table -struct SrtpCipherMapEntry { - const char* external_name; - PRUint16 cipher_id; -}; - -// This isn't elegant, but it's better than an external reference -static const SrtpCipherMapEntry kSrtpCipherMap[] = { - {"AES_CM_128_HMAC_SHA1_80", SRTP_AES128_CM_HMAC_SHA1_80 }, - {"AES_CM_128_HMAC_SHA1_32", SRTP_AES128_CM_HMAC_SHA1_32 }, - {NULL, 0} -}; -#endif - - -// Implementation of NSPR methods -static PRStatus StreamClose(PRFileDesc *socket) { - ASSERT(!socket->lower); - socket->dtor(socket); - return PR_SUCCESS; -} - -static PRInt32 StreamRead(PRFileDesc *socket, void *buf, PRInt32 length) { - StreamInterface *stream = reinterpret_cast(socket->secret); - size_t read; - int error; - StreamResult result = stream->Read(buf, length, &read, &error); - if (result == SR_SUCCESS) { - return checked_cast(read); - } - - if (result == SR_EOS) { - return 0; - } - - if (result == SR_BLOCK) { - PR_SetError(PR_WOULD_BLOCK_ERROR, 0); - return -1; - } - - PR_SetError(PR_UNKNOWN_ERROR, error); - return -1; -} - -static PRInt32 StreamWrite(PRFileDesc *socket, const void *buf, - PRInt32 length) { - StreamInterface *stream = reinterpret_cast(socket->secret); - size_t written; - int error; - StreamResult result = stream->Write(buf, length, &written, &error); - if (result == SR_SUCCESS) { - return checked_cast(written); - } - - if (result == SR_BLOCK) { - LOG(LS_INFO) << - "NSSStreamAdapter: write to underlying transport would block"; - PR_SetError(PR_WOULD_BLOCK_ERROR, 0); - return -1; - } - - LOG(LS_ERROR) << "Write error"; - PR_SetError(PR_UNKNOWN_ERROR, error); - return -1; -} - -static PRInt32 StreamAvailable(PRFileDesc *socket) { - UNIMPLEMENTED; - return -1; -} - -PRInt64 StreamAvailable64(PRFileDesc *socket) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamSync(PRFileDesc *socket) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PROffset32 StreamSeek(PRFileDesc *socket, PROffset32 offset, - PRSeekWhence how) { - UNIMPLEMENTED; - return -1; -} - -static PROffset64 StreamSeek64(PRFileDesc *socket, PROffset64 offset, - PRSeekWhence how) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamFileInfo(PRFileDesc *socket, PRFileInfo *info) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRStatus StreamFileInfo64(PRFileDesc *socket, PRFileInfo64 *info) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRInt32 StreamWritev(PRFileDesc *socket, const PRIOVec *iov, - PRInt32 iov_size, PRIntervalTime timeout) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamConnect(PRFileDesc *socket, const PRNetAddr *addr, - PRIntervalTime timeout) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRFileDesc *StreamAccept(PRFileDesc *sd, PRNetAddr *addr, - PRIntervalTime timeout) { - UNIMPLEMENTED; - return NULL; -} - -static PRStatus StreamBind(PRFileDesc *socket, const PRNetAddr *addr) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRStatus StreamListen(PRFileDesc *socket, PRIntn depth) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRStatus StreamShutdown(PRFileDesc *socket, PRIntn how) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -// Note: this is always nonblocking and ignores the timeout. -// TODO(ekr@rtfm.com): In future verify that the socket is -// actually in non-blocking mode. -// This function does not support peek. -static PRInt32 StreamRecv(PRFileDesc *socket, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime to) { - ASSERT(flags == 0); - - if (flags != 0) { - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return -1; - } - - return StreamRead(socket, buf, amount); -} - -// Note: this is always nonblocking and assumes a zero timeout. -// This function does not support peek. -static PRInt32 StreamSend(PRFileDesc *socket, const void *buf, - PRInt32 amount, PRIntn flags, - PRIntervalTime to) { - ASSERT(flags == 0); - - return StreamWrite(socket, buf, amount); -} - -static PRInt32 StreamRecvfrom(PRFileDesc *socket, void *buf, - PRInt32 amount, PRIntn flags, - PRNetAddr *addr, PRIntervalTime to) { - UNIMPLEMENTED; - return -1; -} - -static PRInt32 StreamSendto(PRFileDesc *socket, const void *buf, - PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRIntervalTime to) { - UNIMPLEMENTED; - return -1; -} - -static PRInt16 StreamPoll(PRFileDesc *socket, PRInt16 in_flags, - PRInt16 *out_flags) { - UNIMPLEMENTED; - return -1; -} - -static PRInt32 StreamAcceptRead(PRFileDesc *sd, PRFileDesc **nd, - PRNetAddr **raddr, - void *buf, PRInt32 amount, PRIntervalTime t) { - UNIMPLEMENTED; - return -1; -} - -static PRInt32 StreamTransmitFile(PRFileDesc *sd, PRFileDesc *socket, - const void *headers, PRInt32 hlen, - PRTransmitFileFlags flags, PRIntervalTime t) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamGetPeerName(PRFileDesc *socket, PRNetAddr *addr) { - // TODO(ekr@rtfm.com): Modify to return unique names for each channel - // somehow, as opposed to always the same static address. The current - // implementation messes up the session cache, which is why it's off - // elsewhere - addr->inet.family = PR_AF_INET; - addr->inet.port = 0; - addr->inet.ip = 0; - - return PR_SUCCESS; -} - -static PRStatus StreamGetSockName(PRFileDesc *socket, PRNetAddr *addr) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRStatus StreamGetSockOption(PRFileDesc *socket, PRSocketOptionData *opt) { - switch (opt->option) { - case PR_SockOpt_Nonblocking: - opt->value.non_blocking = PR_TRUE; - return PR_SUCCESS; - default: - UNIMPLEMENTED; - break; - } - - return PR_FAILURE; -} - -// Imitate setting socket options. These are mostly noops. -static PRStatus StreamSetSockOption(PRFileDesc *socket, - const PRSocketOptionData *opt) { - switch (opt->option) { - case PR_SockOpt_Nonblocking: - return PR_SUCCESS; - case PR_SockOpt_NoDelay: - return PR_SUCCESS; - default: - UNIMPLEMENTED; - break; - } - - return PR_FAILURE; -} - -static PRInt32 StreamSendfile(PRFileDesc *out, PRSendFileData *in, - PRTransmitFileFlags flags, PRIntervalTime to) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamConnectContinue(PRFileDesc *socket, PRInt16 flags) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRIntn StreamReserved(PRFileDesc *socket) { - UNIMPLEMENTED; - return -1; -} - -static const struct PRIOMethods nss_methods = { - PR_DESC_LAYERED, - StreamClose, - StreamRead, - StreamWrite, - StreamAvailable, - StreamAvailable64, - StreamSync, - StreamSeek, - StreamSeek64, - StreamFileInfo, - StreamFileInfo64, - StreamWritev, - StreamConnect, - StreamAccept, - StreamBind, - StreamListen, - StreamShutdown, - StreamRecv, - StreamSend, - StreamRecvfrom, - StreamSendto, - StreamPoll, - StreamAcceptRead, - StreamTransmitFile, - StreamGetSockName, - StreamGetPeerName, - StreamReserved, - StreamReserved, - StreamGetSockOption, - StreamSetSockOption, - StreamSendfile, - StreamConnectContinue, - StreamReserved, - StreamReserved, - StreamReserved, - StreamReserved -}; - -NSSStreamAdapter::NSSStreamAdapter(StreamInterface *stream) - : SSLStreamAdapterHelper(stream), - ssl_fd_(NULL), - cert_ok_(false) { -} - -bool NSSStreamAdapter::Init() { - if (nspr_layer_identity == PR_INVALID_IO_LAYER) { - nspr_layer_identity = PR_GetUniqueIdentity("nssstreamadapter"); - } - PRFileDesc *pr_fd = PR_CreateIOLayerStub(nspr_layer_identity, &nss_methods); - if (!pr_fd) - return false; - pr_fd->secret = reinterpret_cast(stream()); - - PRFileDesc *ssl_fd; - if (ssl_mode_ == SSL_MODE_DTLS) { - ssl_fd = DTLS_ImportFD(NULL, pr_fd); - } else { - ssl_fd = SSL_ImportFD(NULL, pr_fd); - } - ASSERT(ssl_fd != NULL); // This should never happen - if (!ssl_fd) { - PR_Close(pr_fd); - return false; - } - - SECStatus rv; - // Turn on security. - rv = SSL_OptionSet(ssl_fd, SSL_SECURITY, PR_TRUE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error enabling security on SSL Socket"; - return false; - } - - // Disable SSLv2. - rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_SSL2, PR_FALSE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error disabling SSL2"; - return false; - } - - // Disable caching. - // TODO(ekr@rtfm.com): restore this when I have the caching - // identity set. - rv = SSL_OptionSet(ssl_fd, SSL_NO_CACHE, PR_TRUE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error disabling cache"; - return false; - } - - // Disable session tickets. - rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error enabling tickets"; - return false; - } - - // Disable renegotiation. - rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_RENEGOTIATION, - SSL_RENEGOTIATE_NEVER); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error disabling renegotiation"; - return false; - } - - // Disable false start. - rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_FALSE_START, PR_FALSE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error disabling false start"; - return false; - } - - ssl_fd_ = ssl_fd; - - return true; -} - -NSSStreamAdapter::~NSSStreamAdapter() { - if (ssl_fd_) - PR_Close(ssl_fd_); -}; - - -int NSSStreamAdapter::BeginSSL() { - SECStatus rv; - - if (!Init()) { - Error("Init", -1, false); - return -1; - } - - ASSERT(state_ == SSL_CONNECTING); - // The underlying stream has been opened. 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_.get() != NULL || - !peer_certificate_digest_algorithm_.empty()); - LOG(LS_INFO) << "BeginSSL: " - << (!ssl_server_name_.empty() ? ssl_server_name_ : - "with peer"); - - if (role_ == SSL_CLIENT) { - LOG(LS_INFO) << "BeginSSL: as client"; - - rv = SSL_GetClientAuthDataHook(ssl_fd_, GetClientAuthDataHook, - this); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - } else { - LOG(LS_INFO) << "BeginSSL: as server"; - NSSIdentity *identity; - - if (identity_.get()) { - identity = static_cast(identity_.get()); - } else { - LOG(LS_ERROR) << "Can't be an SSL server without an identity"; - Error("BeginSSL", -1, false); - return -1; - } - rv = SSL_ConfigSecureServer(ssl_fd_, identity->certificate().certificate(), - identity->keypair()->privkey(), - kt_rsa); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - - // Insist on a certificate from the client - rv = SSL_OptionSet(ssl_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - - rv = SSL_OptionSet(ssl_fd_, SSL_REQUIRE_CERTIFICATE, PR_TRUE); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - } - - // Set the version range. - SSLVersionRange vrange; - vrange.min = (ssl_mode_ == SSL_MODE_DTLS) ? - 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); - return -1; - } - - // SRTP -#ifdef HAVE_DTLS_SRTP - if (!srtp_ciphers_.empty()) { - rv = SSL_SetSRTPCiphers( - ssl_fd_, &srtp_ciphers_[0], - checked_cast(srtp_ciphers_.size())); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - } -#endif - - // Certificate validation - rv = SSL_AuthCertificateHook(ssl_fd_, AuthCertificateHook, this); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - - // Now start the handshake - rv = SSL_ResetHandshake(ssl_fd_, role_ == SSL_SERVER ? PR_TRUE : PR_FALSE); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - - return ContinueSSL(); -} - -int NSSStreamAdapter::ContinueSSL() { - LOG(LS_INFO) << "ContinueSSL"; - ASSERT(state_ == SSL_CONNECTING); - - // Clear the DTLS timer - Thread::Current()->Clear(this, MSG_DTLS_TIMEOUT); - - SECStatus rv = SSL_ForceHandshake(ssl_fd_); - - if (rv == SECSuccess) { - LOG(LS_INFO) << "Handshake complete"; - - ASSERT(cert_ok_); - if (!cert_ok_) { - Error("ContinueSSL", -1, true); - return -1; - } - - state_ = SSL_CONNECTED; - StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0); - return 0; - } - - PRInt32 err = PR_GetError(); - switch (err) { - case SSL_ERROR_RX_MALFORMED_HANDSHAKE: - if (ssl_mode_ != SSL_MODE_DTLS) { - Error("ContinueSSL", -1, true); - return -1; - } else { - LOG(LS_INFO) << "Malformed DTLS message. Ignoring."; - // Fall through - } - case PR_WOULD_BLOCK_ERROR: - LOG(LS_INFO) << "Would have blocked"; - if (ssl_mode_ == SSL_MODE_DTLS) { - PRIntervalTime timeout; - - SECStatus rv = DTLS_GetHandshakeTimeout(ssl_fd_, &timeout); - if (rv == SECSuccess) { - LOG(LS_INFO) << "Timeout is " << timeout << " ms"; - Thread::Current()->PostDelayed(PR_IntervalToMilliseconds(timeout), - this, MSG_DTLS_TIMEOUT, 0); - } - } - - return 0; - default: - LOG(LS_INFO) << "Error " << err; - break; - } - - Error("ContinueSSL", -1, true); - return -1; -} - -void NSSStreamAdapter::Cleanup() { - if (state_ != SSL_ERROR) { - state_ = SSL_CLOSED; - } - - if (ssl_fd_) { - PR_Close(ssl_fd_); - ssl_fd_ = NULL; - } - - identity_.reset(); - peer_certificate_.reset(); - - Thread::Current()->Clear(this, MSG_DTLS_TIMEOUT); -} - -StreamResult NSSStreamAdapter::Read(void* data, size_t data_len, - size_t* read, int* error) { - // SSL_CONNECTED sanity check. - switch (state_) { - case SSL_NONE: - case SSL_WAIT: - case SSL_CONNECTING: - return SR_BLOCK; - - case SSL_CONNECTED: - break; - - case SSL_CLOSED: - return SR_EOS; - - case SSL_ERROR: - default: - if (error) - *error = ssl_error_code_; - return SR_ERROR; - } - - PRInt32 rv = PR_Read(ssl_fd_, data, checked_cast(data_len)); - - if (rv == 0) { - return SR_EOS; - } - - // Error - if (rv < 0) { - PRInt32 err = PR_GetError(); - - switch (err) { - case PR_WOULD_BLOCK_ERROR: - return SR_BLOCK; - default: - Error("Read", -1, false); - *error = err; // libjingle semantics are that this is impl-specific - return SR_ERROR; - } - } - - // Success - *read = rv; - - return SR_SUCCESS; -} - -StreamResult NSSStreamAdapter::Write(const void* data, size_t data_len, - size_t* written, int* error) { - // SSL_CONNECTED sanity check. - switch (state_) { - case SSL_NONE: - case SSL_WAIT: - case SSL_CONNECTING: - return SR_BLOCK; - - case SSL_CONNECTED: - break; - - case SSL_ERROR: - case SSL_CLOSED: - default: - if (error) - *error = ssl_error_code_; - return SR_ERROR; - } - - PRInt32 rv = PR_Write(ssl_fd_, data, checked_cast(data_len)); - - // Error - if (rv < 0) { - PRInt32 err = PR_GetError(); - - switch (err) { - case PR_WOULD_BLOCK_ERROR: - return SR_BLOCK; - default: - Error("Write", -1, false); - *error = err; // libjingle semantics are that this is impl-specific - return SR_ERROR; - } - } - - // Success - *written = rv; - - return SR_SUCCESS; -} - -void NSSStreamAdapter::OnEvent(StreamInterface* stream, int events, - int err) { - int events_to_signal = 0; - int signal_error = 0; - ASSERT(stream == this->stream()); - if ((events & SE_OPEN)) { - LOG(LS_INFO) << "NSSStreamAdapter::OnEvent SE_OPEN"; - if (state_ != SSL_WAIT) { - ASSERT(state_ == SSL_NONE); - events_to_signal |= SE_OPEN; - } else { - state_ = SSL_CONNECTING; - if (int err = BeginSSL()) { - Error("BeginSSL", err, true); - return; - } - } - } - if ((events & (SE_READ|SE_WRITE))) { - LOG(LS_INFO) << "NSSStreamAdapter::OnEvent" - << ((events & SE_READ) ? " SE_READ" : "") - << ((events & SE_WRITE) ? " SE_WRITE" : ""); - if (state_ == SSL_NONE) { - events_to_signal |= events & (SE_READ|SE_WRITE); - } else if (state_ == SSL_CONNECTING) { - if (int err = ContinueSSL()) { - Error("ContinueSSL", err, true); - return; - } - } else if (state_ == SSL_CONNECTED) { - if (events & SE_WRITE) { - LOG(LS_INFO) << " -- onStreamWriteable"; - events_to_signal |= SE_WRITE; - } - if (events & SE_READ) { - LOG(LS_INFO) << " -- onStreamReadable"; - events_to_signal |= SE_READ; - } - } - } - if ((events & SE_CLOSE)) { - LOG(LS_INFO) << "NSSStreamAdapter::OnEvent(SE_CLOSE, " << err << ")"; - Cleanup(); - events_to_signal |= SE_CLOSE; - // SE_CLOSE is the only event that uses the final parameter to OnEvent(). - ASSERT(signal_error == 0); - signal_error = err; - } - if (events_to_signal) - StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error); -} - -void NSSStreamAdapter::OnMessage(Message* msg) { - // Process our own messages and then pass others to the superclass - if (MSG_DTLS_TIMEOUT == msg->message_id) { - LOG(LS_INFO) << "DTLS timeout expired"; - ContinueSSL(); - } else { - StreamInterface::OnMessage(msg); - } -} - -// Certificate verification callback. Called to check any certificate -SECStatus NSSStreamAdapter::AuthCertificateHook(void *arg, - PRFileDesc *fd, - PRBool checksig, - PRBool isServer) { - LOG(LS_INFO) << "NSSStreamAdapter::AuthCertificateHook"; - // 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); - - NSSStreamAdapter *stream = reinterpret_cast(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"; - - // The peer certificate was specified - if (reinterpret_cast(stream->peer_certificate_.get())-> - Equals(&peer_cert)) { - LOG(LS_INFO) << "Accepted peer certificate"; - 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 - size_t digest_length; - - if (!peer_cert.ComputeDigest( - stream->peer_certificate_digest_algorithm_, - digest, sizeof(digest), &digest_length)) { - LOG(LS_ERROR) << "Digest computation failed"; - } else { - Buffer computed_digest(digest, digest_length); - if (computed_digest == stream->peer_certificate_digest_value_) { - LOG(LS_INFO) << "Accepted peer certificate"; - stream->cert_ok_ = true; - } - } - } else { - // Other modes, but we haven't implemented yet - // TODO(ekr@rtfm.com): Implement real certificate validation - UNIMPLEMENTED; - } - - if (!stream->cert_ok_ && stream->ignore_bad_cert()) { - LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain"; - stream->cert_ok_ = true; - } - - if (stream->cert_ok_) - stream->peer_certificate_.reset(new NSSCertificate(cert_list)); - - CERT_DestroyCertList(cert_list); - - if (stream->cert_ok_) - return SECSuccess; - - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - return SECFailure; -} - - -SECStatus NSSStreamAdapter::GetClientAuthDataHook(void *arg, PRFileDesc *fd, - CERTDistNames *caNames, - CERTCertificate **pRetCert, - SECKEYPrivateKey **pRetKey) { - LOG(LS_INFO) << "Client cert requested"; - NSSStreamAdapter *stream = reinterpret_cast(arg); - - if (!stream->identity_.get()) { - LOG(LS_ERROR) << "No identity available"; - return SECFailure; - } - - NSSIdentity *identity = static_cast(stream->identity_.get()); - // Destroyed internally by NSS - *pRetCert = CERT_DupCertificate(identity->certificate().certificate()); - *pRetKey = SECKEY_CopyPrivateKey(identity->keypair()->privkey()); - - return SECSuccess; -} - -// RFC 5705 Key Exporter -bool NSSStreamAdapter::ExportKeyingMaterial(const std::string& label, - const uint8* context, - size_t context_len, - bool use_context, - uint8* result, - size_t result_len) { - SECStatus rv = SSL_ExportKeyingMaterial( - ssl_fd_, - label.c_str(), - checked_cast(label.size()), - use_context, - context, - checked_cast(context_len), - result, - checked_cast(result_len)); - - return rv == SECSuccess; -} - -bool NSSStreamAdapter::SetDtlsSrtpCiphers( - const std::vector& ciphers) { -#ifdef HAVE_DTLS_SRTP - std::vector internal_ciphers; - if (state_ != SSL_NONE) - return false; - - for (std::vector::const_iterator cipher = ciphers.begin(); - cipher != ciphers.end(); ++cipher) { - bool found = false; - for (const SrtpCipherMapEntry *entry = kSrtpCipherMap; entry->cipher_id; - ++entry) { - if (*cipher == entry->external_name) { - found = true; - internal_ciphers.push_back(entry->cipher_id); - break; - } - } - - if (!found) { - LOG(LS_ERROR) << "Could not find cipher: " << *cipher; - return false; - } - } - - if (internal_ciphers.empty()) - return false; - - srtp_ciphers_ = internal_ciphers; - - return true; -#else - return false; -#endif -} - -bool NSSStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) { -#ifdef HAVE_DTLS_SRTP - ASSERT(state_ == SSL_CONNECTED); - if (state_ != SSL_CONNECTED) - return false; - - PRUint16 selected_cipher; - - SECStatus rv = SSL_GetSRTPCipher(ssl_fd_, &selected_cipher); - if (rv == SECFailure) - return false; - - for (const SrtpCipherMapEntry *entry = kSrtpCipherMap; - entry->cipher_id; ++entry) { - if (selected_cipher == entry->cipher_id) { - *cipher = entry->external_name; - return true; - } - } - - ASSERT(false); // This should never happen -#endif - return false; -} - - -bool NSSContext::initialized; -NSSContext *NSSContext::global_nss_context; - -// Static initialization and shutdown -NSSContext *NSSContext::Instance() { - if (!global_nss_context) { - NSSContext *new_ctx = new NSSContext(); - - if (!(new_ctx->slot_ = PK11_GetInternalSlot())) { - delete new_ctx; - goto fail; - } - - global_nss_context = new_ctx; - } - - fail: - return global_nss_context; -} - - - -bool NSSContext::InitializeSSL(VerificationCallback callback) { - ASSERT(!callback); - - if (!initialized) { - SECStatus rv; - - rv = NSS_NoDB_Init(NULL); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Couldn't initialize NSS error=" << - PORT_GetError(); - return false; - } - - NSS_SetDomesticPolicy(); - - initialized = true; - } - - return true; -} - -bool NSSContext::InitializeSSLThread() { - // Not needed - return true; -} - -bool NSSContext::CleanupSSL() { - // Not needed - return true; -} - -bool NSSStreamAdapter::HaveDtls() { - return true; -} - -bool NSSStreamAdapter::HaveDtlsSrtp() { -#ifdef HAVE_DTLS_SRTP - return true; -#else - return false; -#endif -} - -bool NSSStreamAdapter::HaveExporter() { - return true; -} - -} // namespace rtc - -#endif // HAVE_NSS_SSL_H diff --git a/webrtc/base/nssstreamadapter.h b/webrtc/base/nssstreamadapter.h deleted file mode 100644 index 210a47933..000000000 --- a/webrtc/base/nssstreamadapter.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NSSSTREAMADAPTER_H_ -#define WEBRTC_BASE_NSSSTREAMADAPTER_H_ - -#include -#include - -#include "nspr.h" -#include "nss.h" -#include "secmodt.h" - -#include "webrtc/base/buffer.h" -#include "webrtc/base/nssidentity.h" -#include "webrtc/base/ssladapter.h" -#include "webrtc/base/sslstreamadapter.h" -#include "webrtc/base/sslstreamadapterhelper.h" - -namespace rtc { - -// Singleton -class NSSContext { - public: - NSSContext() {} - ~NSSContext() { - } - - static PK11SlotInfo *GetSlot() { - return Instance() ? Instance()->slot_: NULL; - } - - static NSSContext *Instance(); - static bool InitializeSSL(VerificationCallback callback); - static bool InitializeSSLThread(); - static bool CleanupSSL(); - - private: - PK11SlotInfo *slot_; // The PKCS-11 slot - static bool initialized; // Was this initialized? - static NSSContext *global_nss_context; // The global context -}; - - -class NSSStreamAdapter : public SSLStreamAdapterHelper { - public: - explicit NSSStreamAdapter(StreamInterface* stream); - virtual ~NSSStreamAdapter(); - bool Init(); - - virtual StreamResult Read(void* data, size_t data_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - void OnMessage(Message *msg); - - // Key Extractor interface - virtual bool ExportKeyingMaterial(const std::string& label, - const uint8* context, - size_t context_len, - bool use_context, - uint8* result, - size_t result_len); - - // DTLS-SRTP interface - virtual bool SetDtlsSrtpCiphers(const std::vector& ciphers); - virtual bool GetDtlsSrtpCipher(std::string* cipher); - - // Capabilities interfaces - static bool HaveDtls(); - static bool HaveDtlsSrtp(); - static bool HaveExporter(); - - protected: - // Override SSLStreamAdapter - virtual void OnEvent(StreamInterface* stream, int events, int err); - - // Override SSLStreamAdapterHelper - virtual int BeginSSL(); - virtual void Cleanup(); - virtual bool GetDigestLength(const std::string& algorithm, size_t* length) { - return NSSCertificate::GetDigestLength(algorithm, length); - } - - private: - int ContinueSSL(); - static SECStatus AuthCertificateHook(void *arg, PRFileDesc *fd, - PRBool checksig, PRBool isServer); - static SECStatus GetClientAuthDataHook(void *arg, PRFileDesc *fd, - CERTDistNames *caNames, - CERTCertificate **pRetCert, - SECKEYPrivateKey **pRetKey); - - PRFileDesc *ssl_fd_; // NSS's SSL file descriptor - static bool initialized; // Was InitializeSSL() called? - bool cert_ok_; // Did we get and check a cert - std::vector srtp_ciphers_; // SRTP cipher list - - static PRDescIdentity nspr_layer_identity; // The NSPR layer identity -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_NSSSTREAMADAPTER_H_ diff --git a/webrtc/base/nullsocketserver.h b/webrtc/base/nullsocketserver.h deleted file mode 100644 index 5378e4315..000000000 --- a/webrtc/base/nullsocketserver.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NULLSOCKETSERVER_H_ -#define WEBRTC_BASE_NULLSOCKETSERVER_H_ - -#include "webrtc/base/event.h" -#include "webrtc/base/physicalsocketserver.h" - -namespace rtc { - -// NullSocketServer - -class NullSocketServer : public rtc::SocketServer { - public: - NullSocketServer() : event_(false, false) {} - - virtual bool Wait(int cms, bool process_io) { - event_.Wait(cms); - return true; - } - - virtual void WakeUp() { - event_.Set(); - } - - virtual rtc::Socket* CreateSocket(int type) { - ASSERT(false); - return NULL; - } - - virtual rtc::Socket* CreateSocket(int family, int type) { - ASSERT(false); - return NULL; - } - - virtual rtc::AsyncSocket* CreateAsyncSocket(int type) { - ASSERT(false); - return NULL; - } - - virtual rtc::AsyncSocket* CreateAsyncSocket(int family, int type) { - ASSERT(false); - return NULL; - } - - - private: - rtc::Event event_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_NULLSOCKETSERVER_H_ diff --git a/webrtc/base/nullsocketserver_unittest.cc b/webrtc/base/nullsocketserver_unittest.cc deleted file mode 100644 index fe21f6ad0..000000000 --- a/webrtc/base/nullsocketserver_unittest.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/nullsocketserver.h" - -namespace rtc { - -static const uint32 kTimeout = 5000U; - -class NullSocketServerTest - : public testing::Test, - public MessageHandler { - public: - NullSocketServerTest() {} - protected: - virtual void OnMessage(Message* message) { - ss_.WakeUp(); - } - NullSocketServer ss_; -}; - -TEST_F(NullSocketServerTest, WaitAndSet) { - Thread thread; - EXPECT_TRUE(thread.Start()); - thread.Post(this, 0); - // The process_io will be ignored. - const bool process_io = true; - EXPECT_TRUE_WAIT(ss_.Wait(rtc::kForever, process_io), kTimeout); -} - -TEST_F(NullSocketServerTest, TestWait) { - uint32 start = Time(); - ss_.Wait(200, true); - // The actual wait time is dependent on the resolution of the timer used by - // the Event class. Allow for the event to signal ~20ms early. - EXPECT_GE(TimeSince(start), 180); -} - -} // namespace rtc diff --git a/webrtc/base/openssl.h b/webrtc/base/openssl.h deleted file mode 100644 index 2071619d5..000000000 --- a/webrtc/base/openssl.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_OPENSSL_H_ -#define WEBRTC_BASE_OPENSSL_H_ - -#include - -#if (OPENSSL_VERSION_NUMBER < 0x10000000L) -#error OpenSSL is older than 1.0.0, which is the minimum supported version. -#endif - -#endif // WEBRTC_BASE_OPENSSL_H_ diff --git a/webrtc/base/openssladapter.cc b/webrtc/base/openssladapter.cc deleted file mode 100644 index d0311100e..000000000 --- a/webrtc/base/openssladapter.cc +++ /dev/null @@ -1,884 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if HAVE_OPENSSL_SSL_H - -#include "webrtc/base/openssladapter.h" - -#if defined(WEBRTC_POSIX) -#include -#endif - -// Must be included first before openssl headers. -#include "webrtc/base/win32.h" // NOLINT - -#include -#include -#include -#include -#include -#include - -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/openssl.h" -#include "webrtc/base/sslroots.h" -#include "webrtc/base/stringutils.h" - -// TODO: Use a nicer abstraction for mutex. - -#if defined(WEBRTC_WIN) - #define MUTEX_TYPE HANDLE - #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL) - #define MUTEX_CLEANUP(x) CloseHandle(x) - #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE) - #define MUTEX_UNLOCK(x) ReleaseMutex(x) - #define THREAD_ID GetCurrentThreadId() -#elif defined(WEBRTC_POSIX) - #define MUTEX_TYPE pthread_mutex_t - #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) - #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) - #define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) - #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) - #define THREAD_ID pthread_self() -#else - #error You must define mutex operations appropriate for your platform! -#endif - -struct CRYPTO_dynlock_value { - MUTEX_TYPE mutex; -}; - -////////////////////////////////////////////////////////////////////// -// SocketBIO -////////////////////////////////////////////////////////////////////// - -static int socket_write(BIO* h, const char* buf, int num); -static int socket_read(BIO* h, char* buf, int size); -static int socket_puts(BIO* h, const char* str); -static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2); -static int socket_new(BIO* h); -static int socket_free(BIO* data); - -static BIO_METHOD methods_socket = { - BIO_TYPE_BIO, - "socket", - socket_write, - socket_read, - socket_puts, - 0, - socket_ctrl, - socket_new, - socket_free, - NULL, -}; - -BIO_METHOD* BIO_s_socket2() { return(&methods_socket); } - -BIO* BIO_new_socket(rtc::AsyncSocket* socket) { - BIO* ret = BIO_new(BIO_s_socket2()); - if (ret == NULL) { - return NULL; - } - ret->ptr = socket; - return ret; -} - -static int socket_new(BIO* b) { - b->shutdown = 0; - b->init = 1; - b->num = 0; // 1 means socket closed - b->ptr = 0; - return 1; -} - -static int socket_free(BIO* b) { - if (b == NULL) - return 0; - return 1; -} - -static int socket_read(BIO* b, char* out, int outl) { - if (!out) - return -1; - rtc::AsyncSocket* socket = static_cast(b->ptr); - BIO_clear_retry_flags(b); - int result = socket->Recv(out, outl); - if (result > 0) { - return result; - } else if (result == 0) { - b->num = 1; - } else if (socket->IsBlocking()) { - BIO_set_retry_read(b); - } - return -1; -} - -static int socket_write(BIO* b, const char* in, int inl) { - if (!in) - return -1; - rtc::AsyncSocket* socket = static_cast(b->ptr); - BIO_clear_retry_flags(b); - int result = socket->Send(in, inl); - if (result > 0) { - return result; - } else if (socket->IsBlocking()) { - BIO_set_retry_write(b); - } - return -1; -} - -static int socket_puts(BIO* b, const char* str) { - return socket_write(b, str, strlen(str)); -} - -static long socket_ctrl(BIO* b, int cmd, long num, void* ptr) { - UNUSED(num); - UNUSED(ptr); - - switch (cmd) { - case BIO_CTRL_RESET: - return 0; - case BIO_CTRL_EOF: - return b->num; - case BIO_CTRL_WPENDING: - case BIO_CTRL_PENDING: - return 0; - case BIO_CTRL_FLUSH: - return 1; - default: - return 0; - } -} - -///////////////////////////////////////////////////////////////////////////// -// OpenSSLAdapter -///////////////////////////////////////////////////////////////////////////// - -namespace rtc { - -// This array will store all of the mutexes available to OpenSSL. -static MUTEX_TYPE* mutex_buf = NULL; - -static void locking_function(int mode, int n, const char * file, int line) { - if (mode & CRYPTO_LOCK) { - MUTEX_LOCK(mutex_buf[n]); - } else { - MUTEX_UNLOCK(mutex_buf[n]); - } -} - -static unsigned long id_function() { // NOLINT - // Use old-style C cast because THREAD_ID's type varies with the platform, - // in some cases requiring static_cast, and in others requiring - // reinterpret_cast. - return (unsigned long)THREAD_ID; // NOLINT -} - -static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) { - CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value; - if (!value) - return NULL; - MUTEX_SETUP(value->mutex); - return value; -} - -static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l, - const char* file, int line) { - if (mode & CRYPTO_LOCK) { - MUTEX_LOCK(l->mutex); - } else { - MUTEX_UNLOCK(l->mutex); - } -} - -static void dyn_destroy_function(CRYPTO_dynlock_value* l, - const char* file, int line) { - MUTEX_CLEANUP(l->mutex); - delete l; -} - -VerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL; - -bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) { - if (!InitializeSSLThread() || !SSL_library_init()) - return false; -#if !defined(ADDRESS_SANITIZER) || !defined(WEBRTC_MAC) || defined(WEBRTC_IOS) - // Loading the error strings crashes mac_asan. Omit this debugging aid there. - SSL_load_error_strings(); -#endif - ERR_load_BIO_strings(); - OpenSSL_add_all_algorithms(); - RAND_poll(); - custom_verify_callback_ = callback; - return true; -} - -bool OpenSSLAdapter::InitializeSSLThread() { - mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()]; - if (!mutex_buf) - return false; - for (int i = 0; i < CRYPTO_num_locks(); ++i) - MUTEX_SETUP(mutex_buf[i]); - - // we need to cast our id_function to return an unsigned long -- pthread_t is - // a pointer - CRYPTO_set_id_callback(id_function); - CRYPTO_set_locking_callback(locking_function); - CRYPTO_set_dynlock_create_callback(dyn_create_function); - CRYPTO_set_dynlock_lock_callback(dyn_lock_function); - CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); - return true; -} - -bool OpenSSLAdapter::CleanupSSL() { - if (!mutex_buf) - return false; - CRYPTO_set_id_callback(NULL); - CRYPTO_set_locking_callback(NULL); - CRYPTO_set_dynlock_create_callback(NULL); - CRYPTO_set_dynlock_lock_callback(NULL); - CRYPTO_set_dynlock_destroy_callback(NULL); - for (int i = 0; i < CRYPTO_num_locks(); ++i) - MUTEX_CLEANUP(mutex_buf[i]); - delete [] mutex_buf; - mutex_buf = NULL; - return true; -} - -OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket) - : SSLAdapter(socket), - state_(SSL_NONE), - ssl_read_needs_write_(false), - ssl_write_needs_read_(false), - restartable_(false), - ssl_(NULL), ssl_ctx_(NULL), - custom_verification_succeeded_(false) { -} - -OpenSSLAdapter::~OpenSSLAdapter() { - Cleanup(); -} - -int -OpenSSLAdapter::StartSSL(const char* hostname, bool restartable) { - if (state_ != SSL_NONE) - return -1; - - ssl_host_name_ = hostname; - restartable_ = restartable; - - if (socket_->GetState() != Socket::CS_CONNECTED) { - state_ = SSL_WAIT; - return 0; - } - - state_ = SSL_CONNECTING; - if (int err = BeginSSL()) { - Error("BeginSSL", err, false); - return err; - } - - return 0; -} - -int -OpenSSLAdapter::BeginSSL() { - LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_; - ASSERT(state_ == SSL_CONNECTING); - - int err = 0; - BIO* bio = NULL; - - // First set up the context - if (!ssl_ctx_) - ssl_ctx_ = SetupSSLContext(); - - if (!ssl_ctx_) { - err = -1; - goto ssl_error; - } - - bio = BIO_new_socket(static_cast(socket_)); - if (!bio) { - err = -1; - goto ssl_error; - } - - ssl_ = SSL_new(ssl_ctx_); - if (!ssl_) { - err = -1; - goto ssl_error; - } - - SSL_set_app_data(ssl_, this); - - SSL_set_bio(ssl_, bio, bio); - SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - - // the SSL object owns the bio now - bio = NULL; - - // Do the connect - err = ContinueSSL(); - if (err != 0) - goto ssl_error; - - return err; - -ssl_error: - Cleanup(); - if (bio) - BIO_free(bio); - - return err; -} - -int -OpenSSLAdapter::ContinueSSL() { - ASSERT(state_ == SSL_CONNECTING); - - int code = SSL_connect(ssl_); - switch (SSL_get_error(ssl_, code)) { - case SSL_ERROR_NONE: - if (!SSLPostConnectionCheck(ssl_, ssl_host_name_.c_str())) { - LOG(LS_ERROR) << "TLS post connection check failed"; - // make sure we close the socket - Cleanup(); - // The connect failed so return -1 to shut down the socket - return -1; - } - - state_ = SSL_CONNECTED; - AsyncSocketAdapter::OnConnectEvent(this); -#if 0 // TODO: worry about this - // Don't let ourselves go away during the callbacks - PRefPtr lock(this); - LOG(LS_INFO) << " -- onStreamReadable"; - AsyncSocketAdapter::OnReadEvent(this); - LOG(LS_INFO) << " -- onStreamWriteable"; - AsyncSocketAdapter::OnWriteEvent(this); -#endif - break; - - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - break; - - case SSL_ERROR_ZERO_RETURN: - default: - LOG(LS_WARNING) << "ContinueSSL -- error " << code; - return (code != 0) ? code : -1; - } - - return 0; -} - -void -OpenSSLAdapter::Error(const char* context, int err, bool signal) { - LOG(LS_WARNING) << "OpenSSLAdapter::Error(" - << context << ", " << err << ")"; - state_ = SSL_ERROR; - SetError(err); - if (signal) - AsyncSocketAdapter::OnCloseEvent(this, err); -} - -void -OpenSSLAdapter::Cleanup() { - LOG(LS_INFO) << "Cleanup"; - - state_ = SSL_NONE; - ssl_read_needs_write_ = false; - ssl_write_needs_read_ = false; - custom_verification_succeeded_ = false; - - if (ssl_) { - SSL_free(ssl_); - ssl_ = NULL; - } - - if (ssl_ctx_) { - SSL_CTX_free(ssl_ctx_); - ssl_ctx_ = NULL; - } -} - -// -// AsyncSocket Implementation -// - -int -OpenSSLAdapter::Send(const void* pv, size_t cb) { - //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")"; - - switch (state_) { - case SSL_NONE: - return AsyncSocketAdapter::Send(pv, cb); - - case SSL_WAIT: - case SSL_CONNECTING: - SetError(EWOULDBLOCK); - return SOCKET_ERROR; - - case SSL_CONNECTED: - break; - - case SSL_ERROR: - default: - return SOCKET_ERROR; - } - - // OpenSSL will return an error if we try to write zero bytes - if (cb == 0) - return 0; - - ssl_write_needs_read_ = false; - - int code = SSL_write(ssl_, pv, cb); - switch (SSL_get_error(ssl_, code)) { - case SSL_ERROR_NONE: - //LOG(LS_INFO) << " -- success"; - return code; - case SSL_ERROR_WANT_READ: - //LOG(LS_INFO) << " -- error want read"; - ssl_write_needs_read_ = true; - SetError(EWOULDBLOCK); - break; - case SSL_ERROR_WANT_WRITE: - //LOG(LS_INFO) << " -- error want write"; - SetError(EWOULDBLOCK); - break; - case SSL_ERROR_ZERO_RETURN: - //LOG(LS_INFO) << " -- remote side closed"; - SetError(EWOULDBLOCK); - // do we need to signal closure? - break; - default: - //LOG(LS_INFO) << " -- error " << code; - Error("SSL_write", (code ? code : -1), false); - break; - } - - return SOCKET_ERROR; -} - -int -OpenSSLAdapter::Recv(void* pv, size_t cb) { - //LOG(LS_INFO) << "OpenSSLAdapter::Recv(" << cb << ")"; - switch (state_) { - - case SSL_NONE: - return AsyncSocketAdapter::Recv(pv, cb); - - case SSL_WAIT: - case SSL_CONNECTING: - SetError(EWOULDBLOCK); - return SOCKET_ERROR; - - case SSL_CONNECTED: - break; - - case SSL_ERROR: - default: - return SOCKET_ERROR; - } - - // Don't trust OpenSSL with zero byte reads - if (cb == 0) - return 0; - - ssl_read_needs_write_ = false; - - int code = SSL_read(ssl_, pv, cb); - switch (SSL_get_error(ssl_, code)) { - case SSL_ERROR_NONE: - //LOG(LS_INFO) << " -- success"; - return code; - case SSL_ERROR_WANT_READ: - //LOG(LS_INFO) << " -- error want read"; - SetError(EWOULDBLOCK); - break; - case SSL_ERROR_WANT_WRITE: - //LOG(LS_INFO) << " -- error want write"; - ssl_read_needs_write_ = true; - SetError(EWOULDBLOCK); - break; - case SSL_ERROR_ZERO_RETURN: - //LOG(LS_INFO) << " -- remote side closed"; - SetError(EWOULDBLOCK); - // do we need to signal closure? - break; - default: - //LOG(LS_INFO) << " -- error " << code; - Error("SSL_read", (code ? code : -1), false); - break; - } - - return SOCKET_ERROR; -} - -int -OpenSSLAdapter::Close() { - Cleanup(); - state_ = restartable_ ? SSL_WAIT : SSL_NONE; - return AsyncSocketAdapter::Close(); -} - -Socket::ConnState -OpenSSLAdapter::GetState() const { - //if (signal_close_) - // return CS_CONNECTED; - ConnState state = socket_->GetState(); - if ((state == CS_CONNECTED) - && ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING))) - state = CS_CONNECTING; - return state; -} - -void -OpenSSLAdapter::OnConnectEvent(AsyncSocket* socket) { - LOG(LS_INFO) << "OpenSSLAdapter::OnConnectEvent"; - if (state_ != SSL_WAIT) { - ASSERT(state_ == SSL_NONE); - AsyncSocketAdapter::OnConnectEvent(socket); - return; - } - - state_ = SSL_CONNECTING; - if (int err = BeginSSL()) { - AsyncSocketAdapter::OnCloseEvent(socket, err); - } -} - -void -OpenSSLAdapter::OnReadEvent(AsyncSocket* socket) { - //LOG(LS_INFO) << "OpenSSLAdapter::OnReadEvent"; - - if (state_ == SSL_NONE) { - AsyncSocketAdapter::OnReadEvent(socket); - return; - } - - if (state_ == SSL_CONNECTING) { - if (int err = ContinueSSL()) { - Error("ContinueSSL", err); - } - return; - } - - if (state_ != SSL_CONNECTED) - return; - - // Don't let ourselves go away during the callbacks - //PRefPtr lock(this); // TODO: fix this - if (ssl_write_needs_read_) { - //LOG(LS_INFO) << " -- onStreamWriteable"; - AsyncSocketAdapter::OnWriteEvent(socket); - } - - //LOG(LS_INFO) << " -- onStreamReadable"; - AsyncSocketAdapter::OnReadEvent(socket); -} - -void -OpenSSLAdapter::OnWriteEvent(AsyncSocket* socket) { - //LOG(LS_INFO) << "OpenSSLAdapter::OnWriteEvent"; - - if (state_ == SSL_NONE) { - AsyncSocketAdapter::OnWriteEvent(socket); - return; - } - - if (state_ == SSL_CONNECTING) { - if (int err = ContinueSSL()) { - Error("ContinueSSL", err); - } - return; - } - - if (state_ != SSL_CONNECTED) - return; - - // Don't let ourselves go away during the callbacks - //PRefPtr lock(this); // TODO: fix this - - if (ssl_read_needs_write_) { - //LOG(LS_INFO) << " -- onStreamReadable"; - AsyncSocketAdapter::OnReadEvent(socket); - } - - //LOG(LS_INFO) << " -- onStreamWriteable"; - AsyncSocketAdapter::OnWriteEvent(socket); -} - -void -OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) { - LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")"; - AsyncSocketAdapter::OnCloseEvent(socket, err); -} - -// This code is taken from the "Network Security with OpenSSL" -// sample in chapter 5 - -bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host, - bool ignore_bad_cert) { - if (!host) - return false; - - // Checking the return from SSL_get_peer_certificate here is not strictly - // necessary. With our setup, it is not possible for it to return - // NULL. However, it is good form to check the return. - X509* certificate = SSL_get_peer_certificate(ssl); - if (!certificate) - return false; - - // Logging certificates is extremely verbose. So it is disabled by default. -#ifdef LOG_CERTIFICATES - { - LOG(LS_INFO) << "Certificate from server:"; - BIO* mem = BIO_new(BIO_s_mem()); - X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER); - BIO_write(mem, "\0", 1); - char* buffer; - BIO_get_mem_data(mem, &buffer); - LOG(LS_INFO) << buffer; - BIO_free(mem); - - char* cipher_description = - SSL_CIPHER_description(SSL_get_current_cipher(ssl), NULL, 128); - LOG(LS_INFO) << "Cipher: " << cipher_description; - OPENSSL_free(cipher_description); - } -#endif - - bool ok = false; - int extension_count = X509_get_ext_count(certificate); - for (int i = 0; i < extension_count; ++i) { - X509_EXTENSION* extension = X509_get_ext(certificate, i); - int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension)); - - if (extension_nid == NID_subject_alt_name) { - const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension); - if (!meth) - break; - - void* ext_str = NULL; - - // We assign this to a local variable, instead of passing the address - // directly to ASN1_item_d2i. - // See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html. - unsigned char* ext_value_data = extension->value->data; - - const unsigned char **ext_value_data_ptr = - (const_cast(&ext_value_data)); - - if (meth->it) { - ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr, - extension->value->length, - ASN1_ITEM_ptr(meth->it)); - } else { - ext_str = meth->d2i(NULL, ext_value_data_ptr, extension->value->length); - } - - STACK_OF(CONF_VALUE)* value = meth->i2v(meth, ext_str, NULL); - for (int j = 0; j < sk_CONF_VALUE_num(value); ++j) { - CONF_VALUE* nval = sk_CONF_VALUE_value(value, j); - // The value for nval can contain wildcards - if (!strcmp(nval->name, "DNS") && string_match(host, nval->value)) { - ok = true; - break; - } - } - sk_CONF_VALUE_pop_free(value, X509V3_conf_free); - value = NULL; - - if (meth->it) { - ASN1_item_free(reinterpret_cast(ext_str), - ASN1_ITEM_ptr(meth->it)); - } else { - meth->ext_free(ext_str); - } - ext_str = NULL; - } - if (ok) - break; - } - - char data[256]; - X509_name_st* subject; - if (!ok - && ((subject = X509_get_subject_name(certificate)) != NULL) - && (X509_NAME_get_text_by_NID(subject, NID_commonName, - data, sizeof(data)) > 0)) { - data[sizeof(data)-1] = 0; - if (_stricmp(data, host) == 0) - ok = true; - } - - X509_free(certificate); - - // This should only ever be turned on for debugging and development. - if (!ok && ignore_bad_cert) { - LOG(LS_WARNING) << "TLS certificate check FAILED. " - << "Allowing connection anyway."; - ok = true; - } - - return ok; -} - -bool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, const char* host) { - bool ok = VerifyServerName(ssl, host, ignore_bad_cert()); - - if (ok) { - ok = (SSL_get_verify_result(ssl) == X509_V_OK || - custom_verification_succeeded_); - } - - if (!ok && ignore_bad_cert()) { - LOG(LS_INFO) << "Other TLS post connection checks failed."; - ok = true; - } - - return ok; -} - -#if _DEBUG - -// We only use this for tracing and so it is only needed in debug mode - -void -OpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int ret) { - const char* str = "undefined"; - int w = where & ~SSL_ST_MASK; - if (w & SSL_ST_CONNECT) { - str = "SSL_connect"; - } else if (w & SSL_ST_ACCEPT) { - str = "SSL_accept"; - } - if (where & SSL_CB_LOOP) { - LOG(LS_INFO) << str << ":" << SSL_state_string_long(s); - } else if (where & SSL_CB_ALERT) { - str = (where & SSL_CB_READ) ? "read" : "write"; - LOG(LS_INFO) << "SSL3 alert " << str - << ":" << SSL_alert_type_string_long(ret) - << ":" << SSL_alert_desc_string_long(ret); - } else if (where & SSL_CB_EXIT) { - if (ret == 0) { - LOG(LS_INFO) << str << ":failed in " << SSL_state_string_long(s); - } else if (ret < 0) { - LOG(LS_INFO) << str << ":error in " << SSL_state_string_long(s); - } - } -} - -#endif // _DEBUG - -int -OpenSSLAdapter::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 stream pointer from the store - SSL* ssl = reinterpret_cast( - X509_STORE_CTX_get_ex_data(store, - SSL_get_ex_data_X509_STORE_CTX_idx())); - - OpenSSLAdapter* stream = - reinterpret_cast(SSL_get_app_data(ssl)); - - if (!ok && custom_verify_callback_) { - void* cert = - reinterpret_cast(X509_STORE_CTX_get_current_cert(store)); - if (custom_verify_callback_(cert)) { - stream->custom_verification_succeeded_ = true; - LOG(LS_INFO) << "validated certificate using custom callback"; - ok = true; - } - } - - // Should only be used for debugging and development. - if (!ok && stream->ignore_bad_cert()) { - LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain"; - ok = 1; - } - - return ok; -} - -bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) { - // Add the root cert that we care about to the SSL context - int count_of_added_certs = 0; - for (int i = 0; i < ARRAY_SIZE(kSSLCertCertificateList); i++) { - const unsigned char* cert_buffer = kSSLCertCertificateList[i]; - size_t cert_buffer_len = kSSLCertCertificateSizeList[i]; - X509* cert = d2i_X509(NULL, &cert_buffer, cert_buffer_len); - if (cert) { - int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert); - if (return_value == 0) { - LOG(LS_WARNING) << "Unable to add certificate."; - } else { - count_of_added_certs++; - } - X509_free(cert); - } - } - return count_of_added_certs > 0; -} - -SSL_CTX* -OpenSSLAdapter::SetupSSLContext() { - SSL_CTX* ctx = SSL_CTX_new(TLSv1_client_method()); - if (ctx == NULL) { - unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL. - LOG(LS_WARNING) << "SSL_CTX creation failed: " - << '"' << ERR_reason_error_string(error) << "\" " - << "(error=" << error << ')'; - return NULL; - } - if (!ConfigureTrustedRootCertificates(ctx)) { - SSL_CTX_free(ctx); - return NULL; - } - -#ifdef _DEBUG - SSL_CTX_set_info_callback(ctx, SSLInfoCallback); -#endif - - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback); - SSL_CTX_set_verify_depth(ctx, 4); - SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); - - return ctx; -} - -} // namespace rtc - -#endif // HAVE_OPENSSL_SSL_H diff --git a/webrtc/base/openssladapter.h b/webrtc/base/openssladapter.h deleted file mode 100644 index d244a7f5c..000000000 --- a/webrtc/base/openssladapter.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_OPENSSLADAPTER_H__ -#define WEBRTC_BASE_OPENSSLADAPTER_H__ - -#include -#include "webrtc/base/ssladapter.h" - -typedef struct ssl_st SSL; -typedef struct ssl_ctx_st SSL_CTX; -typedef struct x509_store_ctx_st X509_STORE_CTX; - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// - -class OpenSSLAdapter : public SSLAdapter { -public: - static bool InitializeSSL(VerificationCallback callback); - static bool InitializeSSLThread(); - static bool CleanupSSL(); - - OpenSSLAdapter(AsyncSocket* socket); - virtual ~OpenSSLAdapter(); - - virtual int StartSSL(const char* hostname, bool restartable); - virtual int Send(const void* pv, size_t cb); - virtual int Recv(void* pv, size_t cb); - virtual int Close(); - - // Note that the socket returns ST_CONNECTING while SSL is being negotiated. - virtual ConnState GetState() const; - -protected: - virtual void OnConnectEvent(AsyncSocket* socket); - virtual void OnReadEvent(AsyncSocket* socket); - virtual void OnWriteEvent(AsyncSocket* socket); - virtual void OnCloseEvent(AsyncSocket* socket, int err); - -private: - enum SSLState { - SSL_NONE, SSL_WAIT, SSL_CONNECTING, SSL_CONNECTED, SSL_ERROR - }; - - int BeginSSL(); - int ContinueSSL(); - void Error(const char* context, int err, bool signal = true); - void Cleanup(); - - static bool VerifyServerName(SSL* ssl, const char* host, - bool ignore_bad_cert); - bool SSLPostConnectionCheck(SSL* ssl, const char* host); -#if _DEBUG - static void SSLInfoCallback(const SSL* s, int where, int ret); -#endif // !_DEBUG - static int SSLVerifyCallback(int ok, X509_STORE_CTX* store); - static VerificationCallback custom_verify_callback_; - friend class OpenSSLStreamAdapter; // for custom_verify_callback_; - - static bool ConfigureTrustedRootCertificates(SSL_CTX* ctx); - static SSL_CTX* SetupSSLContext(); - - SSLState state_; - bool ssl_read_needs_write_; - bool ssl_write_needs_read_; - // If true, socket will retain SSL configuration after Close. - bool restartable_; - - SSL* ssl_; - SSL_CTX* ssl_ctx_; - std::string ssl_host_name_; - - bool custom_verification_succeeded_; -}; - -///////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_OPENSSLADAPTER_H__ diff --git a/webrtc/base/openssldigest.cc b/webrtc/base/openssldigest.cc deleted file mode 100644 index 0d22f4329..000000000 --- a/webrtc/base/openssldigest.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if HAVE_OPENSSL_SSL_H - -#include "webrtc/base/openssldigest.h" - -#include "webrtc/base/common.h" -#include "webrtc/base/openssl.h" - -namespace rtc { - -OpenSSLDigest::OpenSSLDigest(const std::string& algorithm) { - EVP_MD_CTX_init(&ctx_); - if (GetDigestEVP(algorithm, &md_)) { - EVP_DigestInit_ex(&ctx_, md_, NULL); - } else { - md_ = NULL; - } -} - -OpenSSLDigest::~OpenSSLDigest() { - EVP_MD_CTX_cleanup(&ctx_); -} - -size_t OpenSSLDigest::Size() const { - if (!md_) { - return 0; - } - return EVP_MD_size(md_); -} - -void OpenSSLDigest::Update(const void* buf, size_t len) { - if (!md_) { - return; - } - EVP_DigestUpdate(&ctx_, buf, len); -} - -size_t OpenSSLDigest::Finish(void* buf, size_t len) { - if (!md_ || len < Size()) { - return 0; - } - unsigned int md_len; - EVP_DigestFinal_ex(&ctx_, static_cast(buf), &md_len); - EVP_DigestInit_ex(&ctx_, md_, NULL); // prepare for future Update()s - ASSERT(md_len == Size()); - return md_len; -} - -bool OpenSSLDigest::GetDigestEVP(const std::string& algorithm, - const EVP_MD** mdp) { - const EVP_MD* md; - if (algorithm == DIGEST_MD5) { - md = EVP_md5(); - } else if (algorithm == DIGEST_SHA_1) { - md = EVP_sha1(); - } else if (algorithm == DIGEST_SHA_224) { - md = EVP_sha224(); - } else if (algorithm == DIGEST_SHA_256) { - md = EVP_sha256(); - } else if (algorithm == DIGEST_SHA_384) { - md = EVP_sha384(); - } else if (algorithm == DIGEST_SHA_512) { - md = EVP_sha512(); - } else { - return false; - } - - // Can't happen - ASSERT(EVP_MD_size(md) >= 16); - *mdp = md; - return true; -} - -bool OpenSSLDigest::GetDigestName(const EVP_MD* md, - std::string* algorithm) { - ASSERT(md != NULL); - ASSERT(algorithm != NULL); - - int md_type = EVP_MD_type(md); - if (md_type == NID_md5) { - *algorithm = DIGEST_MD5; - } else if (md_type == NID_sha1) { - *algorithm = DIGEST_SHA_1; - } else if (md_type == NID_sha224) { - *algorithm = DIGEST_SHA_224; - } else if (md_type == NID_sha256) { - *algorithm = DIGEST_SHA_256; - } else if (md_type == NID_sha384) { - *algorithm = DIGEST_SHA_384; - } else if (md_type == NID_sha512) { - *algorithm = DIGEST_SHA_512; - } else { - algorithm->clear(); - return false; - } - - return true; -} - -bool OpenSSLDigest::GetDigestSize(const std::string& algorithm, - size_t* length) { - const EVP_MD *md; - if (!GetDigestEVP(algorithm, &md)) - return false; - - *length = EVP_MD_size(md); - return true; -} - -} // namespace rtc - -#endif // HAVE_OPENSSL_SSL_H - diff --git a/webrtc/base/openssldigest.h b/webrtc/base/openssldigest.h deleted file mode 100644 index c4b0d8aed..000000000 --- a/webrtc/base/openssldigest.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_OPENSSLDIGEST_H_ -#define WEBRTC_BASE_OPENSSLDIGEST_H_ - -#include - -#include "webrtc/base/messagedigest.h" - -namespace rtc { - -// An implementation of the digest class that uses OpenSSL. -class OpenSSLDigest : public MessageDigest { - public: - // Creates an OpenSSLDigest with |algorithm| as the hash algorithm. - explicit OpenSSLDigest(const std::string& algorithm); - ~OpenSSLDigest(); - // Returns the digest output size (e.g. 16 bytes for MD5). - virtual size_t Size() const; - // Updates the digest with |len| bytes from |buf|. - virtual void Update(const void* buf, size_t len); - // Outputs the digest value to |buf| with length |len|. - virtual size_t Finish(void* buf, size_t len); - - // Helper function to look up a digest's EVP by name. - static bool GetDigestEVP(const std::string &algorithm, - const EVP_MD** md); - // Helper function to look up a digest's name by EVP. - static bool GetDigestName(const EVP_MD* md, - std::string* algorithm); - // Helper function to get the length of a digest. - static bool GetDigestSize(const std::string &algorithm, - size_t* len); - - private: - EVP_MD_CTX ctx_; - const EVP_MD* md_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_OPENSSLDIGEST_H_ diff --git a/webrtc/base/opensslidentity.cc b/webrtc/base/opensslidentity.cc deleted file mode 100644 index 915680ce2..000000000 --- a/webrtc/base/opensslidentity.cc +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if HAVE_OPENSSL_SSL_H - -#include "webrtc/base/opensslidentity.h" - -// Must be included first before openssl headers. -#include "webrtc/base/win32.h" // NOLINT - -#include -#include -#include -#include -#include -#include - -#include "webrtc/base/checks.h" -#include "webrtc/base/helpers.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/openssl.h" -#include "webrtc/base/openssldigest.h" - -namespace rtc { - -// We could have exposed a myriad of parameters for the crypto stuff, -// but keeping it simple seems best. - -// Strength of generated keys. Those are RSA. -static const int KEY_LENGTH = 1024; - -// Random bits for certificate serial number -static const int SERIAL_RAND_BITS = 64; - -// Certificate validity lifetime -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; - -// Generate a key pair. Caller is responsible for freeing the returned object. -static EVP_PKEY* MakeKey() { - LOG(LS_INFO) << "Making key pair"; - EVP_PKEY* pkey = EVP_PKEY_new(); - // RSA_generate_key is deprecated. Use _ex version. - BIGNUM* exponent = BN_new(); - RSA* rsa = RSA_new(); - if (!pkey || !exponent || !rsa || - !BN_set_word(exponent, 0x10001) || // 65537 RSA exponent - !RSA_generate_key_ex(rsa, KEY_LENGTH, exponent, NULL) || - !EVP_PKEY_assign_RSA(pkey, rsa)) { - EVP_PKEY_free(pkey); - BN_free(exponent); - RSA_free(rsa); - return NULL; - } - // ownership of rsa struct was assigned, don't free it. - BN_free(exponent); - 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 SSLIdentityParams& params) { - LOG(LS_INFO) << "Making certificate for " << params.common_name; - X509* x509 = NULL; - BIGNUM* serial_number = NULL; - X509_NAME* name = NULL; - - if ((x509=X509_new()) == NULL) - goto error; - - if (!X509_set_pubkey(x509, pkey)) - goto error; - - // serial number - // temporary reference to serial number inside x509 struct - ASN1_INTEGER* asn1_serial_number; - if ((serial_number = BN_new()) == NULL || - !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) || - (asn1_serial_number = X509_get_serialNumber(x509)) == NULL || - !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number)) - goto error; - - if (!X509_set_version(x509, 0L)) // version 1 - goto error; - - // There are a lot of possible components for the name entries. In - // our P2P SSL mode however, the certificates are pre-exchanged - // (through the secure XMPP channel), and so the certificate - // identification is arbitrary. It can't be empty, so we set some - // arbitrary common_name. Note that this certificate goes out in - // 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*)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), params.not_before) || - !X509_gmtime_adj(X509_get_notAfter(x509), params.not_after)) - goto error; - - if (!X509_sign(x509, pkey, EVP_sha1())) - goto error; - - BN_free(serial_number); - X509_NAME_free(name); - LOG(LS_INFO) << "Returning certificate"; - return x509; - - error: - BN_free(serial_number); - X509_NAME_free(name); - X509_free(x509); - return NULL; -} - -// This dumps the SSL error stack to the log. -static void LogSSLErrors(const std::string& prefix) { - char error_buf[200]; - unsigned long err; - - while ((err = ERR_get_error()) != 0) { - ERR_error_string_n(err, error_buf, sizeof(error_buf)); - LOG(LS_ERROR) << prefix << ": " << error_buf << "\n"; - } -} - -OpenSSLKeyPair* OpenSSLKeyPair::Generate() { - EVP_PKEY* pkey = MakeKey(); - if (!pkey) { - LogSSLErrors("Generating key pair"); - return NULL; - } - return new OpenSSLKeyPair(pkey); -} - -OpenSSLKeyPair::~OpenSSLKeyPair() { - EVP_PKEY_free(pkey_); -} - -void OpenSSLKeyPair::AddReference() { - CRYPTO_add(&pkey_->references, 1, CRYPTO_LOCK_EVP_PKEY); -} - -#ifdef _DEBUG -// Print a certificate to the log, for debugging. -static void PrintCert(X509* x509) { - BIO* temp_memory_bio = BIO_new(BIO_s_mem()); - if (!temp_memory_bio) { - LOG_F(LS_ERROR) << "Failed to allocate temporary memory bio"; - return; - } - X509_print_ex(temp_memory_bio, x509, XN_FLAG_SEP_CPLUS_SPC, 0); - BIO_write(temp_memory_bio, "\0", 1); - char* buffer; - BIO_get_mem_data(temp_memory_bio, &buffer); - LOG(LS_VERBOSE) << buffer; - BIO_free(temp_memory_bio); -} -#endif - -OpenSSLCertificate* OpenSSLCertificate::Generate( - OpenSSLKeyPair* key_pair, const SSLIdentityParams& params) { - SSLIdentityParams actual_params(params); - if (actual_params.common_name.empty()) { - // Use a random string, arbitrarily 8chars long. - actual_params.common_name = CreateRandomString(8); - } - X509* x509 = MakeCertificate(key_pair->pkey(), actual_params); - if (!x509) { - LogSSLErrors("Generating certificate"); - return NULL; - } -#ifdef _DEBUG - PrintCert(x509); -#endif - OpenSSLCertificate* ret = new OpenSSLCertificate(x509); - X509_free(x509); - return ret; -} - -OpenSSLCertificate* OpenSSLCertificate::FromPEMString( - const std::string& pem_string) { - BIO* bio = BIO_new_mem_buf(const_cast(pem_string.c_str()), -1); - if (!bio) - return NULL; - BIO_set_mem_eof_return(bio, 0); - X509 *x509 = PEM_read_bio_X509(bio, NULL, NULL, - const_cast("\0")); - BIO_free(bio); // Frees the BIO, but not the pointed-to string. - - if (!x509) - return NULL; - - OpenSSLCertificate* ret = new OpenSSLCertificate(x509); - X509_free(x509); - return ret; -} - -// NOTE: This implementation only functions correctly after InitializeSSL -// and before CleanupSSL. -bool OpenSSLCertificate::GetSignatureDigestAlgorithm( - std::string* algorithm) const { - return OpenSSLDigest::GetDigestName( - EVP_get_digestbyobj(x509_->sig_alg->algorithm), algorithm); -} - -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, - size_t size, - size_t* length) { - const EVP_MD *md; - unsigned int n; - - if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) - return false; - - if (size < static_cast(EVP_MD_size(md))) - return false; - - X509_digest(x509, md, digest, &n); - - *length = n; - - return true; -} - -OpenSSLCertificate::~OpenSSLCertificate() { - X509_free(x509_); -} - -std::string OpenSSLCertificate::ToPEMString() const { - BIO* bio = BIO_new(BIO_s_mem()); - if (!bio) { - UNREACHABLE(); - return std::string(); - } - if (!PEM_write_bio_X509(bio, x509_)) { - BIO_free(bio); - UNREACHABLE(); - return std::string(); - } - BIO_write(bio, "\0", 1); - char* buffer; - BIO_get_mem_data(bio, &buffer); - std::string ret(buffer); - BIO_free(bio); - return ret; -} - -void OpenSSLCertificate::ToDER(Buffer* der_buffer) const { - // In case of failure, make sure to leave the buffer empty. - der_buffer->SetData(NULL, 0); - - // Calculates the DER representation of the certificate, from scratch. - BIO* bio = BIO_new(BIO_s_mem()); - if (!bio) { - UNREACHABLE(); - return; - } - if (!i2d_X509_bio(bio, x509_)) { - BIO_free(bio); - UNREACHABLE(); - return; - } - char* data; - size_t length = BIO_get_mem_data(bio, &data); - der_buffer->SetData(data, length); - BIO_free(bio); -} - -void OpenSSLCertificate::AddReference() const { - ASSERT(x509_ != NULL); - CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509); -} - -OpenSSLIdentity* OpenSSLIdentity::GenerateInternal( - const SSLIdentityParams& params) { - OpenSSLKeyPair *key_pair = OpenSSLKeyPair::Generate(); - if (key_pair) { - OpenSSLCertificate *certificate = OpenSSLCertificate::Generate( - key_pair, params); - if (certificate) - return new OpenSSLIdentity(key_pair, certificate); - delete key_pair; - } - LOG(LS_INFO) << "Identity generation failed"; - 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) { - scoped_ptr cert( - OpenSSLCertificate::FromPEMString(certificate)); - if (!cert) { - LOG(LS_ERROR) << "Failed to create OpenSSLCertificate from PEM string."; - return NULL; - } - - BIO* bio = BIO_new_mem_buf(const_cast(private_key.c_str()), -1); - if (!bio) { - LOG(LS_ERROR) << "Failed to create a new BIO buffer."; - return NULL; - } - BIO_set_mem_eof_return(bio, 0); - EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, - const_cast("\0")); - 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."; - return NULL; - } - - return new OpenSSLIdentity(new OpenSSLKeyPair(pkey), - cert.release()); -} - -bool OpenSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) { - // 1 is the documented success return code. - if (SSL_CTX_use_certificate(ctx, certificate_->x509()) != 1 || - SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) { - LogSSLErrors("Configuring key and certificate"); - return false; - } - return true; -} - -} // namespace rtc - -#endif // HAVE_OPENSSL_SSL_H diff --git a/webrtc/base/opensslidentity.h b/webrtc/base/opensslidentity.h deleted file mode 100644 index e52cd10a9..000000000 --- a/webrtc/base/opensslidentity.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_OPENSSLIDENTITY_H_ -#define WEBRTC_BASE_OPENSSLIDENTITY_H_ - -#include -#include - -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/sslidentity.h" - -typedef struct ssl_ctx_st SSL_CTX; - -namespace rtc { - -// OpenSSLKeyPair encapsulates an OpenSSL EVP_PKEY* keypair object, -// which is reference counted inside the OpenSSL library. -class OpenSSLKeyPair { - public: - explicit OpenSSLKeyPair(EVP_PKEY* pkey) : pkey_(pkey) { - ASSERT(pkey_ != NULL); - } - - static OpenSSLKeyPair* Generate(); - - virtual ~OpenSSLKeyPair(); - - virtual OpenSSLKeyPair* GetReference() { - AddReference(); - return new OpenSSLKeyPair(pkey_); - } - - EVP_PKEY* pkey() const { return pkey_; } - - private: - void AddReference(); - - EVP_PKEY* pkey_; - - DISALLOW_EVIL_CONSTRUCTORS(OpenSSLKeyPair); -}; - -// OpenSSLCertificate encapsulates an OpenSSL X509* certificate object, -// which is also reference counted inside the OpenSSL library. -class OpenSSLCertificate : public SSLCertificate { - public: - // Caller retains ownership of the X509 object. - explicit OpenSSLCertificate(X509* x509) : x509_(x509) { - AddReference(); - } - - static OpenSSLCertificate* Generate(OpenSSLKeyPair* key_pair, - const SSLIdentityParams& params); - static OpenSSLCertificate* FromPEMString(const std::string& pem_string); - - virtual ~OpenSSLCertificate(); - - virtual OpenSSLCertificate* GetReference() const { - return new OpenSSLCertificate(x509_); - } - - X509* x509() const { return x509_; } - - virtual std::string ToPEMString() const; - - 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, - 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, - size_t size, - size_t* length); - - virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const; - - virtual bool GetChain(SSLCertChain** chain) const { - // Chains are not yet supported when using OpenSSL. - // OpenSSLStreamAdapter::SSLVerifyCallback currently requires the remote - // certificate to be self-signed. - return false; - } - - private: - void AddReference() const; - - X509* x509_; - - DISALLOW_EVIL_CONSTRUCTORS(OpenSSLCertificate); -}; - -// Holds a keypair and certificate together, and a method to generate -// them consistently. -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() { } - - virtual const OpenSSLCertificate& certificate() const { - return *certificate_; - } - - virtual OpenSSLIdentity* GetReference() const { - return new OpenSSLIdentity(key_pair_->GetReference(), - certificate_->GetReference()); - } - - // Configure an SSL context object to use our key and certificate. - bool ConfigureIdentity(SSL_CTX* ctx); - - private: - OpenSSLIdentity(OpenSSLKeyPair* key_pair, - OpenSSLCertificate* certificate) - : key_pair_(key_pair), certificate_(certificate) { - ASSERT(key_pair != NULL); - ASSERT(certificate != NULL); - } - - static OpenSSLIdentity* GenerateInternal(const SSLIdentityParams& params); - - scoped_ptr key_pair_; - scoped_ptr certificate_; - - DISALLOW_EVIL_CONSTRUCTORS(OpenSSLIdentity); -}; - - -} // namespace rtc - -#endif // WEBRTC_BASE_OPENSSLIDENTITY_H_ diff --git a/webrtc/base/opensslstreamadapter.cc b/webrtc/base/opensslstreamadapter.cc deleted file mode 100644 index 203cc6d6a..000000000 --- a/webrtc/base/opensslstreamadapter.cc +++ /dev/null @@ -1,843 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#if HAVE_OPENSSL_SSL_H - -#include "webrtc/base/opensslstreamadapter.h" - -#include -#include -#include -#include -#include - -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/openssl.h" -#include "webrtc/base/openssladapter.h" -#include "webrtc/base/openssldigest.h" -#include "webrtc/base/opensslidentity.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -#if (OPENSSL_VERSION_NUMBER >= 0x10001000L) -#define HAVE_DTLS_SRTP -#endif - -#ifdef HAVE_DTLS_SRTP -// SRTP cipher suite table -struct SrtpCipherMapEntry { - const char* external_name; - const char* internal_name; -}; - -// This isn't elegant, but it's better than an external reference -static SrtpCipherMapEntry SrtpCipherMap[] = { - {"AES_CM_128_HMAC_SHA1_80", "SRTP_AES128_CM_SHA1_80"}, - {"AES_CM_128_HMAC_SHA1_32", "SRTP_AES128_CM_SHA1_32"}, - {NULL, NULL} -}; -#endif - -////////////////////////////////////////////////////////////////////// -// StreamBIO -////////////////////////////////////////////////////////////////////// - -static int stream_write(BIO* h, const char* buf, int num); -static int stream_read(BIO* h, char* buf, int size); -static int stream_puts(BIO* h, const char* str); -static long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2); -static int stream_new(BIO* h); -static int stream_free(BIO* data); - -static BIO_METHOD methods_stream = { - BIO_TYPE_BIO, - "stream", - stream_write, - stream_read, - stream_puts, - 0, - stream_ctrl, - stream_new, - stream_free, - NULL, -}; - -static BIO_METHOD* BIO_s_stream() { return(&methods_stream); } - -static BIO* BIO_new_stream(StreamInterface* stream) { - BIO* ret = BIO_new(BIO_s_stream()); - if (ret == NULL) - return NULL; - ret->ptr = stream; - return ret; -} - -// bio methods return 1 (or at least non-zero) on success and 0 on failure. - -static int stream_new(BIO* b) { - b->shutdown = 0; - b->init = 1; - b->num = 0; // 1 means end-of-stream - b->ptr = 0; - return 1; -} - -static int stream_free(BIO* b) { - if (b == NULL) - return 0; - return 1; -} - -static int stream_read(BIO* b, char* out, int outl) { - if (!out) - return -1; - StreamInterface* stream = static_cast(b->ptr); - BIO_clear_retry_flags(b); - size_t read; - int error; - StreamResult result = stream->Read(out, outl, &read, &error); - if (result == SR_SUCCESS) { - return read; - } else if (result == SR_EOS) { - b->num = 1; - } else if (result == SR_BLOCK) { - BIO_set_retry_read(b); - } - return -1; -} - -static int stream_write(BIO* b, const char* in, int inl) { - if (!in) - return -1; - StreamInterface* stream = static_cast(b->ptr); - BIO_clear_retry_flags(b); - size_t written; - int error; - StreamResult result = stream->Write(in, inl, &written, &error); - if (result == SR_SUCCESS) { - return written; - } else if (result == SR_BLOCK) { - BIO_set_retry_write(b); - } - return -1; -} - -static int stream_puts(BIO* b, const char* str) { - return stream_write(b, str, strlen(str)); -} - -static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) { - UNUSED(num); - UNUSED(ptr); - - switch (cmd) { - case BIO_CTRL_RESET: - return 0; - case BIO_CTRL_EOF: - return b->num; - case BIO_CTRL_WPENDING: - case BIO_CTRL_PENDING: - return 0; - case BIO_CTRL_FLUSH: - return 1; - default: - return 0; - } -} - -///////////////////////////////////////////////////////////////////////////// -// OpenSSLStreamAdapter -///////////////////////////////////////////////////////////////////////////// - -OpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream) - : SSLStreamAdapter(stream), - state_(SSL_NONE), - role_(SSL_CLIENT), - ssl_read_needs_write_(false), ssl_write_needs_read_(false), - ssl_(NULL), ssl_ctx_(NULL), - custom_verification_succeeded_(false), - ssl_mode_(SSL_MODE_TLS) { -} - -OpenSSLStreamAdapter::~OpenSSLStreamAdapter() { - Cleanup(); -} - -void OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) { - ASSERT(!identity_); - identity_.reset(static_cast(identity)); -} - -void OpenSSLStreamAdapter::SetServerRole(SSLRole role) { - role_ = role; -} - -bool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const { - if (!peer_certificate_) - return false; - - *cert = peer_certificate_->GetReference(); - return true; -} - -bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string - &digest_alg, - const unsigned char* - digest_val, - size_t digest_len) { - ASSERT(!peer_certificate_); - ASSERT(peer_certificate_digest_algorithm_.size() == 0); - ASSERT(ssl_server_name_.empty()); - size_t expected_len; - - if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) { - LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg; - return false; - } - if (expected_len != digest_len) - return false; - - peer_certificate_digest_value_.SetData(digest_val, digest_len); - peer_certificate_digest_algorithm_ = digest_alg; - - return true; -} - -// Key Extractor interface -bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label, - const uint8* context, - size_t context_len, - bool use_context, - uint8* result, - size_t result_len) { -#ifdef HAVE_DTLS_SRTP - int i; - - i = SSL_export_keying_material(ssl_, result, result_len, - label.c_str(), label.length(), - const_cast(context), - context_len, use_context); - - if (i != 1) - return false; - - return true; -#else - return false; -#endif -} - -bool OpenSSLStreamAdapter::SetDtlsSrtpCiphers( - const std::vector& ciphers) { -#ifdef HAVE_DTLS_SRTP - std::string internal_ciphers; - - if (state_ != SSL_NONE) - return false; - - for (std::vector::const_iterator cipher = ciphers.begin(); - cipher != ciphers.end(); ++cipher) { - bool found = false; - for (SrtpCipherMapEntry *entry = SrtpCipherMap; entry->internal_name; - ++entry) { - if (*cipher == entry->external_name) { - found = true; - if (!internal_ciphers.empty()) - internal_ciphers += ":"; - internal_ciphers += entry->internal_name; - break; - } - } - - if (!found) { - LOG(LS_ERROR) << "Could not find cipher: " << *cipher; - return false; - } - } - - if (internal_ciphers.empty()) - return false; - - srtp_ciphers_ = internal_ciphers; - return true; -#else - return false; -#endif -} - -bool OpenSSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) { -#ifdef HAVE_DTLS_SRTP - ASSERT(state_ == SSL_CONNECTED); - if (state_ != SSL_CONNECTED) - return false; - - SRTP_PROTECTION_PROFILE *srtp_profile = - SSL_get_selected_srtp_profile(ssl_); - - if (!srtp_profile) - return false; - - for (SrtpCipherMapEntry *entry = SrtpCipherMap; - entry->internal_name; ++entry) { - if (!strcmp(entry->internal_name, srtp_profile->name)) { - *cipher = entry->external_name; - return true; - } - } - - ASSERT(false); // This should never happen - - return false; -#else - return false; -#endif -} - -int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) { - ASSERT(server_name != NULL && server_name[0] != '\0'); - ssl_server_name_ = server_name; - return StartSSL(); -} - -int OpenSSLStreamAdapter::StartSSLWithPeer() { - ASSERT(ssl_server_name_.empty()); - // It is permitted to specify peer_certificate_ only later. - return StartSSL(); -} - -void OpenSSLStreamAdapter::SetMode(SSLMode mode) { - ASSERT(state_ == SSL_NONE); - ssl_mode_ = mode; -} - -// -// StreamInterface Implementation -// - -StreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len, - size_t* written, int* error) { - LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")"; - - switch (state_) { - case SSL_NONE: - // pass-through in clear text - return StreamAdapterInterface::Write(data, data_len, written, error); - - case SSL_WAIT: - case SSL_CONNECTING: - return SR_BLOCK; - - case SSL_CONNECTED: - break; - - case SSL_ERROR: - case SSL_CLOSED: - default: - if (error) - *error = ssl_error_code_; - return SR_ERROR; - } - - // OpenSSL will return an error if we try to write zero bytes - if (data_len == 0) { - if (written) - *written = 0; - return SR_SUCCESS; - } - - ssl_write_needs_read_ = false; - - int code = SSL_write(ssl_, data, data_len); - int ssl_error = SSL_get_error(ssl_, code); - switch (ssl_error) { - case SSL_ERROR_NONE: - LOG(LS_VERBOSE) << " -- success"; - ASSERT(0 < code && static_cast(code) <= data_len); - if (written) - *written = code; - return SR_SUCCESS; - case SSL_ERROR_WANT_READ: - LOG(LS_VERBOSE) << " -- error want read"; - ssl_write_needs_read_ = true; - return SR_BLOCK; - case SSL_ERROR_WANT_WRITE: - LOG(LS_VERBOSE) << " -- error want write"; - return SR_BLOCK; - - case SSL_ERROR_ZERO_RETURN: - default: - Error("SSL_write", (ssl_error ? ssl_error : -1), false); - if (error) - *error = ssl_error_code_; - return SR_ERROR; - } - // not reached -} - -StreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len, - size_t* read, int* error) { - LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")"; - switch (state_) { - case SSL_NONE: - // pass-through in clear text - return StreamAdapterInterface::Read(data, data_len, read, error); - - case SSL_WAIT: - case SSL_CONNECTING: - return SR_BLOCK; - - case SSL_CONNECTED: - break; - - case SSL_CLOSED: - return SR_EOS; - - case SSL_ERROR: - default: - if (error) - *error = ssl_error_code_; - return SR_ERROR; - } - - // Don't trust OpenSSL with zero byte reads - if (data_len == 0) { - if (read) - *read = 0; - return SR_SUCCESS; - } - - ssl_read_needs_write_ = false; - - int code = SSL_read(ssl_, data, data_len); - int ssl_error = SSL_get_error(ssl_, code); - switch (ssl_error) { - case SSL_ERROR_NONE: - LOG(LS_VERBOSE) << " -- success"; - ASSERT(0 < code && static_cast(code) <= data_len); - if (read) - *read = code; - - if (ssl_mode_ == SSL_MODE_DTLS) { - // Enforce atomic reads -- this is a short read - unsigned int pending = SSL_pending(ssl_); - - if (pending) { - LOG(LS_INFO) << " -- short DTLS read. flushing"; - FlushInput(pending); - if (error) - *error = SSE_MSG_TRUNC; - return SR_ERROR; - } - } - return SR_SUCCESS; - case SSL_ERROR_WANT_READ: - LOG(LS_VERBOSE) << " -- error want read"; - return SR_BLOCK; - case SSL_ERROR_WANT_WRITE: - LOG(LS_VERBOSE) << " -- error want write"; - ssl_read_needs_write_ = true; - return SR_BLOCK; - case SSL_ERROR_ZERO_RETURN: - LOG(LS_VERBOSE) << " -- remote side closed"; - return SR_EOS; - break; - default: - LOG(LS_VERBOSE) << " -- error " << code; - Error("SSL_read", (ssl_error ? ssl_error : -1), false); - if (error) - *error = ssl_error_code_; - return SR_ERROR; - } - // not reached -} - -void OpenSSLStreamAdapter::FlushInput(unsigned int left) { - unsigned char buf[2048]; - - while (left) { - // This should always succeed - int toread = (sizeof(buf) < left) ? sizeof(buf) : left; - int code = SSL_read(ssl_, buf, toread); - - int ssl_error = SSL_get_error(ssl_, code); - ASSERT(ssl_error == SSL_ERROR_NONE); - - if (ssl_error != SSL_ERROR_NONE) { - LOG(LS_VERBOSE) << " -- error " << code; - Error("SSL_read", (ssl_error ? ssl_error : -1), false); - return; - } - - LOG(LS_VERBOSE) << " -- flushed " << code << " bytes"; - left -= code; - } -} - -void OpenSSLStreamAdapter::Close() { - Cleanup(); - ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR); - StreamAdapterInterface::Close(); -} - -StreamState OpenSSLStreamAdapter::GetState() const { - switch (state_) { - case SSL_WAIT: - case SSL_CONNECTING: - return SS_OPENING; - case SSL_CONNECTED: - return SS_OPEN; - default: - return SS_CLOSED; - }; - // not reached -} - -void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events, - int err) { - int events_to_signal = 0; - int signal_error = 0; - ASSERT(stream == this->stream()); - if ((events & SE_OPEN)) { - LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN"; - if (state_ != SSL_WAIT) { - ASSERT(state_ == SSL_NONE); - events_to_signal |= SE_OPEN; - } else { - state_ = SSL_CONNECTING; - if (int err = BeginSSL()) { - Error("BeginSSL", err, true); - return; - } - } - } - if ((events & (SE_READ|SE_WRITE))) { - LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent" - << ((events & SE_READ) ? " SE_READ" : "") - << ((events & SE_WRITE) ? " SE_WRITE" : ""); - if (state_ == SSL_NONE) { - events_to_signal |= events & (SE_READ|SE_WRITE); - } else if (state_ == SSL_CONNECTING) { - if (int err = ContinueSSL()) { - Error("ContinueSSL", err, true); - return; - } - } else if (state_ == SSL_CONNECTED) { - if (((events & SE_READ) && ssl_write_needs_read_) || - (events & SE_WRITE)) { - LOG(LS_VERBOSE) << " -- onStreamWriteable"; - events_to_signal |= SE_WRITE; - } - if (((events & SE_WRITE) && ssl_read_needs_write_) || - (events & SE_READ)) { - LOG(LS_VERBOSE) << " -- onStreamReadable"; - events_to_signal |= SE_READ; - } - } - } - if ((events & SE_CLOSE)) { - LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")"; - Cleanup(); - events_to_signal |= SE_CLOSE; - // SE_CLOSE is the only event that uses the final parameter to OnEvent(). - ASSERT(signal_error == 0); - signal_error = err; - } - if (events_to_signal) - StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error); -} - -int OpenSSLStreamAdapter::StartSSL() { - ASSERT(state_ == SSL_NONE); - - if (StreamAdapterInterface::GetState() != SS_OPEN) { - state_ = SSL_WAIT; - return 0; - } - - state_ = SSL_CONNECTING; - if (int err = BeginSSL()) { - Error("BeginSSL", err, false); - return err; - } - - return 0; -} - -int OpenSSLStreamAdapter::BeginSSL() { - ASSERT(state_ == SSL_CONNECTING); - // 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_digest_algorithm_.empty()); - LOG(LS_INFO) << "BeginSSL: " - << (!ssl_server_name_.empty() ? ssl_server_name_ : - "with peer"); - - BIO* bio = NULL; - - // First set up the context - ASSERT(ssl_ctx_ == NULL); - ssl_ctx_ = SetupSSLContext(); - if (!ssl_ctx_) - return -1; - - bio = BIO_new_stream(static_cast(stream())); - if (!bio) - return -1; - - ssl_ = SSL_new(ssl_ctx_); - if (!ssl_) { - BIO_free(bio); - return -1; - } - - SSL_set_app_data(ssl_, this); - - SSL_set_bio(ssl_, bio, bio); // the SSL object owns the bio now. - - SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - - // Do the connect - return ContinueSSL(); -} - -int OpenSSLStreamAdapter::ContinueSSL() { - LOG(LS_VERBOSE) << "ContinueSSL"; - ASSERT(state_ == SSL_CONNECTING); - - // Clear the DTLS timer - Thread::Current()->Clear(this, MSG_TIMEOUT); - - int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_); - int ssl_error; - switch (ssl_error = SSL_get_error(ssl_, code)) { - case SSL_ERROR_NONE: - LOG(LS_VERBOSE) << " -- success"; - - if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(), NULL, - peer_certificate_digest_algorithm_)) { - LOG(LS_ERROR) << "TLS post connection check failed"; - return -1; - } - - state_ = SSL_CONNECTED; - StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0); - break; - - case SSL_ERROR_WANT_READ: { - LOG(LS_VERBOSE) << " -- error want read"; - 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); - } - } - break; - - case SSL_ERROR_WANT_WRITE: - LOG(LS_VERBOSE) << " -- error want write"; - break; - - case SSL_ERROR_ZERO_RETURN: - default: - LOG(LS_VERBOSE) << " -- error " << code; - return (ssl_error != 0) ? ssl_error : -1; - } - - return 0; -} - -void OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) { - LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error(" - << context << ", " << err << ")"; - state_ = SSL_ERROR; - ssl_error_code_ = err; - Cleanup(); - if (signal) - StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err); -} - -void OpenSSLStreamAdapter::Cleanup() { - LOG(LS_INFO) << "Cleanup"; - - if (state_ != SSL_ERROR) { - state_ = SSL_CLOSED; - ssl_error_code_ = 0; - } - - if (ssl_) { - SSL_free(ssl_); - ssl_ = NULL; - } - if (ssl_ctx_) { - SSL_CTX_free(ssl_ctx_); - ssl_ctx_ = NULL; - } - identity_.reset(); - peer_certificate_.reset(); - - // Clear the DTLS timer - Thread::Current()->Clear(this, MSG_TIMEOUT); -} - - -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"; - DTLSv1_handle_timeout(ssl_); - ContinueSSL(); - } else { - StreamInterface::OnMessage(msg); - } -} - -SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() { - SSL_CTX *ctx = NULL; - - if (role_ == SSL_CLIENT) { - ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? - DTLSv1_client_method() : TLSv1_client_method()); - } else { - ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? - DTLSv1_server_method() : TLSv1_server_method()); - } - if (ctx == NULL) - return NULL; - - if (identity_ && !identity_->ConfigureIdentity(ctx)) { - SSL_CTX_free(ctx); - return NULL; - } - -#ifdef _DEBUG - SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback); -#endif - - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |SSL_VERIFY_FAIL_IF_NO_PEER_CERT, - SSLVerifyCallback); - SSL_CTX_set_verify_depth(ctx, 4); - SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); - -#ifdef HAVE_DTLS_SRTP - if (!srtp_ciphers_.empty()) { - if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) { - SSL_CTX_free(ctx); - return NULL; - } - } -#endif - - return ctx; -} - -int OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) { - // Get our SSL structure from the store - SSL* ssl = reinterpret_cast(X509_STORE_CTX_get_ex_data( - store, - SSL_get_ex_data_X509_STORE_CTX_idx())); - OpenSSLStreamAdapter* stream = - reinterpret_cast(SSL_get_app_data(ssl)); - - if (stream->peer_certificate_digest_algorithm_.empty()) { - return 0; - } - X509* cert = X509_STORE_CTX_get_current_cert(store); - 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; - } - 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."; - // Record the peer's certificate. - stream->peer_certificate_.reset(new OpenSSLCertificate(cert)); - return 1; -} - -// This code is taken from the "Network Security with OpenSSL" -// sample in chapter 5 -bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl, - const char* server_name, - const X509* peer_cert, - const std::string - &peer_digest) { - ASSERT(server_name != NULL); - bool ok; - if (server_name[0] != '\0') { // traditional mode - ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert()); - - if (ok) { - ok = (SSL_get_verify_result(ssl) == X509_V_OK || - custom_verification_succeeded_); - } - } else { // peer-to-peer mode - ASSERT((peer_cert != NULL) || (!peer_digest.empty())); - // no server name validation - ok = true; - } - - if (!ok && ignore_bad_cert()) { - LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = " - << SSL_get_verify_result(ssl); - LOG(LS_INFO) << "Other TLS post connection checks failed."; - ok = true; - } - - return ok; -} - -bool OpenSSLStreamAdapter::HaveDtls() { - return true; -} - -bool OpenSSLStreamAdapter::HaveDtlsSrtp() { -#ifdef HAVE_DTLS_SRTP - return true; -#else - return false; -#endif -} - -bool OpenSSLStreamAdapter::HaveExporter() { -#ifdef HAVE_DTLS_SRTP - return true; -#else - return false; -#endif -} - -} // namespace rtc - -#endif // HAVE_OPENSSL_SSL_H diff --git a/webrtc/base/opensslstreamadapter.h b/webrtc/base/opensslstreamadapter.h deleted file mode 100644 index 9506217b4..000000000 --- a/webrtc/base/opensslstreamadapter.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__ -#define WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__ - -#include -#include - -#include "webrtc/base/buffer.h" -#include "webrtc/base/sslstreamadapter.h" -#include "webrtc/base/opensslidentity.h" - -typedef struct ssl_st SSL; -typedef struct ssl_ctx_st SSL_CTX; -typedef struct x509_store_ctx_st X509_STORE_CTX; - -namespace rtc { - -// This class was written with OpenSSLAdapter (a socket adapter) as a -// starting point. It has similar structure and functionality, with -// the peer-to-peer mode added. -// -// Static methods to initialize and deinit the SSL library are in -// OpenSSLAdapter. This class also uses -// OpenSSLAdapter::custom_verify_callback_ (a static field). These -// should probably be moved out to a neutral class. -// -// In a few cases I have factored out some OpenSSLAdapter code into -// static methods so it can be reused from this class. Eventually that -// code should probably be moved to a common support -// class. Unfortunately there remain a few duplicated sections of -// code. I have not done more restructuring because I did not want to -// affect existing code that uses OpenSSLAdapter. -// -// This class does not support the SSL connection restart feature -// present in OpenSSLAdapter. I am not entirely sure how the feature -// is useful and I am not convinced that it works properly. -// -// This implementation is careful to disallow data exchange after an -// SSL error, and it has an explicit SSL_CLOSED state. It should not -// be possible to send any data in clear after one of the StartSSL -// methods has been called. - -// Look in sslstreamadapter.h for documentation of the methods. - -class OpenSSLIdentity; - -/////////////////////////////////////////////////////////////////////////////// - -class OpenSSLStreamAdapter : public SSLStreamAdapter { - public: - explicit OpenSSLStreamAdapter(StreamInterface* stream); - virtual ~OpenSSLStreamAdapter(); - - virtual void SetIdentity(SSLIdentity* identity); - - // Default argument is for compatibility - virtual void SetServerRole(SSLRole role = SSL_SERVER); - virtual bool SetPeerCertificateDigest(const std::string& digest_alg, - const unsigned char* digest_val, - size_t digest_len); - - virtual bool GetPeerCertificate(SSLCertificate** cert) const; - - virtual int StartSSLWithServer(const char* server_name); - virtual int StartSSLWithPeer(); - virtual void SetMode(SSLMode mode); - - virtual StreamResult Read(void* data, size_t data_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - virtual void Close(); - virtual StreamState GetState() const; - - // Key Extractor interface - virtual bool ExportKeyingMaterial(const std::string& label, - const uint8* context, - size_t context_len, - bool use_context, - uint8* result, - size_t result_len); - - - // DTLS-SRTP interface - virtual bool SetDtlsSrtpCiphers(const std::vector& ciphers); - virtual bool GetDtlsSrtpCipher(std::string* cipher); - - // Capabilities interfaces - static bool HaveDtls(); - static bool HaveDtlsSrtp(); - static bool HaveExporter(); - - protected: - virtual void OnEvent(StreamInterface* stream, int events, int err); - - private: - enum SSLState { - // Before calling one of the StartSSL methods, data flows - // in clear text. - SSL_NONE, - SSL_WAIT, // waiting for the stream to open to start SSL negotiation - SSL_CONNECTING, // SSL negotiation in progress - SSL_CONNECTED, // SSL stream successfully established - SSL_ERROR, // some SSL error occurred, stream is closed - SSL_CLOSED // Clean close - }; - - enum { MSG_TIMEOUT = MSG_MAX+1}; - - // The following three methods return 0 on success and a negative - // error code on failure. The error code may be from OpenSSL or -1 - // on some other error cases, so it can't really be interpreted - // unfortunately. - - // Go from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT, - // depending on whether the underlying stream is already open or - // not. - int StartSSL(); - // Prepare SSL library, state is SSL_CONNECTING. - int BeginSSL(); - // Perform SSL negotiation steps. - int ContinueSSL(); - - // Error handler helper. signal is given as true for errors in - // asynchronous contexts (when an error method was not returned - // through some other method), and in that case an SE_CLOSE event is - // raised on the stream with the specified error. - // A 0 error means a graceful close, otherwise there is not really enough - // context to interpret the error code. - void Error(const char* context, int err, bool signal); - void Cleanup(); - - // Override MessageHandler - virtual void OnMessage(Message* msg); - - // Flush the input buffers by reading left bytes (for DTLS) - void FlushInput(unsigned int left); - - // SSL library configuration - SSL_CTX* SetupSSLContext(); - // SSL verification check - bool SSLPostConnectionCheck(SSL* ssl, const char* server_name, - const X509* peer_cert, - const std::string& peer_digest); - // SSL certification verification error handler, called back from - // the openssl library. Returns an int interpreted as a boolean in - // the C style: zero means verification failure, non-zero means - // 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 - // Whether the SSL negotiation is blocked on needing to read or - // write to the wrapped stream. - bool ssl_read_needs_write_; - bool ssl_write_needs_read_; - - SSL* ssl_; - SSL_CTX* ssl_ctx_; - - // Our key and certificate, mostly useful in peer-to-peer mode. - scoped_ptr identity_; - // in traditional mode, the server name that the server's certificate - // must specify. Empty in peer-to-peer mode. - std::string ssl_server_name_; - // The certificate that the peer must present or did present. Initially - // null in traditional mode, until the connection is established. - scoped_ptr peer_certificate_; - // In peer-to-peer mode, the digest of the certificate that - // the peer must present. - Buffer peer_certificate_digest_value_; - std::string peer_certificate_digest_algorithm_; - - // OpenSSLAdapter::custom_verify_callback_ result - bool custom_verification_succeeded_; - - // The DtlsSrtp ciphers - std::string srtp_ciphers_; - - // Do DTLS or not - SSLMode ssl_mode_; -}; - -///////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__ diff --git a/webrtc/base/optionsfile.cc b/webrtc/base/optionsfile.cc deleted file mode 100644 index d84c948e3..000000000 --- a/webrtc/base/optionsfile.cc +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/optionsfile.h" - -#include - -#include "webrtc/base/logging.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/stringencode.h" - -namespace rtc { - -OptionsFile::OptionsFile(const std::string &path) : path_(path) { -} - -bool OptionsFile::Load() { - options_.clear(); - // Open file. - FileStream stream; - int err; - if (!stream.Open(path_, "r", &err)) { - LOG_F(LS_WARNING) << "Could not open file, err=" << err; - // We do not consider this an error because we expect there to be no file - // until the user saves a setting. - return true; - } - // Read in all its data. - std::string line; - StreamResult res; - for (;;) { - res = stream.ReadLine(&line); - if (res != SR_SUCCESS) { - break; - } - size_t equals_pos = line.find('='); - if (equals_pos == std::string::npos) { - // We do not consider this an error. Instead we ignore the line and - // keep going. - LOG_F(LS_WARNING) << "Ignoring malformed line in " << path_; - continue; - } - std::string key(line, 0, equals_pos); - std::string value(line, equals_pos + 1, line.length() - (equals_pos + 1)); - options_[key] = value; - } - if (res != SR_EOS) { - LOG_F(LS_ERROR) << "Error when reading from file"; - return false; - } else { - return true; - } -} - -bool OptionsFile::Save() { - // Open file. - FileStream stream; - int err; - if (!stream.Open(path_, "w", &err)) { - LOG_F(LS_ERROR) << "Could not open file, err=" << err; - return false; - } - // Write out all the data. - StreamResult res = SR_SUCCESS; - size_t written; - int error; - for (OptionsMap::const_iterator i = options_.begin(); i != options_.end(); - ++i) { - res = stream.WriteAll(i->first.c_str(), i->first.length(), &written, - &error); - if (res != SR_SUCCESS) { - break; - } - res = stream.WriteAll("=", 1, &written, &error); - if (res != SR_SUCCESS) { - break; - } - res = stream.WriteAll(i->second.c_str(), i->second.length(), &written, - &error); - if (res != SR_SUCCESS) { - break; - } - res = stream.WriteAll("\n", 1, &written, &error); - if (res != SR_SUCCESS) { - break; - } - } - if (res != SR_SUCCESS) { - LOG_F(LS_ERROR) << "Unable to write to file"; - return false; - } else { - return true; - } -} - -bool OptionsFile::IsLegalName(const std::string &name) { - for (size_t pos = 0; pos < name.length(); ++pos) { - if (name[pos] == '\n' || name[pos] == '\\' || name[pos] == '=') { - // Illegal character. - LOG(LS_WARNING) << "Ignoring operation for illegal option " << name; - return false; - } - } - return true; -} - -bool OptionsFile::IsLegalValue(const std::string &value) { - for (size_t pos = 0; pos < value.length(); ++pos) { - if (value[pos] == '\n' || value[pos] == '\\') { - // Illegal character. - LOG(LS_WARNING) << "Ignoring operation for illegal value " << value; - return false; - } - } - return true; -} - -bool OptionsFile::GetStringValue(const std::string& option, - std::string *out_val) const { - LOG(LS_VERBOSE) << "OptionsFile::GetStringValue " - << option; - if (!IsLegalName(option)) { - return false; - } - OptionsMap::const_iterator i = options_.find(option); - if (i == options_.end()) { - return false; - } - *out_val = i->second; - return true; -} - -bool OptionsFile::GetIntValue(const std::string& option, - int *out_val) const { - LOG(LS_VERBOSE) << "OptionsFile::GetIntValue " - << option; - if (!IsLegalName(option)) { - return false; - } - OptionsMap::const_iterator i = options_.find(option); - if (i == options_.end()) { - return false; - } - return FromString(i->second, out_val); -} - -bool OptionsFile::SetStringValue(const std::string& option, - const std::string& value) { - LOG(LS_VERBOSE) << "OptionsFile::SetStringValue " - << option << ":" << value; - if (!IsLegalName(option) || !IsLegalValue(value)) { - return false; - } - options_[option] = value; - return true; -} - -bool OptionsFile::SetIntValue(const std::string& option, - int value) { - LOG(LS_VERBOSE) << "OptionsFile::SetIntValue " - << option << ":" << value; - if (!IsLegalName(option)) { - return false; - } - return ToString(value, &options_[option]); -} - -bool OptionsFile::RemoveValue(const std::string& option) { - LOG(LS_VERBOSE) << "OptionsFile::RemoveValue " << option; - if (!IsLegalName(option)) { - return false; - } - options_.erase(option); - return true; -} - -} // namespace rtc diff --git a/webrtc/base/optionsfile.h b/webrtc/base/optionsfile.h deleted file mode 100644 index c740ce4fa..000000000 --- a/webrtc/base/optionsfile.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_OPTIONSFILE_H_ -#define WEBRTC_BASE_OPTIONSFILE_H_ - -#include -#include - -namespace rtc { - -// Implements storage of simple options in a text file on disk. This is -// cross-platform, but it is intended mostly for Linux where there is no -// first-class options storage system. -class OptionsFile { - public: - OptionsFile(const std::string &path); - - // Loads the file from disk, overwriting the in-memory values. - bool Load(); - // Saves the contents in memory, overwriting the on-disk values. - bool Save(); - - bool GetStringValue(const std::string& option, std::string* out_val) const; - bool GetIntValue(const std::string& option, int* out_val) const; - bool SetStringValue(const std::string& option, const std::string& val); - bool SetIntValue(const std::string& option, int val); - bool RemoveValue(const std::string& option); - - private: - typedef std::map OptionsMap; - - static bool IsLegalName(const std::string &name); - static bool IsLegalValue(const std::string &value); - - std::string path_; - OptionsMap options_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_OPTIONSFILE_H_ diff --git a/webrtc/base/optionsfile_unittest.cc b/webrtc/base/optionsfile_unittest.cc deleted file mode 100644 index adddb9521..000000000 --- a/webrtc/base/optionsfile_unittest.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/fileutils.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/optionsfile.h" -#include "webrtc/base/pathutils.h" - -namespace rtc { - -static const std::string kTestOptionA = "test-option-a"; -static const std::string kTestOptionB = "test-option-b"; -static const std::string kTestString1 = "a string"; -static const std::string kTestString2 = "different string"; -static const std::string kOptionWithEquals = "foo=bar"; -static const std::string kOptionWithNewline = "foo\nbar"; -static const std::string kValueWithEquals = "baz=quux"; -static const std::string kValueWithNewline = "baz\nquux"; -static const std::string kEmptyString = ""; -static const char kOptionWithUtf8[] = {'O', 'p', 't', '\302', '\256', 'i', 'o', - 'n', '\342', '\204', '\242', '\0'}; // Opt(R)io(TM). -static const char kValueWithUtf8[] = {'V', 'a', 'l', '\302', '\256', 'v', 'e', - '\342', '\204', '\242', '\0'}; // Val(R)ue(TM). -static int kTestInt1 = 12345; -static int kTestInt2 = 67890; -static int kNegInt = -634; -static int kZero = 0; - -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_)); - } - - rtc::scoped_ptr store_; - - private: - std::string test_file_; -}; - -TEST_F(OptionsFileTest, GetSetString) { - // Clear contents of the file on disk. - 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_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)); -} - -TEST_F(OptionsFileTest, GetSetInt) { - // Clear contents of the file on disk. - 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_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_EQ(kNegInt, out1); - EXPECT_TRUE(store_->SetIntValue(kTestOptionA, kZero)); - EXPECT_TRUE(store_->GetIntValue(kTestOptionA, &out1)); - EXPECT_EQ(kZero, out1); -} - -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_F(OptionsFileTest, SpecialCharacters) { - // Clear contents of the file on disk. - 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_EQ(kTestString1, out); - EXPECT_TRUE(store_->GetStringValue(kOptionWithUtf8, &out)); - EXPECT_EQ(kValueWithUtf8, 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_EQ(kValueWithEquals, 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_EQ(kEmptyString, out); -} - -} // namespace rtc diff --git a/webrtc/base/pathutils.cc b/webrtc/base/pathutils.cc deleted file mode 100644 index 7671bfc29..000000000 --- a/webrtc/base/pathutils.cc +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#include -#include -#include -#endif // WEBRTC_WIN - -#include "webrtc/base/common.h" -#include "webrtc/base/fileutils.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/urlencode.h" - -namespace rtc { - -static const char EMPTY_STR[] = ""; - -// EXT_DELIM separates a file basename from extension -const char EXT_DELIM = '.'; - -// FOLDER_DELIMS separate folder segments and the filename -const char* const FOLDER_DELIMS = "/\\"; - -// DEFAULT_FOLDER_DELIM is the preferred delimiter for this platform -#if WEBRTC_WIN -const char DEFAULT_FOLDER_DELIM = '\\'; -#else // !WEBRTC_WIN -const char DEFAULT_FOLDER_DELIM = '/'; -#endif // !WEBRTC_WIN - -/////////////////////////////////////////////////////////////////////////////// -// Pathname - parsing of pathnames into components, and vice versa -/////////////////////////////////////////////////////////////////////////////// - -bool Pathname::IsFolderDelimiter(char ch) { - return (NULL != ::strchr(FOLDER_DELIMS, ch)); -} - -char Pathname::DefaultFolderDelimiter() { - return DEFAULT_FOLDER_DELIM; -} - -Pathname::Pathname() - : folder_delimiter_(DEFAULT_FOLDER_DELIM) { -} - -Pathname::Pathname(const std::string& pathname) - : folder_delimiter_(DEFAULT_FOLDER_DELIM) { - SetPathname(pathname); -} - -Pathname::Pathname(const std::string& folder, const std::string& filename) - : folder_delimiter_(DEFAULT_FOLDER_DELIM) { - SetPathname(folder, filename); -} - -void Pathname::SetFolderDelimiter(char delimiter) { - ASSERT(IsFolderDelimiter(delimiter)); - folder_delimiter_ = delimiter; -} - -void Pathname::Normalize() { - for (size_t i=0; i= 2) { - pos = folder_.find_last_of(FOLDER_DELIMS, folder_.length() - 2); - } - if (pos != std::string::npos) { - return folder_.substr(pos + 1); - } else { - return folder_; - } -} - -std::string Pathname::parent_folder() const { - std::string::size_type pos = std::string::npos; - if (folder_.size() >= 2) { - pos = folder_.find_last_of(FOLDER_DELIMS, folder_.length() - 2); - } - if (pos != std::string::npos) { - return folder_.substr(0, pos + 1); - } else { - return EMPTY_STR; - } -} - -void Pathname::SetFolder(const std::string& folder) { - folder_.assign(folder); - // Ensure folder ends in a path delimiter - if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) { - folder_.push_back(folder_delimiter_); - } -} - -void Pathname::AppendFolder(const std::string& folder) { - folder_.append(folder); - // Ensure folder ends in a path delimiter - if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) { - folder_.push_back(folder_delimiter_); - } -} - -std::string Pathname::basename() const { - return basename_; -} - -bool Pathname::SetBasename(const std::string& basename) { - if(basename.find_first_of(FOLDER_DELIMS) != std::string::npos) { - return false; - } - basename_.assign(basename); - return true; -} - -std::string Pathname::extension() const { - return extension_; -} - -bool Pathname::SetExtension(const std::string& extension) { - if (extension.find_first_of(FOLDER_DELIMS) != std::string::npos || - extension.find_first_of(EXT_DELIM, 1) != std::string::npos) { - return false; - } - extension_.assign(extension); - // Ensure extension begins with the extension delimiter - if (!extension_.empty() && (extension_[0] != EXT_DELIM)) { - extension_.insert(extension_.begin(), EXT_DELIM); - } - return true; -} - -std::string Pathname::filename() const { - std::string filename(basename_); - filename.append(extension_); - return filename; -} - -bool Pathname::SetFilename(const std::string& filename) { - std::string::size_type pos = filename.rfind(EXT_DELIM); - if ((pos == std::string::npos) || (pos == 0)) { - return SetExtension(EMPTY_STR) && SetBasename(filename); - } else { - return SetExtension(filename.substr(pos)) && SetBasename(filename.substr(0, pos)); - } -} - -#if defined(WEBRTC_WIN) -bool Pathname::GetDrive(char *drive, uint32 bytes) const { - return GetDrive(drive, bytes, folder_); -} - -// static -bool Pathname::GetDrive(char *drive, uint32 bytes, - const std::string& pathname) { - // need at lease 4 bytes to save c: - if (bytes < 4 || pathname.size() < 3) { - return false; - } - - memcpy(drive, pathname.c_str(), 3); - drive[3] = 0; - // sanity checking - return (isalpha(drive[0]) && - drive[1] == ':' && - drive[2] == '\\'); -} -#endif - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/pathutils.h b/webrtc/base/pathutils.h deleted file mode 100644 index 8f07e1dbc..000000000 --- a/webrtc/base/pathutils.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_PATHUTILS_H__ -#define WEBRTC_BASE_PATHUTILS_H__ - -#include -// Temporary, until deprecated helpers are removed. -#include "webrtc/base/fileutils.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// Pathname - parsing of pathnames into components, and vice versa. -// -// To establish consistent terminology, a filename never contains a folder -// component. A folder never contains a filename. A pathname may include -// a folder and/or filename component. Here are some examples: -// -// pathname() /home/john/example.txt -// folder() /home/john/ -// filename() example.txt -// parent_folder() /home/ -// folder_name() john/ -// basename() example -// extension() .txt -// -// Basename may begin, end, and/or include periods, but no folder delimiters. -// If extension exists, it consists of a period followed by zero or more -// non-period/non-delimiter characters, and basename is non-empty. -/////////////////////////////////////////////////////////////////////////////// - -class Pathname { -public: - // Folder delimiters are slash and backslash - static bool IsFolderDelimiter(char ch); - static char DefaultFolderDelimiter(); - - Pathname(); - Pathname(const std::string& pathname); - Pathname(const std::string& folder, const std::string& filename); - - // Set's the default folder delimiter for this Pathname - char folder_delimiter() const { return folder_delimiter_; } - void SetFolderDelimiter(char delimiter); - - // Normalize changes all folder delimiters to folder_delimiter() - void Normalize(); - - // Reset to the empty pathname - void clear(); - - // Returns true if the pathname is empty. Note: this->pathname().empty() - // is always false. - bool empty() const; - - std::string url() const; - - // Returns the folder and filename components. If the pathname is empty, - // returns a string representing the current directory (as a relative path, - // i.e., "."). - std::string pathname() const; - void SetPathname(const std::string& pathname); - void SetPathname(const std::string& folder, const std::string& filename); - - // Append pathname to the current folder (if any). Any existing filename - // will be discarded. - void AppendPathname(const std::string& pathname); - - std::string folder() const; - std::string folder_name() const; - std::string parent_folder() const; - // SetFolder and AppendFolder will append a folder delimiter, if needed. - void SetFolder(const std::string& folder); - void AppendFolder(const std::string& folder); - - std::string basename() const; - bool SetBasename(const std::string& basename); - - std::string extension() const; - // SetExtension will prefix a period, if needed. - bool SetExtension(const std::string& extension); - - std::string filename() const; - bool SetFilename(const std::string& filename); - -#if defined(WEBRTC_WIN) - bool GetDrive(char *drive, uint32 bytes) const; - static bool GetDrive(char *drive, uint32 bytes,const std::string& pathname); -#endif - -private: - std::string folder_, basename_, extension_; - char folder_delimiter_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Global Helpers (deprecated) -/////////////////////////////////////////////////////////////////////////////// - -inline void SetOrganizationName(const std::string& organization) { - Filesystem::SetOrganizationName(organization); -} -inline void SetApplicationName(const std::string& application) { - Filesystem::SetApplicationName(application); -} -inline void GetOrganizationName(std::string* organization) { - Filesystem::GetOrganizationName(organization); -} -inline void GetApplicationName(std::string* application) { - Filesystem::GetApplicationName(application); -} -inline bool CreateFolder(const Pathname& path) { - return Filesystem::CreateFolder(path); -} -inline bool FinishPath(Pathname& path, bool create, const std::string& append) { - if (!append.empty()) - path.AppendFolder(append); - return !create || CreateFolder(path); -} -// Note: this method uses the convention of / for the temporary -// folder. Filesystem uses /. We will be migrating exclusively -// to // eventually. Since these are temp folders, -// it's probably ok to orphan them during the transition. -inline bool GetTemporaryFolder(Pathname& path, bool create, - const std::string& append) { - std::string application_name; - Filesystem::GetApplicationName(&application_name); - ASSERT(!application_name.empty()); - return Filesystem::GetTemporaryFolder(path, create, &application_name) - && FinishPath(path, create, append); -} -inline bool GetAppDataFolder(Pathname& path, bool create, - const std::string& append) { - ASSERT(!create); // TODO: Support create flag on Filesystem::GetAppDataFolder. - return Filesystem::GetAppDataFolder(&path, true) - && FinishPath(path, create, append); -} -inline bool CleanupTemporaryFolder() { - Pathname path; - if (!GetTemporaryFolder(path, false, "")) - return false; - if (Filesystem::IsAbsent(path)) - return true; - if (!Filesystem::IsTemporaryPath(path)) { - ASSERT(false); - return false; - } - return Filesystem::DeleteFolderContents(path); -} - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_PATHUTILS_H__ diff --git a/webrtc/base/pathutils_unittest.cc b/webrtc/base/pathutils_unittest.cc deleted file mode 100644 index a04effa68..000000000 --- a/webrtc/base/pathutils_unittest.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/pathutils.h" -#include "webrtc/base/gunit.h" - -TEST(Pathname, ReturnsDotForEmptyPathname) { - const std::string kCWD = - std::string(".") + rtc::Pathname::DefaultFolderDelimiter(); - - rtc::Pathname path("/", ""); - EXPECT_FALSE(path.empty()); - EXPECT_FALSE(path.folder().empty()); - EXPECT_TRUE (path.filename().empty()); - EXPECT_FALSE(path.pathname().empty()); - EXPECT_EQ(std::string("/"), path.pathname()); - - path.SetPathname("", "foo"); - EXPECT_FALSE(path.empty()); - EXPECT_TRUE (path.folder().empty()); - EXPECT_FALSE(path.filename().empty()); - EXPECT_FALSE(path.pathname().empty()); - EXPECT_EQ(std::string("foo"), path.pathname()); - - path.SetPathname("", ""); - EXPECT_TRUE (path.empty()); - EXPECT_TRUE (path.folder().empty()); - EXPECT_TRUE (path.filename().empty()); - EXPECT_FALSE(path.pathname().empty()); - EXPECT_EQ(kCWD, path.pathname()); - - path.SetPathname(kCWD, ""); - EXPECT_FALSE(path.empty()); - EXPECT_FALSE(path.folder().empty()); - EXPECT_TRUE (path.filename().empty()); - EXPECT_FALSE(path.pathname().empty()); - EXPECT_EQ(kCWD, path.pathname()); - - rtc::Pathname path2("c:/foo bar.txt"); - EXPECT_EQ(path2.url(), std::string("file:///c:/foo%20bar.txt")); -} diff --git a/webrtc/base/physicalsocketserver.cc b/webrtc/base/physicalsocketserver.cc deleted file mode 100644 index cff5e4dcb..000000000 --- a/webrtc/base/physicalsocketserver.cc +++ /dev/null @@ -1,1659 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(_MSC_VER) && _MSC_VER < 1300 -#pragma warning(disable:4786) -#endif - -#include - -#if defined(WEBRTC_POSIX) -#include -#include -#include -#include -#include -#include -#include -#endif - -#if defined(WEBRTC_WIN) -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#undef SetPort -#endif - -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/byteorder.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/nethelpers.h" -#include "webrtc/base/physicalsocketserver.h" -#include "webrtc/base/timeutils.h" -#include "webrtc/base/winping.h" -#include "webrtc/base/win32socketinit.h" - -// stm: this will tell us if we are on OSX -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined(WEBRTC_POSIX) -#include // for TCP_NODELAY -#define IP_MTU 14 // Until this is integrated from linux/in.h to netinet/in.h -typedef void* SockOptArg; -#endif // WEBRTC_POSIX - -#if defined(WEBRTC_WIN) -typedef char* SockOptArg; -#endif - -namespace rtc { - -#if defined(WEBRTC_WIN) -// Standard MTUs, from RFC 1191 -const uint16 PACKET_MAXIMUMS[] = { - 65535, // Theoretical maximum, Hyperchannel - 32000, // Nothing - 17914, // 16Mb IBM Token Ring - 8166, // IEEE 802.4 - //4464, // IEEE 802.5 (4Mb max) - 4352, // FDDI - //2048, // Wideband Network - 2002, // IEEE 802.5 (4Mb recommended) - //1536, // Expermental Ethernet Networks - //1500, // Ethernet, Point-to-Point (default) - 1492, // IEEE 802.3 - 1006, // SLIP, ARPANET - //576, // X.25 Networks - //544, // DEC IP Portal - //512, // NETBIOS - 508, // IEEE 802/Source-Rt Bridge, ARCNET - 296, // Point-to-Point (low delay) - 68, // Official minimum - 0, // End of list marker -}; - -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: - PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET) - : ss_(ss), s_(s), enabled_events_(0), error_(0), - state_((s == INVALID_SOCKET) ? CS_CLOSED : CS_CONNECTED), - resolver_(NULL) { -#if defined(WEBRTC_WIN) - // EnsureWinsockInit() ensures that winsock is initialized. The default - // version of this function doesn't do anything because winsock is - // initialized by constructor of a static object. If neccessary libjingle - // users can link it with a different version of this function by replacing - // win32socketinit.cc. See win32socketinit.cc for more details. - EnsureWinsockInit(); -#endif - if (s_ != INVALID_SOCKET) { - enabled_events_ = DE_READ | DE_WRITE; - - int type = SOCK_STREAM; - socklen_t len = sizeof(type); - VERIFY(0 == getsockopt(s_, SOL_SOCKET, SO_TYPE, (SockOptArg)&type, &len)); - udp_ = (SOCK_DGRAM == type); - } - } - - virtual ~PhysicalSocket() { - Close(); - } - - // Creates the underlying OS socket (same as the "socket" function). - virtual bool Create(int family, int type) { - Close(); - s_ = ::socket(family, type, 0); - udp_ = (SOCK_DGRAM == type); - UpdateLastError(); - if (udp_) - enabled_events_ = DE_READ | DE_WRITE; - return s_ != INVALID_SOCKET; - } - - SocketAddress GetLocalAddress() const { - sockaddr_storage addr_storage = {0}; - socklen_t addrlen = sizeof(addr_storage); - sockaddr* addr = reinterpret_cast(&addr_storage); - int result = ::getsockname(s_, addr, &addrlen); - SocketAddress address; - if (result >= 0) { - SocketAddressFromSockAddrStorage(addr_storage, &address); - } else { - LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket=" - << s_; - } - return address; - } - - SocketAddress GetRemoteAddress() const { - sockaddr_storage addr_storage = {0}; - socklen_t addrlen = sizeof(addr_storage); - sockaddr* addr = reinterpret_cast(&addr_storage); - int result = ::getpeername(s_, addr, &addrlen); - SocketAddress address; - if (result >= 0) { - SocketAddressFromSockAddrStorage(addr_storage, &address); - } else { - LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket=" - << s_; - } - return address; - } - - int Bind(const SocketAddress& bind_addr) { - sockaddr_storage addr_storage; - size_t len = bind_addr.ToSockAddrStorage(&addr_storage); - sockaddr* addr = reinterpret_cast(&addr_storage); - int err = ::bind(s_, addr, static_cast(len)); - UpdateLastError(); -#ifdef _DEBUG - if (0 == err) { - dbg_addr_ = "Bound @ "; - dbg_addr_.append(GetLocalAddress().ToString()); - } -#endif // _DEBUG - return err; - } - - int Connect(const SocketAddress& addr) { - // TODO: Implicit creation is required to reconnect... - // ...but should we make it more explicit? - if (state_ != CS_CLOSED) { - SetError(EALREADY); - return SOCKET_ERROR; - } - if (addr.IsUnresolved()) { - LOG(LS_VERBOSE) << "Resolving addr in PhysicalSocket::Connect"; - resolver_ = new AsyncResolver(); - resolver_->SignalDone.connect(this, &PhysicalSocket::OnResolveResult); - resolver_->Start(addr); - state_ = CS_CONNECTING; - return 0; - } - - return DoConnect(addr); - } - - int DoConnect(const SocketAddress& connect_addr) { - if ((s_ == INVALID_SOCKET) && - !Create(connect_addr.family(), SOCK_STREAM)) { - return SOCKET_ERROR; - } - sockaddr_storage addr_storage; - size_t len = connect_addr.ToSockAddrStorage(&addr_storage); - sockaddr* addr = reinterpret_cast(&addr_storage); - int err = ::connect(s_, addr, static_cast(len)); - UpdateLastError(); - if (err == 0) { - state_ = CS_CONNECTED; - } else if (IsBlockingError(GetError())) { - state_ = CS_CONNECTING; - enabled_events_ |= DE_CONNECT; - } else { - return SOCKET_ERROR; - } - - enabled_events_ |= DE_READ | DE_WRITE; - return 0; - } - - int GetError() const { - CritScope cs(&crit_); - return error_; - } - - void SetError(int error) { - CritScope cs(&crit_); - error_ = error; - } - - ConnState GetState() const { - return state_; - } - - int GetOption(Option opt, int* value) { - int slevel; - int sopt; - if (TranslateOption(opt, &slevel, &sopt) == -1) - return -1; - socklen_t optlen = sizeof(*value); - int ret = ::getsockopt(s_, slevel, sopt, (SockOptArg)value, &optlen); - if (ret != -1 && opt == OPT_DONTFRAGMENT) { -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - *value = (*value != IP_PMTUDISC_DONT) ? 1 : 0; -#endif - } - return ret; - } - - int SetOption(Option opt, int value) { - int slevel; - int sopt; - if (TranslateOption(opt, &slevel, &sopt) == -1) - return -1; - if (opt == OPT_DONTFRAGMENT) { -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - value = (value) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; -#endif - } - return ::setsockopt(s_, slevel, sopt, (SockOptArg)&value, sizeof(value)); - } - - int Send(const void *pv, size_t cb) { - int sent = ::send(s_, reinterpret_cast(pv), (int)cb, -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - // Suppress SIGPIPE. Without this, attempting to send on a socket whose - // other end is closed will result in a SIGPIPE signal being raised to - // our process, which by default will terminate the process, which we - // don't want. By specifying this flag, we'll just get the error EPIPE - // instead and can handle the error gracefully. - MSG_NOSIGNAL -#else - 0 -#endif - ); - UpdateLastError(); - MaybeRemapSendError(); - // We have seen minidumps where this may be false. - ASSERT(sent <= static_cast(cb)); - if ((sent < 0) && IsBlockingError(GetError())) { - enabled_events_ |= DE_WRITE; - } - return sent; - } - - int SendTo(const void* buffer, size_t length, const SocketAddress& addr) { - sockaddr_storage saddr; - size_t len = addr.ToSockAddrStorage(&saddr); - int sent = ::sendto( - s_, static_cast(buffer), static_cast(length), -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - // Suppress SIGPIPE. See above for explanation. - MSG_NOSIGNAL, -#else - 0, -#endif - reinterpret_cast(&saddr), static_cast(len)); - UpdateLastError(); - MaybeRemapSendError(); - // We have seen minidumps where this may be false. - ASSERT(sent <= static_cast(length)); - if ((sent < 0) && IsBlockingError(GetError())) { - enabled_events_ |= DE_WRITE; - } - return sent; - } - - int Recv(void* buffer, size_t length) { - int received = ::recv(s_, static_cast(buffer), - static_cast(length), 0); - if ((received == 0) && (length != 0)) { - // Note: on graceful shutdown, recv can return 0. In this case, we - // pretend it is blocking, and then signal close, so that simplifying - // assumptions can be made about Recv. - LOG(LS_WARNING) << "EOF from socket; deferring close event"; - // Must turn this back on so that the select() loop will notice the close - // event. - enabled_events_ |= DE_READ; - SetError(EWOULDBLOCK); - return SOCKET_ERROR; - } - UpdateLastError(); - int error = GetError(); - bool success = (received >= 0) || IsBlockingError(error); - if (udp_ || success) { - enabled_events_ |= DE_READ; - } - if (!success) { - LOG_F(LS_VERBOSE) << "Error = " << error; - } - return received; - } - - int RecvFrom(void* buffer, size_t length, SocketAddress *out_addr) { - sockaddr_storage addr_storage; - socklen_t addr_len = sizeof(addr_storage); - sockaddr* addr = reinterpret_cast(&addr_storage); - int received = ::recvfrom(s_, static_cast(buffer), - static_cast(length), 0, addr, &addr_len); - UpdateLastError(); - if ((received >= 0) && (out_addr != NULL)) - SocketAddressFromSockAddrStorage(addr_storage, out_addr); - int error = GetError(); - bool success = (received >= 0) || IsBlockingError(error); - if (udp_ || success) { - enabled_events_ |= DE_READ; - } - if (!success) { - LOG_F(LS_VERBOSE) << "Error = " << error; - } - return received; - } - - int Listen(int backlog) { - int err = ::listen(s_, backlog); - UpdateLastError(); - if (err == 0) { - state_ = CS_CONNECTING; - enabled_events_ |= DE_ACCEPT; -#ifdef _DEBUG - dbg_addr_ = "Listening @ "; - dbg_addr_.append(GetLocalAddress().ToString()); -#endif // _DEBUG - } - return err; - } - - AsyncSocket* Accept(SocketAddress *out_addr) { - sockaddr_storage addr_storage; - socklen_t addr_len = sizeof(addr_storage); - sockaddr* addr = reinterpret_cast(&addr_storage); - SOCKET s = ::accept(s_, addr, &addr_len); - UpdateLastError(); - if (s == INVALID_SOCKET) - return NULL; - enabled_events_ |= DE_ACCEPT; - if (out_addr != NULL) - SocketAddressFromSockAddrStorage(addr_storage, out_addr); - return ss_->WrapSocket(s); - } - - int Close() { - if (s_ == INVALID_SOCKET) - return 0; - int err = ::closesocket(s_); - UpdateLastError(); - s_ = INVALID_SOCKET; - state_ = CS_CLOSED; - enabled_events_ = 0; - if (resolver_) { - resolver_->Destroy(false); - resolver_ = NULL; - } - return err; - } - - int EstimateMTU(uint16* mtu) { - SocketAddress addr = GetRemoteAddress(); - if (addr.IsAny()) { - SetError(ENOTCONN); - return -1; - } - -#if defined(WEBRTC_WIN) - // Gets the interface MTU (TTL=1) for the interface used to reach |addr|. - WinPing ping; - if (!ping.IsValid()) { - SetError(EINVAL); // can't think of a better error ID - return -1; - } - int header_size = ICMP_HEADER_SIZE; - if (addr.family() == AF_INET6) { - header_size += IPV6_HEADER_SIZE; - } else if (addr.family() == AF_INET) { - header_size += IP_HEADER_SIZE; - } - - for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) { - int32 size = PACKET_MAXIMUMS[level] - header_size; - WinPing::PingResult result = ping.Ping(addr.ipaddr(), size, - ICMP_PING_TIMEOUT_MILLIS, - 1, false); - if (result == WinPing::PING_FAIL) { - SetError(EINVAL); // can't think of a better error ID - return -1; - } else if (result != WinPing::PING_TOO_LARGE) { - *mtu = PACKET_MAXIMUMS[level]; - return 0; - } - } - - ASSERT(false); - return -1; -#elif defined(WEBRTC_MAC) - // No simple way to do this on Mac OS X. - // SIOCGIFMTU would work if we knew which interface would be used, but - // figuring that out is pretty complicated. For now we'll return an error - // and let the caller pick a default MTU. - SetError(EINVAL); - return -1; -#elif defined(WEBRTC_LINUX) - // Gets the path MTU. - int value; - socklen_t vlen = sizeof(value); - int err = getsockopt(s_, IPPROTO_IP, IP_MTU, &value, &vlen); - if (err < 0) { - UpdateLastError(); - return err; - } - - ASSERT((0 <= value) && (value <= 65536)); - *mtu = value; - return 0; -#elif defined(__native_client__) - // Most socket operations, including this, will fail in NaCl's sandbox. - error_ = EACCES; - return -1; -#endif - } - - SocketServer* socketserver() { return ss_; } - - protected: - void OnResolveResult(AsyncResolverInterface* resolver) { - if (resolver != resolver_) { - return; - } - - int error = resolver_->GetError(); - if (error == 0) { - error = DoConnect(resolver_->address()); - } else { - Close(); - } - - if (error) { - SetError(error); - SignalCloseEvent(this, error); - } - } - - void UpdateLastError() { - SetError(LAST_SYSTEM_ERROR); - } - - void MaybeRemapSendError() { -#if defined(WEBRTC_MAC) - // https://developer.apple.com/library/mac/documentation/Darwin/ - // Reference/ManPages/man2/sendto.2.html - // ENOBUFS - The output queue for a network interface is full. - // This generally indicates that the interface has stopped sending, - // but may be caused by transient congestion. - if (GetError() == ENOBUFS) { - SetError(EWOULDBLOCK); - } -#endif - } - - static int TranslateOption(Option opt, int* slevel, int* sopt) { - switch (opt) { - case OPT_DONTFRAGMENT: -#if defined(WEBRTC_WIN) - *slevel = IPPROTO_IP; - *sopt = IP_DONTFRAGMENT; - break; -#elif defined(WEBRTC_MAC) || defined(BSD) || defined(__native_client__) - LOG(LS_WARNING) << "Socket::OPT_DONTFRAGMENT not supported."; - return -1; -#elif defined(WEBRTC_POSIX) - *slevel = IPPROTO_IP; - *sopt = IP_MTU_DISCOVER; - break; -#endif - case OPT_RCVBUF: - *slevel = SOL_SOCKET; - *sopt = SO_RCVBUF; - break; - case OPT_SNDBUF: - *slevel = SOL_SOCKET; - *sopt = SO_SNDBUF; - break; - case OPT_NODELAY: - *slevel = IPPROTO_TCP; - *sopt = TCP_NODELAY; - break; - 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; - } - return 0; - } - - PhysicalSocketServer* ss_; - SOCKET s_; - uint8 enabled_events_; - bool udp_; - int error_; - // Protects |error_| that is accessed from different threads. - mutable CriticalSection crit_; - ConnState state_; - AsyncResolver* resolver_; - -#ifdef _DEBUG - std::string dbg_addr_; -#endif // _DEBUG; -}; - -#if defined(WEBRTC_POSIX) -class EventDispatcher : public Dispatcher { - public: - EventDispatcher(PhysicalSocketServer* ss) : ss_(ss), fSignaled_(false) { - if (pipe(afd_) < 0) - LOG(LERROR) << "pipe failed"; - ss_->Add(this); - } - - virtual ~EventDispatcher() { - ss_->Remove(this); - close(afd_[0]); - close(afd_[1]); - } - - virtual void Signal() { - CritScope cs(&crit_); - if (!fSignaled_) { - const uint8 b[1] = { 0 }; - if (VERIFY(1 == write(afd_[1], b, sizeof(b)))) { - fSignaled_ = true; - } - } - } - - virtual uint32 GetRequestedEvents() { - return DE_READ; - } - - virtual void OnPreEvent(uint32 ff) { - // It is not possible to perfectly emulate an auto-resetting event with - // pipes. This simulates it by resetting before the event is handled. - - CritScope cs(&crit_); - if (fSignaled_) { - uint8 b[4]; // Allow for reading more than 1 byte, but expect 1. - VERIFY(1 == read(afd_[0], b, sizeof(b))); - fSignaled_ = false; - } - } - - virtual void OnEvent(uint32 ff, int err) { - ASSERT(false); - } - - virtual int GetDescriptor() { - return afd_[0]; - } - - virtual bool IsDescriptorClosed() { - return false; - } - - private: - PhysicalSocketServer *ss_; - int afd_[2]; - bool fSignaled_; - CriticalSection crit_; -}; - -// These two classes use the self-pipe trick to deliver POSIX signals to our -// select loop. This is the only safe, reliable, cross-platform way to do -// non-trivial things with a POSIX signal in an event-driven program (until -// proper pselect() implementations become ubiquitous). - -class PosixSignalHandler { - public: - // POSIX only specifies 32 signals, but in principle the system might have - // more and the programmer might choose to use them, so we size our array - // for 128. - static const int kNumPosixSignals = 128; - - // There is just a single global instance. (Signal handlers do not get any - // sort of user-defined void * parameter, so they can't access anything that - // isn't global.) - static PosixSignalHandler* Instance() { - LIBJINGLE_DEFINE_STATIC_LOCAL(PosixSignalHandler, instance, ()); - return &instance; - } - - // Returns true if the given signal number is set. - bool IsSignalSet(int signum) const { - ASSERT(signum < ARRAY_SIZE(received_signal_)); - if (signum < ARRAY_SIZE(received_signal_)) { - return received_signal_[signum]; - } else { - return false; - } - } - - // Clears the given signal number. - void ClearSignal(int signum) { - ASSERT(signum < ARRAY_SIZE(received_signal_)); - if (signum < ARRAY_SIZE(received_signal_)) { - received_signal_[signum] = false; - } - } - - // Returns the file descriptor to monitor for signal events. - int GetDescriptor() const { - return afd_[0]; - } - - // This is called directly from our real signal handler, so it must be - // signal-handler-safe. That means it cannot assume anything about the - // user-level state of the process, since the handler could be executed at any - // time on any thread. - void OnPosixSignalReceived(int signum) { - if (signum >= ARRAY_SIZE(received_signal_)) { - // We don't have space in our array for this. - return; - } - // Set a flag saying we've seen this signal. - received_signal_[signum] = true; - // Notify application code that we got a signal. - const uint8 b[1] = { 0 }; - if (-1 == write(afd_[1], b, sizeof(b))) { - // Nothing we can do here. If there's an error somehow then there's - // nothing we can safely do from a signal handler. - // No, we can't even safely log it. - // But, we still have to check the return value here. Otherwise, - // GCC 4.4.1 complains ignoring return value. Even (void) doesn't help. - return; - } - } - - private: - PosixSignalHandler() { - if (pipe(afd_) < 0) { - LOG_ERR(LS_ERROR) << "pipe failed"; - return; - } - if (fcntl(afd_[0], F_SETFL, O_NONBLOCK) < 0) { - LOG_ERR(LS_WARNING) << "fcntl #1 failed"; - } - if (fcntl(afd_[1], F_SETFL, O_NONBLOCK) < 0) { - LOG_ERR(LS_WARNING) << "fcntl #2 failed"; - } - memset(const_cast(static_cast(received_signal_)), - 0, - sizeof(received_signal_)); - } - - ~PosixSignalHandler() { - int fd1 = afd_[0]; - int fd2 = afd_[1]; - // We clobber the stored file descriptor numbers here or else in principle - // a signal that happens to be delivered during application termination - // could erroneously write a zero byte to an unrelated file handle in - // OnPosixSignalReceived() if some other file happens to be opened later - // during shutdown and happens to be given the same file descriptor number - // as our pipe had. Unfortunately even with this precaution there is still a - // race where that could occur if said signal happens to be handled - // concurrently with this code and happens to have already read the value of - // afd_[1] from memory before we clobber it, but that's unlikely. - afd_[0] = -1; - afd_[1] = -1; - close(fd1); - close(fd2); - } - - int afd_[2]; - // These are boolean flags that will be set in our signal handler and read - // and cleared from Wait(). There is a race involved in this, but it is - // benign. The signal handler sets the flag before signaling the pipe, so - // we'll never end up blocking in select() while a flag is still true. - // However, if two of the same signal arrive close to each other then it's - // possible that the second time the handler may set the flag while it's still - // true, meaning that signal will be missed. But the first occurrence of it - // will still be handled, so this isn't a problem. - // Volatile is not necessary here for correctness, but this data _is_ volatile - // so I've marked it as such. - volatile uint8 received_signal_[kNumPosixSignals]; -}; - -class PosixSignalDispatcher : public Dispatcher { - public: - PosixSignalDispatcher(PhysicalSocketServer *owner) : owner_(owner) { - owner_->Add(this); - } - - virtual ~PosixSignalDispatcher() { - owner_->Remove(this); - } - - virtual uint32 GetRequestedEvents() { - return DE_READ; - } - - virtual void OnPreEvent(uint32 ff) { - // Events might get grouped if signals come very fast, so we read out up to - // 16 bytes to make sure we keep the pipe empty. - uint8 b[16]; - ssize_t ret = read(GetDescriptor(), b, sizeof(b)); - if (ret < 0) { - LOG_ERR(LS_WARNING) << "Error in read()"; - } else if (ret == 0) { - LOG(LS_WARNING) << "Should have read at least one byte"; - } - } - - virtual void OnEvent(uint32 ff, int err) { - for (int signum = 0; signum < PosixSignalHandler::kNumPosixSignals; - ++signum) { - if (PosixSignalHandler::Instance()->IsSignalSet(signum)) { - PosixSignalHandler::Instance()->ClearSignal(signum); - HandlerMap::iterator i = handlers_.find(signum); - if (i == handlers_.end()) { - // This can happen if a signal is delivered to our process at around - // the same time as we unset our handler for it. It is not an error - // condition, but it's unusual enough to be worth logging. - LOG(LS_INFO) << "Received signal with no handler: " << signum; - } else { - // Otherwise, execute our handler. - (*i->second)(signum); - } - } - } - } - - virtual int GetDescriptor() { - return PosixSignalHandler::Instance()->GetDescriptor(); - } - - virtual bool IsDescriptorClosed() { - return false; - } - - void SetHandler(int signum, void (*handler)(int)) { - handlers_[signum] = handler; - } - - void ClearHandler(int signum) { - handlers_.erase(signum); - } - - bool HasHandlers() { - return !handlers_.empty(); - } - - private: - typedef std::map HandlerMap; - - HandlerMap handlers_; - // Our owner. - PhysicalSocketServer *owner_; -}; - -class SocketDispatcher : public Dispatcher, public PhysicalSocket { - public: - explicit SocketDispatcher(PhysicalSocketServer *ss) : PhysicalSocket(ss) { - } - SocketDispatcher(SOCKET s, PhysicalSocketServer *ss) : PhysicalSocket(ss, s) { - } - - virtual ~SocketDispatcher() { - Close(); - } - - bool Initialize() { - ss_->Add(this); - fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK); - return true; - } - - virtual bool Create(int type) { - return Create(AF_INET, type); - } - - virtual bool Create(int family, int type) { - // Change the socket to be non-blocking. - if (!PhysicalSocket::Create(family, type)) - return false; - - return Initialize(); - } - - virtual int GetDescriptor() { - return s_; - } - - virtual bool IsDescriptorClosed() { - // We don't have a reliable way of distinguishing end-of-stream - // from readability. So test on each readable call. Is this - // inefficient? Probably. - char ch; - ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK); - if (res > 0) { - // Data available, so not closed. - return false; - } else if (res == 0) { - // EOF, so closed. - return true; - } else { // error - switch (errno) { - // Returned if we've already closed s_. - case EBADF: - // Returned during ungraceful peer shutdown. - case ECONNRESET: - return true; - default: - // Assume that all other errors are just blocking errors, meaning the - // connection is still good but we just can't read from it right now. - // This should only happen when connecting (and at most once), because - // in all other cases this function is only called if the file - // descriptor is already known to be in the readable state. However, - // it's not necessary a problem if we spuriously interpret a - // "connection lost"-type error as a blocking error, because typically - // the next recv() will get EOF, so we'll still eventually notice that - // the socket is closed. - LOG_ERR(LS_WARNING) << "Assuming benign blocking error"; - return false; - } - } - } - - virtual uint32 GetRequestedEvents() { - return enabled_events_; - } - - virtual void OnPreEvent(uint32 ff) { - if ((ff & DE_CONNECT) != 0) - state_ = CS_CONNECTED; - if ((ff & DE_CLOSE) != 0) - state_ = CS_CLOSED; - } - - virtual void OnEvent(uint32 ff, int err) { - // Make sure we deliver connect/accept first. Otherwise, consumers may see - // something like a READ followed by a CONNECT, which would be odd. - if ((ff & DE_CONNECT) != 0) { - enabled_events_ &= ~DE_CONNECT; - SignalConnectEvent(this); - } - if ((ff & DE_ACCEPT) != 0) { - enabled_events_ &= ~DE_ACCEPT; - SignalReadEvent(this); - } - if ((ff & DE_READ) != 0) { - enabled_events_ &= ~DE_READ; - SignalReadEvent(this); - } - if ((ff & DE_WRITE) != 0) { - enabled_events_ &= ~DE_WRITE; - SignalWriteEvent(this); - } - if ((ff & DE_CLOSE) != 0) { - // The socket is now dead to us, so stop checking it. - enabled_events_ = 0; - SignalCloseEvent(this, err); - } - } - - virtual int Close() { - if (s_ == INVALID_SOCKET) - return 0; - - ss_->Remove(this); - return PhysicalSocket::Close(); - } -}; - -class FileDispatcher: public Dispatcher, public AsyncFile { - public: - FileDispatcher(int fd, PhysicalSocketServer *ss) : ss_(ss), fd_(fd) { - set_readable(true); - - ss_->Add(this); - - fcntl(fd_, F_SETFL, fcntl(fd_, F_GETFL, 0) | O_NONBLOCK); - } - - virtual ~FileDispatcher() { - ss_->Remove(this); - } - - SocketServer* socketserver() { return ss_; } - - virtual int GetDescriptor() { - return fd_; - } - - virtual bool IsDescriptorClosed() { - return false; - } - - virtual uint32 GetRequestedEvents() { - return flags_; - } - - virtual void OnPreEvent(uint32 ff) { - } - - virtual void OnEvent(uint32 ff, int err) { - if ((ff & DE_READ) != 0) - SignalReadEvent(this); - if ((ff & DE_WRITE) != 0) - SignalWriteEvent(this); - if ((ff & DE_CLOSE) != 0) - SignalCloseEvent(this, err); - } - - virtual bool readable() { - return (flags_ & DE_READ) != 0; - } - - virtual void set_readable(bool value) { - flags_ = value ? (flags_ | DE_READ) : (flags_ & ~DE_READ); - } - - virtual bool writable() { - return (flags_ & DE_WRITE) != 0; - } - - virtual void set_writable(bool value) { - flags_ = value ? (flags_ | DE_WRITE) : (flags_ & ~DE_WRITE); - } - - private: - PhysicalSocketServer* ss_; - int fd_; - int flags_; -}; - -AsyncFile* PhysicalSocketServer::CreateFile(int fd) { - return new FileDispatcher(fd, this); -} - -#endif // WEBRTC_POSIX - -#if defined(WEBRTC_WIN) -static uint32 FlagsToEvents(uint32 events) { - uint32 ffFD = FD_CLOSE; - if (events & DE_READ) - ffFD |= FD_READ; - if (events & DE_WRITE) - ffFD |= FD_WRITE; - if (events & DE_CONNECT) - ffFD |= FD_CONNECT; - if (events & DE_ACCEPT) - ffFD |= FD_ACCEPT; - return ffFD; -} - -class EventDispatcher : public Dispatcher { - public: - EventDispatcher(PhysicalSocketServer *ss) : ss_(ss) { - hev_ = WSACreateEvent(); - if (hev_) { - ss_->Add(this); - } - } - - ~EventDispatcher() { - if (hev_ != NULL) { - ss_->Remove(this); - WSACloseEvent(hev_); - hev_ = NULL; - } - } - - virtual void Signal() { - if (hev_ != NULL) - WSASetEvent(hev_); - } - - virtual uint32 GetRequestedEvents() { - return 0; - } - - virtual void OnPreEvent(uint32 ff) { - WSAResetEvent(hev_); - } - - virtual void OnEvent(uint32 ff, int err) { - } - - virtual WSAEVENT GetWSAEvent() { - return hev_; - } - - virtual SOCKET GetSocket() { - return INVALID_SOCKET; - } - - virtual bool CheckSignalClose() { return false; } - -private: - PhysicalSocketServer* ss_; - WSAEVENT hev_; -}; - -class SocketDispatcher : public Dispatcher, public PhysicalSocket { - public: - static int next_id_; - int id_; - bool signal_close_; - int signal_err_; - - SocketDispatcher(PhysicalSocketServer* ss) - : PhysicalSocket(ss), - id_(0), - signal_close_(false) { - } - - SocketDispatcher(SOCKET s, PhysicalSocketServer* ss) - : PhysicalSocket(ss, s), - id_(0), - signal_close_(false) { - } - - virtual ~SocketDispatcher() { - Close(); - } - - bool Initialize() { - ASSERT(s_ != INVALID_SOCKET); - // Must be a non-blocking - u_long argp = 1; - ioctlsocket(s_, FIONBIO, &argp); - ss_->Add(this); - return true; - } - - virtual bool Create(int type) { - return Create(AF_INET, type); - } - - virtual bool Create(int family, int type) { - // Create socket - if (!PhysicalSocket::Create(family, type)) - return false; - - if (!Initialize()) - return false; - - do { id_ = ++next_id_; } while (id_ == 0); - return true; - } - - virtual int Close() { - if (s_ == INVALID_SOCKET) - return 0; - - id_ = 0; - signal_close_ = false; - ss_->Remove(this); - return PhysicalSocket::Close(); - } - - virtual uint32 GetRequestedEvents() { - return enabled_events_; - } - - virtual void OnPreEvent(uint32 ff) { - if ((ff & DE_CONNECT) != 0) - state_ = CS_CONNECTED; - // We set CS_CLOSED from CheckSignalClose. - } - - virtual void OnEvent(uint32 ff, int err) { - int cache_id = id_; - // Make sure we deliver connect/accept first. Otherwise, consumers may see - // something like a READ followed by a CONNECT, which would be odd. - if (((ff & DE_CONNECT) != 0) && (id_ == cache_id)) { - if (ff != DE_CONNECT) - LOG(LS_VERBOSE) << "Signalled with DE_CONNECT: " << ff; - enabled_events_ &= ~DE_CONNECT; -#ifdef _DEBUG - dbg_addr_ = "Connected @ "; - dbg_addr_.append(GetRemoteAddress().ToString()); -#endif // _DEBUG - SignalConnectEvent(this); - } - if (((ff & DE_ACCEPT) != 0) && (id_ == cache_id)) { - enabled_events_ &= ~DE_ACCEPT; - SignalReadEvent(this); - } - if ((ff & DE_READ) != 0) { - enabled_events_ &= ~DE_READ; - SignalReadEvent(this); - } - if (((ff & DE_WRITE) != 0) && (id_ == cache_id)) { - enabled_events_ &= ~DE_WRITE; - SignalWriteEvent(this); - } - if (((ff & DE_CLOSE) != 0) && (id_ == cache_id)) { - signal_close_ = true; - signal_err_ = err; - } - } - - virtual WSAEVENT GetWSAEvent() { - return WSA_INVALID_EVENT; - } - - virtual SOCKET GetSocket() { - return s_; - } - - virtual bool CheckSignalClose() { - if (!signal_close_) - return false; - - char ch; - if (recv(s_, &ch, 1, MSG_PEEK) > 0) - return false; - - state_ = CS_CLOSED; - signal_close_ = false; - SignalCloseEvent(this, signal_err_); - return true; - } -}; - -int SocketDispatcher::next_id_ = 0; - -#endif // WEBRTC_WIN - -// Sets the value of a boolean value to false when signaled. -class Signaler : public EventDispatcher { - public: - Signaler(PhysicalSocketServer* ss, bool* pf) - : EventDispatcher(ss), pf_(pf) { - } - virtual ~Signaler() { } - - void OnEvent(uint32 ff, int err) { - if (pf_) - *pf_ = false; - } - - private: - bool *pf_; -}; - -PhysicalSocketServer::PhysicalSocketServer() - : fWait_(false) { - signal_wakeup_ = new Signaler(this, &fWait_); -#if defined(WEBRTC_WIN) - socket_ev_ = WSACreateEvent(); -#endif -} - -PhysicalSocketServer::~PhysicalSocketServer() { -#if defined(WEBRTC_WIN) - WSACloseEvent(socket_ev_); -#endif -#if defined(WEBRTC_POSIX) - signal_dispatcher_.reset(); -#endif - delete signal_wakeup_; - ASSERT(dispatchers_.empty()); -} - -void PhysicalSocketServer::WakeUp() { - signal_wakeup_->Signal(); -} - -Socket* PhysicalSocketServer::CreateSocket(int type) { - return CreateSocket(AF_INET, type); -} - -Socket* PhysicalSocketServer::CreateSocket(int family, int type) { - PhysicalSocket* socket = new PhysicalSocket(this); - if (socket->Create(family, type)) { - return socket; - } else { - delete socket; - return 0; - } -} - -AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int type) { - return CreateAsyncSocket(AF_INET, type); -} - -AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int family, int type) { - SocketDispatcher* dispatcher = new SocketDispatcher(this); - if (dispatcher->Create(family, type)) { - return dispatcher; - } else { - delete dispatcher; - return 0; - } -} - -AsyncSocket* PhysicalSocketServer::WrapSocket(SOCKET s) { - SocketDispatcher* dispatcher = new SocketDispatcher(s, this); - if (dispatcher->Initialize()) { - return dispatcher; - } else { - delete dispatcher; - return 0; - } -} - -void PhysicalSocketServer::Add(Dispatcher *pdispatcher) { - CritScope cs(&crit_); - // Prevent duplicates. This can cause dead dispatchers to stick around. - DispatcherList::iterator pos = std::find(dispatchers_.begin(), - dispatchers_.end(), - pdispatcher); - if (pos != dispatchers_.end()) - return; - dispatchers_.push_back(pdispatcher); -} - -void PhysicalSocketServer::Remove(Dispatcher *pdispatcher) { - CritScope cs(&crit_); - DispatcherList::iterator pos = std::find(dispatchers_.begin(), - dispatchers_.end(), - pdispatcher); - // We silently ignore duplicate calls to Add, so we should silently ignore - // the (expected) symmetric calls to Remove. Note that this may still hide - // a real issue, so we at least log a warning about it. - if (pos == dispatchers_.end()) { - LOG(LS_WARNING) << "PhysicalSocketServer asked to remove a unknown " - << "dispatcher, potentially from a duplicate call to Add."; - return; - } - size_t index = pos - dispatchers_.begin(); - dispatchers_.erase(pos); - for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end(); - ++it) { - if (index < **it) { - --**it; - } - } -} - -#if defined(WEBRTC_POSIX) -bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { - // Calculate timing information - - struct timeval *ptvWait = NULL; - struct timeval tvWait; - struct timeval tvStop; - if (cmsWait != kForever) { - // Calculate wait timeval - tvWait.tv_sec = cmsWait / 1000; - tvWait.tv_usec = (cmsWait % 1000) * 1000; - ptvWait = &tvWait; - - // Calculate when to return in a timeval - gettimeofday(&tvStop, NULL); - tvStop.tv_sec += tvWait.tv_sec; - tvStop.tv_usec += tvWait.tv_usec; - if (tvStop.tv_usec >= 1000000) { - tvStop.tv_usec -= 1000000; - tvStop.tv_sec += 1; - } - } - - // Zero all fd_sets. Don't need to do this inside the loop since - // select() zeros the descriptors not signaled - - fd_set fdsRead; - FD_ZERO(&fdsRead); - fd_set fdsWrite; - FD_ZERO(&fdsWrite); - - fWait_ = true; - - while (fWait_) { - int fdmax = -1; - { - CritScope cr(&crit_); - for (size_t i = 0; i < dispatchers_.size(); ++i) { - // Query dispatchers for read and write wait state - Dispatcher *pdispatcher = dispatchers_[i]; - ASSERT(pdispatcher); - if (!process_io && (pdispatcher != signal_wakeup_)) - continue; - int fd = pdispatcher->GetDescriptor(); - if (fd > fdmax) - fdmax = fd; - - uint32 ff = pdispatcher->GetRequestedEvents(); - if (ff & (DE_READ | DE_ACCEPT)) - FD_SET(fd, &fdsRead); - if (ff & (DE_WRITE | DE_CONNECT)) - FD_SET(fd, &fdsWrite); - } - } - - // Wait then call handlers as appropriate - // < 0 means error - // 0 means timeout - // > 0 means count of descriptors ready - int n = select(fdmax + 1, &fdsRead, &fdsWrite, NULL, ptvWait); - - // If error, return error. - if (n < 0) { - if (errno != EINTR) { - LOG_E(LS_ERROR, EN, errno) << "select"; - return false; - } - // Else ignore the error and keep going. If this EINTR was for one of the - // signals managed by this PhysicalSocketServer, the - // PosixSignalDeliveryDispatcher will be in the signaled state in the next - // iteration. - } else if (n == 0) { - // If timeout, return success - return true; - } else { - // We have signaled descriptors - CritScope cr(&crit_); - for (size_t i = 0; i < dispatchers_.size(); ++i) { - Dispatcher *pdispatcher = dispatchers_[i]; - int fd = pdispatcher->GetDescriptor(); - uint32 ff = 0; - int errcode = 0; - - // Reap any error code, which can be signaled through reads or writes. - // TODO: Should we set errcode if getsockopt fails? - if (FD_ISSET(fd, &fdsRead) || FD_ISSET(fd, &fdsWrite)) { - socklen_t len = sizeof(errcode); - ::getsockopt(fd, SOL_SOCKET, SO_ERROR, &errcode, &len); - } - - // Check readable descriptors. If we're waiting on an accept, signal - // that. Otherwise we're waiting for data, check to see if we're - // readable or really closed. - // TODO: Only peek at TCP descriptors. - if (FD_ISSET(fd, &fdsRead)) { - FD_CLR(fd, &fdsRead); - if (pdispatcher->GetRequestedEvents() & DE_ACCEPT) { - ff |= DE_ACCEPT; - } else if (errcode || pdispatcher->IsDescriptorClosed()) { - ff |= DE_CLOSE; - } else { - ff |= DE_READ; - } - } - - // Check writable descriptors. If we're waiting on a connect, detect - // success versus failure by the reaped error code. - if (FD_ISSET(fd, &fdsWrite)) { - FD_CLR(fd, &fdsWrite); - if (pdispatcher->GetRequestedEvents() & DE_CONNECT) { - if (!errcode) { - ff |= DE_CONNECT; - } else { - ff |= DE_CLOSE; - } - } else { - ff |= DE_WRITE; - } - } - - // Tell the descriptor about the event. - if (ff != 0) { - pdispatcher->OnPreEvent(ff); - pdispatcher->OnEvent(ff, errcode); - } - } - } - - // Recalc the time remaining to wait. Doing it here means it doesn't get - // calced twice the first time through the loop - if (ptvWait) { - ptvWait->tv_sec = 0; - ptvWait->tv_usec = 0; - struct timeval tvT; - gettimeofday(&tvT, NULL); - if ((tvStop.tv_sec > tvT.tv_sec) - || ((tvStop.tv_sec == tvT.tv_sec) - && (tvStop.tv_usec > tvT.tv_usec))) { - ptvWait->tv_sec = tvStop.tv_sec - tvT.tv_sec; - ptvWait->tv_usec = tvStop.tv_usec - tvT.tv_usec; - if (ptvWait->tv_usec < 0) { - ASSERT(ptvWait->tv_sec > 0); - ptvWait->tv_usec += 1000000; - ptvWait->tv_sec -= 1; - } - } - } - } - - return true; -} - -static void GlobalSignalHandler(int signum) { - PosixSignalHandler::Instance()->OnPosixSignalReceived(signum); -} - -bool PhysicalSocketServer::SetPosixSignalHandler(int signum, - void (*handler)(int)) { - // If handler is SIG_IGN or SIG_DFL then clear our user-level handler, - // otherwise set one. - if (handler == SIG_IGN || handler == SIG_DFL) { - if (!InstallSignal(signum, handler)) { - return false; - } - if (signal_dispatcher_) { - signal_dispatcher_->ClearHandler(signum); - if (!signal_dispatcher_->HasHandlers()) { - signal_dispatcher_.reset(); - } - } - } else { - if (!signal_dispatcher_) { - signal_dispatcher_.reset(new PosixSignalDispatcher(this)); - } - signal_dispatcher_->SetHandler(signum, handler); - if (!InstallSignal(signum, &GlobalSignalHandler)) { - return false; - } - } - return true; -} - -Dispatcher* PhysicalSocketServer::signal_dispatcher() { - return signal_dispatcher_.get(); -} - -bool PhysicalSocketServer::InstallSignal(int signum, void (*handler)(int)) { - struct sigaction act; - // It doesn't really matter what we set this mask to. - if (sigemptyset(&act.sa_mask) != 0) { - LOG_ERR(LS_ERROR) << "Couldn't set mask"; - 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; - } - return true; -} -#endif // WEBRTC_POSIX - -#if defined(WEBRTC_WIN) -bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { - int cmsTotal = cmsWait; - int cmsElapsed = 0; - uint32 msStart = Time(); - - fWait_ = true; - while (fWait_) { - std::vector events; - std::vector event_owners; - - events.push_back(socket_ev_); - - { - CritScope cr(&crit_); - size_t i = 0; - iterators_.push_back(&i); - // Don't track dispatchers_.size(), because we want to pick up any new - // dispatchers that were added while processing the loop. - while (i < dispatchers_.size()) { - Dispatcher* disp = dispatchers_[i++]; - if (!process_io && (disp != signal_wakeup_)) - continue; - SOCKET s = disp->GetSocket(); - if (disp->CheckSignalClose()) { - // We just signalled close, don't poll this socket - } else if (s != INVALID_SOCKET) { - WSAEventSelect(s, - events[0], - FlagsToEvents(disp->GetRequestedEvents())); - } else { - events.push_back(disp->GetWSAEvent()); - event_owners.push_back(disp); - } - } - ASSERT(iterators_.back() == &i); - iterators_.pop_back(); - } - - // Which is shorter, the delay wait or the asked wait? - - int cmsNext; - if (cmsWait == kForever) { - cmsNext = cmsWait; - } else { - cmsNext = _max(0, cmsTotal - cmsElapsed); - } - - // Wait for one of the events to signal - DWORD dw = WSAWaitForMultipleEvents(static_cast(events.size()), - &events[0], - false, - cmsNext, - false); - - if (dw == WSA_WAIT_FAILED) { - // Failed? - // TODO: need a better strategy than this! - WSAGetLastError(); - ASSERT(false); - return false; - } else if (dw == WSA_WAIT_TIMEOUT) { - // Timeout? - return true; - } else { - // Figure out which one it is and call it - CritScope cr(&crit_); - int index = dw - WSA_WAIT_EVENT_0; - if (index > 0) { - --index; // The first event is the socket event - event_owners[index]->OnPreEvent(0); - event_owners[index]->OnEvent(0, 0); - } else if (process_io) { - size_t i = 0, end = dispatchers_.size(); - iterators_.push_back(&i); - iterators_.push_back(&end); // Don't iterate over new dispatchers. - while (i < end) { - Dispatcher* disp = dispatchers_[i++]; - SOCKET s = disp->GetSocket(); - if (s == INVALID_SOCKET) - continue; - - WSANETWORKEVENTS wsaEvents; - int err = WSAEnumNetworkEvents(s, events[0], &wsaEvents); - if (err == 0) { - -#if LOGGING - { - if ((wsaEvents.lNetworkEvents & FD_READ) && - wsaEvents.iErrorCode[FD_READ_BIT] != 0) { - LOG(WARNING) << "PhysicalSocketServer got FD_READ_BIT error " - << wsaEvents.iErrorCode[FD_READ_BIT]; - } - if ((wsaEvents.lNetworkEvents & FD_WRITE) && - wsaEvents.iErrorCode[FD_WRITE_BIT] != 0) { - LOG(WARNING) << "PhysicalSocketServer got FD_WRITE_BIT error " - << wsaEvents.iErrorCode[FD_WRITE_BIT]; - } - if ((wsaEvents.lNetworkEvents & FD_CONNECT) && - wsaEvents.iErrorCode[FD_CONNECT_BIT] != 0) { - LOG(WARNING) << "PhysicalSocketServer got FD_CONNECT_BIT error " - << wsaEvents.iErrorCode[FD_CONNECT_BIT]; - } - if ((wsaEvents.lNetworkEvents & FD_ACCEPT) && - wsaEvents.iErrorCode[FD_ACCEPT_BIT] != 0) { - LOG(WARNING) << "PhysicalSocketServer got FD_ACCEPT_BIT error " - << wsaEvents.iErrorCode[FD_ACCEPT_BIT]; - } - if ((wsaEvents.lNetworkEvents & FD_CLOSE) && - wsaEvents.iErrorCode[FD_CLOSE_BIT] != 0) { - LOG(WARNING) << "PhysicalSocketServer got FD_CLOSE_BIT error " - << wsaEvents.iErrorCode[FD_CLOSE_BIT]; - } - } -#endif - uint32 ff = 0; - int errcode = 0; - if (wsaEvents.lNetworkEvents & FD_READ) - ff |= DE_READ; - if (wsaEvents.lNetworkEvents & FD_WRITE) - ff |= DE_WRITE; - if (wsaEvents.lNetworkEvents & FD_CONNECT) { - if (wsaEvents.iErrorCode[FD_CONNECT_BIT] == 0) { - ff |= DE_CONNECT; - } else { - ff |= DE_CLOSE; - errcode = wsaEvents.iErrorCode[FD_CONNECT_BIT]; - } - } - if (wsaEvents.lNetworkEvents & FD_ACCEPT) - ff |= DE_ACCEPT; - if (wsaEvents.lNetworkEvents & FD_CLOSE) { - ff |= DE_CLOSE; - errcode = wsaEvents.iErrorCode[FD_CLOSE_BIT]; - } - if (ff != 0) { - disp->OnPreEvent(ff); - disp->OnEvent(ff, errcode); - } - } - } - ASSERT(iterators_.back() == &end); - iterators_.pop_back(); - ASSERT(iterators_.back() == &i); - iterators_.pop_back(); - } - - // Reset the network event until new activity occurs - WSAResetEvent(socket_ev_); - } - - // Break? - if (!fWait_) - break; - cmsElapsed = TimeSince(msStart); - if ((cmsWait != kForever) && (cmsElapsed >= cmsWait)) { - break; - } - } - - // Done - return true; -} -#endif // WEBRTC_WIN - -} // namespace rtc diff --git a/webrtc/base/physicalsocketserver.h b/webrtc/base/physicalsocketserver.h deleted file mode 100644 index 8a289de7e..000000000 --- a/webrtc/base/physicalsocketserver.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_PHYSICALSOCKETSERVER_H__ -#define WEBRTC_BASE_PHYSICALSOCKETSERVER_H__ - -#include - -#include "webrtc/base/asyncfile.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/socketserver.h" -#include "webrtc/base/criticalsection.h" - -#if defined(WEBRTC_POSIX) -typedef int SOCKET; -#endif // WEBRTC_POSIX - -namespace rtc { - -// Event constants for the Dispatcher class. -enum DispatcherEvent { - DE_READ = 0x0001, - DE_WRITE = 0x0002, - DE_CONNECT = 0x0004, - DE_CLOSE = 0x0008, - DE_ACCEPT = 0x0010, -}; - -class Signaler; -#if defined(WEBRTC_POSIX) -class PosixSignalDispatcher; -#endif - -class Dispatcher { - public: - virtual ~Dispatcher() {} - virtual uint32 GetRequestedEvents() = 0; - virtual void OnPreEvent(uint32 ff) = 0; - virtual void OnEvent(uint32 ff, int err) = 0; -#if defined(WEBRTC_WIN) - virtual WSAEVENT GetWSAEvent() = 0; - virtual SOCKET GetSocket() = 0; - virtual bool CheckSignalClose() = 0; -#elif defined(WEBRTC_POSIX) - virtual int GetDescriptor() = 0; - virtual bool IsDescriptorClosed() = 0; -#endif -}; - -// A socket server that provides the real sockets of the underlying OS. -class PhysicalSocketServer : public SocketServer { - public: - PhysicalSocketServer(); - virtual ~PhysicalSocketServer(); - - // SocketFactory: - virtual Socket* CreateSocket(int type); - virtual Socket* CreateSocket(int family, int type); - - virtual AsyncSocket* CreateAsyncSocket(int type); - virtual AsyncSocket* CreateAsyncSocket(int family, int type); - - // Internal Factory for Accept - AsyncSocket* WrapSocket(SOCKET s); - - // SocketServer: - virtual bool Wait(int cms, bool process_io); - virtual void WakeUp(); - - void Add(Dispatcher* dispatcher); - void Remove(Dispatcher* dispatcher); - -#if defined(WEBRTC_POSIX) - AsyncFile* CreateFile(int fd); - - // Sets the function to be executed in response to the specified POSIX signal. - // The function is executed from inside Wait() using the "self-pipe trick"-- - // regardless of which thread receives the signal--and hence can safely - // manipulate user-level data structures. - // "handler" may be SIG_IGN, SIG_DFL, or a user-specified function, just like - // with signal(2). - // Only one PhysicalSocketServer should have user-level signal handlers. - // Dispatching signals on multiple PhysicalSocketServers is not reliable. - // The signal mask is not modified. It is the caller's responsibily to - // maintain it as desired. - virtual bool SetPosixSignalHandler(int signum, void (*handler)(int)); - - protected: - Dispatcher* signal_dispatcher(); -#endif - - private: - typedef std::vector DispatcherList; - typedef std::vector IteratorList; - -#if defined(WEBRTC_POSIX) - static bool InstallSignal(int signum, void (*handler)(int)); - - scoped_ptr signal_dispatcher_; -#endif - DispatcherList dispatchers_; - IteratorList iterators_; - Signaler* signal_wakeup_; - CriticalSection crit_; - bool fWait_; -#if defined(WEBRTC_WIN) - WSAEVENT socket_ev_; -#endif -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_PHYSICALSOCKETSERVER_H__ diff --git a/webrtc/base/physicalsocketserver_unittest.cc b/webrtc/base/physicalsocketserver_unittest.cc deleted file mode 100644 index f29c5fc12..000000000 --- a/webrtc/base/physicalsocketserver_unittest.cc +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/physicalsocketserver.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/socket_unittest.h" -#include "webrtc/base/testutils.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -class PhysicalSocketTest : public SocketTest { -}; - -TEST_F(PhysicalSocketTest, TestConnectIPv4) { - SocketTest::TestConnectIPv4(); -} - -TEST_F(PhysicalSocketTest, TestConnectIPv6) { - SocketTest::TestConnectIPv6(); -} - -TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) { - SocketTest::TestConnectWithDnsLookupIPv4(); -} - -TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) { - SocketTest::TestConnectWithDnsLookupIPv6(); -} - -TEST_F(PhysicalSocketTest, TestConnectFailIPv4) { - SocketTest::TestConnectFailIPv4(); -} - -TEST_F(PhysicalSocketTest, TestConnectFailIPv6) { - SocketTest::TestConnectFailIPv6(); -} - -TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) { - SocketTest::TestConnectWithDnsLookupFailIPv4(); -} - - -TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) { - SocketTest::TestConnectWithDnsLookupFailIPv6(); -} - - -TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) { - SocketTest::TestConnectWithClosedSocketIPv4(); -} - -TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) { - SocketTest::TestConnectWithClosedSocketIPv6(); -} - -TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) { - SocketTest::TestConnectWhileNotClosedIPv4(); -} - -TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) { - SocketTest::TestConnectWhileNotClosedIPv6(); -} - -TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) { - SocketTest::TestServerCloseDuringConnectIPv4(); -} - -TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) { - SocketTest::TestServerCloseDuringConnectIPv6(); -} - -TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) { - SocketTest::TestClientCloseDuringConnectIPv4(); -} - -TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) { - SocketTest::TestClientCloseDuringConnectIPv6(); -} - -TEST_F(PhysicalSocketTest, TestServerCloseIPv4) { - SocketTest::TestServerCloseIPv4(); -} - -TEST_F(PhysicalSocketTest, TestServerCloseIPv6) { - SocketTest::TestServerCloseIPv6(); -} - -TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) { - SocketTest::TestCloseInClosedCallbackIPv4(); -} - -TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) { - SocketTest::TestCloseInClosedCallbackIPv6(); -} - -TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) { - SocketTest::TestSocketServerWaitIPv4(); -} - -TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv6) { - SocketTest::TestSocketServerWaitIPv6(); -} - -TEST_F(PhysicalSocketTest, TestTcpIPv4) { - SocketTest::TestTcpIPv4(); -} - -TEST_F(PhysicalSocketTest, TestTcpIPv6) { - SocketTest::TestTcpIPv6(); -} - -TEST_F(PhysicalSocketTest, TestUdpIPv4) { - SocketTest::TestUdpIPv4(); -} - -TEST_F(PhysicalSocketTest, TestUdpIPv6) { - SocketTest::TestUdpIPv6(); -} - -TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv4) { - SocketTest::TestUdpReadyToSendIPv4(); -} - -TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) { - SocketTest::TestUdpReadyToSendIPv6(); -} - -TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) { - SocketTest::TestGetSetOptionsIPv4(); -} - -TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) { - SocketTest::TestGetSetOptionsIPv6(); -} - -#if defined(WEBRTC_POSIX) - -class PosixSignalDeliveryTest : public testing::Test { - public: - static void RecordSignal(int signum) { - signals_received_.push_back(signum); - signaled_thread_ = Thread::Current(); - } - - protected: - void SetUp() { - ss_.reset(new PhysicalSocketServer()); - } - - void TearDown() { - ss_.reset(NULL); - signals_received_.clear(); - signaled_thread_ = NULL; - } - - bool ExpectSignal(int signum) { - if (signals_received_.empty()) { - LOG(LS_ERROR) << "ExpectSignal(): No signal received"; - return false; - } - if (signals_received_[0] != signum) { - LOG(LS_ERROR) << "ExpectSignal(): Received signal " << - signals_received_[0] << ", expected " << signum; - return false; - } - signals_received_.erase(signals_received_.begin()); - return true; - } - - bool ExpectNone() { - bool ret = signals_received_.empty(); - if (!ret) { - LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0] - << ", expected none"; - } - return ret; - } - - static std::vector signals_received_; - static Thread *signaled_thread_; - - scoped_ptr ss_; -}; - -std::vector PosixSignalDeliveryTest::signals_received_; -Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL; - -// Test receiving a synchronous signal while not in Wait() and then entering -// Wait() afterwards. -TEST_F(PosixSignalDeliveryTest, RaiseThenWait) { - ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal)); - raise(SIGTERM); - EXPECT_TRUE(ss_->Wait(0, true)); - EXPECT_TRUE(ExpectSignal(SIGTERM)); - EXPECT_TRUE(ExpectNone()); -} - -// Test that we can handle getting tons of repeated signals and that we see all -// the different ones. -TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) { - ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal); - ss_->SetPosixSignalHandler(SIGINT, &RecordSignal); - for (int i = 0; i < 10000; ++i) { - raise(SIGTERM); - } - raise(SIGINT); - EXPECT_TRUE(ss_->Wait(0, true)); - // Order will be lowest signal numbers first. - EXPECT_TRUE(ExpectSignal(SIGINT)); - EXPECT_TRUE(ExpectSignal(SIGTERM)); - EXPECT_TRUE(ExpectNone()); -} - -// Test that a signal during a Wait() call is detected. -TEST_F(PosixSignalDeliveryTest, SignalDuringWait) { - ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal); - alarm(1); - EXPECT_TRUE(ss_->Wait(1500, true)); - EXPECT_TRUE(ExpectSignal(SIGALRM)); - EXPECT_TRUE(ExpectNone()); -} - -class RaiseSigTermRunnable : public Runnable { - void Run(Thread *thread) { - thread->socketserver()->Wait(1000, false); - - // Allow SIGTERM. This will be the only thread with it not masked so it will - // be delivered to us. - sigset_t mask; - sigemptyset(&mask); - pthread_sigmask(SIG_SETMASK, &mask, NULL); - - // Raise it. - raise(SIGTERM); - } -}; - -// Test that it works no matter what thread the kernel chooses to give the -// signal to (since it's not guaranteed to be the one that Wait() runs on). -TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) { - ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal); - // Mask out SIGTERM so that it can't be delivered to this thread. - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, SIGTERM); - EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL)); - // Start a new thread that raises it. It will have to be delivered to that - // thread. Our implementation should safely handle it and dispatch - // RecordSignal() on this thread. - scoped_ptr thread(new Thread()); - scoped_ptr runnable(new RaiseSigTermRunnable()); - thread->Start(runnable.get()); - EXPECT_TRUE(ss_->Wait(1500, true)); - EXPECT_TRUE(ExpectSignal(SIGTERM)); - EXPECT_EQ(Thread::Current(), signaled_thread_); - EXPECT_TRUE(ExpectNone()); -} - -#endif - -} // namespace rtc diff --git a/webrtc/base/posix.cc b/webrtc/base/posix.cc deleted file mode 100644 index 0eb24ee64..000000000 --- a/webrtc/base/posix.cc +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/posix.h" - -#include -#include -#include - -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) -#include "webrtc/base/linuxfdwalk.h" -#endif -#include "webrtc/base/logging.h" - -namespace rtc { - -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) -static void closefds(void *close_errors, int fd) { - if (fd <= 2) { - // We leave stdin/out/err open to the browser's terminal, if any. - return; - } - if (close(fd) < 0) { - *static_cast(close_errors) = true; - } -} -#endif - -enum { - EXIT_FLAG_CHDIR_ERRORS = 1 << 0, -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - EXIT_FLAG_FDWALK_ERRORS = 1 << 1, - EXIT_FLAG_CLOSE_ERRORS = 1 << 2, -#endif - EXIT_FLAG_SECOND_FORK_FAILED = 1 << 3, -}; - -bool RunAsDaemon(const char *file, const char *const argv[]) { - // Fork intermediate child to daemonize. - pid_t pid = fork(); - if (pid < 0) { - LOG_ERR(LS_ERROR) << "fork()"; - return false; - } else if (!pid) { - // Child. - - // We try to close all fds and change directory to /, but if that fails we - // keep going because it's not critical. - int exit_code = 0; - if (chdir("/") < 0) { - exit_code |= EXIT_FLAG_CHDIR_ERRORS; - } -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - bool close_errors = false; - if (fdwalk(&closefds, &close_errors) < 0) { - exit_code |= EXIT_FLAG_FDWALK_ERRORS; - } - if (close_errors) { - exit_code |= EXIT_FLAG_CLOSE_ERRORS; - } -#endif - - // Fork again to become a daemon. - pid = fork(); - // It is important that everything here use _exit() and not exit(), because - // exit() would call the destructors of all global variables in the whole - // process, which is both unnecessary and unsafe. - if (pid < 0) { - exit_code |= EXIT_FLAG_SECOND_FORK_FAILED; - _exit(exit_code); // if second fork failed - } else if (!pid) { - // Child. - // Successfully daemonized. Run command. - // WEBRTC_POSIX requires the args to be typed as non-const for historical - // reasons, but it mandates that the actual implementation be const, so - // the cast is safe. - execvp(file, const_cast(argv)); - _exit(255); // if execvp failed - } - - // Parent. - // Successfully spawned process, but report any problems to the parent where - // we can log them. - _exit(exit_code); - } - - // Parent. Reap intermediate child. - int status; - pid_t child = waitpid(pid, &status, 0); - if (child < 0) { - LOG_ERR(LS_ERROR) << "Error in waitpid()"; - return false; - } - if (child != pid) { - // Should never happen (see man page). - LOG(LS_ERROR) << "waitpid() chose wrong child???"; - return false; - } - if (!WIFEXITED(status)) { - LOG(LS_ERROR) << "Intermediate child killed uncleanly"; // Probably crashed - return false; - } - - int exit_code = WEXITSTATUS(status); - if (exit_code & EXIT_FLAG_CHDIR_ERRORS) { - LOG(LS_WARNING) << "Child reported probles calling chdir()"; - } -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - if (exit_code & EXIT_FLAG_FDWALK_ERRORS) { - LOG(LS_WARNING) << "Child reported problems calling fdwalk()"; - } - if (exit_code & EXIT_FLAG_CLOSE_ERRORS) { - LOG(LS_WARNING) << "Child reported problems calling close()"; - } -#endif - if (exit_code & EXIT_FLAG_SECOND_FORK_FAILED) { - LOG(LS_ERROR) << "Failed to daemonize"; - // This means the command was not launched, so failure. - return false; - } - return true; -} - -} // namespace rtc diff --git a/webrtc/base/posix.h b/webrtc/base/posix.h deleted file mode 100644 index 8d1c2b11e..000000000 --- a/webrtc/base/posix.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_POSIX_H_ -#define WEBRTC_BASE_POSIX_H_ - -namespace rtc { - -// Runs the given executable name as a daemon, so that it executes concurrently -// with this process. Upon completion, the daemon process will automatically be -// reaped by init(8), so an error exit status or a failure to start the -// executable are not reported. Returns true if the daemon process was forked -// successfully, else false. -bool RunAsDaemon(const char *file, const char *const argv[]); - -} // namespace rtc - -#endif // WEBRTC_BASE_POSIX_H_ diff --git a/webrtc/base/profiler.cc b/webrtc/base/profiler.cc deleted file mode 100644 index f57344853..000000000 --- a/webrtc/base/profiler.cc +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/profiler.h" - -#include - -#include "webrtc/base/timeutils.h" - -namespace { - -// When written to an ostream, FormattedTime chooses an appropriate scale and -// suffix for a time value given in seconds. -class FormattedTime { - public: - explicit FormattedTime(double t) : time_(t) {} - double time() const { return time_; } - private: - double time_; -}; - -std::ostream& operator<<(std::ostream& stream, const FormattedTime& time) { - if (time.time() < 1.0) { - stream << (time.time() * 1000.0) << "ms"; - } else { - stream << time.time() << 's'; - } - return stream; -} - -} // namespace - -namespace rtc { - -ProfilerEvent::ProfilerEvent() - : total_time_(0.0), - mean_(0.0), - sum_of_squared_differences_(0.0), - start_count_(0), - event_count_(0) { -} - -void ProfilerEvent::Start() { - if (start_count_ == 0) { - current_start_time_ = TimeNanos(); - } - ++start_count_; -} - -void ProfilerEvent::Stop(uint64 stop_time) { - --start_count_; - ASSERT(start_count_ >= 0); - if (start_count_ == 0) { - double elapsed = static_cast(stop_time - current_start_time_) / - kNumNanosecsPerSec; - total_time_ += elapsed; - if (event_count_ == 0) { - minimum_ = maximum_ = elapsed; - } else { - minimum_ = _min(minimum_, elapsed); - maximum_ = _max(maximum_, elapsed); - } - // Online variance and mean algorithm: http://en.wikipedia.org/wiki/ - // Algorithms_for_calculating_variance#Online_algorithm - ++event_count_; - double delta = elapsed - mean_; - mean_ = mean_ + delta / event_count_; - sum_of_squared_differences_ += delta * (elapsed - mean_); - } -} - -void ProfilerEvent::Stop() { - Stop(TimeNanos()); -} - -double ProfilerEvent::standard_deviation() const { - if (event_count_ <= 1) return 0.0; - return sqrt(sum_of_squared_differences_ / (event_count_ - 1.0)); -} - -Profiler* Profiler::Instance() { - LIBJINGLE_DEFINE_STATIC_LOCAL(Profiler, instance, ()); - return &instance; -} - -void Profiler::StartEvent(const std::string& event_name) { - lock_.LockShared(); - EventMap::iterator it = events_.find(event_name); - bool needs_insert = (it == events_.end()); - lock_.UnlockShared(); - - if (needs_insert) { - // Need an exclusive lock to modify the map. - ExclusiveScope scope(&lock_); - it = events_.insert( - EventMap::value_type(event_name, ProfilerEvent())).first; - } - - it->second.Start(); -} - -void Profiler::StopEvent(const std::string& event_name) { - // Get the time ASAP, then wait for the lock. - uint64 stop_time = TimeNanos(); - SharedScope scope(&lock_); - EventMap::iterator it = events_.find(event_name); - if (it != events_.end()) { - it->second.Stop(stop_time); - } -} - -void Profiler::ReportToLog(const char* file, int line, - LoggingSeverity severity_to_use, - const std::string& event_prefix) { - if (!LogMessage::Loggable(severity_to_use)) { - return; - } - - SharedScope scope(&lock_); - - { // Output first line. - LogMessage msg(file, line, severity_to_use); - msg.stream() << "=== Profile report "; - if (event_prefix.empty()) { - msg.stream() << "(prefix: '" << event_prefix << "') "; - } - msg.stream() << "==="; - } - for (EventMap::const_iterator it = events_.begin(); - it != events_.end(); ++it) { - if (event_prefix.empty() || it->first.find(event_prefix) == 0) { - LogMessage(file, line, severity_to_use).stream() - << it->first << " " << it->second; - } - } - LogMessage(file, line, severity_to_use).stream() - << "=== End profile report ==="; -} - -void Profiler::ReportAllToLog(const char* file, int line, - LoggingSeverity severity_to_use) { - ReportToLog(file, line, severity_to_use, ""); -} - -const ProfilerEvent* Profiler::GetEvent(const std::string& event_name) const { - SharedScope scope(&lock_); - EventMap::const_iterator it = - events_.find(event_name); - return (it == events_.end()) ? NULL : &it->second; -} - -bool Profiler::Clear() { - ExclusiveScope scope(&lock_); - bool result = true; - // Clear all events that aren't started. - EventMap::iterator it = events_.begin(); - while (it != events_.end()) { - if (it->second.is_started()) { - ++it; // Can't clear started events. - result = false; - } else { - events_.erase(it++); - } - } - return result; -} - -std::ostream& operator<<(std::ostream& stream, - const ProfilerEvent& profiler_event) { - stream << "count=" << profiler_event.event_count() - << " total=" << FormattedTime(profiler_event.total_time()) - << " mean=" << FormattedTime(profiler_event.mean()) - << " min=" << FormattedTime(profiler_event.minimum()) - << " max=" << FormattedTime(profiler_event.maximum()) - << " sd=" << profiler_event.standard_deviation(); - return stream; -} - -} // namespace rtc diff --git a/webrtc/base/profiler.h b/webrtc/base/profiler.h deleted file mode 100644 index 13b99f7c9..000000000 --- a/webrtc/base/profiler.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2013 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// A simple wall-clock profiler for instrumented code. -// Example: -// void MyLongFunction() { -// PROFILE_F(); // Time the execution of this function. -// // Do something -// { // Time just what is in this scope. -// PROFILE("My event"); -// // Do something else -// } -// } -// Another example: -// void StartAsyncProcess() { -// PROFILE_START("My async event"); -// DoSomethingAsyncAndThenCall(&Callback); -// } -// void Callback() { -// PROFILE_STOP("My async event"); -// // Handle callback. -// } - -#ifndef WEBRTC_BASE_PROFILER_H_ -#define WEBRTC_BASE_PROFILER_H_ - -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/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 - -#define UV_HELPER2(x) _uv_ ## x -#define UV_HELPER(x) UV_HELPER2(x) -#define UNIQUE_VAR UV_HELPER(__LINE__) - -// Profiles the current scope. -#define PROFILE(msg) rtc::ProfilerScope UNIQUE_VAR(msg) -// When placed at the start of a function, profiles the current function. -#define PROFILE_F() PROFILE(__FUNCTION__) -// Reports current timings to the log at severity |sev|. -#define PROFILE_DUMP_ALL(sev) \ - rtc::Profiler::Instance()->ReportAllToLog(__FILE__, __LINE__, sev) -// Reports current timings for all events whose names are prefixed by |prefix| -// to the log at severity |sev|. Using a unique event name as |prefix| will -// report only that event. -#define PROFILE_DUMP(sev, prefix) \ - rtc::Profiler::Instance()->ReportToLog(__FILE__, __LINE__, sev, prefix) -// Starts and stops a profile event. Useful when an event is not easily -// captured within a scope (eg, an async call with a callback when done). -#define PROFILE_START(msg) rtc::Profiler::Instance()->StartEvent(msg) -#define PROFILE_STOP(msg) rtc::Profiler::Instance()->StopEvent(msg) -// TODO(ryanpetrie): Consider adding PROFILE_DUMP_EVERY(sev, iterations) - -#undef UV_HELPER2 -#undef UV_HELPER -#undef UNIQUE_VAR - -#else // ENABLE_PROFILING - -#define PROFILE(msg) (void)0 -#define PROFILE_F() (void)0 -#define PROFILE_DUMP_ALL(sev) (void)0 -#define PROFILE_DUMP(sev, prefix) (void)0 -#define PROFILE_START(msg) (void)0 -#define PROFILE_STOP(msg) (void)0 - -#endif // ENABLE_PROFILING - -namespace rtc { - -// Tracks information for one profiler event. -class ProfilerEvent { - public: - ProfilerEvent(); - void Start(); - void Stop(); - void Stop(uint64 stop_time); - double standard_deviation() const; - double total_time() const { return total_time_; } - double mean() const { return mean_; } - double minimum() const { return minimum_; } - double maximum() const { return maximum_; } - int event_count() const { return event_count_; } - bool is_started() const { return start_count_ > 0; } - - private: - uint64 current_start_time_; - double total_time_; - double mean_; - double sum_of_squared_differences_; - double minimum_; - double maximum_; - int start_count_; - int event_count_; -}; - -// Singleton that owns ProfilerEvents and reports results. Prefer to use -// macros, defined above, rather than directly calling Profiler methods. -class Profiler { - public: - void StartEvent(const std::string& event_name); - void StopEvent(const std::string& event_name); - void ReportToLog(const char* file, int line, LoggingSeverity severity_to_use, - const std::string& event_prefix); - void ReportAllToLog(const char* file, int line, - LoggingSeverity severity_to_use); - const ProfilerEvent* GetEvent(const std::string& event_name) const; - // Clears all _stopped_ events. Returns true if _all_ events were cleared. - bool Clear(); - - static Profiler* Instance(); - private: - Profiler() {} - - typedef std::map EventMap; - EventMap events_; - mutable SharedExclusiveLock lock_; - - DISALLOW_COPY_AND_ASSIGN(Profiler); -}; - -// Starts an event on construction and stops it on destruction. -// Used by PROFILE macro. -class ProfilerScope { - public: - explicit ProfilerScope(const std::string& event_name) - : event_name_(event_name) { - Profiler::Instance()->StartEvent(event_name_); - } - ~ProfilerScope() { - Profiler::Instance()->StopEvent(event_name_); - } - private: - std::string event_name_; - - DISALLOW_COPY_AND_ASSIGN(ProfilerScope); -}; - -std::ostream& operator<<(std::ostream& stream, - const ProfilerEvent& profiler_event); - -} // namespace rtc - -#endif // WEBRTC_BASE_PROFILER_H_ diff --git a/webrtc/base/profiler_unittest.cc b/webrtc/base/profiler_unittest.cc deleted file mode 100644 index 5a607914a..000000000 --- a/webrtc/base/profiler_unittest.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/profiler.h" -#include "webrtc/base/thread.h" - -namespace { - -const int kWaitMs = 250; -const double kWaitSec = 0.250; -const double kTolerance = 0.1; - -const char* TestFunc() { - PROFILE_F(); - rtc::Thread::SleepMs(kWaitMs); - return __FUNCTION__; -} - -} // namespace - -namespace rtc { - -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); - // Run it a second time. - TestFunc(); - EXPECT_FALSE(event->is_started()); - EXPECT_EQ(2, event->event_count()); - EXPECT_NEAR(kWaitSec, event->mean(), kTolerance); - EXPECT_NEAR(kWaitSec * 2, event->total_time(), kTolerance * 2); - EXPECT_DOUBLE_EQ(event->mean(), event->total_time() / event->event_count()); -} - -TEST(ProfilerTest, TestScopedEvents) { - const std::string kEvent1Name = "Event 1"; - const std::string kEvent2Name = "Event 2"; - const int kEvent2WaitMs = 150; - const double kEvent2WaitSec = 0.150; - const ProfilerEvent* event1; - const ProfilerEvent* event2; - ASSERT_TRUE(Profiler::Instance()->Clear()); - { // Profile a scope. - PROFILE(kEvent1Name); - event1 = Profiler::Instance()->GetEvent(kEvent1Name); - ASSERT_TRUE(event1 != NULL); - EXPECT_TRUE(event1->is_started()); - EXPECT_EQ(0, event1->event_count()); - rtc::Thread::SleepMs(kWaitMs); - EXPECT_TRUE(event1->is_started()); - } - // Check the result. - EXPECT_FALSE(event1->is_started()); - EXPECT_EQ(1, event1->event_count()); - EXPECT_NEAR(kWaitSec, event1->mean(), kTolerance); - { // Profile a second event. - PROFILE(kEvent2Name); - event2 = Profiler::Instance()->GetEvent(kEvent2Name); - ASSERT_TRUE(event2 != NULL); - EXPECT_FALSE(event1->is_started()); - EXPECT_TRUE(event2->is_started()); - rtc::Thread::SleepMs(kEvent2WaitMs); - } - // Check the result. - EXPECT_FALSE(event2->is_started()); - EXPECT_EQ(1, event2->event_count()); - EXPECT_NEAR(kEvent2WaitSec, event2->mean(), kTolerance); - // Make sure event1 is unchanged. - EXPECT_FALSE(event1->is_started()); - EXPECT_EQ(1, event1->event_count()); - { // Run another event 1. - PROFILE(kEvent1Name); - EXPECT_TRUE(event1->is_started()); - rtc::Thread::SleepMs(kWaitMs); - } - // Check the result. - EXPECT_FALSE(event1->is_started()); - EXPECT_EQ(2, event1->event_count()); - EXPECT_NEAR(kWaitSec, event1->mean(), kTolerance); - EXPECT_NEAR(kWaitSec * 2, event1->total_time(), kTolerance * 2); - EXPECT_DOUBLE_EQ(event1->mean(), - event1->total_time() / event1->event_count()); -} - -TEST(ProfilerTest, Clear) { - ASSERT_TRUE(Profiler::Instance()->Clear()); - PROFILE_START("event"); - EXPECT_FALSE(Profiler::Instance()->Clear()); - EXPECT_TRUE(Profiler::Instance()->GetEvent("event") != NULL); - PROFILE_STOP("event"); - EXPECT_TRUE(Profiler::Instance()->Clear()); - EXPECT_EQ(NULL, Profiler::Instance()->GetEvent("event")); -} - -} // namespace rtc diff --git a/webrtc/base/proxy_unittest.cc b/webrtc/base/proxy_unittest.cc deleted file mode 100644 index d8a523fe1..000000000 --- a/webrtc/base/proxy_unittest.cc +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "webrtc/base/autodetectproxy.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/httpserver.h" -#include "webrtc/base/proxyserver.h" -#include "webrtc/base/socketadapters.h" -#include "webrtc/base/testclient.h" -#include "webrtc/base/testechoserver.h" -#include "webrtc/base/virtualsocketserver.h" - -using rtc::Socket; -using rtc::Thread; -using rtc::SocketAddress; - -static const SocketAddress kSocksProxyIntAddr("1.2.3.4", 1080); -static const SocketAddress kSocksProxyExtAddr("1.2.3.5", 0); -static const SocketAddress kHttpsProxyIntAddr("1.2.3.4", 443); -static const SocketAddress kHttpsProxyExtAddr("1.2.3.5", 0); -static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999); - -// Used to run a proxy detect on the current thread. Otherwise we would need -// to make both threads share the same VirtualSocketServer. -class AutoDetectProxyRunner : public rtc::AutoDetectProxy { - public: - explicit AutoDetectProxyRunner(const std::string& agent) - : AutoDetectProxy(agent) {} - void Run() { - DoWork(); - Thread::Current()->Restart(); // needed to reset the messagequeue - } -}; - -// Sets up a virtual socket server and HTTPS/SOCKS5 proxy servers. -class ProxyTest : public testing::Test { - public: - ProxyTest() : ss_(new rtc::VirtualSocketServer(NULL)) { - Thread::Current()->set_socketserver(ss_.get()); - socks_.reset(new rtc::SocksProxyServer( - ss_.get(), kSocksProxyIntAddr, ss_.get(), kSocksProxyExtAddr)); - https_.reset(new rtc::HttpListenServer()); - https_->Listen(kHttpsProxyIntAddr); - } - ~ProxyTest() { - Thread::Current()->set_socketserver(NULL); - } - - rtc::SocketServer* ss() { return ss_.get(); } - - rtc::ProxyType DetectProxyType(const SocketAddress& address) { - rtc::ProxyType type; - AutoDetectProxyRunner* detect = new AutoDetectProxyRunner("unittest/1.0"); - detect->set_proxy(address); - detect->Run(); // blocks until done - type = detect->proxy().type; - detect->Destroy(false); - return type; - } - - private: - rtc::scoped_ptr ss_; - rtc::scoped_ptr socks_; - // TODO: Make this a real HTTPS proxy server. - rtc::scoped_ptr https_; -}; - -// Tests whether we can use a SOCKS5 proxy to connect to a server. -TEST_F(ProxyTest, TestSocks5Connect) { - rtc::AsyncSocket* socket = - ss()->CreateAsyncSocket(kSocksProxyIntAddr.family(), SOCK_STREAM); - rtc::AsyncSocksProxySocket* proxy_socket = - new rtc::AsyncSocksProxySocket(socket, kSocksProxyIntAddr, - "", rtc::CryptString()); - // TODO: IPv6-ize these tests when proxy supports IPv6. - - rtc::TestEchoServer server(Thread::Current(), - SocketAddress(INADDR_ANY, 0)); - - rtc::AsyncTCPSocket* packet_socket = rtc::AsyncTCPSocket::Create( - proxy_socket, SocketAddress(INADDR_ANY, 0), server.address()); - EXPECT_TRUE(packet_socket != NULL); - rtc::TestClient client(packet_socket); - - EXPECT_EQ(Socket::CS_CONNECTING, proxy_socket->GetState()); - EXPECT_TRUE(client.CheckConnected()); - EXPECT_EQ(Socket::CS_CONNECTED, proxy_socket->GetState()); - EXPECT_EQ(server.address(), client.remote_address()); - client.Send("foo", 3); - EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL)); - EXPECT_TRUE(client.CheckNoPacket()); -} - -/* -// Tests whether we can use a HTTPS proxy to connect to a server. -TEST_F(ProxyTest, TestHttpsConnect) { - AsyncSocket* socket = ss()->CreateAsyncSocket(SOCK_STREAM); - AsyncHttpsProxySocket* proxy_socket = new AsyncHttpsProxySocket( - socket, "unittest/1.0", kHttpsProxyIntAddress, "", CryptString()); - TestClient client(new AsyncTCPSocket(proxy_socket)); - TestEchoServer server(Thread::Current(), SocketAddress()); - - EXPECT_TRUE(client.Connect(server.address())); - EXPECT_TRUE(client.CheckConnected()); - EXPECT_EQ(server.address(), client.remote_address()); - client.Send("foo", 3); - EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL)); - EXPECT_TRUE(client.CheckNoPacket()); -} -*/ - -// Tests whether we can autodetect a SOCKS5 proxy. -TEST_F(ProxyTest, TestAutoDetectSocks5) { - EXPECT_EQ(rtc::PROXY_SOCKS5, DetectProxyType(kSocksProxyIntAddr)); -} - -/* -// Tests whether we can autodetect a HTTPS proxy. -TEST_F(ProxyTest, TestAutoDetectHttps) { - EXPECT_EQ(rtc::PROXY_HTTPS, DetectProxyType(kHttpsProxyIntAddr)); -} -*/ - -// Tests whether we fail properly for no proxy. -TEST_F(ProxyTest, TestAutoDetectBogus) { - EXPECT_EQ(rtc::PROXY_UNKNOWN, DetectProxyType(kBogusProxyIntAddr)); -} diff --git a/webrtc/base/proxydetect.cc b/webrtc/base/proxydetect.cc deleted file mode 100644 index 716888637..000000000 --- a/webrtc/base/proxydetect.cc +++ /dev/null @@ -1,1246 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/proxydetect.h" - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#include -#endif // WEBRTC_WIN - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include -#include -#include -#include -#include "macconversion.h" -#endif - -#include - -#include "webrtc/base/fileutils.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/httpcommon-inl.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/stringutils.h" - -#if defined(WEBRTC_WIN) -#define _TRY_WINHTTP 1 -#define _TRY_JSPROXY 0 -#define _TRY_WM_FINDPROXY 0 -#define _TRY_IE_LAN_SETTINGS 1 -#endif // WEBRTC_WIN - -// For all platforms try Firefox. -#define _TRY_FIREFOX 1 - -// Use profiles.ini to find the correct profile for this user. -// If not set, we'll just look for the default one. -#define USE_FIREFOX_PROFILES_INI 1 - -static const size_t kMaxLineLength = 1024; -static const char kFirefoxPattern[] = "Firefox"; -static const char kInternetExplorerPattern[] = "MSIE"; - -struct StringMap { - public: - void Add(const char * name, const char * value) { map_[name] = value; } - const std::string& Get(const char * name, const char * def = "") const { - std::map::const_iterator it = - map_.find(name); - if (it != map_.end()) - return it->second; - def_ = def; - return def_; - } - bool IsSet(const char * name) const { - return (map_.find(name) != map_.end()); - } - private: - std::map map_; - mutable std::string def_; -}; - -enum UserAgent { - UA_FIREFOX, - UA_INTERNETEXPLORER, - UA_OTHER, - UA_UNKNOWN -}; - -#if _TRY_WINHTTP -//#include -// Note: From winhttp.h - -const char WINHTTP[] = "winhttp"; - -typedef LPVOID HINTERNET; - -typedef struct { - DWORD dwAccessType; // see WINHTTP_ACCESS_* types below - LPWSTR lpszProxy; // proxy server list - LPWSTR lpszProxyBypass; // proxy bypass list -} WINHTTP_PROXY_INFO, * LPWINHTTP_PROXY_INFO; - -typedef struct { - DWORD dwFlags; - DWORD dwAutoDetectFlags; - LPCWSTR lpszAutoConfigUrl; - LPVOID lpvReserved; - DWORD dwReserved; - BOOL fAutoLogonIfChallenged; -} WINHTTP_AUTOPROXY_OPTIONS; - -typedef struct { - BOOL fAutoDetect; - LPWSTR lpszAutoConfigUrl; - LPWSTR lpszProxy; - LPWSTR lpszProxyBypass; -} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG; - -extern "C" { - typedef HINTERNET (WINAPI * pfnWinHttpOpen) - ( - IN LPCWSTR pwszUserAgent, - IN DWORD dwAccessType, - IN LPCWSTR pwszProxyName OPTIONAL, - IN LPCWSTR pwszProxyBypass OPTIONAL, - IN DWORD dwFlags - ); - typedef BOOL (STDAPICALLTYPE * pfnWinHttpCloseHandle) - ( - IN HINTERNET hInternet - ); - typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetProxyForUrl) - ( - IN HINTERNET hSession, - IN LPCWSTR lpcwszUrl, - IN WINHTTP_AUTOPROXY_OPTIONS * pAutoProxyOptions, - OUT WINHTTP_PROXY_INFO * pProxyInfo - ); - typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetIEProxyConfig) - ( - IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig - ); - -} // extern "C" - -#define WINHTTP_AUTOPROXY_AUTO_DETECT 0x00000001 -#define WINHTTP_AUTOPROXY_CONFIG_URL 0x00000002 -#define WINHTTP_AUTOPROXY_RUN_INPROCESS 0x00010000 -#define WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY 0x00020000 -#define WINHTTP_AUTO_DETECT_TYPE_DHCP 0x00000001 -#define WINHTTP_AUTO_DETECT_TYPE_DNS_A 0x00000002 -#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 -#define WINHTTP_ACCESS_TYPE_NO_PROXY 1 -#define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 -#define WINHTTP_NO_PROXY_NAME NULL -#define WINHTTP_NO_PROXY_BYPASS NULL - -#endif // _TRY_WINHTTP - -#if _TRY_JSPROXY -extern "C" { - typedef BOOL (STDAPICALLTYPE * pfnInternetGetProxyInfo) - ( - LPCSTR lpszUrl, - DWORD dwUrlLength, - LPSTR lpszUrlHostName, - DWORD dwUrlHostNameLength, - LPSTR * lplpszProxyHostName, - LPDWORD lpdwProxyHostNameLength - ); -} // extern "C" -#endif // _TRY_JSPROXY - -#if _TRY_WM_FINDPROXY -#include -#include -#include -#endif // _TRY_WM_FINDPROXY - -#if _TRY_IE_LAN_SETTINGS -#include -#include -#endif // _TRY_IE_LAN_SETTINGS - -namespace rtc { - -////////////////////////////////////////////////////////////////////// -// Utility Functions -////////////////////////////////////////////////////////////////////// - -#if defined(WEBRTC_WIN) -#ifdef _UNICODE - -typedef std::wstring tstring; -std::string Utf8String(const tstring& str) { return ToUtf8(str); } - -#else // !_UNICODE - -typedef std::string tstring; -std::string Utf8String(const tstring& str) { return str; } - -#endif // !_UNICODE -#endif // WEBRTC_WIN - -bool ProxyItemMatch(const Url& url, char * item, size_t len) { - // hostname:443 - if (char * port = ::strchr(item, ':')) { - *port++ = '\0'; - if (url.port() != atol(port)) { - return false; - } - } - - // A.B.C.D or A.B.C.D/24 - int a, b, c, d, m; - int match = sscanf(item, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &m); - if (match >= 4) { - uint32 ip = ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | - (d & 0xFF); - if ((match < 5) || (m > 32)) - m = 32; - else if (m < 0) - m = 0; - uint32 mask = (m == 0) ? 0 : (~0UL) << (32 - m); - SocketAddress addr(url.host(), 0); - // TODO: Support IPv6 proxyitems. This code block is IPv4 only anyway. - return !addr.IsUnresolved() && - ((addr.ipaddr().v4AddressAsHostOrderInteger() & mask) == (ip & mask)); - } - - // .foo.com - if (*item == '.') { - size_t hostlen = url.host().length(); - return (hostlen > len) - && (stricmp(url.host().c_str() + (hostlen - len), item) == 0); - } - - // localhost or www.*.com - if (!string_match(url.host().c_str(), item)) - return false; - - return true; -} - -bool ProxyListMatch(const Url& url, const std::string& proxy_list, - char sep) { - const size_t BUFSIZE = 256; - char buffer[BUFSIZE]; - const char* list = proxy_list.c_str(); - while (*list) { - // Remove leading space - if (isspace(*list)) { - ++list; - continue; - } - // Break on separator - size_t len; - const char * start = list; - if (const char * end = ::strchr(list, sep)) { - len = (end - list); - list += len + 1; - } else { - len = strlen(list); - list += len; - } - // Remove trailing space - while ((len > 0) && isspace(start[len-1])) - --len; - // Check for oversized entry - if (len >= BUFSIZE) - continue; - memcpy(buffer, start, len); - buffer[len] = 0; - if (!ProxyItemMatch(url, buffer, len)) - continue; - return true; - } - return false; -} - -bool Better(ProxyType lhs, const ProxyType rhs) { - // PROXY_NONE, PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN - const int PROXY_VALUE[5] = { 0, 2, 3, 1 }; - return (PROXY_VALUE[lhs] > PROXY_VALUE[rhs]); -} - -bool ParseProxy(const std::string& saddress, ProxyInfo* proxy) { - const size_t kMaxAddressLength = 1024; - // Allow semicolon, space, or tab as an address separator - const char* const kAddressSeparator = " ;\t"; - - ProxyType ptype; - std::string host; - uint16 port; - - const char* address = saddress.c_str(); - while (*address) { - size_t len; - const char * start = address; - if (const char * sep = strchr(address, kAddressSeparator)) { - len = (sep - address); - address += len + 1; - while (*address != '\0' && ::strchr(kAddressSeparator, *address)) { - address += 1; - } - } else { - len = strlen(address); - address += len; - } - - if (len > kMaxAddressLength - 1) { - LOG(LS_WARNING) << "Proxy address too long [" << start << "]"; - continue; - } - - char buffer[kMaxAddressLength]; - memcpy(buffer, start, len); - buffer[len] = 0; - - char * colon = ::strchr(buffer, ':'); - if (!colon) { - LOG(LS_WARNING) << "Proxy address without port [" << buffer << "]"; - continue; - } - - *colon = 0; - char * endptr; - port = static_cast(strtol(colon + 1, &endptr, 0)); - if (*endptr != 0) { - LOG(LS_WARNING) << "Proxy address with invalid port [" << buffer << "]"; - continue; - } - - if (char * equals = ::strchr(buffer, '=')) { - *equals = 0; - host = equals + 1; - if (_stricmp(buffer, "socks") == 0) { - ptype = PROXY_SOCKS5; - } else if (_stricmp(buffer, "https") == 0) { - ptype = PROXY_HTTPS; - } else { - LOG(LS_WARNING) << "Proxy address with unknown protocol [" - << buffer << "]"; - ptype = PROXY_UNKNOWN; - } - } else { - host = buffer; - ptype = PROXY_UNKNOWN; - } - - if (Better(ptype, proxy->type)) { - proxy->type = ptype; - proxy->address.SetIP(host); - proxy->address.SetPort(port); - } - } - - return proxy->type != PROXY_NONE; -} - -UserAgent GetAgent(const char* agent) { - if (agent) { - std::string agent_str(agent); - if (agent_str.find(kFirefoxPattern) != std::string::npos) { - return UA_FIREFOX; - } else if (agent_str.find(kInternetExplorerPattern) != std::string::npos) { - return UA_INTERNETEXPLORER; - } else if (agent_str.empty()) { - return UA_UNKNOWN; - } - } - return UA_OTHER; -} - -bool EndsWith(const std::string& a, const std::string& b) { - if (b.size() > a.size()) { - return false; - } - int result = a.compare(a.size() - b.size(), b.size(), b); - return result == 0; -} - -bool GetFirefoxProfilePath(Pathname* path) { -#if defined(WEBRTC_WIN) - wchar_t w_path[MAX_PATH]; - if (SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, w_path) != - S_OK) { - LOG(LS_ERROR) << "SHGetFolderPath failed"; - return false; - } - path->SetFolder(ToUtf8(w_path, wcslen(w_path))); - path->AppendFolder("Mozilla"); - path->AppendFolder("Firefox"); -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - FSRef fr; - if (0 != FSFindFolder(kUserDomain, kApplicationSupportFolderType, - kCreateFolder, &fr)) { - LOG(LS_ERROR) << "FSFindFolder failed"; - return false; - } - char buffer[NAME_MAX + 1]; - if (0 != FSRefMakePath(&fr, reinterpret_cast(buffer), - ARRAY_SIZE(buffer))) { - LOG(LS_ERROR) << "FSRefMakePath failed"; - return false; - } - path->SetFolder(std::string(buffer)); - path->AppendFolder("Firefox"); -#else - char* user_home = getenv("HOME"); - if (user_home == NULL) { - return false; - } - path->SetFolder(std::string(user_home)); - path->AppendFolder(".mozilla"); - path->AppendFolder("firefox"); -#endif // WEBRTC_WIN - return true; -} - -bool GetDefaultFirefoxProfile(Pathname* profile_path) { - ASSERT(NULL != profile_path); - Pathname path; - if (!GetFirefoxProfilePath(&path)) { - return false; - } - -#if USE_FIREFOX_PROFILES_INI - // [Profile0] - // Name=default - // IsRelative=1 - // Path=Profiles/2de53ejb.default - // Default=1 - - // Note: we are looking for the first entry with "Default=1", or the last - // entry in the file - path.SetFilename("profiles.ini"); - scoped_ptr fs(Filesystem::OpenFile(path, "r")); - if (!fs) { - return false; - } - Pathname candidate; - bool relative = true; - std::string line; - while (fs->ReadLine(&line) == SR_SUCCESS) { - if (line.length() == 0) { - continue; - } - if (line.at(0) == '[') { - relative = true; - candidate.clear(); - } else if (line.find("IsRelative=") == 0 && - line.length() >= 12) { - // TODO: The initial Linux public launch revealed a fairly - // high number of machines where IsRelative= did not have anything after - // it. Perhaps that is legal profiles.ini syntax? - relative = (line.at(11) != '0'); - } else if (line.find("Path=") == 0 && - line.length() >= 6) { - if (relative) { - candidate = path; - } else { - candidate.clear(); - } - candidate.AppendFolder(line.substr(5)); - } else if (line.find("Default=") == 0 && - line.length() >= 9) { - if ((line.at(8) != '0') && !candidate.empty()) { - break; - } - } - } - fs->Close(); - if (candidate.empty()) { - return false; - } - profile_path->SetPathname(candidate.pathname()); - -#else // !USE_FIREFOX_PROFILES_INI - path.AppendFolder("Profiles"); - DirectoryIterator* it = Filesystem::IterateDirectory(); - it->Iterate(path); - std::string extension(".default"); - while (!EndsWith(it->Name(), extension)) { - if (!it->Next()) { - return false; - } - } - - profile_path->SetPathname(path); - profile->AppendFolder("Profiles"); - profile->AppendFolder(it->Name()); - delete it; - -#endif // !USE_FIREFOX_PROFILES_INI - - return true; -} - -bool ReadFirefoxPrefs(const Pathname& filename, - const char * prefix, - StringMap* settings) { - scoped_ptr fs(Filesystem::OpenFile(filename, "r")); - if (!fs) { - LOG(LS_ERROR) << "Failed to open file: " << filename.pathname(); - return false; - } - - std::string line; - while (fs->ReadLine(&line) == SR_SUCCESS) { - size_t prefix_len = strlen(prefix); - - // Skip blank lines and too long lines. - if ((line.length() == 0) || (line.length() > kMaxLineLength) - || (line.at(0) == '#') || line.compare(0, 2, "/*") == 0 - || line.compare(0, 2, " *") == 0) { - continue; - } - - char buffer[kMaxLineLength]; - strcpyn(buffer, sizeof(buffer), line.c_str()); - int nstart = 0, nend = 0, vstart = 0, vend = 0; - sscanf(buffer, "user_pref(\"%n%*[^\"]%n\", %n%*[^)]%n);", - &nstart, &nend, &vstart, &vend); - if (vend > 0) { - char* name = buffer + nstart; - name[nend - nstart] = 0; - if ((vend - vstart >= 2) && (buffer[vstart] == '"')) { - vstart += 1; - vend -= 1; - } - char* value = buffer + vstart; - value[vend - vstart] = 0; - if ((strncmp(name, prefix, prefix_len) == 0) && *value) { - settings->Add(name + prefix_len, value); - } - } else { - LOG_F(LS_WARNING) << "Unparsed pref [" << buffer << "]"; - } - } - fs->Close(); - return true; -} - -bool GetFirefoxProxySettings(const char* url, ProxyInfo* proxy) { - Url purl(url); - Pathname path; - bool success = false; - if (GetDefaultFirefoxProfile(&path)) { - StringMap settings; - path.SetFilename("prefs.js"); - if (ReadFirefoxPrefs(path, "network.proxy.", &settings)) { - success = true; - proxy->bypass_list = - settings.Get("no_proxies_on", "localhost, 127.0.0.1"); - if (settings.Get("type") == "1") { - // User has manually specified a proxy, try to figure out what - // type it is. - if (ProxyListMatch(purl, proxy->bypass_list.c_str(), ',')) { - // Our url is in the list of url's to bypass proxy. - } else if (settings.Get("share_proxy_settings") == "true") { - proxy->type = PROXY_UNKNOWN; - proxy->address.SetIP(settings.Get("http")); - proxy->address.SetPort(atoi(settings.Get("http_port").c_str())); - } else if (settings.IsSet("socks")) { - proxy->type = PROXY_SOCKS5; - proxy->address.SetIP(settings.Get("socks")); - proxy->address.SetPort(atoi(settings.Get("socks_port").c_str())); - } else if (settings.IsSet("ssl")) { - proxy->type = PROXY_HTTPS; - proxy->address.SetIP(settings.Get("ssl")); - proxy->address.SetPort(atoi(settings.Get("ssl_port").c_str())); - } else if (settings.IsSet("http")) { - proxy->type = PROXY_HTTPS; - proxy->address.SetIP(settings.Get("http")); - proxy->address.SetPort(atoi(settings.Get("http_port").c_str())); - } - } else if (settings.Get("type") == "2") { - // Browser is configured to get proxy settings from a given url. - proxy->autoconfig_url = settings.Get("autoconfig_url").c_str(); - } else if (settings.Get("type") == "4") { - // Browser is configured to auto detect proxy config. - proxy->autodetect = true; - } else { - // No proxy set. - } - } - } - return success; -} - -#if defined(WEBRTC_WIN) // Windows specific implementation for reading Internet - // Explorer proxy settings. - -void LogGetProxyFault() { - LOG_GLEM(LERROR, WINHTTP) << "WinHttpGetProxyForUrl faulted!!"; -} - -BOOL MyWinHttpGetProxyForUrl(pfnWinHttpGetProxyForUrl pWHGPFU, - HINTERNET hWinHttp, LPCWSTR url, - WINHTTP_AUTOPROXY_OPTIONS *options, - WINHTTP_PROXY_INFO *info) { - // WinHttpGetProxyForUrl() can call plugins which can crash. - // In the case of McAfee scriptproxy.dll, it does crash in - // older versions. Try to catch crashes here and treat as an - // error. - BOOL success = FALSE; - -#if (_HAS_EXCEPTIONS == 0) - __try { - success = pWHGPFU(hWinHttp, url, options, info); - } __except(EXCEPTION_EXECUTE_HANDLER) { - // This is a separate function to avoid - // Visual C++ error 2712 when compiling with C++ EH - LogGetProxyFault(); - } -#else - success = pWHGPFU(hWinHttp, url, options, info); -#endif // (_HAS_EXCEPTIONS == 0) - - return success; -} - -bool IsDefaultBrowserFirefox() { - HKEY key; - LONG result = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"http\\shell\\open\\command", - 0, KEY_READ, &key); - if (ERROR_SUCCESS != result) - return false; - - wchar_t* value = NULL; - DWORD size, type; - 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]; - BYTE* buffer = reinterpret_cast(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]); - } - success = (NULL != strstr(value, L"firefox.exe")); - } - delete [] value; - return success; -} - -bool GetWinHttpProxySettings(const char* url, ProxyInfo* proxy) { - HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll"); - if (winhttp_handle == NULL) { - LOG(LS_ERROR) << "Failed to load winhttp.dll."; - return false; - } - WINHTTP_CURRENT_USER_IE_PROXY_CONFIG iecfg; - memset(&iecfg, 0, sizeof(iecfg)); - Url purl(url); - pfnWinHttpGetIEProxyConfig pWHGIEPC = - reinterpret_cast( - GetProcAddress(winhttp_handle, - "WinHttpGetIEProxyConfigForCurrentUser")); - bool success = false; - if (pWHGIEPC && pWHGIEPC(&iecfg)) { - // We were read proxy config successfully. - success = true; - if (iecfg.fAutoDetect) { - proxy->autodetect = true; - } - if (iecfg.lpszAutoConfigUrl) { - proxy->autoconfig_url = ToUtf8(iecfg.lpszAutoConfigUrl); - GlobalFree(iecfg.lpszAutoConfigUrl); - } - if (iecfg.lpszProxyBypass) { - proxy->bypass_list = ToUtf8(iecfg.lpszProxyBypass); - GlobalFree(iecfg.lpszProxyBypass); - } - if (iecfg.lpszProxy) { - if (!ProxyListMatch(purl, proxy->bypass_list, ';')) { - ParseProxy(ToUtf8(iecfg.lpszProxy), proxy); - } - GlobalFree(iecfg.lpszProxy); - } - } - FreeLibrary(winhttp_handle); - return success; -} - -// Uses the WinHTTP API to auto detect proxy for the given url. Firefox and IE -// have slightly different option dialogs for proxy settings. In Firefox, -// either a location of a proxy configuration file can be specified or auto -// detection can be selected. In IE theese two options can be independently -// selected. For the case where both options are selected (only IE) we try to -// fetch the config file first, and if that fails we'll perform an auto -// detection. -// -// Returns true if we successfully performed an auto detection not depending on -// whether we found a proxy or not. Returns false on error. -bool WinHttpAutoDetectProxyForUrl(const char* agent, const char* url, - ProxyInfo* proxy) { - Url purl(url); - bool success = true; - HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll"); - if (winhttp_handle == NULL) { - LOG(LS_ERROR) << "Failed to load winhttp.dll."; - return false; - } - pfnWinHttpOpen pWHO = - reinterpret_cast(GetProcAddress(winhttp_handle, - "WinHttpOpen")); - pfnWinHttpCloseHandle pWHCH = - reinterpret_cast( - GetProcAddress(winhttp_handle, "WinHttpCloseHandle")); - pfnWinHttpGetProxyForUrl pWHGPFU = - reinterpret_cast( - GetProcAddress(winhttp_handle, "WinHttpGetProxyForUrl")); - if (pWHO && pWHCH && pWHGPFU) { - if (HINTERNET hWinHttp = pWHO(ToUtf16(agent).c_str(), - WINHTTP_ACCESS_TYPE_NO_PROXY, - WINHTTP_NO_PROXY_NAME, - WINHTTP_NO_PROXY_BYPASS, - 0)) { - BOOL result = FALSE; - WINHTTP_PROXY_INFO info; - memset(&info, 0, sizeof(info)); - if (proxy->autodetect) { - // Use DHCP and DNS to try to find any proxy to use. - WINHTTP_AUTOPROXY_OPTIONS options; - memset(&options, 0, sizeof(options)); - options.fAutoLogonIfChallenged = TRUE; - - options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT; - options.dwAutoDetectFlags |= WINHTTP_AUTO_DETECT_TYPE_DHCP - | WINHTTP_AUTO_DETECT_TYPE_DNS_A; - result = MyWinHttpGetProxyForUrl( - pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info); - } - if (!result && !proxy->autoconfig_url.empty()) { - // We have the location of a proxy config file. Download it and - // execute it to find proxy settings for our url. - WINHTTP_AUTOPROXY_OPTIONS options; - memset(&options, 0, sizeof(options)); - memset(&info, 0, sizeof(info)); - options.fAutoLogonIfChallenged = TRUE; - - std::wstring autoconfig_url16((ToUtf16)(proxy->autoconfig_url)); - options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL; - options.lpszAutoConfigUrl = autoconfig_url16.c_str(); - - result = MyWinHttpGetProxyForUrl( - pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info); - } - if (result) { - // Either the given auto config url was valid or auto - // detection found a proxy on this network. - if (info.lpszProxy) { - // TODO: Does this bypass list differ from the list - // retreived from GetWinHttpProxySettings earlier? - if (info.lpszProxyBypass) { - proxy->bypass_list = ToUtf8(info.lpszProxyBypass); - GlobalFree(info.lpszProxyBypass); - } else { - proxy->bypass_list.clear(); - } - if (!ProxyListMatch(purl, proxy->bypass_list, ';')) { - // Found proxy for this URL. If parsing the address turns - // out ok then we are successful. - success = ParseProxy(ToUtf8(info.lpszProxy), proxy); - } - GlobalFree(info.lpszProxy); - } - } else { - // We could not find any proxy for this url. - LOG(LS_INFO) << "No proxy detected for " << url; - } - pWHCH(hWinHttp); - } - } else { - LOG(LS_ERROR) << "Failed loading WinHTTP functions."; - success = false; - } - FreeLibrary(winhttp_handle); - return success; -} - -#if 0 // Below functions currently not used. - -bool GetJsProxySettings(const char* url, ProxyInfo* proxy) { - Url purl(url); - bool success = false; - - if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) { - pfnInternetGetProxyInfo pIGPI = - reinterpret_cast( - GetProcAddress(hModJS, "InternetGetProxyInfo")); - if (pIGPI) { - char proxy[256], host[256]; - memset(proxy, 0, sizeof(proxy)); - char * ptr = proxy; - DWORD proxylen = sizeof(proxy); - std::string surl = Utf8String(url); - DWORD hostlen = _snprintf(host, sizeof(host), "http%s://%S", - purl.secure() ? "s" : "", purl.server()); - if (pIGPI(surl.data(), surl.size(), host, hostlen, &ptr, &proxylen)) { - LOG(INFO) << "Proxy: " << proxy; - } else { - LOG_GLE(INFO) << "InternetGetProxyInfo"; - } - } - FreeLibrary(hModJS); - } - return success; -} - -bool GetWmProxySettings(const char* url, ProxyInfo* proxy) { - Url purl(url); - bool success = false; - - INSNetSourceCreator * nsc = 0; - HRESULT hr = CoCreateInstance(CLSID_ClientNetManager, 0, CLSCTX_ALL, - IID_INSNetSourceCreator, (LPVOID *) &nsc); - if (SUCCEEDED(hr)) { - if (SUCCEEDED(hr = nsc->Initialize())) { - VARIANT dispatch; - VariantInit(&dispatch); - if (SUCCEEDED(hr = nsc->GetNetSourceAdminInterface(L"http", &dispatch))) { - IWMSInternalAdminNetSource * ians = 0; - if (SUCCEEDED(hr = dispatch.pdispVal->QueryInterface( - IID_IWMSInternalAdminNetSource, (LPVOID *) &ians))) { - _bstr_t host(purl.server()); - BSTR proxy = 0; - BOOL bProxyEnabled = FALSE; - DWORD port, context = 0; - if (SUCCEEDED(hr = ians->FindProxyForURL( - L"http", host, &bProxyEnabled, &proxy, &port, &context))) { - success = true; - if (bProxyEnabled) { - _bstr_t sproxy = proxy; - proxy->ptype = PT_HTTPS; - proxy->host = sproxy; - proxy->port = port; - } - } - SysFreeString(proxy); - if (FAILED(hr = ians->ShutdownProxyContext(context))) { - LOG(LS_INFO) << "IWMSInternalAdminNetSource::ShutdownProxyContext" - << "failed: " << hr; - } - ians->Release(); - } - } - VariantClear(&dispatch); - if (FAILED(hr = nsc->Shutdown())) { - LOG(LS_INFO) << "INSNetSourceCreator::Shutdown failed: " << hr; - } - } - nsc->Release(); - } - return success; -} - -bool GetIePerConnectionProxySettings(const char* url, ProxyInfo* proxy) { - Url purl(url); - bool success = false; - - INTERNET_PER_CONN_OPTION_LIST list; - INTERNET_PER_CONN_OPTION options[3]; - memset(&list, 0, sizeof(list)); - memset(&options, 0, sizeof(options)); - - list.dwSize = sizeof(list); - list.dwOptionCount = 3; - list.pOptions = options; - options[0].dwOption = INTERNET_PER_CONN_FLAGS; - options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER; - options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS; - DWORD dwSize = sizeof(list); - - if (!InternetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, - &dwSize)) { - LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError(); - } else if ((options[0].Value.dwValue & PROXY_TYPE_PROXY) != 0) { - success = true; - if (!ProxyListMatch(purl, nonnull(options[2].Value.pszValue), _T(';'))) { - ParseProxy(nonnull(options[1].Value.pszValue), proxy); - } - } else if ((options[0].Value.dwValue & PROXY_TYPE_DIRECT) != 0) { - success = true; - } else { - LOG(LS_INFO) << "unknown internet access type: " - << options[0].Value.dwValue; - } - if (options[1].Value.pszValue) { - GlobalFree(options[1].Value.pszValue); - } - if (options[2].Value.pszValue) { - GlobalFree(options[2].Value.pszValue); - } - return success; -} - -#endif // 0 - -// Uses the InternetQueryOption function to retrieve proxy settings -// from the registry. This will only give us the 'static' settings, -// ie, not any information about auto config etc. -bool GetIeLanProxySettings(const char* url, ProxyInfo* proxy) { - Url purl(url); - bool success = false; - - wchar_t buffer[1024]; - memset(buffer, 0, sizeof(buffer)); - INTERNET_PROXY_INFO * info = reinterpret_cast(buffer); - DWORD dwSize = sizeof(buffer); - - if (!InternetQueryOption(0, INTERNET_OPTION_PROXY, info, &dwSize)) { - LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError(); - } else if (info->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) { - success = true; - } else if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { - success = true; - if (!ProxyListMatch(purl, nonnull(reinterpret_cast( - info->lpszProxyBypass)), ' ')) { - ParseProxy(nonnull(reinterpret_cast(info->lpszProxy)), - proxy); - } - } else { - LOG(LS_INFO) << "unknown internet access type: " << info->dwAccessType; - } - return success; -} - -bool GetIeProxySettings(const char* agent, const char* url, ProxyInfo* proxy) { - bool success = GetWinHttpProxySettings(url, proxy); - if (!success) { - // TODO: Should always call this if no proxy were detected by - // GetWinHttpProxySettings? - // WinHttp failed. Try using the InternetOptionQuery method instead. - return GetIeLanProxySettings(url, proxy); - } - return true; -} - -#endif // WEBRTC_WIN - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) // WEBRTC_MAC && !defined(WEBRTC_IOS) specific implementation for reading system wide - // proxy settings. - -bool p_getProxyInfoForTypeFromDictWithKeys(ProxyInfo* proxy, - ProxyType type, - const CFDictionaryRef proxyDict, - const CFStringRef enabledKey, - const CFStringRef hostKey, - const CFStringRef portKey) { - // whether or not we set up the proxy info. - bool result = false; - - // we use this as a scratch variable for determining if operations - // succeeded. - bool converted = false; - - // the data we need to construct the SocketAddress for the proxy. - std::string hostname; - int port; - - if ((proxyDict != NULL) && - (CFGetTypeID(proxyDict) == CFDictionaryGetTypeID())) { - // CoreFoundation stuff that we'll have to get from - // the dictionaries and interpret or convert into more usable formats. - CFNumberRef enabledCFNum; - CFNumberRef portCFNum; - CFStringRef hostCFStr; - - enabledCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, enabledKey); - - if (p_isCFNumberTrue(enabledCFNum)) { - // let's see if we can get the address and port. - hostCFStr = (CFStringRef)CFDictionaryGetValue(proxyDict, hostKey); - converted = p_convertHostCFStringRefToCPPString(hostCFStr, hostname); - if (converted) { - portCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, portKey); - converted = p_convertCFNumberToInt(portCFNum, &port); - if (converted) { - // we have something enabled, with a hostname and a port. - // That's sufficient to set up the proxy info. - proxy->type = type; - proxy->address.SetIP(hostname); - proxy->address.SetPort(port); - result = true; - } - } - } - } - - return result; -} - -// Looks for proxy information in the given dictionary, -// return true if it found sufficient information to define one, -// false otherwise. This is guaranteed to not change the values in proxy -// unless a full-fledged proxy description was discovered in the dictionary. -// However, at the present time this does not support username or password. -// Checks first for a SOCKS proxy, then for HTTPS, then HTTP. -bool GetMacProxySettingsFromDictionary(ProxyInfo* proxy, - const CFDictionaryRef proxyDict) { - // the function result. - bool gotProxy = false; - - - // first we see if there's a SOCKS proxy in place. - gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy, - PROXY_SOCKS5, - proxyDict, - kSCPropNetProxiesSOCKSEnable, - kSCPropNetProxiesSOCKSProxy, - kSCPropNetProxiesSOCKSPort); - - if (!gotProxy) { - // okay, no SOCKS proxy, let's look for https. - gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy, - PROXY_HTTPS, - proxyDict, - kSCPropNetProxiesHTTPSEnable, - kSCPropNetProxiesHTTPSProxy, - kSCPropNetProxiesHTTPSPort); - if (!gotProxy) { - // Finally, try HTTP proxy. Note that flute doesn't - // differentiate between HTTPS and HTTP, hence we are using the - // same flute type here, ie. PROXY_HTTPS. - gotProxy = p_getProxyInfoForTypeFromDictWithKeys( - proxy, PROXY_HTTPS, proxyDict, kSCPropNetProxiesHTTPEnable, - kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); - } - } - return gotProxy; -} - -// TODO(hughv) Update keychain functions. They work on 10.8, but are depricated. -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -bool p_putPasswordInProxyInfo(ProxyInfo* proxy) { - bool result = true; // by default we assume we're good. - // for all we know there isn't any password. We'll set to false - // if we find a problem. - - // Ask the keychain for an internet password search for the given protocol. - OSStatus oss = 0; - SecKeychainAttributeList attrList; - attrList.count = 3; - SecKeychainAttribute attributes[3]; - attrList.attr = attributes; - - attributes[0].tag = kSecProtocolItemAttr; - attributes[0].length = sizeof(SecProtocolType); - SecProtocolType protocol; - switch (proxy->type) { - case PROXY_HTTPS : - protocol = kSecProtocolTypeHTTPS; - break; - case PROXY_SOCKS5 : - protocol = kSecProtocolTypeSOCKS; - break; - default : - LOG(LS_ERROR) << "asked for proxy password for unknown proxy type."; - result = false; - break; - } - attributes[0].data = &protocol; - - UInt32 port = proxy->address.port(); - attributes[1].tag = kSecPortItemAttr; - attributes[1].length = sizeof(UInt32); - attributes[1].data = &port; - - std::string ip = proxy->address.ipaddr().ToString(); - attributes[2].tag = kSecServerItemAttr; - attributes[2].length = ip.length(); - attributes[2].data = const_cast(ip.c_str()); - - if (result) { - LOG(LS_INFO) << "trying to get proxy username/password"; - SecKeychainSearchRef sref; - oss = SecKeychainSearchCreateFromAttributes(NULL, - kSecInternetPasswordItemClass, - &attrList, &sref); - if (0 == oss) { - LOG(LS_INFO) << "SecKeychainSearchCreateFromAttributes was good"; - // Get the first item, if there is one. - SecKeychainItemRef iref; - oss = SecKeychainSearchCopyNext(sref, &iref); - if (0 == oss) { - LOG(LS_INFO) << "...looks like we have the username/password data"; - // If there is, get the username and the password. - - SecKeychainAttributeInfo attribsToGet; - attribsToGet.count = 1; - UInt32 tag = kSecAccountItemAttr; - UInt32 format = CSSM_DB_ATTRIBUTE_FORMAT_STRING; - void *data; - UInt32 length; - SecKeychainAttributeList *localList; - - attribsToGet.tag = &tag; - attribsToGet.format = &format; - OSStatus copyres = SecKeychainItemCopyAttributesAndData(iref, - &attribsToGet, - NULL, - &localList, - &length, - &data); - if (0 == copyres) { - LOG(LS_INFO) << "...and we can pull it out."; - // now, we know from experimentation (sadly not from docs) - // that the username is in the local attribute list, - // and the password in the data, - // both without null termination but with info on their length. - // grab the password from the data. - std::string password; - password.append(static_cast(data), length); - - // make the password into a CryptString - // huh, at the time of writing, you can't. - // so we'll skip that for now and come back to it later. - - // now put the username in the proxy. - if (1 <= localList->attr->length) { - proxy->username.append( - static_cast(localList->attr->data), - localList->attr->length); - LOG(LS_INFO) << "username is " << proxy->username; - } else { - LOG(LS_ERROR) << "got keychain entry with no username"; - result = false; - } - } else { - LOG(LS_ERROR) << "couldn't copy info from keychain."; - result = false; - } - SecKeychainItemFreeAttributesAndData(localList, data); - } else if (errSecItemNotFound == oss) { - LOG(LS_INFO) << "...username/password info not found"; - } else { - // oooh, neither 0 nor itemNotFound. - LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss; - result = false; - } - } else if (errSecItemNotFound == oss) { // noop - } else { - // oooh, neither 0 nor itemNotFound. - LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss; - result = false; - } - } - - return result; -} - -bool GetMacProxySettings(ProxyInfo* proxy) { - // based on the Apple Technical Q&A QA1234 - // http://developer.apple.com/qa/qa2001/qa1234.html - CFDictionaryRef proxyDict = SCDynamicStoreCopyProxies(NULL); - bool result = false; - - if (proxyDict != NULL) { - // sending it off to another function makes it easier to unit test - // since we can make our own dictionary to hand to that function. - result = GetMacProxySettingsFromDictionary(proxy, proxyDict); - - if (result) { - result = p_putPasswordInProxyInfo(proxy); - } - - // We created the dictionary with something that had the - // word 'copy' in it, so we have to release it, according - // to the Carbon memory management standards. - CFRelease(proxyDict); - } else { - LOG(LS_ERROR) << "SCDynamicStoreCopyProxies failed"; - } - - return result; -} -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) - -bool AutoDetectProxySettings(const char* agent, const char* url, - ProxyInfo* proxy) { -#if defined(WEBRTC_WIN) - return WinHttpAutoDetectProxyForUrl(agent, url, proxy); -#else - LOG(LS_WARNING) << "Proxy auto-detection not implemented for this platform"; - return false; -#endif -} - -bool GetSystemDefaultProxySettings(const char* agent, const char* url, - ProxyInfo* proxy) { -#if defined(WEBRTC_WIN) - return GetIeProxySettings(agent, url, proxy); -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - return GetMacProxySettings(proxy); -#else - // TODO: Get System settings if browser is not firefox. - return GetFirefoxProxySettings(url, proxy); -#endif -} - -bool GetProxySettingsForUrl(const char* agent, const char* url, - ProxyInfo* proxy, bool long_operation) { - UserAgent a = GetAgent(agent); - bool result; - switch (a) { - case UA_FIREFOX: { - result = GetFirefoxProxySettings(url, proxy); - break; - } -#if defined(WEBRTC_WIN) - case UA_INTERNETEXPLORER: - result = GetIeProxySettings(agent, url, proxy); - break; - case UA_UNKNOWN: - // Agent not defined, check default browser. - if (IsDefaultBrowserFirefox()) { - result = GetFirefoxProxySettings(url, proxy); - } else { - result = GetIeProxySettings(agent, url, proxy); - } - break; -#endif // WEBRTC_WIN - default: - result = GetSystemDefaultProxySettings(agent, url, proxy); - break; - } - - // TODO: Consider using the 'long_operation' parameter to - // decide whether to do the auto detection. - if (result && (proxy->autodetect || - !proxy->autoconfig_url.empty())) { - // Use WinHTTP to auto detect proxy for us. - result = AutoDetectProxySettings(agent, url, proxy); - if (!result) { - // Either auto detection is not supported or we simply didn't - // find any proxy, reset type. - proxy->type = rtc::PROXY_NONE; - } - } - return result; -} - -} // namespace rtc diff --git a/webrtc/base/proxydetect.h b/webrtc/base/proxydetect.h deleted file mode 100644 index f9bf5f873..000000000 --- a/webrtc/base/proxydetect.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef _PROXYDETECT_H_ -#define _PROXYDETECT_H_ - -#include "webrtc/base/proxyinfo.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -namespace rtc { -// Auto-detect the proxy server. Returns true if a proxy is configured, -// although hostname may be empty if the proxy is not required for -// the given URL. - -bool GetProxySettingsForUrl(const char* agent, const char* url, - rtc::ProxyInfo* proxy, - bool long_operation = false); - -} // namespace rtc - -#endif // _PROXYDETECT_H_ diff --git a/webrtc/base/proxydetect_unittest.cc b/webrtc/base/proxydetect_unittest.cc deleted file mode 100644 index ca0b428fc..000000000 --- a/webrtc/base/proxydetect_unittest.cc +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/fileutils_mock.h" -#include "webrtc/base/proxydetect.h" - -namespace rtc { - -static const std::string kFirefoxProfilesIni = - "[Profile0]\n" - "Name=default\n" - "IsRelative=1\n" - "Path=Profiles/2de53ejb.default\n" - "Default=1\n"; - -static const std::string kFirefoxHeader = - "# Mozilla User Preferences\n" - "\n" - "/* Some Comments\n" - "*\n" - "*/\n" - "\n"; - -static const std::string kFirefoxCorruptHeader = - "iuahueqe32164"; - -static const std::string kProxyAddress = "proxy.net.com"; - -// Mocking out platform specific path to firefox prefs file. -class FirefoxPrefsFileSystem : public FakeFileSystem { - public: - explicit FirefoxPrefsFileSystem(const std::vector& all_files) : - FakeFileSystem(all_files) { - } - virtual FileStream* OpenFile(const Pathname& filename, - const std::string& mode) { - // TODO: We could have a platform dependent check of paths here. - std::string name = filename.basename(); - name.append(filename.extension()); - EXPECT_TRUE(name.compare("prefs.js") == 0 || - name.compare("profiles.ini") == 0); - FileStream* stream = FakeFileSystem::OpenFile(name, mode); - return stream; - } -}; - -class ProxyDetectTest : public testing::Test { -}; - -bool GetProxyInfo(const std::string prefs, ProxyInfo* info) { - std::vector files; - files.push_back(rtc::FakeFileSystem::File("profiles.ini", - kFirefoxProfilesIni)); - files.push_back(rtc::FakeFileSystem::File("prefs.js", prefs)); - rtc::FilesystemScope fs(new rtc::FirefoxPrefsFileSystem(files)); - return GetProxySettingsForUrl("Firefox", "www.google.com", info, false); -} - -// Verifies that an empty Firefox prefs file results in no proxy detected. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxEmptyPrefs) { - ProxyInfo proxy_info; - EXPECT_TRUE(GetProxyInfo(kFirefoxHeader, &proxy_info)); - EXPECT_EQ(PROXY_NONE, proxy_info.type); -} - -// Verifies that corrupted prefs file results in no proxy detected. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxCorruptedPrefs) { - ProxyInfo proxy_info; - EXPECT_TRUE(GetProxyInfo(kFirefoxCorruptHeader, &proxy_info)); - EXPECT_EQ(PROXY_NONE, proxy_info.type); -} - -// Verifies that SOCKS5 proxy is detected if configured. SOCKS uses a -// handshake protocol to inform the proxy software about the -// connection that the client is trying to make and may be used for -// any form of TCP or UDP socket connection. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxySocks) { - ProxyInfo proxy_info; - SocketAddress proxy_address("proxy.socks.com", 6666); - std::string prefs(kFirefoxHeader); - prefs.append("user_pref(\"network.proxy.socks\", \"proxy.socks.com\");\n"); - prefs.append("user_pref(\"network.proxy.socks_port\", 6666);\n"); - prefs.append("user_pref(\"network.proxy.type\", 1);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_EQ(PROXY_SOCKS5, proxy_info.type); - EXPECT_EQ(proxy_address, proxy_info.address); -} - -// Verified that SSL proxy is detected if configured. SSL proxy is an -// extention of a HTTP proxy to support secure connections. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxySsl) { - ProxyInfo proxy_info; - SocketAddress proxy_address("proxy.ssl.com", 7777); - std::string prefs(kFirefoxHeader); - - prefs.append("user_pref(\"network.proxy.ssl\", \"proxy.ssl.com\");\n"); - prefs.append("user_pref(\"network.proxy.ssl_port\", 7777);\n"); - prefs.append("user_pref(\"network.proxy.type\", 1);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_EQ(PROXY_HTTPS, proxy_info.type); - EXPECT_EQ(proxy_address, proxy_info.address); -} - -// Verifies that a HTTP proxy is detected if configured. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyHttp) { - ProxyInfo proxy_info; - SocketAddress proxy_address("proxy.http.com", 8888); - std::string prefs(kFirefoxHeader); - - prefs.append("user_pref(\"network.proxy.http\", \"proxy.http.com\");\n"); - prefs.append("user_pref(\"network.proxy.http_port\", 8888);\n"); - prefs.append("user_pref(\"network.proxy.type\", 1);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_EQ(PROXY_HTTPS, proxy_info.type); - EXPECT_EQ(proxy_address, proxy_info.address); -} - -// Verifies detection of automatic proxy detection. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyAuto) { - ProxyInfo proxy_info; - std::string prefs(kFirefoxHeader); - - prefs.append("user_pref(\"network.proxy.type\", 4);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_EQ(PROXY_NONE, proxy_info.type); - EXPECT_TRUE(proxy_info.autodetect); - EXPECT_TRUE(proxy_info.autoconfig_url.empty()); -} - -// Verifies detection of automatic proxy detection using a static url -// to config file. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyAutoUrl) { - ProxyInfo proxy_info; - std::string prefs(kFirefoxHeader); - - prefs.append( - "user_pref(\"network.proxy.autoconfig_url\", \"http://a/b.pac\");\n"); - prefs.append("user_pref(\"network.proxy.type\", 2);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_FALSE(proxy_info.autodetect); - EXPECT_EQ(PROXY_NONE, proxy_info.type); - EXPECT_EQ(0, proxy_info.autoconfig_url.compare("http://a/b.pac")); -} - -} // namespace rtc diff --git a/webrtc/base/proxyinfo.cc b/webrtc/base/proxyinfo.cc deleted file mode 100644 index 70c3b5584..000000000 --- a/webrtc/base/proxyinfo.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/proxyinfo.h" - -namespace rtc { - -const char * ProxyToString(ProxyType proxy) { - const char * const PROXY_NAMES[] = { "none", "https", "socks5", "unknown" }; - return PROXY_NAMES[proxy]; -} - -} // namespace rtc diff --git a/webrtc/base/proxyinfo.h b/webrtc/base/proxyinfo.h deleted file mode 100644 index 9947f4552..000000000 --- a/webrtc/base/proxyinfo.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_PROXYINFO_H__ -#define WEBRTC_BASE_PROXYINFO_H__ - -#include -#include "webrtc/base/socketaddress.h" -#include "webrtc/base/cryptstring.h" - -namespace rtc { - -enum ProxyType { - PROXY_NONE, - PROXY_HTTPS, - PROXY_SOCKS5, - PROXY_UNKNOWN -}; -const char * ProxyToString(ProxyType proxy); - -struct ProxyInfo { - ProxyType type; - SocketAddress address; - std::string autoconfig_url; - bool autodetect; - std::string bypass_list; - std::string username; - CryptString password; - - ProxyInfo() : type(PROXY_NONE), autodetect(false) { } -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_PROXYINFO_H__ diff --git a/webrtc/base/proxyserver.cc b/webrtc/base/proxyserver.cc deleted file mode 100644 index 548cfbf5b..000000000 --- a/webrtc/base/proxyserver.cc +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/proxyserver.h" - -#include -#include "webrtc/base/socketfactory.h" - -namespace rtc { - -// ProxyServer -ProxyServer::ProxyServer( - SocketFactory* int_factory, const SocketAddress& int_addr, - SocketFactory* ext_factory, const SocketAddress& ext_ip) - : ext_factory_(ext_factory), ext_ip_(ext_ip.ipaddr(), 0), // strip off port - server_socket_(int_factory->CreateAsyncSocket(int_addr.family(), - SOCK_STREAM)) { - ASSERT(server_socket_.get() != NULL); - ASSERT(int_addr.family() == AF_INET || int_addr.family() == AF_INET6); - server_socket_->Bind(int_addr); - server_socket_->Listen(5); - server_socket_->SignalReadEvent.connect(this, &ProxyServer::OnAcceptEvent); -} - -ProxyServer::~ProxyServer() { - for (BindingList::iterator it = bindings_.begin(); - it != bindings_.end(); ++it) { - delete (*it); - } -} - -void ProxyServer::OnAcceptEvent(AsyncSocket* socket) { - ASSERT(socket != NULL && socket == server_socket_.get()); - AsyncSocket* int_socket = socket->Accept(NULL); - AsyncProxyServerSocket* wrapped_socket = WrapSocket(int_socket); - AsyncSocket* ext_socket = ext_factory_->CreateAsyncSocket(ext_ip_.family(), - SOCK_STREAM); - if (ext_socket) { - ext_socket->Bind(ext_ip_); - bindings_.push_back(new ProxyBinding(wrapped_socket, ext_socket)); - } else { - LOG(LS_ERROR) << "Unable to create external socket on proxy accept event"; - } -} - -void ProxyServer::OnBindingDestroyed(ProxyBinding* binding) { - BindingList::iterator it = - std::find(bindings_.begin(), bindings_.end(), binding); - delete (*it); - bindings_.erase(it); -} - -// ProxyBinding -ProxyBinding::ProxyBinding(AsyncProxyServerSocket* int_socket, - AsyncSocket* ext_socket) - : int_socket_(int_socket), ext_socket_(ext_socket), connected_(false), - out_buffer_(kBufferSize), in_buffer_(kBufferSize) { - int_socket_->SignalConnectRequest.connect(this, - &ProxyBinding::OnConnectRequest); - int_socket_->SignalReadEvent.connect(this, &ProxyBinding::OnInternalRead); - int_socket_->SignalWriteEvent.connect(this, &ProxyBinding::OnInternalWrite); - int_socket_->SignalCloseEvent.connect(this, &ProxyBinding::OnInternalClose); - ext_socket_->SignalConnectEvent.connect(this, - &ProxyBinding::OnExternalConnect); - ext_socket_->SignalReadEvent.connect(this, &ProxyBinding::OnExternalRead); - ext_socket_->SignalWriteEvent.connect(this, &ProxyBinding::OnExternalWrite); - ext_socket_->SignalCloseEvent.connect(this, &ProxyBinding::OnExternalClose); -} - -void ProxyBinding::OnConnectRequest(AsyncProxyServerSocket* socket, - const SocketAddress& addr) { - ASSERT(!connected_ && ext_socket_.get() != NULL); - ext_socket_->Connect(addr); - // TODO: handle errors here -} - -void ProxyBinding::OnInternalRead(AsyncSocket* socket) { - Read(int_socket_.get(), &out_buffer_); - Write(ext_socket_.get(), &out_buffer_); -} - -void ProxyBinding::OnInternalWrite(AsyncSocket* socket) { - Write(int_socket_.get(), &in_buffer_); -} - -void ProxyBinding::OnInternalClose(AsyncSocket* socket, int err) { - Destroy(); -} - -void ProxyBinding::OnExternalConnect(AsyncSocket* socket) { - ASSERT(socket != NULL); - connected_ = true; - int_socket_->SendConnectResult(0, socket->GetRemoteAddress()); -} - -void ProxyBinding::OnExternalRead(AsyncSocket* socket) { - Read(ext_socket_.get(), &in_buffer_); - Write(int_socket_.get(), &in_buffer_); -} - -void ProxyBinding::OnExternalWrite(AsyncSocket* socket) { - Write(ext_socket_.get(), &out_buffer_); -} - -void ProxyBinding::OnExternalClose(AsyncSocket* socket, int err) { - if (!connected_) { - int_socket_->SendConnectResult(err, SocketAddress()); - } - Destroy(); -} - -void ProxyBinding::Read(AsyncSocket* socket, FifoBuffer* buffer) { - // Only read if the buffer is empty. - ASSERT(socket != NULL); - size_t size; - int read; - if (buffer->GetBuffered(&size) && size == 0) { - void* p = buffer->GetWriteBuffer(&size); - read = socket->Recv(p, size); - buffer->ConsumeWriteBuffer(_max(read, 0)); - } -} - -void ProxyBinding::Write(AsyncSocket* socket, FifoBuffer* buffer) { - ASSERT(socket != NULL); - size_t size; - int written; - const void* p = buffer->GetReadData(&size); - written = socket->Send(p, size); - buffer->ConsumeReadData(_max(written, 0)); -} - -void ProxyBinding::Destroy() { - SignalDestroyed(this); -} - -} // namespace rtc diff --git a/webrtc/base/proxyserver.h b/webrtc/base/proxyserver.h deleted file mode 100644 index 80e15d969..000000000 --- a/webrtc/base/proxyserver.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_PROXYSERVER_H_ -#define WEBRTC_BASE_PROXYSERVER_H_ - -#include -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/socketadapters.h" -#include "webrtc/base/socketaddress.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -class SocketFactory; - -// ProxyServer is a base class that allows for easy construction of proxy -// servers. With its helper class ProxyBinding, it contains all the necessary -// logic for receiving and bridging connections. The specific client-server -// proxy protocol is implemented by an instance of the AsyncProxyServerSocket -// class; children of ProxyServer implement WrapSocket appropriately to return -// the correct protocol handler. - -class ProxyBinding : public sigslot::has_slots<> { - public: - ProxyBinding(AsyncProxyServerSocket* in_socket, AsyncSocket* out_socket); - sigslot::signal1 SignalDestroyed; - - private: - void OnConnectRequest(AsyncProxyServerSocket* socket, - const SocketAddress& addr); - void OnInternalRead(AsyncSocket* socket); - void OnInternalWrite(AsyncSocket* socket); - void OnInternalClose(AsyncSocket* socket, int err); - void OnExternalConnect(AsyncSocket* socket); - void OnExternalRead(AsyncSocket* socket); - void OnExternalWrite(AsyncSocket* socket); - void OnExternalClose(AsyncSocket* socket, int err); - - static void Read(AsyncSocket* socket, FifoBuffer* buffer); - static void Write(AsyncSocket* socket, FifoBuffer* buffer); - void Destroy(); - - static const int kBufferSize = 4096; - scoped_ptr int_socket_; - scoped_ptr ext_socket_; - bool connected_; - FifoBuffer out_buffer_; - FifoBuffer in_buffer_; - DISALLOW_EVIL_CONSTRUCTORS(ProxyBinding); -}; - -class ProxyServer : public sigslot::has_slots<> { - public: - ProxyServer(SocketFactory* int_factory, const SocketAddress& int_addr, - SocketFactory* ext_factory, const SocketAddress& ext_ip); - virtual ~ProxyServer(); - - protected: - void OnAcceptEvent(AsyncSocket* socket); - virtual AsyncProxyServerSocket* WrapSocket(AsyncSocket* socket) = 0; - void OnBindingDestroyed(ProxyBinding* binding); - - private: - typedef std::list BindingList; - SocketFactory* ext_factory_; - SocketAddress ext_ip_; - scoped_ptr server_socket_; - BindingList bindings_; - DISALLOW_EVIL_CONSTRUCTORS(ProxyServer); -}; - -// SocksProxyServer is a simple extension of ProxyServer to implement SOCKS. -class SocksProxyServer : public ProxyServer { - public: - SocksProxyServer(SocketFactory* int_factory, const SocketAddress& int_addr, - SocketFactory* ext_factory, const SocketAddress& ext_ip) - : ProxyServer(int_factory, int_addr, ext_factory, ext_ip) { - } - protected: - AsyncProxyServerSocket* WrapSocket(AsyncSocket* socket) { - return new AsyncSocksProxyServerSocket(socket); - } - DISALLOW_EVIL_CONSTRUCTORS(SocksProxyServer); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_PROXYSERVER_H_ diff --git a/webrtc/base/ratelimiter.cc b/webrtc/base/ratelimiter.cc deleted file mode 100644 index c4a251d14..000000000 --- a/webrtc/base/ratelimiter.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/ratelimiter.h" - -namespace rtc { - -bool RateLimiter::CanUse(size_t desired, double time) { - return ((time > period_end_ && desired <= max_per_period_) || - (used_in_period_ + desired) <= max_per_period_); -} - -void RateLimiter::Use(size_t used, double time) { - if (time > period_end_) { - period_start_ = time; - period_end_ = time + period_length_; - used_in_period_ = 0; - } - used_in_period_ += used; -} - -} // namespace rtc diff --git a/webrtc/base/ratelimiter.h b/webrtc/base/ratelimiter.h deleted file mode 100644 index cf5d6b05b..000000000 --- a/webrtc/base/ratelimiter.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_RATELIMITER_H_ -#define WEBRTC_BASE_RATELIMITER_H_ - -#include -#include "webrtc/base/basictypes.h" - -namespace rtc { - -// Limits the rate of use to a certain maximum quantity per period of -// time. Use, for example, for simple bandwidth throttling. -// -// It's implemented like a diet plan: You have so many calories per -// day. If you hit the limit, you can't eat any more until the next -// day. -class RateLimiter { - public: - // For example, 100kb per second. - RateLimiter(size_t max, double period) - : max_per_period_(max), - period_length_(period), - used_in_period_(0), - period_start_(0.0), - period_end_(period) { - } - virtual ~RateLimiter() {} - - // Returns true if if the desired quantity is available in the - // current period (< (max - used)). Once the given time passes the - // end of the period, used is set to zero and more use is available. - bool CanUse(size_t desired, double time); - // Increment the quantity used this period. If past the end of a - // period, a new period is started. - void Use(size_t used, double time); - - size_t used_in_period() const { - return used_in_period_; - } - - size_t max_per_period() const { - return max_per_period_; - } - - private: - size_t max_per_period_; - double period_length_; - size_t used_in_period_; - double period_start_; - double period_end_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_RATELIMITER_H_ diff --git a/webrtc/base/ratelimiter_unittest.cc b/webrtc/base/ratelimiter_unittest.cc deleted file mode 100644 index b54a751b7..000000000 --- a/webrtc/base/ratelimiter_unittest.cc +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/ratelimiter.h" - -namespace rtc { - -TEST(RateLimiterTest, TestCanUse) { - // Diet: Can eat 2,000 calories per day. - RateLimiter limiter = RateLimiter(2000, 1.0); - - double monday = 1.0; - double tuesday = 2.0; - double thursday = 4.0; - - EXPECT_TRUE(limiter.CanUse(0, monday)); - EXPECT_TRUE(limiter.CanUse(1000, monday)); - EXPECT_TRUE(limiter.CanUse(1999, monday)); - EXPECT_TRUE(limiter.CanUse(2000, monday)); - EXPECT_FALSE(limiter.CanUse(2001, monday)); - - limiter.Use(1000, monday); - - EXPECT_TRUE(limiter.CanUse(0, monday)); - EXPECT_TRUE(limiter.CanUse(999, monday)); - EXPECT_TRUE(limiter.CanUse(1000, monday)); - EXPECT_FALSE(limiter.CanUse(1001, monday)); - - limiter.Use(1000, monday); - - EXPECT_TRUE(limiter.CanUse(0, monday)); - EXPECT_FALSE(limiter.CanUse(1, monday)); - - EXPECT_TRUE(limiter.CanUse(0, tuesday)); - EXPECT_TRUE(limiter.CanUse(1, tuesday)); - EXPECT_TRUE(limiter.CanUse(1999, tuesday)); - EXPECT_TRUE(limiter.CanUse(2000, tuesday)); - EXPECT_FALSE(limiter.CanUse(2001, tuesday)); - - limiter.Use(1000, tuesday); - - EXPECT_TRUE(limiter.CanUse(1000, tuesday)); - EXPECT_FALSE(limiter.CanUse(1001, tuesday)); - - limiter.Use(1000, thursday); - - EXPECT_TRUE(limiter.CanUse(1000, tuesday)); - EXPECT_FALSE(limiter.CanUse(1001, tuesday)); -} - -} // namespace rtc diff --git a/webrtc/base/ratetracker.cc b/webrtc/base/ratetracker.cc deleted file mode 100644 index 31ecd9bbb..000000000 --- a/webrtc/base/ratetracker.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/ratetracker.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { - -RateTracker::RateTracker() - : total_units_(0), units_second_(0), - last_units_second_time_(static_cast(-1)), - last_units_second_calc_(0) { -} - -size_t RateTracker::total_units() const { - return total_units_; -} - -size_t RateTracker::units_second() { - // Snapshot units / second calculator. Determine how many seconds have - // elapsed since our last reference point. If over 1 second, establish - // a new reference point that is an integer number of seconds since the - // last one, and compute the units over that interval. - uint32 current_time = Time(); - if (last_units_second_time_ != static_cast(-1)) { - int delta = rtc::TimeDiff(current_time, last_units_second_time_); - if (delta >= 1000) { - int fraction_time = delta % 1000; - int seconds = delta / 1000; - int fraction_units = - static_cast(total_units_ - last_units_second_calc_) * - fraction_time / delta; - // Compute "units received during the interval" / "seconds in interval" - units_second_ = - (total_units_ - last_units_second_calc_ - fraction_units) / seconds; - last_units_second_time_ = current_time - fraction_time; - last_units_second_calc_ = total_units_ - fraction_units; - } - } - if (last_units_second_time_ == static_cast(-1)) { - last_units_second_time_ = current_time; - last_units_second_calc_ = total_units_; - } - - return units_second_; -} - -void RateTracker::Update(size_t units) { - total_units_ += units; -} - -uint32 RateTracker::Time() const { - return rtc::Time(); -} - -} // namespace rtc diff --git a/webrtc/base/ratetracker.h b/webrtc/base/ratetracker.h deleted file mode 100644 index 575bff75a..000000000 --- a/webrtc/base/ratetracker.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_RATETRACKER_H_ -#define WEBRTC_BASE_RATETRACKER_H_ - -#include -#include "webrtc/base/basictypes.h" - -namespace rtc { - -// Computes instantaneous units per second. -class RateTracker { - public: - RateTracker(); - virtual ~RateTracker() {} - - size_t total_units() const; - size_t units_second(); - void Update(size_t units); - - protected: - // overrideable for tests - virtual uint32 Time() const; - - private: - size_t total_units_; - size_t units_second_; - uint32 last_units_second_time_; - size_t last_units_second_calc_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_RATETRACKER_H_ diff --git a/webrtc/base/ratetracker_unittest.cc b/webrtc/base/ratetracker_unittest.cc deleted file mode 100644 index e9fee2b9f..000000000 --- a/webrtc/base/ratetracker_unittest.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/ratetracker.h" - -namespace rtc { - -class RateTrackerForTest : public RateTracker { - public: - RateTrackerForTest() : time_(0) {} - virtual uint32 Time() const { return time_; } - void AdvanceTime(uint32 delta) { time_ += delta; } - - private: - uint32 time_; -}; - -TEST(RateTrackerTest, TestBasics) { - RateTrackerForTest tracker; - EXPECT_EQ(0U, tracker.total_units()); - EXPECT_EQ(0U, tracker.units_second()); - - // Add a sample. - tracker.Update(1234); - // Advance the clock by 100 ms. - tracker.AdvanceTime(100); - // total_units should advance, but units_second should stay 0. - EXPECT_EQ(1234U, tracker.total_units()); - EXPECT_EQ(0U, tracker.units_second()); - - // Repeat. - tracker.Update(1234); - tracker.AdvanceTime(100); - EXPECT_EQ(1234U * 2, tracker.total_units()); - EXPECT_EQ(0U, tracker.units_second()); - - // Advance the clock by 800 ms, so we've elapsed a full second. - // units_second should now be filled in properly. - tracker.AdvanceTime(800); - EXPECT_EQ(1234U * 2, tracker.total_units()); - EXPECT_EQ(1234U * 2, tracker.units_second()); - - // Poll the tracker again immediately. The reported rate should stay the same. - EXPECT_EQ(1234U * 2, tracker.total_units()); - EXPECT_EQ(1234U * 2, tracker.units_second()); - - // Do nothing and advance by a second. We should drop down to zero. - tracker.AdvanceTime(1000); - EXPECT_EQ(1234U * 2, tracker.total_units()); - EXPECT_EQ(0U, tracker.units_second()); - - // Send a bunch of data at a constant rate for 5.5 "seconds". - // We should report the rate properly. - for (int i = 0; i < 5500; i += 100) { - tracker.Update(9876U); - tracker.AdvanceTime(100); - } - EXPECT_EQ(9876U * 10, tracker.units_second()); - - // Advance the clock by 500 ms. Since we sent nothing over this half-second, - // the reported rate should be reduced by half. - tracker.AdvanceTime(500); - EXPECT_EQ(9876U * 5, tracker.units_second()); -} - -} // namespace rtc diff --git a/webrtc/base/refcount.h b/webrtc/base/refcount.h deleted file mode 100644 index 7bb6da36a..000000000 --- a/webrtc/base/refcount.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef TALK_APP_BASE_REFCOUNT_H_ -#define TALK_APP_BASE_REFCOUNT_H_ - -#include - -#include "webrtc/base/criticalsection.h" - -namespace rtc { - -// Reference count interface. -class RefCountInterface { - public: - virtual int AddRef() = 0; - virtual int Release() = 0; - protected: - virtual ~RefCountInterface() {} -}; - -template -class RefCountedObject : public T { - public: - RefCountedObject() : ref_count_(0) { - } - - template - explicit RefCountedObject(P p) : T(p), ref_count_(0) { - } - - template - RefCountedObject(P1 p1, P2 p2) : T(p1, p2), ref_count_(0) { - } - - template - RefCountedObject(P1 p1, P2 p2, P3 p3) : T(p1, p2, p3), ref_count_(0) { - } - - template - RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4) - : T(p1, p2, p3, p4), ref_count_(0) { - } - - template - RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) - : T(p1, p2, p3, p4, p5), ref_count_(0) { - } - - virtual int AddRef() { - return rtc::AtomicOps::Increment(&ref_count_); - } - - virtual int Release() { - int count = rtc::AtomicOps::Decrement(&ref_count_); - if (!count) { - delete this; - } - return count; - } - - protected: - virtual ~RefCountedObject() { - } - - int ref_count_; -}; - -} // namespace rtc - -#endif // TALK_APP_BASE_REFCOUNT_H_ diff --git a/webrtc/base/referencecountedsingletonfactory.h b/webrtc/base/referencecountedsingletonfactory.h deleted file mode 100644 index 7138c8c5e..000000000 --- a/webrtc/base/referencecountedsingletonfactory.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_REFERENCECOUNTEDSINGLETONFACTORY_H_ -#define WEBRTC_BASE_REFERENCECOUNTEDSINGLETONFACTORY_H_ - -#include "webrtc/base/common.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/scoped_ptr.h" - -namespace rtc { - -template class rcsf_ptr; - -// A ReferenceCountedSingletonFactory is an object which owns another object, -// and doles out the owned object to consumers in a reference-counted manner. -// Thus, the factory owns at most one object of the desired kind, and -// hands consumers a special pointer to it, through which they can access it. -// When the consumers delete the pointer, the reference count goes down, -// and if the reference count hits zero, the factory can throw the object -// away. If a consumer requests the pointer and the factory has none, -// it can create one on the fly and pass it back. -template -class ReferenceCountedSingletonFactory { - friend class rcsf_ptr; - public: - ReferenceCountedSingletonFactory() : ref_count_(0) {} - - virtual ~ReferenceCountedSingletonFactory() { - ASSERT(ref_count_ == 0); - } - - protected: - // Must be implemented in a sub-class. The sub-class may choose whether or not - // to cache the instance across lifetimes by either reset()'ing or not - // reset()'ing the scoped_ptr in CleanupInstance(). - virtual bool SetupInstance() = 0; - virtual void CleanupInstance() = 0; - - scoped_ptr instance_; - - private: - Interface* GetInstance() { - rtc::CritScope cs(&crit_); - if (ref_count_ == 0) { - if (!SetupInstance()) { - LOG(LS_VERBOSE) << "Failed to setup instance"; - return NULL; - } - ASSERT(instance_.get() != NULL); - } - ++ref_count_; - - LOG(LS_VERBOSE) << "Number of references: " << ref_count_; - return instance_.get(); - } - - void ReleaseInstance() { - rtc::CritScope cs(&crit_); - ASSERT(ref_count_ > 0); - ASSERT(instance_.get() != NULL); - --ref_count_; - LOG(LS_VERBOSE) << "Number of references: " << ref_count_; - if (ref_count_ == 0) { - CleanupInstance(); - } - } - - CriticalSection crit_; - int ref_count_; - - DISALLOW_COPY_AND_ASSIGN(ReferenceCountedSingletonFactory); -}; - -template -class rcsf_ptr { - public: - // Create a pointer that uses the factory to get the instance. - // This is lazy - it won't generate the instance until it is requested. - explicit rcsf_ptr(ReferenceCountedSingletonFactory* factory) - : instance_(NULL), - factory_(factory) { - } - - ~rcsf_ptr() { - release(); - } - - Interface& operator*() { - EnsureAcquired(); - return *instance_; - } - - Interface* operator->() { - EnsureAcquired(); - return instance_; - } - - // Gets the pointer, creating the singleton if necessary. May return NULL if - // creation failed. - Interface* get() { - Acquire(); - return instance_; - } - - // Set instance to NULL and tell the factory we aren't using the instance - // anymore. - void release() { - if (instance_) { - instance_ = NULL; - factory_->ReleaseInstance(); - } - } - - // Lets us know whether instance is valid or not right now. - // Even though attempts to use the instance will automatically create it, it - // is advisable to check this because creation can fail. - bool valid() const { - return instance_ != NULL; - } - - // Returns the factory that this pointer is using. - ReferenceCountedSingletonFactory* factory() const { - return factory_; - } - - private: - void EnsureAcquired() { - Acquire(); - ASSERT(instance_ != NULL); - } - - void Acquire() { - // Since we're getting a singleton back, acquire is a noop if instance is - // already populated. - if (!instance_) { - instance_ = factory_->GetInstance(); - } - } - - Interface* instance_; - ReferenceCountedSingletonFactory* factory_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(rcsf_ptr); -}; - -}; // namespace rtc - -#endif // WEBRTC_BASE_REFERENCECOUNTEDSINGLETONFACTORY_H_ diff --git a/webrtc/base/referencecountedsingletonfactory_unittest.cc b/webrtc/base/referencecountedsingletonfactory_unittest.cc deleted file mode 100644 index 75d97a639..000000000 --- a/webrtc/base/referencecountedsingletonfactory_unittest.cc +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/referencecountedsingletonfactory.h" - -namespace rtc { - -class MyExistenceWatcher { - public: - MyExistenceWatcher() { create_called_ = true; } - ~MyExistenceWatcher() { delete_called_ = true; } - - static bool create_called_; - static bool delete_called_; -}; - -bool MyExistenceWatcher::create_called_ = false; -bool MyExistenceWatcher::delete_called_ = false; - -class TestReferenceCountedSingletonFactory : - public ReferenceCountedSingletonFactory { - protected: - virtual bool SetupInstance() { - instance_.reset(new MyExistenceWatcher()); - return true; - } - - virtual void CleanupInstance() { - instance_.reset(); - } -}; - -static void DoCreateAndGoOutOfScope( - ReferenceCountedSingletonFactory *factory) { - rcsf_ptr ptr(factory); - ptr.get(); - // and now ptr should go out of scope. -} - -TEST(ReferenceCountedSingletonFactory, ZeroReferenceCountCausesDeletion) { - TestReferenceCountedSingletonFactory factory; - MyExistenceWatcher::delete_called_ = false; - DoCreateAndGoOutOfScope(&factory); - EXPECT_TRUE(MyExistenceWatcher::delete_called_); -} - -TEST(ReferenceCountedSingletonFactory, NonZeroReferenceCountDoesNotDelete) { - TestReferenceCountedSingletonFactory factory; - rcsf_ptr ptr(&factory); - ptr.get(); - MyExistenceWatcher::delete_called_ = false; - DoCreateAndGoOutOfScope(&factory); - EXPECT_FALSE(MyExistenceWatcher::delete_called_); -} - -TEST(ReferenceCountedSingletonFactory, ReturnedPointersReferToSameThing) { - TestReferenceCountedSingletonFactory factory; - rcsf_ptr one(&factory), two(&factory); - - EXPECT_EQ(one.get(), two.get()); -} - -TEST(ReferenceCountedSingletonFactory, Release) { - TestReferenceCountedSingletonFactory factory; - - rcsf_ptr one(&factory); - one.get(); - - MyExistenceWatcher::delete_called_ = false; - one.release(); - EXPECT_TRUE(MyExistenceWatcher::delete_called_); -} - -TEST(ReferenceCountedSingletonFactory, GetWithoutRelease) { - TestReferenceCountedSingletonFactory factory; - rcsf_ptr one(&factory); - one.get(); - - MyExistenceWatcher::create_called_ = false; - one.get(); - EXPECT_FALSE(MyExistenceWatcher::create_called_); -} - -TEST(ReferenceCountedSingletonFactory, GetAfterRelease) { - TestReferenceCountedSingletonFactory factory; - rcsf_ptr one(&factory); - - MyExistenceWatcher::create_called_ = false; - one.release(); - one.get(); - EXPECT_TRUE(MyExistenceWatcher::create_called_); -} - -TEST(ReferenceCountedSingletonFactory, MultipleReleases) { - TestReferenceCountedSingletonFactory factory; - rcsf_ptr one(&factory), two(&factory); - - MyExistenceWatcher::create_called_ = false; - MyExistenceWatcher::delete_called_ = false; - one.release(); - EXPECT_FALSE(MyExistenceWatcher::delete_called_); - one.release(); - EXPECT_FALSE(MyExistenceWatcher::delete_called_); - one.release(); - EXPECT_FALSE(MyExistenceWatcher::delete_called_); - one.get(); - EXPECT_TRUE(MyExistenceWatcher::create_called_); -} - -TEST(ReferenceCountedSingletonFactory, Existentialism) { - TestReferenceCountedSingletonFactory factory; - - rcsf_ptr one(&factory); - - MyExistenceWatcher::create_called_ = false; - MyExistenceWatcher::delete_called_ = false; - - one.get(); - EXPECT_TRUE(MyExistenceWatcher::create_called_); - one.release(); - EXPECT_TRUE(MyExistenceWatcher::delete_called_); -} - -} // namespace rtc diff --git a/webrtc/base/rollingaccumulator.h b/webrtc/base/rollingaccumulator.h deleted file mode 100644 index 0dce0c3a0..000000000 --- a/webrtc/base/rollingaccumulator.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ROLLINGACCUMULATOR_H_ -#define WEBRTC_BASE_ROLLINGACCUMULATOR_H_ - -#include - -#include "webrtc/base/common.h" - -namespace rtc { - -// RollingAccumulator stores and reports statistics -// over N most recent samples. -// -// T is assumed to be an int, long, double or float. -template -class RollingAccumulator { - public: - explicit RollingAccumulator(size_t max_count) - : samples_(max_count) { - Reset(); - } - ~RollingAccumulator() { - } - - size_t max_count() const { - return samples_.size(); - } - - size_t count() const { - 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_; - } - // Add new sample. - 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(); - } - - T ComputeSum() const { - return static_cast(sum_); - } - - double ComputeMean() const { - if (count_ == 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 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. - double ComputeWeightedMean(double learning_rate) const { - if (count_ < 1 || learning_rate <= 0.0 || learning_rate >= 1.0) { - return ComputeMean(); - } - double weighted_mean = 0.0; - double current_weight = 1.0; - double weight_sum = 0.0; - const size_t max_size = max_count(); - for (size_t i = 0; i < count_; ++i) { - current_weight *= learning_rate; - weight_sum += current_weight; - // Add max_size to prevent underflow. - size_t index = (next_index_ + max_size - i - 1) % max_size; - weighted_mean += current_weight * samples_[index]; - } - return weighted_mean / weight_sum; - } - - // Compute estimated variance. Estimation is more accurate - // as the number of samples grows. - double ComputeVariance() const { - if (count_ == 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 mean_2 - (mean * mean); - } - - private: - size_t count_; - size_t next_index_; - 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 samples_; - - DISALLOW_COPY_AND_ASSIGN(RollingAccumulator); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_ROLLINGACCUMULATOR_H_ diff --git a/webrtc/base/rollingaccumulator_unittest.cc b/webrtc/base/rollingaccumulator_unittest.cc deleted file mode 100644 index 7e3d8cdf0..000000000 --- a/webrtc/base/rollingaccumulator_unittest.cc +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/rollingaccumulator.h" - -namespace rtc { - -namespace { - -const double kLearningRate = 0.5; - -} // namespace - -TEST(RollingAccumulatorTest, ZeroSamples) { - RollingAccumulator accum(10); - - EXPECT_EQ(0U, accum.count()); - 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) { - RollingAccumulator accum(10); - for (int i = 0; i < 4; ++i) { - accum.AddSample(i); - } - - EXPECT_EQ(4U, accum.count()); - EXPECT_EQ(6, accum.ComputeSum()); - 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) { - RollingAccumulator accum(10); - for (int i = 0; i < 12; ++i) { - accum.AddSample(i); - } - - EXPECT_EQ(10U, accum.count()); - EXPECT_EQ(65, accum.ComputeSum()); - 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 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) { - RollingAccumulator accum(10); - for (int i = 0; i < 23; ++i) { - accum.AddSample(5 * i); - } - - EXPECT_EQ(10u, accum.count()); - EXPECT_DOUBLE_EQ(875.0, accum.ComputeSum()); - 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 accum(10); - 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_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 rtc diff --git a/webrtc/base/safe_conversions.h b/webrtc/base/safe_conversions.h deleted file mode 100644 index f6cb24e41..000000000 --- a/webrtc/base/safe_conversions.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Borrowed from Chromium's src/base/numerics/safe_conversions.h. - -#ifndef WEBRTC_BASE_SAFE_CONVERSIONS_H_ -#define WEBRTC_BASE_SAFE_CONVERSIONS_H_ - -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/safe_conversions_impl.h" - -namespace rtc { - -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 -inline bool IsValueInRangeForNumericType(Src value) { - return internal::RangeCheck(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 -inline Dst checked_cast(Src value) { - Check(IsValueInRangeForNumericType(value)); - return static_cast(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 -inline Dst saturated_cast(Src value) { - // Optimization for floating point values, which already saturate. - if (std::numeric_limits::is_iec559) - return static_cast(value); - - switch (internal::RangeCheck(value)) { - case internal::TYPE_VALID: - return static_cast(value); - - case internal::TYPE_UNDERFLOW: - return std::numeric_limits::min(); - - case internal::TYPE_OVERFLOW: - return std::numeric_limits::max(); - - // Should fail only on attempting to assign NaN to a saturated integer. - case internal::TYPE_INVALID: - Check(false); - return std::numeric_limits::max(); - } - - Check(false); // NOTREACHED(); - return static_cast(value); -} - -} // namespace rtc - -#endif // WEBRTC_BASE_SAFE_CONVERSIONS_H_ diff --git a/webrtc/base/safe_conversions_impl.h b/webrtc/base/safe_conversions_impl.h deleted file mode 100644 index 2950f970c..000000000 --- a/webrtc/base/safe_conversions_impl.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Borrowed from Chromium's src/base/numerics/safe_conversions_impl.h. - -#ifndef WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_ -#define WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_ - -#include - -namespace rtc { -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 ::is_signed ? - DST_SIGNED : DST_UNSIGNED, - SrcSign IsSrcSigned = std::numeric_limits::is_signed ? - SRC_SIGNED : SRC_UNSIGNED> -struct StaticRangeCheck {}; - -template -struct StaticRangeCheck { - typedef std::numeric_limits DstLimits; - typedef std::numeric_limits 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 -struct StaticRangeCheck { - static const DstRange value = sizeof(Dst) >= sizeof(Src) ? - CONTAINS_RANGE : OVERLAPS_RANGE; -}; - -template -struct StaticRangeCheck { - typedef std::numeric_limits DstLimits; - typedef std::numeric_limits 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 -struct StaticRangeCheck { - 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 ::is_signed ? - DST_SIGNED : DST_UNSIGNED, - SrcSign IsSrcSigned = std::numeric_limits::is_signed ? - SRC_SIGNED : SRC_UNSIGNED, - DstRange IsSrcRangeContained = StaticRangeCheck::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 -struct RangeCheckImpl { - static RangeCheckResult Check(Src value) { - return TYPE_VALID; - } -}; - -// Signed to signed narrowing. -template -struct RangeCheckImpl { - static RangeCheckResult Check(Src value) { - typedef std::numeric_limits DstLimits; - return DstLimits::is_iec559 ? - BASE_NUMERIC_RANGE_CHECK_RESULT( - value <= static_cast(DstLimits::max()), - value >= static_cast(DstLimits::max() * -1)) : - BASE_NUMERIC_RANGE_CHECK_RESULT( - value <= static_cast(DstLimits::max()), - value >= static_cast(DstLimits::min())); - } -}; - -// Unsigned to unsigned narrowing. -template -struct RangeCheckImpl { - static RangeCheckResult Check(Src value) { - typedef std::numeric_limits DstLimits; - return BASE_NUMERIC_RANGE_CHECK_RESULT( - value <= static_cast(DstLimits::max()), true); - } -}; - -// Unsigned to signed. -template -struct RangeCheckImpl { - static RangeCheckResult Check(Src value) { - typedef std::numeric_limits DstLimits; - return sizeof(Dst) > sizeof(Src) ? TYPE_VALID : - BASE_NUMERIC_RANGE_CHECK_RESULT( - value <= static_cast(DstLimits::max()), true); - } -}; - -// Signed to unsigned. -template -struct RangeCheckImpl { - static RangeCheckResult Check(Src value) { - typedef std::numeric_limits DstLimits; - typedef std::numeric_limits 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(0)) : - BASE_NUMERIC_RANGE_CHECK_RESULT( - value <= static_cast(DstLimits::max()), - value >= static_cast(0)); - } -}; - -template -inline RangeCheckResult RangeCheck(Src value) { - COMPILE_ASSERT(std::numeric_limits::is_specialized, - argument_must_be_numeric); - COMPILE_ASSERT(std::numeric_limits::is_specialized, - result_must_be_numeric); - return RangeCheckImpl::Check(value); -} - -} // namespace internal -} // namespace rtc - -#endif // WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_ diff --git a/webrtc/base/schanneladapter.cc b/webrtc/base/schanneladapter.cc deleted file mode 100644 index 50c0638fd..000000000 --- a/webrtc/base/schanneladapter.cc +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/win32.h" -#define SECURITY_WIN32 -#include -#include - -#include -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/schanneladapter.h" -#include "webrtc/base/sec_buffer.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -///////////////////////////////////////////////////////////////////////////// -// SChannelAdapter -///////////////////////////////////////////////////////////////////////////// - -extern const ConstantLabel SECURITY_ERRORS[]; - -const ConstantLabel SCHANNEL_BUFFER_TYPES[] = { - KLABEL(SECBUFFER_EMPTY), // 0 - KLABEL(SECBUFFER_DATA), // 1 - KLABEL(SECBUFFER_TOKEN), // 2 - KLABEL(SECBUFFER_PKG_PARAMS), // 3 - KLABEL(SECBUFFER_MISSING), // 4 - KLABEL(SECBUFFER_EXTRA), // 5 - KLABEL(SECBUFFER_STREAM_TRAILER), // 6 - KLABEL(SECBUFFER_STREAM_HEADER), // 7 - KLABEL(SECBUFFER_MECHLIST), // 11 - KLABEL(SECBUFFER_MECHLIST_SIGNATURE), // 12 - KLABEL(SECBUFFER_TARGET), // 13 - KLABEL(SECBUFFER_CHANNEL_BINDINGS), // 14 - LASTLABEL -}; - -void DescribeBuffer(LoggingSeverity severity, const char* prefix, - const SecBuffer& sb) { - LOG_V(severity) - << prefix - << "(" << sb.cbBuffer - << ", " << FindLabel(sb.BufferType & ~SECBUFFER_ATTRMASK, - SCHANNEL_BUFFER_TYPES) - << ", " << sb.pvBuffer << ")"; -} - -void DescribeBuffers(LoggingSeverity severity, const char* prefix, - const SecBufferDesc* sbd) { - if (!LOG_CHECK_LEVEL_V(severity)) - return; - LOG_V(severity) << prefix << "("; - for (size_t i=0; icBuffers; ++i) { - DescribeBuffer(severity, " ", sbd->pBuffers[i]); - } - LOG_V(severity) << ")"; -} - -const ULONG SSL_FLAGS_DEFAULT = ISC_REQ_ALLOCATE_MEMORY - | ISC_REQ_CONFIDENTIALITY - | ISC_REQ_EXTENDED_ERROR - | ISC_REQ_INTEGRITY - | ISC_REQ_REPLAY_DETECT - | ISC_REQ_SEQUENCE_DETECT - | ISC_REQ_STREAM; - //| ISC_REQ_USE_SUPPLIED_CREDS; - -typedef std::vector SChannelBuffer; - -struct SChannelAdapter::SSLImpl { - CredHandle cred; - CtxtHandle ctx; - bool cred_init, ctx_init; - SChannelBuffer inbuf, outbuf, readable; - SecPkgContext_StreamSizes sizes; - - SSLImpl() : cred_init(false), ctx_init(false) { } -}; - -SChannelAdapter::SChannelAdapter(AsyncSocket* socket) - : SSLAdapter(socket), state_(SSL_NONE), - restartable_(false), signal_close_(false), message_pending_(false), - impl_(new SSLImpl) { -} - -SChannelAdapter::~SChannelAdapter() { - Cleanup(); -} - -int -SChannelAdapter::StartSSL(const char* hostname, bool restartable) { - if (state_ != SSL_NONE) - return ERROR_ALREADY_INITIALIZED; - - ssl_host_name_ = hostname; - restartable_ = restartable; - - if (socket_->GetState() != Socket::CS_CONNECTED) { - state_ = SSL_WAIT; - return 0; - } - - state_ = SSL_CONNECTING; - if (int err = BeginSSL()) { - Error("BeginSSL", err, false); - return err; - } - - return 0; -} - -int -SChannelAdapter::BeginSSL() { - LOG(LS_VERBOSE) << "BeginSSL: " << ssl_host_name_; - ASSERT(state_ == SSL_CONNECTING); - - SECURITY_STATUS ret; - - SCHANNEL_CRED sc_cred = { 0 }; - sc_cred.dwVersion = SCHANNEL_CRED_VERSION; - //sc_cred.dwMinimumCipherStrength = 128; // Note: use system default - sc_cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_AUTO_CRED_VALIDATION; - - ret = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, - &sc_cred, NULL, NULL, &impl_->cred, NULL); - if (ret != SEC_E_OK) { - LOG(LS_ERROR) << "AcquireCredentialsHandle error: " - << ErrorName(ret, SECURITY_ERRORS); - return ret; - } - impl_->cred_init = true; - - if (LOG_CHECK_LEVEL(LS_VERBOSE)) { - SecPkgCred_CipherStrengths cipher_strengths = { 0 }; - ret = QueryCredentialsAttributes(&impl_->cred, - SECPKG_ATTR_CIPHER_STRENGTHS, - &cipher_strengths); - if (SUCCEEDED(ret)) { - LOG(LS_VERBOSE) << "SChannel cipher strength: " - << cipher_strengths.dwMinimumCipherStrength << " - " - << cipher_strengths.dwMaximumCipherStrength; - } - - SecPkgCred_SupportedAlgs supported_algs = { 0 }; - ret = QueryCredentialsAttributes(&impl_->cred, - SECPKG_ATTR_SUPPORTED_ALGS, - &supported_algs); - if (SUCCEEDED(ret)) { - LOG(LS_VERBOSE) << "SChannel supported algorithms:"; - for (DWORD i=0; ipwszName : L"Unknown"; - LOG(LS_VERBOSE) << " " << ToUtf8(alg_name) << " (" << alg_id << ")"; - } - CSecBufferBase::FreeSSPI(supported_algs.palgSupportedAlgs); - } - } - - ULONG flags = SSL_FLAGS_DEFAULT, ret_flags = 0; - if (ignore_bad_cert()) - flags |= ISC_REQ_MANUAL_CRED_VALIDATION; - - CSecBufferBundle<2, CSecBufferBase::FreeSSPI> sb_out; - ret = InitializeSecurityContextA(&impl_->cred, NULL, - const_cast(ssl_host_name_.c_str()), - flags, 0, 0, NULL, 0, - &impl_->ctx, sb_out.desc(), - &ret_flags, NULL); - if (SUCCEEDED(ret)) - impl_->ctx_init = true; - return ProcessContext(ret, NULL, sb_out.desc()); -} - -int -SChannelAdapter::ContinueSSL() { - LOG(LS_VERBOSE) << "ContinueSSL"; - ASSERT(state_ == SSL_CONNECTING); - - SECURITY_STATUS ret; - - CSecBufferBundle<2> sb_in; - sb_in[0].BufferType = SECBUFFER_TOKEN; - sb_in[0].cbBuffer = static_cast(impl_->inbuf.size()); - sb_in[0].pvBuffer = &impl_->inbuf[0]; - //DescribeBuffers(LS_VERBOSE, "Input Buffer ", sb_in.desc()); - - ULONG flags = SSL_FLAGS_DEFAULT, ret_flags = 0; - if (ignore_bad_cert()) - flags |= ISC_REQ_MANUAL_CRED_VALIDATION; - - CSecBufferBundle<2, CSecBufferBase::FreeSSPI> sb_out; - ret = InitializeSecurityContextA(&impl_->cred, &impl_->ctx, - const_cast(ssl_host_name_.c_str()), - flags, 0, 0, sb_in.desc(), 0, - NULL, sb_out.desc(), - &ret_flags, NULL); - return ProcessContext(ret, sb_in.desc(), sb_out.desc()); -} - -int -SChannelAdapter::ProcessContext(long int status, _SecBufferDesc* sbd_in, - _SecBufferDesc* sbd_out) { - if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED && - status != SEC_E_INCOMPLETE_MESSAGE) { - LOG(LS_ERROR) - << "InitializeSecurityContext error: " - << ErrorName(status, SECURITY_ERRORS); - } - //if (sbd_in) - // DescribeBuffers(LS_VERBOSE, "Input Buffer ", sbd_in); - //if (sbd_out) - // DescribeBuffers(LS_VERBOSE, "Output Buffer ", sbd_out); - - if (status == SEC_E_INCOMPLETE_MESSAGE) { - // Wait for more input from server. - return Flush(); - } - - if (FAILED(status)) { - // We can't continue. Common errors: - // SEC_E_CERT_EXPIRED - Typically, this means the computer clock is wrong. - return status; - } - - // Note: we check both input and output buffers for SECBUFFER_EXTRA. - // Experience shows it appearing in the input, but the documentation claims - // it should appear in the output. - size_t extra = 0; - if (sbd_in) { - for (size_t i=0; icBuffers; ++i) { - SecBuffer& buffer = sbd_in->pBuffers[i]; - if (buffer.BufferType == SECBUFFER_EXTRA) { - extra += buffer.cbBuffer; - } - } - } - if (sbd_out) { - for (size_t i=0; icBuffers; ++i) { - SecBuffer& buffer = sbd_out->pBuffers[i]; - if (buffer.BufferType == SECBUFFER_EXTRA) { - extra += buffer.cbBuffer; - } else if (buffer.BufferType == SECBUFFER_TOKEN) { - impl_->outbuf.insert(impl_->outbuf.end(), - reinterpret_cast(buffer.pvBuffer), - reinterpret_cast(buffer.pvBuffer) + buffer.cbBuffer); - } - } - } - - if (extra) { - ASSERT(extra <= impl_->inbuf.size()); - size_t consumed = impl_->inbuf.size() - extra; - memmove(&impl_->inbuf[0], &impl_->inbuf[consumed], extra); - impl_->inbuf.resize(extra); - } else { - impl_->inbuf.clear(); - } - - if (SEC_I_CONTINUE_NEEDED == status) { - // Send data to server and wait for response. - // Note: ContinueSSL will result in a Flush, anyway. - return impl_->inbuf.empty() ? Flush() : ContinueSSL(); - } - - if (SEC_E_OK == status) { - LOG(LS_VERBOSE) << "QueryContextAttributes"; - status = QueryContextAttributes(&impl_->ctx, SECPKG_ATTR_STREAM_SIZES, - &impl_->sizes); - if (FAILED(status)) { - LOG(LS_ERROR) << "QueryContextAttributes error: " - << ErrorName(status, SECURITY_ERRORS); - return status; - } - - state_ = SSL_CONNECTED; - - if (int err = DecryptData()) { - return err; - } else if (int err = Flush()) { - return err; - } else { - // If we decrypted any data, queue up a notification here - PostEvent(); - // Signal our connectedness - AsyncSocketAdapter::OnConnectEvent(this); - } - return 0; - } - - if (SEC_I_INCOMPLETE_CREDENTIALS == status) { - // We don't support client authentication in schannel. - return status; - } - - // We don't expect any other codes - ASSERT(false); - return status; -} - -int -SChannelAdapter::DecryptData() { - SChannelBuffer& inbuf = impl_->inbuf; - SChannelBuffer& readable = impl_->readable; - - while (!inbuf.empty()) { - CSecBufferBundle<4> in_buf; - in_buf[0].BufferType = SECBUFFER_DATA; - in_buf[0].cbBuffer = static_cast(inbuf.size()); - in_buf[0].pvBuffer = &inbuf[0]; - - //DescribeBuffers(LS_VERBOSE, "Decrypt In ", in_buf.desc()); - SECURITY_STATUS status = DecryptMessage(&impl_->ctx, in_buf.desc(), 0, 0); - //DescribeBuffers(LS_VERBOSE, "Decrypt Out ", in_buf.desc()); - - // Note: We are explicitly treating SEC_E_OK, SEC_I_CONTEXT_EXPIRED, and - // any other successful results as continue. - if (SUCCEEDED(status)) { - size_t data_len = 0, extra_len = 0; - for (size_t i=0; icBuffers; ++i) { - if (in_buf[i].BufferType == SECBUFFER_DATA) { - data_len += in_buf[i].cbBuffer; - readable.insert(readable.end(), - reinterpret_cast(in_buf[i].pvBuffer), - reinterpret_cast(in_buf[i].pvBuffer) + in_buf[i].cbBuffer); - } else if (in_buf[i].BufferType == SECBUFFER_EXTRA) { - extra_len += in_buf[i].cbBuffer; - } - } - // There is a bug on Win2K where SEC_I_CONTEXT_EXPIRED is misclassified. - if ((data_len == 0) && (inbuf[0] == 0x15)) { - status = SEC_I_CONTEXT_EXPIRED; - } - if (extra_len) { - size_t consumed = inbuf.size() - extra_len; - memmove(&inbuf[0], &inbuf[consumed], extra_len); - inbuf.resize(extra_len); - } else { - inbuf.clear(); - } - // TODO: Handle SEC_I_CONTEXT_EXPIRED to do clean shutdown - if (status != SEC_E_OK) { - LOG(LS_INFO) << "DecryptMessage returned continuation code: " - << ErrorName(status, SECURITY_ERRORS); - } - continue; - } - - if (status == SEC_E_INCOMPLETE_MESSAGE) { - break; - } else { - return status; - } - } - - return 0; -} - -void -SChannelAdapter::Cleanup() { - if (impl_->ctx_init) - DeleteSecurityContext(&impl_->ctx); - if (impl_->cred_init) - FreeCredentialsHandle(&impl_->cred); - delete impl_; -} - -void -SChannelAdapter::PostEvent() { - // Check if there's anything notable to signal - if (impl_->readable.empty() && !signal_close_) - return; - - // Only one post in the queue at a time - if (message_pending_) - return; - - if (Thread* thread = Thread::Current()) { - message_pending_ = true; - thread->Post(this); - } else { - LOG(LS_ERROR) << "No thread context available for SChannelAdapter"; - ASSERT(false); - } -} - -void -SChannelAdapter::Error(const char* context, int err, bool signal) { - LOG(LS_WARNING) << "SChannelAdapter::Error(" - << context << ", " - << ErrorName(err, SECURITY_ERRORS) << ")"; - state_ = SSL_ERROR; - SetError(err); - if (signal) - AsyncSocketAdapter::OnCloseEvent(this, err); -} - -int -SChannelAdapter::Read() { - char buffer[4096]; - SChannelBuffer& inbuf = impl_->inbuf; - while (true) { - int ret = AsyncSocketAdapter::Recv(buffer, sizeof(buffer)); - if (ret > 0) { - inbuf.insert(inbuf.end(), buffer, buffer + ret); - } else if (GetError() == EWOULDBLOCK) { - return 0; // Blocking - } else { - return GetError(); - } - } -} - -int -SChannelAdapter::Flush() { - int result = 0; - size_t pos = 0; - SChannelBuffer& outbuf = impl_->outbuf; - while (pos < outbuf.size()) { - int sent = AsyncSocketAdapter::Send(&outbuf[pos], outbuf.size() - pos); - if (sent > 0) { - pos += sent; - } else if (GetError() == EWOULDBLOCK) { - break; // Blocking - } else { - result = GetError(); - break; - } - } - if (int remainder = static_cast(outbuf.size() - pos)) { - memmove(&outbuf[0], &outbuf[pos], remainder); - outbuf.resize(remainder); - } else { - outbuf.clear(); - } - return result; -} - -// -// AsyncSocket Implementation -// - -int -SChannelAdapter::Send(const void* pv, size_t cb) { - switch (state_) { - case SSL_NONE: - return AsyncSocketAdapter::Send(pv, cb); - - case SSL_WAIT: - case SSL_CONNECTING: - SetError(EWOULDBLOCK); - return SOCKET_ERROR; - - case SSL_CONNECTED: - break; - - case SSL_ERROR: - default: - return SOCKET_ERROR; - } - - size_t written = 0; - SChannelBuffer& outbuf = impl_->outbuf; - while (written < cb) { - const size_t encrypt_len = std::min(cb - written, - impl_->sizes.cbMaximumMessage); - - CSecBufferBundle<4> out_buf; - out_buf[0].BufferType = SECBUFFER_STREAM_HEADER; - out_buf[0].cbBuffer = impl_->sizes.cbHeader; - out_buf[1].BufferType = SECBUFFER_DATA; - out_buf[1].cbBuffer = static_cast(encrypt_len); - out_buf[2].BufferType = SECBUFFER_STREAM_TRAILER; - out_buf[2].cbBuffer = impl_->sizes.cbTrailer; - - size_t packet_len = out_buf[0].cbBuffer - + out_buf[1].cbBuffer - + out_buf[2].cbBuffer; - - SChannelBuffer message; - message.resize(packet_len); - out_buf[0].pvBuffer = &message[0]; - out_buf[1].pvBuffer = &message[out_buf[0].cbBuffer]; - out_buf[2].pvBuffer = &message[out_buf[0].cbBuffer + out_buf[1].cbBuffer]; - - memcpy(out_buf[1].pvBuffer, - static_cast(pv) + written, - encrypt_len); - - //DescribeBuffers(LS_VERBOSE, "Encrypt In ", out_buf.desc()); - SECURITY_STATUS res = EncryptMessage(&impl_->ctx, 0, out_buf.desc(), 0); - //DescribeBuffers(LS_VERBOSE, "Encrypt Out ", out_buf.desc()); - - if (FAILED(res)) { - Error("EncryptMessage", res, false); - return SOCKET_ERROR; - } - - // We assume that the header and data segments do not change length, - // or else encrypting the concatenated packet in-place is wrong. - ASSERT(out_buf[0].cbBuffer == impl_->sizes.cbHeader); - ASSERT(out_buf[1].cbBuffer == static_cast(encrypt_len)); - - // However, the length of the trailer may change due to padding. - ASSERT(out_buf[2].cbBuffer <= impl_->sizes.cbTrailer); - - packet_len = out_buf[0].cbBuffer - + out_buf[1].cbBuffer - + out_buf[2].cbBuffer; - - written += encrypt_len; - outbuf.insert(outbuf.end(), &message[0], &message[packet_len-1]+1); - } - - if (int err = Flush()) { - state_ = SSL_ERROR; - SetError(err); - return SOCKET_ERROR; - } - - return static_cast(written); -} - -int -SChannelAdapter::Recv(void* pv, size_t cb) { - switch (state_) { - case SSL_NONE: - return AsyncSocketAdapter::Recv(pv, cb); - - case SSL_WAIT: - case SSL_CONNECTING: - SetError(EWOULDBLOCK); - return SOCKET_ERROR; - - case SSL_CONNECTED: - break; - - case SSL_ERROR: - default: - return SOCKET_ERROR; - } - - SChannelBuffer& readable = impl_->readable; - if (readable.empty()) { - SetError(EWOULDBLOCK); - return SOCKET_ERROR; - } - size_t read = _min(cb, readable.size()); - memcpy(pv, &readable[0], read); - if (size_t remaining = readable.size() - read) { - memmove(&readable[0], &readable[read], remaining); - readable.resize(remaining); - } else { - readable.clear(); - } - - PostEvent(); - return static_cast(read); -} - -int -SChannelAdapter::Close() { - if (!impl_->readable.empty()) { - LOG(WARNING) << "SChannelAdapter::Close with readable data"; - // Note: this isn't strictly an error, but we're using it temporarily to - // track bugs. - //ASSERT(false); - } - if (state_ == SSL_CONNECTED) { - DWORD token = SCHANNEL_SHUTDOWN; - CSecBufferBundle<1> sb_in; - sb_in[0].BufferType = SECBUFFER_TOKEN; - sb_in[0].cbBuffer = sizeof(token); - sb_in[0].pvBuffer = &token; - ApplyControlToken(&impl_->ctx, sb_in.desc()); - // TODO: In theory, to do a nice shutdown, we need to begin shutdown - // negotiation with more calls to InitializeSecurityContext. Since the - // socket api doesn't support nice shutdown at this point, we don't bother. - } - Cleanup(); - impl_ = new SSLImpl; - state_ = restartable_ ? SSL_WAIT : SSL_NONE; - signal_close_ = false; - message_pending_ = false; - return AsyncSocketAdapter::Close(); -} - -Socket::ConnState -SChannelAdapter::GetState() const { - if (signal_close_) - return CS_CONNECTED; - ConnState state = socket_->GetState(); - if ((state == CS_CONNECTED) - && ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING))) - state = CS_CONNECTING; - return state; -} - -void -SChannelAdapter::OnConnectEvent(AsyncSocket* socket) { - LOG(LS_VERBOSE) << "SChannelAdapter::OnConnectEvent"; - if (state_ != SSL_WAIT) { - ASSERT(state_ == SSL_NONE); - AsyncSocketAdapter::OnConnectEvent(socket); - return; - } - - state_ = SSL_CONNECTING; - if (int err = BeginSSL()) { - Error("BeginSSL", err); - } -} - -void -SChannelAdapter::OnReadEvent(AsyncSocket* socket) { - if (state_ == SSL_NONE) { - AsyncSocketAdapter::OnReadEvent(socket); - return; - } - - if (int err = Read()) { - Error("Read", err); - return; - } - - if (impl_->inbuf.empty()) - return; - - if (state_ == SSL_CONNECTED) { - if (int err = DecryptData()) { - Error("DecryptData", err); - } else if (!impl_->readable.empty()) { - AsyncSocketAdapter::OnReadEvent(this); - } - } else if (state_ == SSL_CONNECTING) { - if (int err = ContinueSSL()) { - Error("ContinueSSL", err); - } - } -} - -void -SChannelAdapter::OnWriteEvent(AsyncSocket* socket) { - if (state_ == SSL_NONE) { - AsyncSocketAdapter::OnWriteEvent(socket); - return; - } - - if (int err = Flush()) { - Error("Flush", err); - return; - } - - // See if we have more data to write - if (!impl_->outbuf.empty()) - return; - - // Buffer is empty, submit notification - if (state_ == SSL_CONNECTED) { - AsyncSocketAdapter::OnWriteEvent(socket); - } -} - -void -SChannelAdapter::OnCloseEvent(AsyncSocket* socket, int err) { - if ((state_ == SSL_NONE) || impl_->readable.empty()) { - AsyncSocketAdapter::OnCloseEvent(socket, err); - return; - } - - // If readable is non-empty, then we have a pending Message - // that will allow us to signal close (eventually). - signal_close_ = true; -} - -void -SChannelAdapter::OnMessage(Message* pmsg) { - if (!message_pending_) - return; // This occurs when socket is closed - - message_pending_ = false; - if (!impl_->readable.empty()) { - AsyncSocketAdapter::OnReadEvent(this); - } else if (signal_close_) { - signal_close_ = false; - AsyncSocketAdapter::OnCloseEvent(this, 0); // TODO: cache this error? - } -} - -} // namespace rtc diff --git a/webrtc/base/schanneladapter.h b/webrtc/base/schanneladapter.h deleted file mode 100644 index d174b593f..000000000 --- a/webrtc/base/schanneladapter.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SCHANNELADAPTER_H__ -#define WEBRTC_BASE_SCHANNELADAPTER_H__ - -#include -#include "webrtc/base/ssladapter.h" -#include "webrtc/base/messagequeue.h" -struct _SecBufferDesc; - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// - -class SChannelAdapter : public SSLAdapter, public MessageHandler { -public: - SChannelAdapter(AsyncSocket* socket); - virtual ~SChannelAdapter(); - - virtual int StartSSL(const char* hostname, bool restartable); - virtual int Send(const void* pv, size_t cb); - virtual int Recv(void* pv, size_t cb); - virtual int Close(); - - // Note that the socket returns ST_CONNECTING while SSL is being negotiated. - virtual ConnState GetState() const; - -protected: - enum SSLState { - SSL_NONE, SSL_WAIT, SSL_CONNECTING, SSL_CONNECTED, SSL_ERROR - }; - struct SSLImpl; - - virtual void OnConnectEvent(AsyncSocket* socket); - virtual void OnReadEvent(AsyncSocket* socket); - virtual void OnWriteEvent(AsyncSocket* socket); - virtual void OnCloseEvent(AsyncSocket* socket, int err); - virtual void OnMessage(Message* pmsg); - - int BeginSSL(); - int ContinueSSL(); - int ProcessContext(long int status, _SecBufferDesc* sbd_in, - _SecBufferDesc* sbd_out); - int DecryptData(); - - int Read(); - int Flush(); - void Error(const char* context, int err, bool signal = true); - void Cleanup(); - - void PostEvent(); - -private: - SSLState state_; - std::string ssl_host_name_; - // If true, socket will retain SSL configuration after Close. - bool restartable_; - // If true, we are delaying signalling close until all data is read. - bool signal_close_; - // If true, we are waiting to be woken up to signal readability or closure. - bool message_pending_; - SSLImpl* impl_; -}; - -///////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_SCHANNELADAPTER_H__ diff --git a/webrtc/base/scoped_autorelease_pool.h b/webrtc/base/scoped_autorelease_pool.h deleted file mode 100644 index d9cc3cb36..000000000 --- a/webrtc/base/scoped_autorelease_pool.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Automatically initialize and and free an autoreleasepool. Never allocate -// an instance of this class using "new" - that will result in a compile-time -// error. Only use it as a stack object. -// -// Note: NSAutoreleasePool docs say that you should not normally need to -// declare an NSAutoreleasePool as a member of an object - but there's nothing -// that indicates it will be a problem, as long as the stack lifetime of the -// pool exactly matches the stack lifetime of the object. - -#ifndef WEBRTC_BASE_SCOPED_AUTORELEASE_POOL_H__ -#define WEBRTC_BASE_SCOPED_AUTORELEASE_POOL_H__ - -#if defined(WEBRTC_MAC) - -#include "webrtc/base/common.h" - -// This header may be included from Obj-C files or C++ files. -#ifdef __OBJC__ -@class NSAutoreleasePool; -#else -class NSAutoreleasePool; -#endif - -namespace rtc { - -class ScopedAutoreleasePool { - public: - ScopedAutoreleasePool(); - ~ScopedAutoreleasePool(); - - private: - // Declaring private overrides of new and delete here enforces the "only use - // as a stack object" discipline. - // - // Note: new is declared as "throw()" to get around a gcc warning about new - // returning NULL, but this method will never get called and therefore will - // never actually throw any exception. - void* operator new(size_t size) throw() { return NULL; } - void operator delete (void* ptr) {} - - NSAutoreleasePool* pool_; - - DISALLOW_EVIL_CONSTRUCTORS(ScopedAutoreleasePool); -}; - -} // namespace rtc - -#endif // WEBRTC_MAC -#endif // WEBRTC_BASE_SCOPED_AUTORELEASE_POOL_H__ diff --git a/webrtc/base/scoped_autorelease_pool.mm b/webrtc/base/scoped_autorelease_pool.mm deleted file mode 100644 index 4176aad0e..000000000 --- a/webrtc/base/scoped_autorelease_pool.mm +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#import - -#import "webrtc/base/scoped_autorelease_pool.h" - -namespace rtc { - -ScopedAutoreleasePool::ScopedAutoreleasePool() { - pool_ = [[NSAutoreleasePool alloc] init]; -} - -ScopedAutoreleasePool::~ScopedAutoreleasePool() { - [pool_ drain]; -} - -} // namespace rtc diff --git a/webrtc/base/scoped_ptr.h b/webrtc/base/scoped_ptr.h deleted file mode 100644 index 0c0a637a2..000000000 --- a/webrtc/base/scoped_ptr.h +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Scopers help you manage ownership of a pointer, helping you easily manage the -// a pointer within a scope, and automatically destroying the pointer at the -// end of a scope. There are two main classes you will use, which correspond -// to the operators new/delete and new[]/delete[]. -// -// Example usage (scoped_ptr): -// { -// scoped_ptr foo(new Foo("wee")); -// } // foo goes out of scope, releasing the pointer with it. -// -// { -// scoped_ptr foo; // No pointer managed. -// foo.reset(new Foo("wee")); // Now a pointer is managed. -// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. -// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. -// foo->Method(); // Foo::Method() called. -// foo.get()->Method(); // Foo::Method() called. -// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer -// // manages a pointer. -// foo.reset(new Foo("wee4")); // foo manages a pointer again. -// foo.reset(); // Foo("wee4") destroyed, foo no longer -// // manages a pointer. -// } // foo wasn't managing a pointer, so nothing was destroyed. -// -// Example usage (scoped_ptr): -// { -// scoped_ptr foo(new Foo[100]); -// foo.get()->Method(); // Foo::Method on the 0th element. -// foo[10].Method(); // Foo::Method on the 10th element. -// } -// -// These scopers also implement part of the functionality of C++11 unique_ptr -// in that they are "movable but not copyable." You can use the scopers in -// the parameter and return types of functions to signify ownership transfer -// in to and out of a function. When calling a function that has a scoper -// as the argument type, it must be called with the result of an analogous -// scoper's Pass() function or another function that generates a temporary; -// passing by copy will NOT work. Here is an example using scoped_ptr: -// -// void TakesOwnership(scoped_ptr arg) { -// // Do something with arg -// } -// scoped_ptr CreateFoo() { -// // No need for calling Pass() because we are constructing a temporary -// // for the return value. -// return scoped_ptr(new Foo("new")); -// } -// scoped_ptr PassThru(scoped_ptr arg) { -// return arg.Pass(); -// } -// -// { -// scoped_ptr ptr(new Foo("yay")); // ptr manages Foo("yay"). -// TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay"). -// scoped_ptr ptr2 = CreateFoo(); // ptr2 owns the return Foo. -// scoped_ptr ptr3 = // ptr3 now owns what was in ptr2. -// PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL. -// } -// -// Notice that if you do not call Pass() when returning from PassThru(), or -// when invoking TakesOwnership(), the code will not compile because scopers -// are not copyable; they only implement move semantics which require calling -// the Pass() function to signify a destructive transfer of state. CreateFoo() -// is different though because we are constructing a temporary on the return -// line and thus can avoid needing to call Pass(). -// -// Pass() properly handles upcast in initialization, i.e. you can use a -// scoped_ptr to initialize a scoped_ptr: -// -// scoped_ptr foo(new Foo()); -// scoped_ptr parent(foo.Pass()); -// -// PassAs<>() should be used to upcast return value in return statement: -// -// scoped_ptr CreateFoo() { -// scoped_ptr result(new FooChild()); -// return result.PassAs(); -// } -// -// Note that PassAs<>() is implemented only for scoped_ptr, but not for -// scoped_ptr. This is because casting array pointers may not be safe. - -#ifndef WEBRTC_BASE_SCOPED_PTR_H__ -#define WEBRTC_BASE_SCOPED_PTR_H__ - -#include // for ptrdiff_t -#include // for free() decl - -#include // For std::swap(). - -#include "webrtc/base/common.h" // for ASSERT -#include "webrtc/base/compile_assert.h" // for COMPILE_ASSERT -#include "webrtc/base/move.h" // for TALK_MOVE_ONLY_TYPE_FOR_CPP_03 -#include "webrtc/base/template_util.h" // for is_convertible, is_array - -#ifdef WEBRTC_WIN -namespace std { using ::ptrdiff_t; }; -#endif // WEBRTC_WIN - -namespace rtc { - -// Function object which deletes its parameter, which must be a pointer. -// If C is an array type, invokes 'delete[]' on the parameter; otherwise, -// invokes 'delete'. The default deleter for scoped_ptr. -template -struct DefaultDeleter { - DefaultDeleter() {} - template DefaultDeleter(const DefaultDeleter& other) { - // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor - // if U* is implicitly convertible to T* and U is not an array type. - // - // Correct implementation should use SFINAE to disable this - // constructor. However, since there are no other 1-argument constructors, - // using a COMPILE_ASSERT() based on is_convertible<> and requiring - // complete types is simpler and will cause compile failures for equivalent - // misuses. - // - // Note, the is_convertible check also ensures that U is not an - // array. T is guaranteed to be a non-array, so any U* where U is an array - // cannot convert to T*. - enum { T_must_be_complete = sizeof(T) }; - enum { U_must_be_complete = sizeof(U) }; - COMPILE_ASSERT((rtc::is_convertible::value), - U_ptr_must_implicitly_convert_to_T_ptr); - } - inline void operator()(T* ptr) const { - enum { type_must_be_complete = sizeof(T) }; - delete ptr; - } -}; - -// Specialization of DefaultDeleter for array types. -template -struct DefaultDeleter { - inline void operator()(T* ptr) const { - enum { type_must_be_complete = sizeof(T) }; - delete[] ptr; - } - - private: - // Disable this operator for any U != T because it is undefined to execute - // an array delete when the static type of the array mismatches the dynamic - // type. - // - // References: - // C++98 [expr.delete]p3 - // http://cplusplus.github.com/LWG/lwg-defects.html#938 - template void operator()(U* array) const; -}; - -template -struct DefaultDeleter { - // Never allow someone to declare something like scoped_ptr. - COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type); -}; - -// Function object which invokes 'free' on its parameter, which must be -// a pointer. Can be used to store malloc-allocated pointers in scoped_ptr: -// -// scoped_ptr foo_ptr( -// static_cast(malloc(sizeof(int)))); -struct FreeDeleter { - inline void operator()(void* ptr) const { - free(ptr); - } -}; - -namespace internal { - -// Minimal implementation of the core logic of scoped_ptr, suitable for -// reuse in both scoped_ptr and its specializations. -template -class scoped_ptr_impl { - public: - explicit scoped_ptr_impl(T* p) : data_(p) { } - - // Initializer for deleters that have data parameters. - scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} - - // Templated constructor that destructively takes the value from another - // scoped_ptr_impl. - template - scoped_ptr_impl(scoped_ptr_impl* other) - : data_(other->release(), other->get_deleter()) { - // We do not support move-only deleters. We could modify our move - // emulation to have rtc::subtle::move() and - // rtc::subtle::forward() - // functions that are imperfect emulations of their C++11 equivalents, - // but until there's a requirement, just assume deleters are copyable. - } - - template - void TakeState(scoped_ptr_impl* other) { - // See comment in templated constructor above regarding lack of support - // for move-only deleters. - reset(other->release()); - get_deleter() = other->get_deleter(); - } - - ~scoped_ptr_impl() { - if (data_.ptr != NULL) { - // Not using get_deleter() saves one function call in non-optimized - // builds. - static_cast(data_)(data_.ptr); - } - } - - void reset(T* p) { - // This is a self-reset, which is no longer allowed: http://crbug.com/162971 - if (p != NULL && p == data_.ptr) - abort(); - - // Note that running data_.ptr = p can lead to undefined behavior if - // get_deleter()(get()) deletes this. In order to pevent this, reset() - // should update the stored pointer before deleting its old value. - // - // However, changing reset() to use that behavior may cause current code to - // break in unexpected ways. If the destruction of the owned object - // dereferences the scoped_ptr when it is destroyed by a call to reset(), - // then it will incorrectly dispatch calls to |p| rather than the original - // value of |data_.ptr|. - // - // During the transition period, set the stored pointer to NULL while - // deleting the object. Eventually, this safety check will be removed to - // prevent the scenario initially described from occuring and - // http://crbug.com/176091 can be closed. - T* old = data_.ptr; - data_.ptr = NULL; - if (old != NULL) - static_cast(data_)(old); - data_.ptr = p; - } - - T* get() const { return data_.ptr; } - - D& get_deleter() { return data_; } - const D& get_deleter() const { return data_; } - - void swap(scoped_ptr_impl& p2) { - // Standard swap idiom: 'using std::swap' ensures that std::swap is - // present in the overload set, but we call swap unqualified so that - // any more-specific overloads can be used, if available. - using std::swap; - swap(static_cast(data_), static_cast(p2.data_)); - swap(data_.ptr, p2.data_.ptr); - } - - T* release() { - T* old_ptr = data_.ptr; - data_.ptr = NULL; - return old_ptr; - } - - T** accept() { - reset(NULL); - return &(data_.ptr); - } - - T** use() { - return &(data_.ptr); - } - - private: - // Needed to allow type-converting constructor. - template friend class scoped_ptr_impl; - - // Use the empty base class optimization to allow us to have a D - // member, while avoiding any space overhead for it when D is an - // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good - // discussion of this technique. - struct Data : public D { - explicit Data(T* ptr_in) : ptr(ptr_in) {} - Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} - T* ptr; - }; - - Data data_; - - DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); -}; - -} // namespace internal - -// A scoped_ptr is like a T*, except that the destructor of scoped_ptr -// automatically deletes the pointer it holds (if any). -// That is, scoped_ptr owns the T object that it points to. -// Like a T*, a scoped_ptr may hold either NULL or a pointer to a T object. -// Also like T*, scoped_ptr is thread-compatible, and once you -// dereference it, you get the thread safety guarantees of T. -// -// The size of scoped_ptr is small. On most compilers, when using the -// DefaultDeleter, sizeof(scoped_ptr) == sizeof(T*). Custom deleters will -// increase the size proportional to whatever state they need to have. See -// comments inside scoped_ptr_impl<> for details. -// -// Current implementation targets having a strict subset of C++11's -// unique_ptr<> features. Known deficiencies include not supporting move-only -// deleteres, function pointers as deleters, and deleters with reference -// types. -template > -class scoped_ptr { - TALK_MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) - - public: - // The element and deleter types. - typedef T element_type; - typedef D deleter_type; - - // Constructor. Defaults to initializing with NULL. - scoped_ptr() : impl_(NULL) { } - - // Constructor. Takes ownership of p. - explicit scoped_ptr(element_type* p) : impl_(p) { } - - // Constructor. Allows initialization of a stateful deleter. - scoped_ptr(element_type* p, const D& d) : impl_(p, d) { } - - // Constructor. Allows construction from a scoped_ptr rvalue for a - // convertible type and deleter. - // - // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct - // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor - // has different post-conditions if D is a reference type. Since this - // implementation does not support deleters with reference type, - // we do not need a separate move constructor allowing us to avoid one - // use of SFINAE. You only need to care about this if you modify the - // implementation of scoped_ptr. - template - scoped_ptr(scoped_ptr other) : impl_(&other.impl_) { - COMPILE_ASSERT(!rtc::is_array::value, U_cannot_be_an_array); - } - - // Constructor. Move constructor for C++03 move emulation of this type. - scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } - - // operator=. Allows assignment from a scoped_ptr rvalue for a convertible - // type and deleter. - // - // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from - // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated - // form has different requirements on for move-only Deleters. Since this - // implementation does not support move-only Deleters, we do not need a - // separate move assignment operator allowing us to avoid one use of SFINAE. - // You only need to care about this if you modify the implementation of - // scoped_ptr. - template - scoped_ptr& operator=(scoped_ptr rhs) { - COMPILE_ASSERT(!rtc::is_array::value, U_cannot_be_an_array); - impl_.TakeState(&rhs.impl_); - return *this; - } - - // Reset. Deletes the currently owned object, if any. - // Then takes ownership of a new object, if given. - void reset(element_type* p = NULL) { impl_.reset(p); } - - // Accessors to get the owned object. - // operator* and operator-> will assert() if there is no current object. - element_type& operator*() const { - ASSERT(impl_.get() != NULL); - return *impl_.get(); - } - element_type* operator->() const { - ASSERT(impl_.get() != NULL); - return impl_.get(); - } - element_type* get() const { return impl_.get(); } - - // Access to the deleter. - deleter_type& get_deleter() { return impl_.get_deleter(); } - const deleter_type& get_deleter() const { return impl_.get_deleter(); } - - // Allow scoped_ptr to be used in boolean expressions, but not - // implicitly convertible to a real bool (which is dangerous). - // - // Note that this trick is only safe when the == and != operators - // are declared explicitly, as otherwise "scoped_ptr1 == - // scoped_ptr2" will compile but do the wrong thing (i.e., convert - // to Testable and then do the comparison). - private: - typedef rtc::internal::scoped_ptr_impl - scoped_ptr::*Testable; - - public: - operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } - - // Comparison operators. - // These return whether two scoped_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(const element_type* p) const { return impl_.get() == p; } - bool operator!=(const element_type* p) const { return impl_.get() != p; } - - // Swap two scoped pointers. - void swap(scoped_ptr& p2) { - impl_.swap(p2.impl_); - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - element_type* release() WARN_UNUSED_RESULT { - return impl_.release(); - } - - // Delete the currently held pointer and return a pointer - // to allow overwriting of the current pointer address. - element_type** accept() WARN_UNUSED_RESULT { - return impl_.accept(); - } - - // Return a pointer to the current pointer address. - element_type** use() WARN_UNUSED_RESULT { - return impl_.use(); - } - - // C++98 doesn't support functions templates with default parameters which - // makes it hard to write a PassAs() that understands converting the deleter - // while preserving simple calling semantics. - // - // Until there is a use case for PassAs() with custom deleters, just ignore - // the custom deleter. - template - scoped_ptr PassAs() { - return scoped_ptr(Pass()); - } - - private: - // Needed to reach into |impl_| in the constructor. - template friend class scoped_ptr; - rtc::internal::scoped_ptr_impl impl_; - - // Forbidden for API compatibility with std::unique_ptr. - explicit scoped_ptr(int disallow_construction_from_null); - - // Forbid comparison of scoped_ptr types. If U != T, it totally - // doesn't make sense, and if U == T, it still doesn't make sense - // because you should never have the same object owned by two different - // scoped_ptrs. - template bool operator==(scoped_ptr const& p2) const; - template bool operator!=(scoped_ptr const& p2) const; -}; - -template -class scoped_ptr { - TALK_MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) - - public: - // The element and deleter types. - typedef T element_type; - typedef D deleter_type; - - // Constructor. Defaults to initializing with NULL. - scoped_ptr() : impl_(NULL) { } - - // Constructor. Stores the given array. Note that the argument's type - // must exactly match T*. In particular: - // - it cannot be a pointer to a type derived from T, because it is - // inherently unsafe in the general case to access an array through a - // pointer whose dynamic type does not match its static type (eg., if - // T and the derived types had different sizes access would be - // incorrectly calculated). Deletion is also always undefined - // (C++98 [expr.delete]p3). If you're doing this, fix your code. - // - it cannot be NULL, because NULL is an integral expression, not a - // pointer to T. Use the no-argument version instead of explicitly - // passing NULL. - // - it cannot be const-qualified differently from T per unique_ptr spec - // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting - // to work around this may use implicit_cast(). - // However, because of the first bullet in this comment, users MUST - // NOT use implicit_cast() to upcast the static type of the array. - explicit scoped_ptr(element_type* array) : impl_(array) { } - - // Constructor. Move constructor for C++03 move emulation of this type. - scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } - - // operator=. Move operator= for C++03 move emulation of this type. - scoped_ptr& operator=(RValue rhs) { - impl_.TakeState(&rhs.object->impl_); - return *this; - } - - // Reset. Deletes the currently owned array, if any. - // Then takes ownership of a new object, if given. - void reset(element_type* array = NULL) { impl_.reset(array); } - - // Accessors to get the owned array. - element_type& operator[](size_t i) const { - ASSERT(impl_.get() != NULL); - return impl_.get()[i]; - } - element_type* get() const { return impl_.get(); } - - // Access to the deleter. - deleter_type& get_deleter() { return impl_.get_deleter(); } - const deleter_type& get_deleter() const { return impl_.get_deleter(); } - - // Allow scoped_ptr to be used in boolean expressions, but not - // implicitly convertible to a real bool (which is dangerous). - private: - typedef rtc::internal::scoped_ptr_impl - scoped_ptr::*Testable; - - public: - operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } - - // Comparison operators. - // These return whether two scoped_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(element_type* array) const { return impl_.get() == array; } - bool operator!=(element_type* array) const { return impl_.get() != array; } - - // Swap two scoped pointers. - void swap(scoped_ptr& p2) { - impl_.swap(p2.impl_); - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - element_type* release() WARN_UNUSED_RESULT { - return impl_.release(); - } - - // Delete the currently held pointer and return a pointer - // to allow overwriting of the current pointer address. - element_type** accept() WARN_UNUSED_RESULT { - return impl_.accept(); - } - - // Return a pointer to the current pointer address. - element_type** use() WARN_UNUSED_RESULT { - return impl_.use(); - } - - private: - // Force element_type to be a complete type. - enum { type_must_be_complete = sizeof(element_type) }; - - // Actually hold the data. - rtc::internal::scoped_ptr_impl impl_; - - // Disable initialization from any type other than element_type*, by - // providing a constructor that matches such an initialization, but is - // private and has no definition. This is disabled because it is not safe to - // call delete[] on an array whose static type does not match its dynamic - // type. - template explicit scoped_ptr(U* array); - explicit scoped_ptr(int disallow_construction_from_null); - - // Disable reset() from any type other than element_type*, for the same - // reasons as the constructor above. - template void reset(U* array); - void reset(int disallow_reset_from_null); - - // Forbid comparison of scoped_ptr types. If U != T, it totally - // doesn't make sense, and if U == T, it still doesn't make sense - // because you should never have the same object owned by two different - // scoped_ptrs. - template bool operator==(scoped_ptr const& p2) const; - template bool operator!=(scoped_ptr const& p2) const; -}; - -} // namespace rtc - -// Free functions -template -void swap(rtc::scoped_ptr& p1, rtc::scoped_ptr& p2) { - p1.swap(p2); -} - -template -bool operator==(T* p1, const rtc::scoped_ptr& p2) { - return p1 == p2.get(); -} - -template -bool operator!=(T* p1, const rtc::scoped_ptr& p2) { - return p1 != p2.get(); -} - -#endif // #ifndef WEBRTC_BASE_SCOPED_PTR_H__ diff --git a/webrtc/base/scoped_ref_ptr.h b/webrtc/base/scoped_ref_ptr.h deleted file mode 100644 index a71c20ae3..000000000 --- a/webrtc/base/scoped_ref_ptr.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Originally these classes are from Chromium. -// http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/ref_counted.h?view=markup - -// -// A smart pointer class for reference counted objects. Use this class instead -// of calling AddRef and Release manually on a reference counted object to -// avoid common memory leaks caused by forgetting to Release an object -// reference. Sample usage: -// -// class MyFoo : public RefCounted { -// ... -// }; -// -// void some_function() { -// scoped_refptr foo = new MyFoo(); -// foo->Method(param); -// // |foo| is released when this function returns -// } -// -// void some_other_function() { -// scoped_refptr foo = new MyFoo(); -// ... -// foo = NULL; // explicitly releases |foo| -// ... -// if (foo) -// foo->Method(param); -// } -// -// The above examples show how scoped_refptr acts like a pointer to T. -// Given two scoped_refptr classes, it is also possible to exchange -// references between the two objects, like so: -// -// { -// scoped_refptr a = new MyFoo(); -// scoped_refptr b; -// -// b.swap(a); -// // now, |b| references the MyFoo object, and |a| references NULL. -// } -// -// To make both |a| and |b| in the above example reference the same MyFoo -// object, simply use the assignment operator: -// -// { -// scoped_refptr a = new MyFoo(); -// scoped_refptr b; -// -// b = a; -// // now, |a| and |b| each own a reference to the same MyFoo object. -// } -// - -#ifndef WEBRTC_BASE_SCOPED_REF_PTR_H_ -#define WEBRTC_BASE_SCOPED_REF_PTR_H_ - -#include - -namespace rtc { - -template -class scoped_refptr { - public: - scoped_refptr() : ptr_(NULL) { - } - - scoped_refptr(T* p) : ptr_(p) { - if (ptr_) - ptr_->AddRef(); - } - - scoped_refptr(const scoped_refptr& r) : ptr_(r.ptr_) { - if (ptr_) - ptr_->AddRef(); - } - - template - scoped_refptr(const scoped_refptr& r) : ptr_(r.get()) { - if (ptr_) - ptr_->AddRef(); - } - - ~scoped_refptr() { - if (ptr_) - ptr_->Release(); - } - - T* get() const { return ptr_; } - operator T*() const { return ptr_; } - T* operator->() const { return ptr_; } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - T* release() { - T* retVal = ptr_; - ptr_ = NULL; - return retVal; - } - - scoped_refptr& operator=(T* p) { - // AddRef first so that self assignment should work - if (p) - p->AddRef(); - if (ptr_ ) - ptr_ ->Release(); - ptr_ = p; - return *this; - } - - scoped_refptr& operator=(const scoped_refptr& r) { - return *this = r.ptr_; - } - - template - scoped_refptr& operator=(const scoped_refptr& r) { - return *this = r.get(); - } - - void swap(T** pp) { - T* p = ptr_; - ptr_ = *pp; - *pp = p; - } - - void swap(scoped_refptr& r) { - swap(&r.ptr_); - } - - protected: - T* ptr_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SCOPED_REF_PTR_H_ diff --git a/webrtc/base/scopedptrcollection.h b/webrtc/base/scopedptrcollection.h deleted file mode 100644 index 47dff6503..000000000 --- a/webrtc/base/scopedptrcollection.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Stores a collection of pointers that are deleted when the container is -// destructed. - -#ifndef WEBRTC_BASE_SCOPEDPTRCOLLECTION_H_ -#define WEBRTC_BASE_SCOPEDPTRCOLLECTION_H_ - -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/constructormagic.h" - -namespace rtc { - -template -class ScopedPtrCollection { - public: - typedef std::vector 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 rtc - -#endif // WEBRTC_BASE_SCOPEDPTRCOLLECTION_H_ diff --git a/webrtc/base/scopedptrcollection_unittest.cc b/webrtc/base/scopedptrcollection_unittest.cc deleted file mode 100644 index 30b8ed9ed..000000000 --- a/webrtc/base/scopedptrcollection_unittest.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2014 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/scopedptrcollection.h" -#include "webrtc/base/gunit.h" - -namespace rtc { - -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()) { - } - - int num_instances_; - scoped_ptr > 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(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 rtc diff --git a/webrtc/base/sec_buffer.h b/webrtc/base/sec_buffer.h deleted file mode 100644 index d4cda00d4..000000000 --- a/webrtc/base/sec_buffer.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// @file Contains utility classes that make it easier to use SecBuffers - -#ifndef WEBRTC_BASE_SEC_BUFFER_H__ -#define WEBRTC_BASE_SEC_BUFFER_H__ - -namespace rtc { - -// A base class for CSecBuffer. Contains -// all implementation that does not require -// template arguments. -class CSecBufferBase : public SecBuffer { - public: - CSecBufferBase() { - Clear(); - } - - // Uses the SSPI to free a pointer, must be - // used for buffers returned from SSPI APIs. - static void FreeSSPI(void *ptr) { - if ( ptr ) { - SECURITY_STATUS status; - status = ::FreeContextBuffer(ptr); - ASSERT(SEC_E_OK == status); // "Freeing context buffer" - } - } - - // Deletes a buffer with operator delete - static void FreeDelete(void *ptr) { - delete [] reinterpret_cast(ptr); - } - - // A noop delete, for buffers over other - // people's memory - static void FreeNone(void *ptr) { - } - - protected: - // Clears the buffer to EMPTY & NULL - void Clear() { - this->BufferType = SECBUFFER_EMPTY; - this->cbBuffer = 0; - this->pvBuffer = NULL; - } -}; - -// Wrapper class for SecBuffer to take care -// of initialization and destruction. -template -class CSecBuffer: public CSecBufferBase { - public: - // Initializes buffer to empty & NULL - CSecBuffer() { - } - - // Frees any allocated memory - ~CSecBuffer() { - Release(); - } - - // Frees the buffer appropriately, and re-nulls - void Release() { - pfnFreeBuffer(this->pvBuffer); - Clear(); - } - - private: - // A placeholder function for compile-time asserts on the class - void CompileAsserts() { - // never invoked... - assert(false); // _T("Notreached") - - // This class must not extend the size of SecBuffer, since - // we use arrays of CSecBuffer in CSecBufferBundle below - cassert(sizeof(CSecBuffer == sizeof(SecBuffer))); - } -}; - -// Contains all generic implementation for the -// SecBufferBundle class -class SecBufferBundleBase { - public: -}; - -// A template class that bundles a SecBufferDesc with -// one or more SecBuffers for convenience. Can take -// care of deallocating buffers appropriately, as indicated -// by pfnFreeBuffer function. -// By default does no deallocation. -template -class CSecBufferBundle : public SecBufferBundleBase { - public: - // Constructs a security buffer bundle with num_buffers - // buffers, all of which are empty and nulled. - CSecBufferBundle() { - desc_.ulVersion = SECBUFFER_VERSION; - desc_.cBuffers = num_buffers; - desc_.pBuffers = buffers_; - } - - // Frees all currently used buffers. - ~CSecBufferBundle() { - Release(); - } - - // Accessor for the descriptor - PSecBufferDesc desc() { - return &desc_; - } - - // Accessor for the descriptor - const PSecBufferDesc desc() const { - return &desc_; - } - - // returns the i-th security buffer - SecBuffer &operator[] (size_t num) { - ASSERT(num < num_buffers); // "Buffer index out of bounds" - return buffers_[num]; - } - - // returns the i-th security buffer - const SecBuffer &operator[] (size_t num) const { - ASSERT(num < num_buffers); // "Buffer index out of bounds" - return buffers_[num]; - } - - // Frees all non-NULL security buffers, - // using the deallocation function - void Release() { - for ( size_t i = 0; i < num_buffers; ++i ) { - buffers_[i].Release(); - } - } - - private: - // Our descriptor - SecBufferDesc desc_; - // Our bundled buffers, each takes care of its own - // initialization and destruction - CSecBuffer buffers_[num_buffers]; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SEC_BUFFER_H__ diff --git a/webrtc/base/sha1.cc b/webrtc/base/sha1.cc deleted file mode 100644 index 8f8bd3d4a..000000000 --- a/webrtc/base/sha1.cc +++ /dev/null @@ -1,282 +0,0 @@ -/* - * SHA-1 in C - * By Steve Reid - * 100% Public Domain - * - * ----------------- - * Modified 7/98 - * By James H. Brown - * Still 100% Public Domain - * - * Corrected a problem which generated improper hash values on 16 bit machines - * Routine SHA1Update changed from - * void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int - * len) - * to - * void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned - * long len) - * - * The 'len' parameter was declared an int which works fine on 32 bit machines. - * However, on 16 bit machines an int is too small for the shifts being done - * against - * it. This caused the hash function to generate incorrect values if len was - * greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). - * - * Since the file IO in main() reads 16K at a time, any file 8K or larger would - * be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million - * "a"s). - * - * I also changed the declaration of variables i & j in SHA1Update to - * unsigned long from unsigned int for the same reason. - * - * These changes should make no difference to any 32 bit implementations since - * an - * int and a long are the same size in those environments. - * - * -- - * I also corrected a few compiler warnings generated by Borland C. - * 1. Added #include for exit() prototype - * 2. Removed unused variable 'j' in SHA1Final - * 3. Changed exit(0) to return(0) at end of main. - * - * ALL changes I made can be located by searching for comments containing 'JHB' - * ----------------- - * Modified 8/98 - * By Steve Reid - * Still 100% public domain - * - * 1- Removed #include and used return() instead of exit() - * 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) - * 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net - * - * ----------------- - * Modified 4/01 - * By Saul Kravitz - * Still 100% PD - * Modified to run on Compaq Alpha hardware. - * - * ----------------- - * Modified 07/2002 - * By Ralph Giles - * Still 100% public domain - * modified for use with stdint types, autoconf - * code cleanup, removed attribution comments - * switched SHA1Final() argument order for consistency - * use SHA1_ prefix for public api - * move public api to sha1.h - * - * ----------------- - * Modified 02/2012 - * By Justin Uberti - * Remove underscore from SHA1 prefix to avoid conflict with OpenSSL - * Remove test code - * Untabify - * - * ----------------- - * Modified 03/2012 - * By Ronghua Wu - * Change the typedef of uint32(8)_t to uint32(8). We need this because in the - * chromium android build, the stdio.h will include stdint.h which already - * defined uint32(8)_t. - * - * ----------------- - * Modified 04/2012 - * By Frank Barchard - * Ported to C++, Google style, change len to size_t, enable SHA1HANDSOFF - * - * Test Vectors (from FIPS PUB 180-1) - * "abc" - * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D - * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 - * A million repetitions of "a" - * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F - */ - -// Enabling SHA1HANDSOFF preserves the caller's data buffer. -// Disabling SHA1HANDSOFF the buffer will be modified (end swapped). -#define SHA1HANDSOFF - -#include "webrtc/base/sha1.h" - -#include -#include - -void SHA1Transform(uint32 state[5], const uint8 buffer[64]); - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -// blk0() and blk() perform the initial expand. -// I got the idea of expanding during the round function from SSLeay -// FIXME: can we do this in an endian-proof way? -#ifdef ARCH_CPU_BIG_ENDIAN -#define blk0(i) block->l[i] -#else -#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \ - (rol(block->l[i], 8) & 0x00FF00FF)) -#endif -#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \ - block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1)) - -// (R0+R1), R2, R3, R4 are the different operations used in SHA1. -#define R0(v, w, x, y, z, i) \ - z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ - w = rol(w, 30); -#define R1(v, w, x, y, z, i) \ - z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ - w = rol(w, 30); -#define R2(v, w, x, y, z, i) \ - z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5);\ - w = rol(w, 30); -#define R3(v, w, x, y, z, i) \ - z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ - w = rol(w, 30); -#define R4(v, w, x, y, z, i) \ - z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ - w = rol(w, 30); - -#ifdef VERBOSE // SAK -void SHAPrintContext(SHA1_CTX *context, char *msg) { - printf("%s (%d,%d) %x %x %x %x %x\n", - msg, - context->count[0], context->count[1], - context->state[0], - context->state[1], - context->state[2], - context->state[3], - context->state[4]); -} -#endif /* VERBOSE */ - -// Hash a single 512-bit block. This is the core of the algorithm. -void SHA1Transform(uint32 state[5], const uint8 buffer[64]) { - union CHAR64LONG16 { - uint8 c[64]; - uint32 l[16]; - }; -#ifdef SHA1HANDSOFF - static uint8 workspace[64]; - memcpy(workspace, buffer, 64); - CHAR64LONG16* block = reinterpret_cast(workspace); -#else - // Note(fbarchard): This option does modify the user's data buffer. - CHAR64LONG16* block = const_cast( - reinterpret_cast(buffer)); -#endif - - // Copy context->state[] to working vars. - uint32 a = state[0]; - uint32 b = state[1]; - uint32 c = state[2]; - uint32 d = state[3]; - uint32 e = state[4]; - - // 4 rounds of 20 operations each. Loop unrolled. - // Note(fbarchard): The following has lint warnings for multiple ; on - // a line and no space after , but is left as-is to be similar to the - // original code. - R0(a,b,c,d,e,0); R0(e,a,b,c,d,1); R0(d,e,a,b,c,2); R0(c,d,e,a,b,3); - R0(b,c,d,e,a,4); R0(a,b,c,d,e,5); R0(e,a,b,c,d,6); R0(d,e,a,b,c,7); - R0(c,d,e,a,b,8); R0(b,c,d,e,a,9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - - // Add the working vars back into context.state[]. - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; -} - -// SHA1Init - Initialize new context. -void SHA1Init(SHA1_CTX* context) { - // SHA1 initialization constants. - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - -// Run your data through this. -void SHA1Update(SHA1_CTX* context, const uint8* data, size_t input_len) { - size_t i = 0; - -#ifdef VERBOSE - SHAPrintContext(context, "before"); -#endif - - // Compute number of bytes mod 64. - size_t index = (context->count[0] >> 3) & 63; - - // Update number of bits. - // TODO: Use uint64 instead of 2 uint32 for count. - // count[0] has low 29 bits for byte count + 3 pad 0's making 32 bits for - // bit count. - // Add bit count to low uint32 - context->count[0] += static_cast(input_len << 3); - if (context->count[0] < static_cast(input_len << 3)) { - ++context->count[1]; // if overlow (carry), add one to high word - } - context->count[1] += static_cast(input_len >> 29); - if ((index + input_len) > 63) { - i = 64 - index; - memcpy(&context->buffer[index], data, i); - SHA1Transform(context->state, context->buffer); - for (; i + 63 < input_len; i += 64) { - SHA1Transform(context->state, data + i); - } - index = 0; - } - memcpy(&context->buffer[index], &data[i], input_len - i); - -#ifdef VERBOSE - SHAPrintContext(context, "after "); -#endif -} - -// Add padding and return the message digest. -void SHA1Final(SHA1_CTX* context, uint8 digest[SHA1_DIGEST_SIZE]) { - uint8 finalcount[8]; - for (int i = 0; i < 8; ++i) { - // Endian independent - finalcount[i] = static_cast( - (context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8) ) & 255); - } - SHA1Update(context, reinterpret_cast("\200"), 1); - while ((context->count[0] & 504) != 448) { - SHA1Update(context, reinterpret_cast("\0"), 1); - } - SHA1Update(context, finalcount, 8); // Should cause a SHA1Transform(). - for (int i = 0; i < SHA1_DIGEST_SIZE; ++i) { - digest[i] = static_cast( - (context->state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255); - } - - // Wipe variables. - memset(context->buffer, 0, 64); - memset(context->state, 0, 20); - memset(context->count, 0, 8); - memset(finalcount, 0, 8); // SWR - -#ifdef SHA1HANDSOFF // Make SHA1Transform overwrite its own static vars. - SHA1Transform(context->state, context->buffer); -#endif -} diff --git a/webrtc/base/sha1.h b/webrtc/base/sha1.h deleted file mode 100644 index b19c6592e..000000000 --- a/webrtc/base/sha1.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * SHA-1 in C - * By Steve Reid - * 100% Public Domain - * -*/ - -// Ported to C++, Google style and uses basictypes.h - -#ifndef WEBRTC_BASE_SHA1_H_ -#define WEBRTC_BASE_SHA1_H_ - -#include "webrtc/base/basictypes.h" - -struct SHA1_CTX { - uint32 state[5]; - // TODO: Change bit count to uint64. - uint32 count[2]; // Bit count of input. - uint8 buffer[64]; -}; - -#define SHA1_DIGEST_SIZE 20 - -void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, const uint8* data, size_t len); -void SHA1Final(SHA1_CTX* context, uint8 digest[SHA1_DIGEST_SIZE]); - -#endif // WEBRTC_BASE_SHA1_H_ diff --git a/webrtc/base/sha1digest.h b/webrtc/base/sha1digest.h deleted file mode 100644 index fb4c53e6e..000000000 --- a/webrtc/base/sha1digest.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SHA1DIGEST_H_ -#define WEBRTC_BASE_SHA1DIGEST_H_ - -#include "webrtc/base/messagedigest.h" -#include "webrtc/base/sha1.h" - -namespace rtc { - -// A simple wrapper for our SHA-1 implementation. -class Sha1Digest : public MessageDigest { - public: - enum { kSize = SHA1_DIGEST_SIZE }; - Sha1Digest() { - SHA1Init(&ctx_); - } - virtual size_t Size() const { - return kSize; - } - virtual void Update(const void* buf, size_t len) { - SHA1Update(&ctx_, static_cast(buf), len); - } - virtual size_t Finish(void* buf, size_t len) { - if (len < kSize) { - return 0; - } - SHA1Final(&ctx_, static_cast(buf)); - SHA1Init(&ctx_); // Reset for next use. - return kSize; - } - - private: - SHA1_CTX ctx_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SHA1DIGEST_H_ diff --git a/webrtc/base/sha1digest_unittest.cc b/webrtc/base/sha1digest_unittest.cc deleted file mode 100644 index d3c204387..000000000 --- a/webrtc/base/sha1digest_unittest.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/sha1digest.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/stringencode.h" - -namespace rtc { - -std::string Sha1(const std::string& input) { - Sha1Digest sha1; - return ComputeDigest(&sha1, input); -} - -TEST(Sha1DigestTest, TestSize) { - Sha1Digest sha1; - EXPECT_EQ(20, static_cast(Sha1Digest::kSize)); - EXPECT_EQ(20U, sha1.Size()); -} - -TEST(Sha1DigestTest, TestBasic) { - // Test vectors from sha1.c. - EXPECT_EQ("da39a3ee5e6b4b0d3255bfef95601890afd80709", Sha1("")); - EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", Sha1("abc")); - EXPECT_EQ("84983e441c3bd26ebaae4aa1f95129e5e54670f1", - Sha1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")); - std::string a_million_as(1000000, 'a'); - EXPECT_EQ("34aa973cd4c4daa4f61eeb2bdbad27316534016f", Sha1(a_million_as)); -} - -TEST(Sha1DigestTest, TestMultipleUpdates) { - Sha1Digest sha1; - std::string input = - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; - char output[Sha1Digest::kSize]; - for (size_t i = 0; i < input.size(); ++i) { - sha1.Update(&input[i], 1); - } - EXPECT_EQ(sha1.Size(), sha1.Finish(output, sizeof(output))); - EXPECT_EQ("84983e441c3bd26ebaae4aa1f95129e5e54670f1", - hex_encode(output, sizeof(output))); -} - -TEST(Sha1DigestTest, TestReuse) { - Sha1Digest sha1; - std::string input = "abc"; - EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", - ComputeDigest(&sha1, input)); - input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; - EXPECT_EQ("84983e441c3bd26ebaae4aa1f95129e5e54670f1", - ComputeDigest(&sha1, input)); -} - -TEST(Sha1DigestTest, TestBufferTooSmall) { - Sha1Digest sha1; - std::string input = "abcdefghijklmnopqrstuvwxyz"; - char output[Sha1Digest::kSize - 1]; - sha1.Update(input.c_str(), input.size()); - EXPECT_EQ(0U, sha1.Finish(output, sizeof(output))); -} - -TEST(Sha1DigestTest, TestBufferConst) { - Sha1Digest sha1; - const int kLongSize = 1000000; - std::string input(kLongSize, '\0'); - for (int i = 0; i < kLongSize; ++i) { - input[i] = static_cast(i); - } - sha1.Update(input.c_str(), input.size()); - for (int i = 0; i < kLongSize; ++i) { - EXPECT_EQ(static_cast(i), input[i]); - } -} - -} // namespace rtc diff --git a/webrtc/base/sharedexclusivelock.cc b/webrtc/base/sharedexclusivelock.cc deleted file mode 100644 index 9facf60ea..000000000 --- a/webrtc/base/sharedexclusivelock.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/sharedexclusivelock.h" - -namespace rtc { - -SharedExclusiveLock::SharedExclusiveLock() - : shared_count_is_zero_(true, true), - shared_count_(0) { -} - -void SharedExclusiveLock::LockExclusive() { - cs_exclusive_.Enter(); - shared_count_is_zero_.Wait(rtc::kForever); -} - -void SharedExclusiveLock::UnlockExclusive() { - cs_exclusive_.Leave(); -} - -void SharedExclusiveLock::LockShared() { - CritScope exclusive_scope(&cs_exclusive_); - CritScope shared_scope(&cs_shared_); - if (++shared_count_ == 1) { - shared_count_is_zero_.Reset(); - } -} - -void SharedExclusiveLock::UnlockShared() { - CritScope shared_scope(&cs_shared_); - if (--shared_count_ == 0) { - shared_count_is_zero_.Set(); - } -} - -} // namespace rtc diff --git a/webrtc/base/sharedexclusivelock.h b/webrtc/base/sharedexclusivelock.h deleted file mode 100644 index f64d7cf50..000000000 --- a/webrtc/base/sharedexclusivelock.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SHAREDEXCLUSIVELOCK_H_ -#define WEBRTC_BASE_SHAREDEXCLUSIVELOCK_H_ - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/event.h" - -namespace rtc { - -// This class provides shared-exclusive lock. It can be used in cases like -// multiple-readers/single-writer model. -class SharedExclusiveLock { - public: - SharedExclusiveLock(); - - // Locking/unlocking methods. It is encouraged to use SharedScope or - // ExclusiveScope for protection. - void LockExclusive(); - void UnlockExclusive(); - void LockShared(); - void UnlockShared(); - - private: - rtc::CriticalSection cs_exclusive_; - rtc::CriticalSection cs_shared_; - rtc::Event shared_count_is_zero_; - int shared_count_; - - DISALLOW_COPY_AND_ASSIGN(SharedExclusiveLock); -}; - -class SharedScope { - public: - explicit SharedScope(SharedExclusiveLock* lock) : lock_(lock) { - lock_->LockShared(); - } - - ~SharedScope() { - lock_->UnlockShared(); - } - - private: - SharedExclusiveLock* lock_; - - DISALLOW_COPY_AND_ASSIGN(SharedScope); -}; - -class ExclusiveScope { - public: - explicit ExclusiveScope(SharedExclusiveLock* lock) : lock_(lock) { - lock_->LockExclusive(); - } - - ~ExclusiveScope() { - lock_->UnlockExclusive(); - } - - private: - SharedExclusiveLock* lock_; - - DISALLOW_COPY_AND_ASSIGN(ExclusiveScope); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SHAREDEXCLUSIVELOCK_H_ diff --git a/webrtc/base/sharedexclusivelock_unittest.cc b/webrtc/base/sharedexclusivelock_unittest.cc deleted file mode 100644 index de1dbe812..000000000 --- a/webrtc/base/sharedexclusivelock_unittest.cc +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/common.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/messagequeue.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/sharedexclusivelock.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { - -static const uint32 kMsgRead = 0; -static const uint32 kMsgWrite = 0; -static const int kNoWaitThresholdInMs = 10; -static const int kWaitThresholdInMs = 80; -static const int kProcessTimeInMs = 100; -static const int kProcessTimeoutInMs = 5000; - -class SharedExclusiveTask : public MessageHandler { - public: - SharedExclusiveTask(SharedExclusiveLock* shared_exclusive_lock, - int* value, - bool* done) - : shared_exclusive_lock_(shared_exclusive_lock), - waiting_time_in_ms_(0), - value_(value), - done_(done) { - worker_thread_.reset(new Thread()); - worker_thread_->Start(); - } - - int waiting_time_in_ms() const { return waiting_time_in_ms_; } - - protected: - scoped_ptr worker_thread_; - SharedExclusiveLock* shared_exclusive_lock_; - int waiting_time_in_ms_; - int* value_; - bool* done_; -}; - -class ReadTask : public SharedExclusiveTask { - public: - ReadTask(SharedExclusiveLock* shared_exclusive_lock, int* value, bool* done) - : SharedExclusiveTask(shared_exclusive_lock, value, done) { - } - - void PostRead(int* value) { - worker_thread_->Post(this, kMsgRead, new TypedMessageData(value)); - } - - private: - virtual void OnMessage(Message* message) { - ASSERT(rtc::Thread::Current() == worker_thread_.get()); - ASSERT(message != NULL); - ASSERT(message->message_id == kMsgRead); - - TypedMessageData* message_data = - static_cast*>(message->pdata); - - uint32 start_time = Time(); - { - SharedScope ss(shared_exclusive_lock_); - waiting_time_in_ms_ = TimeDiff(Time(), start_time); - - Thread::SleepMs(kProcessTimeInMs); - *message_data->data() = *value_; - *done_ = true; - } - delete message->pdata; - message->pdata = NULL; - } -}; - -class WriteTask : public SharedExclusiveTask { - public: - WriteTask(SharedExclusiveLock* shared_exclusive_lock, int* value, bool* done) - : SharedExclusiveTask(shared_exclusive_lock, value, done) { - } - - void PostWrite(int value) { - worker_thread_->Post(this, kMsgWrite, new TypedMessageData(value)); - } - - private: - virtual void OnMessage(Message* message) { - ASSERT(rtc::Thread::Current() == worker_thread_.get()); - ASSERT(message != NULL); - ASSERT(message->message_id == kMsgWrite); - - TypedMessageData* message_data = - static_cast*>(message->pdata); - - uint32 start_time = Time(); - { - ExclusiveScope es(shared_exclusive_lock_); - waiting_time_in_ms_ = TimeDiff(Time(), start_time); - - Thread::SleepMs(kProcessTimeInMs); - *value_ = message_data->data(); - *done_ = true; - } - delete message->pdata; - message->pdata = NULL; - } -}; - -// Unit test for SharedExclusiveLock. -class SharedExclusiveLockTest - : public testing::Test { - public: - SharedExclusiveLockTest() : value_(0) { - } - - virtual void SetUp() { - shared_exclusive_lock_.reset(new SharedExclusiveLock()); - } - - protected: - scoped_ptr shared_exclusive_lock_; - int value_; -}; - -TEST_F(SharedExclusiveLockTest, TestSharedShared) { - int value0, value1; - bool done0, done1; - ReadTask reader0(shared_exclusive_lock_.get(), &value_, &done0); - ReadTask reader1(shared_exclusive_lock_.get(), &value_, &done1); - - // Test shared locks can be shared without waiting. - { - SharedScope ss(shared_exclusive_lock_.get()); - value_ = 1; - done0 = false; - done1 = false; - reader0.PostRead(&value0); - reader1.PostRead(&value1); - Thread::SleepMs(kProcessTimeInMs); - } - - EXPECT_TRUE_WAIT(done0, kProcessTimeoutInMs); - EXPECT_EQ(1, value0); - EXPECT_LE(reader0.waiting_time_in_ms(), kNoWaitThresholdInMs); - EXPECT_TRUE_WAIT(done1, kProcessTimeoutInMs); - EXPECT_EQ(1, value1); - EXPECT_LE(reader1.waiting_time_in_ms(), kNoWaitThresholdInMs); -} - -TEST_F(SharedExclusiveLockTest, TestSharedExclusive) { - bool done; - WriteTask writer(shared_exclusive_lock_.get(), &value_, &done); - - // Test exclusive lock needs to wait for shared lock. - { - SharedScope ss(shared_exclusive_lock_.get()); - value_ = 1; - done = false; - writer.PostWrite(2); - Thread::SleepMs(kProcessTimeInMs); - EXPECT_EQ(1, value_); - } - - EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs); - EXPECT_EQ(2, value_); - EXPECT_GE(writer.waiting_time_in_ms(), kWaitThresholdInMs); -} - -TEST_F(SharedExclusiveLockTest, TestExclusiveShared) { - int value; - bool done; - ReadTask reader(shared_exclusive_lock_.get(), &value_, &done); - - // Test shared lock needs to wait for exclusive lock. - { - ExclusiveScope es(shared_exclusive_lock_.get()); - value_ = 1; - done = false; - reader.PostRead(&value); - Thread::SleepMs(kProcessTimeInMs); - value_ = 2; - } - - EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs); - EXPECT_EQ(2, value); - EXPECT_GE(reader.waiting_time_in_ms(), kWaitThresholdInMs); -} - -TEST_F(SharedExclusiveLockTest, TestExclusiveExclusive) { - bool done; - WriteTask writer(shared_exclusive_lock_.get(), &value_, &done); - - // Test exclusive lock needs to wait for exclusive lock. - { - ExclusiveScope es(shared_exclusive_lock_.get()); - value_ = 1; - done = false; - writer.PostWrite(2); - Thread::SleepMs(kProcessTimeInMs); - EXPECT_EQ(1, value_); - } - - EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs); - EXPECT_EQ(2, value_); - EXPECT_GE(writer.waiting_time_in_ms(), kWaitThresholdInMs); -} - -} // namespace rtc diff --git a/webrtc/base/signalthread.cc b/webrtc/base/signalthread.cc deleted file mode 100644 index f95cb5fbc..000000000 --- a/webrtc/base/signalthread.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/signalthread.h" - -#include "webrtc/base/common.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// SignalThread -/////////////////////////////////////////////////////////////////////////////// - -SignalThread::SignalThread() - : main_(Thread::Current()), - worker_(this), - state_(kInit), - refcount_(1) { - main_->SignalQueueDestroyed.connect(this, - &SignalThread::OnMainThreadDestroyed); - worker_.SetName("SignalThread", this); -} - -SignalThread::~SignalThread() { - ASSERT(refcount_ == 0); -} - -bool SignalThread::SetName(const std::string& name, const void* obj) { - EnterExit ee(this); - ASSERT(main_->IsCurrent()); - ASSERT(kInit == state_); - return worker_.SetName(name, obj); -} - -bool SignalThread::SetPriority(ThreadPriority priority) { - EnterExit ee(this); - ASSERT(main_->IsCurrent()); - ASSERT(kInit == state_); - return worker_.SetPriority(priority); -} - -void SignalThread::Start() { - EnterExit ee(this); - ASSERT(main_->IsCurrent()); - if (kInit == state_ || kComplete == state_) { - state_ = kRunning; - OnWorkStart(); - worker_.Start(); - } else { - ASSERT(false); - } -} - -void SignalThread::Destroy(bool wait) { - EnterExit ee(this); - ASSERT(main_->IsCurrent()); - if ((kInit == state_) || (kComplete == state_)) { - refcount_--; - } else if (kRunning == state_ || kReleasing == state_) { - state_ = kStopping; - // OnWorkStop() must follow Quit(), so that when the thread wakes up due to - // OWS(), ContinueWork() will return false. - worker_.Quit(); - OnWorkStop(); - if (wait) { - // Release the thread's lock so that it can return from ::Run. - cs_.Leave(); - worker_.Stop(); - cs_.Enter(); - refcount_--; - } - } else { - ASSERT(false); - } -} - -void SignalThread::Release() { - EnterExit ee(this); - ASSERT(main_->IsCurrent()); - if (kComplete == state_) { - refcount_--; - } else if (kRunning == state_) { - state_ = kReleasing; - } else { - // if (kInit == state_) use Destroy() - ASSERT(false); - } -} - -bool SignalThread::ContinueWork() { - EnterExit ee(this); - ASSERT(worker_.IsCurrent()); - return worker_.ProcessMessages(0); -} - -void SignalThread::OnMessage(Message *msg) { - EnterExit ee(this); - if (ST_MSG_WORKER_DONE == msg->message_id) { - ASSERT(main_->IsCurrent()); - OnWorkDone(); - bool do_delete = false; - if (kRunning == state_) { - state_ = kComplete; - } else { - do_delete = true; - } - if (kStopping != state_) { - // Before signaling that the work is done, make sure that the worker - // thread actually is done. We got here because DoWork() finished and - // Run() posted the ST_MSG_WORKER_DONE message. This means the worker - // thread is about to go away anyway, but sometimes it doesn't actually - // finish before SignalWorkDone is processed, and for a reusable - // SignalThread this makes an assert in thread.cc fire. - // - // Calling Stop() on the worker ensures that the OS thread that underlies - // the worker will finish, and will be set to NULL, enabling us to call - // Start() again. - worker_.Stop(); - SignalWorkDone(this); - } - if (do_delete) { - refcount_--; - } - } -} - -void SignalThread::Run() { - DoWork(); - { - EnterExit ee(this); - if (main_) { - main_->Post(this, ST_MSG_WORKER_DONE); - } - } -} - -void SignalThread::OnMainThreadDestroyed() { - EnterExit ee(this); - main_ = NULL; -} - -} // namespace rtc diff --git a/webrtc/base/signalthread.h b/webrtc/base/signalthread.h deleted file mode 100644 index a97bda1af..000000000 --- a/webrtc/base/signalthread.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SIGNALTHREAD_H_ -#define WEBRTC_BASE_SIGNALTHREAD_H_ - -#include - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// SignalThread - Base class for worker threads. The main thread should call -// Start() to begin work, and then follow one of these models: -// Normal: Wait for SignalWorkDone, and then call Release to destroy. -// Cancellation: Call Release(true), to abort the worker thread. -// Fire-and-forget: Call Release(false), which allows the thread to run to -// completion, and then self-destruct without further notification. -// Periodic tasks: Wait for SignalWorkDone, then eventually call Start() -// again to repeat the task. When the instance isn't needed anymore, -// call Release. DoWork, OnWorkStart and OnWorkStop are called again, -// on a new thread. -// The subclass should override DoWork() to perform the background task. By -// periodically calling ContinueWork(), it can check for cancellation. -// OnWorkStart and OnWorkDone can be overridden to do pre- or post-work -// tasks in the context of the main thread. -/////////////////////////////////////////////////////////////////////////////// - -class SignalThread - : public sigslot::has_slots<>, - protected MessageHandler { - public: - SignalThread(); - - // Context: Main Thread. Call before Start to change the worker's name. - bool SetName(const std::string& name, const void* obj); - - // Context: Main Thread. Call before Start to change the worker's priority. - bool SetPriority(ThreadPriority priority); - - // Context: Main Thread. Call to begin the worker thread. - void Start(); - - // Context: Main Thread. If the worker thread is not running, deletes the - // object immediately. Otherwise, asks the worker thread to abort processing, - // and schedules the object to be deleted once the worker exits. - // SignalWorkDone will not be signalled. If wait is true, does not return - // until the thread is deleted. - void Destroy(bool wait); - - // Context: Main Thread. If the worker thread is complete, deletes the - // object immediately. Otherwise, schedules the object to be deleted once - // the worker thread completes. SignalWorkDone will be signalled. - void Release(); - - // Context: Main Thread. Signalled when work is complete. - sigslot::signal1 SignalWorkDone; - - enum { ST_MSG_WORKER_DONE, ST_MSG_FIRST_AVAILABLE }; - - protected: - virtual ~SignalThread(); - - Thread* worker() { return &worker_; } - - // Context: Main Thread. Subclass should override to do pre-work setup. - virtual void OnWorkStart() { } - - // Context: Worker Thread. Subclass should override to do work. - virtual void DoWork() = 0; - - // Context: Worker Thread. Subclass should call periodically to - // dispatch messages and determine if the thread should terminate. - bool ContinueWork(); - - // Context: Worker Thread. Subclass should override when extra work is - // needed to abort the worker thread. - virtual void OnWorkStop() { } - - // Context: Main Thread. Subclass should override to do post-work cleanup. - virtual void OnWorkDone() { } - - // Context: Any Thread. If subclass overrides, be sure to call the base - // implementation. Do not use (message_id < ST_MSG_FIRST_AVAILABLE) - virtual void OnMessage(Message *msg); - - private: - enum State { - kInit, // Initialized, but not started - kRunning, // Started and doing work - kReleasing, // Same as running, but to be deleted when work is done - kComplete, // Work is done - kStopping, // Work is being interrupted - }; - - class Worker : public Thread { - public: - explicit Worker(SignalThread* parent) : parent_(parent) {} - virtual ~Worker() { Stop(); } - virtual void Run() { parent_->Run(); } - - private: - SignalThread* parent_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(Worker); - }; - - class EnterExit { - public: - explicit EnterExit(SignalThread* t) : t_(t) { - t_->cs_.Enter(); - // If refcount_ is zero then the object has already been deleted and we - // will be double-deleting it in ~EnterExit()! (shouldn't happen) - ASSERT(t_->refcount_ != 0); - ++t_->refcount_; - } - ~EnterExit() { - bool d = (0 == --t_->refcount_); - t_->cs_.Leave(); - if (d) - delete t_; - } - - private: - SignalThread* t_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(EnterExit); - }; - - void Run(); - void OnMainThreadDestroyed(); - - Thread* main_; - Worker worker_; - CriticalSection cs_; - State state_; - int refcount_; - - DISALLOW_COPY_AND_ASSIGN(SignalThread); -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_SIGNALTHREAD_H_ diff --git a/webrtc/base/signalthread_unittest.cc b/webrtc/base/signalthread_unittest.cc deleted file mode 100644 index 4d3e0402e..000000000 --- a/webrtc/base/signalthread_unittest.cc +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/signalthread.h" -#include "webrtc/base/thread.h" - -using namespace rtc; - -class SignalThreadTest : public testing::Test, public sigslot::has_slots<> { - public: - class SlowSignalThread : public SignalThread { - public: - SlowSignalThread(SignalThreadTest* harness) : harness_(harness) { - } - - virtual ~SlowSignalThread() { - EXPECT_EQ(harness_->main_thread_, Thread::Current()); - ++harness_->thread_deleted_; - } - - const SignalThreadTest* harness() { return harness_; } - - protected: - virtual void OnWorkStart() { - ASSERT_TRUE(harness_ != NULL); - ++harness_->thread_started_; - EXPECT_EQ(harness_->main_thread_, Thread::Current()); - EXPECT_FALSE(worker()->started()); // not started yet - } - - virtual void OnWorkStop() { - ++harness_->thread_stopped_; - EXPECT_EQ(harness_->main_thread_, Thread::Current()); - EXPECT_TRUE(worker()->started()); // not stopped yet - } - - virtual void OnWorkDone() { - ++harness_->thread_done_; - EXPECT_EQ(harness_->main_thread_, Thread::Current()); - EXPECT_TRUE(worker()->started()); // not stopped yet - } - - virtual void DoWork() { - EXPECT_NE(harness_->main_thread_, Thread::Current()); - EXPECT_EQ(worker(), Thread::Current()); - Thread::Current()->socketserver()->Wait(250, false); - } - - private: - SignalThreadTest* harness_; - DISALLOW_EVIL_CONSTRUCTORS(SlowSignalThread); - }; - - void OnWorkComplete(rtc::SignalThread* thread) { - SlowSignalThread* t = static_cast(thread); - EXPECT_EQ(t->harness(), this); - EXPECT_EQ(main_thread_, Thread::Current()); - - ++thread_completed_; - if (!called_release_) { - thread->Release(); - } - } - - virtual void SetUp() { - main_thread_ = Thread::Current(); - thread_ = new SlowSignalThread(this); - thread_->SignalWorkDone.connect(this, &SignalThreadTest::OnWorkComplete); - called_release_ = false; - thread_started_ = 0; - thread_done_ = 0; - thread_completed_ = 0; - thread_stopped_ = 0; - thread_deleted_ = 0; - } - - virtual void TearDown() { - } - - Thread* main_thread_; - SlowSignalThread* thread_; - bool called_release_; - - int thread_started_; - int thread_done_; - int thread_completed_; - int thread_stopped_; - int thread_deleted_; -}; - -class OwnerThread : public Thread, public sigslot::has_slots<> { - public: - explicit OwnerThread(SignalThreadTest* harness) - : harness_(harness), - has_run_(false) { - } - - virtual ~OwnerThread() { - Stop(); - } - - virtual void Run() { - SignalThreadTest::SlowSignalThread* signal_thread = - new SignalThreadTest::SlowSignalThread(harness_); - signal_thread->SignalWorkDone.connect(this, &OwnerThread::OnWorkDone); - signal_thread->Start(); - Thread::Current()->socketserver()->Wait(100, false); - signal_thread->Release(); - // Delete |signal_thread|. - signal_thread->Destroy(true); - has_run_ = true; - } - - bool has_run() { return has_run_; } - void OnWorkDone(SignalThread* signal_thread) { - FAIL() << " This shouldn't get called."; - } - - private: - SignalThreadTest* harness_; - bool has_run_; - DISALLOW_EVIL_CONSTRUCTORS(OwnerThread); -}; - -// Test for when the main thread goes away while the -// signal thread is still working. This may happen -// when shutting down the process. -TEST_F(SignalThreadTest, OwnerThreadGoesAway) { - { - scoped_ptr owner(new OwnerThread(this)); - main_thread_ = owner.get(); - owner->Start(); - while (!owner->has_run()) { - Thread::Current()->socketserver()->Wait(10, false); - } - } - // At this point the main thread has gone away. - // Give the SignalThread a little time to do its callback, - // which will crash if the signal thread doesn't handle - // this situation well. - Thread::Current()->socketserver()->Wait(500, false); -} - -#define EXPECT_STATE(started, done, completed, stopped, deleted) \ - EXPECT_EQ(started, thread_started_); \ - EXPECT_EQ(done, thread_done_); \ - EXPECT_EQ(completed, thread_completed_); \ - EXPECT_EQ(stopped, thread_stopped_); \ - EXPECT_EQ(deleted, thread_deleted_); - -TEST_F(SignalThreadTest, ThreadFinishes) { - thread_->Start(); - EXPECT_STATE(1, 0, 0, 0, 0); - Thread::SleepMs(500); - EXPECT_STATE(1, 0, 0, 0, 0); - Thread::Current()->ProcessMessages(0); - EXPECT_STATE(1, 1, 1, 0, 1); -} - -TEST_F(SignalThreadTest, ReleasedThreadFinishes) { - thread_->Start(); - EXPECT_STATE(1, 0, 0, 0, 0); - thread_->Release(); - called_release_ = true; - EXPECT_STATE(1, 0, 0, 0, 0); - Thread::SleepMs(500); - EXPECT_STATE(1, 0, 0, 0, 0); - Thread::Current()->ProcessMessages(0); - EXPECT_STATE(1, 1, 1, 0, 1); -} - -TEST_F(SignalThreadTest, DestroyedThreadCleansUp) { - thread_->Start(); - EXPECT_STATE(1, 0, 0, 0, 0); - thread_->Destroy(true); - EXPECT_STATE(1, 0, 0, 1, 1); - Thread::Current()->ProcessMessages(0); - EXPECT_STATE(1, 0, 0, 1, 1); -} - -TEST_F(SignalThreadTest, DeferredDestroyedThreadCleansUp) { - thread_->Start(); - EXPECT_STATE(1, 0, 0, 0, 0); - thread_->Destroy(false); - EXPECT_STATE(1, 0, 0, 1, 0); - Thread::SleepMs(500); - EXPECT_STATE(1, 0, 0, 1, 0); - Thread::Current()->ProcessMessages(0); - EXPECT_STATE(1, 1, 0, 1, 1); -} diff --git a/webrtc/base/sigslot.h b/webrtc/base/sigslot.h deleted file mode 100644 index 990d2efb7..000000000 --- a/webrtc/base/sigslot.h +++ /dev/null @@ -1,2850 +0,0 @@ -// sigslot.h: Signal/Slot classes -// -// Written by Sarah Thompson (sarah@telergy.com) 2002. -// -// License: Public domain. You are free to use this code however you like, with the proviso that -// the author takes on no responsibility or liability for any use. -// -// QUICK DOCUMENTATION -// -// (see also the full documentation at http://sigslot.sourceforge.net/) -// -// #define switches -// SIGSLOT_PURE_ISO - Define this to force ISO C++ compliance. This also disables -// all of the thread safety support on platforms where it is -// available. -// -// SIGSLOT_USE_POSIX_THREADS - Force use of Posix threads when using a C++ compiler other than -// gcc on a platform that supports Posix threads. (When using gcc, -// this is the default - use SIGSLOT_PURE_ISO to disable this if -// necessary) -// -// SIGSLOT_DEFAULT_MT_POLICY - Where thread support is enabled, this defaults to multi_threaded_global. -// Otherwise, the default is single_threaded. #define this yourself to -// override the default. In pure ISO mode, anything other than -// single_threaded will cause a compiler error. -// -// PLATFORM NOTES -// -// Win32 - On Win32, the WEBRTC_WIN symbol must be #defined. Most mainstream -// compilers do this by default, but you may need to define it -// yourself if your build environment is less standard. This causes -// the Win32 thread support to be compiled in and used automatically. -// -// Unix/Linux/BSD, etc. - If you're using gcc, it is assumed that you have Posix threads -// available, so they are used automatically. You can override this -// (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using -// something other than gcc but still want to use Posix threads, you -// need to #define SIGSLOT_USE_POSIX_THREADS. -// -// ISO C++ - If none of the supported platforms are detected, or if -// SIGSLOT_PURE_ISO is defined, all multithreading support is turned off, -// along with any code that might cause a pure ISO C++ environment to -// complain. Before you ask, gcc -ansi -pedantic won't compile this -// library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of -// errors that aren't really there. If you feel like investigating this, -// please contact the author. -// -// -// THREADING MODES -// -// single_threaded - Your program is assumed to be single threaded from the point of view -// of signal/slot usage (i.e. all objects using signals and slots are -// created and destroyed from a single thread). Behaviour if objects are -// destroyed concurrently is undefined (i.e. you'll get the occasional -// segmentation fault/memory exception). -// -// multi_threaded_global - Your program is assumed to be multi threaded. Objects using signals and -// slots can be safely created and destroyed from any thread, even when -// connections exist. In multi_threaded_global mode, this is achieved by a -// single global mutex (actually a critical section on Windows because they -// are faster). This option uses less OS resources, but results in more -// opportunities for contention, possibly resulting in more context switches -// than are strictly necessary. -// -// multi_threaded_local - Behaviour in this mode is essentially the same as multi_threaded_global, -// except that each signal, and each object that inherits has_slots, all -// have their own mutex/critical section. In practice, this means that -// mutex collisions (and hence context switches) only happen if they are -// absolutely essential. However, on some platforms, creating a lot of -// mutexes can slow down the whole OS, so use this option with care. -// -// USING THE LIBRARY -// -// See the full documentation at http://sigslot.sourceforge.net/ -// -// -// Libjingle specific: -// This file has been modified such that has_slots and signalx do not have to be -// using the same threading requirements. E.g. it is possible to connect a -// has_slots and signal0 or -// has_slots and signal0. -// If has_slots is single threaded the user must ensure that it is not trying -// to connect or disconnect to signalx concurrently or data race may occur. -// If signalx is single threaded the user must ensure that disconnect, connect -// or signal is not happening concurrently or data race may occur. - -#ifndef WEBRTC_BASE_SIGSLOT_H__ -#define WEBRTC_BASE_SIGSLOT_H__ - -#include -#include -#include - -// On our copy of sigslot.h, we set single threading as default. -#define SIGSLOT_DEFAULT_MT_POLICY single_threaded - -#if defined(SIGSLOT_PURE_ISO) || (!defined(WEBRTC_WIN) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS)) -# define _SIGSLOT_SINGLE_THREADED -#elif defined(WEBRTC_WIN) -# define _SIGSLOT_HAS_WIN32_THREADS -# if !defined(WIN32_LEAN_AND_MEAN) -# define WIN32_LEAN_AND_MEAN -# endif -# include "webrtc/base/win32.h" -#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS) -# define _SIGSLOT_HAS_POSIX_THREADS -# include -#else -# define _SIGSLOT_SINGLE_THREADED -#endif - -#ifndef SIGSLOT_DEFAULT_MT_POLICY -# ifdef _SIGSLOT_SINGLE_THREADED -# define SIGSLOT_DEFAULT_MT_POLICY single_threaded -# else -# define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local -# endif -#endif - -// TODO: change this namespace to rtc? -namespace sigslot { - - class single_threaded - { - public: - single_threaded() - { - ; - } - - virtual ~single_threaded() - { - ; - } - - virtual void lock() - { - ; - } - - virtual void unlock() - { - ; - } - }; - -#ifdef _SIGSLOT_HAS_WIN32_THREADS - // The multi threading policies only get compiled in if they are enabled. - class multi_threaded_global - { - public: - multi_threaded_global() - { - static bool isinitialised = false; - - if(!isinitialised) - { - InitializeCriticalSection(get_critsec()); - isinitialised = true; - } - } - - multi_threaded_global(const multi_threaded_global&) - { - ; - } - - virtual ~multi_threaded_global() - { - ; - } - - virtual void lock() - { - EnterCriticalSection(get_critsec()); - } - - virtual void unlock() - { - LeaveCriticalSection(get_critsec()); - } - - private: - CRITICAL_SECTION* get_critsec() - { - static CRITICAL_SECTION g_critsec; - return &g_critsec; - } - }; - - class multi_threaded_local - { - public: - multi_threaded_local() - { - InitializeCriticalSection(&m_critsec); - } - - multi_threaded_local(const multi_threaded_local&) - { - InitializeCriticalSection(&m_critsec); - } - - virtual ~multi_threaded_local() - { - DeleteCriticalSection(&m_critsec); - } - - virtual void lock() - { - EnterCriticalSection(&m_critsec); - } - - virtual void unlock() - { - LeaveCriticalSection(&m_critsec); - } - - private: - CRITICAL_SECTION m_critsec; - }; -#endif // _SIGSLOT_HAS_WIN32_THREADS - -#ifdef _SIGSLOT_HAS_POSIX_THREADS - // The multi threading policies only get compiled in if they are enabled. - class multi_threaded_global - { - public: - multi_threaded_global() - { - pthread_mutex_init(get_mutex(), NULL); - } - - multi_threaded_global(const multi_threaded_global&) - { - ; - } - - virtual ~multi_threaded_global() - { - ; - } - - virtual void lock() - { - pthread_mutex_lock(get_mutex()); - } - - virtual void unlock() - { - pthread_mutex_unlock(get_mutex()); - } - - private: - pthread_mutex_t* get_mutex() - { - static pthread_mutex_t g_mutex; - return &g_mutex; - } - }; - - class multi_threaded_local - { - public: - multi_threaded_local() - { - pthread_mutex_init(&m_mutex, NULL); - } - - multi_threaded_local(const multi_threaded_local&) - { - pthread_mutex_init(&m_mutex, NULL); - } - - virtual ~multi_threaded_local() - { - pthread_mutex_destroy(&m_mutex); - } - - virtual void lock() - { - pthread_mutex_lock(&m_mutex); - } - - virtual void unlock() - { - pthread_mutex_unlock(&m_mutex); - } - - private: - pthread_mutex_t m_mutex; - }; -#endif // _SIGSLOT_HAS_POSIX_THREADS - - template - class lock_block - { - public: - mt_policy *m_mutex; - - lock_block(mt_policy *mtx) - : m_mutex(mtx) - { - m_mutex->lock(); - } - - ~lock_block() - { - m_mutex->unlock(); - } - }; - - class has_slots_interface; - - template - class _connection_base0 - { - public: - virtual ~_connection_base0() {} - virtual has_slots_interface* getdest() const = 0; - virtual void emit() = 0; - virtual _connection_base0* clone() = 0; - virtual _connection_base0* duplicate(has_slots_interface* pnewdest) = 0; - }; - - template - class _connection_base1 - { - public: - virtual ~_connection_base1() {} - virtual has_slots_interface* getdest() const = 0; - virtual void emit(arg1_type) = 0; - virtual _connection_base1* clone() = 0; - virtual _connection_base1* duplicate(has_slots_interface* pnewdest) = 0; - }; - - template - class _connection_base2 - { - public: - virtual ~_connection_base2() {} - virtual has_slots_interface* getdest() const = 0; - virtual void emit(arg1_type, arg2_type) = 0; - virtual _connection_base2* clone() = 0; - virtual _connection_base2* duplicate(has_slots_interface* pnewdest) = 0; - }; - - template - class _connection_base3 - { - public: - virtual ~_connection_base3() {} - virtual has_slots_interface* getdest() const = 0; - virtual void emit(arg1_type, arg2_type, arg3_type) = 0; - virtual _connection_base3* clone() = 0; - virtual _connection_base3* duplicate(has_slots_interface* pnewdest) = 0; - }; - - template - class _connection_base4 - { - public: - virtual ~_connection_base4() {} - virtual has_slots_interface* getdest() const = 0; - virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type) = 0; - virtual _connection_base4* clone() = 0; - virtual _connection_base4* duplicate(has_slots_interface* pnewdest) = 0; - }; - - template - class _connection_base5 - { - public: - virtual ~_connection_base5() {} - virtual has_slots_interface* getdest() const = 0; - virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, - arg5_type) = 0; - virtual _connection_base5* clone() = 0; - virtual _connection_base5* duplicate(has_slots_interface* pnewdest) = 0; - }; - - template - class _connection_base6 - { - public: - virtual ~_connection_base6() {} - virtual has_slots_interface* getdest() const = 0; - virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, - arg6_type) = 0; - virtual _connection_base6* clone() = 0; - virtual _connection_base6* duplicate(has_slots_interface* pnewdest) = 0; - }; - - template - class _connection_base7 - { - public: - virtual ~_connection_base7() {} - virtual has_slots_interface* getdest() const = 0; - virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, - arg6_type, arg7_type) = 0; - virtual _connection_base7* clone() = 0; - virtual _connection_base7* duplicate(has_slots_interface* pnewdest) = 0; - }; - - template - class _connection_base8 - { - public: - virtual ~_connection_base8() {} - virtual has_slots_interface* getdest() const = 0; - virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, - arg6_type, arg7_type, arg8_type) = 0; - virtual _connection_base8* clone() = 0; - virtual _connection_base8* duplicate(has_slots_interface* pnewdest) = 0; - }; - - class _signal_base_interface - { - public: - virtual void slot_disconnect(has_slots_interface* pslot) = 0; - virtual void slot_duplicate(const has_slots_interface* poldslot, has_slots_interface* pnewslot) = 0; - }; - - template - class _signal_base : public _signal_base_interface, public mt_policy - { - }; - - class has_slots_interface - { - public: - has_slots_interface() - { - ; - } - - virtual void signal_connect(_signal_base_interface* sender) = 0; - - virtual void signal_disconnect(_signal_base_interface* sender) = 0; - - virtual ~has_slots_interface() - { - } - - virtual void disconnect_all() = 0; - }; - - template - class has_slots : public has_slots_interface, public mt_policy - { - private: - typedef std::set<_signal_base_interface*> sender_set; - typedef sender_set::const_iterator const_iterator; - - public: - has_slots() - { - ; - } - - has_slots(const has_slots& hs) - { - lock_block lock(this); - const_iterator it = hs.m_senders.begin(); - const_iterator itEnd = hs.m_senders.end(); - - while(it != itEnd) - { - (*it)->slot_duplicate(&hs, this); - m_senders.insert(*it); - ++it; - } - } - - void signal_connect(_signal_base_interface* sender) - { - lock_block lock(this); - m_senders.insert(sender); - } - - void signal_disconnect(_signal_base_interface* sender) - { - lock_block lock(this); - m_senders.erase(sender); - } - - virtual ~has_slots() - { - disconnect_all(); - } - - void disconnect_all() - { - lock_block lock(this); - const_iterator it = m_senders.begin(); - const_iterator itEnd = m_senders.end(); - - while(it != itEnd) - { - (*it)->slot_disconnect(this); - ++it; - } - - m_senders.erase(m_senders.begin(), m_senders.end()); - } - - private: - sender_set m_senders; - }; - - template - class _signal_base0 : public _signal_base - { - public: - typedef std::list<_connection_base0 *> connections_list; - - _signal_base0() - { - ; - } - - _signal_base0(const _signal_base0& s) - : _signal_base(s) - { - lock_block lock(this); - typename connections_list::const_iterator it = s.m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_connect(this); - m_connected_slots.push_back((*it)->clone()); - - ++it; - } - } - - ~_signal_base0() - { - disconnect_all(); - } - - bool is_empty() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - return it == itEnd; - } - - void disconnect_all() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_disconnect(this); - delete *it; - - ++it; - } - - m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); - } - -#ifdef _DEBUG - bool connected(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - while(it != itEnd) - { - itNext = it; - ++itNext; - if ((*it)->getdest() == pclass) - return true; - it = itNext; - } - return false; - } -#endif - - void disconnect(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == pclass) - { - delete *it; - m_connected_slots.erase(it); - pclass->signal_disconnect(this); - return; - } - - ++it; - } - } - - void slot_disconnect(has_slots_interface* pslot) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - typename connections_list::iterator itNext = it; - ++itNext; - - if((*it)->getdest() == pslot) - { - delete *it; - m_connected_slots.erase(it); - } - - it = itNext; - } - } - - void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == oldtarget) - { - m_connected_slots.push_back((*it)->duplicate(newtarget)); - } - - ++it; - } - } - - protected: - connections_list m_connected_slots; - }; - - template - class _signal_base1 : public _signal_base - { - public: - typedef std::list<_connection_base1 *> connections_list; - - _signal_base1() - { - ; - } - - _signal_base1(const _signal_base1& s) - : _signal_base(s) - { - lock_block lock(this); - typename connections_list::const_iterator it = s.m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_connect(this); - m_connected_slots.push_back((*it)->clone()); - - ++it; - } - } - - void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == oldtarget) - { - m_connected_slots.push_back((*it)->duplicate(newtarget)); - } - - ++it; - } - } - - ~_signal_base1() - { - disconnect_all(); - } - - bool is_empty() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - return it == itEnd; - } - - void disconnect_all() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_disconnect(this); - delete *it; - - ++it; - } - - m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); - } - -#ifdef _DEBUG - bool connected(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - while(it != itEnd) - { - itNext = it; - ++itNext; - if ((*it)->getdest() == pclass) - return true; - it = itNext; - } - return false; - } -#endif - - void disconnect(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == pclass) - { - delete *it; - m_connected_slots.erase(it); - pclass->signal_disconnect(this); - return; - } - - ++it; - } - } - - void slot_disconnect(has_slots_interface* pslot) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - typename connections_list::iterator itNext = it; - ++itNext; - - if((*it)->getdest() == pslot) - { - delete *it; - m_connected_slots.erase(it); - } - - it = itNext; - } - } - - - protected: - connections_list m_connected_slots; - }; - - template - class _signal_base2 : public _signal_base - { - public: - typedef std::list<_connection_base2 *> - connections_list; - - _signal_base2() - { - ; - } - - _signal_base2(const _signal_base2& s) - : _signal_base(s) - { - lock_block lock(this); - typename connections_list::const_iterator it = s.m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_connect(this); - m_connected_slots.push_back((*it)->clone()); - - ++it; - } - } - - void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == oldtarget) - { - m_connected_slots.push_back((*it)->duplicate(newtarget)); - } - - ++it; - } - } - - ~_signal_base2() - { - disconnect_all(); - } - - bool is_empty() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - return it == itEnd; - } - - void disconnect_all() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_disconnect(this); - delete *it; - - ++it; - } - - m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); - } - -#ifdef _DEBUG - bool connected(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - while(it != itEnd) - { - itNext = it; - ++itNext; - if ((*it)->getdest() == pclass) - return true; - it = itNext; - } - return false; - } -#endif - - void disconnect(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == pclass) - { - delete *it; - m_connected_slots.erase(it); - pclass->signal_disconnect(this); - return; - } - - ++it; - } - } - - void slot_disconnect(has_slots_interface* pslot) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - typename connections_list::iterator itNext = it; - ++itNext; - - if((*it)->getdest() == pslot) - { - delete *it; - m_connected_slots.erase(it); - } - - it = itNext; - } - } - - protected: - connections_list m_connected_slots; - }; - - template - class _signal_base3 : public _signal_base - { - public: - typedef std::list<_connection_base3 *> - connections_list; - - _signal_base3() - { - ; - } - - _signal_base3(const _signal_base3& s) - : _signal_base(s) - { - lock_block lock(this); - typename connections_list::const_iterator it = s.m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_connect(this); - m_connected_slots.push_back((*it)->clone()); - - ++it; - } - } - - void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == oldtarget) - { - m_connected_slots.push_back((*it)->duplicate(newtarget)); - } - - ++it; - } - } - - ~_signal_base3() - { - disconnect_all(); - } - - bool is_empty() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - return it == itEnd; - } - - void disconnect_all() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_disconnect(this); - delete *it; - - ++it; - } - - m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); - } - -#ifdef _DEBUG - bool connected(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - while(it != itEnd) - { - itNext = it; - ++itNext; - if ((*it)->getdest() == pclass) - return true; - it = itNext; - } - return false; - } -#endif - - void disconnect(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == pclass) - { - delete *it; - m_connected_slots.erase(it); - pclass->signal_disconnect(this); - return; - } - - ++it; - } - } - - void slot_disconnect(has_slots_interface* pslot) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - typename connections_list::iterator itNext = it; - ++itNext; - - if((*it)->getdest() == pslot) - { - delete *it; - m_connected_slots.erase(it); - } - - it = itNext; - } - } - - protected: - connections_list m_connected_slots; - }; - - template - class _signal_base4 : public _signal_base - { - public: - typedef std::list<_connection_base4 *> connections_list; - - _signal_base4() - { - ; - } - - _signal_base4(const _signal_base4& s) - : _signal_base(s) - { - lock_block lock(this); - typename connections_list::const_iterator it = s.m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_connect(this); - m_connected_slots.push_back((*it)->clone()); - - ++it; - } - } - - void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == oldtarget) - { - m_connected_slots.push_back((*it)->duplicate(newtarget)); - } - - ++it; - } - } - - ~_signal_base4() - { - disconnect_all(); - } - - bool is_empty() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - return it == itEnd; - } - - void disconnect_all() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_disconnect(this); - delete *it; - - ++it; - } - - m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); - } - -#ifdef _DEBUG - bool connected(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - while(it != itEnd) - { - itNext = it; - ++itNext; - if ((*it)->getdest() == pclass) - return true; - it = itNext; - } - return false; - } -#endif - - void disconnect(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == pclass) - { - delete *it; - m_connected_slots.erase(it); - pclass->signal_disconnect(this); - return; - } - - ++it; - } - } - - void slot_disconnect(has_slots_interface* pslot) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - typename connections_list::iterator itNext = it; - ++itNext; - - if((*it)->getdest() == pslot) - { - delete *it; - m_connected_slots.erase(it); - } - - it = itNext; - } - } - - protected: - connections_list m_connected_slots; - }; - - template - class _signal_base5 : public _signal_base - { - public: - typedef std::list<_connection_base5 *> connections_list; - - _signal_base5() - { - ; - } - - _signal_base5(const _signal_base5& s) - : _signal_base(s) - { - lock_block lock(this); - typename connections_list::const_iterator it = s.m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_connect(this); - m_connected_slots.push_back((*it)->clone()); - - ++it; - } - } - - void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == oldtarget) - { - m_connected_slots.push_back((*it)->duplicate(newtarget)); - } - - ++it; - } - } - - ~_signal_base5() - { - disconnect_all(); - } - - bool is_empty() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - return it == itEnd; - } - - void disconnect_all() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_disconnect(this); - delete *it; - - ++it; - } - - m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); - } - -#ifdef _DEBUG - bool connected(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - while(it != itEnd) - { - itNext = it; - ++itNext; - if ((*it)->getdest() == pclass) - return true; - it = itNext; - } - return false; - } -#endif - - void disconnect(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == pclass) - { - delete *it; - m_connected_slots.erase(it); - pclass->signal_disconnect(this); - return; - } - - ++it; - } - } - - void slot_disconnect(has_slots_interface* pslot) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - typename connections_list::iterator itNext = it; - ++itNext; - - if((*it)->getdest() == pslot) - { - delete *it; - m_connected_slots.erase(it); - } - - it = itNext; - } - } - - protected: - connections_list m_connected_slots; - }; - - template - class _signal_base6 : public _signal_base - { - public: - typedef std::list<_connection_base6 *> connections_list; - - _signal_base6() - { - ; - } - - _signal_base6(const _signal_base6& s) - : _signal_base(s) - { - lock_block lock(this); - typename connections_list::const_iterator it = s.m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_connect(this); - m_connected_slots.push_back((*it)->clone()); - - ++it; - } - } - - void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == oldtarget) - { - m_connected_slots.push_back((*it)->duplicate(newtarget)); - } - - ++it; - } - } - - ~_signal_base6() - { - disconnect_all(); - } - - bool is_empty() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - return it == itEnd; - } - - void disconnect_all() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_disconnect(this); - delete *it; - - ++it; - } - - m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); - } - -#ifdef _DEBUG - bool connected(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - while(it != itEnd) - { - itNext = it; - ++itNext; - if ((*it)->getdest() == pclass) - return true; - it = itNext; - } - return false; - } -#endif - - void disconnect(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == pclass) - { - delete *it; - m_connected_slots.erase(it); - pclass->signal_disconnect(this); - return; - } - - ++it; - } - } - - void slot_disconnect(has_slots_interface* pslot) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - typename connections_list::iterator itNext = it; - ++itNext; - - if((*it)->getdest() == pslot) - { - delete *it; - m_connected_slots.erase(it); - } - - it = itNext; - } - } - - protected: - connections_list m_connected_slots; - }; - - template - class _signal_base7 : public _signal_base - { - public: - typedef std::list<_connection_base7 *> connections_list; - - _signal_base7() - { - ; - } - - _signal_base7(const _signal_base7& s) - : _signal_base(s) - { - lock_block lock(this); - typename connections_list::const_iterator it = s.m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_connect(this); - m_connected_slots.push_back((*it)->clone()); - - ++it; - } - } - - void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == oldtarget) - { - m_connected_slots.push_back((*it)->duplicate(newtarget)); - } - - ++it; - } - } - - ~_signal_base7() - { - disconnect_all(); - } - - bool is_empty() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - return it == itEnd; - } - - void disconnect_all() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_disconnect(this); - delete *it; - - ++it; - } - - m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); - } - -#ifdef _DEBUG - bool connected(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - while(it != itEnd) - { - itNext = it; - ++itNext; - if ((*it)->getdest() == pclass) - return true; - it = itNext; - } - return false; - } -#endif - - void disconnect(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == pclass) - { - delete *it; - m_connected_slots.erase(it); - pclass->signal_disconnect(this); - return; - } - - ++it; - } - } - - void slot_disconnect(has_slots_interface* pslot) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - typename connections_list::iterator itNext = it; - ++itNext; - - if((*it)->getdest() == pslot) - { - delete *it; - m_connected_slots.erase(it); - } - - it = itNext; - } - } - - protected: - connections_list m_connected_slots; - }; - - template - class _signal_base8 : public _signal_base - { - public: - typedef std::list<_connection_base8 *> - connections_list; - - _signal_base8() - { - ; - } - - _signal_base8(const _signal_base8& s) - : _signal_base(s) - { - lock_block lock(this); - typename connections_list::const_iterator it = s.m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_connect(this); - m_connected_slots.push_back((*it)->clone()); - - ++it; - } - } - - void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == oldtarget) - { - m_connected_slots.push_back((*it)->duplicate(newtarget)); - } - - ++it; - } - } - - ~_signal_base8() - { - disconnect_all(); - } - - bool is_empty() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - return it == itEnd; - } - - void disconnect_all() - { - lock_block lock(this); - typename connections_list::const_iterator it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - (*it)->getdest()->signal_disconnect(this); - delete *it; - - ++it; - } - - m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); - } - -#ifdef _DEBUG - bool connected(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - while(it != itEnd) - { - itNext = it; - ++itNext; - if ((*it)->getdest() == pclass) - return true; - it = itNext; - } - return false; - } -#endif - - void disconnect(has_slots_interface* pclass) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - if((*it)->getdest() == pclass) - { - delete *it; - m_connected_slots.erase(it); - pclass->signal_disconnect(this); - return; - } - - ++it; - } - } - - void slot_disconnect(has_slots_interface* pslot) - { - lock_block lock(this); - typename connections_list::iterator it = m_connected_slots.begin(); - typename connections_list::iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - typename connections_list::iterator itNext = it; - ++itNext; - - if((*it)->getdest() == pslot) - { - delete *it; - m_connected_slots.erase(it); - } - - it = itNext; - } - } - - protected: - connections_list m_connected_slots; - }; - - - template - class _connection0 : public _connection_base0 - { - public: - _connection0() - { - m_pobject = NULL; - m_pmemfun = NULL; - } - - _connection0(dest_type* pobject, void (dest_type::*pmemfun)()) - { - m_pobject = pobject; - m_pmemfun = pmemfun; - } - - virtual ~_connection0() - { - } - - virtual _connection_base0* clone() - { - return new _connection0(*this); - } - - virtual _connection_base0* duplicate(has_slots_interface* pnewdest) - { - return new _connection0((dest_type *)pnewdest, m_pmemfun); - } - - virtual void emit() - { - (m_pobject->*m_pmemfun)(); - } - - virtual has_slots_interface* getdest() const - { - return m_pobject; - } - - private: - dest_type* m_pobject; - void (dest_type::* m_pmemfun)(); - }; - - template - class _connection1 : public _connection_base1 - { - public: - _connection1() - { - m_pobject = NULL; - m_pmemfun = NULL; - } - - _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type)) - { - m_pobject = pobject; - m_pmemfun = pmemfun; - } - - virtual ~_connection1() - { - } - - virtual _connection_base1* clone() - { - return new _connection1(*this); - } - - virtual _connection_base1* duplicate(has_slots_interface* pnewdest) - { - return new _connection1((dest_type *)pnewdest, m_pmemfun); - } - - virtual void emit(arg1_type a1) - { - (m_pobject->*m_pmemfun)(a1); - } - - virtual has_slots_interface* getdest() const - { - return m_pobject; - } - - private: - dest_type* m_pobject; - void (dest_type::* m_pmemfun)(arg1_type); - }; - - template - class _connection2 : public _connection_base2 - { - public: - _connection2() - { - m_pobject = NULL; - m_pmemfun = NULL; - } - - _connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, - arg2_type)) - { - m_pobject = pobject; - m_pmemfun = pmemfun; - } - - virtual ~_connection2() - { - } - - virtual _connection_base2* clone() - { - return new _connection2(*this); - } - - virtual _connection_base2* duplicate(has_slots_interface* pnewdest) - { - return new _connection2((dest_type *)pnewdest, m_pmemfun); - } - - virtual void emit(arg1_type a1, arg2_type a2) - { - (m_pobject->*m_pmemfun)(a1, a2); - } - - virtual has_slots_interface* getdest() const - { - return m_pobject; - } - - private: - dest_type* m_pobject; - void (dest_type::* m_pmemfun)(arg1_type, arg2_type); - }; - - template - class _connection3 : public _connection_base3 - { - public: - _connection3() - { - m_pobject = NULL; - m_pmemfun = NULL; - } - - _connection3(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, - arg2_type, arg3_type)) - { - m_pobject = pobject; - m_pmemfun = pmemfun; - } - - virtual ~_connection3() - { - } - - virtual _connection_base3* clone() - { - return new _connection3(*this); - } - - virtual _connection_base3* duplicate(has_slots_interface* pnewdest) - { - return new _connection3((dest_type *)pnewdest, m_pmemfun); - } - - virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3) - { - (m_pobject->*m_pmemfun)(a1, a2, a3); - } - - virtual has_slots_interface* getdest() const - { - return m_pobject; - } - - private: - dest_type* m_pobject; - void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type); - }; - - template - class _connection4 : public _connection_base4 - { - public: - _connection4() - { - m_pobject = NULL; - m_pmemfun = NULL; - } - - _connection4(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type)) - { - m_pobject = pobject; - m_pmemfun = pmemfun; - } - - virtual ~_connection4() - { - } - - virtual _connection_base4* clone() - { - return new _connection4(*this); - } - - virtual _connection_base4* duplicate(has_slots_interface* pnewdest) - { - return new _connection4((dest_type *)pnewdest, m_pmemfun); - } - - virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, - arg4_type a4) - { - (m_pobject->*m_pmemfun)(a1, a2, a3, a4); - } - - virtual has_slots_interface* getdest() const - { - return m_pobject; - } - - private: - dest_type* m_pobject; - void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, - arg4_type); - }; - - template - class _connection5 : public _connection_base5 - { - public: - _connection5() - { - m_pobject = NULL; - m_pmemfun = NULL; - } - - _connection5(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type, arg5_type)) - { - m_pobject = pobject; - m_pmemfun = pmemfun; - } - - virtual ~_connection5() - { - } - - virtual _connection_base5* clone() - { - return new _connection5(*this); - } - - virtual _connection_base5* duplicate(has_slots_interface* pnewdest) - { - return new _connection5((dest_type *)pnewdest, m_pmemfun); - } - - virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5) - { - (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5); - } - - virtual has_slots_interface* getdest() const - { - return m_pobject; - } - - private: - dest_type* m_pobject; - void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, - arg5_type); - }; - - template - class _connection6 : public _connection_base6 - { - public: - _connection6() - { - m_pobject = NULL; - m_pmemfun = NULL; - } - - _connection6(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type, arg5_type, arg6_type)) - { - m_pobject = pobject; - m_pmemfun = pmemfun; - } - - virtual ~_connection6() - { - } - - virtual _connection_base6* clone() - { - return new _connection6(*this); - } - - virtual _connection_base6* duplicate(has_slots_interface* pnewdest) - { - return new _connection6((dest_type *)pnewdest, m_pmemfun); - } - - virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5, arg6_type a6) - { - (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6); - } - - virtual has_slots_interface* getdest() const - { - return m_pobject; - } - - private: - dest_type* m_pobject; - void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, - arg5_type, arg6_type); - }; - - template - class _connection7 : public _connection_base7 - { - public: - _connection7() - { - m_pobject = NULL; - m_pmemfun = NULL; - } - - _connection7(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type)) - { - m_pobject = pobject; - m_pmemfun = pmemfun; - } - - virtual ~_connection7() - { - } - - virtual _connection_base7* clone() - { - return new _connection7(*this); - } - - virtual _connection_base7* duplicate(has_slots_interface* pnewdest) - { - return new _connection7((dest_type *)pnewdest, m_pmemfun); - } - - virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5, arg6_type a6, arg7_type a7) - { - (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7); - } - - virtual has_slots_interface* getdest() const - { - return m_pobject; - } - - private: - dest_type* m_pobject; - void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, - arg5_type, arg6_type, arg7_type); - }; - - template - class _connection8 : public _connection_base8 - { - public: - _connection8() - { - m_pobject = NULL; - m_pmemfun = NULL; - } - - _connection8(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, - arg7_type, arg8_type)) - { - m_pobject = pobject; - m_pmemfun = pmemfun; - } - - virtual ~_connection8() - { - } - - virtual _connection_base8* clone() - { - return new _connection8(*this); - } - - virtual _connection_base8* duplicate(has_slots_interface* pnewdest) - { - return new _connection8((dest_type *)pnewdest, m_pmemfun); - } - - virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) - { - (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7, a8); - } - - virtual has_slots_interface* getdest() const - { - return m_pobject; - } - - private: - dest_type* m_pobject; - void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, - arg5_type, arg6_type, arg7_type, arg8_type); - }; - - template - class signal0 : public _signal_base0 - { - public: - typedef _signal_base0 base; - typedef typename base::connections_list connections_list; - using base::m_connected_slots; - - signal0() - { - ; - } - - signal0(const signal0& s) - : _signal_base0(s) - { - ; - } - - template - void connect(desttype* pclass, void (desttype::*pmemfun)()) - { - lock_block lock(this); - _connection0* conn = - new _connection0(pclass, pmemfun); - m_connected_slots.push_back(conn); - pclass->signal_connect(this); - } - - void emit() - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(); - - it = itNext; - } - } - - void operator()() - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(); - - it = itNext; - } - } - }; - - template - class signal1 : public _signal_base1 - { - public: - typedef _signal_base1 base; - typedef typename base::connections_list connections_list; - using base::m_connected_slots; - - signal1() - { - ; - } - - signal1(const signal1& s) - : _signal_base1(s) - { - ; - } - - template - void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type)) - { - lock_block lock(this); - _connection1* conn = - new _connection1(pclass, pmemfun); - m_connected_slots.push_back(conn); - pclass->signal_connect(this); - } - - void emit(arg1_type a1) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1); - - it = itNext; - } - } - - void operator()(arg1_type a1) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1); - - it = itNext; - } - } - }; - - template - class signal2 : public _signal_base2 - { - public: - typedef _signal_base2 base; - typedef typename base::connections_list connections_list; - using base::m_connected_slots; - - signal2() - { - ; - } - - signal2(const signal2& s) - : _signal_base2(s) - { - ; - } - - template - void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, - arg2_type)) - { - lock_block lock(this); - _connection2* conn = new - _connection2(pclass, pmemfun); - m_connected_slots.push_back(conn); - pclass->signal_connect(this); - } - - void emit(arg1_type a1, arg2_type a2) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2); - - it = itNext; - } - } - - void operator()(arg1_type a1, arg2_type a2) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2); - - it = itNext; - } - } - }; - - template - class signal3 : public _signal_base3 - { - public: - typedef _signal_base3 base; - typedef typename base::connections_list connections_list; - using base::m_connected_slots; - - signal3() - { - ; - } - - signal3(const signal3& s) - : _signal_base3(s) - { - ; - } - - template - void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, - arg2_type, arg3_type)) - { - lock_block lock(this); - _connection3* conn = - new _connection3(pclass, - pmemfun); - m_connected_slots.push_back(conn); - pclass->signal_connect(this); - } - - void emit(arg1_type a1, arg2_type a2, arg3_type a3) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3); - - it = itNext; - } - } - - void operator()(arg1_type a1, arg2_type a2, arg3_type a3) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3); - - it = itNext; - } - } - }; - - template - class signal4 : public _signal_base4 - { - public: - typedef _signal_base4 base; - typedef typename base::connections_list connections_list; - using base::m_connected_slots; - - signal4() - { - ; - } - - signal4(const signal4& s) - : _signal_base4(s) - { - ; - } - - template - void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type)) - { - lock_block lock(this); - _connection4* - conn = new _connection4(pclass, pmemfun); - m_connected_slots.push_back(conn); - pclass->signal_connect(this); - } - - void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4); - - it = itNext; - } - } - - void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4); - - it = itNext; - } - } - }; - - template - class signal5 : public _signal_base5 - { - public: - typedef _signal_base5 base; - typedef typename base::connections_list connections_list; - using base::m_connected_slots; - - signal5() - { - ; - } - - signal5(const signal5& s) - : _signal_base5(s) - { - ; - } - - template - void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type, arg5_type)) - { - lock_block lock(this); - _connection5* conn = new _connection5(pclass, pmemfun); - m_connected_slots.push_back(conn); - pclass->signal_connect(this); - } - - void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4, a5); - - it = itNext; - } - } - - void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4, a5); - - it = itNext; - } - } - }; - - - template - class signal6 : public _signal_base6 - { - public: - typedef _signal_base6 base; - typedef typename base::connections_list connections_list; - using base::m_connected_slots; - - signal6() - { - ; - } - - signal6(const signal6& s) - : _signal_base6(s) - { - ; - } - - template - void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type, arg5_type, arg6_type)) - { - lock_block lock(this); - _connection6* conn = - new _connection6(pclass, pmemfun); - m_connected_slots.push_back(conn); - pclass->signal_connect(this); - } - - void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5, arg6_type a6) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4, a5, a6); - - it = itNext; - } - } - - void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5, arg6_type a6) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4, a5, a6); - - it = itNext; - } - } - }; - - template - class signal7 : public _signal_base7 - { - public: - typedef _signal_base7 base; - typedef typename base::connections_list connections_list; - using base::m_connected_slots; - - signal7() - { - ; - } - - signal7(const signal7& s) - : _signal_base7(s) - { - ; - } - - template - void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, - arg7_type)) - { - lock_block lock(this); - _connection7* conn = - new _connection7(pclass, pmemfun); - m_connected_slots.push_back(conn); - pclass->signal_connect(this); - } - - void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5, arg6_type a6, arg7_type a7) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4, a5, a6, a7); - - it = itNext; - } - } - - void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5, arg6_type a6, arg7_type a7) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4, a5, a6, a7); - - it = itNext; - } - } - }; - - template - class signal8 : public _signal_base8 - { - public: - typedef _signal_base8 base; - typedef typename base::connections_list connections_list; - using base::m_connected_slots; - - signal8() - { - ; - } - - signal8(const signal8& s) - : _signal_base8(s) - { - ; - } - - template - void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, - arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, - arg7_type, arg8_type)) - { - lock_block lock(this); - _connection8* conn = - new _connection8(pclass, pmemfun); - m_connected_slots.push_back(conn); - pclass->signal_connect(this); - } - - void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8); - - it = itNext; - } - } - - void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, - arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) - { - lock_block lock(this); - typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); - typename connections_list::const_iterator itEnd = m_connected_slots.end(); - - while(it != itEnd) - { - itNext = it; - ++itNext; - - (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8); - - it = itNext; - } - } - }; - -}; // namespace sigslot - -#endif // WEBRTC_BASE_SIGSLOT_H__ diff --git a/webrtc/base/sigslot_unittest.cc b/webrtc/base/sigslot_unittest.cc deleted file mode 100644 index 4d3041d13..000000000 --- a/webrtc/base/sigslot_unittest.cc +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/sigslot.h" - -#include "webrtc/base/gunit.h" - -// This function, when passed a has_slots or signalx, will break the build if -// its threading requirement is not single threaded -static bool TemplateIsST(const sigslot::single_threaded* p) { - return true; -} -// This function, when passed a has_slots or signalx, will break the build if -// its threading requirement is not multi threaded -static bool TemplateIsMT(const sigslot::multi_threaded_local* p) { - return true; -} - -class SigslotDefault : public testing::Test, public sigslot::has_slots<> { - protected: - sigslot::signal0<> signal_; -}; - -template -class SigslotReceiver : public sigslot::has_slots { - public: - SigslotReceiver() : signal_(NULL), signal_count_(0) { - } - ~SigslotReceiver() { - } - - void Connect(sigslot::signal0* signal) { - if (!signal) return; - Disconnect(); - signal_ = signal; - signal->connect(this, - &SigslotReceiver::OnSignal); - } - void Disconnect() { - if (!signal_) return; - signal_->disconnect(this); - signal_ = NULL; - } - void OnSignal() { - ++signal_count_; - } - int signal_count() { return signal_count_; } - - private: - sigslot::signal0* signal_; - int signal_count_; -}; - -template -class SigslotSlotTest : public testing::Test { - protected: - SigslotSlotTest() { - mt_signal_policy mt_policy; - TemplateIsMT(&mt_policy); - } - - virtual void SetUp() { - Connect(); - } - virtual void TearDown() { - Disconnect(); - } - - void Disconnect() { - st_receiver_.Disconnect(); - mt_receiver_.Disconnect(); - } - - void Connect() { - st_receiver_.Connect(&SignalSTLoopback); - mt_receiver_.Connect(&SignalMTLoopback); - } - - int st_loop_back_count() { return st_receiver_.signal_count(); } - int mt_loop_back_count() { return mt_receiver_.signal_count(); } - - sigslot::signal0<> SignalSTLoopback; - SigslotReceiver st_receiver_; - sigslot::signal0 SignalMTLoopback; - SigslotReceiver mt_receiver_; -}; - -typedef SigslotSlotTest<> SigslotSTSlotTest; -typedef SigslotSlotTest SigslotMTSlotTest; - -class multi_threaded_local_fake : public sigslot::multi_threaded_local { - public: - multi_threaded_local_fake() : lock_count_(0), unlock_count_(0) { - } - - virtual void lock() { - ++lock_count_; - } - virtual void unlock() { - ++unlock_count_; - } - - int lock_count() { return lock_count_; } - - bool InCriticalSection() { return lock_count_ != unlock_count_; } - - protected: - int lock_count_; - int unlock_count_; -}; - -typedef SigslotSlotTest SigslotMTLockBase; - -class SigslotMTLockTest : public SigslotMTLockBase { - protected: - SigslotMTLockTest() {} - - virtual void SetUp() { - EXPECT_EQ(0, SlotLockCount()); - SigslotMTLockBase::SetUp(); - // Connects to two signals (ST and MT). However, - // SlotLockCount() only gets the count for the - // MT signal (there are two separate SigslotReceiver which - // keep track of their own count). - EXPECT_EQ(1, SlotLockCount()); - } - virtual void TearDown() { - const int previous_lock_count = SlotLockCount(); - SigslotMTLockBase::TearDown(); - // Disconnects from two signals. Note analogous to SetUp(). - EXPECT_EQ(previous_lock_count + 1, SlotLockCount()); - } - - int SlotLockCount() { return mt_receiver_.lock_count(); } - void Signal() { SignalMTLoopback(); } - int SignalLockCount() { return SignalMTLoopback.lock_count(); } - int signal_count() { return mt_loop_back_count(); } - bool InCriticalSection() { return SignalMTLoopback.InCriticalSection(); } -}; - -// This test will always succeed. However, if the default template instantiation -// changes from single threaded to multi threaded it will break the build here. -TEST_F(SigslotDefault, DefaultIsST) { - EXPECT_TRUE(TemplateIsST(this)); - EXPECT_TRUE(TemplateIsST(&signal_)); -} - -// ST slot, ST signal -TEST_F(SigslotSTSlotTest, STLoopbackTest) { - SignalSTLoopback(); - EXPECT_EQ(1, st_loop_back_count()); - EXPECT_EQ(0, mt_loop_back_count()); -} - -// ST slot, MT signal -TEST_F(SigslotSTSlotTest, MTLoopbackTest) { - SignalMTLoopback(); - EXPECT_EQ(1, mt_loop_back_count()); - EXPECT_EQ(0, st_loop_back_count()); -} - -// ST slot, both ST and MT (separate) signal -TEST_F(SigslotSTSlotTest, AllLoopbackTest) { - SignalSTLoopback(); - SignalMTLoopback(); - EXPECT_EQ(1, mt_loop_back_count()); - EXPECT_EQ(1, st_loop_back_count()); -} - -TEST_F(SigslotSTSlotTest, Reconnect) { - SignalSTLoopback(); - SignalMTLoopback(); - EXPECT_EQ(1, mt_loop_back_count()); - EXPECT_EQ(1, st_loop_back_count()); - Disconnect(); - SignalSTLoopback(); - SignalMTLoopback(); - EXPECT_EQ(1, mt_loop_back_count()); - EXPECT_EQ(1, st_loop_back_count()); - Connect(); - SignalSTLoopback(); - SignalMTLoopback(); - EXPECT_EQ(2, mt_loop_back_count()); - EXPECT_EQ(2, st_loop_back_count()); -} - -// MT slot, ST signal -TEST_F(SigslotMTSlotTest, STLoopbackTest) { - SignalSTLoopback(); - EXPECT_EQ(1, st_loop_back_count()); - EXPECT_EQ(0, mt_loop_back_count()); -} - -// MT slot, MT signal -TEST_F(SigslotMTSlotTest, MTLoopbackTest) { - SignalMTLoopback(); - EXPECT_EQ(1, mt_loop_back_count()); - EXPECT_EQ(0, st_loop_back_count()); -} - -// MT slot, both ST and MT (separate) signal -TEST_F(SigslotMTSlotTest, AllLoopbackTest) { - SignalMTLoopback(); - SignalSTLoopback(); - EXPECT_EQ(1, st_loop_back_count()); - EXPECT_EQ(1, mt_loop_back_count()); -} - -// Test that locks are acquired and released correctly. -TEST_F(SigslotMTLockTest, LockSanity) { - const int lock_count = SignalLockCount(); - Signal(); - EXPECT_FALSE(InCriticalSection()); - EXPECT_EQ(lock_count + 1, SignalLockCount()); - EXPECT_EQ(1, signal_count()); -} - -// Destroy signal and slot in different orders. -TEST(DestructionOrder, SignalFirst) { - sigslot::signal0<>* signal = new sigslot::signal0<>; - SigslotReceiver<>* receiver = new SigslotReceiver<>(); - receiver->Connect(signal); - (*signal)(); - EXPECT_EQ(1, receiver->signal_count()); - delete signal; - delete receiver; -} - -TEST(DestructionOrder, SlotFirst) { - sigslot::signal0<>* signal = new sigslot::signal0<>; - SigslotReceiver<>* receiver = new SigslotReceiver<>(); - receiver->Connect(signal); - (*signal)(); - EXPECT_EQ(1, receiver->signal_count()); - - delete receiver; - (*signal)(); - delete signal; -} diff --git a/webrtc/base/sigslotrepeater.h b/webrtc/base/sigslotrepeater.h deleted file mode 100644 index d1c891e02..000000000 --- a/webrtc/base/sigslotrepeater.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SIGSLOTREPEATER_H__ -#define WEBRTC_BASE_SIGSLOTREPEATER_H__ - -// repeaters are both signals and slots, which are designed as intermediate -// pass-throughs for signals and slots which don't know about each other (for -// modularity or encapsulation). This eliminates the need to declare a signal -// handler whose sole purpose is to fire another signal. The repeater connects -// to the originating signal using the 'repeat' method. When the repeated -// signal fires, the repeater will also fire. - -#include "webrtc/base/sigslot.h" - -namespace sigslot { - - template - class repeater0 : public signal0, - public has_slots - { - public: - typedef signal0 base_type; - typedef repeater0 this_type; - - repeater0() { } - repeater0(const this_type& s) : base_type(s) { } - - void reemit() { signal0::emit(); } - void repeat(base_type &s) { s.connect(this, &this_type::reemit); } - void stop(base_type &s) { s.disconnect(this); } - }; - - template - class repeater1 : public signal1, - public has_slots - { - public: - typedef signal1 base_type; - typedef repeater1 this_type; - - repeater1() { } - repeater1(const this_type& s) : base_type(s) { } - - void reemit(arg1_type a1) { signal1::emit(a1); } - void repeat(base_type& s) { s.connect(this, &this_type::reemit); } - void stop(base_type &s) { s.disconnect(this); } - }; - - template - class repeater2 : public signal2, - public has_slots - { - public: - typedef signal2 base_type; - typedef repeater2 this_type; - - repeater2() { } - repeater2(const this_type& s) : base_type(s) { } - - void reemit(arg1_type a1, arg2_type a2) { signal2::emit(a1,a2); } - void repeat(base_type& s) { s.connect(this, &this_type::reemit); } - void stop(base_type &s) { s.disconnect(this); } - }; - - template - class repeater3 : public signal3, - public has_slots - { - public: - typedef signal3 base_type; - typedef repeater3 this_type; - - repeater3() { } - repeater3(const this_type& s) : base_type(s) { } - - void reemit(arg1_type a1, arg2_type a2, arg3_type a3) { - signal3::emit(a1,a2,a3); - } - void repeat(base_type& s) { s.connect(this, &this_type::reemit); } - void stop(base_type &s) { s.disconnect(this); } - }; - -} // namespace sigslot - -#endif // WEBRTC_BASE_SIGSLOTREPEATER_H__ diff --git a/webrtc/base/socket.h b/webrtc/base/socket.h deleted file mode 100644 index 725bd45d1..000000000 --- a/webrtc/base/socket.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SOCKET_H__ -#define WEBRTC_BASE_SOCKET_H__ - -#include - -#if defined(WEBRTC_POSIX) -#include -#include -#include -#include -#define SOCKET_EACCES EACCES -#endif - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#endif - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/socketaddress.h" - -// Rather than converting errors into a private namespace, -// Reuse the POSIX socket api errors. Note this depends on -// Win32 compatibility. - -#if defined(WEBRTC_WIN) -#undef EWOULDBLOCK // Remove errno.h's definition for each macro below. -#define EWOULDBLOCK WSAEWOULDBLOCK -#undef EINPROGRESS -#define EINPROGRESS WSAEINPROGRESS -#undef EALREADY -#define EALREADY WSAEALREADY -#undef ENOTSOCK -#define ENOTSOCK WSAENOTSOCK -#undef EDESTADDRREQ -#define EDESTADDRREQ WSAEDESTADDRREQ -#undef EMSGSIZE -#define EMSGSIZE WSAEMSGSIZE -#undef EPROTOTYPE -#define EPROTOTYPE WSAEPROTOTYPE -#undef ENOPROTOOPT -#define ENOPROTOOPT WSAENOPROTOOPT -#undef EPROTONOSUPPORT -#define EPROTONOSUPPORT WSAEPROTONOSUPPORT -#undef ESOCKTNOSUPPORT -#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT -#undef EOPNOTSUPP -#define EOPNOTSUPP WSAEOPNOTSUPP -#undef EPFNOSUPPORT -#define EPFNOSUPPORT WSAEPFNOSUPPORT -#undef EAFNOSUPPORT -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#undef EADDRINUSE -#define EADDRINUSE WSAEADDRINUSE -#undef EADDRNOTAVAIL -#define EADDRNOTAVAIL WSAEADDRNOTAVAIL -#undef ENETDOWN -#define ENETDOWN WSAENETDOWN -#undef ENETUNREACH -#define ENETUNREACH WSAENETUNREACH -#undef ENETRESET -#define ENETRESET WSAENETRESET -#undef ECONNABORTED -#define ECONNABORTED WSAECONNABORTED -#undef ECONNRESET -#define ECONNRESET WSAECONNRESET -#undef ENOBUFS -#define ENOBUFS WSAENOBUFS -#undef EISCONN -#define EISCONN WSAEISCONN -#undef ENOTCONN -#define ENOTCONN WSAENOTCONN -#undef ESHUTDOWN -#define ESHUTDOWN WSAESHUTDOWN -#undef ETOOMANYREFS -#define ETOOMANYREFS WSAETOOMANYREFS -#undef ETIMEDOUT -#define ETIMEDOUT WSAETIMEDOUT -#undef ECONNREFUSED -#define ECONNREFUSED WSAECONNREFUSED -#undef ELOOP -#define ELOOP WSAELOOP -#undef ENAMETOOLONG -#define ENAMETOOLONG WSAENAMETOOLONG -#undef EHOSTDOWN -#define EHOSTDOWN WSAEHOSTDOWN -#undef EHOSTUNREACH -#define EHOSTUNREACH WSAEHOSTUNREACH -#undef ENOTEMPTY -#define ENOTEMPTY WSAENOTEMPTY -#undef EPROCLIM -#define EPROCLIM WSAEPROCLIM -#undef EUSERS -#define EUSERS WSAEUSERS -#undef EDQUOT -#define EDQUOT WSAEDQUOT -#undef ESTALE -#define ESTALE WSAESTALE -#undef EREMOTE -#define EREMOTE WSAEREMOTE -#undef EACCES -#define SOCKET_EACCES WSAEACCES -#endif // WEBRTC_WIN - -#if defined(WEBRTC_POSIX) -#define INVALID_SOCKET (-1) -#define SOCKET_ERROR (-1) -#define closesocket(s) close(s) -#endif // WEBRTC_POSIX - -namespace rtc { - -inline bool IsBlockingError(int e) { - return (e == EWOULDBLOCK) || (e == EAGAIN) || (e == EINPROGRESS); -} - -// General interface for the socket implementations of various networks. The -// methods match those of normal UNIX sockets very closely. -class Socket { - public: - virtual ~Socket() {} - - // Returns the address to which the socket is bound. If the socket is not - // bound, then the any-address is returned. - virtual SocketAddress GetLocalAddress() const = 0; - - // Returns the address to which the socket is connected. If the socket is - // not connected, then the any-address is returned. - virtual SocketAddress GetRemoteAddress() const = 0; - - virtual int Bind(const SocketAddress& addr) = 0; - virtual int Connect(const SocketAddress& addr) = 0; - virtual int Send(const void *pv, size_t cb) = 0; - virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr) = 0; - virtual int Recv(void *pv, size_t cb) = 0; - virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr) = 0; - virtual int Listen(int backlog) = 0; - virtual Socket *Accept(SocketAddress *paddr) = 0; - virtual int Close() = 0; - virtual int GetError() const = 0; - virtual void SetError(int error) = 0; - inline bool IsBlocking() const { return IsBlockingError(GetError()); } - - enum ConnState { - CS_CLOSED, - CS_CONNECTING, - CS_CONNECTED - }; - virtual ConnState GetState() const = 0; - - // Fills in the given uint16 with the current estimate of the MTU along the - // path to the address to which this socket is connected. NOTE: This method - // can block for up to 10 seconds on Windows. - virtual int EstimateMTU(uint16* mtu) = 0; - - enum Option { - OPT_DONTFRAGMENT, - OPT_RCVBUF, // receive buffer size - 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_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; - - protected: - Socket() {} - - private: - DISALLOW_EVIL_CONSTRUCTORS(Socket); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SOCKET_H__ diff --git a/webrtc/base/socket_unittest.cc b/webrtc/base/socket_unittest.cc deleted file mode 100644 index 6104eda4e..000000000 --- a/webrtc/base/socket_unittest.cc +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/socket_unittest.h" - -#include "webrtc/base/asyncudpsocket.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/nethelpers.h" -#include "webrtc/base/socketserver.h" -#include "webrtc/base/testclient.h" -#include "webrtc/base/testutils.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -#define MAYBE_SKIP_IPV6 \ - if (!HasIPv6Enabled()) { \ - LOG(LS_INFO) << "No IPv6... skipping"; \ - return; \ - } - - -void SocketTest::TestConnectIPv4() { - ConnectInternal(kIPv4Loopback); -} - -void SocketTest::TestConnectIPv6() { - MAYBE_SKIP_IPV6; - ConnectInternal(kIPv6Loopback); -} - -void SocketTest::TestConnectWithDnsLookupIPv4() { - ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost"); -} - -void SocketTest::TestConnectWithDnsLookupIPv6() { - // TODO: Enable this when DNS resolution supports IPv6. - LOG(LS_INFO) << "Skipping IPv6 DNS test"; - // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6"); -} - -void SocketTest::TestConnectFailIPv4() { - ConnectFailInternal(kIPv4Loopback); -} - -void SocketTest::TestConnectFailIPv6() { - MAYBE_SKIP_IPV6; - ConnectFailInternal(kIPv6Loopback); -} - -void SocketTest::TestConnectWithDnsLookupFailIPv4() { - ConnectWithDnsLookupFailInternal(kIPv4Loopback); -} - -void SocketTest::TestConnectWithDnsLookupFailIPv6() { - MAYBE_SKIP_IPV6; - ConnectWithDnsLookupFailInternal(kIPv6Loopback); -} - -void SocketTest::TestConnectWithClosedSocketIPv4() { - ConnectWithClosedSocketInternal(kIPv4Loopback); -} - -void SocketTest::TestConnectWithClosedSocketIPv6() { - MAYBE_SKIP_IPV6; - ConnectWithClosedSocketInternal(kIPv6Loopback); -} - -void SocketTest::TestConnectWhileNotClosedIPv4() { - ConnectWhileNotClosedInternal(kIPv4Loopback); -} - -void SocketTest::TestConnectWhileNotClosedIPv6() { - MAYBE_SKIP_IPV6; - ConnectWhileNotClosedInternal(kIPv6Loopback); -} - -void SocketTest::TestServerCloseDuringConnectIPv4() { - ServerCloseDuringConnectInternal(kIPv4Loopback); -} - -void SocketTest::TestServerCloseDuringConnectIPv6() { - MAYBE_SKIP_IPV6; - ServerCloseDuringConnectInternal(kIPv6Loopback); -} - -void SocketTest::TestClientCloseDuringConnectIPv4() { - ClientCloseDuringConnectInternal(kIPv4Loopback); -} - -void SocketTest::TestClientCloseDuringConnectIPv6() { - MAYBE_SKIP_IPV6; - ClientCloseDuringConnectInternal(kIPv6Loopback); -} - -void SocketTest::TestServerCloseIPv4() { - ServerCloseInternal(kIPv4Loopback); -} - -void SocketTest::TestServerCloseIPv6() { - MAYBE_SKIP_IPV6; - ServerCloseInternal(kIPv6Loopback); -} - -void SocketTest::TestCloseInClosedCallbackIPv4() { - CloseInClosedCallbackInternal(kIPv4Loopback); -} - -void SocketTest::TestCloseInClosedCallbackIPv6() { - MAYBE_SKIP_IPV6; - CloseInClosedCallbackInternal(kIPv6Loopback); -} - -void SocketTest::TestSocketServerWaitIPv4() { - SocketServerWaitInternal(kIPv4Loopback); -} - -void SocketTest::TestSocketServerWaitIPv6() { - MAYBE_SKIP_IPV6; - SocketServerWaitInternal(kIPv6Loopback); -} - -void SocketTest::TestTcpIPv4() { - TcpInternal(kIPv4Loopback); -} - -void SocketTest::TestTcpIPv6() { - MAYBE_SKIP_IPV6; - TcpInternal(kIPv6Loopback); -} - -void SocketTest::TestSingleFlowControlCallbackIPv4() { - SingleFlowControlCallbackInternal(kIPv4Loopback); -} - -void SocketTest::TestSingleFlowControlCallbackIPv6() { - MAYBE_SKIP_IPV6; - SingleFlowControlCallbackInternal(kIPv6Loopback); -} - -void SocketTest::TestUdpIPv4() { - UdpInternal(kIPv4Loopback); -} - -void SocketTest::TestUdpIPv6() { - MAYBE_SKIP_IPV6; - UdpInternal(kIPv6Loopback); -} - -void SocketTest::TestUdpReadyToSendIPv4() { -#if !defined(WEBRTC_MAC) - // TODO(ronghuawu): Enable this test on mac/ios. - UdpReadyToSend(kIPv4Loopback); -#endif -} - -void SocketTest::TestUdpReadyToSendIPv6() { -#if defined(WEBRTC_WIN) - // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux. - MAYBE_SKIP_IPV6; - UdpReadyToSend(kIPv6Loopback); -#endif -} - -void SocketTest::TestGetSetOptionsIPv4() { - GetSetOptionsInternal(kIPv4Loopback); -} - -void SocketTest::TestGetSetOptionsIPv6() { - MAYBE_SKIP_IPV6; - GetSetOptionsInternal(kIPv6Loopback); -} - -// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC -// values on Windows, but an empty address of the same family on Linux/MacOS X. -bool IsUnspecOrEmptyIP(const IPAddress& address) { -#if !defined(WEBRTC_WIN) - return IPIsAny(address); -#else - return address.family() == AF_UNSPEC; -#endif -} - -void SocketTest::ConnectInternal(const IPAddress& loopback) { - testing::StreamSink sink; - SocketAddress accept_addr; - - // Create client. - scoped_ptr client(ss_->CreateAsyncSocket(loopback.family(), - SOCK_STREAM)); - sink.Monitor(client.get()); - EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState()); - EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr()); - - // Create server and listen. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState()); - - // Ensure no pending server connections, since we haven't done anything yet. - EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ)); - EXPECT_TRUE(NULL == server->Accept(&accept_addr)); - EXPECT_TRUE(accept_addr.IsNil()); - - // Attempt connect to listening socket. - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - EXPECT_FALSE(client->GetLocalAddress().IsNil()); - EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress()); - - // Client is connecting, outcome not yet determined. - EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState()); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - - // Server has pending connection, accept it. - EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout); - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(accepted); - EXPECT_FALSE(accept_addr.IsNil()); - EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr); - - // Connected from server perspective, check the addresses are correct. - EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState()); - EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress()); - EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress()); - - // Connected from client perspective, check the addresses are correct. - EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress()); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); -} - -void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback, - const std::string& host) { - testing::StreamSink sink; - SocketAddress accept_addr; - - // Create client. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - - // Create server and listen. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - - // Attempt connect to listening socket. - SocketAddress dns_addr(server->GetLocalAddress()); - dns_addr.SetIP(host); - EXPECT_EQ(0, client->Connect(dns_addr)); - // TODO: Bind when doing DNS lookup. - //EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind - - // Client is connecting, outcome not yet determined. - EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState()); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - - // Server has pending connection, accept it. - EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout); - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(accepted); - EXPECT_FALSE(accept_addr.IsNil()); - EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr); - - // Connected from server perspective, check the addresses are correct. - EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState()); - EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress()); - EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress()); - - // Connected from client perspective, check the addresses are correct. - EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress()); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); -} - -void SocketTest::ConnectFailInternal(const IPAddress& loopback) { - testing::StreamSink sink; - SocketAddress accept_addr; - - // Create client. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - - // Create server, but don't listen yet. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - - // Attempt connect to a non-existent socket. - // We don't connect to the server socket created above, since on - // MacOS it takes about 75 seconds to get back an error! - SocketAddress bogus_addr(loopback, 65535); - EXPECT_EQ(0, client->Connect(bogus_addr)); - - // Wait for connection to fail (ECONNREFUSED). - EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR)); - EXPECT_TRUE(client->GetRemoteAddress().IsNil()); - - // Should be no pending server connections. - EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ)); - EXPECT_TRUE(NULL == server->Accept(&accept_addr)); - EXPECT_EQ(IPAddress(), accept_addr.ipaddr()); -} - -void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) { - testing::StreamSink sink; - SocketAddress accept_addr; - - // Create client. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - - // Create server, but don't listen yet. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - - // Attempt connect to a non-existent host. - // We don't connect to the server socket created above, since on - // MacOS it takes about 75 seconds to get back an error! - SocketAddress bogus_dns_addr("not-a-real-hostname", 65535); - EXPECT_EQ(0, client->Connect(bogus_dns_addr)); - - // Wait for connection to fail (EHOSTNOTFOUND). - bool dns_lookup_finished = false; - WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout, - dns_lookup_finished); - if (!dns_lookup_finished) { - LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 " - << "seconds."; - return; - } - - EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR)); - EXPECT_TRUE(client->GetRemoteAddress().IsNil()); - // Should be no pending server connections. - EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ)); - EXPECT_TRUE(NULL == server->Accept(&accept_addr)); - EXPECT_TRUE(accept_addr.IsNil()); -} - -void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) { - // Create server and listen. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - - // Create a client and put in to CS_CLOSED state. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - EXPECT_EQ(0, client->Close()); - EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState()); - - // Connect() should reinitialize the socket, and put it in to CS_CONNECTING. - EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress()))); - EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState()); -} - -void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) { - // Create server and listen. - testing::StreamSink sink; - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - // Create client, connect. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress()))); - EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState()); - // Try to connect again. Should fail, but not interfere with original attempt. - EXPECT_EQ(SOCKET_ERROR, - client->Connect(SocketAddress(server->GetLocalAddress()))); - - // Accept the original connection. - SocketAddress accept_addr; - EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout); - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(accepted); - EXPECT_FALSE(accept_addr.IsNil()); - - // Check the states and addresses. - EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState()); - EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress()); - EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress()); - EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout); - EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress()); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); - - // Try to connect again, to an unresolved hostname. - // Shouldn't break anything. - EXPECT_EQ(SOCKET_ERROR, - client->Connect(SocketAddress("localhost", - server->GetLocalAddress().port()))); - EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState()); - EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState()); - EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress()); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); -} - -void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) { - testing::StreamSink sink; - - // Create client. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - - // Create server and listen. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - - // Attempt connect to listening socket. - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - // Close down the server while the socket is in the accept queue. - EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout); - server->Close(); - - // This should fail the connection for the client. Clean up. - EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR)); - client->Close(); -} - -void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) { - testing::StreamSink sink; - SocketAddress accept_addr; - - // Create client. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - - // Create server and listen. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - - // Attempt connect to listening socket. - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - // Close down the client while the socket is in the accept queue. - EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout); - client->Close(); - - // The connection should still be able to be accepted. - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(accepted); - sink.Monitor(accepted.get()); - EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState()); - - // The accepted socket should then close (possibly with err, timing-related) - EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) || - sink.Check(accepted.get(), testing::SSE_ERROR)); - - // The client should not get a close event. - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); -} - -void SocketTest::ServerCloseInternal(const IPAddress& loopback) { - testing::StreamSink sink; - SocketAddress accept_addr; - - // Create client. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - - // Create server and listen. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - - // Attempt connection. - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - // Accept connection. - EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout); - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(accepted); - sink.Monitor(accepted.get()); - - // Both sides are now connected. - EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); - EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress()); - - // Send data to the client, and then close the connection. - EXPECT_EQ(1, accepted->Send("a", 1)); - accepted->Close(); - EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState()); - - // Expect that the client is notified, and has not yet closed. - EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState()); - - // Ensure the data can be read. - char buffer[10]; - EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer))); - EXPECT_EQ('a', buffer[0]); - - // Now we should close, but the remote address will remain. - EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE)); - EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP()); - - // The closer should not get a close signal. - EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE)); - EXPECT_TRUE(accepted->GetRemoteAddress().IsNil()); - - // And the closee should only get a single signal. - Thread::Current()->ProcessMessages(0); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - - // Close down the client and ensure all is good. - client->Close(); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - EXPECT_TRUE(client->GetRemoteAddress().IsNil()); -} - -class SocketCloser : public sigslot::has_slots<> { - public: - void OnClose(AsyncSocket* socket, int error) { - socket->Close(); // Deleting here would blow up the vector of handlers - // for the socket's signal. - } -}; - -void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) { - testing::StreamSink sink; - SocketCloser closer; - SocketAddress accept_addr; - - // Create client. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose); - - // Create server and listen. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - - // Attempt connection. - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - // Accept connection. - EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout); - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(accepted); - sink.Monitor(accepted.get()); - - // Both sides are now connected. - EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); - EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress()); - - // Send data to the client, and then close the connection. - accepted->Close(); - EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState()); - - // Expect that the client is notified, and has not yet closed. - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState()); - - // Now we should be closed and invalidated - EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE)); - EXPECT_TRUE(Socket::CS_CLOSED == client->GetState()); -} - -class Sleeper : public MessageHandler { - public: - Sleeper() {} - void OnMessage(Message* msg) { - Thread::Current()->SleepMs(500); - } -}; - -void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) { - testing::StreamSink sink; - SocketAddress accept_addr; - - // Create & connect server and client sockets. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout); - - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(accepted); - sink.Monitor(accepted.get()); - EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState()); - EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress()); - EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress()); - - EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress()); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); - - // Do an i/o operation, triggering an eventual callback. - EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ)); - char buf[1024] = {0}; - - EXPECT_EQ(1024, client->Send(buf, 1024)); - EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ)); - - // Shouldn't signal when blocked in a thread Send, where process_io is false. - scoped_ptr thread(new Thread()); - thread->Start(); - Sleeper sleeper; - TypedMessageData data(client.get()); - thread->Send(&sleeper, 0, &data); - EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ)); - - // But should signal when process_io is true. - EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout); - EXPECT_LT(0, accepted->Recv(buf, 1024)); -} - -void SocketTest::TcpInternal(const IPAddress& loopback) { - testing::StreamSink sink; - SocketAddress accept_addr; - - // Create test data. - const size_t kDataSize = 1024 * 1024; - scoped_ptr send_buffer(new char[kDataSize]); - scoped_ptr recv_buffer(new char[kDataSize]); - size_t send_pos = 0, recv_pos = 0; - for (size_t i = 0; i < kDataSize; ++i) { - send_buffer[i] = static_cast(i % 256); - recv_buffer[i] = 0; - } - - // Create client. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - - // Create server and listen. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - - // Attempt connection. - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - // Accept connection. - EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout); - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(accepted); - sink.Monitor(accepted.get()); - - // Both sides are now connected. - EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); - EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress()); - - // Send and receive a bunch of data. - bool send_waiting_for_writability = false; - bool send_expect_success = true; - bool recv_waiting_for_readability = true; - bool recv_expect_success = false; - int data_in_flight = 0; - while (recv_pos < kDataSize) { - // Send as much as we can if we've been cleared to send. - while (!send_waiting_for_writability && send_pos < kDataSize) { - int tosend = static_cast(kDataSize - send_pos); - int sent = accepted->Send(send_buffer.get() + send_pos, tosend); - if (send_expect_success) { - // The first Send() after connecting or getting writability should - // succeed and send some data. - EXPECT_GT(sent, 0); - send_expect_success = false; - } - if (sent >= 0) { - EXPECT_LE(sent, tosend); - send_pos += sent; - data_in_flight += sent; - } else { - ASSERT_TRUE(accepted->IsBlocking()); - send_waiting_for_writability = true; - } - } - - // Read all the sent data. - while (data_in_flight > 0) { - if (recv_waiting_for_readability) { - // Wait until data is available. - EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout); - recv_waiting_for_readability = false; - recv_expect_success = true; - } - - // Receive as much as we can get in a single recv call. - int rcvd = client->Recv(recv_buffer.get() + recv_pos, - kDataSize - recv_pos); - - if (recv_expect_success) { - // The first Recv() after getting readability should succeed and receive - // some data. - // TODO: The following line is disabled due to flakey pulse - // builds. Re-enable if/when possible. - // EXPECT_GT(rcvd, 0); - recv_expect_success = false; - } - if (rcvd >= 0) { - EXPECT_LE(rcvd, data_in_flight); - recv_pos += rcvd; - data_in_flight -= rcvd; - } else { - ASSERT_TRUE(client->IsBlocking()); - recv_waiting_for_readability = true; - } - } - - // Once all that we've sent has been rcvd, expect to be able to send again. - if (send_waiting_for_writability) { - EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), - kTimeout); - send_waiting_for_writability = false; - send_expect_success = true; - } - } - - // The received data matches the sent data. - EXPECT_EQ(kDataSize, send_pos); - EXPECT_EQ(kDataSize, recv_pos); - EXPECT_EQ(0, memcmp(recv_buffer.get(), send_buffer.get(), kDataSize)); - - // Close down. - accepted->Close(); - EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE)); - client->Close(); -} - -void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) { - testing::StreamSink sink; - SocketAddress accept_addr; - - // Create client. - scoped_ptr client( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(client.get()); - - // Create server and listen. - scoped_ptr server( - ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); - EXPECT_EQ(0, server->Listen(5)); - - // Attempt connection. - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - // Accept connection. - EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout); - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(accepted); - sink.Monitor(accepted.get()); - - // Both sides are now connected. - EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN)); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); - EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress()); - - // Expect a writable callback from the connect. - EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout); - - // Fill the socket buffer. - char buf[1024 * 16] = {0}; - int sends = 0; - while (++sends && accepted->Send(&buf, ARRAY_SIZE(buf)) != -1) {} - EXPECT_TRUE(accepted->IsBlocking()); - - // Wait until data is available. - EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout); - - // Pull data. - for (int i = 0; i < sends; ++i) { - client->Recv(buf, ARRAY_SIZE(buf)); - } - - // Expect at least one additional writable callback. - EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout); - - // Adding data in response to the writeable callback shouldn't cause infinite - // callbacks. - int extras = 0; - for (int i = 0; i < 100; ++i) { - accepted->Send(&buf, ARRAY_SIZE(buf)); - rtc::Thread::Current()->ProcessMessages(1); - if (sink.Check(accepted.get(), testing::SSE_WRITE)) { - extras++; - } - } - EXPECT_LT(extras, 2); - - // Close down. - accepted->Close(); - client->Close(); -} - -void SocketTest::UdpInternal(const IPAddress& loopback) { - SocketAddress empty = EmptySocketAddressWithFamily(loopback.family()); - // Test basic bind and connect behavior. - AsyncSocket* socket = - ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM); - EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState()); - EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0))); - SocketAddress addr1 = socket->GetLocalAddress(); - EXPECT_EQ(0, socket->Connect(addr1)); - EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState()); - socket->Close(); - EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState()); - delete socket; - - // Test send/receive behavior. - scoped_ptr client1( - new TestClient(AsyncUDPSocket::Create(ss_, addr1))); - scoped_ptr client2( - new TestClient(AsyncUDPSocket::Create(ss_, empty))); - - SocketAddress addr2; - EXPECT_EQ(3, client2->SendTo("foo", 3, addr1)); - EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2)); - - SocketAddress addr3; - EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2)); - EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3)); - EXPECT_EQ(addr3, addr1); - // TODO: figure out what the intent is here - for (int i = 0; i < 10; ++i) { - client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty))); - - SocketAddress addr4; - EXPECT_EQ(3, client2->SendTo("foo", 3, addr1)); - EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4)); - EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr()); - - SocketAddress addr5; - EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4)); - EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5)); - EXPECT_EQ(addr5, addr1); - - addr2 = addr4; - } -} - -void SocketTest::UdpReadyToSend(const IPAddress& loopback) { - SocketAddress empty = EmptySocketAddressWithFamily(loopback.family()); - // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in - // documentation. - // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix. - std::string dest = (loopback.family() == AF_INET6) ? - "2001:db8::1" : "192.0.2.0"; - SocketAddress test_addr(dest, 2345); - - // Test send - scoped_ptr client( - new TestClient(AsyncUDPSocket::Create(ss_, empty))); - int test_packet_size = 1200; - rtc::scoped_ptr test_packet(new char[test_packet_size]); - // Init the test packet just to avoid memcheck warning. - memset(test_packet.get(), 0, test_packet_size); - // Set the send buffer size to the same size as the test packet to have a - // better chance to get EWOULDBLOCK. - int send_buffer_size = test_packet_size; -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - send_buffer_size /= 2; -#endif - client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size); - - int error = 0; - uint32 start_ms = Time(); - int sent_packet_num = 0; - int expected_error = EWOULDBLOCK; - while (start_ms + kTimeout > Time()) { - int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr); - ++sent_packet_num; - if (ret != test_packet_size) { - error = client->GetError(); - if (error == expected_error) { - LOG(LS_INFO) << "Got expected error code after sending " - << sent_packet_num << " packets."; - break; - } - } - } - EXPECT_EQ(expected_error, error); - EXPECT_FALSE(client->ready_to_send()); - EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout); - LOG(LS_INFO) << "Got SignalReadyToSend"; -} - -void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) { - rtc::scoped_ptr socket( - ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM)); - socket->Bind(SocketAddress(loopback, 0)); - - // Check SNDBUF/RCVBUF. - const int desired_size = 12345; -#if defined(WEBRTC_LINUX) - // Yes, really. It's in the kernel source. - const int expected_size = desired_size * 2; -#else // !WEBRTC_LINUX - const int expected_size = desired_size; -#endif // !WEBRTC_LINUX - int recv_size = 0; - int send_size = 0; - // get the initial sizes - ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size)); - ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size)); - // set our desired sizes - ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size)); - ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size)); - // get the sizes again - ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size)); - ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size)); - // make sure they are right - ASSERT_EQ(expected_size, recv_size); - ASSERT_EQ(expected_size, send_size); - - // Check that we can't set NODELAY on a UDP socket. - int current_nd, desired_nd = 1; - ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, ¤t_nd)); - ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd)); - - // Skip the esimate MTU test for IPv6 for now. - if (loopback.family() != AF_INET6) { - // Try estimating MTU. - rtc::scoped_ptr - mtu_socket( - ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM)); - mtu_socket->Bind(SocketAddress(loopback, 0)); - uint16 mtu; - // should fail until we connect - ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu)); - mtu_socket->Connect(SocketAddress(loopback, 0)); -#if defined(WEBRTC_WIN) - // now it should succeed - ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu)); - ASSERT_GE(mtu, 1492); // should be at least the 1492 "plateau" on localhost -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - // except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented - ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu)); -#else - // and the behavior seems unpredictable on Linux, - // failing on the build machine - // but succeeding on my Ubiquity instance. -#endif - } -} - -} // namespace rtc diff --git a/webrtc/base/socket_unittest.h b/webrtc/base/socket_unittest.h deleted file mode 100644 index d368afb3f..000000000 --- a/webrtc/base/socket_unittest.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SOCKET_UNITTEST_H_ -#define WEBRTC_BASE_SOCKET_UNITTEST_H_ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -// Generic socket tests, to be used when testing individual socketservers. -// Derive your specific test class from SocketTest, install your -// socketserver, and call the SocketTest test methods. -class SocketTest : public testing::Test { - protected: - SocketTest() : ss_(NULL), kIPv4Loopback(INADDR_LOOPBACK), - kIPv6Loopback(in6addr_loopback) {} - virtual void SetUp() { ss_ = Thread::Current()->socketserver(); } - void TestConnectIPv4(); - void TestConnectIPv6(); - void TestConnectWithDnsLookupIPv4(); - void TestConnectWithDnsLookupIPv6(); - void TestConnectFailIPv4(); - void TestConnectFailIPv6(); - void TestConnectWithDnsLookupFailIPv4(); - void TestConnectWithDnsLookupFailIPv6(); - void TestConnectWithClosedSocketIPv4(); - void TestConnectWithClosedSocketIPv6(); - void TestConnectWhileNotClosedIPv4(); - void TestConnectWhileNotClosedIPv6(); - void TestServerCloseDuringConnectIPv4(); - void TestServerCloseDuringConnectIPv6(); - void TestClientCloseDuringConnectIPv4(); - void TestClientCloseDuringConnectIPv6(); - void TestServerCloseIPv4(); - void TestServerCloseIPv6(); - void TestCloseInClosedCallbackIPv4(); - void TestCloseInClosedCallbackIPv6(); - void TestSocketServerWaitIPv4(); - void TestSocketServerWaitIPv6(); - void TestTcpIPv4(); - void TestTcpIPv6(); - void TestSingleFlowControlCallbackIPv4(); - void TestSingleFlowControlCallbackIPv6(); - void TestUdpIPv4(); - void TestUdpIPv6(); - void TestUdpReadyToSendIPv4(); - void TestUdpReadyToSendIPv6(); - void TestGetSetOptionsIPv4(); - void TestGetSetOptionsIPv6(); - - private: - void ConnectInternal(const IPAddress& loopback); - void ConnectWithDnsLookupInternal(const IPAddress& loopback, - const std::string& host); - void ConnectFailInternal(const IPAddress& loopback); - - void ConnectWithDnsLookupFailInternal(const IPAddress& loopback); - void ConnectWithClosedSocketInternal(const IPAddress& loopback); - void ConnectWhileNotClosedInternal(const IPAddress& loopback); - void ServerCloseDuringConnectInternal(const IPAddress& loopback); - void ClientCloseDuringConnectInternal(const IPAddress& loopback); - void ServerCloseInternal(const IPAddress& loopback); - void CloseInClosedCallbackInternal(const IPAddress& loopback); - void SocketServerWaitInternal(const IPAddress& loopback); - void TcpInternal(const IPAddress& loopback); - void SingleFlowControlCallbackInternal(const IPAddress& loopback); - void UdpInternal(const IPAddress& loopback); - void UdpReadyToSend(const IPAddress& loopback); - void GetSetOptionsInternal(const IPAddress& loopback); - - static const int kTimeout = 5000; // ms - SocketServer* ss_; - const IPAddress kIPv4Loopback; - const IPAddress kIPv6Loopback; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SOCKET_UNITTEST_H_ diff --git a/webrtc/base/socketadapters.cc b/webrtc/base/socketadapters.cc deleted file mode 100644 index 1cdd1bcbe..000000000 --- a/webrtc/base/socketadapters.cc +++ /dev/null @@ -1,893 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(_MSC_VER) && _MSC_VER < 1300 -#pragma warning(disable:4786) -#endif - -#include -#include - -#if defined(WEBRTC_WIN) -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#define SECURITY_WIN32 -#include -#endif - -#include "webrtc/base/bytebuffer.h" -#include "webrtc/base/common.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/socketadapters.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/stringutils.h" - -#if defined(WEBRTC_WIN) -#include "webrtc/base/sec_buffer.h" -#endif // WEBRTC_WIN - -namespace rtc { - -BufferedReadAdapter::BufferedReadAdapter(AsyncSocket* socket, size_t size) - : AsyncSocketAdapter(socket), buffer_size_(size), - data_len_(0), buffering_(false) { - buffer_ = new char[buffer_size_]; -} - -BufferedReadAdapter::~BufferedReadAdapter() { - delete [] buffer_; -} - -int BufferedReadAdapter::Send(const void *pv, size_t cb) { - if (buffering_) { - // TODO: Spoof error better; Signal Writeable - socket_->SetError(EWOULDBLOCK); - return -1; - } - return AsyncSocketAdapter::Send(pv, cb); -} - -int BufferedReadAdapter::Recv(void *pv, size_t cb) { - if (buffering_) { - socket_->SetError(EWOULDBLOCK); - return -1; - } - - size_t read = 0; - - if (data_len_) { - read = _min(cb, data_len_); - memcpy(pv, buffer_, read); - data_len_ -= read; - if (data_len_ > 0) { - memmove(buffer_, buffer_ + read, data_len_); - } - pv = static_cast(pv) + read; - cb -= read; - } - - // FIX: If cb == 0, we won't generate another read event - - int res = AsyncSocketAdapter::Recv(pv, cb); - if (res < 0) - return res; - - return res + static_cast(read); -} - -void BufferedReadAdapter::BufferInput(bool on) { - buffering_ = on; -} - -void BufferedReadAdapter::OnReadEvent(AsyncSocket * socket) { - ASSERT(socket == socket_); - - if (!buffering_) { - AsyncSocketAdapter::OnReadEvent(socket); - return; - } - - if (data_len_ >= buffer_size_) { - LOG(INFO) << "Input buffer overflow"; - ASSERT(false); - data_len_ = 0; - } - - int len = socket_->Recv(buffer_ + data_len_, buffer_size_ - data_len_); - if (len < 0) { - // TODO: Do something better like forwarding the error to the user. - LOG_ERR(INFO) << "Recv"; - return; - } - - data_len_ += len; - - ProcessInput(buffer_, &data_len_); -} - -/////////////////////////////////////////////////////////////////////////////// - -// This is a SSL v2 CLIENT_HELLO message. -// TODO: Should this have a session id? The response doesn't have a -// certificate, so the hello should have a session id. -static const uint8 kSslClientHello[] = { - 0x80, 0x46, // msg len - 0x01, // CLIENT_HELLO - 0x03, 0x01, // SSL 3.1 - 0x00, 0x2d, // ciphersuite len - 0x00, 0x00, // session id len - 0x00, 0x10, // challenge len - 0x01, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0xc0, // ciphersuites - 0x06, 0x00, 0x40, 0x02, 0x00, 0x80, 0x04, 0x00, 0x80, // - 0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a, // - 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, // - 0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, // - 0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc, // challenge - 0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea // -}; - -// This is a TLSv1 SERVER_HELLO message. -static const uint8 kSslServerHello[] = { - 0x16, // handshake message - 0x03, 0x01, // SSL 3.1 - 0x00, 0x4a, // message len - 0x02, // SERVER_HELLO - 0x00, 0x00, 0x46, // handshake len - 0x03, 0x01, // SSL 3.1 - 0x42, 0x85, 0x45, 0xa7, 0x27, 0xa9, 0x5d, 0xa0, // server random - 0xb3, 0xc5, 0xe7, 0x53, 0xda, 0x48, 0x2b, 0x3f, // - 0xc6, 0x5a, 0xca, 0x89, 0xc1, 0x58, 0x52, 0xa1, // - 0x78, 0x3c, 0x5b, 0x17, 0x46, 0x00, 0x85, 0x3f, // - 0x20, // session id len - 0x0e, 0xd3, 0x06, 0x72, 0x5b, 0x5b, 0x1b, 0x5f, // session id - 0x15, 0xac, 0x13, 0xf9, 0x88, 0x53, 0x9d, 0x9b, // - 0xe8, 0x3d, 0x7b, 0x0c, 0x30, 0x32, 0x6e, 0x38, // - 0x4d, 0xa2, 0x75, 0x57, 0x41, 0x6c, 0x34, 0x5c, // - 0x00, 0x04, // RSA/RC4-128/MD5 - 0x00 // null compression -}; - -AsyncSSLSocket::AsyncSSLSocket(AsyncSocket* socket) - : BufferedReadAdapter(socket, 1024) { -} - -int AsyncSSLSocket::Connect(const SocketAddress& addr) { - // Begin buffering before we connect, so that there isn't a race condition - // between potential senders and receiving the OnConnectEvent signal - BufferInput(true); - return BufferedReadAdapter::Connect(addr); -} - -void AsyncSSLSocket::OnConnectEvent(AsyncSocket * socket) { - ASSERT(socket == socket_); - // TODO: we could buffer output too... - VERIFY(sizeof(kSslClientHello) == - DirectSend(kSslClientHello, sizeof(kSslClientHello))); -} - -void AsyncSSLSocket::ProcessInput(char* data, size_t* len) { - if (*len < sizeof(kSslServerHello)) - return; - - if (memcmp(kSslServerHello, data, sizeof(kSslServerHello)) != 0) { - Close(); - SignalCloseEvent(this, 0); // TODO: error code? - return; - } - - *len -= sizeof(kSslServerHello); - if (*len > 0) { - memmove(data, data + sizeof(kSslServerHello), *len); - } - - bool remainder = (*len > 0); - BufferInput(false); - SignalConnectEvent(this); - - // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble - if (remainder) - SignalReadEvent(this); -} - -AsyncSSLServerSocket::AsyncSSLServerSocket(AsyncSocket* socket) - : BufferedReadAdapter(socket, 1024) { - BufferInput(true); -} - -void AsyncSSLServerSocket::ProcessInput(char* data, size_t* len) { - // We only accept client hello messages. - if (*len < sizeof(kSslClientHello)) { - return; - } - - if (memcmp(kSslClientHello, data, sizeof(kSslClientHello)) != 0) { - Close(); - SignalCloseEvent(this, 0); - return; - } - - *len -= sizeof(kSslClientHello); - - // Clients should not send more data until the handshake is completed. - ASSERT(*len == 0); - - // Send a server hello back to the client. - DirectSend(kSslServerHello, sizeof(kSslServerHello)); - - // Handshake completed for us, redirect input to our parent. - BufferInput(false); -} - -/////////////////////////////////////////////////////////////////////////////// - -AsyncHttpsProxySocket::AsyncHttpsProxySocket(AsyncSocket* socket, - const std::string& user_agent, - const SocketAddress& proxy, - const std::string& username, - const CryptString& password) - : BufferedReadAdapter(socket, 1024), proxy_(proxy), agent_(user_agent), - user_(username), pass_(password), force_connect_(false), state_(PS_ERROR), - context_(0) { -} - -AsyncHttpsProxySocket::~AsyncHttpsProxySocket() { - delete context_; -} - -int AsyncHttpsProxySocket::Connect(const SocketAddress& addr) { - int ret; - LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::Connect(" - << proxy_.ToSensitiveString() << ")"; - dest_ = addr; - state_ = PS_INIT; - if (ShouldIssueConnect()) { - BufferInput(true); - } - ret = BufferedReadAdapter::Connect(proxy_); - // TODO: Set state_ appropriately if Connect fails. - return ret; -} - -SocketAddress AsyncHttpsProxySocket::GetRemoteAddress() const { - return dest_; -} - -int AsyncHttpsProxySocket::Close() { - headers_.clear(); - state_ = PS_ERROR; - dest_.Clear(); - delete context_; - context_ = NULL; - return BufferedReadAdapter::Close(); -} - -Socket::ConnState AsyncHttpsProxySocket::GetState() const { - if (state_ < PS_TUNNEL) { - return CS_CONNECTING; - } else if (state_ == PS_TUNNEL) { - return CS_CONNECTED; - } else { - return CS_CLOSED; - } -} - -void AsyncHttpsProxySocket::OnConnectEvent(AsyncSocket * socket) { - LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::OnConnectEvent"; - if (!ShouldIssueConnect()) { - state_ = PS_TUNNEL; - BufferedReadAdapter::OnConnectEvent(socket); - return; - } - SendRequest(); -} - -void AsyncHttpsProxySocket::OnCloseEvent(AsyncSocket * socket, int err) { - LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::OnCloseEvent(" << err << ")"; - if ((state_ == PS_WAIT_CLOSE) && (err == 0)) { - state_ = PS_ERROR; - Connect(dest_); - } else { - BufferedReadAdapter::OnCloseEvent(socket, err); - } -} - -void AsyncHttpsProxySocket::ProcessInput(char* data, size_t* len) { - size_t start = 0; - for (size_t pos = start; state_ < PS_TUNNEL && pos < *len;) { - if (state_ == PS_SKIP_BODY) { - size_t consume = _min(*len - pos, content_length_); - pos += consume; - start = pos; - content_length_ -= consume; - if (content_length_ == 0) { - EndResponse(); - } - continue; - } - - if (data[pos++] != '\n') - continue; - - size_t len = pos - start - 1; - if ((len > 0) && (data[start + len - 1] == '\r')) - --len; - - data[start + len] = 0; - ProcessLine(data + start, len); - start = pos; - } - - *len -= start; - if (*len > 0) { - memmove(data, data + start, *len); - } - - if (state_ != PS_TUNNEL) - return; - - bool remainder = (*len > 0); - BufferInput(false); - SignalConnectEvent(this); - - // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble - if (remainder) - SignalReadEvent(this); // TODO: signal this?? -} - -bool AsyncHttpsProxySocket::ShouldIssueConnect() const { - // TODO: Think about whether a more sophisticated test - // than dest port == 80 is needed. - return force_connect_ || (dest_.port() != 80); -} - -void AsyncHttpsProxySocket::SendRequest() { - std::stringstream ss; - ss << "CONNECT " << dest_.ToString() << " HTTP/1.0\r\n"; - ss << "User-Agent: " << agent_ << "\r\n"; - ss << "Host: " << dest_.HostAsURIString() << "\r\n"; - ss << "Content-Length: 0\r\n"; - ss << "Proxy-Connection: Keep-Alive\r\n"; - ss << headers_; - ss << "\r\n"; - std::string str = ss.str(); - DirectSend(str.c_str(), str.size()); - state_ = PS_LEADER; - expect_close_ = true; - content_length_ = 0; - headers_.clear(); - - LOG(LS_VERBOSE) << "AsyncHttpsProxySocket >> " << str; -} - -void AsyncHttpsProxySocket::ProcessLine(char * data, size_t len) { - LOG(LS_VERBOSE) << "AsyncHttpsProxySocket << " << data; - - if (len == 0) { - if (state_ == PS_TUNNEL_HEADERS) { - state_ = PS_TUNNEL; - } else if (state_ == PS_ERROR_HEADERS) { - Error(defer_error_); - return; - } else if (state_ == PS_SKIP_HEADERS) { - if (content_length_) { - state_ = PS_SKIP_BODY; - } else { - EndResponse(); - return; - } - } else { - static bool report = false; - if (!unknown_mechanisms_.empty() && !report) { - report = true; - std::string msg( - "Unable to connect to the Google Talk service due to an incompatibility " - "with your proxy.\r\nPlease help us resolve this issue by submitting the " - "following information to us using our technical issue submission form " - "at:\r\n\r\n" - "http://www.google.com/support/talk/bin/request.py\r\n\r\n" - "We apologize for the inconvenience.\r\n\r\n" - "Information to submit to Google: " - ); - //std::string msg("Please report the following information to foo@bar.com:\r\nUnknown methods: "); - msg.append(unknown_mechanisms_); -#if defined(WEBRTC_WIN) - MessageBoxA(0, msg.c_str(), "Oops!", MB_OK); -#endif -#if defined(WEBRTC_POSIX) - // TODO: Raise a signal so the UI can be separated. - LOG(LS_ERROR) << "Oops!\n\n" << msg; -#endif - } - // Unexpected end of headers - Error(0); - return; - } - } else if (state_ == PS_LEADER) { - unsigned int code; - if (sscanf(data, "HTTP/%*u.%*u %u", &code) != 1) { - Error(0); - return; - } - switch (code) { - case 200: - // connection good! - state_ = PS_TUNNEL_HEADERS; - return; -#if defined(HTTP_STATUS_PROXY_AUTH_REQ) && (HTTP_STATUS_PROXY_AUTH_REQ != 407) -#error Wrong code for HTTP_STATUS_PROXY_AUTH_REQ -#endif - case 407: // HTTP_STATUS_PROXY_AUTH_REQ - state_ = PS_AUTHENTICATE; - return; - default: - defer_error_ = 0; - state_ = PS_ERROR_HEADERS; - return; - } - } else if ((state_ == PS_AUTHENTICATE) - && (_strnicmp(data, "Proxy-Authenticate:", 19) == 0)) { - std::string response, auth_method; - switch (HttpAuthenticate(data + 19, len - 19, - proxy_, "CONNECT", "/", - user_, pass_, context_, response, auth_method)) { - case HAR_IGNORE: - LOG(LS_VERBOSE) << "Ignoring Proxy-Authenticate: " << auth_method; - if (!unknown_mechanisms_.empty()) - unknown_mechanisms_.append(", "); - unknown_mechanisms_.append(auth_method); - break; - case HAR_RESPONSE: - headers_ = "Proxy-Authorization: "; - headers_.append(response); - headers_.append("\r\n"); - state_ = PS_SKIP_HEADERS; - unknown_mechanisms_.clear(); - break; - case HAR_CREDENTIALS: - defer_error_ = SOCKET_EACCES; - state_ = PS_ERROR_HEADERS; - unknown_mechanisms_.clear(); - break; - case HAR_ERROR: - defer_error_ = 0; - state_ = PS_ERROR_HEADERS; - unknown_mechanisms_.clear(); - break; - } - } else if (_strnicmp(data, "Content-Length:", 15) == 0) { - content_length_ = strtoul(data + 15, 0, 0); - } else if (_strnicmp(data, "Proxy-Connection: Keep-Alive", 28) == 0) { - expect_close_ = false; - /* - } else if (_strnicmp(data, "Connection: close", 17) == 0) { - expect_close_ = true; - */ - } -} - -void AsyncHttpsProxySocket::EndResponse() { - if (!expect_close_) { - SendRequest(); - return; - } - - // No point in waiting for the server to close... let's close now - // TODO: Refactor out PS_WAIT_CLOSE - state_ = PS_WAIT_CLOSE; - BufferedReadAdapter::Close(); - OnCloseEvent(this, 0); -} - -void AsyncHttpsProxySocket::Error(int error) { - BufferInput(false); - Close(); - SetError(error); - SignalCloseEvent(this, error); -} - -/////////////////////////////////////////////////////////////////////////////// - -AsyncSocksProxySocket::AsyncSocksProxySocket(AsyncSocket* socket, - const SocketAddress& proxy, - const std::string& username, - const CryptString& password) - : BufferedReadAdapter(socket, 1024), state_(SS_ERROR), proxy_(proxy), - user_(username), pass_(password) { -} - -int AsyncSocksProxySocket::Connect(const SocketAddress& addr) { - int ret; - dest_ = addr; - state_ = SS_INIT; - BufferInput(true); - ret = BufferedReadAdapter::Connect(proxy_); - // TODO: Set state_ appropriately if Connect fails. - return ret; -} - -SocketAddress AsyncSocksProxySocket::GetRemoteAddress() const { - return dest_; -} - -int AsyncSocksProxySocket::Close() { - state_ = SS_ERROR; - dest_.Clear(); - return BufferedReadAdapter::Close(); -} - -Socket::ConnState AsyncSocksProxySocket::GetState() const { - if (state_ < SS_TUNNEL) { - return CS_CONNECTING; - } else if (state_ == SS_TUNNEL) { - return CS_CONNECTED; - } else { - return CS_CLOSED; - } -} - -void AsyncSocksProxySocket::OnConnectEvent(AsyncSocket* socket) { - SendHello(); -} - -void AsyncSocksProxySocket::ProcessInput(char* data, size_t* len) { - ASSERT(state_ < SS_TUNNEL); - - ByteBuffer response(data, *len); - - if (state_ == SS_HELLO) { - uint8 ver, method; - if (!response.ReadUInt8(&ver) || - !response.ReadUInt8(&method)) - return; - - if (ver != 5) { - Error(0); - return; - } - - if (method == 0) { - SendConnect(); - } else if (method == 2) { - SendAuth(); - } else { - Error(0); - return; - } - } else if (state_ == SS_AUTH) { - uint8 ver, status; - if (!response.ReadUInt8(&ver) || - !response.ReadUInt8(&status)) - return; - - if ((ver != 1) || (status != 0)) { - Error(SOCKET_EACCES); - return; - } - - SendConnect(); - } else if (state_ == SS_CONNECT) { - uint8 ver, rep, rsv, atyp; - if (!response.ReadUInt8(&ver) || - !response.ReadUInt8(&rep) || - !response.ReadUInt8(&rsv) || - !response.ReadUInt8(&atyp)) - return; - - if ((ver != 5) || (rep != 0)) { - Error(0); - return; - } - - uint16 port; - if (atyp == 1) { - uint32 addr; - if (!response.ReadUInt32(&addr) || - !response.ReadUInt16(&port)) - return; - LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; - } else if (atyp == 3) { - uint8 len; - std::string addr; - if (!response.ReadUInt8(&len) || - !response.ReadString(&addr, len) || - !response.ReadUInt16(&port)) - return; - LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; - } else if (atyp == 4) { - std::string addr; - if (!response.ReadString(&addr, 16) || - !response.ReadUInt16(&port)) - return; - LOG(LS_VERBOSE) << "Bound on :" << port; - } else { - Error(0); - return; - } - - state_ = SS_TUNNEL; - } - - // Consume parsed data - *len = response.Length(); - memcpy(data, response.Data(), *len); - - if (state_ != SS_TUNNEL) - return; - - bool remainder = (*len > 0); - BufferInput(false); - SignalConnectEvent(this); - - // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble - if (remainder) - SignalReadEvent(this); // TODO: signal this?? -} - -void AsyncSocksProxySocket::SendHello() { - ByteBuffer request; - request.WriteUInt8(5); // Socks Version - if (user_.empty()) { - request.WriteUInt8(1); // Authentication Mechanisms - request.WriteUInt8(0); // No authentication - } else { - request.WriteUInt8(2); // Authentication Mechanisms - request.WriteUInt8(0); // No authentication - request.WriteUInt8(2); // Username/Password - } - DirectSend(request.Data(), request.Length()); - state_ = SS_HELLO; -} - -void AsyncSocksProxySocket::SendAuth() { - ByteBuffer request; - request.WriteUInt8(1); // Negotiation Version - request.WriteUInt8(static_cast(user_.size())); - request.WriteString(user_); // Username - request.WriteUInt8(static_cast(pass_.GetLength())); - size_t len = pass_.GetLength() + 1; - char * sensitive = new char[len]; - pass_.CopyTo(sensitive, true); - request.WriteString(sensitive); // Password - memset(sensitive, 0, len); - delete [] sensitive; - DirectSend(request.Data(), request.Length()); - state_ = SS_AUTH; -} - -void AsyncSocksProxySocket::SendConnect() { - ByteBuffer request; - request.WriteUInt8(5); // Socks Version - request.WriteUInt8(1); // CONNECT - request.WriteUInt8(0); // Reserved - if (dest_.IsUnresolved()) { - std::string hostname = dest_.hostname(); - request.WriteUInt8(3); // DOMAINNAME - request.WriteUInt8(static_cast(hostname.size())); - request.WriteString(hostname); // Destination Hostname - } else { - request.WriteUInt8(1); // IPV4 - request.WriteUInt32(dest_.ip()); // Destination IP - } - request.WriteUInt16(dest_.port()); // Destination Port - DirectSend(request.Data(), request.Length()); - state_ = SS_CONNECT; -} - -void AsyncSocksProxySocket::Error(int error) { - state_ = SS_ERROR; - BufferInput(false); - Close(); - SetError(SOCKET_EACCES); - SignalCloseEvent(this, error); -} - -AsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(AsyncSocket* socket) - : AsyncProxyServerSocket(socket, kBufferSize), state_(SS_HELLO) { - BufferInput(true); -} - -void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) { - // TODO: See if the whole message has arrived - ASSERT(state_ < SS_CONNECT_PENDING); - - ByteBuffer response(data, *len); - if (state_ == SS_HELLO) { - HandleHello(&response); - } else if (state_ == SS_AUTH) { - HandleAuth(&response); - } else if (state_ == SS_CONNECT) { - HandleConnect(&response); - } - - // Consume parsed data - *len = response.Length(); - memcpy(data, response.Data(), *len); -} - -void AsyncSocksProxyServerSocket::DirectSend(const ByteBuffer& buf) { - BufferedReadAdapter::DirectSend(buf.Data(), buf.Length()); -} - -void AsyncSocksProxyServerSocket::HandleHello(ByteBuffer* request) { - uint8 ver, num_methods; - if (!request->ReadUInt8(&ver) || - !request->ReadUInt8(&num_methods)) { - Error(0); - return; - } - - if (ver != 5) { - Error(0); - return; - } - - // Handle either no-auth (0) or user/pass auth (2) - uint8 method = 0xFF; - if (num_methods > 0 && !request->ReadUInt8(&method)) { - Error(0); - return; - } - - // TODO: Ask the server which method to use. - SendHelloReply(method); - if (method == 0) { - state_ = SS_CONNECT; - } else if (method == 2) { - state_ = SS_AUTH; - } else { - state_ = SS_ERROR; - } -} - -void AsyncSocksProxyServerSocket::SendHelloReply(int method) { - ByteBuffer response; - response.WriteUInt8(5); // Socks Version - response.WriteUInt8(method); // Auth method - DirectSend(response); -} - -void AsyncSocksProxyServerSocket::HandleAuth(ByteBuffer* request) { - uint8 ver, user_len, pass_len; - std::string user, pass; - if (!request->ReadUInt8(&ver) || - !request->ReadUInt8(&user_len) || - !request->ReadString(&user, user_len) || - !request->ReadUInt8(&pass_len) || - !request->ReadString(&pass, pass_len)) { - Error(0); - return; - } - - // TODO: Allow for checking of credentials. - SendAuthReply(0); - state_ = SS_CONNECT; -} - -void AsyncSocksProxyServerSocket::SendAuthReply(int result) { - ByteBuffer response; - response.WriteUInt8(1); // Negotiation Version - response.WriteUInt8(result); - DirectSend(response); -} - -void AsyncSocksProxyServerSocket::HandleConnect(ByteBuffer* request) { - uint8 ver, command, reserved, addr_type; - uint32 ip; - uint16 port; - if (!request->ReadUInt8(&ver) || - !request->ReadUInt8(&command) || - !request->ReadUInt8(&reserved) || - !request->ReadUInt8(&addr_type) || - !request->ReadUInt32(&ip) || - !request->ReadUInt16(&port)) { - Error(0); - return; - } - - if (ver != 5 || command != 1 || - reserved != 0 || addr_type != 1) { - Error(0); - return; - } - - SignalConnectRequest(this, SocketAddress(ip, port)); - state_ = SS_CONNECT_PENDING; -} - -void AsyncSocksProxyServerSocket::SendConnectResult(int result, - const SocketAddress& addr) { - if (state_ != SS_CONNECT_PENDING) - return; - - ByteBuffer response; - response.WriteUInt8(5); // Socks version - response.WriteUInt8((result != 0)); // 0x01 is generic error - response.WriteUInt8(0); // reserved - response.WriteUInt8(1); // IPv4 address - response.WriteUInt32(addr.ip()); - response.WriteUInt16(addr.port()); - DirectSend(response); - BufferInput(false); - state_ = SS_TUNNEL; -} - -void AsyncSocksProxyServerSocket::Error(int error) { - state_ = SS_ERROR; - BufferInput(false); - Close(); - SetError(SOCKET_EACCES); - SignalCloseEvent(this, error); -} - -/////////////////////////////////////////////////////////////////////////////// - -LoggingSocketAdapter::LoggingSocketAdapter(AsyncSocket* socket, - LoggingSeverity level, - const char * label, bool hex_mode) - : AsyncSocketAdapter(socket), level_(level), hex_mode_(hex_mode) { - label_.append("["); - label_.append(label); - label_.append("]"); -} - -int LoggingSocketAdapter::Send(const void *pv, size_t cb) { - int res = AsyncSocketAdapter::Send(pv, cb); - if (res > 0) - LogMultiline(level_, label_.c_str(), false, pv, res, hex_mode_, &lms_); - return res; -} - -int LoggingSocketAdapter::SendTo(const void *pv, size_t cb, - const SocketAddress& addr) { - int res = AsyncSocketAdapter::SendTo(pv, cb, addr); - if (res > 0) - LogMultiline(level_, label_.c_str(), false, pv, res, hex_mode_, &lms_); - return res; -} - -int LoggingSocketAdapter::Recv(void *pv, size_t cb) { - int res = AsyncSocketAdapter::Recv(pv, cb); - if (res > 0) - LogMultiline(level_, label_.c_str(), true, pv, res, hex_mode_, &lms_); - return res; -} - -int LoggingSocketAdapter::RecvFrom(void *pv, size_t cb, SocketAddress *paddr) { - int res = AsyncSocketAdapter::RecvFrom(pv, cb, paddr); - if (res > 0) - LogMultiline(level_, label_.c_str(), true, pv, res, hex_mode_, &lms_); - return res; -} - -int LoggingSocketAdapter::Close() { - LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_); - LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_); - LOG_V(level_) << label_ << " Closed locally"; - return socket_->Close(); -} - -void LoggingSocketAdapter::OnConnectEvent(AsyncSocket * socket) { - LOG_V(level_) << label_ << " Connected"; - AsyncSocketAdapter::OnConnectEvent(socket); -} - -void LoggingSocketAdapter::OnCloseEvent(AsyncSocket * socket, int err) { - LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_); - LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_); - LOG_V(level_) << label_ << " Closed with error: " << err; - AsyncSocketAdapter::OnCloseEvent(socket, err); -} - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/socketadapters.h b/webrtc/base/socketadapters.h deleted file mode 100644 index 3292df289..000000000 --- a/webrtc/base/socketadapters.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SOCKETADAPTERS_H_ -#define WEBRTC_BASE_SOCKETADAPTERS_H_ - -#include -#include - -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/cryptstring.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -struct HttpAuthContext; -class ByteBuffer; - -/////////////////////////////////////////////////////////////////////////////// - -// Implements a socket adapter that can buffer and process data internally, -// as in the case of connecting to a proxy, where you must speak the proxy -// protocol before commencing normal socket behavior. -class BufferedReadAdapter : public AsyncSocketAdapter { - public: - BufferedReadAdapter(AsyncSocket* socket, size_t buffer_size); - virtual ~BufferedReadAdapter(); - - virtual int Send(const void* pv, size_t cb); - virtual int Recv(void* pv, size_t cb); - - protected: - int DirectSend(const void* pv, size_t cb) { - return AsyncSocketAdapter::Send(pv, cb); - } - - void BufferInput(bool on = true); - virtual void ProcessInput(char* data, size_t* len) = 0; - - virtual void OnReadEvent(AsyncSocket * socket); - - private: - char * buffer_; - size_t buffer_size_, data_len_; - bool buffering_; - DISALLOW_EVIL_CONSTRUCTORS(BufferedReadAdapter); -}; - -/////////////////////////////////////////////////////////////////////////////// - -// Interface for implementing proxy server sockets. -class AsyncProxyServerSocket : public BufferedReadAdapter { - public: - AsyncProxyServerSocket(AsyncSocket* socket, size_t buffer_size) - : BufferedReadAdapter(socket, buffer_size) {} - sigslot::signal2 SignalConnectRequest; - virtual void SendConnectResult(int err, const SocketAddress& addr) = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// - -// Implements a socket adapter that performs the client side of a -// fake SSL handshake. Used for "ssltcp" P2P functionality. -class AsyncSSLSocket : public BufferedReadAdapter { - public: - explicit AsyncSSLSocket(AsyncSocket* socket); - - virtual int Connect(const SocketAddress& addr); - - protected: - virtual void OnConnectEvent(AsyncSocket* socket); - virtual void ProcessInput(char* data, size_t* len); - DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLSocket); -}; - -// Implements a socket adapter that performs the server side of a -// fake SSL handshake. Used when implementing a relay server that does "ssltcp". -class AsyncSSLServerSocket : public BufferedReadAdapter { - public: - explicit AsyncSSLServerSocket(AsyncSocket* socket); - - protected: - virtual void ProcessInput(char* data, size_t* len); - DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLServerSocket); -}; - -/////////////////////////////////////////////////////////////////////////////// - -// Implements a socket adapter that speaks the HTTP/S proxy protocol. -class AsyncHttpsProxySocket : public BufferedReadAdapter { - public: - AsyncHttpsProxySocket(AsyncSocket* socket, const std::string& user_agent, - const SocketAddress& proxy, - const std::string& username, const CryptString& password); - virtual ~AsyncHttpsProxySocket(); - - // If connect is forced, the adapter will always issue an HTTP CONNECT to the - // target address. Otherwise, it will connect only if the destination port - // is not port 80. - void SetForceConnect(bool force) { force_connect_ = force; } - - virtual int Connect(const SocketAddress& addr); - virtual SocketAddress GetRemoteAddress() const; - virtual int Close(); - virtual ConnState GetState() const; - - protected: - virtual void OnConnectEvent(AsyncSocket* socket); - virtual void OnCloseEvent(AsyncSocket* socket, int err); - virtual void ProcessInput(char* data, size_t* len); - - bool ShouldIssueConnect() const; - void SendRequest(); - void ProcessLine(char* data, size_t len); - void EndResponse(); - void Error(int error); - - private: - SocketAddress proxy_, dest_; - std::string agent_, user_, headers_; - CryptString pass_; - bool force_connect_; - size_t content_length_; - int defer_error_; - bool expect_close_; - enum ProxyState { - PS_INIT, PS_LEADER, PS_AUTHENTICATE, PS_SKIP_HEADERS, PS_ERROR_HEADERS, - PS_TUNNEL_HEADERS, PS_SKIP_BODY, PS_TUNNEL, PS_WAIT_CLOSE, PS_ERROR - } state_; - HttpAuthContext * context_; - std::string unknown_mechanisms_; - DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxySocket); -}; - -/* TODO: Implement this. -class AsyncHttpsProxyServerSocket : public AsyncProxyServerSocket { - public: - explicit AsyncHttpsProxyServerSocket(AsyncSocket* socket); - - private: - virtual void ProcessInput(char * data, size_t& len); - void Error(int error); - DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxyServerSocket); -}; -*/ - -/////////////////////////////////////////////////////////////////////////////// - -// Implements a socket adapter that speaks the SOCKS proxy protocol. -class AsyncSocksProxySocket : public BufferedReadAdapter { - public: - AsyncSocksProxySocket(AsyncSocket* socket, const SocketAddress& proxy, - const std::string& username, const CryptString& password); - - virtual int Connect(const SocketAddress& addr); - virtual SocketAddress GetRemoteAddress() const; - virtual int Close(); - virtual ConnState GetState() const; - - protected: - virtual void OnConnectEvent(AsyncSocket* socket); - virtual void ProcessInput(char* data, size_t* len); - - void SendHello(); - void SendConnect(); - void SendAuth(); - void Error(int error); - - private: - enum State { - SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR - }; - State state_; - SocketAddress proxy_, dest_; - std::string user_; - CryptString pass_; - DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxySocket); -}; - -// Implements a proxy server socket for the SOCKS protocol. -class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket { - public: - explicit AsyncSocksProxyServerSocket(AsyncSocket* socket); - - private: - virtual void ProcessInput(char* data, size_t* len); - void DirectSend(const ByteBuffer& buf); - - void HandleHello(ByteBuffer* request); - void SendHelloReply(int method); - void HandleAuth(ByteBuffer* request); - void SendAuthReply(int result); - void HandleConnect(ByteBuffer* request); - virtual void SendConnectResult(int result, const SocketAddress& addr); - - void Error(int error); - - static const int kBufferSize = 1024; - enum State { - SS_HELLO, SS_AUTH, SS_CONNECT, SS_CONNECT_PENDING, SS_TUNNEL, SS_ERROR - }; - State state_; - DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxyServerSocket); -}; - -/////////////////////////////////////////////////////////////////////////////// - -// Implements a socket adapter that logs everything that it sends and receives. -class LoggingSocketAdapter : public AsyncSocketAdapter { - public: - LoggingSocketAdapter(AsyncSocket* socket, LoggingSeverity level, - const char * label, bool hex_mode = false); - - virtual int Send(const void *pv, size_t cb); - virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr); - virtual int Recv(void *pv, size_t cb); - virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr); - virtual int Close(); - - protected: - virtual void OnConnectEvent(AsyncSocket * socket); - virtual void OnCloseEvent(AsyncSocket * socket, int err); - - private: - LoggingSeverity level_; - std::string label_; - bool hex_mode_; - LogMultilineState lms_; - DISALLOW_EVIL_CONSTRUCTORS(LoggingSocketAdapter); -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_SOCKETADAPTERS_H_ diff --git a/webrtc/base/socketaddress.cc b/webrtc/base/socketaddress.cc deleted file mode 100644 index 47ddd0400..000000000 --- a/webrtc/base/socketaddress.cc +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/socketaddress.h" - -#if defined(WEBRTC_POSIX) -#include -#include -#include -#if defined(OPENBSD) -#include -#endif -#if !defined(__native_client__) -#include -#endif -#include -#include -#include -#endif - -#include - -#include "webrtc/base/byteorder.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/nethelpers.h" - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#endif - -namespace rtc { - -SocketAddress::SocketAddress() { - Clear(); -} - -SocketAddress::SocketAddress(const std::string& hostname, int port) { - SetIP(hostname); - SetPort(port); -} - -SocketAddress::SocketAddress(uint32 ip_as_host_order_integer, int port) { - SetIP(IPAddress(ip_as_host_order_integer)); - SetPort(port); -} - -SocketAddress::SocketAddress(const IPAddress& ip, int port) { - SetIP(ip); - SetPort(port); -} - -SocketAddress::SocketAddress(const SocketAddress& addr) { - this->operator=(addr); -} - -void SocketAddress::Clear() { - hostname_.clear(); - literal_ = false; - ip_ = IPAddress(); - port_ = 0; - scope_id_ = 0; -} - -bool SocketAddress::IsNil() const { - return hostname_.empty() && IPIsUnspec(ip_) && 0 == port_; -} - -bool SocketAddress::IsComplete() const { - return (!IPIsAny(ip_)) && (0 != port_); -} - -SocketAddress& SocketAddress::operator=(const SocketAddress& addr) { - hostname_ = addr.hostname_; - ip_ = addr.ip_; - port_ = addr.port_; - literal_ = addr.literal_; - scope_id_ = addr.scope_id_; - return *this; -} - -void SocketAddress::SetIP(uint32 ip_as_host_order_integer) { - hostname_.clear(); - literal_ = false; - ip_ = IPAddress(ip_as_host_order_integer); - scope_id_ = 0; -} - -void SocketAddress::SetIP(const IPAddress& ip) { - hostname_.clear(); - literal_ = false; - ip_ = ip; - scope_id_ = 0; -} - -void SocketAddress::SetIP(const std::string& hostname) { - hostname_ = hostname; - literal_ = IPFromString(hostname, &ip_); - if (!literal_) { - ip_ = IPAddress(); - } - scope_id_ = 0; -} - -void SocketAddress::SetResolvedIP(uint32 ip_as_host_order_integer) { - ip_ = IPAddress(ip_as_host_order_integer); - scope_id_ = 0; -} - -void SocketAddress::SetResolvedIP(const IPAddress& ip) { - ip_ = ip; - scope_id_ = 0; -} - -void SocketAddress::SetPort(int port) { - ASSERT((0 <= port) && (port < 65536)); - port_ = port; -} - -uint32 SocketAddress::ip() const { - return ip_.v4AddressAsHostOrderInteger(); -} - -const IPAddress& SocketAddress::ipaddr() const { - return ip_; -} - -uint16 SocketAddress::port() const { - return port_; -} - -std::string SocketAddress::HostAsURIString() const { - // If the hostname was a literal IP string, it may need to have square - // brackets added (for SocketAddress::ToString()). - if (!literal_ && !hostname_.empty()) - return hostname_; - if (ip_.family() == AF_INET6) { - return "[" + ip_.ToString() + "]"; - } else { - return ip_.ToString(); - } -} - -std::string SocketAddress::HostAsSensitiveURIString() const { - // If the hostname was a literal IP string, it may need to have square - // brackets added (for SocketAddress::ToString()). - if (!literal_ && !hostname_.empty()) - return hostname_; - if (ip_.family() == AF_INET6) { - return "[" + ip_.ToSensitiveString() + "]"; - } else { - return ip_.ToSensitiveString(); - } -} - -std::string SocketAddress::PortAsString() const { - std::ostringstream ost; - ost << port_; - return ost.str(); -} - -std::string SocketAddress::ToString() const { - std::ostringstream ost; - ost << *this; - return ost.str(); -} - -std::string SocketAddress::ToSensitiveString() const { - std::ostringstream ost; - ost << HostAsSensitiveURIString() << ":" << port(); - return ost.str(); -} - -bool SocketAddress::FromString(const std::string& str) { - if (str.at(0) == '[') { - std::string::size_type closebracket = str.rfind(']'); - if (closebracket != std::string::npos) { - std::string::size_type colon = str.find(':', closebracket); - if (colon != std::string::npos && colon > closebracket) { - SetPort(strtoul(str.substr(colon + 1).c_str(), NULL, 10)); - SetIP(str.substr(1, closebracket - 1)); - } else { - return false; - } - } - } else { - std::string::size_type pos = str.find(':'); - if (std::string::npos == pos) - return false; - SetPort(strtoul(str.substr(pos + 1).c_str(), NULL, 10)); - SetIP(str.substr(0, pos)); - } - return true; -} - -std::ostream& operator<<(std::ostream& os, const SocketAddress& addr) { - os << addr.HostAsURIString() << ":" << addr.port(); - return os; -} - -bool SocketAddress::IsAnyIP() const { - return IPIsAny(ip_); -} - -bool SocketAddress::IsLoopbackIP() const { - return IPIsLoopback(ip_) || (IPIsAny(ip_) && - 0 == strcmp(hostname_.c_str(), "localhost")); -} - -bool SocketAddress::IsPrivateIP() const { - return IPIsPrivate(ip_); -} - -bool SocketAddress::IsUnresolvedIP() const { - return IPIsUnspec(ip_) && !literal_ && !hostname_.empty(); -} - -bool SocketAddress::operator==(const SocketAddress& addr) const { - return EqualIPs(addr) && EqualPorts(addr); -} - -bool SocketAddress::operator<(const SocketAddress& addr) const { - if (ip_ < addr.ip_) - return true; - else if (addr.ip_ < ip_) - return false; - - // We only check hostnames if both IPs are zero. This matches EqualIPs() - if (addr.IsAnyIP()) { - if (hostname_ < addr.hostname_) - return true; - else if (addr.hostname_ < hostname_) - return false; - } - - return port_ < addr.port_; -} - -bool SocketAddress::EqualIPs(const SocketAddress& addr) const { - return (ip_ == addr.ip_) && - ((!IPIsAny(ip_)) || (hostname_ == addr.hostname_)); -} - -bool SocketAddress::EqualPorts(const SocketAddress& addr) const { - return (port_ == addr.port_); -} - -size_t SocketAddress::Hash() const { - size_t h = 0; - h ^= HashIP(ip_); - h ^= port_ | (port_ << 16); - return h; -} - -void SocketAddress::ToSockAddr(sockaddr_in* saddr) const { - memset(saddr, 0, sizeof(*saddr)); - if (ip_.family() != AF_INET) { - saddr->sin_family = AF_UNSPEC; - return; - } - saddr->sin_family = AF_INET; - saddr->sin_port = HostToNetwork16(port_); - if (IPIsAny(ip_)) { - saddr->sin_addr.s_addr = INADDR_ANY; - } else { - saddr->sin_addr = ip_.ipv4_address(); - } -} - -bool SocketAddress::FromSockAddr(const sockaddr_in& saddr) { - if (saddr.sin_family != AF_INET) - return false; - SetIP(NetworkToHost32(saddr.sin_addr.s_addr)); - SetPort(NetworkToHost16(saddr.sin_port)); - literal_ = false; - return true; -} - -static size_t ToSockAddrStorageHelper(sockaddr_storage* addr, - IPAddress ip, int port, int scope_id) { - memset(addr, 0, sizeof(sockaddr_storage)); - addr->ss_family = ip.family(); - if (addr->ss_family == AF_INET6) { - sockaddr_in6* saddr = reinterpret_cast(addr); - saddr->sin6_addr = ip.ipv6_address(); - saddr->sin6_port = HostToNetwork16(port); - saddr->sin6_scope_id = scope_id; - return sizeof(sockaddr_in6); - } else if (addr->ss_family == AF_INET) { - sockaddr_in* saddr = reinterpret_cast(addr); - saddr->sin_addr = ip.ipv4_address(); - saddr->sin_port = HostToNetwork16(port); - return sizeof(sockaddr_in); - } - return 0; -} - -size_t SocketAddress::ToDualStackSockAddrStorage(sockaddr_storage *addr) const { - return ToSockAddrStorageHelper(addr, ip_.AsIPv6Address(), port_, scope_id_); -} - -size_t SocketAddress::ToSockAddrStorage(sockaddr_storage* addr) const { - return ToSockAddrStorageHelper(addr, ip_, port_, scope_id_); -} - -std::string SocketAddress::IPToString(uint32 ip_as_host_order_integer) { - return IPAddress(ip_as_host_order_integer).ToString(); -} - -std::string IPToSensitiveString(uint32 ip_as_host_order_integer) { - return IPAddress(ip_as_host_order_integer).ToSensitiveString(); -} - -bool SocketAddress::StringToIP(const std::string& hostname, uint32* ip) { - in_addr addr; - if (rtc::inet_pton(AF_INET, hostname.c_str(), &addr) == 0) - return false; - *ip = NetworkToHost32(addr.s_addr); - return true; -} - -bool SocketAddress::StringToIP(const std::string& hostname, IPAddress* ip) { - in_addr addr4; - if (rtc::inet_pton(AF_INET, hostname.c_str(), &addr4) > 0) { - if (ip) { - *ip = IPAddress(addr4); - } - return true; - } - - in6_addr addr6; - if (rtc::inet_pton(AF_INET6, hostname.c_str(), &addr6) > 0) { - if (ip) { - *ip = IPAddress(addr6); - } - return true; - } - return false; -} - -uint32 SocketAddress::StringToIP(const std::string& hostname) { - uint32 ip = 0; - StringToIP(hostname, &ip); - return ip; -} - -bool SocketAddressFromSockAddrStorage(const sockaddr_storage& addr, - SocketAddress* out) { - if (!out) { - return false; - } - if (addr.ss_family == AF_INET) { - const sockaddr_in* saddr = reinterpret_cast(&addr); - *out = SocketAddress(IPAddress(saddr->sin_addr), - NetworkToHost16(saddr->sin_port)); - return true; - } else if (addr.ss_family == AF_INET6) { - const sockaddr_in6* saddr = reinterpret_cast(&addr); - *out = SocketAddress(IPAddress(saddr->sin6_addr), - NetworkToHost16(saddr->sin6_port)); - out->SetScopeID(saddr->sin6_scope_id); - return true; - } - return false; -} - -SocketAddress EmptySocketAddressWithFamily(int family) { - if (family == AF_INET) { - return SocketAddress(IPAddress(INADDR_ANY), 0); - } else if (family == AF_INET6) { - return SocketAddress(IPAddress(in6addr_any), 0); - } - return SocketAddress(); -} - -} // namespace rtc diff --git a/webrtc/base/socketaddress.h b/webrtc/base/socketaddress.h deleted file mode 100644 index f8256fc62..000000000 --- a/webrtc/base/socketaddress.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SOCKETADDRESS_H_ -#define WEBRTC_BASE_SOCKETADDRESS_H_ - -#include -#include -#include -#include "webrtc/base/basictypes.h" -#include "webrtc/base/ipaddress.h" - -#undef SetPort - -struct sockaddr_in; -struct sockaddr_storage; - -namespace rtc { - -// Records an IP address and port. -class SocketAddress { - public: - // Creates a nil address. - SocketAddress(); - - // Creates the address with the given host and port. Host may be a - // literal IP string or a hostname to be resolved later. - SocketAddress(const std::string& hostname, int port); - - // Creates the address with the given IP and port. - // IP is given as an integer in host byte order. V4 only, to be deprecated. - SocketAddress(uint32 ip_as_host_order_integer, int port); - - // Creates the address with the given IP and port. - SocketAddress(const IPAddress& ip, int port); - - // Creates a copy of the given address. - SocketAddress(const SocketAddress& addr); - - // Resets to the nil address. - void Clear(); - - // Determines if this is a nil address (empty hostname, any IP, null port) - bool IsNil() const; - - // Returns true if ip and port are set. - bool IsComplete() const; - - // Replaces our address with the given one. - SocketAddress& operator=(const SocketAddress& addr); - - // Changes the IP of this address to the given one, and clears the hostname - // IP is given as an integer in host byte order. V4 only, to be deprecated.. - void SetIP(uint32 ip_as_host_order_integer); - - // Changes the IP of this address to the given one, and clears the hostname. - void SetIP(const IPAddress& ip); - - // Changes the hostname of this address to the given one. - // Does not resolve the address; use Resolve to do so. - void SetIP(const std::string& hostname); - - // Sets the IP address while retaining the hostname. Useful for bypassing - // DNS for a pre-resolved IP. - // IP is given as an integer in host byte order. V4 only, to be deprecated. - void SetResolvedIP(uint32 ip_as_host_order_integer); - - // Sets the IP address while retaining the hostname. Useful for bypassing - // DNS for a pre-resolved IP. - void SetResolvedIP(const IPAddress& ip); - - // Changes the port of this address to the given one. - void SetPort(int port); - - // Returns the hostname. - const std::string& hostname() const { return hostname_; } - - // Returns the IP address as a host byte order integer. - // Returns 0 for non-v4 addresses. - uint32 ip() const; - - const IPAddress& ipaddr() const; - - int family() const {return ip_.family(); } - - // Returns the port part of this address. - uint16 port() const; - - // Returns the scope ID associated with this address. Scope IDs are a - // necessary addition to IPv6 link-local addresses, with different network - // interfaces having different scope-ids for their link-local addresses. - // IPv4 address do not have scope_ids and sockaddr_in structures do not have - // a field for them. - int scope_id() const {return scope_id_; } - void SetScopeID(int id) { scope_id_ = id; } - - // Returns the 'host' portion of the address (hostname or IP) in a form - // suitable for use in a URI. If both IP and hostname are present, hostname - // is preferred. IPv6 addresses are enclosed in square brackets ('[' and ']'). - std::string HostAsURIString() const; - - // Same as HostAsURIString but anonymizes IP addresses by hiding the last - // part. - std::string HostAsSensitiveURIString() const; - - // Returns the port as a string. - std::string PortAsString() const; - - // Returns hostname:port or [hostname]:port. - std::string ToString() const; - - // Same as ToString but anonymizes it by hiding the last part. - std::string ToSensitiveString() const; - - // Parses hostname:port and [hostname]:port. - bool FromString(const std::string& str); - - friend std::ostream& operator<<(std::ostream& os, const SocketAddress& addr); - - // Determines whether this represents a missing / any IP address. - // That is, 0.0.0.0 or ::. - // Hostname and/or port may be set. - bool IsAnyIP() const; - inline bool IsAny() const { return IsAnyIP(); } // deprecated - - // Determines whether the IP address refers to a loopback address. - // For v4 addresses this means the address is in the range 127.0.0.0/8. - // For v6 addresses this means the address is ::1. - bool IsLoopbackIP() const; - - // Determines whether the IP address is in one of the private ranges: - // For v4: 127.0.0.0/8 10.0.0.0/8 192.168.0.0/16 172.16.0.0/12. - // For v6: FE80::/16 and ::1. - bool IsPrivateIP() const; - - // Determines whether the hostname has been resolved to an IP. - bool IsUnresolvedIP() const; - inline bool IsUnresolved() const { return IsUnresolvedIP(); } // deprecated - - // Determines whether this address is identical to the given one. - bool operator ==(const SocketAddress& addr) const; - inline bool operator !=(const SocketAddress& addr) const { - return !this->operator ==(addr); - } - - // Compares based on IP and then port. - bool operator <(const SocketAddress& addr) const; - - // Determines whether this address has the same IP as the one given. - bool EqualIPs(const SocketAddress& addr) const; - - // Determines whether this address has the same port as the one given. - bool EqualPorts(const SocketAddress& addr) const; - - // Hashes this address into a small number. - size_t Hash() const; - - // Write this address to a sockaddr_in. - // If IPv6, will zero out the sockaddr_in and sets family to AF_UNSPEC. - void ToSockAddr(sockaddr_in* saddr) const; - - // Read this address from a sockaddr_in. - bool FromSockAddr(const sockaddr_in& saddr); - - // Read and write the address to/from a sockaddr_storage. - // Dual stack version always sets family to AF_INET6, and maps v4 addresses. - // The other version doesn't map, and outputs an AF_INET address for - // v4 or mapped addresses, and AF_INET6 addresses for others. - // Returns the size of the sockaddr_in or sockaddr_in6 structure that is - // written to the sockaddr_storage, or zero on failure. - size_t ToDualStackSockAddrStorage(sockaddr_storage* saddr) const; - size_t ToSockAddrStorage(sockaddr_storage* saddr) const; - - // Converts the IP address given in 'compact form' into dotted form. - // IP is given as an integer in host byte order. V4 only, to be deprecated. - // TODO: Deprecate this. - static std::string IPToString(uint32 ip_as_host_order_integer); - - // Same as IPToString but anonymizes it by hiding the last part. - // TODO: Deprecate this. - static std::string IPToSensitiveString(uint32 ip_as_host_order_integer); - - // Converts the IP address given in dotted form into compact form. - // Only dotted names (A.B.C.D) are converted. - // Output integer is returned in host byte order. - // TODO: Deprecate, replace wth agnostic versions. - static bool StringToIP(const std::string& str, uint32* ip); - static uint32 StringToIP(const std::string& str); - - // Converts the IP address given in printable form into an IPAddress. - static bool StringToIP(const std::string& str, IPAddress* ip); - - private: - std::string hostname_; - IPAddress ip_; - uint16 port_; - int scope_id_; - bool literal_; // Indicates that 'hostname_' contains a literal IP string. -}; - -bool SocketAddressFromSockAddrStorage(const sockaddr_storage& saddr, - SocketAddress* out); -SocketAddress EmptySocketAddressWithFamily(int family); - -} // namespace rtc - -#endif // WEBRTC_BASE_SOCKETADDRESS_H_ diff --git a/webrtc/base/socketaddress_unittest.cc b/webrtc/base/socketaddress_unittest.cc deleted file mode 100644 index 6166183fe..000000000 --- a/webrtc/base/socketaddress_unittest.cc +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_POSIX) -#include // for sockaddr_in -#endif - -#include "webrtc/base/gunit.h" -#include "webrtc/base/socketaddress.h" -#include "webrtc/base/ipaddress.h" - -namespace rtc { - -const in6_addr kTestV6Addr = { { {0x20, 0x01, 0x0d, 0xb8, - 0x10, 0x20, 0x30, 0x40, - 0x50, 0x60, 0x70, 0x80, - 0x90, 0xA0, 0xB0, 0xC0} } }; -const in6_addr kMappedV4Addr = { { {0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xFF, 0xFF, - 0x01, 0x02, 0x03, 0x04} } }; -const std::string kTestV6AddrString = "2001:db8:1020:3040:5060:7080:90a0:b0c0"; -const std::string kTestV6AddrAnonymizedString = "2001:db8:1020::"; -const std::string kTestV6AddrFullString = - "[2001:db8:1020:3040:5060:7080:90a0:b0c0]:5678"; -const std::string kTestV6AddrFullAnonymizedString = "[2001:db8:1020::]:5678"; - -TEST(SocketAddressTest, TestDefaultCtor) { - SocketAddress addr; - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(), addr.ipaddr()); - EXPECT_EQ(0, addr.port()); - EXPECT_EQ("", addr.hostname()); -} - -TEST(SocketAddressTest, TestIPPortCtor) { - SocketAddress addr(IPAddress(0x01020304), 5678); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("", addr.hostname()); - EXPECT_EQ("1.2.3.4:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestIPv4StringPortCtor) { - SocketAddress addr("1.2.3.4", 5678); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("1.2.3.4", addr.hostname()); - EXPECT_EQ("1.2.3.4:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestIPv6StringPortCtor) { - SocketAddress addr2(kTestV6AddrString, 1234); - IPAddress tocheck(kTestV6Addr); - - EXPECT_FALSE(addr2.IsUnresolvedIP()); - EXPECT_EQ(tocheck, addr2.ipaddr()); - EXPECT_EQ(1234, addr2.port()); - EXPECT_EQ(kTestV6AddrString, addr2.hostname()); - EXPECT_EQ("[" + kTestV6AddrString + "]:1234", addr2.ToString()); -} - -TEST(SocketAddressTest, TestSpecialStringPortCtor) { - // inet_addr doesn't handle this address properly. - SocketAddress addr("255.255.255.255", 5678); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0xFFFFFFFFU), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("255.255.255.255", addr.hostname()); - EXPECT_EQ("255.255.255.255:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestHostnamePortCtor) { - SocketAddress addr("a.b.com", 5678); - EXPECT_TRUE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("a.b.com", addr.hostname()); - EXPECT_EQ("a.b.com:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestCopyCtor) { - SocketAddress from("1.2.3.4", 5678); - SocketAddress addr(from); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("1.2.3.4", addr.hostname()); - EXPECT_EQ("1.2.3.4:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestAssign) { - SocketAddress from("1.2.3.4", 5678); - SocketAddress addr(IPAddress(0x88888888), 9999); - addr = from; - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("1.2.3.4", addr.hostname()); - EXPECT_EQ("1.2.3.4:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestSetIPPort) { - SocketAddress addr(IPAddress(0x88888888), 9999); - addr.SetIP(IPAddress(0x01020304)); - addr.SetPort(5678); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("", addr.hostname()); - EXPECT_EQ("1.2.3.4:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestSetIPFromString) { - SocketAddress addr(IPAddress(0x88888888), 9999); - addr.SetIP("1.2.3.4"); - addr.SetPort(5678); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("1.2.3.4", addr.hostname()); - EXPECT_EQ("1.2.3.4:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestSetIPFromHostname) { - SocketAddress addr(IPAddress(0x88888888), 9999); - addr.SetIP("a.b.com"); - addr.SetPort(5678); - EXPECT_TRUE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("a.b.com", addr.hostname()); - EXPECT_EQ("a.b.com:5678", addr.ToString()); - addr.SetResolvedIP(IPAddress(0x01020304)); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ("a.b.com", addr.hostname()); - EXPECT_EQ("a.b.com:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestFromIPv4String) { - SocketAddress addr; - EXPECT_TRUE(addr.FromString("1.2.3.4:5678")); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("1.2.3.4", addr.hostname()); - EXPECT_EQ("1.2.3.4:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestFromIPv6String) { - SocketAddress addr; - EXPECT_TRUE(addr.FromString(kTestV6AddrFullString)); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ(kTestV6AddrString, addr.hostname()); - EXPECT_EQ(kTestV6AddrFullString, addr.ToString()); -} - -TEST(SocketAddressTest, TestFromHostname) { - SocketAddress addr; - EXPECT_TRUE(addr.FromString("a.b.com:5678")); - EXPECT_TRUE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("a.b.com", addr.hostname()); - EXPECT_EQ("a.b.com:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestToFromSockAddr) { - SocketAddress from("1.2.3.4", 5678), addr; - sockaddr_in addr_in; - from.ToSockAddr(&addr_in); - EXPECT_TRUE(addr.FromSockAddr(addr_in)); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("", addr.hostname()); - EXPECT_EQ("1.2.3.4:5678", addr.ToString()); -} - -TEST(SocketAddressTest, TestToFromSockAddrStorage) { - SocketAddress from("1.2.3.4", 5678), addr; - sockaddr_storage addr_storage; - from.ToSockAddrStorage(&addr_storage); - EXPECT_TRUE(SocketAddressFromSockAddrStorage(addr_storage, &addr)); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("", addr.hostname()); - EXPECT_EQ("1.2.3.4:5678", addr.ToString()); - - addr.Clear(); - from.ToDualStackSockAddrStorage(&addr_storage); - EXPECT_TRUE(SocketAddressFromSockAddrStorage(addr_storage, &addr)); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(kMappedV4Addr), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("", addr.hostname()); - EXPECT_EQ("[::ffff:1.2.3.4]:5678", addr.ToString()); - - addr.Clear(); - memset(&addr_storage, 0, sizeof(sockaddr_storage)); - from = SocketAddress(kTestV6AddrString, 5678); - from.SetScopeID(6); - from.ToSockAddrStorage(&addr_storage); - EXPECT_TRUE(SocketAddressFromSockAddrStorage(addr_storage, &addr)); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(kTestV6Addr), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("", addr.hostname()); - EXPECT_EQ(kTestV6AddrFullString, addr.ToString()); - EXPECT_EQ(6, addr.scope_id()); - - addr.Clear(); - from.ToDualStackSockAddrStorage(&addr_storage); - EXPECT_TRUE(SocketAddressFromSockAddrStorage(addr_storage, &addr)); - EXPECT_FALSE(addr.IsUnresolvedIP()); - EXPECT_EQ(IPAddress(kTestV6Addr), addr.ipaddr()); - EXPECT_EQ(5678, addr.port()); - EXPECT_EQ("", addr.hostname()); - EXPECT_EQ(kTestV6AddrFullString, addr.ToString()); - EXPECT_EQ(6, addr.scope_id()); - - addr = from; - addr_storage.ss_family = AF_UNSPEC; - EXPECT_FALSE(SocketAddressFromSockAddrStorage(addr_storage, &addr)); - EXPECT_EQ(from, addr); - - EXPECT_FALSE(SocketAddressFromSockAddrStorage(addr_storage, NULL)); -} - -bool AreEqual(const SocketAddress& addr1, - const SocketAddress& addr2) { - return addr1 == addr2 && addr2 == addr1 && - !(addr1 != addr2) && !(addr2 != addr1); -} - -bool AreUnequal(const SocketAddress& addr1, - const SocketAddress& addr2) { - return !(addr1 == addr2) && !(addr2 == addr1) && - addr1 != addr2 && addr2 != addr1; -} - -TEST(SocketAddressTest, TestEqualityOperators) { - SocketAddress addr1("1.2.3.4", 5678); - SocketAddress addr2("1.2.3.4", 5678); - EXPECT_PRED2(AreEqual, addr1, addr2); - - addr2 = SocketAddress("0.0.0.1", 5678); - EXPECT_PRED2(AreUnequal, addr1, addr2); - - addr2 = SocketAddress("1.2.3.4", 1234); - EXPECT_PRED2(AreUnequal, addr1, addr2); - - addr2 = SocketAddress(kTestV6AddrString, 5678); - EXPECT_PRED2(AreUnequal, addr1, addr2); - - addr1 = SocketAddress(kTestV6AddrString, 5678); - EXPECT_PRED2(AreEqual, addr1, addr2); - - addr2 = SocketAddress(kTestV6AddrString, 1234); - EXPECT_PRED2(AreUnequal, addr1, addr2); - - addr2 = SocketAddress("fe80::1", 5678); - EXPECT_PRED2(AreUnequal, addr1, addr2); -} - -bool IsLessThan(const SocketAddress& addr1, - const SocketAddress& addr2) { - return addr1 < addr2 && - !(addr2 < addr1) && - !(addr1 == addr2); -} - -TEST(SocketAddressTest, TestComparisonOperator) { - SocketAddress addr1("1.2.3.4", 5678); - SocketAddress addr2("1.2.3.4", 5678); - - EXPECT_FALSE(addr1 < addr2); - EXPECT_FALSE(addr2 < addr1); - - addr2 = SocketAddress("1.2.3.4", 5679); - EXPECT_PRED2(IsLessThan, addr1, addr2); - - addr2 = SocketAddress("2.2.3.4", 49152); - EXPECT_PRED2(IsLessThan, addr1, addr2); - - addr2 = SocketAddress(kTestV6AddrString, 5678); - EXPECT_PRED2(IsLessThan, addr1, addr2); - - addr1 = SocketAddress("fe80::1", 5678); - EXPECT_PRED2(IsLessThan, addr2, addr1); - - addr2 = SocketAddress("fe80::1", 5679); - EXPECT_PRED2(IsLessThan, addr1, addr2); - - addr2 = SocketAddress("fe80::1", 5678); - EXPECT_FALSE(addr1 < addr2); - EXPECT_FALSE(addr2 < addr1); -} - -TEST(SocketAddressTest, TestToSensitiveString) { - SocketAddress addr_v4("1.2.3.4", 5678); - EXPECT_EQ("1.2.3.4", addr_v4.HostAsURIString()); - EXPECT_EQ("1.2.3.4:5678", addr_v4.ToString()); - EXPECT_EQ("1.2.3.4", addr_v4.HostAsSensitiveURIString()); - EXPECT_EQ("1.2.3.4:5678", addr_v4.ToSensitiveString()); - IPAddress::set_strip_sensitive(true); - EXPECT_EQ("1.2.3.x", addr_v4.HostAsSensitiveURIString()); - EXPECT_EQ("1.2.3.x:5678", addr_v4.ToSensitiveString()); - IPAddress::set_strip_sensitive(false); - - SocketAddress addr_v6(kTestV6AddrString, 5678); - EXPECT_EQ("[" + kTestV6AddrString + "]", addr_v6.HostAsURIString()); - EXPECT_EQ(kTestV6AddrFullString, addr_v6.ToString()); - EXPECT_EQ("[" + kTestV6AddrString + "]", addr_v6.HostAsSensitiveURIString()); - EXPECT_EQ(kTestV6AddrFullString, addr_v6.ToSensitiveString()); - IPAddress::set_strip_sensitive(true); - EXPECT_EQ("[" + kTestV6AddrAnonymizedString + "]", - addr_v6.HostAsSensitiveURIString()); - EXPECT_EQ(kTestV6AddrFullAnonymizedString, addr_v6.ToSensitiveString()); - IPAddress::set_strip_sensitive(false); -} - -} // namespace rtc diff --git a/webrtc/base/socketaddresspair.cc b/webrtc/base/socketaddresspair.cc deleted file mode 100644 index dfa8b25a0..000000000 --- a/webrtc/base/socketaddresspair.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/socketaddresspair.h" - -namespace rtc { - -SocketAddressPair::SocketAddressPair( - const SocketAddress& src, const SocketAddress& dest) - : src_(src), dest_(dest) { -} - - -bool SocketAddressPair::operator ==(const SocketAddressPair& p) const { - return (src_ == p.src_) && (dest_ == p.dest_); -} - -bool SocketAddressPair::operator <(const SocketAddressPair& p) const { - if (src_ < p.src_) - return true; - if (p.src_ < src_) - return false; - if (dest_ < p.dest_) - return true; - if (p.dest_ < dest_) - return false; - return false; -} - -size_t SocketAddressPair::Hash() const { - return src_.Hash() ^ dest_.Hash(); -} - -} // namespace rtc diff --git a/webrtc/base/socketaddresspair.h b/webrtc/base/socketaddresspair.h deleted file mode 100644 index 73a627f10..000000000 --- a/webrtc/base/socketaddresspair.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SOCKETADDRESSPAIR_H__ -#define WEBRTC_BASE_SOCKETADDRESSPAIR_H__ - -#include "webrtc/base/socketaddress.h" - -namespace rtc { - -// Records a pair (source,destination) of socket addresses. The two addresses -// identify a connection between two machines. (For UDP, this "connection" is -// not maintained explicitly in a socket.) -class SocketAddressPair { -public: - SocketAddressPair() {} - SocketAddressPair(const SocketAddress& srs, const SocketAddress& dest); - - const SocketAddress& source() const { return src_; } - const SocketAddress& destination() const { return dest_; } - - bool operator ==(const SocketAddressPair& r) const; - bool operator <(const SocketAddressPair& r) const; - - size_t Hash() const; - -private: - SocketAddress src_; - SocketAddress dest_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SOCKETADDRESSPAIR_H__ diff --git a/webrtc/base/socketfactory.h b/webrtc/base/socketfactory.h deleted file mode 100644 index fe0f32bdb..000000000 --- a/webrtc/base/socketfactory.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SOCKETFACTORY_H__ -#define WEBRTC_BASE_SOCKETFACTORY_H__ - -#include "webrtc/base/socket.h" -#include "webrtc/base/asyncsocket.h" - -namespace rtc { - -class SocketFactory { -public: - virtual ~SocketFactory() {} - - // Returns a new socket for blocking communication. The type can be - // SOCK_DGRAM and SOCK_STREAM. - // TODO: C++ inheritance rules mean that all users must have both - // CreateSocket(int) and CreateSocket(int,int). Will remove CreateSocket(int) - // (and CreateAsyncSocket(int) when all callers are changed. - virtual Socket* CreateSocket(int type) = 0; - virtual Socket* CreateSocket(int family, int type) = 0; - // Returns a new socket for nonblocking communication. The type can be - // SOCK_DGRAM and SOCK_STREAM. - virtual AsyncSocket* CreateAsyncSocket(int type) = 0; - virtual AsyncSocket* CreateAsyncSocket(int family, int type) = 0; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SOCKETFACTORY_H__ diff --git a/webrtc/base/socketpool.cc b/webrtc/base/socketpool.cc deleted file mode 100644 index 8e61cc313..000000000 --- a/webrtc/base/socketpool.cc +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/socketfactory.h" -#include "webrtc/base/socketpool.h" -#include "webrtc/base/socketstream.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// StreamCache - Caches a set of open streams, defers creation to a separate -// StreamPool. -/////////////////////////////////////////////////////////////////////////////// - -StreamCache::StreamCache(StreamPool* pool) : pool_(pool) { -} - -StreamCache::~StreamCache() { - for (ConnectedList::iterator it = active_.begin(); it != active_.end(); - ++it) { - delete it->second; - } - for (ConnectedList::iterator it = cached_.begin(); it != cached_.end(); - ++it) { - delete it->second; - } -} - -StreamInterface* StreamCache::RequestConnectedStream( - const SocketAddress& remote, int* err) { - LOG_F(LS_VERBOSE) << "(" << remote << ")"; - for (ConnectedList::iterator it = cached_.begin(); it != cached_.end(); - ++it) { - if (remote == it->first) { - it->second->SignalEvent.disconnect(this); - // Move from cached_ to active_ - active_.push_front(*it); - cached_.erase(it); - if (err) - *err = 0; - LOG_F(LS_VERBOSE) << "Providing cached stream"; - return active_.front().second; - } - } - if (StreamInterface* stream = pool_->RequestConnectedStream(remote, err)) { - // We track active streams so that we can remember their address - active_.push_front(ConnectedStream(remote, stream)); - LOG_F(LS_VERBOSE) << "Providing new stream"; - return active_.front().second; - } - return NULL; -} - -void StreamCache::ReturnConnectedStream(StreamInterface* stream) { - for (ConnectedList::iterator it = active_.begin(); it != active_.end(); - ++it) { - if (stream == it->second) { - LOG_F(LS_VERBOSE) << "(" << it->first << ")"; - if (stream->GetState() == SS_CLOSED) { - // Return closed streams - LOG_F(LS_VERBOSE) << "Returning closed stream"; - pool_->ReturnConnectedStream(it->second); - } else { - // Monitor open streams - stream->SignalEvent.connect(this, &StreamCache::OnStreamEvent); - LOG_F(LS_VERBOSE) << "Caching stream"; - cached_.push_front(*it); - } - active_.erase(it); - return; - } - } - ASSERT(false); -} - -void StreamCache::OnStreamEvent(StreamInterface* stream, int events, int err) { - if ((events & SE_CLOSE) == 0) { - LOG_F(LS_WARNING) << "(" << events << ", " << err - << ") received non-close event"; - return; - } - for (ConnectedList::iterator it = cached_.begin(); it != cached_.end(); - ++it) { - if (stream == it->second) { - LOG_F(LS_VERBOSE) << "(" << it->first << ")"; - // We don't cache closed streams, so return it. - it->second->SignalEvent.disconnect(this); - LOG_F(LS_VERBOSE) << "Returning closed stream"; - pool_->ReturnConnectedStream(it->second); - cached_.erase(it); - return; - } - } - ASSERT(false); -} - -////////////////////////////////////////////////////////////////////// -// NewSocketPool -////////////////////////////////////////////////////////////////////// - -NewSocketPool::NewSocketPool(SocketFactory* factory) : factory_(factory) { -} - -NewSocketPool::~NewSocketPool() { -} - -StreamInterface* -NewSocketPool::RequestConnectedStream(const SocketAddress& remote, int* err) { - AsyncSocket* socket = - factory_->CreateAsyncSocket(remote.family(), SOCK_STREAM); - if (!socket) { - if (err) - *err = -1; - return NULL; - } - if ((socket->Connect(remote) != 0) && !socket->IsBlocking()) { - if (err) - *err = socket->GetError(); - delete socket; - return NULL; - } - if (err) - *err = 0; - return new SocketStream(socket); -} - -void -NewSocketPool::ReturnConnectedStream(StreamInterface* stream) { - Thread::Current()->Dispose(stream); -} - -////////////////////////////////////////////////////////////////////// -// ReuseSocketPool -////////////////////////////////////////////////////////////////////// - -ReuseSocketPool::ReuseSocketPool(SocketFactory* factory) -: factory_(factory), stream_(NULL), checked_out_(false) { -} - -ReuseSocketPool::~ReuseSocketPool() { - ASSERT(!checked_out_); - delete stream_; -} - -StreamInterface* -ReuseSocketPool::RequestConnectedStream(const SocketAddress& remote, int* err) { - // Only one socket can be used from this "pool" at a time - ASSERT(!checked_out_); - if (!stream_) { - LOG_F(LS_VERBOSE) << "Creating new socket"; - int family = remote.family(); - // TODO: Deal with this when we/I clean up DNS resolution. - if (remote.IsUnresolvedIP()) { - family = AF_INET; - } - AsyncSocket* socket = - factory_->CreateAsyncSocket(family, SOCK_STREAM); - if (!socket) { - if (err) - *err = -1; - return NULL; - } - stream_ = new SocketStream(socket); - } - if ((stream_->GetState() == SS_OPEN) && (remote == remote_)) { - LOG_F(LS_VERBOSE) << "Reusing connection to: " << remote_; - } else { - remote_ = remote; - stream_->Close(); - if ((stream_->GetSocket()->Connect(remote_) != 0) - && !stream_->GetSocket()->IsBlocking()) { - if (err) - *err = stream_->GetSocket()->GetError(); - return NULL; - } else { - LOG_F(LS_VERBOSE) << "Opening connection to: " << remote_; - } - } - stream_->SignalEvent.disconnect(this); - checked_out_ = true; - if (err) - *err = 0; - return stream_; -} - -void -ReuseSocketPool::ReturnConnectedStream(StreamInterface* stream) { - ASSERT(stream == stream_); - ASSERT(checked_out_); - checked_out_ = false; - // Until the socket is reused, monitor it to determine if it closes. - stream_->SignalEvent.connect(this, &ReuseSocketPool::OnStreamEvent); -} - -void -ReuseSocketPool::OnStreamEvent(StreamInterface* stream, int events, int err) { - ASSERT(stream == stream_); - ASSERT(!checked_out_); - - // If the stream was written to and then immediately returned to us then - // we may get a writable notification for it, which we should ignore. - if (events == SE_WRITE) { - LOG_F(LS_VERBOSE) << "Pooled Socket unexpectedly writable: ignoring"; - return; - } - - // If the peer sent data, we can't process it, so drop the connection. - // If the socket has closed, clean it up. - // In either case, we'll reconnect it the next time it is used. - ASSERT(0 != (events & (SE_READ|SE_CLOSE))); - if (0 != (events & SE_CLOSE)) { - LOG_F(LS_VERBOSE) << "Connection closed with error: " << err; - } else { - LOG_F(LS_VERBOSE) << "Pooled Socket unexpectedly readable: closing"; - } - stream_->Close(); -} - -/////////////////////////////////////////////////////////////////////////////// -// LoggingPoolAdapter - Adapts a StreamPool to supply streams with attached -// LoggingAdapters. -/////////////////////////////////////////////////////////////////////////////// - -LoggingPoolAdapter::LoggingPoolAdapter( - StreamPool* pool, LoggingSeverity level, const std::string& label, - bool binary_mode) - : pool_(pool), level_(level), label_(label), binary_mode_(binary_mode) { -} - -LoggingPoolAdapter::~LoggingPoolAdapter() { - for (StreamList::iterator it = recycle_bin_.begin(); - it != recycle_bin_.end(); ++it) { - delete *it; - } -} - -StreamInterface* LoggingPoolAdapter::RequestConnectedStream( - const SocketAddress& remote, int* err) { - if (StreamInterface* stream = pool_->RequestConnectedStream(remote, err)) { - ASSERT(SS_CLOSED != stream->GetState()); - std::stringstream ss; - ss << label_ << "(0x" << std::setfill('0') << std::hex << std::setw(8) - << stream << ")"; - LOG_V(level_) << ss.str() - << ((SS_OPEN == stream->GetState()) ? " Connected" - : " Connecting") - << " to " << remote; - if (recycle_bin_.empty()) { - return new LoggingAdapter(stream, level_, ss.str(), binary_mode_); - } - LoggingAdapter* logging = recycle_bin_.front(); - recycle_bin_.pop_front(); - logging->set_label(ss.str()); - logging->Attach(stream); - return logging; - } - return NULL; -} - -void LoggingPoolAdapter::ReturnConnectedStream(StreamInterface* stream) { - LoggingAdapter* logging = static_cast(stream); - pool_->ReturnConnectedStream(logging->Detach()); - recycle_bin_.push_back(logging); -} - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/socketpool.h b/webrtc/base/socketpool.h deleted file mode 100644 index 7bcaa062d..000000000 --- a/webrtc/base/socketpool.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SOCKETPOOL_H_ -#define WEBRTC_BASE_SOCKETPOOL_H_ - -#include -#include -#include "webrtc/base/logging.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/socketaddress.h" - -namespace rtc { - -class AsyncSocket; -class LoggingAdapter; -class SocketFactory; -class SocketStream; -class StreamInterface; - -////////////////////////////////////////////////////////////////////// -// StreamPool -////////////////////////////////////////////////////////////////////// - -class StreamPool { -public: - virtual ~StreamPool() { } - - virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote, - int* err) = 0; - virtual void ReturnConnectedStream(StreamInterface* stream) = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// -// StreamCache - Caches a set of open streams, defers creation/destruction to -// the supplied StreamPool. -/////////////////////////////////////////////////////////////////////////////// - -class StreamCache : public StreamPool, public sigslot::has_slots<> { -public: - StreamCache(StreamPool* pool); - virtual ~StreamCache(); - - // StreamPool Interface - virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote, - int* err); - virtual void ReturnConnectedStream(StreamInterface* stream); - -private: - typedef std::pair ConnectedStream; - typedef std::list ConnectedList; - - void OnStreamEvent(StreamInterface* stream, int events, int err); - - // We delegate stream creation and deletion to this pool. - StreamPool* pool_; - // Streams that are in use (returned from RequestConnectedStream). - ConnectedList active_; - // Streams which were returned to us, but are still open. - ConnectedList cached_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// NewSocketPool -// Creates a new stream on every request -/////////////////////////////////////////////////////////////////////////////// - -class NewSocketPool : public StreamPool { -public: - NewSocketPool(SocketFactory* factory); - virtual ~NewSocketPool(); - - // StreamPool Interface - virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote, - int* err); - virtual void ReturnConnectedStream(StreamInterface* stream); - -private: - SocketFactory* factory_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// ReuseSocketPool -// Maintains a single socket at a time, and will reuse it without closing if -// the destination address is the same. -/////////////////////////////////////////////////////////////////////////////// - -class ReuseSocketPool : public StreamPool, public sigslot::has_slots<> { -public: - ReuseSocketPool(SocketFactory* factory); - virtual ~ReuseSocketPool(); - - // StreamPool Interface - virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote, - int* err); - virtual void ReturnConnectedStream(StreamInterface* stream); - -private: - void OnStreamEvent(StreamInterface* stream, int events, int err); - - SocketFactory* factory_; - SocketStream* stream_; - SocketAddress remote_; - bool checked_out_; // Whether the stream is currently checked out -}; - -/////////////////////////////////////////////////////////////////////////////// -// LoggingPoolAdapter - Adapts a StreamPool to supply streams with attached -// LoggingAdapters. -/////////////////////////////////////////////////////////////////////////////// - -class LoggingPoolAdapter : public StreamPool { -public: - LoggingPoolAdapter(StreamPool* pool, LoggingSeverity level, - const std::string& label, bool binary_mode); - virtual ~LoggingPoolAdapter(); - - // StreamPool Interface - virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote, - int* err); - virtual void ReturnConnectedStream(StreamInterface* stream); - -private: - StreamPool* pool_; - LoggingSeverity level_; - std::string label_; - bool binary_mode_; - typedef std::deque StreamList; - StreamList recycle_bin_; -}; - -////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_SOCKETPOOL_H_ diff --git a/webrtc/base/socketserver.h b/webrtc/base/socketserver.h deleted file mode 100644 index 467105a6a..000000000 --- a/webrtc/base/socketserver.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SOCKETSERVER_H_ -#define WEBRTC_BASE_SOCKETSERVER_H_ - -#include "webrtc/base/socketfactory.h" - -namespace rtc { - -class MessageQueue; - -// Provides the ability to wait for activity on a set of sockets. The Thread -// class provides a nice wrapper on a socket server. -// -// The server is also a socket factory. The sockets it creates will be -// notified of asynchronous I/O from this server's Wait method. -class SocketServer : public SocketFactory { - public: - // When the socket server is installed into a Thread, this function is - // called to allow the socket server to use the thread's message queue for - // any messaging that it might need to perform. - virtual void SetMessageQueue(MessageQueue* queue) {} - - // Sleeps until: - // 1) cms milliseconds have elapsed (unless cms == kForever) - // 2) WakeUp() is called - // While sleeping, I/O is performed if process_io is true. - virtual bool Wait(int cms, bool process_io) = 0; - - // Causes the current wait (if one is in progress) to wake up. - virtual void WakeUp() = 0; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SOCKETSERVER_H_ diff --git a/webrtc/base/socketstream.cc b/webrtc/base/socketstream.cc deleted file mode 100644 index b0acf94c5..000000000 --- a/webrtc/base/socketstream.cc +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/socketstream.h" - -namespace rtc { - -SocketStream::SocketStream(AsyncSocket* socket) : socket_(NULL) { - Attach(socket); -} - -SocketStream::~SocketStream() { - delete socket_; -} - -void SocketStream::Attach(AsyncSocket* socket) { - if (socket_) - delete socket_; - socket_ = socket; - if (socket_) { - socket_->SignalConnectEvent.connect(this, &SocketStream::OnConnectEvent); - socket_->SignalReadEvent.connect(this, &SocketStream::OnReadEvent); - socket_->SignalWriteEvent.connect(this, &SocketStream::OnWriteEvent); - socket_->SignalCloseEvent.connect(this, &SocketStream::OnCloseEvent); - } -} - -AsyncSocket* SocketStream::Detach() { - AsyncSocket* socket = socket_; - if (socket_) { - socket_->SignalConnectEvent.disconnect(this); - socket_->SignalReadEvent.disconnect(this); - socket_->SignalWriteEvent.disconnect(this); - socket_->SignalCloseEvent.disconnect(this); - socket_ = NULL; - } - return socket; -} - -StreamState SocketStream::GetState() const { - ASSERT(socket_ != NULL); - switch (socket_->GetState()) { - case Socket::CS_CONNECTED: - return SS_OPEN; - case Socket::CS_CONNECTING: - return SS_OPENING; - case Socket::CS_CLOSED: - default: - return SS_CLOSED; - } -} - -StreamResult SocketStream::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - ASSERT(socket_ != NULL); - int result = socket_->Recv(buffer, buffer_len); - if (result < 0) { - if (socket_->IsBlocking()) - return SR_BLOCK; - if (error) - *error = socket_->GetError(); - return SR_ERROR; - } - if ((result > 0) || (buffer_len == 0)) { - if (read) - *read = result; - return SR_SUCCESS; - } - return SR_EOS; -} - -StreamResult SocketStream::Write(const void* data, size_t data_len, - size_t* written, int* error) { - ASSERT(socket_ != NULL); - int result = socket_->Send(data, data_len); - if (result < 0) { - if (socket_->IsBlocking()) - return SR_BLOCK; - if (error) - *error = socket_->GetError(); - return SR_ERROR; - } - if (written) - *written = result; - return SR_SUCCESS; -} - -void SocketStream::Close() { - ASSERT(socket_ != NULL); - socket_->Close(); -} - -void SocketStream::OnConnectEvent(AsyncSocket* socket) { - ASSERT(socket == socket_); - SignalEvent(this, SE_OPEN | SE_READ | SE_WRITE, 0); -} - -void SocketStream::OnReadEvent(AsyncSocket* socket) { - ASSERT(socket == socket_); - SignalEvent(this, SE_READ, 0); -} - -void SocketStream::OnWriteEvent(AsyncSocket* socket) { - ASSERT(socket == socket_); - SignalEvent(this, SE_WRITE, 0); -} - -void SocketStream::OnCloseEvent(AsyncSocket* socket, int err) { - ASSERT(socket == socket_); - SignalEvent(this, SE_CLOSE, err); -} - - -} // namespace rtc diff --git a/webrtc/base/socketstream.h b/webrtc/base/socketstream.h deleted file mode 100644 index ce9939b0f..000000000 --- a/webrtc/base/socketstream.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2005 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SOCKETSTREAM_H_ -#define WEBRTC_BASE_SOCKETSTREAM_H_ - -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/common.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// - -class SocketStream : public StreamInterface, public sigslot::has_slots<> { - public: - explicit SocketStream(AsyncSocket* socket); - virtual ~SocketStream(); - - void Attach(AsyncSocket* socket); - AsyncSocket* Detach(); - - AsyncSocket* GetSocket() { return socket_; } - - virtual StreamState GetState() const; - - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - - virtual void Close(); - - private: - void OnConnectEvent(AsyncSocket* socket); - void OnReadEvent(AsyncSocket* socket); - void OnWriteEvent(AsyncSocket* socket); - void OnCloseEvent(AsyncSocket* socket, int err); - - AsyncSocket* socket_; - - DISALLOW_EVIL_CONSTRUCTORS(SocketStream); -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_SOCKETSTREAM_H_ diff --git a/webrtc/base/ssladapter.cc b/webrtc/base/ssladapter.cc deleted file mode 100644 index d83a2779e..000000000 --- a/webrtc/base/ssladapter.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#include "webrtc/base/ssladapter.h" - -#include "webrtc/base/sslconfig.h" - -#if SSL_USE_SCHANNEL - -#include "schanneladapter.h" - -#elif SSL_USE_OPENSSL // && !SSL_USE_SCHANNEL - -#include "openssladapter.h" - -#elif SSL_USE_NSS // && !SSL_USE_CHANNEL && !SSL_USE_OPENSSL - -#include "nssstreamadapter.h" - -#endif // SSL_USE_OPENSSL && !SSL_USE_SCHANNEL && !SSL_USE_NSS - -/////////////////////////////////////////////////////////////////////////////// - -namespace rtc { - -SSLAdapter* -SSLAdapter::Create(AsyncSocket* socket) { -#if SSL_USE_SCHANNEL - return new SChannelAdapter(socket); -#elif SSL_USE_OPENSSL // && !SSL_USE_SCHANNEL - return new OpenSSLAdapter(socket); -#else // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL - delete socket; - return NULL; -#endif // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL -} - -/////////////////////////////////////////////////////////////////////////////// - -#if SSL_USE_OPENSSL - -bool InitializeSSL(VerificationCallback callback) { - return OpenSSLAdapter::InitializeSSL(callback); -} - -bool InitializeSSLThread() { - return OpenSSLAdapter::InitializeSSLThread(); -} - -bool CleanupSSL() { - return OpenSSLAdapter::CleanupSSL(); -} - -#elif SSL_USE_NSS // !SSL_USE_OPENSSL - -bool InitializeSSL(VerificationCallback callback) { - return NSSContext::InitializeSSL(callback); -} - -bool InitializeSSLThread() { - return NSSContext::InitializeSSLThread(); -} - -bool CleanupSSL() { - return NSSContext::CleanupSSL(); -} - -#else // !SSL_USE_OPENSSL && !SSL_USE_NSS - -bool InitializeSSL(VerificationCallback callback) { - return true; -} - -bool InitializeSSLThread() { - return true; -} - -bool CleanupSSL() { - return true; -} - -#endif // !SSL_USE_OPENSSL && !SSL_USE_NSS - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/ssladapter.h b/webrtc/base/ssladapter.h deleted file mode 100644 index 87b993ffb..000000000 --- a/webrtc/base/ssladapter.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SSLADAPTER_H_ -#define WEBRTC_BASE_SSLADAPTER_H_ - -#include "webrtc/base/asyncsocket.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// - -class SSLAdapter : public AsyncSocketAdapter { - public: - explicit SSLAdapter(AsyncSocket* socket) - : AsyncSocketAdapter(socket), ignore_bad_cert_(false) { } - - bool ignore_bad_cert() const { return ignore_bad_cert_; } - void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; } - - // StartSSL returns 0 if successful. - // If StartSSL is called while the socket is closed or connecting, the SSL - // negotiation will begin as soon as the socket connects. - virtual int StartSSL(const char* hostname, bool restartable) = 0; - - // Create the default SSL adapter for this platform. On failure, returns NULL - // and deletes |socket|. Otherwise, the returned SSLAdapter takes ownership - // of |socket|. - static SSLAdapter* Create(AsyncSocket* socket); - - private: - // If true, the server certificate need not match the configured hostname. - bool ignore_bad_cert_; -}; - -/////////////////////////////////////////////////////////////////////////////// - -typedef bool (*VerificationCallback)(void* cert); - -// Call this on the main thread, before using SSL. -// Call CleanupSSLThread when finished with SSL. -bool InitializeSSL(VerificationCallback callback = NULL); - -// Call to initialize additional threads. -bool InitializeSSLThread(); - -// Call to cleanup additional threads, and also the main thread. -bool CleanupSSL(); - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_SSLADAPTER_H_ diff --git a/webrtc/base/sslconfig.h b/webrtc/base/sslconfig.h deleted file mode 100644 index d824ab062..000000000 --- a/webrtc/base/sslconfig.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SSLCONFIG_H_ -#define WEBRTC_BASE_SSLCONFIG_H_ - -// If no preference has been indicated, default to SChannel on Windows and -// OpenSSL everywhere else, if it is available. -#if !defined(SSL_USE_SCHANNEL) && !defined(SSL_USE_OPENSSL) && \ - !defined(SSL_USE_NSS) -#if defined(WEBRTC_WIN) - -#define SSL_USE_SCHANNEL 1 - -#else // defined(WEBRTC_WIN) - -#if defined(HAVE_OPENSSL_SSL_H) -#define SSL_USE_OPENSSL 1 -#elif defined(HAVE_NSS_SSL_H) -#define SSL_USE_NSS 1 -#endif - -#endif // !defined(WEBRTC_WIN) -#endif - -#endif // WEBRTC_BASE_SSLCONFIG_H_ diff --git a/webrtc/base/sslfingerprint.cc b/webrtc/base/sslfingerprint.cc deleted file mode 100644 index 1419243c8..000000000 --- a/webrtc/base/sslfingerprint.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/sslfingerprint.h" - -#include -#include - -#include "webrtc/base/helpers.h" -#include "webrtc/base/messagedigest.h" -#include "webrtc/base/stringencode.h" - -namespace rtc { - -SSLFingerprint* SSLFingerprint::Create( - const std::string& algorithm, const rtc::SSLIdentity* identity) { - if (!identity) { - return NULL; - } - - return Create(algorithm, &(identity->certificate())); -} - -SSLFingerprint* SSLFingerprint::Create( - const std::string& algorithm, const rtc::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() || !rtc::IsFips180DigestAlgorithm(algorithm)) - return NULL; - - if (fingerprint.empty()) - return NULL; - - size_t value_len; - char value[rtc::MessageDigest::kMaxSize]; - value_len = rtc::hex_decode_with_delimiter(value, sizeof(value), - fingerprint.c_str(), - fingerprint.length(), - ':'); - if (!value_len) - return NULL; - - return new SSLFingerprint(algorithm, - reinterpret_cast(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 = - rtc::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 rtc diff --git a/webrtc/base/sslfingerprint.h b/webrtc/base/sslfingerprint.h deleted file mode 100644 index a63b3dd87..000000000 --- a/webrtc/base/sslfingerprint.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SSLFINGERPRINT_H_ -#define WEBRTC_BASE_SSLFINGERPRINT_H_ - -#include - -#include "webrtc/base/buffer.h" -#include "webrtc/base/sslidentity.h" - -namespace rtc { - -class SSLCertificate; - -struct SSLFingerprint { - static SSLFingerprint* Create(const std::string& algorithm, - const rtc::SSLIdentity* identity); - - static SSLFingerprint* Create(const std::string& algorithm, - const rtc::SSLCertificate* cert); - - static SSLFingerprint* CreateFromRfc4572(const std::string& algorithm, - const std::string& fingerprint); - - SSLFingerprint(const std::string& algorithm, const uint8* digest_in, - size_t digest_len); - - SSLFingerprint(const SSLFingerprint& from); - - bool operator==(const SSLFingerprint& other) const; - - std::string GetRfc4572Fingerprint() const; - - std::string ToString(); - - std::string algorithm; - rtc::Buffer digest; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SSLFINGERPRINT_H_ diff --git a/webrtc/base/sslidentity.cc b/webrtc/base/sslidentity.cc deleted file mode 100644 index 00085740d..000000000 --- a/webrtc/base/sslidentity.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Handling of certificates and keypairs for SSLStreamAdapter's peer mode. -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#include "webrtc/base/sslidentity.h" - -#include - -#include "webrtc/base/base64.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/sslconfig.h" - -#if SSL_USE_SCHANNEL - -#elif SSL_USE_OPENSSL // !SSL_USE_SCHANNEL - -#include "webrtc/base/opensslidentity.h" - -#elif SSL_USE_NSS // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL - -#include "webrtc/base/nssidentity.h" - -#endif // SSL_USE_SCHANNEL - -namespace rtc { - -const char kPemTypeCertificate[] = "CERTIFICATE"; -const char kPemTypeRsaPrivateKey[] = "RSA PRIVATE KEY"; - -bool SSLIdentity::PemToDer(const std::string& pem_type, - const std::string& pem_string, - std::string* der) { - // Find the inner body. We need this to fulfill the contract of - // returning pem_length. - size_t header = pem_string.find("-----BEGIN " + pem_type + "-----"); - if (header == std::string::npos) - return false; - - size_t body = pem_string.find("\n", header); - if (body == std::string::npos) - return false; - - size_t trailer = pem_string.find("-----END " + pem_type + "-----"); - if (trailer == std::string::npos) - return false; - - std::string inner = pem_string.substr(body + 1, trailer - (body + 1)); - - *der = Base64::Decode(inner, Base64::DO_PARSE_WHITE | - Base64::DO_PAD_ANY | - Base64::DO_TERM_BUFFER); - return true; -} - -std::string SSLIdentity::DerToPem(const std::string& pem_type, - const unsigned char* data, - size_t length) { - std::stringstream result; - - result << "-----BEGIN " << pem_type << "-----\n"; - - std::string b64_encoded; - Base64::EncodeFromArray(data, length, &b64_encoded); - - // Divide the Base-64 encoded data into 64-character chunks, as per - // 4.3.2.4 of RFC 1421. - static const size_t kChunkSize = 64; - size_t chunks = (b64_encoded.size() + (kChunkSize - 1)) / kChunkSize; - for (size_t i = 0, chunk_offset = 0; i < chunks; - ++i, chunk_offset += kChunkSize) { - result << b64_encoded.substr(chunk_offset, kChunkSize); - result << "\n"; - } - - result << "-----END " << pem_type << "-----\n"; - - return result.str(); -} - -#if SSL_USE_SCHANNEL - -SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string) { - return NULL; -} - -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; -} - -#elif SSL_USE_OPENSSL // !SSL_USE_SCHANNEL - -SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string) { - return OpenSSLCertificate::FromPEMString(pem_string); -} - -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); -} - -#elif SSL_USE_NSS // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL - -SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string) { - return NSSCertificate::FromPEMString(pem_string); -} - -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); -} - -#else // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL && !SSL_USE_NSS - -#error "No SSL implementation" - -#endif // SSL_USE_SCHANNEL - -} // namespace rtc diff --git a/webrtc/base/sslidentity.h b/webrtc/base/sslidentity.h deleted file mode 100644 index a0f32fd3b..000000000 --- a/webrtc/base/sslidentity.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Handling of certificates and keypairs for SSLStreamAdapter's peer mode. - -#ifndef WEBRTC_BASE_SSLIDENTITY_H_ -#define WEBRTC_BASE_SSLIDENTITY_H_ - -#include -#include -#include - -#include "webrtc/base/buffer.h" -#include "webrtc/base/messagedigest.h" - -namespace rtc { - -// Forward declaration due to circular dependency with SSLCertificate. -class SSLCertChain; - -// Abstract interface overridden by SSL library specific -// implementations. - -// A somewhat opaque type used to encapsulate a certificate. -// Wraps the SSL library's notion of a certificate, with reference counting. -// The SSLCertificate object is pretty much immutable once created. -// (The OpenSSL implementation only does reference counting and -// possibly caching of intermediate results.) -class SSLCertificate { - public: - // Parses and build a certificate from a PEM encoded string. - // Returns NULL on failure. - // The length of the string representation of the certificate is - // stored in *pem_length if it is non-NULL, and only if - // parsing was successful. - // Caller is responsible for freeing the returned object. - static SSLCertificate* FromPEMString(const std::string& pem_string); - virtual ~SSLCertificate() {} - - // Returns a new SSLCertificate object instance wrapping the same - // underlying certificate, including its chain if present. - // Caller is responsible for freeing the returned object. - virtual SSLCertificate* GetReference() const = 0; - - // Provides the cert chain, or returns false. The caller owns the chain. - // The chain includes a copy of each certificate, excluding the leaf. - virtual bool GetChain(SSLCertChain** chain) const = 0; - - // Returns a PEM encoded string representation of the certificate. - virtual std::string ToPEMString() const = 0; - - // Provides a DER encoded binary representation of the certificate. - virtual void ToDER(Buffer* der_buffer) const = 0; - - // Gets the name of the digest algorithm that was used to compute this - // certificate's signature. - 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, - size_t size, - size_t* length) const = 0; -}; - -// SSLCertChain is a simple wrapper for a vector of SSLCertificates. It serves -// primarily to ensure proper memory management (especially deletion) of the -// SSLCertificate pointers. -class SSLCertChain { - public: - // These constructors copy the provided SSLCertificate(s), so the caller - // retains ownership. - explicit SSLCertChain(const std::vector& certs) { - ASSERT(!certs.empty()); - certs_.resize(certs.size()); - std::transform(certs.begin(), certs.end(), certs_.begin(), DupCert); - } - explicit SSLCertChain(const SSLCertificate* cert) { - certs_.push_back(cert->GetReference()); - } - - ~SSLCertChain() { - std::for_each(certs_.begin(), certs_.end(), DeleteCert); - } - - // Vector access methods. - size_t GetSize() const { return certs_.size(); } - - // Returns a temporary reference, only valid until the chain is destroyed. - const SSLCertificate& Get(size_t pos) const { return *(certs_[pos]); } - - // Returns a new SSLCertChain object instance wrapping the same underlying - // certificate chain. Caller is responsible for freeing the returned object. - SSLCertChain* Copy() const { - return new SSLCertChain(certs_); - } - - private: - // Helper function for duplicating a vector of certificates. - static SSLCertificate* DupCert(const SSLCertificate* cert) { - return cert->GetReference(); - } - - // Helper function for deleting a vector of certificates. - static void DeleteCert(SSLCertificate* cert) { delete cert; } - - std::vector certs_; - - 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. -class SSLIdentity { - public: - // Generates an identity (keypair and self-signed certificate). 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. - // Returns NULL on failure. - // 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); - - virtual ~SSLIdentity() {} - - // Returns a new SSLIdentity object instance wrapping the same - // identity information. - // Caller is responsible for freeing the returned object. - virtual SSLIdentity* GetReference() const = 0; - - // Returns a temporary reference to the certificate. - virtual const SSLCertificate& certificate() const = 0; - - // Helpers for parsing converting between PEM and DER format. - static bool PemToDer(const std::string& pem_type, - const std::string& pem_string, - std::string* der); - static std::string DerToPem(const std::string& pem_type, - const unsigned char* data, - size_t length); -}; - -extern const char kPemTypeCertificate[]; -extern const char kPemTypeRsaPrivateKey[]; - -} // namespace rtc - -#endif // WEBRTC_BASE_SSLIDENTITY_H_ diff --git a/webrtc/base/sslidentity_unittest.cc b/webrtc/base/sslidentity_unittest.cc deleted file mode 100644 index 1486bebb5..000000000 --- a/webrtc/base/sslidentity_unittest.cc +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/ssladapter.h" -#include "webrtc/base/sslidentity.h" - -using rtc::SSLIdentity; - -const char kTestCertificate[] = "-----BEGIN CERTIFICATE-----\n" - "MIIB6TCCAVICAQYwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV\n" - "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD\n" - "VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNMDAxMDE2MjIzMTAzWhcNMDMwMTE0\n" - "MjIzMTAzWjBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG\n" - "A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0IGNl\n" - "cnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8SMVIP\n" - "Fe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8Ey2//\n" - "Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQCT0grFQeZaqYb5EYfk20XixZV4\n" - "GmyAbXMftG1Eo7qGiMhYzRwGNWxEYojf5PZkYZXvSqZ/ZXHXa4g59jK/rJNnaVGM\n" - "k+xIX8mxQvlV0n5O9PIha5BX5teZnkHKgL8aKKLKW1BK7YTngsfSzzaeame5iKfz\n" - "itAE+OjGF+PFKbwX8Q==\n" - "-----END CERTIFICATE-----\n"; - -const unsigned char kTestCertSha1[] = {0xA6, 0xC8, 0x59, 0xEA, - 0xC3, 0x7E, 0x6D, 0x33, - 0xCF, 0xE2, 0x69, 0x9D, - 0x74, 0xE6, 0xF6, 0x8A, - 0x9E, 0x47, 0xA7, 0xCA}; - -class SSLIdentityTest : public testing::Test { - public: - SSLIdentityTest() : - identity1_(), identity2_() { - } - - ~SSLIdentityTest() { - } - - static void SetUpTestCase() { - rtc::InitializeSSL(); - } - - static void TearDownTestCase() { - rtc::CleanupSSL(); - } - - virtual void SetUp() { - identity1_.reset(SSLIdentity::Generate("test1")); - identity2_.reset(SSLIdentity::Generate("test2")); - - ASSERT_TRUE(identity1_); - ASSERT_TRUE(identity2_); - - test_cert_.reset( - rtc::SSLCertificate::FromPEMString(kTestCertificate)); - ASSERT_TRUE(test_cert_); - } - - void TestGetSignatureDigestAlgorithm() { - std::string digest_algorithm; - // Both NSSIdentity::Generate and OpenSSLIdentity::Generate are - // hard-coded to generate RSA-SHA1 certificates. - ASSERT_TRUE(identity1_->certificate().GetSignatureDigestAlgorithm( - &digest_algorithm)); - ASSERT_EQ(rtc::DIGEST_SHA_1, digest_algorithm); - ASSERT_TRUE(identity2_->certificate().GetSignatureDigestAlgorithm( - &digest_algorithm)); - ASSERT_EQ(rtc::DIGEST_SHA_1, digest_algorithm); - - // The test certificate has an MD5-based signature. - ASSERT_TRUE(test_cert_->GetSignatureDigestAlgorithm(&digest_algorithm)); - ASSERT_EQ(rtc::DIGEST_MD5, digest_algorithm); - } - - void TestDigest(const std::string &algorithm, size_t expected_len, - const unsigned char *expected_digest = NULL) { - unsigned char digest1[64]; - unsigned char digest1b[64]; - unsigned char digest2[64]; - size_t digest1_len; - size_t digest1b_len; - size_t digest2_len; - bool rv; - - rv = identity1_->certificate().ComputeDigest(algorithm, - digest1, sizeof(digest1), - &digest1_len); - EXPECT_TRUE(rv); - EXPECT_EQ(expected_len, digest1_len); - - rv = identity1_->certificate().ComputeDigest(algorithm, - digest1b, sizeof(digest1b), - &digest1b_len); - EXPECT_TRUE(rv); - EXPECT_EQ(expected_len, digest1b_len); - EXPECT_EQ(0, memcmp(digest1, digest1b, expected_len)); - - - rv = identity2_->certificate().ComputeDigest(algorithm, - digest2, sizeof(digest2), - &digest2_len); - EXPECT_TRUE(rv); - EXPECT_EQ(expected_len, digest2_len); - EXPECT_NE(0, memcmp(digest1, digest2, expected_len)); - - // If we have an expected hash for the test cert, check it. - if (expected_digest) { - unsigned char digest3[64]; - size_t digest3_len; - - rv = test_cert_->ComputeDigest(algorithm, digest3, sizeof(digest3), - &digest3_len); - EXPECT_TRUE(rv); - EXPECT_EQ(expected_len, digest3_len); - EXPECT_EQ(0, memcmp(digest3, expected_digest, expected_len)); - } - } - - private: - rtc::scoped_ptr identity1_; - rtc::scoped_ptr identity2_; - rtc::scoped_ptr test_cert_; -}; - -TEST_F(SSLIdentityTest, DigestSHA1) { - TestDigest(rtc::DIGEST_SHA_1, 20, kTestCertSha1); -} - -// HASH_AlgSHA224 is not supported in the chromium linux build. -#if SSL_USE_NSS -TEST_F(SSLIdentityTest, DISABLED_DigestSHA224) { -#else -TEST_F(SSLIdentityTest, DigestSHA224) { -#endif - TestDigest(rtc::DIGEST_SHA_224, 28); -} - -TEST_F(SSLIdentityTest, DigestSHA256) { - TestDigest(rtc::DIGEST_SHA_256, 32); -} - -TEST_F(SSLIdentityTest, DigestSHA384) { - TestDigest(rtc::DIGEST_SHA_384, 48); -} - -TEST_F(SSLIdentityTest, DigestSHA512) { - TestDigest(rtc::DIGEST_SHA_512, 64); -} - -TEST_F(SSLIdentityTest, FromPEMStrings) { - static const char kRSA_PRIVATE_KEY_PEM[] = - "-----BEGIN RSA PRIVATE KEY-----\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" - "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"; - - rtc::scoped_ptr identity( - SSLIdentity::FromPEMStrings(kRSA_PRIVATE_KEY_PEM, kCERT_PEM)); - EXPECT_TRUE(identity); - EXPECT_EQ(kCERT_PEM, identity->certificate().ToPEMString()); -} - -TEST_F(SSLIdentityTest, PemDerConversion) { - std::string der; - EXPECT_TRUE(SSLIdentity::PemToDer("CERTIFICATE", kTestCertificate, &der)); - - EXPECT_EQ(kTestCertificate, SSLIdentity::DerToPem( - "CERTIFICATE", - reinterpret_cast(der.data()), der.length())); -} - -TEST_F(SSLIdentityTest, GetSignatureDigestAlgorithm) { - TestGetSignatureDigestAlgorithm(); -} diff --git a/webrtc/base/sslroots.h b/webrtc/base/sslroots.h deleted file mode 100644 index 0f983cd60..000000000 --- a/webrtc/base/sslroots.h +++ /dev/null @@ -1,4930 +0,0 @@ -// This file is the root certificates in C form that are needed to connect to -// Google. - -// It was generated with the following command line: -// > python //depot/googleclient/talk/tools/generate_sslroots.py -// //depot/google3/security/cacerts/for_connecting_to_google/roots.pem - -/* subject:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root */ -/* issuer :/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root */ - - -const unsigned char AddTrust_External_Root_certificate[1082]={ -0x30,0x82,0x04,0x36,0x30,0x82,0x03,0x1E,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31,0x14, -0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75,0x73, -0x74,0x20,0x41,0x42,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41, -0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x45,0x78,0x74,0x65,0x72,0x6E,0x61,0x6C, -0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x22,0x30,0x20, -0x06,0x03,0x55,0x04,0x03,0x13,0x19,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20, -0x45,0x78,0x74,0x65,0x72,0x6E,0x61,0x6C,0x20,0x43,0x41,0x20,0x52,0x6F,0x6F,0x74, -0x30,0x1E,0x17,0x0D,0x30,0x30,0x30,0x35,0x33,0x30,0x31,0x30,0x34,0x38,0x33,0x38, -0x5A,0x17,0x0D,0x32,0x30,0x30,0x35,0x33,0x30,0x31,0x30,0x34,0x38,0x33,0x38,0x5A, -0x30,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31, -0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75, -0x73,0x74,0x20,0x41,0x42,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D, -0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x45,0x78,0x74,0x65,0x72,0x6E,0x61, -0x6C,0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x22,0x30, -0x20,0x06,0x03,0x55,0x04,0x03,0x13,0x19,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74, -0x20,0x45,0x78,0x74,0x65,0x72,0x6E,0x61,0x6C,0x20,0x43,0x41,0x20,0x52,0x6F,0x6F, -0x74,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01, -0x01,0x00,0xB7,0xF7,0x1A,0x33,0xE6,0xF2,0x00,0x04,0x2D,0x39,0xE0,0x4E,0x5B,0xED, -0x1F,0xBC,0x6C,0x0F,0xCD,0xB5,0xFA,0x23,0xB6,0xCE,0xDE,0x9B,0x11,0x33,0x97,0xA4, -0x29,0x4C,0x7D,0x93,0x9F,0xBD,0x4A,0xBC,0x93,0xED,0x03,0x1A,0xE3,0x8F,0xCF,0xE5, -0x6D,0x50,0x5A,0xD6,0x97,0x29,0x94,0x5A,0x80,0xB0,0x49,0x7A,0xDB,0x2E,0x95,0xFD, -0xB8,0xCA,0xBF,0x37,0x38,0x2D,0x1E,0x3E,0x91,0x41,0xAD,0x70,0x56,0xC7,0xF0,0x4F, -0x3F,0xE8,0x32,0x9E,0x74,0xCA,0xC8,0x90,0x54,0xE9,0xC6,0x5F,0x0F,0x78,0x9D,0x9A, -0x40,0x3C,0x0E,0xAC,0x61,0xAA,0x5E,0x14,0x8F,0x9E,0x87,0xA1,0x6A,0x50,0xDC,0xD7, -0x9A,0x4E,0xAF,0x05,0xB3,0xA6,0x71,0x94,0x9C,0x71,0xB3,0x50,0x60,0x0A,0xC7,0x13, -0x9D,0x38,0x07,0x86,0x02,0xA8,0xE9,0xA8,0x69,0x26,0x18,0x90,0xAB,0x4C,0xB0,0x4F, -0x23,0xAB,0x3A,0x4F,0x84,0xD8,0xDF,0xCE,0x9F,0xE1,0x69,0x6F,0xBB,0xD7,0x42,0xD7, -0x6B,0x44,0xE4,0xC7,0xAD,0xEE,0x6D,0x41,0x5F,0x72,0x5A,0x71,0x08,0x37,0xB3,0x79, -0x65,0xA4,0x59,0xA0,0x94,0x37,0xF7,0x00,0x2F,0x0D,0xC2,0x92,0x72,0xDA,0xD0,0x38, -0x72,0xDB,0x14,0xA8,0x45,0xC4,0x5D,0x2A,0x7D,0xB7,0xB4,0xD6,0xC4,0xEE,0xAC,0xCD, -0x13,0x44,0xB7,0xC9,0x2B,0xDD,0x43,0x00,0x25,0xFA,0x61,0xB9,0x69,0x6A,0x58,0x23, -0x11,0xB7,0xA7,0x33,0x8F,0x56,0x75,0x59,0xF5,0xCD,0x29,0xD7,0x46,0xB7,0x0A,0x2B, -0x65,0xB6,0xD3,0x42,0x6F,0x15,0xB2,0xB8,0x7B,0xFB,0xEF,0xE9,0x5D,0x53,0xD5,0x34, -0x5A,0x27,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xDC,0x30,0x81,0xD9,0x30,0x1D,0x06, -0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xAD,0xBD,0x98,0x7A,0x34,0xB4,0x26,0xF7, -0xFA,0xC4,0x26,0x54,0xEF,0x03,0xBD,0xE0,0x24,0xCB,0x54,0x1A,0x30,0x0B,0x06,0x03, -0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13, -0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x81,0x99,0x06,0x03,0x55, -0x1D,0x23,0x04,0x81,0x91,0x30,0x81,0x8E,0x80,0x14,0xAD,0xBD,0x98,0x7A,0x34,0xB4, -0x26,0xF7,0xFA,0xC4,0x26,0x54,0xEF,0x03,0xBD,0xE0,0x24,0xCB,0x54,0x1A,0xA1,0x73, -0xA4,0x71,0x30,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53, -0x45,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54, -0x72,0x75,0x73,0x74,0x20,0x41,0x42,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B, -0x13,0x1D,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x45,0x78,0x74,0x65,0x72, -0x6E,0x61,0x6C,0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31, -0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x13,0x19,0x41,0x64,0x64,0x54,0x72,0x75, -0x73,0x74,0x20,0x45,0x78,0x74,0x65,0x72,0x6E,0x61,0x6C,0x20,0x43,0x41,0x20,0x52, -0x6F,0x6F,0x74,0x82,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xB0,0x9B,0xE0,0x85,0x25,0xC2, -0xD6,0x23,0xE2,0x0F,0x96,0x06,0x92,0x9D,0x41,0x98,0x9C,0xD9,0x84,0x79,0x81,0xD9, -0x1E,0x5B,0x14,0x07,0x23,0x36,0x65,0x8F,0xB0,0xD8,0x77,0xBB,0xAC,0x41,0x6C,0x47, -0x60,0x83,0x51,0xB0,0xF9,0x32,0x3D,0xE7,0xFC,0xF6,0x26,0x13,0xC7,0x80,0x16,0xA5, -0xBF,0x5A,0xFC,0x87,0xCF,0x78,0x79,0x89,0x21,0x9A,0xE2,0x4C,0x07,0x0A,0x86,0x35, -0xBC,0xF2,0xDE,0x51,0xC4,0xD2,0x96,0xB7,0xDC,0x7E,0x4E,0xEE,0x70,0xFD,0x1C,0x39, -0xEB,0x0C,0x02,0x51,0x14,0x2D,0x8E,0xBD,0x16,0xE0,0xC1,0xDF,0x46,0x75,0xE7,0x24, -0xAD,0xEC,0xF4,0x42,0xB4,0x85,0x93,0x70,0x10,0x67,0xBA,0x9D,0x06,0x35,0x4A,0x18, -0xD3,0x2B,0x7A,0xCC,0x51,0x42,0xA1,0x7A,0x63,0xD1,0xE6,0xBB,0xA1,0xC5,0x2B,0xC2, -0x36,0xBE,0x13,0x0D,0xE6,0xBD,0x63,0x7E,0x79,0x7B,0xA7,0x09,0x0D,0x40,0xAB,0x6A, -0xDD,0x8F,0x8A,0xC3,0xF6,0xF6,0x8C,0x1A,0x42,0x05,0x51,0xD4,0x45,0xF5,0x9F,0xA7, -0x62,0x21,0x68,0x15,0x20,0x43,0x3C,0x99,0xE7,0x7C,0xBD,0x24,0xD8,0xA9,0x91,0x17, -0x73,0x88,0x3F,0x56,0x1B,0x31,0x38,0x18,0xB4,0x71,0x0F,0x9A,0xCD,0xC8,0x0E,0x9E, -0x8E,0x2E,0x1B,0xE1,0x8C,0x98,0x83,0xCB,0x1F,0x31,0xF1,0x44,0x4C,0xC6,0x04,0x73, -0x49,0x76,0x60,0x0F,0xC7,0xF8,0xBD,0x17,0x80,0x6B,0x2E,0xE9,0xCC,0x4C,0x0E,0x5A, -0x9A,0x79,0x0F,0x20,0x0A,0x2E,0xD5,0x9E,0x63,0x26,0x1E,0x55,0x92,0x94,0xD8,0x82, -0x17,0x5A,0x7B,0xD0,0xBC,0xC7,0x8F,0x4E,0x86,0x04, -}; - - -/* subject:/C=SE/O=AddTrust AB/OU=AddTrust TTP Network/CN=AddTrust Class 1 CA Root */ -/* issuer :/C=SE/O=AddTrust AB/OU=AddTrust TTP Network/CN=AddTrust Class 1 CA Root */ - - -const unsigned char AddTrust_Low_Value_Services_Root_certificate[1052]={ -0x30,0x82,0x04,0x18,0x30,0x82,0x03,0x00,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x65,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31,0x14, -0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75,0x73, -0x74,0x20,0x41,0x42,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13,0x14,0x41, -0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77, -0x6F,0x72,0x6B,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x41,0x64, -0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x43, -0x41,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x30,0x30,0x30,0x35,0x33,0x30, -0x31,0x30,0x33,0x38,0x33,0x31,0x5A,0x17,0x0D,0x32,0x30,0x30,0x35,0x33,0x30,0x31, -0x30,0x33,0x38,0x33,0x31,0x5A,0x30,0x65,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, -0x06,0x13,0x02,0x53,0x45,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B, -0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x41,0x42,0x31,0x1D,0x30,0x1B,0x06, -0x03,0x55,0x04,0x0B,0x13,0x14,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x54, -0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x21,0x30,0x1F,0x06,0x03, -0x55,0x04,0x03,0x13,0x18,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x43,0x6C, -0x61,0x73,0x73,0x20,0x31,0x20,0x43,0x41,0x20,0x52,0x6F,0x6F,0x74,0x30,0x82,0x01, -0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00, -0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0x96,0x96, -0xD4,0x21,0x49,0x60,0xE2,0x6B,0xE8,0x41,0x07,0x0C,0xDE,0xC4,0xE0,0xDC,0x13,0x23, -0xCD,0xC1,0x35,0xC7,0xFB,0xD6,0x4E,0x11,0x0A,0x67,0x5E,0xF5,0x06,0x5B,0x6B,0xA5, -0x08,0x3B,0x5B,0x29,0x16,0x3A,0xE7,0x87,0xB2,0x34,0x06,0xC5,0xBC,0x05,0xA5,0x03, -0x7C,0x82,0xCB,0x29,0x10,0xAE,0xE1,0x88,0x81,0xBD,0xD6,0x9E,0xD3,0xFE,0x2D,0x56, -0xC1,0x15,0xCE,0xE3,0x26,0x9D,0x15,0x2E,0x10,0xFB,0x06,0x8F,0x30,0x04,0xDE,0xA7, -0xB4,0x63,0xB4,0xFF,0xB1,0x9C,0xAE,0x3C,0xAF,0x77,0xB6,0x56,0xC5,0xB5,0xAB,0xA2, -0xE9,0x69,0x3A,0x3D,0x0E,0x33,0x79,0x32,0x3F,0x70,0x82,0x92,0x99,0x61,0x6D,0x8D, -0x30,0x08,0x8F,0x71,0x3F,0xA6,0x48,0x57,0x19,0xF8,0x25,0xDC,0x4B,0x66,0x5C,0xA5, -0x74,0x8F,0x98,0xAE,0xC8,0xF9,0xC0,0x06,0x22,0xE7,0xAC,0x73,0xDF,0xA5,0x2E,0xFB, -0x52,0xDC,0xB1,0x15,0x65,0x20,0xFA,0x35,0x66,0x69,0xDE,0xDF,0x2C,0xF1,0x6E,0xBC, -0x30,0xDB,0x2C,0x24,0x12,0xDB,0xEB,0x35,0x35,0x68,0x90,0xCB,0x00,0xB0,0x97,0x21, -0x3D,0x74,0x21,0x23,0x65,0x34,0x2B,0xBB,0x78,0x59,0xA3,0xD6,0xE1,0x76,0x39,0x9A, -0xA4,0x49,0x8E,0x8C,0x74,0xAF,0x6E,0xA4,0x9A,0xA3,0xD9,0x9B,0xD2,0x38,0x5C,0x9B, -0xA2,0x18,0xCC,0x75,0x23,0x84,0xBE,0xEB,0xE2,0x4D,0x33,0x71,0x8E,0x1A,0xF0,0xC2, -0xF8,0xC7,0x1D,0xA2,0xAD,0x03,0x97,0x2C,0xF8,0xCF,0x25,0xC6,0xF6,0xB8,0x24,0x31, -0xB1,0x63,0x5D,0x92,0x7F,0x63,0xF0,0x25,0xC9,0x53,0x2E,0x1F,0xBF,0x4D,0x02,0x03, -0x01,0x00,0x01,0xA3,0x81,0xD2,0x30,0x81,0xCF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E, -0x04,0x16,0x04,0x14,0x95,0xB1,0xB4,0xF0,0x94,0xB6,0xBD,0xC7,0xDA,0xD1,0x11,0x09, -0x21,0xBE,0xC1,0xAF,0x49,0xFD,0x10,0x7B,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04, -0x04,0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, -0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x81,0x8F,0x06,0x03,0x55,0x1D,0x23,0x04,0x81, -0x87,0x30,0x81,0x84,0x80,0x14,0x95,0xB1,0xB4,0xF0,0x94,0xB6,0xBD,0xC7,0xDA,0xD1, -0x11,0x09,0x21,0xBE,0xC1,0xAF,0x49,0xFD,0x10,0x7B,0xA1,0x69,0xA4,0x67,0x30,0x65, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31,0x14,0x30, -0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74, -0x20,0x41,0x42,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13,0x14,0x41,0x64, -0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F, -0x72,0x6B,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x41,0x64,0x64, -0x54,0x72,0x75,0x73,0x74,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x43,0x41, -0x20,0x52,0x6F,0x6F,0x74,0x82,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x2C,0x6D,0x64,0x1B, -0x1F,0xCD,0x0D,0xDD,0xB9,0x01,0xFA,0x96,0x63,0x34,0x32,0x48,0x47,0x99,0xAE,0x97, -0xED,0xFD,0x72,0x16,0xA6,0x73,0x47,0x5A,0xF4,0xEB,0xDD,0xE9,0xF5,0xD6,0xFB,0x45, -0xCC,0x29,0x89,0x44,0x5D,0xBF,0x46,0x39,0x3D,0xE8,0xEE,0xBC,0x4D,0x54,0x86,0x1E, -0x1D,0x6C,0xE3,0x17,0x27,0x43,0xE1,0x89,0x56,0x2B,0xA9,0x6F,0x72,0x4E,0x49,0x33, -0xE3,0x72,0x7C,0x2A,0x23,0x9A,0xBC,0x3E,0xFF,0x28,0x2A,0xED,0xA3,0xFF,0x1C,0x23, -0xBA,0x43,0x57,0x09,0x67,0x4D,0x4B,0x62,0x06,0x2D,0xF8,0xFF,0x6C,0x9D,0x60,0x1E, -0xD8,0x1C,0x4B,0x7D,0xB5,0x31,0x2F,0xD9,0xD0,0x7C,0x5D,0xF8,0xDE,0x6B,0x83,0x18, -0x78,0x37,0x57,0x2F,0xE8,0x33,0x07,0x67,0xDF,0x1E,0xC7,0x6B,0x2A,0x95,0x76,0xAE, -0x8F,0x57,0xA3,0xF0,0xF4,0x52,0xB4,0xA9,0x53,0x08,0xCF,0xE0,0x4F,0xD3,0x7A,0x53, -0x8B,0xFD,0xBB,0x1C,0x56,0x36,0xF2,0xFE,0xB2,0xB6,0xE5,0x76,0xBB,0xD5,0x22,0x65, -0xA7,0x3F,0xFE,0xD1,0x66,0xAD,0x0B,0xBC,0x6B,0x99,0x86,0xEF,0x3F,0x7D,0xF3,0x18, -0x32,0xCA,0x7B,0xC6,0xE3,0xAB,0x64,0x46,0x95,0xF8,0x26,0x69,0xD9,0x55,0x83,0x7B, -0x2C,0x96,0x07,0xFF,0x59,0x2C,0x44,0xA3,0xC6,0xE5,0xE9,0xA9,0xDC,0xA1,0x63,0x80, -0x5A,0x21,0x5E,0x21,0xCF,0x53,0x54,0xF0,0xBA,0x6F,0x89,0xDB,0xA8,0xAA,0x95,0xCF, -0x8B,0xE3,0x71,0xCC,0x1E,0x1B,0x20,0x44,0x08,0xC0,0x7A,0xB6,0x40,0xFD,0xC4,0xE4, -0x35,0xE1,0x1D,0x16,0x1C,0xD0,0xBC,0x2B,0x8E,0xD6,0x71,0xD9, -}; - - -/* subject:/C=SE/O=AddTrust AB/OU=AddTrust TTP Network/CN=AddTrust Public CA Root */ -/* issuer :/C=SE/O=AddTrust AB/OU=AddTrust TTP Network/CN=AddTrust Public CA Root */ - - -const unsigned char AddTrust_Public_Services_Root_certificate[1049]={ -0x30,0x82,0x04,0x15,0x30,0x82,0x02,0xFD,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x64,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31,0x14, -0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75,0x73, -0x74,0x20,0x41,0x42,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13,0x14,0x41, -0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77, -0x6F,0x72,0x6B,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x41,0x64, -0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x43,0x41, -0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x30,0x30,0x30,0x35,0x33,0x30,0x31, -0x30,0x34,0x31,0x35,0x30,0x5A,0x17,0x0D,0x32,0x30,0x30,0x35,0x33,0x30,0x31,0x30, -0x34,0x31,0x35,0x30,0x5A,0x30,0x64,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, -0x13,0x02,0x53,0x45,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41, -0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x41,0x42,0x31,0x1D,0x30,0x1B,0x06,0x03, -0x55,0x04,0x0B,0x13,0x14,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x54,0x54, -0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x20,0x30,0x1E,0x06,0x03,0x55, -0x04,0x03,0x13,0x17,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x50,0x75,0x62, -0x6C,0x69,0x63,0x20,0x43,0x41,0x20,0x52,0x6F,0x6F,0x74,0x30,0x82,0x01,0x22,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82, -0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xE9,0x1A,0x30,0x8F, -0x83,0x88,0x14,0xC1,0x20,0xD8,0x3C,0x9B,0x8F,0x1B,0x7E,0x03,0x74,0xBB,0xDA,0x69, -0xD3,0x46,0xA5,0xF8,0x8E,0xC2,0x0C,0x11,0x90,0x51,0xA5,0x2F,0x66,0x54,0x40,0x55, -0xEA,0xDB,0x1F,0x4A,0x56,0xEE,0x9F,0x23,0x6E,0xF4,0x39,0xCB,0xA1,0xB9,0x6F,0xF2, -0x7E,0xF9,0x5D,0x87,0x26,0x61,0x9E,0x1C,0xF8,0xE2,0xEC,0xA6,0x81,0xF8,0x21,0xC5, -0x24,0xCC,0x11,0x0C,0x3F,0xDB,0x26,0x72,0x7A,0xC7,0x01,0x97,0x07,0x17,0xF9,0xD7, -0x18,0x2C,0x30,0x7D,0x0E,0x7A,0x1E,0x62,0x1E,0xC6,0x4B,0xC0,0xFD,0x7D,0x62,0x77, -0xD3,0x44,0x1E,0x27,0xF6,0x3F,0x4B,0x44,0xB3,0xB7,0x38,0xD9,0x39,0x1F,0x60,0xD5, -0x51,0x92,0x73,0x03,0xB4,0x00,0x69,0xE3,0xF3,0x14,0x4E,0xEE,0xD1,0xDC,0x09,0xCF, -0x77,0x34,0x46,0x50,0xB0,0xF8,0x11,0xF2,0xFE,0x38,0x79,0xF7,0x07,0x39,0xFE,0x51, -0x92,0x97,0x0B,0x5B,0x08,0x5F,0x34,0x86,0x01,0xAD,0x88,0x97,0xEB,0x66,0xCD,0x5E, -0xD1,0xFF,0xDC,0x7D,0xF2,0x84,0xDA,0xBA,0x77,0xAD,0xDC,0x80,0x08,0xC7,0xA7,0x87, -0xD6,0x55,0x9F,0x97,0x6A,0xE8,0xC8,0x11,0x64,0xBA,0xE7,0x19,0x29,0x3F,0x11,0xB3, -0x78,0x90,0x84,0x20,0x52,0x5B,0x11,0xEF,0x78,0xD0,0x83,0xF6,0xD5,0x48,0x90,0xD0, -0x30,0x1C,0xCF,0x80,0xF9,0x60,0xFE,0x79,0xE4,0x88,0xF2,0xDD,0x00,0xEB,0x94,0x45, -0xEB,0x65,0x94,0x69,0x40,0xBA,0xC0,0xD5,0xB4,0xB8,0xBA,0x7D,0x04,0x11,0xA8,0xEB, -0x31,0x05,0x96,0x94,0x4E,0x58,0x21,0x8E,0x9F,0xD0,0x60,0xFD,0x02,0x03,0x01,0x00, -0x01,0xA3,0x81,0xD1,0x30,0x81,0xCE,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, -0x04,0x14,0x81,0x3E,0x37,0xD8,0x92,0xB0,0x1F,0x77,0x9F,0x5C,0xB4,0xAB,0x73,0xAA, -0xE7,0xF6,0x34,0x60,0x2F,0xFA,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03, -0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, -0x03,0x01,0x01,0xFF,0x30,0x81,0x8E,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,0x86,0x30, -0x81,0x83,0x80,0x14,0x81,0x3E,0x37,0xD8,0x92,0xB0,0x1F,0x77,0x9F,0x5C,0xB4,0xAB, -0x73,0xAA,0xE7,0xF6,0x34,0x60,0x2F,0xFA,0xA1,0x68,0xA4,0x66,0x30,0x64,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31,0x14,0x30,0x12,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x41, -0x42,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13,0x14,0x41,0x64,0x64,0x54, -0x72,0x75,0x73,0x74,0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B, -0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x41,0x64,0x64,0x54,0x72, -0x75,0x73,0x74,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x43,0x41,0x20,0x52,0x6F, -0x6F,0x74,0x82,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x03,0xF7,0x15,0x4A,0xF8,0x24,0xDA, -0x23,0x56,0x16,0x93,0x76,0xDD,0x36,0x28,0xB9,0xAE,0x1B,0xB8,0xC3,0xF1,0x64,0xBA, -0x20,0x18,0x78,0x95,0x29,0x27,0x57,0x05,0xBC,0x7C,0x2A,0xF4,0xB9,0x51,0x55,0xDA, -0x87,0x02,0xDE,0x0F,0x16,0x17,0x31,0xF8,0xAA,0x79,0x2E,0x09,0x13,0xBB,0xAF,0xB2, -0x20,0x19,0x12,0xE5,0x93,0xF9,0x4B,0xF9,0x83,0xE8,0x44,0xD5,0xB2,0x41,0x25,0xBF, -0x88,0x75,0x6F,0xFF,0x10,0xFC,0x4A,0x54,0xD0,0x5F,0xF0,0xFA,0xEF,0x36,0x73,0x7D, -0x1B,0x36,0x45,0xC6,0x21,0x6D,0xB4,0x15,0xB8,0x4E,0xCF,0x9C,0x5C,0xA5,0x3D,0x5A, -0x00,0x8E,0x06,0xE3,0x3C,0x6B,0x32,0x7B,0xF2,0x9F,0xF0,0xB6,0xFD,0xDF,0xF0,0x28, -0x18,0x48,0xF0,0xC6,0xBC,0xD0,0xBF,0x34,0x80,0x96,0xC2,0x4A,0xB1,0x6D,0x8E,0xC7, -0x90,0x45,0xDE,0x2F,0x67,0xAC,0x45,0x04,0xA3,0x7A,0xDC,0x55,0x92,0xC9,0x47,0x66, -0xD8,0x1A,0x8C,0xC7,0xED,0x9C,0x4E,0x9A,0xE0,0x12,0xBB,0xB5,0x6A,0x4C,0x84,0xE1, -0xE1,0x22,0x0D,0x87,0x00,0x64,0xFE,0x8C,0x7D,0x62,0x39,0x65,0xA6,0xEF,0x42,0xB6, -0x80,0x25,0x12,0x61,0x01,0xA8,0x24,0x13,0x70,0x00,0x11,0x26,0x5F,0xFA,0x35,0x50, -0xC5,0x48,0xCC,0x06,0x47,0xE8,0x27,0xD8,0x70,0x8D,0x5F,0x64,0xE6,0xA1,0x44,0x26, -0x5E,0x22,0xEC,0x92,0xCD,0xFF,0x42,0x9A,0x44,0x21,0x6D,0x5C,0xC5,0xE3,0x22,0x1D, -0x5F,0x47,0x12,0xE7,0xCE,0x5F,0x5D,0xFA,0xD8,0xAA,0xB1,0x33,0x2D,0xD9,0x76,0xF2, -0x4E,0x3A,0x33,0x0C,0x2B,0xB3,0x2D,0x90,0x06, -}; - - -/* subject:/C=SE/O=AddTrust AB/OU=AddTrust TTP Network/CN=AddTrust Qualified CA Root */ -/* issuer :/C=SE/O=AddTrust AB/OU=AddTrust TTP Network/CN=AddTrust Qualified CA Root */ - - -const unsigned char AddTrust_Qualified_Certificates_Root_certificate[1058]={ -0x30,0x82,0x04,0x1E,0x30,0x82,0x03,0x06,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x67,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31,0x14, -0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75,0x73, -0x74,0x20,0x41,0x42,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13,0x14,0x41, -0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77, -0x6F,0x72,0x6B,0x31,0x23,0x30,0x21,0x06,0x03,0x55,0x04,0x03,0x13,0x1A,0x41,0x64, -0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x51,0x75,0x61,0x6C,0x69,0x66,0x69,0x65,0x64, -0x20,0x43,0x41,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x30,0x30,0x30,0x35, -0x33,0x30,0x31,0x30,0x34,0x34,0x35,0x30,0x5A,0x17,0x0D,0x32,0x30,0x30,0x35,0x33, -0x30,0x31,0x30,0x34,0x34,0x35,0x30,0x5A,0x30,0x67,0x31,0x0B,0x30,0x09,0x06,0x03, -0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A, -0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x41,0x42,0x31,0x1D,0x30, -0x1B,0x06,0x03,0x55,0x04,0x0B,0x13,0x14,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74, -0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x23,0x30,0x21, -0x06,0x03,0x55,0x04,0x03,0x13,0x1A,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20, -0x51,0x75,0x61,0x6C,0x69,0x66,0x69,0x65,0x64,0x20,0x43,0x41,0x20,0x52,0x6F,0x6F, -0x74,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01, -0x01,0x00,0xE4,0x1E,0x9A,0xFE,0xDC,0x09,0x5A,0x87,0xA4,0x9F,0x47,0xBE,0x11,0x5F, -0xAF,0x84,0x34,0xDB,0x62,0x3C,0x79,0x78,0xB7,0xE9,0x30,0xB5,0xEC,0x0C,0x1C,0x2A, -0xC4,0x16,0xFF,0xE0,0xEC,0x71,0xEB,0x8A,0xF5,0x11,0x6E,0xED,0x4F,0x0D,0x91,0xD2, -0x12,0x18,0x2D,0x49,0x15,0x01,0xC2,0xA4,0x22,0x13,0xC7,0x11,0x64,0xFF,0x22,0x12, -0x9A,0xB9,0x8E,0x5C,0x2F,0x08,0xCF,0x71,0x6A,0xB3,0x67,0x01,0x59,0xF1,0x5D,0x46, -0xF3,0xB0,0x78,0xA5,0xF6,0x0E,0x42,0x7A,0xE3,0x7F,0x1B,0xCC,0xD0,0xF0,0xB7,0x28, -0xFD,0x2A,0xEA,0x9E,0xB3,0xB0,0xB9,0x04,0xAA,0xFD,0xF6,0xC7,0xB4,0xB1,0xB8,0x2A, -0xA0,0xFB,0x58,0xF1,0x19,0xA0,0x6F,0x70,0x25,0x7E,0x3E,0x69,0x4A,0x7F,0x0F,0x22, -0xD8,0xEF,0xAD,0x08,0x11,0x9A,0x29,0x99,0xE1,0xAA,0x44,0x45,0x9A,0x12,0x5E,0x3E, -0x9D,0x6D,0x52,0xFC,0xE7,0xA0,0x3D,0x68,0x2F,0xF0,0x4B,0x70,0x7C,0x13,0x38,0xAD, -0xBC,0x15,0x25,0xF1,0xD6,0xCE,0xAB,0xA2,0xC0,0x31,0xD6,0x2F,0x9F,0xE0,0xFF,0x14, -0x59,0xFC,0x84,0x93,0xD9,0x87,0x7C,0x4C,0x54,0x13,0xEB,0x9F,0xD1,0x2D,0x11,0xF8, -0x18,0x3A,0x3A,0xDE,0x25,0xD9,0xF7,0xD3,0x40,0xED,0xA4,0x06,0x12,0xC4,0x3B,0xE1, -0x91,0xC1,0x56,0x35,0xF0,0x14,0xDC,0x65,0x36,0x09,0x6E,0xAB,0xA4,0x07,0xC7,0x35, -0xD1,0xC2,0x03,0x33,0x36,0x5B,0x75,0x26,0x6D,0x42,0xF1,0x12,0x6B,0x43,0x6F,0x4B, -0x71,0x94,0xFA,0x34,0x1D,0xED,0x13,0x6E,0xCA,0x80,0x7F,0x98,0x2F,0x6C,0xB9,0x65, -0xD8,0xE9,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xD4,0x30,0x81,0xD1,0x30,0x1D,0x06, -0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x39,0x95,0x8B,0x62,0x8B,0x5C,0xC9,0xD4, -0x80,0xBA,0x58,0x0F,0x97,0x3F,0x15,0x08,0x43,0xCC,0x98,0xA7,0x30,0x0B,0x06,0x03, -0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13, -0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x81,0x91,0x06,0x03,0x55, -0x1D,0x23,0x04,0x81,0x89,0x30,0x81,0x86,0x80,0x14,0x39,0x95,0x8B,0x62,0x8B,0x5C, -0xC9,0xD4,0x80,0xBA,0x58,0x0F,0x97,0x3F,0x15,0x08,0x43,0xCC,0x98,0xA7,0xA1,0x6B, -0xA4,0x69,0x30,0x67,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53, -0x45,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54, -0x72,0x75,0x73,0x74,0x20,0x41,0x42,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B, -0x13,0x14,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x54,0x54,0x50,0x20,0x4E, -0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x23,0x30,0x21,0x06,0x03,0x55,0x04,0x03,0x13, -0x1A,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x51,0x75,0x61,0x6C,0x69,0x66, -0x69,0x65,0x64,0x20,0x43,0x41,0x20,0x52,0x6F,0x6F,0x74,0x82,0x01,0x01,0x30,0x0D, -0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01, -0x01,0x00,0x19,0xAB,0x75,0xEA,0xF8,0x8B,0x65,0x61,0x95,0x13,0xBA,0x69,0x04,0xEF, -0x86,0xCA,0x13,0xA0,0xC7,0xAA,0x4F,0x64,0x1B,0x3F,0x18,0xF6,0xA8,0x2D,0x2C,0x55, -0x8F,0x05,0xB7,0x30,0xEA,0x42,0x6A,0x1D,0xC0,0x25,0x51,0x2D,0xA7,0xBF,0x0C,0xB3, -0xED,0xEF,0x08,0x7F,0x6C,0x3C,0x46,0x1A,0xEA,0x18,0x43,0xDF,0x76,0xCC,0xF9,0x66, -0x86,0x9C,0x2C,0x68,0xF5,0xE9,0x17,0xF8,0x31,0xB3,0x18,0xC4,0xD6,0x48,0x7D,0x23, -0x4C,0x68,0xC1,0x7E,0xBB,0x01,0x14,0x6F,0xC5,0xD9,0x6E,0xDE,0xBB,0x04,0x42,0x6A, -0xF8,0xF6,0x5C,0x7D,0xE5,0xDA,0xFA,0x87,0xEB,0x0D,0x35,0x52,0x67,0xD0,0x9E,0x97, -0x76,0x05,0x93,0x3F,0x95,0xC7,0x01,0xE6,0x69,0x55,0x38,0x7F,0x10,0x61,0x99,0xC9, -0xE3,0x5F,0xA6,0xCA,0x3E,0x82,0x63,0x48,0xAA,0xE2,0x08,0x48,0x3E,0xAA,0xF2,0xB2, -0x85,0x62,0xA6,0xB4,0xA7,0xD9,0xBD,0x37,0x9C,0x68,0xB5,0x2D,0x56,0x7D,0xB0,0xB7, -0x3F,0xA0,0xB1,0x07,0xD6,0xE9,0x4F,0xDC,0xDE,0x45,0x71,0x30,0x32,0x7F,0x1B,0x2E, -0x09,0xF9,0xBF,0x52,0xA1,0xEE,0xC2,0x80,0x3E,0x06,0x5C,0x2E,0x55,0x40,0xC1,0x1B, -0xF5,0x70,0x45,0xB0,0xDC,0x5D,0xFA,0xF6,0x72,0x5A,0x77,0xD2,0x63,0xCD,0xCF,0x58, -0x89,0x00,0x42,0x63,0x3F,0x79,0x39,0xD0,0x44,0xB0,0x82,0x6E,0x41,0x19,0xE8,0xDD, -0xE0,0xC1,0x88,0x5A,0xD1,0x1E,0x71,0x93,0x1F,0x24,0x30,0x74,0xE5,0x1E,0xA8,0xDE, -0x3C,0x27,0x37,0x7F,0x83,0xAE,0x9E,0x77,0xCF,0xF0,0x30,0xB1,0xFF,0x4B,0x99,0xE8, -0xC6,0xA1, -}; - - -/* subject:/C=US/O=AffirmTrust/CN=AffirmTrust Commercial */ -/* issuer :/C=US/O=AffirmTrust/CN=AffirmTrust Commercial */ - - -const unsigned char AffirmTrust_Commercial_certificate[848]={ -0x30,0x82,0x03,0x4C,0x30,0x82,0x02,0x34,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x77, -0x77,0x06,0x27,0x26,0xA9,0xB1,0x7C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x44,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, -0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B, -0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73,0x74,0x31,0x1F,0x30,0x1D,0x06, -0x03,0x55,0x04,0x03,0x0C,0x16,0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73, -0x74,0x20,0x43,0x6F,0x6D,0x6D,0x65,0x72,0x63,0x69,0x61,0x6C,0x30,0x1E,0x17,0x0D, -0x31,0x30,0x30,0x31,0x32,0x39,0x31,0x34,0x30,0x36,0x30,0x36,0x5A,0x17,0x0D,0x33, -0x30,0x31,0x32,0x33,0x31,0x31,0x34,0x30,0x36,0x30,0x36,0x5A,0x30,0x44,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06, -0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73, -0x74,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x0C,0x16,0x41,0x66,0x66,0x69, -0x72,0x6D,0x54,0x72,0x75,0x73,0x74,0x20,0x43,0x6F,0x6D,0x6D,0x65,0x72,0x63,0x69, -0x61,0x6C,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82, -0x01,0x01,0x00,0xF6,0x1B,0x4F,0x67,0x07,0x2B,0xA1,0x15,0xF5,0x06,0x22,0xCB,0x1F, -0x01,0xB2,0xE3,0x73,0x45,0x06,0x44,0x49,0x2C,0xBB,0x49,0x25,0x14,0xD6,0xCE,0xC3, -0xB7,0xAB,0x2C,0x4F,0xC6,0x41,0x32,0x94,0x57,0xFA,0x12,0xA7,0x5B,0x0E,0xE2,0x8F, -0x1F,0x1E,0x86,0x19,0xA7,0xAA,0xB5,0x2D,0xB9,0x5F,0x0D,0x8A,0xC2,0xAF,0x85,0x35, -0x79,0x32,0x2D,0xBB,0x1C,0x62,0x37,0xF2,0xB1,0x5B,0x4A,0x3D,0xCA,0xCD,0x71,0x5F, -0xE9,0x42,0xBE,0x94,0xE8,0xC8,0xDE,0xF9,0x22,0x48,0x64,0xC6,0xE5,0xAB,0xC6,0x2B, -0x6D,0xAD,0x05,0xF0,0xFA,0xD5,0x0B,0xCF,0x9A,0xE5,0xF0,0x50,0xA4,0x8B,0x3B,0x47, -0xA5,0x23,0x5B,0x7A,0x7A,0xF8,0x33,0x3F,0xB8,0xEF,0x99,0x97,0xE3,0x20,0xC1,0xD6, -0x28,0x89,0xCF,0x94,0xFB,0xB9,0x45,0xED,0xE3,0x40,0x17,0x11,0xD4,0x74,0xF0,0x0B, -0x31,0xE2,0x2B,0x26,0x6A,0x9B,0x4C,0x57,0xAE,0xAC,0x20,0x3E,0xBA,0x45,0x7A,0x05, -0xF3,0xBD,0x9B,0x69,0x15,0xAE,0x7D,0x4E,0x20,0x63,0xC4,0x35,0x76,0x3A,0x07,0x02, -0xC9,0x37,0xFD,0xC7,0x47,0xEE,0xE8,0xF1,0x76,0x1D,0x73,0x15,0xF2,0x97,0xA4,0xB5, -0xC8,0x7A,0x79,0xD9,0x42,0xAA,0x2B,0x7F,0x5C,0xFE,0xCE,0x26,0x4F,0xA3,0x66,0x81, -0x35,0xAF,0x44,0xBA,0x54,0x1E,0x1C,0x30,0x32,0x65,0x9D,0xE6,0x3C,0x93,0x5E,0x50, -0x4E,0x7A,0xE3,0x3A,0xD4,0x6E,0xCC,0x1A,0xFB,0xF9,0xD2,0x37,0xAE,0x24,0x2A,0xAB, -0x57,0x03,0x22,0x28,0x0D,0x49,0x75,0x7F,0xB7,0x28,0xDA,0x75,0xBF,0x8E,0xE3,0xDC, -0x0E,0x79,0x31,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x1D,0x06,0x03, -0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0x93,0xC6,0x53,0x8B,0x5E,0xCA,0xAF,0x3F, -0x9F,0x1E,0x0F,0xE5,0x99,0x95,0xBC,0x24,0xF6,0x94,0x8F,0x30,0x0F,0x06,0x03,0x55, -0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03, -0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00, -0x58,0xAC,0xF4,0x04,0x0E,0xCD,0xC0,0x0D,0xFF,0x0A,0xFD,0xD4,0xBA,0x16,0x5F,0x29, -0xBD,0x7B,0x68,0x99,0x58,0x49,0xD2,0xB4,0x1D,0x37,0x4D,0x7F,0x27,0x7D,0x46,0x06, -0x5D,0x43,0xC6,0x86,0x2E,0x3E,0x73,0xB2,0x26,0x7D,0x4F,0x93,0xA9,0xB6,0xC4,0x2A, -0x9A,0xAB,0x21,0x97,0x14,0xB1,0xDE,0x8C,0xD3,0xAB,0x89,0x15,0xD8,0x6B,0x24,0xD4, -0xF1,0x16,0xAE,0xD8,0xA4,0x5C,0xD4,0x7F,0x51,0x8E,0xED,0x18,0x01,0xB1,0x93,0x63, -0xBD,0xBC,0xF8,0x61,0x80,0x9A,0x9E,0xB1,0xCE,0x42,0x70,0xE2,0xA9,0x7D,0x06,0x25, -0x7D,0x27,0xA1,0xFE,0x6F,0xEC,0xB3,0x1E,0x24,0xDA,0xE3,0x4B,0x55,0x1A,0x00,0x3B, -0x35,0xB4,0x3B,0xD9,0xD7,0x5D,0x30,0xFD,0x81,0x13,0x89,0xF2,0xC2,0x06,0x2B,0xED, -0x67,0xC4,0x8E,0xC9,0x43,0xB2,0x5C,0x6B,0x15,0x89,0x02,0xBC,0x62,0xFC,0x4E,0xF2, -0xB5,0x33,0xAA,0xB2,0x6F,0xD3,0x0A,0xA2,0x50,0xE3,0xF6,0x3B,0xE8,0x2E,0x44,0xC2, -0xDB,0x66,0x38,0xA9,0x33,0x56,0x48,0xF1,0x6D,0x1B,0x33,0x8D,0x0D,0x8C,0x3F,0x60, -0x37,0x9D,0xD3,0xCA,0x6D,0x7E,0x34,0x7E,0x0D,0x9F,0x72,0x76,0x8B,0x1B,0x9F,0x72, -0xFD,0x52,0x35,0x41,0x45,0x02,0x96,0x2F,0x1C,0xB2,0x9A,0x73,0x49,0x21,0xB1,0x49, -0x47,0x45,0x47,0xB4,0xEF,0x6A,0x34,0x11,0xC9,0x4D,0x9A,0xCC,0x59,0xB7,0xD6,0x02, -0x9E,0x5A,0x4E,0x65,0xB5,0x94,0xAE,0x1B,0xDF,0x29,0xB0,0x16,0xF1,0xBF,0x00,0x9E, -0x07,0x3A,0x17,0x64,0xB5,0x04,0xB5,0x23,0x21,0x99,0x0A,0x95,0x3B,0x97,0x7C,0xEF, -}; - - -/* subject:/C=US/O=AffirmTrust/CN=AffirmTrust Networking */ -/* issuer :/C=US/O=AffirmTrust/CN=AffirmTrust Networking */ - - -const unsigned char AffirmTrust_Networking_certificate[848]={ -0x30,0x82,0x03,0x4C,0x30,0x82,0x02,0x34,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x7C, -0x4F,0x04,0x39,0x1C,0xD4,0x99,0x2D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x44,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, -0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B, -0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73,0x74,0x31,0x1F,0x30,0x1D,0x06, -0x03,0x55,0x04,0x03,0x0C,0x16,0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73, -0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x69,0x6E,0x67,0x30,0x1E,0x17,0x0D, -0x31,0x30,0x30,0x31,0x32,0x39,0x31,0x34,0x30,0x38,0x32,0x34,0x5A,0x17,0x0D,0x33, -0x30,0x31,0x32,0x33,0x31,0x31,0x34,0x30,0x38,0x32,0x34,0x5A,0x30,0x44,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06, -0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73, -0x74,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x0C,0x16,0x41,0x66,0x66,0x69, -0x72,0x6D,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x69, -0x6E,0x67,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82, -0x01,0x01,0x00,0xB4,0x84,0xCC,0x33,0x17,0x2E,0x6B,0x94,0x6C,0x6B,0x61,0x52,0xA0, -0xEB,0xA3,0xCF,0x79,0x94,0x4C,0xE5,0x94,0x80,0x99,0xCB,0x55,0x64,0x44,0x65,0x8F, -0x67,0x64,0xE2,0x06,0xE3,0x5C,0x37,0x49,0xF6,0x2F,0x9B,0x84,0x84,0x1E,0x2D,0xF2, -0x60,0x9D,0x30,0x4E,0xCC,0x84,0x85,0xE2,0x2C,0xCF,0x1E,0x9E,0xFE,0x36,0xAB,0x33, -0x77,0x35,0x44,0xD8,0x35,0x96,0x1A,0x3D,0x36,0xE8,0x7A,0x0E,0xD8,0xD5,0x47,0xA1, -0x6A,0x69,0x8B,0xD9,0xFC,0xBB,0x3A,0xAE,0x79,0x5A,0xD5,0xF4,0xD6,0x71,0xBB,0x9A, -0x90,0x23,0x6B,0x9A,0xB7,0x88,0x74,0x87,0x0C,0x1E,0x5F,0xB9,0x9E,0x2D,0xFA,0xAB, -0x53,0x2B,0xDC,0xBB,0x76,0x3E,0x93,0x4C,0x08,0x08,0x8C,0x1E,0xA2,0x23,0x1C,0xD4, -0x6A,0xAD,0x22,0xBA,0x99,0x01,0x2E,0x6D,0x65,0xCB,0xBE,0x24,0x66,0x55,0x24,0x4B, -0x40,0x44,0xB1,0x1B,0xD7,0xE1,0xC2,0x85,0xC0,0xDE,0x10,0x3F,0x3D,0xED,0xB8,0xFC, -0xF1,0xF1,0x23,0x53,0xDC,0xBF,0x65,0x97,0x6F,0xD9,0xF9,0x40,0x71,0x8D,0x7D,0xBD, -0x95,0xD4,0xCE,0xBE,0xA0,0x5E,0x27,0x23,0xDE,0xFD,0xA6,0xD0,0x26,0x0E,0x00,0x29, -0xEB,0x3C,0x46,0xF0,0x3D,0x60,0xBF,0x3F,0x50,0xD2,0xDC,0x26,0x41,0x51,0x9E,0x14, -0x37,0x42,0x04,0xA3,0x70,0x57,0xA8,0x1B,0x87,0xED,0x2D,0xFA,0x7B,0xEE,0x8C,0x0A, -0xE3,0xA9,0x66,0x89,0x19,0xCB,0x41,0xF9,0xDD,0x44,0x36,0x61,0xCF,0xE2,0x77,0x46, -0xC8,0x7D,0xF6,0xF4,0x92,0x81,0x36,0xFD,0xDB,0x34,0xF1,0x72,0x7E,0xF3,0x0C,0x16, -0xBD,0xB4,0x15,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x1D,0x06,0x03, -0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x07,0x1F,0xD2,0xE7,0x9C,0xDA,0xC2,0x6E,0xA2, -0x40,0xB4,0xB0,0x7A,0x50,0x10,0x50,0x74,0xC4,0xC8,0xBD,0x30,0x0F,0x06,0x03,0x55, -0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03, -0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00, -0x89,0x57,0xB2,0x16,0x7A,0xA8,0xC2,0xFD,0xD6,0xD9,0x9B,0x9B,0x34,0xC2,0x9C,0xB4, -0x32,0x14,0x4D,0xA7,0xA4,0xDF,0xEC,0xBE,0xA7,0xBE,0xF8,0x43,0xDB,0x91,0x37,0xCE, -0xB4,0x32,0x2E,0x50,0x55,0x1A,0x35,0x4E,0x76,0x43,0x71,0x20,0xEF,0x93,0x77,0x4E, -0x15,0x70,0x2E,0x87,0xC3,0xC1,0x1D,0x6D,0xDC,0xCB,0xB5,0x27,0xD4,0x2C,0x56,0xD1, -0x52,0x53,0x3A,0x44,0xD2,0x73,0xC8,0xC4,0x1B,0x05,0x65,0x5A,0x62,0x92,0x9C,0xEE, -0x41,0x8D,0x31,0xDB,0xE7,0x34,0xEA,0x59,0x21,0xD5,0x01,0x7A,0xD7,0x64,0xB8,0x64, -0x39,0xCD,0xC9,0xED,0xAF,0xED,0x4B,0x03,0x48,0xA7,0xA0,0x99,0x01,0x80,0xDC,0x65, -0xA3,0x36,0xAE,0x65,0x59,0x48,0x4F,0x82,0x4B,0xC8,0x65,0xF1,0x57,0x1D,0xE5,0x59, -0x2E,0x0A,0x3F,0x6C,0xD8,0xD1,0xF5,0xE5,0x09,0xB4,0x6C,0x54,0x00,0x0A,0xE0,0x15, -0x4D,0x87,0x75,0x6D,0xB7,0x58,0x96,0x5A,0xDD,0x6D,0xD2,0x00,0xA0,0xF4,0x9B,0x48, -0xBE,0xC3,0x37,0xA4,0xBA,0x36,0xE0,0x7C,0x87,0x85,0x97,0x1A,0x15,0xA2,0xDE,0x2E, -0xA2,0x5B,0xBD,0xAF,0x18,0xF9,0x90,0x50,0xCD,0x70,0x59,0xF8,0x27,0x67,0x47,0xCB, -0xC7,0xA0,0x07,0x3A,0x7D,0xD1,0x2C,0x5D,0x6C,0x19,0x3A,0x66,0xB5,0x7D,0xFD,0x91, -0x6F,0x82,0xB1,0xBE,0x08,0x93,0xDB,0x14,0x47,0xF1,0xA2,0x37,0xC7,0x45,0x9E,0x3C, -0xC7,0x77,0xAF,0x64,0xA8,0x93,0xDF,0xF6,0x69,0x83,0x82,0x60,0xF2,0x49,0x42,0x34, -0xED,0x5A,0x00,0x54,0x85,0x1C,0x16,0x36,0x92,0x0C,0x5C,0xFA,0xA6,0xAD,0xBF,0xDB, -}; - - -/* subject:/C=US/O=AffirmTrust/CN=AffirmTrust Premium */ -/* issuer :/C=US/O=AffirmTrust/CN=AffirmTrust Premium */ - - -const unsigned char AffirmTrust_Premium_certificate[1354]={ -0x30,0x82,0x05,0x46,0x30,0x82,0x03,0x2E,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x6D, -0x8C,0x14,0x46,0xB1,0xA6,0x0A,0xEE,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x0C,0x05,0x00,0x30,0x41,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, -0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B, -0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73,0x74,0x31,0x1C,0x30,0x1A,0x06, -0x03,0x55,0x04,0x03,0x0C,0x13,0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73, -0x74,0x20,0x50,0x72,0x65,0x6D,0x69,0x75,0x6D,0x30,0x1E,0x17,0x0D,0x31,0x30,0x30, -0x31,0x32,0x39,0x31,0x34,0x31,0x30,0x33,0x36,0x5A,0x17,0x0D,0x34,0x30,0x31,0x32, -0x33,0x31,0x31,0x34,0x31,0x30,0x33,0x36,0x5A,0x30,0x41,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04, -0x0A,0x0C,0x0B,0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73,0x74,0x31,0x1C, -0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x41,0x66,0x66,0x69,0x72,0x6D,0x54, -0x72,0x75,0x73,0x74,0x20,0x50,0x72,0x65,0x6D,0x69,0x75,0x6D,0x30,0x82,0x02,0x22, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03, -0x82,0x02,0x0F,0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02,0x01,0x00,0xC4,0x12,0xDF, -0xA9,0x5F,0xFE,0x41,0xDD,0xDD,0xF5,0x9F,0x8A,0xE3,0xF6,0xAC,0xE1,0x3C,0x78,0x9A, -0xBC,0xD8,0xF0,0x7F,0x7A,0xA0,0x33,0x2A,0xDC,0x8D,0x20,0x5B,0xAE,0x2D,0x6F,0xE7, -0x93,0xD9,0x36,0x70,0x6A,0x68,0xCF,0x8E,0x51,0xA3,0x85,0x5B,0x67,0x04,0xA0,0x10, -0x24,0x6F,0x5D,0x28,0x82,0xC1,0x97,0x57,0xD8,0x48,0x29,0x13,0xB6,0xE1,0xBE,0x91, -0x4D,0xDF,0x85,0x0C,0x53,0x18,0x9A,0x1E,0x24,0xA2,0x4F,0x8F,0xF0,0xA2,0x85,0x0B, -0xCB,0xF4,0x29,0x7F,0xD2,0xA4,0x58,0xEE,0x26,0x4D,0xC9,0xAA,0xA8,0x7B,0x9A,0xD9, -0xFA,0x38,0xDE,0x44,0x57,0x15,0xE5,0xF8,0x8C,0xC8,0xD9,0x48,0xE2,0x0D,0x16,0x27, -0x1D,0x1E,0xC8,0x83,0x85,0x25,0xB7,0xBA,0xAA,0x55,0x41,0xCC,0x03,0x22,0x4B,0x2D, -0x91,0x8D,0x8B,0xE6,0x89,0xAF,0x66,0xC7,0xE9,0xFF,0x2B,0xE9,0x3C,0xAC,0xDA,0xD2, -0xB3,0xC3,0xE1,0x68,0x9C,0x89,0xF8,0x7A,0x00,0x56,0xDE,0xF4,0x55,0x95,0x6C,0xFB, -0xBA,0x64,0xDD,0x62,0x8B,0xDF,0x0B,0x77,0x32,0xEB,0x62,0xCC,0x26,0x9A,0x9B,0xBB, -0xAA,0x62,0x83,0x4C,0xB4,0x06,0x7A,0x30,0xC8,0x29,0xBF,0xED,0x06,0x4D,0x97,0xB9, -0x1C,0xC4,0x31,0x2B,0xD5,0x5F,0xBC,0x53,0x12,0x17,0x9C,0x99,0x57,0x29,0x66,0x77, -0x61,0x21,0x31,0x07,0x2E,0x25,0x49,0x9D,0x18,0xF2,0xEE,0xF3,0x2B,0x71,0x8C,0xB5, -0xBA,0x39,0x07,0x49,0x77,0xFC,0xEF,0x2E,0x92,0x90,0x05,0x8D,0x2D,0x2F,0x77,0x7B, -0xEF,0x43,0xBF,0x35,0xBB,0x9A,0xD8,0xF9,0x73,0xA7,0x2C,0xF2,0xD0,0x57,0xEE,0x28, -0x4E,0x26,0x5F,0x8F,0x90,0x68,0x09,0x2F,0xB8,0xF8,0xDC,0x06,0xE9,0x2E,0x9A,0x3E, -0x51,0xA7,0xD1,0x22,0xC4,0x0A,0xA7,0x38,0x48,0x6C,0xB3,0xF9,0xFF,0x7D,0xAB,0x86, -0x57,0xE3,0xBA,0xD6,0x85,0x78,0x77,0xBA,0x43,0xEA,0x48,0x7F,0xF6,0xD8,0xBE,0x23, -0x6D,0x1E,0xBF,0xD1,0x36,0x6C,0x58,0x5C,0xF1,0xEE,0xA4,0x19,0x54,0x1A,0xF5,0x03, -0xD2,0x76,0xE6,0xE1,0x8C,0xBD,0x3C,0xB3,0xD3,0x48,0x4B,0xE2,0xC8,0xF8,0x7F,0x92, -0xA8,0x76,0x46,0x9C,0x42,0x65,0x3E,0xA4,0x1E,0xC1,0x07,0x03,0x5A,0x46,0x2D,0xB8, -0x97,0xF3,0xB7,0xD5,0xB2,0x55,0x21,0xEF,0xBA,0xDC,0x4C,0x00,0x97,0xFB,0x14,0x95, -0x27,0x33,0xBF,0xE8,0x43,0x47,0x46,0xD2,0x08,0x99,0x16,0x60,0x3B,0x9A,0x7E,0xD2, -0xE6,0xED,0x38,0xEA,0xEC,0x01,0x1E,0x3C,0x48,0x56,0x49,0x09,0xC7,0x4C,0x37,0x00, -0x9E,0x88,0x0E,0xC0,0x73,0xE1,0x6F,0x66,0xE9,0x72,0x47,0x30,0x3E,0x10,0xE5,0x0B, -0x03,0xC9,0x9A,0x42,0x00,0x6C,0xC5,0x94,0x7E,0x61,0xC4,0x8A,0xDF,0x7F,0x82,0x1A, -0x0B,0x59,0xC4,0x59,0x32,0x77,0xB3,0xBC,0x60,0x69,0x56,0x39,0xFD,0xB4,0x06,0x7B, -0x2C,0xD6,0x64,0x36,0xD9,0xBD,0x48,0xED,0x84,0x1F,0x7E,0xA5,0x22,0x8F,0x2A,0xB8, -0x42,0xF4,0x82,0xB7,0xD4,0x53,0x90,0x78,0x4E,0x2D,0x1A,0xFD,0x81,0x6F,0x44,0xD7, -0x3B,0x01,0x74,0x96,0x42,0xE0,0x00,0xE2,0x2E,0x6B,0xEA,0xC5,0xEE,0x72,0xAC,0xBB, -0xBF,0xFE,0xEA,0xAA,0xA8,0xF8,0xDC,0xF6,0xB2,0x79,0x8A,0xB6,0x67,0x02,0x03,0x01, -0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, -0x14,0x9D,0xC0,0x67,0xA6,0x0C,0x22,0xD9,0x26,0xF5,0x45,0xAB,0xA6,0x65,0x52,0x11, -0x27,0xD8,0x45,0xAC,0x63,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, -0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF, -0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x0C,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0xB3,0x57,0x4D,0x10,0x62,0x4E, -0x3A,0xE4,0xAC,0xEA,0xB8,0x1C,0xAF,0x32,0x23,0xC8,0xB3,0x49,0x5A,0x51,0x9C,0x76, -0x28,0x8D,0x79,0xAA,0x57,0x46,0x17,0xD5,0xF5,0x52,0xF6,0xB7,0x44,0xE8,0x08,0x44, -0xBF,0x18,0x84,0xD2,0x0B,0x80,0xCD,0xC5,0x12,0xFD,0x00,0x55,0x05,0x61,0x87,0x41, -0xDC,0xB5,0x24,0x9E,0x3C,0xC4,0xD8,0xC8,0xFB,0x70,0x9E,0x2F,0x78,0x96,0x83,0x20, -0x36,0xDE,0x7C,0x0F,0x69,0x13,0x88,0xA5,0x75,0x36,0x98,0x08,0xA6,0xC6,0xDF,0xAC, -0xCE,0xE3,0x58,0xD6,0xB7,0x3E,0xDE,0xBA,0xF3,0xEB,0x34,0x40,0xD8,0xA2,0x81,0xF5, -0x78,0x3F,0x2F,0xD5,0xA5,0xFC,0xD9,0xA2,0xD4,0x5E,0x04,0x0E,0x17,0xAD,0xFE,0x41, -0xF0,0xE5,0xB2,0x72,0xFA,0x44,0x82,0x33,0x42,0xE8,0x2D,0x58,0xF7,0x56,0x8C,0x62, -0x3F,0xBA,0x42,0xB0,0x9C,0x0C,0x5C,0x7E,0x2E,0x65,0x26,0x5C,0x53,0x4F,0x00,0xB2, -0x78,0x7E,0xA1,0x0D,0x99,0x2D,0x8D,0xB8,0x1D,0x8E,0xA2,0xC4,0xB0,0xFD,0x60,0xD0, -0x30,0xA4,0x8E,0xC8,0x04,0x62,0xA9,0xC4,0xED,0x35,0xDE,0x7A,0x97,0xED,0x0E,0x38, -0x5E,0x92,0x2F,0x93,0x70,0xA5,0xA9,0x9C,0x6F,0xA7,0x7D,0x13,0x1D,0x7E,0xC6,0x08, -0x48,0xB1,0x5E,0x67,0xEB,0x51,0x08,0x25,0xE9,0xE6,0x25,0x6B,0x52,0x29,0x91,0x9C, -0xD2,0x39,0x73,0x08,0x57,0xDE,0x99,0x06,0xB4,0x5B,0x9D,0x10,0x06,0xE1,0xC2,0x00, -0xA8,0xB8,0x1C,0x4A,0x02,0x0A,0x14,0xD0,0xC1,0x41,0xCA,0xFB,0x8C,0x35,0x21,0x7D, -0x82,0x38,0xF2,0xA9,0x54,0x91,0x19,0x35,0x93,0x94,0x6D,0x6A,0x3A,0xC5,0xB2,0xD0, -0xBB,0x89,0x86,0x93,0xE8,0x9B,0xC9,0x0F,0x3A,0xA7,0x7A,0xB8,0xA1,0xF0,0x78,0x46, -0xFA,0xFC,0x37,0x2F,0xE5,0x8A,0x84,0xF3,0xDF,0xFE,0x04,0xD9,0xA1,0x68,0xA0,0x2F, -0x24,0xE2,0x09,0x95,0x06,0xD5,0x95,0xCA,0xE1,0x24,0x96,0xEB,0x7C,0xF6,0x93,0x05, -0xBB,0xED,0x73,0xE9,0x2D,0xD1,0x75,0x39,0xD7,0xE7,0x24,0xDB,0xD8,0x4E,0x5F,0x43, -0x8F,0x9E,0xD0,0x14,0x39,0xBF,0x55,0x70,0x48,0x99,0x57,0x31,0xB4,0x9C,0xEE,0x4A, -0x98,0x03,0x96,0x30,0x1F,0x60,0x06,0xEE,0x1B,0x23,0xFE,0x81,0x60,0x23,0x1A,0x47, -0x62,0x85,0xA5,0xCC,0x19,0x34,0x80,0x6F,0xB3,0xAC,0x1A,0xE3,0x9F,0xF0,0x7B,0x48, -0xAD,0xD5,0x01,0xD9,0x67,0xB6,0xA9,0x72,0x93,0xEA,0x2D,0x66,0xB5,0xB2,0xB8,0xE4, -0x3D,0x3C,0xB2,0xEF,0x4C,0x8C,0xEA,0xEB,0x07,0xBF,0xAB,0x35,0x9A,0x55,0x86,0xBC, -0x18,0xA6,0xB5,0xA8,0x5E,0xB4,0x83,0x6C,0x6B,0x69,0x40,0xD3,0x9F,0xDC,0xF1,0xC3, -0x69,0x6B,0xB9,0xE1,0x6D,0x09,0xF4,0xF1,0xAA,0x50,0x76,0x0A,0x7A,0x7D,0x7A,0x17, -0xA1,0x55,0x96,0x42,0x99,0x31,0x09,0xDD,0x60,0x11,0x8D,0x05,0x30,0x7E,0xE6,0x8E, -0x46,0xD1,0x9D,0x14,0xDA,0xC7,0x17,0xE4,0x05,0x96,0x8C,0xC4,0x24,0xB5,0x1B,0xCF, -0x14,0x07,0xB2,0x40,0xF8,0xA3,0x9E,0x41,0x86,0xBC,0x04,0xD0,0x6B,0x96,0xC8,0x2A, -0x80,0x34,0xFD,0xBF,0xEF,0x06,0xA3,0xDD,0x58,0xC5,0x85,0x3D,0x3E,0x8F,0xFE,0x9E, -0x29,0xE0,0xB6,0xB8,0x09,0x68,0x19,0x1C,0x18,0x43, -}; - - -/* subject:/C=US/O=AffirmTrust/CN=AffirmTrust Premium ECC */ -/* issuer :/C=US/O=AffirmTrust/CN=AffirmTrust Premium ECC */ - - -const unsigned char AffirmTrust_Premium_ECC_certificate[514]={ -0x30,0x82,0x01,0xFE,0x30,0x82,0x01,0x85,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x74, -0x97,0x25,0x8A,0xC7,0x3F,0x7A,0x54,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, -0x04,0x03,0x03,0x30,0x45,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x66,0x66, -0x69,0x72,0x6D,0x54,0x72,0x75,0x73,0x74,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04, -0x03,0x0C,0x17,0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73,0x74,0x20,0x50, -0x72,0x65,0x6D,0x69,0x75,0x6D,0x20,0x45,0x43,0x43,0x30,0x1E,0x17,0x0D,0x31,0x30, -0x30,0x31,0x32,0x39,0x31,0x34,0x32,0x30,0x32,0x34,0x5A,0x17,0x0D,0x34,0x30,0x31, -0x32,0x33,0x31,0x31,0x34,0x32,0x30,0x32,0x34,0x5A,0x30,0x45,0x31,0x0B,0x30,0x09, -0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55, -0x04,0x0A,0x0C,0x0B,0x41,0x66,0x66,0x69,0x72,0x6D,0x54,0x72,0x75,0x73,0x74,0x31, -0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x0C,0x17,0x41,0x66,0x66,0x69,0x72,0x6D, -0x54,0x72,0x75,0x73,0x74,0x20,0x50,0x72,0x65,0x6D,0x69,0x75,0x6D,0x20,0x45,0x43, -0x43,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05, -0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x0D,0x30,0x5E,0x1B,0x15,0x9D,0x03, -0xD0,0xA1,0x79,0x35,0xB7,0x3A,0x3C,0x92,0x7A,0xCA,0x15,0x1C,0xCD,0x62,0xF3,0x9C, -0x26,0x5C,0x07,0x3D,0xE5,0x54,0xFA,0xA3,0xD6,0xCC,0x12,0xEA,0xF4,0x14,0x5F,0xE8, -0x8E,0x19,0xAB,0x2F,0x2E,0x48,0xE6,0xAC,0x18,0x43,0x78,0xAC,0xD0,0x37,0xC3,0xBD, -0xB2,0xCD,0x2C,0xE6,0x47,0xE2,0x1A,0xE6,0x63,0xB8,0x3D,0x2E,0x2F,0x78,0xC4,0x4F, -0xDB,0xF4,0x0F,0xA4,0x68,0x4C,0x55,0x72,0x6B,0x95,0x1D,0x4E,0x18,0x42,0x95,0x78, -0xCC,0x37,0x3C,0x91,0xE2,0x9B,0x65,0x2B,0x29,0xA3,0x42,0x30,0x40,0x30,0x1D,0x06, -0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9A,0xAF,0x29,0x7A,0xC0,0x11,0x35,0x35, -0x26,0x51,0x30,0x00,0xC3,0x6A,0xFE,0x40,0xD5,0xAE,0xD6,0x3C,0x30,0x0F,0x06,0x03, -0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06, -0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0A,0x06, -0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x03,0x67,0x00,0x30,0x64,0x02,0x30, -0x17,0x09,0xF3,0x87,0x88,0x50,0x5A,0xAF,0xC8,0xC0,0x42,0xBF,0x47,0x5F,0xF5,0x6C, -0x6A,0x86,0xE0,0xC4,0x27,0x74,0xE4,0x38,0x53,0xD7,0x05,0x7F,0x1B,0x34,0xE3,0xC6, -0x2F,0xB3,0xCA,0x09,0x3C,0x37,0x9D,0xD7,0xE7,0xB8,0x46,0xF1,0xFD,0xA1,0xE2,0x71, -0x02,0x30,0x42,0x59,0x87,0x43,0xD4,0x51,0xDF,0xBA,0xD3,0x09,0x32,0x5A,0xCE,0x88, -0x7E,0x57,0x3D,0x9C,0x5F,0x42,0x6B,0xF5,0x07,0x2D,0xB5,0xF0,0x82,0x93,0xF9,0x59, -0x6F,0xAE,0x64,0xFA,0x58,0xE5,0x8B,0x1E,0xE3,0x63,0xBE,0xB5,0x81,0xCD,0x6F,0x02, -0x8C,0x79, -}; - - -/* subject:/C=US/O=America Online Inc./CN=America Online Root Certification Authority 1 */ -/* issuer :/C=US/O=America Online Inc./CN=America Online Root Certification Authority 1 */ - - -const unsigned char America_Online_Root_Certification_Authority_1_certificate[936]={ -0x30,0x82,0x03,0xA4,0x30,0x82,0x02,0x8C,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x63,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1C, -0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x41,0x6D,0x65,0x72,0x69,0x63,0x61, -0x20,0x4F,0x6E,0x6C,0x69,0x6E,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x36,0x30,0x34, -0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x41,0x6D,0x65,0x72,0x69,0x63,0x61,0x20,0x4F, -0x6E,0x6C,0x69,0x6E,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x20,0x31,0x30,0x1E,0x17,0x0D,0x30,0x32,0x30,0x35,0x32,0x38,0x30,0x36, -0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x37,0x31,0x31,0x31,0x39,0x32,0x30,0x34, -0x33,0x30,0x30,0x5A,0x30,0x63,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x55,0x53,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x41,0x6D, -0x65,0x72,0x69,0x63,0x61,0x20,0x4F,0x6E,0x6C,0x69,0x6E,0x65,0x20,0x49,0x6E,0x63, -0x2E,0x31,0x36,0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x41,0x6D,0x65,0x72, -0x69,0x63,0x61,0x20,0x4F,0x6E,0x6C,0x69,0x6E,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20, -0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75, -0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x31,0x30,0x82,0x01,0x22,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F, -0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xA8,0x2F,0xE8,0xA4,0x69,0x06, -0x03,0x47,0xC3,0xE9,0x2A,0x98,0xFF,0x19,0xA2,0x70,0x9A,0xC6,0x50,0xB2,0x7E,0xA5, -0xDF,0x68,0x4D,0x1B,0x7C,0x0F,0xB6,0x97,0x68,0x7D,0x2D,0xA6,0x8B,0x97,0xE9,0x64, -0x86,0xC9,0xA3,0xEF,0xA0,0x86,0xBF,0x60,0x65,0x9C,0x4B,0x54,0x88,0xC2,0x48,0xC5, -0x4A,0x39,0xBF,0x14,0xE3,0x59,0x55,0xE5,0x19,0xB4,0x74,0xC8,0xB4,0x05,0x39,0x5C, -0x16,0xA5,0xE2,0x95,0x05,0xE0,0x12,0xAE,0x59,0x8B,0xA2,0x33,0x68,0x58,0x1C,0xA6, -0xD4,0x15,0xB7,0xD8,0x9F,0xD7,0xDC,0x71,0xAB,0x7E,0x9A,0xBF,0x9B,0x8E,0x33,0x0F, -0x22,0xFD,0x1F,0x2E,0xE7,0x07,0x36,0xEF,0x62,0x39,0xC5,0xDD,0xCB,0xBA,0x25,0x14, -0x23,0xDE,0x0C,0xC6,0x3D,0x3C,0xCE,0x82,0x08,0xE6,0x66,0x3E,0xDA,0x51,0x3B,0x16, -0x3A,0xA3,0x05,0x7F,0xA0,0xDC,0x87,0xD5,0x9C,0xFC,0x72,0xA9,0xA0,0x7D,0x78,0xE4, -0xB7,0x31,0x55,0x1E,0x65,0xBB,0xD4,0x61,0xB0,0x21,0x60,0xED,0x10,0x32,0x72,0xC5, -0x92,0x25,0x1E,0xF8,0x90,0x4A,0x18,0x78,0x47,0xDF,0x7E,0x30,0x37,0x3E,0x50,0x1B, -0xDB,0x1C,0xD3,0x6B,0x9A,0x86,0x53,0x07,0xB0,0xEF,0xAC,0x06,0x78,0xF8,0x84,0x99, -0xFE,0x21,0x8D,0x4C,0x80,0xB6,0x0C,0x82,0xF6,0x66,0x70,0x79,0x1A,0xD3,0x4F,0xA3, -0xCF,0xF1,0xCF,0x46,0xB0,0x4B,0x0F,0x3E,0xDD,0x88,0x62,0xB8,0x8C,0xA9,0x09,0x28, -0x3B,0x7A,0xC7,0x97,0xE1,0x1E,0xE5,0xF4,0x9F,0xC0,0xC0,0xAE,0x24,0xA0,0xC8,0xA1, -0xD9,0x0F,0xD6,0x7B,0x26,0x82,0x69,0x32,0x3D,0xA7,0x02,0x03,0x01,0x00,0x01,0xA3, -0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, -0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x00, -0xAD,0xD9,0xA3,0xF6,0x79,0xF6,0x6E,0x74,0xA9,0x7F,0x33,0x3D,0x81,0x17,0xD7,0x4C, -0xCF,0x33,0xDE,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, -0x00,0xAD,0xD9,0xA3,0xF6,0x79,0xF6,0x6E,0x74,0xA9,0x7F,0x33,0x3D,0x81,0x17,0xD7, -0x4C,0xCF,0x33,0xDE,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, -0x03,0x02,0x01,0x86,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x7C,0x8A,0xD1,0x1F,0x18,0x37,0x82,0xE0, -0xB8,0xB0,0xA3,0xED,0x56,0x95,0xC8,0x62,0x61,0x9C,0x05,0xA2,0xCD,0xC2,0x62,0x26, -0x61,0xCD,0x10,0x16,0xD7,0xCC,0xB4,0x65,0x34,0xD0,0x11,0x8A,0xAD,0xA8,0xA9,0x05, -0x66,0xEF,0x74,0xF3,0x6D,0x5F,0x9D,0x99,0xAF,0xF6,0x8B,0xFB,0xEB,0x52,0xB2,0x05, -0x98,0xA2,0x6F,0x2A,0xC5,0x54,0xBD,0x25,0xBD,0x5F,0xAE,0xC8,0x86,0xEA,0x46,0x2C, -0xC1,0xB3,0xBD,0xC1,0xE9,0x49,0x70,0x18,0x16,0x97,0x08,0x13,0x8C,0x20,0xE0,0x1B, -0x2E,0x3A,0x47,0xCB,0x1E,0xE4,0x00,0x30,0x95,0x5B,0xF4,0x45,0xA3,0xC0,0x1A,0xB0, -0x01,0x4E,0xAB,0xBD,0xC0,0x23,0x6E,0x63,0x3F,0x80,0x4A,0xC5,0x07,0xED,0xDC,0xE2, -0x6F,0xC7,0xC1,0x62,0xF1,0xE3,0x72,0xD6,0x04,0xC8,0x74,0x67,0x0B,0xFA,0x88,0xAB, -0xA1,0x01,0xC8,0x6F,0xF0,0x14,0xAF,0xD2,0x99,0xCD,0x51,0x93,0x7E,0xED,0x2E,0x38, -0xC7,0xBD,0xCE,0x46,0x50,0x3D,0x72,0xE3,0x79,0x25,0x9D,0x9B,0x88,0x2B,0x10,0x20, -0xDD,0xA5,0xB8,0x32,0x9F,0x8D,0xE0,0x29,0xDF,0x21,0x74,0x86,0x82,0xDB,0x2F,0x82, -0x30,0xC6,0xC7,0x35,0x86,0xB3,0xF9,0x96,0x5F,0x46,0xDB,0x0C,0x45,0xFD,0xF3,0x50, -0xC3,0x6F,0xC6,0xC3,0x48,0xAD,0x46,0xA6,0xE1,0x27,0x47,0x0A,0x1D,0x0E,0x9B,0xB6, -0xC2,0x77,0x7F,0x63,0xF2,0xE0,0x7D,0x1A,0xBE,0xFC,0xE0,0xDF,0xD7,0xC7,0xA7,0x6C, -0xB0,0xF9,0xAE,0xBA,0x3C,0xFD,0x74,0xB4,0x11,0xE8,0x58,0x0D,0x80,0xBC,0xD3,0xA8, -0x80,0x3A,0x99,0xED,0x75,0xCC,0x46,0x7B, -}; - - -/* subject:/C=US/O=America Online Inc./CN=America Online Root Certification Authority 2 */ -/* issuer :/C=US/O=America Online Inc./CN=America Online Root Certification Authority 2 */ - - -const unsigned char America_Online_Root_Certification_Authority_2_certificate[1448]={ -0x30,0x82,0x05,0xA4,0x30,0x82,0x03,0x8C,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x63,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1C, -0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x41,0x6D,0x65,0x72,0x69,0x63,0x61, -0x20,0x4F,0x6E,0x6C,0x69,0x6E,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x36,0x30,0x34, -0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x41,0x6D,0x65,0x72,0x69,0x63,0x61,0x20,0x4F, -0x6E,0x6C,0x69,0x6E,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x20,0x32,0x30,0x1E,0x17,0x0D,0x30,0x32,0x30,0x35,0x32,0x38,0x30,0x36, -0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x37,0x30,0x39,0x32,0x39,0x31,0x34,0x30, -0x38,0x30,0x30,0x5A,0x30,0x63,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x55,0x53,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x41,0x6D, -0x65,0x72,0x69,0x63,0x61,0x20,0x4F,0x6E,0x6C,0x69,0x6E,0x65,0x20,0x49,0x6E,0x63, -0x2E,0x31,0x36,0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x41,0x6D,0x65,0x72, -0x69,0x63,0x61,0x20,0x4F,0x6E,0x6C,0x69,0x6E,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20, -0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75, -0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x32,0x30,0x82,0x02,0x22,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x02,0x0F, -0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02,0x01,0x00,0xCC,0x41,0x45,0x1D,0xE9,0x3D, -0x4D,0x10,0xF6,0x8C,0xB1,0x41,0xC9,0xE0,0x5E,0xCB,0x0D,0xB7,0xBF,0x47,0x73,0xD3, -0xF0,0x55,0x4D,0xDD,0xC6,0x0C,0xFA,0xB1,0x66,0x05,0x6A,0xCD,0x78,0xB4,0xDC,0x02, -0xDB,0x4E,0x81,0xF3,0xD7,0xA7,0x7C,0x71,0xBC,0x75,0x63,0xA0,0x5D,0xE3,0x07,0x0C, -0x48,0xEC,0x25,0xC4,0x03,0x20,0xF4,0xFF,0x0E,0x3B,0x12,0xFF,0x9B,0x8D,0xE1,0xC6, -0xD5,0x1B,0xB4,0x6D,0x22,0xE3,0xB1,0xDB,0x7F,0x21,0x64,0xAF,0x86,0xBC,0x57,0x22, -0x2A,0xD6,0x47,0x81,0x57,0x44,0x82,0x56,0x53,0xBD,0x86,0x14,0x01,0x0B,0xFC,0x7F, -0x74,0xA4,0x5A,0xAE,0xF1,0xBA,0x11,0xB5,0x9B,0x58,0x5A,0x80,0xB4,0x37,0x78,0x09, -0x33,0x7C,0x32,0x47,0x03,0x5C,0xC4,0xA5,0x83,0x48,0xF4,0x57,0x56,0x6E,0x81,0x36, -0x27,0x18,0x4F,0xEC,0x9B,0x28,0xC2,0xD4,0xB4,0xD7,0x7C,0x0C,0x3E,0x0C,0x2B,0xDF, -0xCA,0x04,0xD7,0xC6,0x8E,0xEA,0x58,0x4E,0xA8,0xA4,0xA5,0x18,0x1C,0x6C,0x45,0x98, -0xA3,0x41,0xD1,0x2D,0xD2,0xC7,0x6D,0x8D,0x19,0xF1,0xAD,0x79,0xB7,0x81,0x3F,0xBD, -0x06,0x82,0x27,0x2D,0x10,0x58,0x05,0xB5,0x78,0x05,0xB9,0x2F,0xDB,0x0C,0x6B,0x90, -0x90,0x7E,0x14,0x59,0x38,0xBB,0x94,0x24,0x13,0xE5,0xD1,0x9D,0x14,0xDF,0xD3,0x82, -0x4D,0x46,0xF0,0x80,0x39,0x52,0x32,0x0F,0xE3,0x84,0xB2,0x7A,0x43,0xF2,0x5E,0xDE, -0x5F,0x3F,0x1D,0xDD,0xE3,0xB2,0x1B,0xA0,0xA1,0x2A,0x23,0x03,0x6E,0x2E,0x01,0x15, -0x87,0x5C,0xA6,0x75,0x75,0xC7,0x97,0x61,0xBE,0xDE,0x86,0xDC,0xD4,0x48,0xDB,0xBD, -0x2A,0xBF,0x4A,0x55,0xDA,0xE8,0x7D,0x50,0xFB,0xB4,0x80,0x17,0xB8,0x94,0xBF,0x01, -0x3D,0xEA,0xDA,0xBA,0x7C,0xE0,0x58,0x67,0x17,0xB9,0x58,0xE0,0x88,0x86,0x46,0x67, -0x6C,0x9D,0x10,0x47,0x58,0x32,0xD0,0x35,0x7C,0x79,0x2A,0x90,0xA2,0x5A,0x10,0x11, -0x23,0x35,0xAD,0x2F,0xCC,0xE4,0x4A,0x5B,0xA7,0xC8,0x27,0xF2,0x83,0xDE,0x5E,0xBB, -0x5E,0x77,0xE7,0xE8,0xA5,0x6E,0x63,0xC2,0x0D,0x5D,0x61,0xD0,0x8C,0xD2,0x6C,0x5A, -0x21,0x0E,0xCA,0x28,0xA3,0xCE,0x2A,0xE9,0x95,0xC7,0x48,0xCF,0x96,0x6F,0x1D,0x92, -0x25,0xC8,0xC6,0xC6,0xC1,0xC1,0x0C,0x05,0xAC,0x26,0xC4,0xD2,0x75,0xD2,0xE1,0x2A, -0x67,0xC0,0x3D,0x5B,0xA5,0x9A,0xEB,0xCF,0x7B,0x1A,0xA8,0x9D,0x14,0x45,0xE5,0x0F, -0xA0,0x9A,0x65,0xDE,0x2F,0x28,0xBD,0xCE,0x6F,0x94,0x66,0x83,0x48,0x29,0xD8,0xEA, -0x65,0x8C,0xAF,0x93,0xD9,0x64,0x9F,0x55,0x57,0x26,0xBF,0x6F,0xCB,0x37,0x31,0x99, -0xA3,0x60,0xBB,0x1C,0xAD,0x89,0x34,0x32,0x62,0xB8,0x43,0x21,0x06,0x72,0x0C,0xA1, -0x5C,0x6D,0x46,0xC5,0xFA,0x29,0xCF,0x30,0xDE,0x89,0xDC,0x71,0x5B,0xDD,0xB6,0x37, -0x3E,0xDF,0x50,0xF5,0xB8,0x07,0x25,0x26,0xE5,0xBC,0xB5,0xFE,0x3C,0x02,0xB3,0xB7, -0xF8,0xBE,0x43,0xC1,0x87,0x11,0x94,0x9E,0x23,0x6C,0x17,0x8A,0xB8,0x8A,0x27,0x0C, -0x54,0x47,0xF0,0xA9,0xB3,0xC0,0x80,0x8C,0xA0,0x27,0xEB,0x1D,0x19,0xE3,0x07,0x8E, -0x77,0x70,0xCA,0x2B,0xF4,0x7D,0x76,0xE0,0x78,0x67,0x02,0x03,0x01,0x00,0x01,0xA3, -0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, -0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x4D, -0x45,0xC1,0x68,0x38,0xBB,0x73,0xA9,0x69,0xA1,0x20,0xE7,0xED,0xF5,0x22,0xA1,0x23, -0x14,0xD7,0x9E,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, -0x4D,0x45,0xC1,0x68,0x38,0xBB,0x73,0xA9,0x69,0xA1,0x20,0xE7,0xED,0xF5,0x22,0xA1, -0x23,0x14,0xD7,0x9E,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, -0x03,0x02,0x01,0x86,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x05,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x67,0x6B,0x06,0xB9,0x5F,0x45,0x3B,0x2A, -0x4B,0x33,0xB3,0xE6,0x1B,0x6B,0x59,0x4E,0x22,0xCC,0xB9,0xB7,0xA4,0x25,0xC9,0xA7, -0xC4,0xF0,0x54,0x96,0x0B,0x64,0xF3,0xB1,0x58,0x4F,0x5E,0x51,0xFC,0xB2,0x97,0x7B, -0x27,0x65,0xC2,0xE5,0xCA,0xE7,0x0D,0x0C,0x25,0x7B,0x62,0xE3,0xFA,0x9F,0xB4,0x87, -0xB7,0x45,0x46,0xAF,0x83,0xA5,0x97,0x48,0x8C,0xA5,0xBD,0xF1,0x16,0x2B,0x9B,0x76, -0x2C,0x7A,0x35,0x60,0x6C,0x11,0x80,0x97,0xCC,0xA9,0x92,0x52,0xE6,0x2B,0xE6,0x69, -0xED,0xA9,0xF8,0x36,0x2D,0x2C,0x77,0xBF,0x61,0x48,0xD1,0x63,0x0B,0xB9,0x5B,0x52, -0xED,0x18,0xB0,0x43,0x42,0x22,0xA6,0xB1,0x77,0xAE,0xDE,0x69,0xC5,0xCD,0xC7,0x1C, -0xA1,0xB1,0xA5,0x1C,0x10,0xFB,0x18,0xBE,0x1A,0x70,0xDD,0xC1,0x92,0x4B,0xBE,0x29, -0x5A,0x9D,0x3F,0x35,0xBE,0xE5,0x7D,0x51,0xF8,0x55,0xE0,0x25,0x75,0x23,0x87,0x1E, -0x5C,0xDC,0xBA,0x9D,0xB0,0xAC,0xB3,0x69,0xDB,0x17,0x83,0xC9,0xF7,0xDE,0x0C,0xBC, -0x08,0xDC,0x91,0x9E,0xA8,0xD0,0xD7,0x15,0x37,0x73,0xA5,0x35,0xB8,0xFC,0x7E,0xC5, -0x44,0x40,0x06,0xC3,0xEB,0xF8,0x22,0x80,0x5C,0x47,0xCE,0x02,0xE3,0x11,0x9F,0x44, -0xFF,0xFD,0x9A,0x32,0xCC,0x7D,0x64,0x51,0x0E,0xEB,0x57,0x26,0x76,0x3A,0xE3,0x1E, -0x22,0x3C,0xC2,0xA6,0x36,0xDD,0x19,0xEF,0xA7,0xFC,0x12,0xF3,0x26,0xC0,0x59,0x31, -0x85,0x4C,0x9C,0xD8,0xCF,0xDF,0xA4,0xCC,0xCC,0x29,0x93,0xFF,0x94,0x6D,0x76,0x5C, -0x13,0x08,0x97,0xF2,0xED,0xA5,0x0B,0x4D,0xDD,0xE8,0xC9,0x68,0x0E,0x66,0xD3,0x00, -0x0E,0x33,0x12,0x5B,0xBC,0x95,0xE5,0x32,0x90,0xA8,0xB3,0xC6,0x6C,0x83,0xAD,0x77, -0xEE,0x8B,0x7E,0x7E,0xB1,0xA9,0xAB,0xD3,0xE1,0xF1,0xB6,0xC0,0xB1,0xEA,0x88,0xC0, -0xE7,0xD3,0x90,0xE9,0x28,0x92,0x94,0x7B,0x68,0x7B,0x97,0x2A,0x0A,0x67,0x2D,0x85, -0x02,0x38,0x10,0xE4,0x03,0x61,0xD4,0xDA,0x25,0x36,0xC7,0x08,0x58,0x2D,0xA1,0xA7, -0x51,0xAF,0x30,0x0A,0x49,0xF5,0xA6,0x69,0x87,0x07,0x2D,0x44,0x46,0x76,0x8E,0x2A, -0xE5,0x9A,0x3B,0xD7,0x18,0xA2,0xFC,0x9C,0x38,0x10,0xCC,0xC6,0x3B,0xD2,0xB5,0x17, -0x3A,0x6F,0xFD,0xAE,0x25,0xBD,0xF5,0x72,0x59,0x64,0xB1,0x74,0x2A,0x38,0x5F,0x18, -0x4C,0xDF,0xCF,0x71,0x04,0x5A,0x36,0xD4,0xBF,0x2F,0x99,0x9C,0xE8,0xD9,0xBA,0xB1, -0x95,0xE6,0x02,0x4B,0x21,0xA1,0x5B,0xD5,0xC1,0x4F,0x8F,0xAE,0x69,0x6D,0x53,0xDB, -0x01,0x93,0xB5,0x5C,0x1E,0x18,0xDD,0x64,0x5A,0xCA,0x18,0x28,0x3E,0x63,0x04,0x11, -0xFD,0x1C,0x8D,0x00,0x0F,0xB8,0x37,0xDF,0x67,0x8A,0x9D,0x66,0xA9,0x02,0x6A,0x91, -0xFF,0x13,0xCA,0x2F,0x5D,0x83,0xBC,0x87,0x93,0x6C,0xDC,0x24,0x51,0x16,0x04,0x25, -0x66,0xFA,0xB3,0xD9,0xC2,0xBA,0x29,0xBE,0x9A,0x48,0x38,0x82,0x99,0xF4,0xBF,0x3B, -0x4A,0x31,0x19,0xF9,0xBF,0x8E,0x21,0x33,0x14,0xCA,0x4F,0x54,0x5F,0xFB,0xCE,0xFB, -0x8F,0x71,0x7F,0xFD,0x5E,0x19,0xA0,0x0F,0x4B,0x91,0xB8,0xC4,0x54,0xBC,0x06,0xB0, -0x45,0x8F,0x26,0x91,0xA2,0x8E,0xFE,0xA9, -}; - - -/* subject:/C=IE/O=Baltimore/OU=CyberTrust/CN=Baltimore CyberTrust Root */ -/* issuer :/C=IE/O=Baltimore/OU=CyberTrust/CN=Baltimore CyberTrust Root */ - - -const unsigned char Baltimore_CyberTrust_Root_certificate[891]={ -0x30,0x82,0x03,0x77,0x30,0x82,0x02,0x5F,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x02, -0x00,0x00,0xB9,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x30,0x5A,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x49, -0x45,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x13,0x09,0x42,0x61,0x6C,0x74, -0x69,0x6D,0x6F,0x72,0x65,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0B,0x13,0x0A, -0x43,0x79,0x62,0x65,0x72,0x54,0x72,0x75,0x73,0x74,0x31,0x22,0x30,0x20,0x06,0x03, -0x55,0x04,0x03,0x13,0x19,0x42,0x61,0x6C,0x74,0x69,0x6D,0x6F,0x72,0x65,0x20,0x43, -0x79,0x62,0x65,0x72,0x54,0x72,0x75,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E, -0x17,0x0D,0x30,0x30,0x30,0x35,0x31,0x32,0x31,0x38,0x34,0x36,0x30,0x30,0x5A,0x17, -0x0D,0x32,0x35,0x30,0x35,0x31,0x32,0x32,0x33,0x35,0x39,0x30,0x30,0x5A,0x30,0x5A, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x49,0x45,0x31,0x12,0x30, -0x10,0x06,0x03,0x55,0x04,0x0A,0x13,0x09,0x42,0x61,0x6C,0x74,0x69,0x6D,0x6F,0x72, -0x65,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0B,0x13,0x0A,0x43,0x79,0x62,0x65, -0x72,0x54,0x72,0x75,0x73,0x74,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x13, -0x19,0x42,0x61,0x6C,0x74,0x69,0x6D,0x6F,0x72,0x65,0x20,0x43,0x79,0x62,0x65,0x72, -0x54,0x72,0x75,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x30,0x82,0x01,0x22,0x30,0x0D, -0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01, -0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xA3,0x04,0xBB,0x22,0xAB, -0x98,0x3D,0x57,0xE8,0x26,0x72,0x9A,0xB5,0x79,0xD4,0x29,0xE2,0xE1,0xE8,0x95,0x80, -0xB1,0xB0,0xE3,0x5B,0x8E,0x2B,0x29,0x9A,0x64,0xDF,0xA1,0x5D,0xED,0xB0,0x09,0x05, -0x6D,0xDB,0x28,0x2E,0xCE,0x62,0xA2,0x62,0xFE,0xB4,0x88,0xDA,0x12,0xEB,0x38,0xEB, -0x21,0x9D,0xC0,0x41,0x2B,0x01,0x52,0x7B,0x88,0x77,0xD3,0x1C,0x8F,0xC7,0xBA,0xB9, -0x88,0xB5,0x6A,0x09,0xE7,0x73,0xE8,0x11,0x40,0xA7,0xD1,0xCC,0xCA,0x62,0x8D,0x2D, -0xE5,0x8F,0x0B,0xA6,0x50,0xD2,0xA8,0x50,0xC3,0x28,0xEA,0xF5,0xAB,0x25,0x87,0x8A, -0x9A,0x96,0x1C,0xA9,0x67,0xB8,0x3F,0x0C,0xD5,0xF7,0xF9,0x52,0x13,0x2F,0xC2,0x1B, -0xD5,0x70,0x70,0xF0,0x8F,0xC0,0x12,0xCA,0x06,0xCB,0x9A,0xE1,0xD9,0xCA,0x33,0x7A, -0x77,0xD6,0xF8,0xEC,0xB9,0xF1,0x68,0x44,0x42,0x48,0x13,0xD2,0xC0,0xC2,0xA4,0xAE, -0x5E,0x60,0xFE,0xB6,0xA6,0x05,0xFC,0xB4,0xDD,0x07,0x59,0x02,0xD4,0x59,0x18,0x98, -0x63,0xF5,0xA5,0x63,0xE0,0x90,0x0C,0x7D,0x5D,0xB2,0x06,0x7A,0xF3,0x85,0xEA,0xEB, -0xD4,0x03,0xAE,0x5E,0x84,0x3E,0x5F,0xFF,0x15,0xED,0x69,0xBC,0xF9,0x39,0x36,0x72, -0x75,0xCF,0x77,0x52,0x4D,0xF3,0xC9,0x90,0x2C,0xB9,0x3D,0xE5,0xC9,0x23,0x53,0x3F, -0x1F,0x24,0x98,0x21,0x5C,0x07,0x99,0x29,0xBD,0xC6,0x3A,0xEC,0xE7,0x6E,0x86,0x3A, -0x6B,0x97,0x74,0x63,0x33,0xBD,0x68,0x18,0x31,0xF0,0x78,0x8D,0x76,0xBF,0xFC,0x9E, -0x8E,0x5D,0x2A,0x86,0xA7,0x4D,0x90,0xDC,0x27,0x1A,0x39,0x02,0x03,0x01,0x00,0x01, -0xA3,0x45,0x30,0x43,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xE5, -0x9D,0x59,0x30,0x82,0x47,0x58,0xCC,0xAC,0xFA,0x08,0x54,0x36,0x86,0x7B,0x3A,0xB5, -0x04,0x4D,0xF0,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30, -0x06,0x01,0x01,0xFF,0x02,0x01,0x03,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, -0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x85,0x0C,0x5D,0x8E,0xE4, -0x6F,0x51,0x68,0x42,0x05,0xA0,0xDD,0xBB,0x4F,0x27,0x25,0x84,0x03,0xBD,0xF7,0x64, -0xFD,0x2D,0xD7,0x30,0xE3,0xA4,0x10,0x17,0xEB,0xDA,0x29,0x29,0xB6,0x79,0x3F,0x76, -0xF6,0x19,0x13,0x23,0xB8,0x10,0x0A,0xF9,0x58,0xA4,0xD4,0x61,0x70,0xBD,0x04,0x61, -0x6A,0x12,0x8A,0x17,0xD5,0x0A,0xBD,0xC5,0xBC,0x30,0x7C,0xD6,0xE9,0x0C,0x25,0x8D, -0x86,0x40,0x4F,0xEC,0xCC,0xA3,0x7E,0x38,0xC6,0x37,0x11,0x4F,0xED,0xDD,0x68,0x31, -0x8E,0x4C,0xD2,0xB3,0x01,0x74,0xEE,0xBE,0x75,0x5E,0x07,0x48,0x1A,0x7F,0x70,0xFF, -0x16,0x5C,0x84,0xC0,0x79,0x85,0xB8,0x05,0xFD,0x7F,0xBE,0x65,0x11,0xA3,0x0F,0xC0, -0x02,0xB4,0xF8,0x52,0x37,0x39,0x04,0xD5,0xA9,0x31,0x7A,0x18,0xBF,0xA0,0x2A,0xF4, -0x12,0x99,0xF7,0xA3,0x45,0x82,0xE3,0x3C,0x5E,0xF5,0x9D,0x9E,0xB5,0xC8,0x9E,0x7C, -0x2E,0xC8,0xA4,0x9E,0x4E,0x08,0x14,0x4B,0x6D,0xFD,0x70,0x6D,0x6B,0x1A,0x63,0xBD, -0x64,0xE6,0x1F,0xB7,0xCE,0xF0,0xF2,0x9F,0x2E,0xBB,0x1B,0xB7,0xF2,0x50,0x88,0x73, -0x92,0xC2,0xE2,0xE3,0x16,0x8D,0x9A,0x32,0x02,0xAB,0x8E,0x18,0xDD,0xE9,0x10,0x11, -0xEE,0x7E,0x35,0xAB,0x90,0xAF,0x3E,0x30,0x94,0x7A,0xD0,0x33,0x3D,0xA7,0x65,0x0F, -0xF5,0xFC,0x8E,0x9E,0x62,0xCF,0x47,0x44,0x2C,0x01,0x5D,0xBB,0x1D,0xB5,0x32,0xD2, -0x47,0xD2,0x38,0x2E,0xD0,0xFE,0x81,0xDC,0x32,0x6A,0x1E,0xB5,0xEE,0x3C,0xD5,0xFC, -0xE7,0x81,0x1D,0x19,0xC3,0x24,0x42,0xEA,0x63,0x39,0xA9, -}; - - -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services */ - - -const unsigned char Comodo_AAA_Services_root_certificate[1078]={ -0x30,0x82,0x04,0x32,0x30,0x82,0x03,0x1A,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x7B,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B, -0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x0C,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72, -0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06, -0x03,0x55,0x04,0x07,0x0C,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30, -0x18,0x06,0x03,0x55,0x04,0x0A,0x0C,0x11,0x43,0x6F,0x6D,0x6F,0x64,0x6F,0x20,0x43, -0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x21,0x30,0x1F,0x06,0x03,0x55, -0x04,0x03,0x0C,0x18,0x41,0x41,0x41,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, -0x61,0x74,0x65,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x30,0x1E,0x17,0x0D, -0x30,0x34,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32, -0x38,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x7B,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06, -0x03,0x55,0x04,0x08,0x0C,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61, -0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04, -0x07,0x0C,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03, -0x55,0x04,0x0A,0x0C,0x11,0x43,0x6F,0x6D,0x6F,0x64,0x6F,0x20,0x43,0x41,0x20,0x4C, -0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x0C, -0x18,0x41,0x41,0x41,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65, -0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x30,0x82,0x01,0x22,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F, -0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBE,0x40,0x9D,0xF4,0x6E,0xE1, -0xEA,0x76,0x87,0x1C,0x4D,0x45,0x44,0x8E,0xBE,0x46,0xC8,0x83,0x06,0x9D,0xC1,0x2A, -0xFE,0x18,0x1F,0x8E,0xE4,0x02,0xFA,0xF3,0xAB,0x5D,0x50,0x8A,0x16,0x31,0x0B,0x9A, -0x06,0xD0,0xC5,0x70,0x22,0xCD,0x49,0x2D,0x54,0x63,0xCC,0xB6,0x6E,0x68,0x46,0x0B, -0x53,0xEA,0xCB,0x4C,0x24,0xC0,0xBC,0x72,0x4E,0xEA,0xF1,0x15,0xAE,0xF4,0x54,0x9A, -0x12,0x0A,0xC3,0x7A,0xB2,0x33,0x60,0xE2,0xDA,0x89,0x55,0xF3,0x22,0x58,0xF3,0xDE, -0xDC,0xCF,0xEF,0x83,0x86,0xA2,0x8C,0x94,0x4F,0x9F,0x68,0xF2,0x98,0x90,0x46,0x84, -0x27,0xC7,0x76,0xBF,0xE3,0xCC,0x35,0x2C,0x8B,0x5E,0x07,0x64,0x65,0x82,0xC0,0x48, -0xB0,0xA8,0x91,0xF9,0x61,0x9F,0x76,0x20,0x50,0xA8,0x91,0xC7,0x66,0xB5,0xEB,0x78, -0x62,0x03,0x56,0xF0,0x8A,0x1A,0x13,0xEA,0x31,0xA3,0x1E,0xA0,0x99,0xFD,0x38,0xF6, -0xF6,0x27,0x32,0x58,0x6F,0x07,0xF5,0x6B,0xB8,0xFB,0x14,0x2B,0xAF,0xB7,0xAA,0xCC, -0xD6,0x63,0x5F,0x73,0x8C,0xDA,0x05,0x99,0xA8,0x38,0xA8,0xCB,0x17,0x78,0x36,0x51, -0xAC,0xE9,0x9E,0xF4,0x78,0x3A,0x8D,0xCF,0x0F,0xD9,0x42,0xE2,0x98,0x0C,0xAB,0x2F, -0x9F,0x0E,0x01,0xDE,0xEF,0x9F,0x99,0x49,0xF1,0x2D,0xDF,0xAC,0x74,0x4D,0x1B,0x98, -0xB5,0x47,0xC5,0xE5,0x29,0xD1,0xF9,0x90,0x18,0xC7,0x62,0x9C,0xBE,0x83,0xC7,0x26, -0x7B,0x3E,0x8A,0x25,0xC7,0xC0,0xDD,0x9D,0xE6,0x35,0x68,0x10,0x20,0x9D,0x8F,0xD8, -0xDE,0xD2,0xC3,0x84,0x9C,0x0D,0x5E,0xE8,0x2F,0xC9,0x02,0x03,0x01,0x00,0x01,0xA3, -0x81,0xC0,0x30,0x81,0xBD,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14, -0xA0,0x11,0x0A,0x23,0x3E,0x96,0xF1,0x07,0xEC,0xE2,0xAF,0x29,0xEF,0x82,0xA5,0x7F, -0xD0,0x30,0xA4,0xB4,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, -0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05, -0x30,0x03,0x01,0x01,0xFF,0x30,0x7B,0x06,0x03,0x55,0x1D,0x1F,0x04,0x74,0x30,0x72, -0x30,0x38,0xA0,0x36,0xA0,0x34,0x86,0x32,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63, -0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F, -0x41,0x41,0x41,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x65, -0x72,0x76,0x69,0x63,0x65,0x73,0x2E,0x63,0x72,0x6C,0x30,0x36,0xA0,0x34,0xA0,0x32, -0x86,0x30,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D, -0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x41,0x41,0x41,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2E,0x63, -0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05, -0x00,0x03,0x82,0x01,0x01,0x00,0x08,0x56,0xFC,0x02,0xF0,0x9B,0xE8,0xFF,0xA4,0xFA, -0xD6,0x7B,0xC6,0x44,0x80,0xCE,0x4F,0xC4,0xC5,0xF6,0x00,0x58,0xCC,0xA6,0xB6,0xBC, -0x14,0x49,0x68,0x04,0x76,0xE8,0xE6,0xEE,0x5D,0xEC,0x02,0x0F,0x60,0xD6,0x8D,0x50, -0x18,0x4F,0x26,0x4E,0x01,0xE3,0xE6,0xB0,0xA5,0xEE,0xBF,0xBC,0x74,0x54,0x41,0xBF, -0xFD,0xFC,0x12,0xB8,0xC7,0x4F,0x5A,0xF4,0x89,0x60,0x05,0x7F,0x60,0xB7,0x05,0x4A, -0xF3,0xF6,0xF1,0xC2,0xBF,0xC4,0xB9,0x74,0x86,0xB6,0x2D,0x7D,0x6B,0xCC,0xD2,0xF3, -0x46,0xDD,0x2F,0xC6,0xE0,0x6A,0xC3,0xC3,0x34,0x03,0x2C,0x7D,0x96,0xDD,0x5A,0xC2, -0x0E,0xA7,0x0A,0x99,0xC1,0x05,0x8B,0xAB,0x0C,0x2F,0xF3,0x5C,0x3A,0xCF,0x6C,0x37, -0x55,0x09,0x87,0xDE,0x53,0x40,0x6C,0x58,0xEF,0xFC,0xB6,0xAB,0x65,0x6E,0x04,0xF6, -0x1B,0xDC,0x3C,0xE0,0x5A,0x15,0xC6,0x9E,0xD9,0xF1,0x59,0x48,0x30,0x21,0x65,0x03, -0x6C,0xEC,0xE9,0x21,0x73,0xEC,0x9B,0x03,0xA1,0xE0,0x37,0xAD,0xA0,0x15,0x18,0x8F, -0xFA,0xBA,0x02,0xCE,0xA7,0x2C,0xA9,0x10,0x13,0x2C,0xD4,0xE5,0x08,0x26,0xAB,0x22, -0x97,0x60,0xF8,0x90,0x5E,0x74,0xD4,0xA2,0x9A,0x53,0xBD,0xF2,0xA9,0x68,0xE0,0xA2, -0x6E,0xC2,0xD7,0x6C,0xB1,0xA3,0x0F,0x9E,0xBF,0xEB,0x68,0xE7,0x56,0xF2,0xAE,0xF2, -0xE3,0x2B,0x38,0x3A,0x09,0x81,0xB5,0x6B,0x85,0xD7,0xBE,0x2D,0xED,0x3F,0x1A,0xB7, -0xB2,0x63,0xE2,0xF5,0x62,0x2C,0x82,0xD4,0x6A,0x00,0x41,0x50,0xF1,0x39,0x83,0x9F, -0x95,0xE9,0x36,0x96,0x98,0x6E, -}; - - -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO Certification Authority */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO Certification Authority */ - - -const unsigned char COMODO_Certification_Authority_certificate[1057]={ -0x30,0x82,0x04,0x1D,0x30,0x82,0x03,0x05,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4E, -0x81,0x2D,0x8A,0x82,0x65,0xE0,0x0B,0x02,0xEE,0x3E,0x35,0x02,0x46,0xE5,0x3D,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, -0x81,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B, -0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72, -0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06, -0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30, -0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43, -0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x27,0x30,0x25,0x06,0x03,0x55, -0x04,0x03,0x13,0x1E,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x30,0x31,0x30,0x30,0x30,0x30, -0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, -0x39,0x5A,0x30,0x81,0x81,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x47,0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65, -0x61,0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31, -0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72, -0x64,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F, -0x44,0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x27,0x30, -0x25,0x06,0x03,0x55,0x04,0x03,0x13,0x1E,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43, -0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74, -0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82, -0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xD0,0x40,0x8B,0x8B,0x72,0xE3,0x91,0x1B,0xF7, -0x51,0xC1,0x1B,0x54,0x04,0x98,0xD3,0xA9,0xBF,0xC1,0xE6,0x8A,0x5D,0x3B,0x87,0xFB, -0xBB,0x88,0xCE,0x0D,0xE3,0x2F,0x3F,0x06,0x96,0xF0,0xA2,0x29,0x50,0x99,0xAE,0xDB, -0x3B,0xA1,0x57,0xB0,0x74,0x51,0x71,0xCD,0xED,0x42,0x91,0x4D,0x41,0xFE,0xA9,0xC8, -0xD8,0x6A,0x86,0x77,0x44,0xBB,0x59,0x66,0x97,0x50,0x5E,0xB4,0xD4,0x2C,0x70,0x44, -0xCF,0xDA,0x37,0x95,0x42,0x69,0x3C,0x30,0xC4,0x71,0xB3,0x52,0xF0,0x21,0x4D,0xA1, -0xD8,0xBA,0x39,0x7C,0x1C,0x9E,0xA3,0x24,0x9D,0xF2,0x83,0x16,0x98,0xAA,0x16,0x7C, -0x43,0x9B,0x15,0x5B,0xB7,0xAE,0x34,0x91,0xFE,0xD4,0x62,0x26,0x18,0x46,0x9A,0x3F, -0xEB,0xC1,0xF9,0xF1,0x90,0x57,0xEB,0xAC,0x7A,0x0D,0x8B,0xDB,0x72,0x30,0x6A,0x66, -0xD5,0xE0,0x46,0xA3,0x70,0xDC,0x68,0xD9,0xFF,0x04,0x48,0x89,0x77,0xDE,0xB5,0xE9, -0xFB,0x67,0x6D,0x41,0xE9,0xBC,0x39,0xBD,0x32,0xD9,0x62,0x02,0xF1,0xB1,0xA8,0x3D, -0x6E,0x37,0x9C,0xE2,0x2F,0xE2,0xD3,0xA2,0x26,0x8B,0xC6,0xB8,0x55,0x43,0x88,0xE1, -0x23,0x3E,0xA5,0xD2,0x24,0x39,0x6A,0x47,0xAB,0x00,0xD4,0xA1,0xB3,0xA9,0x25,0xFE, -0x0D,0x3F,0xA7,0x1D,0xBA,0xD3,0x51,0xC1,0x0B,0xA4,0xDA,0xAC,0x38,0xEF,0x55,0x50, -0x24,0x05,0x65,0x46,0x93,0x34,0x4F,0x2D,0x8D,0xAD,0xC6,0xD4,0x21,0x19,0xD2,0x8E, -0xCA,0x05,0x61,0x71,0x07,0x73,0x47,0xE5,0x8A,0x19,0x12,0xBD,0x04,0x4D,0xCE,0x4E, -0x9C,0xA5,0x48,0xAC,0xBB,0x26,0xF7,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x8E,0x30, -0x81,0x8B,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x0B,0x58,0xE5, -0x8B,0xC6,0x4C,0x15,0x37,0xA4,0x40,0xA9,0x30,0xA9,0x21,0xBE,0x47,0x36,0x5A,0x56, -0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01, -0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01, -0x01,0xFF,0x30,0x49,0x06,0x03,0x55,0x1D,0x1F,0x04,0x42,0x30,0x40,0x30,0x3E,0xA0, -0x3C,0xA0,0x3A,0x86,0x38,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E, -0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F,0x4D, -0x4F,0x44,0x4F,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E, -0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01, -0x00,0x3E,0x98,0x9E,0x9B,0xF6,0x1B,0xE9,0xD7,0x39,0xB7,0x78,0xAE,0x1D,0x72,0x18, -0x49,0xD3,0x87,0xE4,0x43,0x82,0xEB,0x3F,0xC9,0xAA,0xF5,0xA8,0xB5,0xEF,0x55,0x7C, -0x21,0x52,0x65,0xF9,0xD5,0x0D,0xE1,0x6C,0xF4,0x3E,0x8C,0x93,0x73,0x91,0x2E,0x02, -0xC4,0x4E,0x07,0x71,0x6F,0xC0,0x8F,0x38,0x61,0x08,0xA8,0x1E,0x81,0x0A,0xC0,0x2F, -0x20,0x2F,0x41,0x8B,0x91,0xDC,0x48,0x45,0xBC,0xF1,0xC6,0xDE,0xBA,0x76,0x6B,0x33, -0xC8,0x00,0x2D,0x31,0x46,0x4C,0xED,0xE7,0x9D,0xCF,0x88,0x94,0xFF,0x33,0xC0,0x56, -0xE8,0x24,0x86,0x26,0xB8,0xD8,0x38,0x38,0xDF,0x2A,0x6B,0xDD,0x12,0xCC,0xC7,0x3F, -0x47,0x17,0x4C,0xA2,0xC2,0x06,0x96,0x09,0xD6,0xDB,0xFE,0x3F,0x3C,0x46,0x41,0xDF, -0x58,0xE2,0x56,0x0F,0x3C,0x3B,0xC1,0x1C,0x93,0x35,0xD9,0x38,0x52,0xAC,0xEE,0xC8, -0xEC,0x2E,0x30,0x4E,0x94,0x35,0xB4,0x24,0x1F,0x4B,0x78,0x69,0xDA,0xF2,0x02,0x38, -0xCC,0x95,0x52,0x93,0xF0,0x70,0x25,0x59,0x9C,0x20,0x67,0xC4,0xEE,0xF9,0x8B,0x57, -0x61,0xF4,0x92,0x76,0x7D,0x3F,0x84,0x8D,0x55,0xB7,0xE8,0xE5,0xAC,0xD5,0xF1,0xF5, -0x19,0x56,0xA6,0x5A,0xFB,0x90,0x1C,0xAF,0x93,0xEB,0xE5,0x1C,0xD4,0x67,0x97,0x5D, -0x04,0x0E,0xBE,0x0B,0x83,0xA6,0x17,0x83,0xB9,0x30,0x12,0xA0,0xC5,0x33,0x15,0x05, -0xB9,0x0D,0xFB,0xC7,0x05,0x76,0xE3,0xD8,0x4A,0x8D,0xFC,0x34,0x17,0xA3,0xC6,0x21, -0x28,0xBE,0x30,0x45,0x31,0x1E,0xC7,0x78,0xBE,0x58,0x61,0x38,0xAC,0x3B,0xE2,0x01, -0x65, -}; - - -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO ECC Certification Authority */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO ECC Certification Authority */ - - -const unsigned char COMODO_ECC_Certification_Authority_certificate[653]={ -0x30,0x82,0x02,0x89,0x30,0x82,0x02,0x0F,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x1F, -0x47,0xAF,0xAA,0x62,0x00,0x70,0x50,0x54,0x4C,0x01,0x9E,0x9B,0x63,0x99,0x2A,0x30, -0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x30,0x81,0x85,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06, -0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61, -0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04, -0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03, -0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x41,0x20,0x4C, -0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13, -0x22,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x45,0x43,0x43,0x20,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, -0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x33,0x30,0x36,0x30,0x30,0x30, -0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31,0x38,0x32,0x33,0x35,0x39, -0x35,0x39,0x5A,0x30,0x81,0x85,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72, -0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72, -0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F, -0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D, -0x4F,0x44,0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x2B, -0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20, -0x45,0x43,0x43,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F, -0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x76,0x30,0x10,0x06, -0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03, -0x62,0x00,0x04,0x03,0x47,0x7B,0x2F,0x75,0xC9,0x82,0x15,0x85,0xFB,0x75,0xE4,0x91, -0x16,0xD4,0xAB,0x62,0x99,0xF5,0x3E,0x52,0x0B,0x06,0xCE,0x41,0x00,0x7F,0x97,0xE1, -0x0A,0x24,0x3C,0x1D,0x01,0x04,0xEE,0x3D,0xD2,0x8D,0x09,0x97,0x0C,0xE0,0x75,0xE4, -0xFA,0xFB,0x77,0x8A,0x2A,0xF5,0x03,0x60,0x4B,0x36,0x8B,0x16,0x23,0x16,0xAD,0x09, -0x71,0xF4,0x4A,0xF4,0x28,0x50,0xB4,0xFE,0x88,0x1C,0x6E,0x3F,0x6C,0x2F,0x2F,0x09, -0x59,0x5B,0xA5,0x5B,0x0B,0x33,0x99,0xE2,0xC3,0x3D,0x89,0xF9,0x6A,0x2C,0xEF,0xB2, -0xD3,0x06,0xE9,0xA3,0x42,0x30,0x40,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, -0x04,0x14,0x75,0x71,0xA7,0x19,0x48,0x19,0xBC,0x9D,0x9D,0xEA,0x41,0x47,0xDF,0x94, -0xC4,0x48,0x77,0x99,0xD3,0x79,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF, -0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF, -0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, -0x04,0x03,0x03,0x03,0x68,0x00,0x30,0x65,0x02,0x31,0x00,0xEF,0x03,0x5B,0x7A,0xAC, -0xB7,0x78,0x0A,0x72,0xB7,0x88,0xDF,0xFF,0xB5,0x46,0x14,0x09,0x0A,0xFA,0xA0,0xE6, -0x7D,0x08,0xC6,0x1A,0x87,0xBD,0x18,0xA8,0x73,0xBD,0x26,0xCA,0x60,0x0C,0x9D,0xCE, -0x99,0x9F,0xCF,0x5C,0x0F,0x30,0xE1,0xBE,0x14,0x31,0xEA,0x02,0x30,0x14,0xF4,0x93, -0x3C,0x49,0xA7,0x33,0x7A,0x90,0x46,0x47,0xB3,0x63,0x7D,0x13,0x9B,0x4E,0xB7,0x6F, -0x18,0x37,0x80,0x53,0xFE,0xDD,0x20,0xE0,0x35,0x9A,0x36,0xD1,0xC7,0x01,0xB9,0xE6, -0xDC,0xDD,0xF3,0xFF,0x1D,0x2C,0x3A,0x16,0x57,0xD9,0x92,0x39,0xD6, -}; - - -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=Secure Certificate Services */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=Secure Certificate Services */ - - -const unsigned char Comodo_Secure_Services_root_certificate[1091]={ -0x30,0x82,0x04,0x3F,0x30,0x82,0x03,0x27,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x7E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B, -0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x0C,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72, -0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06, -0x03,0x55,0x04,0x07,0x0C,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30, -0x18,0x06,0x03,0x55,0x04,0x0A,0x0C,0x11,0x43,0x6F,0x6D,0x6F,0x64,0x6F,0x20,0x43, -0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x24,0x30,0x22,0x06,0x03,0x55, -0x04,0x03,0x0C,0x1B,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x30, -0x1E,0x17,0x0D,0x30,0x34,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A, -0x17,0x0D,0x32,0x38,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30, -0x7E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B, -0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x0C,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72, -0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06, -0x03,0x55,0x04,0x07,0x0C,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30, -0x18,0x06,0x03,0x55,0x04,0x0A,0x0C,0x11,0x43,0x6F,0x6D,0x6F,0x64,0x6F,0x20,0x43, -0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x24,0x30,0x22,0x06,0x03,0x55, -0x04,0x03,0x0C,0x1B,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x30, -0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01, -0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00, -0xC0,0x71,0x33,0x82,0x8A,0xD0,0x70,0xEB,0x73,0x87,0x82,0x40,0xD5,0x1D,0xE4,0xCB, -0xC9,0x0E,0x42,0x90,0xF9,0xDE,0x34,0xB9,0xA1,0xBA,0x11,0xF4,0x25,0x85,0xF3,0xCC, -0x72,0x6D,0xF2,0x7B,0x97,0x6B,0xB3,0x07,0xF1,0x77,0x24,0x91,0x5F,0x25,0x8F,0xF6, -0x74,0x3D,0xE4,0x80,0xC2,0xF8,0x3C,0x0D,0xF3,0xBF,0x40,0xEA,0xF7,0xC8,0x52,0xD1, -0x72,0x6F,0xEF,0xC8,0xAB,0x41,0xB8,0x6E,0x2E,0x17,0x2A,0x95,0x69,0x0C,0xCD,0xD2, -0x1E,0x94,0x7B,0x2D,0x94,0x1D,0xAA,0x75,0xD7,0xB3,0x98,0xCB,0xAC,0xBC,0x64,0x53, -0x40,0xBC,0x8F,0xAC,0xAC,0x36,0xCB,0x5C,0xAD,0xBB,0xDD,0xE0,0x94,0x17,0xEC,0xD1, -0x5C,0xD0,0xBF,0xEF,0xA5,0x95,0xC9,0x90,0xC5,0xB0,0xAC,0xFB,0x1B,0x43,0xDF,0x7A, -0x08,0x5D,0xB7,0xB8,0xF2,0x40,0x1B,0x2B,0x27,0x9E,0x50,0xCE,0x5E,0x65,0x82,0x88, -0x8C,0x5E,0xD3,0x4E,0x0C,0x7A,0xEA,0x08,0x91,0xB6,0x36,0xAA,0x2B,0x42,0xFB,0xEA, -0xC2,0xA3,0x39,0xE5,0xDB,0x26,0x38,0xAD,0x8B,0x0A,0xEE,0x19,0x63,0xC7,0x1C,0x24, -0xDF,0x03,0x78,0xDA,0xE6,0xEA,0xC1,0x47,0x1A,0x0B,0x0B,0x46,0x09,0xDD,0x02,0xFC, -0xDE,0xCB,0x87,0x5F,0xD7,0x30,0x63,0x68,0xA1,0xAE,0xDC,0x32,0xA1,0xBA,0xBE,0xFE, -0x44,0xAB,0x68,0xB6,0xA5,0x17,0x15,0xFD,0xBD,0xD5,0xA7,0xA7,0x9A,0xE4,0x44,0x33, -0xE9,0x88,0x8E,0xFC,0xED,0x51,0xEB,0x93,0x71,0x4E,0xAD,0x01,0xE7,0x44,0x8E,0xAB, -0x2D,0xCB,0xA8,0xFE,0x01,0x49,0x48,0xF0,0xC0,0xDD,0xC7,0x68,0xD8,0x92,0xFE,0x3D, -0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xC7,0x30,0x81,0xC4,0x30,0x1D,0x06,0x03,0x55, -0x1D,0x0E,0x04,0x16,0x04,0x14,0x3C,0xD8,0x93,0x88,0xC2,0xC0,0x82,0x09,0xCC,0x01, -0x99,0x06,0x93,0x20,0xE9,0x9E,0x70,0x09,0x63,0x4F,0x30,0x0E,0x06,0x03,0x55,0x1D, -0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D, -0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x81,0x81,0x06,0x03, -0x55,0x1D,0x1F,0x04,0x7A,0x30,0x78,0x30,0x3B,0xA0,0x39,0xA0,0x37,0x86,0x35,0x68, -0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F, -0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x53,0x65,0x63,0x75,0x72,0x65,0x43,0x65,0x72, -0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73, -0x2E,0x63,0x72,0x6C,0x30,0x39,0xA0,0x37,0xA0,0x35,0x86,0x33,0x68,0x74,0x74,0x70, -0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65, -0x74,0x2F,0x53,0x65,0x63,0x75,0x72,0x65,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, -0x61,0x74,0x65,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2E,0x63,0x72,0x6C,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82, -0x01,0x01,0x00,0x87,0x01,0x6D,0x23,0x1D,0x7E,0x5B,0x17,0x7D,0xC1,0x61,0x32,0xCF, -0x8F,0xE7,0xF3,0x8A,0x94,0x59,0x66,0xE0,0x9E,0x28,0xA8,0x5E,0xD3,0xB7,0xF4,0x34, -0xE6,0xAA,0x39,0xB2,0x97,0x16,0xC5,0x82,0x6F,0x32,0xA4,0xE9,0x8C,0xE7,0xAF,0xFD, -0xEF,0xC2,0xE8,0xB9,0x4B,0xAA,0xA3,0xF4,0xE6,0xDA,0x8D,0x65,0x21,0xFB,0xBA,0x80, -0xEB,0x26,0x28,0x85,0x1A,0xFE,0x39,0x8C,0xDE,0x5B,0x04,0x04,0xB4,0x54,0xF9,0xA3, -0x67,0x9E,0x41,0xFA,0x09,0x52,0xCC,0x05,0x48,0xA8,0xC9,0x3F,0x21,0x04,0x1E,0xCE, -0x48,0x6B,0xFC,0x85,0xE8,0xC2,0x7B,0xAF,0x7F,0xB7,0xCC,0xF8,0x5F,0x3A,0xFD,0x35, -0xC6,0x0D,0xEF,0x97,0xDC,0x4C,0xAB,0x11,0xE1,0x6B,0xCB,0x31,0xD1,0x6C,0xFB,0x48, -0x80,0xAB,0xDC,0x9C,0x37,0xB8,0x21,0x14,0x4B,0x0D,0x71,0x3D,0xEC,0x83,0x33,0x6E, -0xD1,0x6E,0x32,0x16,0xEC,0x98,0xC7,0x16,0x8B,0x59,0xA6,0x34,0xAB,0x05,0x57,0x2D, -0x93,0xF7,0xAA,0x13,0xCB,0xD2,0x13,0xE2,0xB7,0x2E,0x3B,0xCD,0x6B,0x50,0x17,0x09, -0x68,0x3E,0xB5,0x26,0x57,0xEE,0xB6,0xE0,0xB6,0xDD,0xB9,0x29,0x80,0x79,0x7D,0x8F, -0xA3,0xF0,0xA4,0x28,0xA4,0x15,0xC4,0x85,0xF4,0x27,0xD4,0x6B,0xBF,0xE5,0x5C,0xE4, -0x65,0x02,0x76,0x54,0xB4,0xE3,0x37,0x66,0x24,0xD3,0x19,0x61,0xC8,0x52,0x10,0xE5, -0x8B,0x37,0x9A,0xB9,0xA9,0xF9,0x1D,0xBF,0xEA,0x99,0x92,0x61,0x96,0xFF,0x01,0xCD, -0xA1,0x5F,0x0D,0xBC,0x71,0xBC,0x0E,0xAC,0x0B,0x1D,0x47,0x45,0x1D,0xC1,0xEC,0x7C, -0xEC,0xFD,0x29, -}; - - -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=Trusted Certificate Services */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=Trusted Certificate Services */ - - -const unsigned char Comodo_Trusted_Services_root_certificate[1095]={ -0x30,0x82,0x04,0x43,0x30,0x82,0x03,0x2B,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x7F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B, -0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x0C,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72, -0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06, -0x03,0x55,0x04,0x07,0x0C,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30, -0x18,0x06,0x03,0x55,0x04,0x0A,0x0C,0x11,0x43,0x6F,0x6D,0x6F,0x64,0x6F,0x20,0x43, -0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x25,0x30,0x23,0x06,0x03,0x55, -0x04,0x03,0x0C,0x1C,0x54,0x72,0x75,0x73,0x74,0x65,0x64,0x20,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73, -0x30,0x1E,0x17,0x0D,0x30,0x34,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30, -0x5A,0x17,0x0D,0x32,0x38,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A, -0x30,0x7F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31, -0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x0C,0x12,0x47,0x72,0x65,0x61,0x74,0x65, -0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E, -0x06,0x03,0x55,0x04,0x07,0x0C,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A, -0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x0C,0x11,0x43,0x6F,0x6D,0x6F,0x64,0x6F,0x20, -0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x25,0x30,0x23,0x06,0x03, -0x55,0x04,0x03,0x0C,0x1C,0x54,0x72,0x75,0x73,0x74,0x65,0x64,0x20,0x43,0x65,0x72, -0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65, -0x73,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01, -0x01,0x00,0xDF,0x71,0x6F,0x36,0x58,0x53,0x5A,0xF2,0x36,0x54,0x57,0x80,0xC4,0x74, -0x08,0x20,0xED,0x18,0x7F,0x2A,0x1D,0xE6,0x35,0x9A,0x1E,0x25,0xAC,0x9C,0xE5,0x96, -0x7E,0x72,0x52,0xA0,0x15,0x42,0xDB,0x59,0xDD,0x64,0x7A,0x1A,0xD0,0xB8,0x7B,0xDD, -0x39,0x15,0xBC,0x55,0x48,0xC4,0xED,0x3A,0x00,0xEA,0x31,0x11,0xBA,0xF2,0x71,0x74, -0x1A,0x67,0xB8,0xCF,0x33,0xCC,0xA8,0x31,0xAF,0xA3,0xE3,0xD7,0x7F,0xBF,0x33,0x2D, -0x4C,0x6A,0x3C,0xEC,0x8B,0xC3,0x92,0xD2,0x53,0x77,0x24,0x74,0x9C,0x07,0x6E,0x70, -0xFC,0xBD,0x0B,0x5B,0x76,0xBA,0x5F,0xF2,0xFF,0xD7,0x37,0x4B,0x4A,0x60,0x78,0xF7, -0xF0,0xFA,0xCA,0x70,0xB4,0xEA,0x59,0xAA,0xA3,0xCE,0x48,0x2F,0xA9,0xC3,0xB2,0x0B, -0x7E,0x17,0x72,0x16,0x0C,0xA6,0x07,0x0C,0x1B,0x38,0xCF,0xC9,0x62,0xB7,0x3F,0xA0, -0x93,0xA5,0x87,0x41,0xF2,0xB7,0x70,0x40,0x77,0xD8,0xBE,0x14,0x7C,0xE3,0xA8,0xC0, -0x7A,0x8E,0xE9,0x63,0x6A,0xD1,0x0F,0x9A,0xC6,0xD2,0xF4,0x8B,0x3A,0x14,0x04,0x56, -0xD4,0xED,0xB8,0xCC,0x6E,0xF5,0xFB,0xE2,0x2C,0x58,0xBD,0x7F,0x4F,0x6B,0x2B,0xF7, -0x60,0x24,0x58,0x24,0xCE,0x26,0xEF,0x34,0x91,0x3A,0xD5,0xE3,0x81,0xD0,0xB2,0xF0, -0x04,0x02,0xD7,0x5B,0xB7,0x3E,0x92,0xAC,0x6B,0x12,0x8A,0xF9,0xE4,0x05,0xB0,0x3B, -0x91,0x49,0x5C,0xB2,0xEB,0x53,0xEA,0xF8,0x9F,0x47,0x86,0xEE,0xBF,0x95,0xC0,0xC0, -0x06,0x9F,0xD2,0x5B,0x5E,0x11,0x1B,0xF4,0xC7,0x04,0x35,0x29,0xD2,0x55,0x5C,0xE4, -0xED,0xEB,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xC9,0x30,0x81,0xC6,0x30,0x1D,0x06, -0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xC5,0x7B,0x58,0xBD,0xED,0xDA,0x25,0x69, -0xD2,0xF7,0x59,0x16,0xA8,0xB3,0x32,0xC0,0x7B,0x27,0x5B,0xF4,0x30,0x0E,0x06,0x03, -0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03, -0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x81,0x83, -0x06,0x03,0x55,0x1D,0x1F,0x04,0x7C,0x30,0x7A,0x30,0x3C,0xA0,0x3A,0xA0,0x38,0x86, -0x36,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F, -0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x54,0x72,0x75,0x73,0x74,0x65,0x64, -0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x65,0x72,0x76,0x69, -0x63,0x65,0x73,0x2E,0x63,0x72,0x6C,0x30,0x3A,0xA0,0x38,0xA0,0x36,0x86,0x34,0x68, -0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F, -0x2E,0x6E,0x65,0x74,0x2F,0x54,0x72,0x75,0x73,0x74,0x65,0x64,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2E, -0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xC8,0x93,0x81,0x3B,0x89,0xB4,0xAF,0xB8,0x84, -0x12,0x4C,0x8D,0xD2,0xF0,0xDB,0x70,0xBA,0x57,0x86,0x15,0x34,0x10,0xB9,0x2F,0x7F, -0x1E,0xB0,0xA8,0x89,0x60,0xA1,0x8A,0xC2,0x77,0x0C,0x50,0x4A,0x9B,0x00,0x8B,0xD8, -0x8B,0xF4,0x41,0xE2,0xD0,0x83,0x8A,0x4A,0x1C,0x14,0x06,0xB0,0xA3,0x68,0x05,0x70, -0x31,0x30,0xA7,0x53,0x9B,0x0E,0xE9,0x4A,0xA0,0x58,0x69,0x67,0x0E,0xAE,0x9D,0xF6, -0xA5,0x2C,0x41,0xBF,0x3C,0x06,0x6B,0xE4,0x59,0xCC,0x6D,0x10,0xF1,0x96,0x6F,0x1F, -0xDF,0xF4,0x04,0x02,0xA4,0x9F,0x45,0x3E,0xC8,0xD8,0xFA,0x36,0x46,0x44,0x50,0x3F, -0x82,0x97,0x91,0x1F,0x28,0xDB,0x18,0x11,0x8C,0x2A,0xE4,0x65,0x83,0x57,0x12,0x12, -0x8C,0x17,0x3F,0x94,0x36,0xFE,0x5D,0xB0,0xC0,0x04,0x77,0x13,0xB8,0xF4,0x15,0xD5, -0x3F,0x38,0xCC,0x94,0x3A,0x55,0xD0,0xAC,0x98,0xF5,0xBA,0x00,0x5F,0xE0,0x86,0x19, -0x81,0x78,0x2F,0x28,0xC0,0x7E,0xD3,0xCC,0x42,0x0A,0xF5,0xAE,0x50,0xA0,0xD1,0x3E, -0xC6,0xA1,0x71,0xEC,0x3F,0xA0,0x20,0x8C,0x66,0x3A,0x89,0xB4,0x8E,0xD4,0xD8,0xB1, -0x4D,0x25,0x47,0xEE,0x2F,0x88,0xC8,0xB5,0xE1,0x05,0x45,0xC0,0xBE,0x14,0x71,0xDE, -0x7A,0xFD,0x8E,0x7B,0x7D,0x4D,0x08,0x96,0xA5,0x12,0x73,0xF0,0x2D,0xCA,0x37,0x27, -0x74,0x12,0x27,0x4C,0xCB,0xB6,0x97,0xE9,0xD9,0xAE,0x08,0x6D,0x5A,0x39,0x40,0xDD, -0x05,0x47,0x75,0x6A,0x5A,0x21,0xB3,0xA3,0x18,0xCF,0x4E,0xF7,0x2E,0x57,0xB7,0x98, -0x70,0x5E,0xC8,0xC4,0x78,0xB0,0x62, -}; - - -/* subject:/O=Cybertrust, Inc/CN=Cybertrust Global Root */ -/* issuer :/O=Cybertrust, Inc/CN=Cybertrust Global Root */ - - -const unsigned char Cybertrust_Global_Root_certificate[933]={ -0x30,0x82,0x03,0xA1,0x30,0x82,0x02,0x89,0xA0,0x03,0x02,0x01,0x02,0x02,0x0B,0x04, -0x00,0x00,0x00,0x00,0x01,0x0F,0x85,0xAA,0x2D,0x48,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x3B,0x31,0x18,0x30,0x16,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0F,0x43,0x79,0x62,0x65,0x72,0x74,0x72,0x75,0x73,0x74, -0x2C,0x20,0x49,0x6E,0x63,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x13,0x16, -0x43,0x79,0x62,0x65,0x72,0x74,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61, -0x6C,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x31,0x35, -0x30,0x38,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x31,0x31,0x32,0x31,0x35,0x30, -0x38,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x18,0x30,0x16,0x06,0x03,0x55,0x04, -0x0A,0x13,0x0F,0x43,0x79,0x62,0x65,0x72,0x74,0x72,0x75,0x73,0x74,0x2C,0x20,0x49, -0x6E,0x63,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x13,0x16,0x43,0x79,0x62, -0x65,0x72,0x74,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52, -0x6F,0x6F,0x74,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02, -0x82,0x01,0x01,0x00,0xF8,0xC8,0xBC,0xBD,0x14,0x50,0x66,0x13,0xFF,0xF0,0xD3,0x79, -0xEC,0x23,0xF2,0xB7,0x1A,0xC7,0x8E,0x85,0xF1,0x12,0x73,0xA6,0x19,0xAA,0x10,0xDB, -0x9C,0xA2,0x65,0x74,0x5A,0x77,0x3E,0x51,0x7D,0x56,0xF6,0xDC,0x23,0xB6,0xD4,0xED, -0x5F,0x58,0xB1,0x37,0x4D,0xD5,0x49,0x0E,0x6E,0xF5,0x6A,0x87,0xD6,0xD2,0x8C,0xD2, -0x27,0xC6,0xE2,0xFF,0x36,0x9F,0x98,0x65,0xA0,0x13,0x4E,0xC6,0x2A,0x64,0x9B,0xD5, -0x90,0x12,0xCF,0x14,0x06,0xF4,0x3B,0xE3,0xD4,0x28,0xBE,0xE8,0x0E,0xF8,0xAB,0x4E, -0x48,0x94,0x6D,0x8E,0x95,0x31,0x10,0x5C,0xED,0xA2,0x2D,0xBD,0xD5,0x3A,0x6D,0xB2, -0x1C,0xBB,0x60,0xC0,0x46,0x4B,0x01,0xF5,0x49,0xAE,0x7E,0x46,0x8A,0xD0,0x74,0x8D, -0xA1,0x0C,0x02,0xCE,0xEE,0xFC,0xE7,0x8F,0xB8,0x6B,0x66,0xF3,0x7F,0x44,0x00,0xBF, -0x66,0x25,0x14,0x2B,0xDD,0x10,0x30,0x1D,0x07,0x96,0x3F,0x4D,0xF6,0x6B,0xB8,0x8F, -0xB7,0x7B,0x0C,0xA5,0x38,0xEB,0xDE,0x47,0xDB,0xD5,0x5D,0x39,0xFC,0x88,0xA7,0xF3, -0xD7,0x2A,0x74,0xF1,0xE8,0x5A,0xA2,0x3B,0x9F,0x50,0xBA,0xA6,0x8C,0x45,0x35,0xC2, -0x50,0x65,0x95,0xDC,0x63,0x82,0xEF,0xDD,0xBF,0x77,0x4D,0x9C,0x62,0xC9,0x63,0x73, -0x16,0xD0,0x29,0x0F,0x49,0xA9,0x48,0xF0,0xB3,0xAA,0xB7,0x6C,0xC5,0xA7,0x30,0x39, -0x40,0x5D,0xAE,0xC4,0xE2,0x5D,0x26,0x53,0xF0,0xCE,0x1C,0x23,0x08,0x61,0xA8,0x94, -0x19,0xBA,0x04,0x62,0x40,0xEC,0x1F,0x38,0x70,0x77,0x12,0x06,0x71,0xA7,0x30,0x18, -0x5D,0x25,0x27,0xA5,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xA5,0x30,0x81,0xA2,0x30, -0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30, -0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF, -0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xB6,0x08,0x7B,0x0D,0x7A, -0xCC,0xAC,0x20,0x4C,0x86,0x56,0x32,0x5E,0xCF,0xAB,0x6E,0x85,0x2D,0x70,0x57,0x30, -0x3F,0x06,0x03,0x55,0x1D,0x1F,0x04,0x38,0x30,0x36,0x30,0x34,0xA0,0x32,0xA0,0x30, -0x86,0x2E,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x32,0x2E,0x70,0x75, -0x62,0x6C,0x69,0x63,0x2D,0x74,0x72,0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x63, -0x72,0x6C,0x2F,0x63,0x74,0x2F,0x63,0x74,0x72,0x6F,0x6F,0x74,0x2E,0x63,0x72,0x6C, -0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xB6,0x08,0x7B, -0x0D,0x7A,0xCC,0xAC,0x20,0x4C,0x86,0x56,0x32,0x5E,0xCF,0xAB,0x6E,0x85,0x2D,0x70, -0x57,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00, -0x03,0x82,0x01,0x01,0x00,0x56,0xEF,0x0A,0x23,0xA0,0x54,0x4E,0x95,0x97,0xC9,0xF8, -0x89,0xDA,0x45,0xC1,0xD4,0xA3,0x00,0x25,0xF4,0x1F,0x13,0xAB,0xB7,0xA3,0x85,0x58, -0x69,0xC2,0x30,0xAD,0xD8,0x15,0x8A,0x2D,0xE3,0xC9,0xCD,0x81,0x5A,0xF8,0x73,0x23, -0x5A,0xA7,0x7C,0x05,0xF3,0xFD,0x22,0x3B,0x0E,0xD1,0x06,0xC4,0xDB,0x36,0x4C,0x73, -0x04,0x8E,0xE5,0xB0,0x22,0xE4,0xC5,0xF3,0x2E,0xA5,0xD9,0x23,0xE3,0xB8,0x4E,0x4A, -0x20,0xA7,0x6E,0x02,0x24,0x9F,0x22,0x60,0x67,0x7B,0x8B,0x1D,0x72,0x09,0xC5,0x31, -0x5C,0xE9,0x79,0x9F,0x80,0x47,0x3D,0xAD,0xA1,0x0B,0x07,0x14,0x3D,0x47,0xFF,0x03, -0x69,0x1A,0x0C,0x0B,0x44,0xE7,0x63,0x25,0xA7,0x7F,0xB2,0xC9,0xB8,0x76,0x84,0xED, -0x23,0xF6,0x7D,0x07,0xAB,0x45,0x7E,0xD3,0xDF,0xB3,0xBF,0xE9,0x8A,0xB6,0xCD,0xA8, -0xA2,0x67,0x2B,0x52,0xD5,0xB7,0x65,0xF0,0x39,0x4C,0x63,0xA0,0x91,0x79,0x93,0x52, -0x0F,0x54,0xDD,0x83,0xBB,0x9F,0xD1,0x8F,0xA7,0x53,0x73,0xC3,0xCB,0xFF,0x30,0xEC, -0x7C,0x04,0xB8,0xD8,0x44,0x1F,0x93,0x5F,0x71,0x09,0x22,0xB7,0x6E,0x3E,0xEA,0x1C, -0x03,0x4E,0x9D,0x1A,0x20,0x61,0xFB,0x81,0x37,0xEC,0x5E,0xFC,0x0A,0x45,0xAB,0xD7, -0xE7,0x17,0x55,0xD0,0xA0,0xEA,0x60,0x9B,0xA6,0xF6,0xE3,0x8C,0x5B,0x29,0xC2,0x06, -0x60,0x14,0x9D,0x2D,0x97,0x4C,0xA9,0x93,0x15,0x9D,0x61,0xC4,0x01,0x5F,0x48,0xD6, -0x58,0xBD,0x56,0x31,0x12,0x4E,0x11,0xC8,0x21,0xE0,0xB3,0x11,0x91,0x65,0xDB,0xB4, -0xA6,0x88,0x38,0xCE,0x55, -}; - - -/* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA */ -/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA */ - - -const unsigned char DigiCert_Assured_ID_Root_CA_certificate[955]={ -0x30,0x82,0x03,0xB7,0x30,0x82,0x02,0x9F,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x0C, -0xE7,0xE0,0xE5,0x17,0xD8,0x46,0xFE,0x8F,0xE5,0x60,0xFC,0x1B,0xF0,0x30,0x39,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x65, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, -0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, -0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77, -0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31, -0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x03,0x13,0x1B,0x44,0x69,0x67,0x69,0x43,0x65, -0x72,0x74,0x20,0x41,0x73,0x73,0x75,0x72,0x65,0x64,0x20,0x49,0x44,0x20,0x52,0x6F, -0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31,0x31,0x30,0x30, -0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x31,0x31,0x31,0x31,0x30,0x30,0x30, -0x30,0x30,0x30,0x30,0x5A,0x30,0x65,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, -0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44, -0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06, -0x03,0x55,0x04,0x0B,0x13,0x10,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65, -0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x03,0x13, -0x1B,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x41,0x73,0x73,0x75,0x72,0x65, -0x64,0x20,0x49,0x44,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03, -0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xAD,0x0E,0x15, -0xCE,0xE4,0x43,0x80,0x5C,0xB1,0x87,0xF3,0xB7,0x60,0xF9,0x71,0x12,0xA5,0xAE,0xDC, -0x26,0x94,0x88,0xAA,0xF4,0xCE,0xF5,0x20,0x39,0x28,0x58,0x60,0x0C,0xF8,0x80,0xDA, -0xA9,0x15,0x95,0x32,0x61,0x3C,0xB5,0xB1,0x28,0x84,0x8A,0x8A,0xDC,0x9F,0x0A,0x0C, -0x83,0x17,0x7A,0x8F,0x90,0xAC,0x8A,0xE7,0x79,0x53,0x5C,0x31,0x84,0x2A,0xF6,0x0F, -0x98,0x32,0x36,0x76,0xCC,0xDE,0xDD,0x3C,0xA8,0xA2,0xEF,0x6A,0xFB,0x21,0xF2,0x52, -0x61,0xDF,0x9F,0x20,0xD7,0x1F,0xE2,0xB1,0xD9,0xFE,0x18,0x64,0xD2,0x12,0x5B,0x5F, -0xF9,0x58,0x18,0x35,0xBC,0x47,0xCD,0xA1,0x36,0xF9,0x6B,0x7F,0xD4,0xB0,0x38,0x3E, -0xC1,0x1B,0xC3,0x8C,0x33,0xD9,0xD8,0x2F,0x18,0xFE,0x28,0x0F,0xB3,0xA7,0x83,0xD6, -0xC3,0x6E,0x44,0xC0,0x61,0x35,0x96,0x16,0xFE,0x59,0x9C,0x8B,0x76,0x6D,0xD7,0xF1, -0xA2,0x4B,0x0D,0x2B,0xFF,0x0B,0x72,0xDA,0x9E,0x60,0xD0,0x8E,0x90,0x35,0xC6,0x78, -0x55,0x87,0x20,0xA1,0xCF,0xE5,0x6D,0x0A,0xC8,0x49,0x7C,0x31,0x98,0x33,0x6C,0x22, -0xE9,0x87,0xD0,0x32,0x5A,0xA2,0xBA,0x13,0x82,0x11,0xED,0x39,0x17,0x9D,0x99,0x3A, -0x72,0xA1,0xE6,0xFA,0xA4,0xD9,0xD5,0x17,0x31,0x75,0xAE,0x85,0x7D,0x22,0xAE,0x3F, -0x01,0x46,0x86,0xF6,0x28,0x79,0xC8,0xB1,0xDA,0xE4,0x57,0x17,0xC4,0x7E,0x1C,0x0E, -0xB0,0xB4,0x92,0xA6,0x56,0xB3,0xBD,0xB2,0x97,0xED,0xAA,0xA7,0xF0,0xB7,0xC5,0xA8, -0x3F,0x95,0x16,0xD0,0xFF,0xA1,0x96,0xEB,0x08,0x5F,0x18,0x77,0x4F,0x02,0x03,0x01, -0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF, -0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF, -0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, -0x04,0x14,0x45,0xEB,0xA2,0xAF,0xF4,0x92,0xCB,0x82,0x31,0x2D,0x51,0x8B,0xA7,0xA7, -0x21,0x9D,0xF3,0x6D,0xC8,0x0F,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30, -0x16,0x80,0x14,0x45,0xEB,0xA2,0xAF,0xF4,0x92,0xCB,0x82,0x31,0x2D,0x51,0x8B,0xA7, -0xA7,0x21,0x9D,0xF3,0x6D,0xC8,0x0F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xA2,0x0E,0xBC,0xDF,0xE2, -0xED,0xF0,0xE3,0x72,0x73,0x7A,0x64,0x94,0xBF,0xF7,0x72,0x66,0xD8,0x32,0xE4,0x42, -0x75,0x62,0xAE,0x87,0xEB,0xF2,0xD5,0xD9,0xDE,0x56,0xB3,0x9F,0xCC,0xCE,0x14,0x28, -0xB9,0x0D,0x97,0x60,0x5C,0x12,0x4C,0x58,0xE4,0xD3,0x3D,0x83,0x49,0x45,0x58,0x97, -0x35,0x69,0x1A,0xA8,0x47,0xEA,0x56,0xC6,0x79,0xAB,0x12,0xD8,0x67,0x81,0x84,0xDF, -0x7F,0x09,0x3C,0x94,0xE6,0xB8,0x26,0x2C,0x20,0xBD,0x3D,0xB3,0x28,0x89,0xF7,0x5F, -0xFF,0x22,0xE2,0x97,0x84,0x1F,0xE9,0x65,0xEF,0x87,0xE0,0xDF,0xC1,0x67,0x49,0xB3, -0x5D,0xEB,0xB2,0x09,0x2A,0xEB,0x26,0xED,0x78,0xBE,0x7D,0x3F,0x2B,0xF3,0xB7,0x26, -0x35,0x6D,0x5F,0x89,0x01,0xB6,0x49,0x5B,0x9F,0x01,0x05,0x9B,0xAB,0x3D,0x25,0xC1, -0xCC,0xB6,0x7F,0xC2,0xF1,0x6F,0x86,0xC6,0xFA,0x64,0x68,0xEB,0x81,0x2D,0x94,0xEB, -0x42,0xB7,0xFA,0x8C,0x1E,0xDD,0x62,0xF1,0xBE,0x50,0x67,0xB7,0x6C,0xBD,0xF3,0xF1, -0x1F,0x6B,0x0C,0x36,0x07,0x16,0x7F,0x37,0x7C,0xA9,0x5B,0x6D,0x7A,0xF1,0x12,0x46, -0x60,0x83,0xD7,0x27,0x04,0xBE,0x4B,0xCE,0x97,0xBE,0xC3,0x67,0x2A,0x68,0x11,0xDF, -0x80,0xE7,0x0C,0x33,0x66,0xBF,0x13,0x0D,0x14,0x6E,0xF3,0x7F,0x1F,0x63,0x10,0x1E, -0xFA,0x8D,0x1B,0x25,0x6D,0x6C,0x8F,0xA5,0xB7,0x61,0x01,0xB1,0xD2,0xA3,0x26,0xA1, -0x10,0x71,0x9D,0xAD,0xE2,0xC3,0xF9,0xC3,0x99,0x51,0xB7,0x2B,0x07,0x08,0xCE,0x2E, -0xE6,0x50,0xB2,0xA7,0xFA,0x0A,0x45,0x2F,0xA2,0xF0,0xF2, -}; - - -/* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ -/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ - - -const unsigned char DigiCert_Global_Root_CA_certificate[947]={ -0x30,0x82,0x03,0xAF,0x30,0x82,0x02,0x97,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x08, -0x3B,0xE0,0x56,0x90,0x42,0x46,0xB1,0xA1,0x75,0x6A,0xC9,0x59,0x91,0xC7,0x4A,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x61, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, -0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, -0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77, -0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31, -0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,0x69,0x43,0x65, -0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, -0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30, -0x30,0x5A,0x17,0x0D,0x33,0x31,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30, -0x5A,0x30,0x61,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, -0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43, -0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B, -0x13,0x10,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63, -0x6F,0x6D,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67, -0x69,0x43,0x65,0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F, -0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A, -0x02,0x82,0x01,0x01,0x00,0xE2,0x3B,0xE1,0x11,0x72,0xDE,0xA8,0xA4,0xD3,0xA3,0x57, -0xAA,0x50,0xA2,0x8F,0x0B,0x77,0x90,0xC9,0xA2,0xA5,0xEE,0x12,0xCE,0x96,0x5B,0x01, -0x09,0x20,0xCC,0x01,0x93,0xA7,0x4E,0x30,0xB7,0x53,0xF7,0x43,0xC4,0x69,0x00,0x57, -0x9D,0xE2,0x8D,0x22,0xDD,0x87,0x06,0x40,0x00,0x81,0x09,0xCE,0xCE,0x1B,0x83,0xBF, -0xDF,0xCD,0x3B,0x71,0x46,0xE2,0xD6,0x66,0xC7,0x05,0xB3,0x76,0x27,0x16,0x8F,0x7B, -0x9E,0x1E,0x95,0x7D,0xEE,0xB7,0x48,0xA3,0x08,0xDA,0xD6,0xAF,0x7A,0x0C,0x39,0x06, -0x65,0x7F,0x4A,0x5D,0x1F,0xBC,0x17,0xF8,0xAB,0xBE,0xEE,0x28,0xD7,0x74,0x7F,0x7A, -0x78,0x99,0x59,0x85,0x68,0x6E,0x5C,0x23,0x32,0x4B,0xBF,0x4E,0xC0,0xE8,0x5A,0x6D, -0xE3,0x70,0xBF,0x77,0x10,0xBF,0xFC,0x01,0xF6,0x85,0xD9,0xA8,0x44,0x10,0x58,0x32, -0xA9,0x75,0x18,0xD5,0xD1,0xA2,0xBE,0x47,0xE2,0x27,0x6A,0xF4,0x9A,0x33,0xF8,0x49, -0x08,0x60,0x8B,0xD4,0x5F,0xB4,0x3A,0x84,0xBF,0xA1,0xAA,0x4A,0x4C,0x7D,0x3E,0xCF, -0x4F,0x5F,0x6C,0x76,0x5E,0xA0,0x4B,0x37,0x91,0x9E,0xDC,0x22,0xE6,0x6D,0xCE,0x14, -0x1A,0x8E,0x6A,0xCB,0xFE,0xCD,0xB3,0x14,0x64,0x17,0xC7,0x5B,0x29,0x9E,0x32,0xBF, -0xF2,0xEE,0xFA,0xD3,0x0B,0x42,0xD4,0xAB,0xB7,0x41,0x32,0xDA,0x0C,0xD4,0xEF,0xF8, -0x81,0xD5,0xBB,0x8D,0x58,0x3F,0xB5,0x1B,0xE8,0x49,0x28,0xA2,0x70,0xDA,0x31,0x04, -0xDD,0xF7,0xB2,0x16,0xF2,0x4C,0x0A,0x4E,0x07,0xA8,0xED,0x4A,0x3D,0x5E,0xB5,0x7F, -0xA3,0x90,0xC3,0xAF,0x27,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0E, -0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F, -0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30, -0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x03,0xDE,0x50,0x35,0x56,0xD1, -0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30,0x1F, -0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x03,0xDE,0x50,0x35,0x56, -0xD1,0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82, -0x01,0x01,0x00,0xCB,0x9C,0x37,0xAA,0x48,0x13,0x12,0x0A,0xFA,0xDD,0x44,0x9C,0x4F, -0x52,0xB0,0xF4,0xDF,0xAE,0x04,0xF5,0x79,0x79,0x08,0xA3,0x24,0x18,0xFC,0x4B,0x2B, -0x84,0xC0,0x2D,0xB9,0xD5,0xC7,0xFE,0xF4,0xC1,0x1F,0x58,0xCB,0xB8,0x6D,0x9C,0x7A, -0x74,0xE7,0x98,0x29,0xAB,0x11,0xB5,0xE3,0x70,0xA0,0xA1,0xCD,0x4C,0x88,0x99,0x93, -0x8C,0x91,0x70,0xE2,0xAB,0x0F,0x1C,0xBE,0x93,0xA9,0xFF,0x63,0xD5,0xE4,0x07,0x60, -0xD3,0xA3,0xBF,0x9D,0x5B,0x09,0xF1,0xD5,0x8E,0xE3,0x53,0xF4,0x8E,0x63,0xFA,0x3F, -0xA7,0xDB,0xB4,0x66,0xDF,0x62,0x66,0xD6,0xD1,0x6E,0x41,0x8D,0xF2,0x2D,0xB5,0xEA, -0x77,0x4A,0x9F,0x9D,0x58,0xE2,0x2B,0x59,0xC0,0x40,0x23,0xED,0x2D,0x28,0x82,0x45, -0x3E,0x79,0x54,0x92,0x26,0x98,0xE0,0x80,0x48,0xA8,0x37,0xEF,0xF0,0xD6,0x79,0x60, -0x16,0xDE,0xAC,0xE8,0x0E,0xCD,0x6E,0xAC,0x44,0x17,0x38,0x2F,0x49,0xDA,0xE1,0x45, -0x3E,0x2A,0xB9,0x36,0x53,0xCF,0x3A,0x50,0x06,0xF7,0x2E,0xE8,0xC4,0x57,0x49,0x6C, -0x61,0x21,0x18,0xD5,0x04,0xAD,0x78,0x3C,0x2C,0x3A,0x80,0x6B,0xA7,0xEB,0xAF,0x15, -0x14,0xE9,0xD8,0x89,0xC1,0xB9,0x38,0x6C,0xE2,0x91,0x6C,0x8A,0xFF,0x64,0xB9,0x77, -0x25,0x57,0x30,0xC0,0x1B,0x24,0xA3,0xE1,0xDC,0xE9,0xDF,0x47,0x7C,0xB5,0xB4,0x24, -0x08,0x05,0x30,0xEC,0x2D,0xBD,0x0B,0xBF,0x45,0xBF,0x50,0xB9,0xA9,0xF3,0xEB,0x98, -0x01,0x12,0xAD,0xC8,0x88,0xC6,0x98,0x34,0x5F,0x8D,0x0A,0x3C,0xC6,0xE9,0xD5,0x95, -0x95,0x6D,0xDE, -}; - - -/* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA */ -/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA */ - - -const unsigned char DigiCert_High_Assurance_EV_Root_CA_certificate[969]={ -0x30,0x82,0x03,0xC5,0x30,0x82,0x02,0xAD,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x02, -0xAC,0x5C,0x26,0x6A,0x0B,0x40,0x9B,0x8F,0x0B,0x79,0xF2,0xAE,0x46,0x25,0x77,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x6C, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, -0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, -0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77, -0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31, -0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x44,0x69,0x67,0x69,0x43,0x65, -0x72,0x74,0x20,0x48,0x69,0x67,0x68,0x20,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63, -0x65,0x20,0x45,0x56,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D, -0x30,0x36,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33, -0x31,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x6C,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x49, -0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77,0x77,0x77, -0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31,0x2B,0x30, -0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, -0x20,0x48,0x69,0x67,0x68,0x20,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63,0x65,0x20, -0x45,0x56,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D, -0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01, -0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xC6,0xCC,0xE5,0x73,0xE6, -0xFB,0xD4,0xBB,0xE5,0x2D,0x2D,0x32,0xA6,0xDF,0xE5,0x81,0x3F,0xC9,0xCD,0x25,0x49, -0xB6,0x71,0x2A,0xC3,0xD5,0x94,0x34,0x67,0xA2,0x0A,0x1C,0xB0,0x5F,0x69,0xA6,0x40, -0xB1,0xC4,0xB7,0xB2,0x8F,0xD0,0x98,0xA4,0xA9,0x41,0x59,0x3A,0xD3,0xDC,0x94,0xD6, -0x3C,0xDB,0x74,0x38,0xA4,0x4A,0xCC,0x4D,0x25,0x82,0xF7,0x4A,0xA5,0x53,0x12,0x38, -0xEE,0xF3,0x49,0x6D,0x71,0x91,0x7E,0x63,0xB6,0xAB,0xA6,0x5F,0xC3,0xA4,0x84,0xF8, -0x4F,0x62,0x51,0xBE,0xF8,0xC5,0xEC,0xDB,0x38,0x92,0xE3,0x06,0xE5,0x08,0x91,0x0C, -0xC4,0x28,0x41,0x55,0xFB,0xCB,0x5A,0x89,0x15,0x7E,0x71,0xE8,0x35,0xBF,0x4D,0x72, -0x09,0x3D,0xBE,0x3A,0x38,0x50,0x5B,0x77,0x31,0x1B,0x8D,0xB3,0xC7,0x24,0x45,0x9A, -0xA7,0xAC,0x6D,0x00,0x14,0x5A,0x04,0xB7,0xBA,0x13,0xEB,0x51,0x0A,0x98,0x41,0x41, -0x22,0x4E,0x65,0x61,0x87,0x81,0x41,0x50,0xA6,0x79,0x5C,0x89,0xDE,0x19,0x4A,0x57, -0xD5,0x2E,0xE6,0x5D,0x1C,0x53,0x2C,0x7E,0x98,0xCD,0x1A,0x06,0x16,0xA4,0x68,0x73, -0xD0,0x34,0x04,0x13,0x5C,0xA1,0x71,0xD3,0x5A,0x7C,0x55,0xDB,0x5E,0x64,0xE1,0x37, -0x87,0x30,0x56,0x04,0xE5,0x11,0xB4,0x29,0x80,0x12,0xF1,0x79,0x39,0x88,0xA2,0x02, -0x11,0x7C,0x27,0x66,0xB7,0x88,0xB7,0x78,0xF2,0xCA,0x0A,0xA8,0x38,0xAB,0x0A,0x64, -0xC2,0xBF,0x66,0x5D,0x95,0x84,0xC1,0xA1,0x25,0x1E,0x87,0x5D,0x1A,0x50,0x0B,0x20, -0x12,0xCC,0x41,0xBB,0x6E,0x0B,0x51,0x38,0xB8,0x4B,0xCB,0x02,0x03,0x01,0x00,0x01, -0xA3,0x63,0x30,0x61,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, -0x03,0x02,0x01,0x86,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05, -0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14, -0xB1,0x3E,0xC3,0x69,0x03,0xF8,0xBF,0x47,0x01,0xD4,0x98,0x26,0x1A,0x08,0x02,0xEF, -0x63,0x64,0x2B,0xC3,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80, -0x14,0xB1,0x3E,0xC3,0x69,0x03,0xF8,0xBF,0x47,0x01,0xD4,0x98,0x26,0x1A,0x08,0x02, -0xEF,0x63,0x64,0x2B,0xC3,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x1C,0x1A,0x06,0x97,0xDC,0xD7,0x9C, -0x9F,0x3C,0x88,0x66,0x06,0x08,0x57,0x21,0xDB,0x21,0x47,0xF8,0x2A,0x67,0xAA,0xBF, -0x18,0x32,0x76,0x40,0x10,0x57,0xC1,0x8A,0xF3,0x7A,0xD9,0x11,0x65,0x8E,0x35,0xFA, -0x9E,0xFC,0x45,0xB5,0x9E,0xD9,0x4C,0x31,0x4B,0xB8,0x91,0xE8,0x43,0x2C,0x8E,0xB3, -0x78,0xCE,0xDB,0xE3,0x53,0x79,0x71,0xD6,0xE5,0x21,0x94,0x01,0xDA,0x55,0x87,0x9A, -0x24,0x64,0xF6,0x8A,0x66,0xCC,0xDE,0x9C,0x37,0xCD,0xA8,0x34,0xB1,0x69,0x9B,0x23, -0xC8,0x9E,0x78,0x22,0x2B,0x70,0x43,0xE3,0x55,0x47,0x31,0x61,0x19,0xEF,0x58,0xC5, -0x85,0x2F,0x4E,0x30,0xF6,0xA0,0x31,0x16,0x23,0xC8,0xE7,0xE2,0x65,0x16,0x33,0xCB, -0xBF,0x1A,0x1B,0xA0,0x3D,0xF8,0xCA,0x5E,0x8B,0x31,0x8B,0x60,0x08,0x89,0x2D,0x0C, -0x06,0x5C,0x52,0xB7,0xC4,0xF9,0x0A,0x98,0xD1,0x15,0x5F,0x9F,0x12,0xBE,0x7C,0x36, -0x63,0x38,0xBD,0x44,0xA4,0x7F,0xE4,0x26,0x2B,0x0A,0xC4,0x97,0x69,0x0D,0xE9,0x8C, -0xE2,0xC0,0x10,0x57,0xB8,0xC8,0x76,0x12,0x91,0x55,0xF2,0x48,0x69,0xD8,0xBC,0x2A, -0x02,0x5B,0x0F,0x44,0xD4,0x20,0x31,0xDB,0xF4,0xBA,0x70,0x26,0x5D,0x90,0x60,0x9E, -0xBC,0x4B,0x17,0x09,0x2F,0xB4,0xCB,0x1E,0x43,0x68,0xC9,0x07,0x27,0xC1,0xD2,0x5C, -0xF7,0xEA,0x21,0xB9,0x68,0x12,0x9C,0x3C,0x9C,0xBF,0x9E,0xFC,0x80,0x5C,0x9B,0x63, -0xCD,0xEC,0x47,0xAA,0x25,0x27,0x67,0xA0,0x37,0xF3,0x00,0x82,0x7D,0x54,0xD7,0xA9, -0xF8,0xE9,0x2E,0x13,0xA3,0x77,0xE8,0x1F,0x4A, -}; - - -/* subject:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048) */ -/* issuer :/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048) */ - - -const unsigned char Entrust_net_Premium_2048_Secure_Server_CA_certificate[1120]={ -0x30,0x82,0x04,0x5C,0x30,0x82,0x03,0x44,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x38, -0x63,0xB9,0x66,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x30,0x81,0xB4,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B, -0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x40,0x30,0x3E,0x06, -0x03,0x55,0x04,0x0B,0x14,0x37,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73, -0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x5F,0x32,0x30,0x34,0x38,0x20,0x69, -0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28, -0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30, -0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39, -0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D, -0x69,0x74,0x65,0x64,0x31,0x33,0x30,0x31,0x06,0x03,0x55,0x04,0x03,0x13,0x2A,0x45, -0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x20,0x28,0x32,0x30,0x34,0x38,0x29,0x30,0x1E,0x17,0x0D,0x39,0x39,0x31, -0x32,0x32,0x34,0x31,0x37,0x35,0x30,0x35,0x31,0x5A,0x17,0x0D,0x31,0x39,0x31,0x32, -0x32,0x34,0x31,0x38,0x32,0x30,0x35,0x31,0x5A,0x30,0x81,0xB4,0x31,0x14,0x30,0x12, -0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, -0x65,0x74,0x31,0x40,0x30,0x3E,0x06,0x03,0x55,0x04,0x0B,0x14,0x37,0x77,0x77,0x77, -0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53, -0x5F,0x32,0x30,0x34,0x38,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,0x79, -0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C,0x69, -0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,0x28, -0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E, -0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x33,0x30,0x31,0x06, -0x03,0x55,0x04,0x03,0x13,0x2A,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65, -0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20, -0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x28,0x32,0x30,0x34,0x38,0x29, -0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01, -0x00,0xAD,0x4D,0x4B,0xA9,0x12,0x86,0xB2,0xEA,0xA3,0x20,0x07,0x15,0x16,0x64,0x2A, -0x2B,0x4B,0xD1,0xBF,0x0B,0x4A,0x4D,0x8E,0xED,0x80,0x76,0xA5,0x67,0xB7,0x78,0x40, -0xC0,0x73,0x42,0xC8,0x68,0xC0,0xDB,0x53,0x2B,0xDD,0x5E,0xB8,0x76,0x98,0x35,0x93, -0x8B,0x1A,0x9D,0x7C,0x13,0x3A,0x0E,0x1F,0x5B,0xB7,0x1E,0xCF,0xE5,0x24,0x14,0x1E, -0xB1,0x81,0xA9,0x8D,0x7D,0xB8,0xCC,0x6B,0x4B,0x03,0xF1,0x02,0x0C,0xDC,0xAB,0xA5, -0x40,0x24,0x00,0x7F,0x74,0x94,0xA1,0x9D,0x08,0x29,0xB3,0x88,0x0B,0xF5,0x87,0x77, -0x9D,0x55,0xCD,0xE4,0xC3,0x7E,0xD7,0x6A,0x64,0xAB,0x85,0x14,0x86,0x95,0x5B,0x97, -0x32,0x50,0x6F,0x3D,0xC8,0xBA,0x66,0x0C,0xE3,0xFC,0xBD,0xB8,0x49,0xC1,0x76,0x89, -0x49,0x19,0xFD,0xC0,0xA8,0xBD,0x89,0xA3,0x67,0x2F,0xC6,0x9F,0xBC,0x71,0x19,0x60, -0xB8,0x2D,0xE9,0x2C,0xC9,0x90,0x76,0x66,0x7B,0x94,0xE2,0xAF,0x78,0xD6,0x65,0x53, -0x5D,0x3C,0xD6,0x9C,0xB2,0xCF,0x29,0x03,0xF9,0x2F,0xA4,0x50,0xB2,0xD4,0x48,0xCE, -0x05,0x32,0x55,0x8A,0xFD,0xB2,0x64,0x4C,0x0E,0xE4,0x98,0x07,0x75,0xDB,0x7F,0xDF, -0xB9,0x08,0x55,0x60,0x85,0x30,0x29,0xF9,0x7B,0x48,0xA4,0x69,0x86,0xE3,0x35,0x3F, -0x1E,0x86,0x5D,0x7A,0x7A,0x15,0xBD,0xEF,0x00,0x8E,0x15,0x22,0x54,0x17,0x00,0x90, -0x26,0x93,0xBC,0x0E,0x49,0x68,0x91,0xBF,0xF8,0x47,0xD3,0x9D,0x95,0x42,0xC1,0x0E, -0x4D,0xDF,0x6F,0x26,0xCF,0xC3,0x18,0x21,0x62,0x66,0x43,0x70,0xD6,0xD5,0xC0,0x07, -0xE1,0x02,0x03,0x01,0x00,0x01,0xA3,0x74,0x30,0x72,0x30,0x11,0x06,0x09,0x60,0x86, -0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07,0x30,0x1F,0x06, -0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x55,0xE4,0x81,0xD1,0x11,0x80, -0xBE,0xD8,0x89,0xB9,0x08,0xA3,0x31,0xF9,0xA1,0x24,0x09,0x16,0xB9,0x70,0x30,0x1D, -0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x55,0xE4,0x81,0xD1,0x11,0x80,0xBE, -0xD8,0x89,0xB9,0x08,0xA3,0x31,0xF9,0xA1,0x24,0x09,0x16,0xB9,0x70,0x30,0x1D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x10,0x30,0x0E,0x1B,0x08, -0x56,0x35,0x2E,0x30,0x3A,0x34,0x2E,0x30,0x03,0x02,0x04,0x90,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00, -0x59,0x47,0xAC,0x21,0x84,0x8A,0x17,0xC9,0x9C,0x89,0x53,0x1E,0xBA,0x80,0x85,0x1A, -0xC6,0x3C,0x4E,0x3E,0xB1,0x9C,0xB6,0x7C,0xC6,0x92,0x5D,0x18,0x64,0x02,0xE3,0xD3, -0x06,0x08,0x11,0x61,0x7C,0x63,0xE3,0x2B,0x9D,0x31,0x03,0x70,0x76,0xD2,0xA3,0x28, -0xA0,0xF4,0xBB,0x9A,0x63,0x73,0xED,0x6D,0xE5,0x2A,0xDB,0xED,0x14,0xA9,0x2B,0xC6, -0x36,0x11,0xD0,0x2B,0xEB,0x07,0x8B,0xA5,0xDA,0x9E,0x5C,0x19,0x9D,0x56,0x12,0xF5, -0x54,0x29,0xC8,0x05,0xED,0xB2,0x12,0x2A,0x8D,0xF4,0x03,0x1B,0xFF,0xE7,0x92,0x10, -0x87,0xB0,0x3A,0xB5,0xC3,0x9D,0x05,0x37,0x12,0xA3,0xC7,0xF4,0x15,0xB9,0xD5,0xA4, -0x39,0x16,0x9B,0x53,0x3A,0x23,0x91,0xF1,0xA8,0x82,0xA2,0x6A,0x88,0x68,0xC1,0x79, -0x02,0x22,0xBC,0xAA,0xA6,0xD6,0xAE,0xDF,0xB0,0x14,0x5F,0xB8,0x87,0xD0,0xDD,0x7C, -0x7F,0x7B,0xFF,0xAF,0x1C,0xCF,0xE6,0xDB,0x07,0xAD,0x5E,0xDB,0x85,0x9D,0xD0,0x2B, -0x0D,0x33,0xDB,0x04,0xD1,0xE6,0x49,0x40,0x13,0x2B,0x76,0xFB,0x3E,0xE9,0x9C,0x89, -0x0F,0x15,0xCE,0x18,0xB0,0x85,0x78,0x21,0x4F,0x6B,0x4F,0x0E,0xFA,0x36,0x67,0xCD, -0x07,0xF2,0xFF,0x08,0xD0,0xE2,0xDE,0xD9,0xBF,0x2A,0xAF,0xB8,0x87,0x86,0x21,0x3C, -0x04,0xCA,0xB7,0x94,0x68,0x7F,0xCF,0x3C,0xE9,0x98,0xD7,0x38,0xFF,0xEC,0xC0,0xD9, -0x50,0xF0,0x2E,0x4B,0x58,0xAE,0x46,0x6F,0xD0,0x2E,0xC3,0x60,0xDA,0x72,0x55,0x72, -0xBD,0x4C,0x45,0x9E,0x61,0xBA,0xBF,0x84,0x81,0x92,0x03,0xD1,0xD2,0x69,0x7C,0xC5, -}; - - -/* subject:/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority */ -/* issuer :/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority */ - - -const unsigned char Entrust_net_Secure_Server_CA_certificate[1244]={ -0x30,0x82,0x04,0xD8,0x30,0x82,0x04,0x41,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x37, -0x4A,0xD2,0x43,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74, -0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04, -0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, -0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62, -0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C, -0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C, -0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74, -0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38, -0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, -0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72, -0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41, -0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x35, -0x32,0x35,0x31,0x36,0x30,0x39,0x34,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x35,0x32, -0x35,0x31,0x36,0x33,0x39,0x34,0x30,0x5A,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04, -0x0A,0x13,0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B, -0x30,0x39,0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74, -0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63, -0x6F,0x72,0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69, -0x6D,0x69,0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06, -0x03,0x55,0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45, -0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74, -0x65,0x64,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74, -0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20, -0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, -0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x81, -0x9D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00, -0x03,0x81,0x8B,0x00,0x30,0x81,0x87,0x02,0x81,0x81,0x00,0xCD,0x28,0x83,0x34,0x54, -0x1B,0x89,0xF3,0x0F,0xAF,0x37,0x91,0x31,0xFF,0xAF,0x31,0x60,0xC9,0xA8,0xE8,0xB2, -0x10,0x68,0xED,0x9F,0xE7,0x93,0x36,0xF1,0x0A,0x64,0xBB,0x47,0xF5,0x04,0x17,0x3F, -0x23,0x47,0x4D,0xC5,0x27,0x19,0x81,0x26,0x0C,0x54,0x72,0x0D,0x88,0x2D,0xD9,0x1F, -0x9A,0x12,0x9F,0xBC,0xB3,0x71,0xD3,0x80,0x19,0x3F,0x47,0x66,0x7B,0x8C,0x35,0x28, -0xD2,0xB9,0x0A,0xDF,0x24,0xDA,0x9C,0xD6,0x50,0x79,0x81,0x7A,0x5A,0xD3,0x37,0xF7, -0xC2,0x4A,0xD8,0x29,0x92,0x26,0x64,0xD1,0xE4,0x98,0x6C,0x3A,0x00,0x8A,0xF5,0x34, -0x9B,0x65,0xF8,0xED,0xE3,0x10,0xFF,0xFD,0xB8,0x49,0x58,0xDC,0xA0,0xDE,0x82,0x39, -0x6B,0x81,0xB1,0x16,0x19,0x61,0xB9,0x54,0xB6,0xE6,0x43,0x02,0x01,0x03,0xA3,0x82, -0x01,0xD7,0x30,0x82,0x01,0xD3,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8, -0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07,0x30,0x82,0x01,0x19,0x06,0x03,0x55, -0x1D,0x1F,0x04,0x82,0x01,0x10,0x30,0x82,0x01,0x0C,0x30,0x81,0xDE,0xA0,0x81,0xDB, -0xA0,0x81,0xD8,0xA4,0x81,0xD5,0x30,0x81,0xD2,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, -0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13, -0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39, -0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75, -0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72, -0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69, -0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55, -0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74, -0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64, -0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75, -0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65, -0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69, -0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x0D,0x30,0x0B, -0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4C,0x31,0x30,0x29,0xA0,0x27,0xA0, -0x25,0x86,0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E, -0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x52,0x4C,0x2F,0x6E,0x65, -0x74,0x31,0x2E,0x63,0x72,0x6C,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30, -0x22,0x80,0x0F,0x31,0x39,0x39,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39,0x34, -0x30,0x5A,0x81,0x0F,0x32,0x30,0x31,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39, -0x34,0x30,0x5A,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x06, -0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62, -0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0, -0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xF0,0x17,0x62,0x13, -0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,0x1A, -0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x19, -0x06,0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B, -0x04,0x56,0x34,0x2E,0x30,0x03,0x02,0x04,0x90,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x90,0xDC,0x30,0x02, -0xFA,0x64,0x74,0xC2,0xA7,0x0A,0xA5,0x7C,0x21,0x8D,0x34,0x17,0xA8,0xFB,0x47,0x0E, -0xFF,0x25,0x7C,0x8D,0x13,0x0A,0xFB,0xE4,0x98,0xB5,0xEF,0x8C,0xF8,0xC5,0x10,0x0D, -0xF7,0x92,0xBE,0xF1,0xC3,0xD5,0xD5,0x95,0x6A,0x04,0xBB,0x2C,0xCE,0x26,0x36,0x65, -0xC8,0x31,0xC6,0xE7,0xEE,0x3F,0xE3,0x57,0x75,0x84,0x7A,0x11,0xEF,0x46,0x4F,0x18, -0xF4,0xD3,0x98,0xBB,0xA8,0x87,0x32,0xBA,0x72,0xF6,0x3C,0xE2,0x3D,0x9F,0xD7,0x1D, -0xD9,0xC3,0x60,0x43,0x8C,0x58,0x0E,0x22,0x96,0x2F,0x62,0xA3,0x2C,0x1F,0xBA,0xAD, -0x05,0xEF,0xAB,0x32,0x78,0x87,0xA0,0x54,0x73,0x19,0xB5,0x5C,0x05,0xF9,0x52,0x3E, -0x6D,0x2D,0x45,0x0B,0xF7,0x0A,0x93,0xEA,0xED,0x06,0xF9,0xB2, -}; - - -/* subject:/C=US/O=Entrust, Inc./OU=www.entrust.net/CPS is incorporated by reference/OU=(c) 2006 Entrust, Inc./CN=Entrust Root Certification Authority */ -/* issuer :/C=US/O=Entrust, Inc./OU=www.entrust.net/CPS is incorporated by reference/OU=(c) 2006 Entrust, Inc./CN=Entrust Root Certification Authority */ - - -const unsigned char Entrust_Root_Certification_Authority_certificate[1173]={ -0x30,0x82,0x04,0x91,0x30,0x82,0x03,0x79,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x45, -0x6B,0x50,0x54,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x30,0x81,0xB0,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x45,0x6E,0x74, -0x72,0x75,0x73,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x39,0x30,0x37,0x06,0x03, -0x55,0x04,0x0B,0x13,0x30,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74, -0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x73,0x20,0x69,0x6E,0x63,0x6F, -0x72,0x70,0x6F,0x72,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x65, -0x72,0x65,0x6E,0x63,0x65,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16, -0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74, -0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x03,0x13, -0x24,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65, -0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68, -0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31,0x32,0x37,0x32, -0x30,0x32,0x33,0x34,0x32,0x5A,0x17,0x0D,0x32,0x36,0x31,0x31,0x32,0x37,0x32,0x30, -0x35,0x33,0x34,0x32,0x5A,0x30,0x81,0xB0,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, -0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D, -0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x39,0x30, -0x37,0x06,0x03,0x55,0x04,0x0B,0x13,0x30,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72, -0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x73,0x20,0x69, -0x6E,0x63,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x72, -0x65,0x66,0x65,0x72,0x65,0x6E,0x63,0x65,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04, -0x0B,0x13,0x16,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x45,0x6E,0x74,0x72, -0x75,0x73,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55, -0x04,0x03,0x13,0x24,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74, -0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41, -0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00, -0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xB6,0x95,0xB6,0x43,0x42,0xFA,0xC6, -0x6D,0x2A,0x6F,0x48,0xDF,0x94,0x4C,0x39,0x57,0x05,0xEE,0xC3,0x79,0x11,0x41,0x68, -0x36,0xED,0xEC,0xFE,0x9A,0x01,0x8F,0xA1,0x38,0x28,0xFC,0xF7,0x10,0x46,0x66,0x2E, -0x4D,0x1E,0x1A,0xB1,0x1A,0x4E,0xC6,0xD1,0xC0,0x95,0x88,0xB0,0xC9,0xFF,0x31,0x8B, -0x33,0x03,0xDB,0xB7,0x83,0x7B,0x3E,0x20,0x84,0x5E,0xED,0xB2,0x56,0x28,0xA7,0xF8, -0xE0,0xB9,0x40,0x71,0x37,0xC5,0xCB,0x47,0x0E,0x97,0x2A,0x68,0xC0,0x22,0x95,0x62, -0x15,0xDB,0x47,0xD9,0xF5,0xD0,0x2B,0xFF,0x82,0x4B,0xC9,0xAD,0x3E,0xDE,0x4C,0xDB, -0x90,0x80,0x50,0x3F,0x09,0x8A,0x84,0x00,0xEC,0x30,0x0A,0x3D,0x18,0xCD,0xFB,0xFD, -0x2A,0x59,0x9A,0x23,0x95,0x17,0x2C,0x45,0x9E,0x1F,0x6E,0x43,0x79,0x6D,0x0C,0x5C, -0x98,0xFE,0x48,0xA7,0xC5,0x23,0x47,0x5C,0x5E,0xFD,0x6E,0xE7,0x1E,0xB4,0xF6,0x68, -0x45,0xD1,0x86,0x83,0x5B,0xA2,0x8A,0x8D,0xB1,0xE3,0x29,0x80,0xFE,0x25,0x71,0x88, -0xAD,0xBE,0xBC,0x8F,0xAC,0x52,0x96,0x4B,0xAA,0x51,0x8D,0xE4,0x13,0x31,0x19,0xE8, -0x4E,0x4D,0x9F,0xDB,0xAC,0xB3,0x6A,0xD5,0xBC,0x39,0x54,0x71,0xCA,0x7A,0x7A,0x7F, -0x90,0xDD,0x7D,0x1D,0x80,0xD9,0x81,0xBB,0x59,0x26,0xC2,0x11,0xFE,0xE6,0x93,0xE2, -0xF7,0x80,0xE4,0x65,0xFB,0x34,0x37,0x0E,0x29,0x80,0x70,0x4D,0xAF,0x38,0x86,0x2E, -0x9E,0x7F,0x57,0xAF,0x9E,0x17,0xAE,0xEB,0x1C,0xCB,0x28,0x21,0x5F,0xB6,0x1C,0xD8, -0xE7,0xA2,0x04,0x22,0xF9,0xD3,0xDA,0xD8,0xCB,0x02,0x03,0x01,0x00,0x01,0xA3,0x81, -0xB0,0x30,0x81,0xAD,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, -0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05, -0x30,0x03,0x01,0x01,0xFF,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,0x22, -0x80,0x0F,0x32,0x30,0x30,0x36,0x31,0x31,0x32,0x37,0x32,0x30,0x32,0x33,0x34,0x32, -0x5A,0x81,0x0F,0x32,0x30,0x32,0x36,0x31,0x31,0x32,0x37,0x32,0x30,0x35,0x33,0x34, -0x32,0x5A,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x68, -0x90,0xE4,0x67,0xA4,0xA6,0x53,0x80,0xC7,0x86,0x66,0xA4,0xF1,0xF7,0x4B,0x43,0xFB, -0x84,0xBD,0x6D,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x68,0x90, -0xE4,0x67,0xA4,0xA6,0x53,0x80,0xC7,0x86,0x66,0xA4,0xF1,0xF7,0x4B,0x43,0xFB,0x84, -0xBD,0x6D,0x30,0x1D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04, -0x10,0x30,0x0E,0x1B,0x08,0x56,0x37,0x2E,0x31,0x3A,0x34,0x2E,0x30,0x03,0x02,0x04, -0x90,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00, -0x03,0x82,0x01,0x01,0x00,0x93,0xD4,0x30,0xB0,0xD7,0x03,0x20,0x2A,0xD0,0xF9,0x63, -0xE8,0x91,0x0C,0x05,0x20,0xA9,0x5F,0x19,0xCA,0x7B,0x72,0x4E,0xD4,0xB1,0xDB,0xD0, -0x96,0xFB,0x54,0x5A,0x19,0x2C,0x0C,0x08,0xF7,0xB2,0xBC,0x85,0xA8,0x9D,0x7F,0x6D, -0x3B,0x52,0xB3,0x2A,0xDB,0xE7,0xD4,0x84,0x8C,0x63,0xF6,0x0F,0xCB,0x26,0x01,0x91, -0x50,0x6C,0xF4,0x5F,0x14,0xE2,0x93,0x74,0xC0,0x13,0x9E,0x30,0x3A,0x50,0xE3,0xB4, -0x60,0xC5,0x1C,0xF0,0x22,0x44,0x8D,0x71,0x47,0xAC,0xC8,0x1A,0xC9,0xE9,0x9B,0x9A, -0x00,0x60,0x13,0xFF,0x70,0x7E,0x5F,0x11,0x4D,0x49,0x1B,0xB3,0x15,0x52,0x7B,0xC9, -0x54,0xDA,0xBF,0x9D,0x95,0xAF,0x6B,0x9A,0xD8,0x9E,0xE9,0xF1,0xE4,0x43,0x8D,0xE2, -0x11,0x44,0x3A,0xBF,0xAF,0xBD,0x83,0x42,0x73,0x52,0x8B,0xAA,0xBB,0xA7,0x29,0xCF, -0xF5,0x64,0x1C,0x0A,0x4D,0xD1,0xBC,0xAA,0xAC,0x9F,0x2A,0xD0,0xFF,0x7F,0x7F,0xDA, -0x7D,0xEA,0xB1,0xED,0x30,0x25,0xC1,0x84,0xDA,0x34,0xD2,0x5B,0x78,0x83,0x56,0xEC, -0x9C,0x36,0xC3,0x26,0xE2,0x11,0xF6,0x67,0x49,0x1D,0x92,0xAB,0x8C,0xFB,0xEB,0xFF, -0x7A,0xEE,0x85,0x4A,0xA7,0x50,0x80,0xF0,0xA7,0x5C,0x4A,0x94,0x2E,0x5F,0x05,0x99, -0x3C,0x52,0x41,0xE0,0xCD,0xB4,0x63,0xCF,0x01,0x43,0xBA,0x9C,0x83,0xDC,0x8F,0x60, -0x3B,0xF3,0x5A,0xB4,0xB4,0x7B,0xAE,0xDA,0x0B,0x90,0x38,0x75,0xEF,0x81,0x1D,0x66, -0xD2,0xF7,0x57,0x70,0x36,0xB3,0xBF,0xFC,0x28,0xAF,0x71,0x25,0x85,0x5B,0x13,0xFE, -0x1E,0x7F,0x5A,0xB4,0x3C, -}; - - -/* subject:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority */ -/* issuer :/C=US/O=Equifax/OU=Equifax Secure Certificate Authority */ - - -const unsigned char Equifax_Secure_CA_certificate[804]={ -0x30,0x82,0x03,0x20,0x30,0x82,0x02,0x89,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x35, -0xDE,0xF4,0xCF,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x30,0x4E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x45,0x71,0x75,0x69, -0x66,0x61,0x78,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x45,0x71, -0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x43,0x65,0x72, -0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x30,0x1E,0x17,0x0D,0x39,0x38,0x30,0x38,0x32,0x32,0x31,0x36,0x34,0x31, -0x35,0x31,0x5A,0x17,0x0D,0x31,0x38,0x30,0x38,0x32,0x32,0x31,0x36,0x34,0x31,0x35, -0x31,0x5A,0x30,0x4E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x45,0x71,0x75,0x69, -0x66,0x61,0x78,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x45,0x71, -0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x43,0x65,0x72, -0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC1, -0x5D,0xB1,0x58,0x67,0x08,0x62,0xEE,0xA0,0x9A,0x2D,0x1F,0x08,0x6D,0x91,0x14,0x68, -0x98,0x0A,0x1E,0xFE,0xDA,0x04,0x6F,0x13,0x84,0x62,0x21,0xC3,0xD1,0x7C,0xCE,0x9F, -0x05,0xE0,0xB8,0x01,0xF0,0x4E,0x34,0xEC,0xE2,0x8A,0x95,0x04,0x64,0xAC,0xF1,0x6B, -0x53,0x5F,0x05,0xB3,0xCB,0x67,0x80,0xBF,0x42,0x02,0x8E,0xFE,0xDD,0x01,0x09,0xEC, -0xE1,0x00,0x14,0x4F,0xFC,0xFB,0xF0,0x0C,0xDD,0x43,0xBA,0x5B,0x2B,0xE1,0x1F,0x80, -0x70,0x99,0x15,0x57,0x93,0x16,0xF1,0x0F,0x97,0x6A,0xB7,0xC2,0x68,0x23,0x1C,0xCC, -0x4D,0x59,0x30,0xAC,0x51,0x1E,0x3B,0xAF,0x2B,0xD6,0xEE,0x63,0x45,0x7B,0xC5,0xD9, -0x5F,0x50,0xD2,0xE3,0x50,0x0F,0x3A,0x88,0xE7,0xBF,0x14,0xFD,0xE0,0xC7,0xB9,0x02, -0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x09,0x30,0x82,0x01,0x05,0x30,0x70,0x06,0x03, -0x55,0x1D,0x1F,0x04,0x69,0x30,0x67,0x30,0x65,0xA0,0x63,0xA0,0x61,0xA4,0x5F,0x30, -0x5D,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, -0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x45,0x71,0x75,0x69,0x66,0x61,0x78, -0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x45,0x71,0x75,0x69,0x66, -0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66, -0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31, -0x0D,0x30,0x0B,0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4C,0x31,0x30,0x1A, -0x06,0x03,0x55,0x1D,0x10,0x04,0x13,0x30,0x11,0x81,0x0F,0x32,0x30,0x31,0x38,0x30, -0x38,0x32,0x32,0x31,0x36,0x34,0x31,0x35,0x31,0x5A,0x30,0x0B,0x06,0x03,0x55,0x1D, -0x0F,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, -0x30,0x16,0x80,0x14,0x48,0xE6,0x68,0xF9,0x2B,0xD2,0xB2,0x95,0xD7,0x47,0xD8,0x23, -0x20,0x10,0x4F,0x33,0x98,0x90,0x9F,0xD4,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, -0x16,0x04,0x14,0x48,0xE6,0x68,0xF9,0x2B,0xD2,0xB2,0x95,0xD7,0x47,0xD8,0x23,0x20, -0x10,0x4F,0x33,0x98,0x90,0x9F,0xD4,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05, -0x30,0x03,0x01,0x01,0xFF,0x30,0x1A,0x06,0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07, -0x41,0x00,0x04,0x0D,0x30,0x0B,0x1B,0x05,0x56,0x33,0x2E,0x30,0x63,0x03,0x02,0x06, -0xC0,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00, -0x03,0x81,0x81,0x00,0x58,0xCE,0x29,0xEA,0xFC,0xF7,0xDE,0xB5,0xCE,0x02,0xB9,0x17, -0xB5,0x85,0xD1,0xB9,0xE3,0xE0,0x95,0xCC,0x25,0x31,0x0D,0x00,0xA6,0x92,0x6E,0x7F, -0xB6,0x92,0x63,0x9E,0x50,0x95,0xD1,0x9A,0x6F,0xE4,0x11,0xDE,0x63,0x85,0x6E,0x98, -0xEE,0xA8,0xFF,0x5A,0xC8,0xD3,0x55,0xB2,0x66,0x71,0x57,0xDE,0xC0,0x21,0xEB,0x3D, -0x2A,0xA7,0x23,0x49,0x01,0x04,0x86,0x42,0x7B,0xFC,0xEE,0x7F,0xA2,0x16,0x52,0xB5, -0x67,0x67,0xD3,0x40,0xDB,0x3B,0x26,0x58,0xB2,0x28,0x77,0x3D,0xAE,0x14,0x77,0x61, -0xD6,0xFA,0x2A,0x66,0x27,0xA0,0x0D,0xFA,0xA7,0x73,0x5C,0xEA,0x70,0xF1,0x94,0x21, -0x65,0x44,0x5F,0xFA,0xFC,0xEF,0x29,0x68,0xA9,0xA2,0x87,0x79,0xEF,0x79,0xEF,0x4F, -0xAC,0x07,0x77,0x38, -}; - - -/* subject:/C=US/O=Equifax Secure Inc./CN=Equifax Secure eBusiness CA-1 */ -/* issuer :/C=US/O=Equifax Secure Inc./CN=Equifax Secure eBusiness CA-1 */ - - -const unsigned char Equifax_Secure_eBusiness_CA_1_certificate[646]={ -0x30,0x82,0x02,0x82,0x30,0x82,0x01,0xEB,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x04, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x30, -0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1C, -0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x45,0x71,0x75,0x69,0x66,0x61,0x78, -0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x26,0x30,0x24, -0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53, -0x65,0x63,0x75,0x72,0x65,0x20,0x65,0x42,0x75,0x73,0x69,0x6E,0x65,0x73,0x73,0x20, -0x43,0x41,0x2D,0x31,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x36,0x32,0x31,0x30,0x34, -0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x30,0x30,0x36,0x32,0x31,0x30,0x34,0x30, -0x30,0x30,0x30,0x5A,0x30,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x55,0x53,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x45,0x71, -0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x49,0x6E,0x63, -0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x45,0x71,0x75,0x69, -0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x65,0x42,0x75,0x73,0x69, -0x6E,0x65,0x73,0x73,0x20,0x43,0x41,0x2D,0x31,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30, -0x81,0x89,0x02,0x81,0x81,0x00,0xCE,0x2F,0x19,0xBC,0x17,0xB7,0x77,0xDE,0x93,0xA9, -0x5F,0x5A,0x0D,0x17,0x4F,0x34,0x1A,0x0C,0x98,0xF4,0x22,0xD9,0x59,0xD4,0xC4,0x68, -0x46,0xF0,0xB4,0x35,0xC5,0x85,0x03,0x20,0xC6,0xAF,0x45,0xA5,0x21,0x51,0x45,0x41, -0xEB,0x16,0x58,0x36,0x32,0x6F,0xE2,0x50,0x62,0x64,0xF9,0xFD,0x51,0x9C,0xAA,0x24, -0xD9,0xF4,0x9D,0x83,0x2A,0x87,0x0A,0x21,0xD3,0x12,0x38,0x34,0x6C,0x8D,0x00,0x6E, -0x5A,0xA0,0xD9,0x42,0xEE,0x1A,0x21,0x95,0xF9,0x52,0x4C,0x55,0x5A,0xC5,0x0F,0x38, -0x4F,0x46,0xFA,0x6D,0xF8,0x2E,0x35,0xD6,0x1D,0x7C,0xEB,0xE2,0xF0,0xB0,0x75,0x80, -0xC8,0xA9,0x13,0xAC,0xBE,0x88,0xEF,0x3A,0x6E,0xAB,0x5F,0x2A,0x38,0x62,0x02,0xB0, -0x12,0x7B,0xFE,0x8F,0xA6,0x03,0x02,0x03,0x01,0x00,0x01,0xA3,0x66,0x30,0x64,0x30, -0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02, -0x00,0x07,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03, -0x01,0x01,0xFF,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, -0x4A,0x78,0x32,0x52,0x11,0xDB,0x59,0x16,0x36,0x5E,0xDF,0xC1,0x14,0x36,0x40,0x6A, -0x47,0x7C,0x4C,0xA1,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x4A, -0x78,0x32,0x52,0x11,0xDB,0x59,0x16,0x36,0x5E,0xDF,0xC1,0x14,0x36,0x40,0x6A,0x47, -0x7C,0x4C,0xA1,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04, -0x05,0x00,0x03,0x81,0x81,0x00,0x75,0x5B,0xA8,0x9B,0x03,0x11,0xE6,0xE9,0x56,0x4C, -0xCD,0xF9,0xA9,0x4C,0xC0,0x0D,0x9A,0xF3,0xCC,0x65,0x69,0xE6,0x25,0x76,0xCC,0x59, -0xB7,0xD6,0x54,0xC3,0x1D,0xCD,0x99,0xAC,0x19,0xDD,0xB4,0x85,0xD5,0xE0,0x3D,0xFC, -0x62,0x20,0xA7,0x84,0x4B,0x58,0x65,0xF1,0xE2,0xF9,0x95,0x21,0x3F,0xF5,0xD4,0x7E, -0x58,0x1E,0x47,0x87,0x54,0x3E,0x58,0xA1,0xB5,0xB5,0xF8,0x2A,0xEF,0x71,0xE7,0xBC, -0xC3,0xF6,0xB1,0x49,0x46,0xE2,0xD7,0xA0,0x6B,0xE5,0x56,0x7A,0x9A,0x27,0x98,0x7C, -0x46,0x62,0x14,0xE7,0xC9,0xFC,0x6E,0x03,0x12,0x79,0x80,0x38,0x1D,0x48,0x82,0x8D, -0xFC,0x17,0xFE,0x2A,0x96,0x2B,0xB5,0x62,0xA6,0xA6,0x3D,0xBD,0x7F,0x92,0x59,0xCD, -0x5A,0x2A,0x82,0xB2,0x37,0x79, -}; - - -/* subject:/C=US/O=Equifax Secure/OU=Equifax Secure eBusiness CA-2 */ -/* issuer :/C=US/O=Equifax Secure/OU=Equifax Secure eBusiness CA-2 */ - - -const unsigned char Equifax_Secure_eBusiness_CA_2_certificate[804]={ -0x30,0x82,0x03,0x20,0x30,0x82,0x02,0x89,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x37, -0x70,0xCF,0xB5,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x30,0x4E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x45,0x71,0x75,0x69, -0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x31,0x26,0x30,0x24,0x06,0x03, -0x55,0x04,0x0B,0x13,0x1D,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63, -0x75,0x72,0x65,0x20,0x65,0x42,0x75,0x73,0x69,0x6E,0x65,0x73,0x73,0x20,0x43,0x41, -0x2D,0x32,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x36,0x32,0x33,0x31,0x32,0x31,0x34, -0x34,0x35,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x32,0x33,0x31,0x32,0x31,0x34,0x34, -0x35,0x5A,0x30,0x4E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x45,0x71,0x75,0x69, -0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x31,0x26,0x30,0x24,0x06,0x03, -0x55,0x04,0x0B,0x13,0x1D,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63, -0x75,0x72,0x65,0x20,0x65,0x42,0x75,0x73,0x69,0x6E,0x65,0x73,0x73,0x20,0x43,0x41, -0x2D,0x32,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xE4, -0x39,0x39,0x93,0x1E,0x52,0x06,0x1B,0x28,0x36,0xF8,0xB2,0xA3,0x29,0xC5,0xED,0x8E, -0xB2,0x11,0xBD,0xFE,0xEB,0xE7,0xB4,0x74,0xC2,0x8F,0xFF,0x05,0xE7,0xD9,0x9D,0x06, -0xBF,0x12,0xC8,0x3F,0x0E,0xF2,0xD6,0xD1,0x24,0xB2,0x11,0xDE,0xD1,0x73,0x09,0x8A, -0xD4,0xB1,0x2C,0x98,0x09,0x0D,0x1E,0x50,0x46,0xB2,0x83,0xA6,0x45,0x8D,0x62,0x68, -0xBB,0x85,0x1B,0x20,0x70,0x32,0xAA,0x40,0xCD,0xA6,0x96,0x5F,0xC4,0x71,0x37,0x3F, -0x04,0xF3,0xB7,0x41,0x24,0x39,0x07,0x1A,0x1E,0x2E,0x61,0x58,0xA0,0x12,0x0B,0xE5, -0xA5,0xDF,0xC5,0xAB,0xEA,0x37,0x71,0xCC,0x1C,0xC8,0x37,0x3A,0xB9,0x97,0x52,0xA7, -0xAC,0xC5,0x6A,0x24,0x94,0x4E,0x9C,0x7B,0xCF,0xC0,0x6A,0xD6,0xDF,0x21,0xBD,0x02, -0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x09,0x30,0x82,0x01,0x05,0x30,0x70,0x06,0x03, -0x55,0x1D,0x1F,0x04,0x69,0x30,0x67,0x30,0x65,0xA0,0x63,0xA0,0x61,0xA4,0x5F,0x30, -0x5D,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, -0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x45,0x71,0x75,0x69,0x66,0x61,0x78, -0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B, -0x13,0x1D,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65, -0x20,0x65,0x42,0x75,0x73,0x69,0x6E,0x65,0x73,0x73,0x20,0x43,0x41,0x2D,0x32,0x31, -0x0D,0x30,0x0B,0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4C,0x31,0x30,0x1A, -0x06,0x03,0x55,0x1D,0x10,0x04,0x13,0x30,0x11,0x81,0x0F,0x32,0x30,0x31,0x39,0x30, -0x36,0x32,0x33,0x31,0x32,0x31,0x34,0x34,0x35,0x5A,0x30,0x0B,0x06,0x03,0x55,0x1D, -0x0F,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, -0x30,0x16,0x80,0x14,0x50,0x9E,0x0B,0xEA,0xAF,0x5E,0xB9,0x20,0x48,0xA6,0x50,0x6A, -0xCB,0xFD,0xD8,0x20,0x7A,0xA7,0x82,0x76,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, -0x16,0x04,0x14,0x50,0x9E,0x0B,0xEA,0xAF,0x5E,0xB9,0x20,0x48,0xA6,0x50,0x6A,0xCB, -0xFD,0xD8,0x20,0x7A,0xA7,0x82,0x76,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05, -0x30,0x03,0x01,0x01,0xFF,0x30,0x1A,0x06,0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07, -0x41,0x00,0x04,0x0D,0x30,0x0B,0x1B,0x05,0x56,0x33,0x2E,0x30,0x63,0x03,0x02,0x06, -0xC0,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00, -0x03,0x81,0x81,0x00,0x0C,0x86,0x82,0xAD,0xE8,0x4E,0x1A,0xF5,0x8E,0x89,0x27,0xE2, -0x35,0x58,0x3D,0x29,0xB4,0x07,0x8F,0x36,0x50,0x95,0xBF,0x6E,0xC1,0x9E,0xEB,0xC4, -0x90,0xB2,0x85,0xA8,0xBB,0xB7,0x42,0xE0,0x0F,0x07,0x39,0xDF,0xFB,0x9E,0x90,0xB2, -0xD1,0xC1,0x3E,0x53,0x9F,0x03,0x44,0xB0,0x7E,0x4B,0xF4,0x6F,0xE4,0x7C,0x1F,0xE7, -0xE2,0xB1,0xE4,0xB8,0x9A,0xEF,0xC3,0xBD,0xCE,0xDE,0x0B,0x32,0x34,0xD9,0xDE,0x28, -0xED,0x33,0x6B,0xC4,0xD4,0xD7,0x3D,0x12,0x58,0xAB,0x7D,0x09,0x2D,0xCB,0x70,0xF5, -0x13,0x8A,0x94,0xA1,0x27,0xA4,0xD6,0x70,0xC5,0x6D,0x94,0xB5,0xC9,0x7D,0x9D,0xA0, -0xD2,0xC6,0x08,0x49,0xD9,0x66,0x9B,0xA6,0xD3,0xF4,0x0B,0xDC,0xC5,0x26,0x57,0xE1, -0x91,0x30,0xEA,0xCD, -}; - - -/* subject:/C=US/O=Equifax Secure Inc./CN=Equifax Secure Global eBusiness CA-1 */ -/* issuer :/C=US/O=Equifax Secure Inc./CN=Equifax Secure Global eBusiness CA-1 */ - - -const unsigned char Equifax_Secure_Global_eBusiness_CA_certificate[660]={ -0x30,0x82,0x02,0x90,0x30,0x82,0x01,0xF9,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x30, -0x5A,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1C, -0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x45,0x71,0x75,0x69,0x66,0x61,0x78, -0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2D,0x30,0x2B, -0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53, -0x65,0x63,0x75,0x72,0x65,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x65,0x42,0x75, -0x73,0x69,0x6E,0x65,0x73,0x73,0x20,0x43,0x41,0x2D,0x31,0x30,0x1E,0x17,0x0D,0x39, -0x39,0x30,0x36,0x32,0x31,0x30,0x34,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x30, -0x30,0x36,0x32,0x31,0x30,0x34,0x30,0x30,0x30,0x30,0x5A,0x30,0x5A,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1C,0x30,0x1A,0x06,0x03, -0x55,0x04,0x0A,0x13,0x13,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63, -0x75,0x72,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04, -0x03,0x13,0x24,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72, -0x65,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x65,0x42,0x75,0x73,0x69,0x6E,0x65, -0x73,0x73,0x20,0x43,0x41,0x2D,0x31,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89, -0x02,0x81,0x81,0x00,0xBA,0xE7,0x17,0x90,0x02,0x65,0xB1,0x34,0x55,0x3C,0x49,0xC2, -0x51,0xD5,0xDF,0xA7,0xD1,0x37,0x8F,0xD1,0xE7,0x81,0x73,0x41,0x52,0x60,0x9B,0x9D, -0xA1,0x17,0x26,0x78,0xAD,0xC7,0xB1,0xE8,0x26,0x94,0x32,0xB5,0xDE,0x33,0x8D,0x3A, -0x2F,0xDB,0xF2,0x9A,0x7A,0x5A,0x73,0x98,0xA3,0x5C,0xE9,0xFB,0x8A,0x73,0x1B,0x5C, -0xE7,0xC3,0xBF,0x80,0x6C,0xCD,0xA9,0xF4,0xD6,0x2B,0xC0,0xF7,0xF9,0x99,0xAA,0x63, -0xA2,0xB1,0x47,0x02,0x0F,0xD4,0xE4,0x51,0x3A,0x12,0x3C,0x6C,0x8A,0x5A,0x54,0x84, -0x70,0xDB,0xC1,0xC5,0x90,0xCF,0x72,0x45,0xCB,0xA8,0x59,0xC0,0xCD,0x33,0x9D,0x3F, -0xA3,0x96,0xEB,0x85,0x33,0x21,0x1C,0x3E,0x1E,0x3E,0x60,0x6E,0x76,0x9C,0x67,0x85, -0xC5,0xC8,0xC3,0x61,0x02,0x03,0x01,0x00,0x01,0xA3,0x66,0x30,0x64,0x30,0x11,0x06, -0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07, -0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01, -0xFF,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xBE,0xA8, -0xA0,0x74,0x72,0x50,0x6B,0x44,0xB7,0xC9,0x23,0xD8,0xFB,0xA8,0xFF,0xB3,0x57,0x6B, -0x68,0x6C,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xBE,0xA8,0xA0, -0x74,0x72,0x50,0x6B,0x44,0xB7,0xC9,0x23,0xD8,0xFB,0xA8,0xFF,0xB3,0x57,0x6B,0x68, -0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00, -0x03,0x81,0x81,0x00,0x30,0xE2,0x01,0x51,0xAA,0xC7,0xEA,0x5F,0xDA,0xB9,0xD0,0x65, -0x0F,0x30,0xD6,0x3E,0xDA,0x0D,0x14,0x49,0x6E,0x91,0x93,0x27,0x14,0x31,0xEF,0xC4, -0xF7,0x2D,0x45,0xF8,0xEC,0xC7,0xBF,0xA2,0x41,0x0D,0x23,0xB4,0x92,0xF9,0x19,0x00, -0x67,0xBD,0x01,0xAF,0xCD,0xE0,0x71,0xFC,0x5A,0xCF,0x64,0xC4,0xE0,0x96,0x98,0xD0, -0xA3,0x40,0xE2,0x01,0x8A,0xEF,0x27,0x07,0xF1,0x65,0x01,0x8A,0x44,0x2D,0x06,0x65, -0x75,0x52,0xC0,0x86,0x10,0x20,0x21,0x5F,0x6C,0x6B,0x0F,0x6C,0xAE,0x09,0x1C,0xAF, -0xF2,0xA2,0x18,0x34,0xC4,0x75,0xA4,0x73,0x1C,0xF1,0x8D,0xDC,0xEF,0xAD,0xF9,0xB3, -0x76,0xB4,0x92,0xBF,0xDC,0x95,0x10,0x1E,0xBE,0xCB,0xC8,0x3B,0x5A,0x84,0x60,0x19, -0x56,0x94,0xA9,0x55, -}; - - -/* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */ -/* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */ - - -const unsigned char GeoTrust_Global_CA_certificate[856]={ -0x30,0x82,0x03,0x54,0x30,0x82,0x02,0x3C,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x02, -0x34,0x56,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05, -0x00,0x30,0x42,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, -0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72, -0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04, -0x03,0x13,0x12,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62, -0x61,0x6C,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x32,0x30,0x35,0x32,0x31,0x30, -0x34,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x32,0x30,0x35,0x32,0x31,0x30,0x34, -0x30,0x30,0x30,0x30,0x5A,0x30,0x42,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, -0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47, -0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1B,0x30,0x19, -0x06,0x03,0x55,0x04,0x03,0x13,0x12,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20, -0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F, -0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xDA,0xCC,0x18,0x63,0x30,0xFD, -0xF4,0x17,0x23,0x1A,0x56,0x7E,0x5B,0xDF,0x3C,0x6C,0x38,0xE4,0x71,0xB7,0x78,0x91, -0xD4,0xBC,0xA1,0xD8,0x4C,0xF8,0xA8,0x43,0xB6,0x03,0xE9,0x4D,0x21,0x07,0x08,0x88, -0xDA,0x58,0x2F,0x66,0x39,0x29,0xBD,0x05,0x78,0x8B,0x9D,0x38,0xE8,0x05,0xB7,0x6A, -0x7E,0x71,0xA4,0xE6,0xC4,0x60,0xA6,0xB0,0xEF,0x80,0xE4,0x89,0x28,0x0F,0x9E,0x25, -0xD6,0xED,0x83,0xF3,0xAD,0xA6,0x91,0xC7,0x98,0xC9,0x42,0x18,0x35,0x14,0x9D,0xAD, -0x98,0x46,0x92,0x2E,0x4F,0xCA,0xF1,0x87,0x43,0xC1,0x16,0x95,0x57,0x2D,0x50,0xEF, -0x89,0x2D,0x80,0x7A,0x57,0xAD,0xF2,0xEE,0x5F,0x6B,0xD2,0x00,0x8D,0xB9,0x14,0xF8, -0x14,0x15,0x35,0xD9,0xC0,0x46,0xA3,0x7B,0x72,0xC8,0x91,0xBF,0xC9,0x55,0x2B,0xCD, -0xD0,0x97,0x3E,0x9C,0x26,0x64,0xCC,0xDF,0xCE,0x83,0x19,0x71,0xCA,0x4E,0xE6,0xD4, -0xD5,0x7B,0xA9,0x19,0xCD,0x55,0xDE,0xC8,0xEC,0xD2,0x5E,0x38,0x53,0xE5,0x5C,0x4F, -0x8C,0x2D,0xFE,0x50,0x23,0x36,0xFC,0x66,0xE6,0xCB,0x8E,0xA4,0x39,0x19,0x00,0xB7, -0x95,0x02,0x39,0x91,0x0B,0x0E,0xFE,0x38,0x2E,0xD1,0x1D,0x05,0x9A,0xF6,0x4D,0x3E, -0x6F,0x0F,0x07,0x1D,0xAF,0x2C,0x1E,0x8F,0x60,0x39,0xE2,0xFA,0x36,0x53,0x13,0x39, -0xD4,0x5E,0x26,0x2B,0xDB,0x3D,0xA8,0x14,0xBD,0x32,0xEB,0x18,0x03,0x28,0x52,0x04, -0x71,0xE5,0xAB,0x33,0x3D,0xE1,0x38,0xBB,0x07,0x36,0x84,0x62,0x9C,0x79,0xEA,0x16, -0x30,0xF4,0x5F,0xC0,0x2B,0xE8,0x71,0x6B,0xE4,0xF9,0x02,0x03,0x01,0x00,0x01,0xA3, -0x53,0x30,0x51,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, -0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xC0, -0x7A,0x98,0x68,0x8D,0x89,0xFB,0xAB,0x05,0x64,0x0C,0x11,0x7D,0xAA,0x7D,0x65,0xB8, -0xCA,0xCC,0x4E,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, -0xC0,0x7A,0x98,0x68,0x8D,0x89,0xFB,0xAB,0x05,0x64,0x0C,0x11,0x7D,0xAA,0x7D,0x65, -0xB8,0xCA,0xCC,0x4E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x35,0xE3,0x29,0x6A,0xE5,0x2F,0x5D,0x54, -0x8E,0x29,0x50,0x94,0x9F,0x99,0x1A,0x14,0xE4,0x8F,0x78,0x2A,0x62,0x94,0xA2,0x27, -0x67,0x9E,0xD0,0xCF,0x1A,0x5E,0x47,0xE9,0xC1,0xB2,0xA4,0xCF,0xDD,0x41,0x1A,0x05, -0x4E,0x9B,0x4B,0xEE,0x4A,0x6F,0x55,0x52,0xB3,0x24,0xA1,0x37,0x0A,0xEB,0x64,0x76, -0x2A,0x2E,0x2C,0xF3,0xFD,0x3B,0x75,0x90,0xBF,0xFA,0x71,0xD8,0xC7,0x3D,0x37,0xD2, -0xB5,0x05,0x95,0x62,0xB9,0xA6,0xDE,0x89,0x3D,0x36,0x7B,0x38,0x77,0x48,0x97,0xAC, -0xA6,0x20,0x8F,0x2E,0xA6,0xC9,0x0C,0xC2,0xB2,0x99,0x45,0x00,0xC7,0xCE,0x11,0x51, -0x22,0x22,0xE0,0xA5,0xEA,0xB6,0x15,0x48,0x09,0x64,0xEA,0x5E,0x4F,0x74,0xF7,0x05, -0x3E,0xC7,0x8A,0x52,0x0C,0xDB,0x15,0xB4,0xBD,0x6D,0x9B,0xE5,0xC6,0xB1,0x54,0x68, -0xA9,0xE3,0x69,0x90,0xB6,0x9A,0xA5,0x0F,0xB8,0xB9,0x3F,0x20,0x7D,0xAE,0x4A,0xB5, -0xB8,0x9C,0xE4,0x1D,0xB6,0xAB,0xE6,0x94,0xA5,0xC1,0xC7,0x83,0xAD,0xDB,0xF5,0x27, -0x87,0x0E,0x04,0x6C,0xD5,0xFF,0xDD,0xA0,0x5D,0xED,0x87,0x52,0xB7,0x2B,0x15,0x02, -0xAE,0x39,0xA6,0x6A,0x74,0xE9,0xDA,0xC4,0xE7,0xBC,0x4D,0x34,0x1E,0xA9,0x5C,0x4D, -0x33,0x5F,0x92,0x09,0x2F,0x88,0x66,0x5D,0x77,0x97,0xC7,0x1D,0x76,0x13,0xA9,0xD5, -0xE5,0xF1,0x16,0x09,0x11,0x35,0xD5,0xAC,0xDB,0x24,0x71,0x70,0x2C,0x98,0x56,0x0B, -0xD9,0x17,0xB4,0xD1,0xE3,0x51,0x2B,0x5E,0x75,0xE8,0xD5,0xD0,0xDC,0x4F,0x34,0xED, -0xC2,0x05,0x66,0x80,0xA1,0xCB,0xE6,0x33, -}; - - -/* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA 2 */ -/* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA 2 */ - - -const unsigned char GeoTrust_Global_CA_2_certificate[874]={ -0x30,0x82,0x03,0x66,0x30,0x82,0x02,0x4E,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x44,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16, -0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73, -0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x13, -0x14,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C, -0x20,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D,0x30,0x34,0x30,0x33,0x30,0x34,0x30, -0x35,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x33,0x30,0x34,0x30,0x35, -0x30,0x30,0x30,0x30,0x5A,0x30,0x44,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, -0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47, -0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B, -0x06,0x03,0x55,0x04,0x03,0x13,0x14,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20, -0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x43,0x41,0x20,0x32,0x30,0x82,0x01,0x22,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82, -0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xEF,0x3C,0x4D,0x40, -0x3D,0x10,0xDF,0x3B,0x53,0x00,0xE1,0x67,0xFE,0x94,0x60,0x15,0x3E,0x85,0x88,0xF1, -0x89,0x0D,0x90,0xC8,0x28,0x23,0x99,0x05,0xE8,0x2B,0x20,0x9D,0xC6,0xF3,0x60,0x46, -0xD8,0xC1,0xB2,0xD5,0x8C,0x31,0xD9,0xDC,0x20,0x79,0x24,0x81,0xBF,0x35,0x32,0xFC, -0x63,0x69,0xDB,0xB1,0x2A,0x6B,0xEE,0x21,0x58,0xF2,0x08,0xE9,0x78,0xCB,0x6F,0xCB, -0xFC,0x16,0x52,0xC8,0x91,0xC4,0xFF,0x3D,0x73,0xDE,0xB1,0x3E,0xA7,0xC2,0x7D,0x66, -0xC1,0xF5,0x7E,0x52,0x24,0x1A,0xE2,0xD5,0x67,0x91,0xD0,0x82,0x10,0xD7,0x78,0x4B, -0x4F,0x2B,0x42,0x39,0xBD,0x64,0x2D,0x40,0xA0,0xB0,0x10,0xD3,0x38,0x48,0x46,0x88, -0xA1,0x0C,0xBB,0x3A,0x33,0x2A,0x62,0x98,0xFB,0x00,0x9D,0x13,0x59,0x7F,0x6F,0x3B, -0x72,0xAA,0xEE,0xA6,0x0F,0x86,0xF9,0x05,0x61,0xEA,0x67,0x7F,0x0C,0x37,0x96,0x8B, -0xE6,0x69,0x16,0x47,0x11,0xC2,0x27,0x59,0x03,0xB3,0xA6,0x60,0xC2,0x21,0x40,0x56, -0xFA,0xA0,0xC7,0x7D,0x3A,0x13,0xE3,0xEC,0x57,0xC7,0xB3,0xD6,0xAE,0x9D,0x89,0x80, -0xF7,0x01,0xE7,0x2C,0xF6,0x96,0x2B,0x13,0x0D,0x79,0x2C,0xD9,0xC0,0xE4,0x86,0x7B, -0x4B,0x8C,0x0C,0x72,0x82,0x8A,0xFB,0x17,0xCD,0x00,0x6C,0x3A,0x13,0x3C,0xB0,0x84, -0x87,0x4B,0x16,0x7A,0x29,0xB2,0x4F,0xDB,0x1D,0xD4,0x0B,0xF3,0x66,0x37,0xBD,0xD8, -0xF6,0x57,0xBB,0x5E,0x24,0x7A,0xB8,0x3C,0x8B,0xB9,0xFA,0x92,0x1A,0x1A,0x84,0x9E, -0xD8,0x74,0x8F,0xAA,0x1B,0x7F,0x5E,0xF4,0xFE,0x45,0x22,0x21,0x02,0x03,0x01,0x00, -0x01,0xA3,0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, -0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, -0x14,0x71,0x38,0x36,0xF2,0x02,0x31,0x53,0x47,0x2B,0x6E,0xBA,0x65,0x46,0xA9,0x10, -0x15,0x58,0x20,0x05,0x09,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, -0x80,0x14,0x71,0x38,0x36,0xF2,0x02,0x31,0x53,0x47,0x2B,0x6E,0xBA,0x65,0x46,0xA9, -0x10,0x15,0x58,0x20,0x05,0x09,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF, -0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x03,0xF7,0xB5,0x2B,0xAB,0x5D, -0x10,0xFC,0x7B,0xB2,0xB2,0x5E,0xAC,0x9B,0x0E,0x7E,0x53,0x78,0x59,0x3E,0x42,0x04, -0xFE,0x75,0xA3,0xAD,0xAC,0x81,0x4E,0xD7,0x02,0x8B,0x5E,0xC4,0x2D,0xC8,0x52,0x76, -0xC7,0x2C,0x1F,0xFC,0x81,0x32,0x98,0xD1,0x4B,0xC6,0x92,0x93,0x33,0x35,0x31,0x2F, -0xFC,0xD8,0x1D,0x44,0xDD,0xE0,0x81,0x7F,0x9D,0xE9,0x8B,0xE1,0x64,0x91,0x62,0x0B, -0x39,0x08,0x8C,0xAC,0x74,0x9D,0x59,0xD9,0x7A,0x59,0x52,0x97,0x11,0xB9,0x16,0x7B, -0x6F,0x45,0xD3,0x96,0xD9,0x31,0x7D,0x02,0x36,0x0F,0x9C,0x3B,0x6E,0xCF,0x2C,0x0D, -0x03,0x46,0x45,0xEB,0xA0,0xF4,0x7F,0x48,0x44,0xC6,0x08,0x40,0xCC,0xDE,0x1B,0x70, -0xB5,0x29,0xAD,0xBA,0x8B,0x3B,0x34,0x65,0x75,0x1B,0x71,0x21,0x1D,0x2C,0x14,0x0A, -0xB0,0x96,0x95,0xB8,0xD6,0xEA,0xF2,0x65,0xFB,0x29,0xBA,0x4F,0xEA,0x91,0x93,0x74, -0x69,0xB6,0xF2,0xFF,0xE1,0x1A,0xD0,0x0C,0xD1,0x76,0x85,0xCB,0x8A,0x25,0xBD,0x97, -0x5E,0x2C,0x6F,0x15,0x99,0x26,0xE7,0xB6,0x29,0xFF,0x22,0xEC,0xC9,0x02,0xC7,0x56, -0x00,0xCD,0x49,0xB9,0xB3,0x6C,0x7B,0x53,0x04,0x1A,0xE2,0xA8,0xC9,0xAA,0x12,0x05, -0x23,0xC2,0xCE,0xE7,0xBB,0x04,0x02,0xCC,0xC0,0x47,0xA2,0xE4,0xC4,0x29,0x2F,0x5B, -0x45,0x57,0x89,0x51,0xEE,0x3C,0xEB,0x52,0x08,0xFF,0x07,0x35,0x1E,0x9F,0x35,0x6A, -0x47,0x4A,0x56,0x98,0xD1,0x5A,0x85,0x1F,0x8C,0xF5,0x22,0xBF,0xAB,0xCE,0x83,0xF3, -0xE2,0x22,0x29,0xAE,0x7D,0x83,0x40,0xA8,0xBA,0x6C, -}; - - -/* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Primary Certification Authority */ -/* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Primary Certification Authority */ - - -const unsigned char GeoTrust_Primary_Certification_Authority_certificate[896]={ -0x30,0x82,0x03,0x7C,0x30,0x82,0x02,0x64,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x18, -0xAC,0xB5,0x6A,0xFD,0x69,0xB6,0x15,0x3A,0x63,0x6C,0xAF,0xDA,0xFA,0xC4,0xA1,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x58, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30, -0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74, -0x20,0x49,0x6E,0x63,0x2E,0x31,0x31,0x30,0x2F,0x06,0x03,0x55,0x04,0x03,0x13,0x28, -0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79, -0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41, -0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31, -0x32,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x36,0x30,0x37,0x31, -0x36,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x58,0x31,0x0B,0x30,0x09,0x06,0x03, -0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A, -0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31, -0x31,0x30,0x2F,0x06,0x03,0x55,0x04,0x03,0x13,0x28,0x47,0x65,0x6F,0x54,0x72,0x75, -0x73,0x74,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82, -0x01,0x01,0x00,0xBE,0xB8,0x15,0x7B,0xFF,0xD4,0x7C,0x7D,0x67,0xAD,0x83,0x64,0x7B, -0xC8,0x42,0x53,0x2D,0xDF,0xF6,0x84,0x08,0x20,0x61,0xD6,0x01,0x59,0x6A,0x9C,0x44, -0x11,0xAF,0xEF,0x76,0xFD,0x95,0x7E,0xCE,0x61,0x30,0xBB,0x7A,0x83,0x5F,0x02,0xBD, -0x01,0x66,0xCA,0xEE,0x15,0x8D,0x6F,0xA1,0x30,0x9C,0xBD,0xA1,0x85,0x9E,0x94,0x3A, -0xF3,0x56,0x88,0x00,0x31,0xCF,0xD8,0xEE,0x6A,0x96,0x02,0xD9,0xED,0x03,0x8C,0xFB, -0x75,0x6D,0xE7,0xEA,0xB8,0x55,0x16,0x05,0x16,0x9A,0xF4,0xE0,0x5E,0xB1,0x88,0xC0, -0x64,0x85,0x5C,0x15,0x4D,0x88,0xC7,0xB7,0xBA,0xE0,0x75,0xE9,0xAD,0x05,0x3D,0x9D, -0xC7,0x89,0x48,0xE0,0xBB,0x28,0xC8,0x03,0xE1,0x30,0x93,0x64,0x5E,0x52,0xC0,0x59, -0x70,0x22,0x35,0x57,0x88,0x8A,0xF1,0x95,0x0A,0x83,0xD7,0xBC,0x31,0x73,0x01,0x34, -0xED,0xEF,0x46,0x71,0xE0,0x6B,0x02,0xA8,0x35,0x72,0x6B,0x97,0x9B,0x66,0xE0,0xCB, -0x1C,0x79,0x5F,0xD8,0x1A,0x04,0x68,0x1E,0x47,0x02,0xE6,0x9D,0x60,0xE2,0x36,0x97, -0x01,0xDF,0xCE,0x35,0x92,0xDF,0xBE,0x67,0xC7,0x6D,0x77,0x59,0x3B,0x8F,0x9D,0xD6, -0x90,0x15,0x94,0xBC,0x42,0x34,0x10,0xC1,0x39,0xF9,0xB1,0x27,0x3E,0x7E,0xD6,0x8A, -0x75,0xC5,0xB2,0xAF,0x96,0xD3,0xA2,0xDE,0x9B,0xE4,0x98,0xBE,0x7D,0xE1,0xE9,0x81, -0xAD,0xB6,0x6F,0xFC,0xD7,0x0E,0xDA,0xE0,0x34,0xB0,0x0D,0x1A,0x77,0xE7,0xE3,0x08, -0x98,0xEF,0x58,0xFA,0x9C,0x84,0xB7,0x36,0xAF,0xC2,0xDF,0xAC,0xD2,0xF4,0x10,0x06, -0x70,0x71,0x35,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x0F,0x06,0x03, -0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06, -0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06, -0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2C,0xD5,0x50,0x41,0x97,0x15,0x8B,0xF0, -0x8F,0x36,0x61,0x5B,0x4A,0xFB,0x6B,0xD9,0x99,0xC9,0x33,0x92,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00, -0x5A,0x70,0x7F,0x2C,0xDD,0xB7,0x34,0x4F,0xF5,0x86,0x51,0xA9,0x26,0xBE,0x4B,0xB8, -0xAA,0xF1,0x71,0x0D,0xDC,0x61,0xC7,0xA0,0xEA,0x34,0x1E,0x7A,0x77,0x0F,0x04,0x35, -0xE8,0x27,0x8F,0x6C,0x90,0xBF,0x91,0x16,0x24,0x46,0x3E,0x4A,0x4E,0xCE,0x2B,0x16, -0xD5,0x0B,0x52,0x1D,0xFC,0x1F,0x67,0xA2,0x02,0x45,0x31,0x4F,0xCE,0xF3,0xFA,0x03, -0xA7,0x79,0x9D,0x53,0x6A,0xD9,0xDA,0x63,0x3A,0xF8,0x80,0xD7,0xD3,0x99,0xE1,0xA5, -0xE1,0xBE,0xD4,0x55,0x71,0x98,0x35,0x3A,0xBE,0x93,0xEA,0xAE,0xAD,0x42,0xB2,0x90, -0x6F,0xE0,0xFC,0x21,0x4D,0x35,0x63,0x33,0x89,0x49,0xD6,0x9B,0x4E,0xCA,0xC7,0xE7, -0x4E,0x09,0x00,0xF7,0xDA,0xC7,0xEF,0x99,0x62,0x99,0x77,0xB6,0x95,0x22,0x5E,0x8A, -0xA0,0xAB,0xF4,0xB8,0x78,0x98,0xCA,0x38,0x19,0x99,0xC9,0x72,0x9E,0x78,0xCD,0x4B, -0xAC,0xAF,0x19,0xA0,0x73,0x12,0x2D,0xFC,0xC2,0x41,0xBA,0x81,0x91,0xDA,0x16,0x5A, -0x31,0xB7,0xF9,0xB4,0x71,0x80,0x12,0x48,0x99,0x72,0x73,0x5A,0x59,0x53,0xC1,0x63, -0x52,0x33,0xED,0xA7,0xC9,0xD2,0x39,0x02,0x70,0xFA,0xE0,0xB1,0x42,0x66,0x29,0xAA, -0x9B,0x51,0xED,0x30,0x54,0x22,0x14,0x5F,0xD9,0xAB,0x1D,0xC1,0xE4,0x94,0xF0,0xF8, -0xF5,0x2B,0xF7,0xEA,0xCA,0x78,0x46,0xD6,0xB8,0x91,0xFD,0xA6,0x0D,0x2B,0x1A,0x14, -0x01,0x3E,0x80,0xF0,0x42,0xA0,0x95,0x07,0x5E,0x6D,0xCD,0xCC,0x4B,0xA4,0x45,0x8D, -0xAB,0x12,0xE8,0xB3,0xDE,0x5A,0xE5,0xA0,0x7C,0xE8,0x0F,0x22,0x1D,0x5A,0xE9,0x59, -}; - - -/* subject:/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 */ -/* issuer :/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 */ - - -const unsigned char GeoTrust_Primary_Certification_Authority___G2_certificate[690]={ -0x30,0x82,0x02,0xAE,0x30,0x82,0x02,0x35,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x3C, -0xB2,0xF4,0x48,0x0A,0x00,0xE2,0xFE,0xEB,0x24,0x3B,0x5E,0x60,0x3E,0xC3,0x6B,0x30, -0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x30,0x81,0x98,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49, -0x6E,0x63,0x2E,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04,0x0B,0x13,0x30,0x28,0x63, -0x29,0x20,0x32,0x30,0x30,0x37,0x20,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20, -0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F, -0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x36, -0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73, -0x74,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66, -0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74, -0x79,0x20,0x2D,0x20,0x47,0x32,0x30,0x1E,0x17,0x0D,0x30,0x37,0x31,0x31,0x30,0x35, -0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31,0x38,0x32, -0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x98,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, -0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13, -0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x39, -0x30,0x37,0x06,0x03,0x55,0x04,0x0B,0x13,0x30,0x28,0x63,0x29,0x20,0x32,0x30,0x30, -0x37,0x20,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x20, -0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64, -0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x36,0x30,0x34,0x06,0x03,0x55, -0x04,0x03,0x13,0x2D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x50,0x72,0x69, -0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69, -0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47, -0x32,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05, -0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x15,0xB1,0xE8,0xFD,0x03,0x15,0x43, -0xE5,0xAC,0xEB,0x87,0x37,0x11,0x62,0xEF,0xD2,0x83,0x36,0x52,0x7D,0x45,0x57,0x0B, -0x4A,0x8D,0x7B,0x54,0x3B,0x3A,0x6E,0x5F,0x15,0x02,0xC0,0x50,0xA6,0xCF,0x25,0x2F, -0x7D,0xCA,0x48,0xB8,0xC7,0x50,0x63,0x1C,0x2A,0x21,0x08,0x7C,0x9A,0x36,0xD8,0x0B, -0xFE,0xD1,0x26,0xC5,0x58,0x31,0x30,0x28,0x25,0xF3,0x5D,0x5D,0xA3,0xB8,0xB6,0xA5, -0xB4,0x92,0xED,0x6C,0x2C,0x9F,0xEB,0xDD,0x43,0x89,0xA2,0x3C,0x4B,0x48,0x91,0x1D, -0x50,0xEC,0x26,0xDF,0xD6,0x60,0x2E,0xBD,0x21,0xA3,0x42,0x30,0x40,0x30,0x0F,0x06, -0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E, -0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D, -0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x15,0x5F,0x35,0x57,0x51,0x55,0xFB, -0x25,0xB2,0xAD,0x03,0x69,0xFC,0x01,0xA3,0xFA,0xBE,0x11,0x55,0xD5,0x30,0x0A,0x06, -0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x03,0x67,0x00,0x30,0x64,0x02,0x30, -0x64,0x96,0x59,0xA6,0xE8,0x09,0xDE,0x8B,0xBA,0xFA,0x5A,0x88,0x88,0xF0,0x1F,0x91, -0xD3,0x46,0xA8,0xF2,0x4A,0x4C,0x02,0x63,0xFB,0x6C,0x5F,0x38,0xDB,0x2E,0x41,0x93, -0xA9,0x0E,0xE6,0x9D,0xDC,0x31,0x1C,0xB2,0xA0,0xA7,0x18,0x1C,0x79,0xE1,0xC7,0x36, -0x02,0x30,0x3A,0x56,0xAF,0x9A,0x74,0x6C,0xF6,0xFB,0x83,0xE0,0x33,0xD3,0x08,0x5F, -0xA1,0x9C,0xC2,0x5B,0x9F,0x46,0xD6,0xB6,0xCB,0x91,0x06,0x63,0xA2,0x06,0xE7,0x33, -0xAC,0x3E,0xA8,0x81,0x12,0xD0,0xCB,0xBA,0xD0,0x92,0x0B,0xB6,0x9E,0x96,0xAA,0x04, -0x0F,0x8A, -}; - - -/* subject:/C=US/O=GeoTrust Inc./OU=(c) 2008 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G3 */ -/* issuer :/C=US/O=GeoTrust Inc./OU=(c) 2008 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G3 */ - - -const unsigned char GeoTrust_Primary_Certification_Authority___G3_certificate[1026]={ -0x30,0x82,0x03,0xFE,0x30,0x82,0x02,0xE6,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x15, -0xAC,0x6E,0x94,0x19,0xB2,0x79,0x4B,0x41,0xF6,0x27,0xA9,0xC3,0x18,0x0F,0x1F,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, -0x98,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16, -0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73, -0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04,0x0B,0x13, -0x30,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x38,0x20,0x47,0x65,0x6F,0x54,0x72,0x75, -0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75, -0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C, -0x79,0x31,0x36,0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x47,0x65,0x6F,0x54, -0x72,0x75,0x73,0x74,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72, -0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F, -0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30, -0x34,0x30,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x37,0x31,0x32, -0x30,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x98,0x31,0x0B,0x30,0x09, -0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55, -0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63, -0x2E,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04,0x0B,0x13,0x30,0x28,0x63,0x29,0x20, -0x32,0x30,0x30,0x38,0x20,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E, -0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69, -0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x36,0x30,0x34, -0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20, -0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, -0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20, -0x2D,0x20,0x47,0x33,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A, -0x02,0x82,0x01,0x01,0x00,0xDC,0xE2,0x5E,0x62,0x58,0x1D,0x33,0x57,0x39,0x32,0x33, -0xFA,0xEB,0xCB,0x87,0x8C,0xA7,0xD4,0x4A,0xDD,0x06,0x88,0xEA,0x64,0x8E,0x31,0x98, -0xA5,0x38,0x90,0x1E,0x98,0xCF,0x2E,0x63,0x2B,0xF0,0x46,0xBC,0x44,0xB2,0x89,0xA1, -0xC0,0x28,0x0C,0x49,0x70,0x21,0x95,0x9F,0x64,0xC0,0xA6,0x93,0x12,0x02,0x65,0x26, -0x86,0xC6,0xA5,0x89,0xF0,0xFA,0xD7,0x84,0xA0,0x70,0xAF,0x4F,0x1A,0x97,0x3F,0x06, -0x44,0xD5,0xC9,0xEB,0x72,0x10,0x7D,0xE4,0x31,0x28,0xFB,0x1C,0x61,0xE6,0x28,0x07, -0x44,0x73,0x92,0x22,0x69,0xA7,0x03,0x88,0x6C,0x9D,0x63,0xC8,0x52,0xDA,0x98,0x27, -0xE7,0x08,0x4C,0x70,0x3E,0xB4,0xC9,0x12,0xC1,0xC5,0x67,0x83,0x5D,0x33,0xF3,0x03, -0x11,0xEC,0x6A,0xD0,0x53,0xE2,0xD1,0xBA,0x36,0x60,0x94,0x80,0xBB,0x61,0x63,0x6C, -0x5B,0x17,0x7E,0xDF,0x40,0x94,0x1E,0xAB,0x0D,0xC2,0x21,0x28,0x70,0x88,0xFF,0xD6, -0x26,0x6C,0x6C,0x60,0x04,0x25,0x4E,0x55,0x7E,0x7D,0xEF,0xBF,0x94,0x48,0xDE,0xB7, -0x1D,0xDD,0x70,0x8D,0x05,0x5F,0x88,0xA5,0x9B,0xF2,0xC2,0xEE,0xEA,0xD1,0x40,0x41, -0x6D,0x62,0x38,0x1D,0x56,0x06,0xC5,0x03,0x47,0x51,0x20,0x19,0xFC,0x7B,0x10,0x0B, -0x0E,0x62,0xAE,0x76,0x55,0xBF,0x5F,0x77,0xBE,0x3E,0x49,0x01,0x53,0x3D,0x98,0x25, -0x03,0x76,0x24,0x5A,0x1D,0xB4,0xDB,0x89,0xEA,0x79,0xE5,0xB6,0xB3,0x3B,0x3F,0xBA, -0x4C,0x28,0x41,0x7F,0x06,0xAC,0x6A,0x8E,0xC1,0xD0,0xF6,0x05,0x1D,0x7D,0xE6,0x42, -0x86,0xE3,0xA5,0xD5,0x47,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x0F, -0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30, -0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30, -0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xC4,0x79,0xCA,0x8E,0xA1,0x4E, -0x03,0x1D,0x1C,0xDC,0x6B,0xDB,0x31,0x5B,0x94,0x3E,0x3F,0x30,0x7F,0x2D,0x30,0x0D, -0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01, -0x01,0x00,0x2D,0xC5,0x13,0xCF,0x56,0x80,0x7B,0x7A,0x78,0xBD,0x9F,0xAE,0x2C,0x99, -0xE7,0xEF,0xDA,0xDF,0x94,0x5E,0x09,0x69,0xA7,0xE7,0x6E,0x68,0x8C,0xBD,0x72,0xBE, -0x47,0xA9,0x0E,0x97,0x12,0xB8,0x4A,0xF1,0x64,0xD3,0x39,0xDF,0x25,0x34,0xD4,0xC1, -0xCD,0x4E,0x81,0xF0,0x0F,0x04,0xC4,0x24,0xB3,0x34,0x96,0xC6,0xA6,0xAA,0x30,0xDF, -0x68,0x61,0x73,0xD7,0xF9,0x8E,0x85,0x89,0xEF,0x0E,0x5E,0x95,0x28,0x4A,0x2A,0x27, -0x8F,0x10,0x8E,0x2E,0x7C,0x86,0xC4,0x02,0x9E,0xDA,0x0C,0x77,0x65,0x0E,0x44,0x0D, -0x92,0xFD,0xFD,0xB3,0x16,0x36,0xFA,0x11,0x0D,0x1D,0x8C,0x0E,0x07,0x89,0x6A,0x29, -0x56,0xF7,0x72,0xF4,0xDD,0x15,0x9C,0x77,0x35,0x66,0x57,0xAB,0x13,0x53,0xD8,0x8E, -0xC1,0x40,0xC5,0xD7,0x13,0x16,0x5A,0x72,0xC7,0xB7,0x69,0x01,0xC4,0x7A,0xB1,0x83, -0x01,0x68,0x7D,0x8D,0x41,0xA1,0x94,0x18,0xC1,0x25,0x5C,0xFC,0xF0,0xFE,0x83,0x02, -0x87,0x7C,0x0D,0x0D,0xCF,0x2E,0x08,0x5C,0x4A,0x40,0x0D,0x3E,0xEC,0x81,0x61,0xE6, -0x24,0xDB,0xCA,0xE0,0x0E,0x2D,0x07,0xB2,0x3E,0x56,0xDC,0x8D,0xF5,0x41,0x85,0x07, -0x48,0x9B,0x0C,0x0B,0xCB,0x49,0x3F,0x7D,0xEC,0xB7,0xFD,0xCB,0x8D,0x67,0x89,0x1A, -0xAB,0xED,0xBB,0x1E,0xA3,0x00,0x08,0x08,0x17,0x2A,0x82,0x5C,0x31,0x5D,0x46,0x8A, -0x2D,0x0F,0x86,0x9B,0x74,0xD9,0x45,0xFB,0xD4,0x40,0xB1,0x7A,0xAA,0x68,0x2D,0x86, -0xB2,0x99,0x22,0xE1,0xC1,0x2B,0xC7,0x9C,0xF8,0xF3,0x5F,0xA8,0x82,0x12,0xEB,0x19, -0x11,0x2D, -}; - - -/* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Universal CA */ -/* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Universal CA */ - - -const unsigned char GeoTrust_Universal_CA_certificate[1388]={ -0x30,0x82,0x05,0x68,0x30,0x82,0x03,0x50,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x45,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16, -0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73, -0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x13, -0x15,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x55,0x6E,0x69,0x76,0x65,0x72, -0x73,0x61,0x6C,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x34,0x30,0x33,0x30,0x34, -0x30,0x35,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x33,0x30,0x34,0x30, -0x35,0x30,0x30,0x30,0x30,0x5A,0x30,0x45,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, -0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D, -0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1E,0x30, -0x1C,0x06,0x03,0x55,0x04,0x03,0x13,0x15,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74, -0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x30,0x82,0x02, -0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00, -0x03,0x82,0x02,0x0F,0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02,0x01,0x00,0xA6,0x15, -0x55,0xA0,0xA3,0xC6,0xE0,0x1F,0x8C,0x9D,0x21,0x50,0xD7,0xC1,0xBE,0x2B,0x5B,0xB5, -0xA4,0x9E,0xA1,0xD9,0x72,0x58,0xBD,0x00,0x1B,0x4C,0xBF,0x61,0xC9,0x14,0x1D,0x45, -0x82,0xAB,0xC6,0x1D,0x80,0xD6,0x3D,0xEB,0x10,0x9C,0x3A,0xAF,0x6D,0x24,0xF8,0xBC, -0x71,0x01,0x9E,0x06,0xF5,0x7C,0x5F,0x1E,0xC1,0x0E,0x55,0xCA,0x83,0x9A,0x59,0x30, -0xAE,0x19,0xCB,0x30,0x48,0x95,0xED,0x22,0x37,0x8D,0xF4,0x4A,0x9A,0x72,0x66,0x3E, -0xAD,0x95,0xC0,0xE0,0x16,0x00,0xE0,0x10,0x1F,0x2B,0x31,0x0E,0xD7,0x94,0x54,0xD3, -0x42,0x33,0xA0,0x34,0x1D,0x1E,0x45,0x76,0xDD,0x4F,0xCA,0x18,0x37,0xEC,0x85,0x15, -0x7A,0x19,0x08,0xFC,0xD5,0xC7,0x9C,0xF0,0xF2,0xA9,0x2E,0x10,0xA9,0x92,0xE6,0x3D, -0x58,0x3D,0xA9,0x16,0x68,0x3C,0x2F,0x75,0x21,0x18,0x7F,0x28,0x77,0xA5,0xE1,0x61, -0x17,0xB7,0xA6,0xE9,0xF8,0x1E,0x99,0xDB,0x73,0x6E,0xF4,0x0A,0xA2,0x21,0x6C,0xEE, -0xDA,0xAA,0x85,0x92,0x66,0xAF,0xF6,0x7A,0x6B,0x82,0xDA,0xBA,0x22,0x08,0x35,0x0F, -0xCF,0x42,0xF1,0x35,0xFA,0x6A,0xEE,0x7E,0x2B,0x25,0xCC,0x3A,0x11,0xE4,0x6D,0xAF, -0x73,0xB2,0x76,0x1D,0xAD,0xD0,0xB2,0x78,0x67,0x1A,0xA4,0x39,0x1C,0x51,0x0B,0x67, -0x56,0x83,0xFD,0x38,0x5D,0x0D,0xCE,0xDD,0xF0,0xBB,0x2B,0x96,0x1F,0xDE,0x7B,0x32, -0x52,0xFD,0x1D,0xBB,0xB5,0x06,0xA1,0xB2,0x21,0x5E,0xA5,0xD6,0x95,0x68,0x7F,0xF0, -0x99,0x9E,0xDC,0x45,0x08,0x3E,0xE7,0xD2,0x09,0x0D,0x35,0x94,0xDD,0x80,0x4E,0x53, -0x97,0xD7,0xB5,0x09,0x44,0x20,0x64,0x16,0x17,0x03,0x02,0x4C,0x53,0x0D,0x68,0xDE, -0xD5,0xAA,0x72,0x4D,0x93,0x6D,0x82,0x0E,0xDB,0x9C,0xBD,0xCF,0xB4,0xF3,0x5C,0x5D, -0x54,0x7A,0x69,0x09,0x96,0xD6,0xDB,0x11,0xC1,0x8D,0x75,0xA8,0xB4,0xCF,0x39,0xC8, -0xCE,0x3C,0xBC,0x24,0x7C,0xE6,0x62,0xCA,0xE1,0xBD,0x7D,0xA7,0xBD,0x57,0x65,0x0B, -0xE4,0xFE,0x25,0xED,0xB6,0x69,0x10,0xDC,0x28,0x1A,0x46,0xBD,0x01,0x1D,0xD0,0x97, -0xB5,0xE1,0x98,0x3B,0xC0,0x37,0x64,0xD6,0x3D,0x94,0xEE,0x0B,0xE1,0xF5,0x28,0xAE, -0x0B,0x56,0xBF,0x71,0x8B,0x23,0x29,0x41,0x8E,0x86,0xC5,0x4B,0x52,0x7B,0xD8,0x71, -0xAB,0x1F,0x8A,0x15,0xA6,0x3B,0x83,0x5A,0xD7,0x58,0x01,0x51,0xC6,0x4C,0x41,0xD9, -0x7F,0xD8,0x41,0x67,0x72,0xA2,0x28,0xDF,0x60,0x83,0xA9,0x9E,0xC8,0x7B,0xFC,0x53, -0x73,0x72,0x59,0xF5,0x93,0x7A,0x17,0x76,0x0E,0xCE,0xF7,0xE5,0x5C,0xD9,0x0B,0x55, -0x34,0xA2,0xAA,0x5B,0xB5,0x6A,0x54,0xE7,0x13,0xCA,0x57,0xEC,0x97,0x6D,0xF4,0x5E, -0x06,0x2F,0x45,0x8B,0x58,0xD4,0x23,0x16,0x92,0xE4,0x16,0x6E,0x28,0x63,0x59,0x30, -0xDF,0x50,0x01,0x9C,0x63,0x89,0x1A,0x9F,0xDB,0x17,0x94,0x82,0x70,0x37,0xC3,0x24, -0x9E,0x9A,0x47,0xD6,0x5A,0xCA,0x4E,0xA8,0x69,0x89,0x72,0x1F,0x91,0x6C,0xDB,0x7E, -0x9E,0x1B,0xAD,0xC7,0x1F,0x73,0xDD,0x2C,0x4F,0x19,0x65,0xFD,0x7F,0x93,0x40,0x10, -0x2E,0xD2,0xF0,0xED,0x3C,0x9E,0x2E,0x28,0x3E,0x69,0x26,0x33,0xC5,0x7B,0x02,0x03, -0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01, -0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, -0x16,0x04,0x14,0xDA,0xBB,0x2E,0xAA,0xB0,0x0C,0xB8,0x88,0x26,0x51,0x74,0x5C,0x6D, -0x03,0xD3,0xC0,0xD8,0x8F,0x7A,0xD6,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, -0x30,0x16,0x80,0x14,0xDA,0xBB,0x2E,0xAA,0xB0,0x0C,0xB8,0x88,0x26,0x51,0x74,0x5C, -0x6D,0x03,0xD3,0xC0,0xD8,0x8F,0x7A,0xD6,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01, -0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x31,0x78,0xE6,0xC7, -0xB5,0xDF,0xB8,0x94,0x40,0xC9,0x71,0xC4,0xA8,0x35,0xEC,0x46,0x1D,0xC2,0x85,0xF3, -0x28,0x58,0x86,0xB0,0x0B,0xFC,0x8E,0xB2,0x39,0x8F,0x44,0x55,0xAB,0x64,0x84,0x5C, -0x69,0xA9,0xD0,0x9A,0x38,0x3C,0xFA,0xE5,0x1F,0x35,0xE5,0x44,0xE3,0x80,0x79,0x94, -0x68,0xA4,0xBB,0xC4,0x9F,0x3D,0xE1,0x34,0xCD,0x30,0x46,0x8B,0x54,0x2B,0x95,0xA5, -0xEF,0xF7,0x3F,0x99,0x84,0xFD,0x35,0xE6,0xCF,0x31,0xC6,0xDC,0x6A,0xBF,0xA7,0xD7, -0x23,0x08,0xE1,0x98,0x5E,0xC3,0x5A,0x08,0x76,0xA9,0xA6,0xAF,0x77,0x2F,0xB7,0x60, -0xBD,0x44,0x46,0x6A,0xEF,0x97,0xFF,0x73,0x95,0xC1,0x8E,0xE8,0x93,0xFB,0xFD,0x31, -0xB7,0xEC,0x57,0x11,0x11,0x45,0x9B,0x30,0xF1,0x1A,0x88,0x39,0xC1,0x4F,0x3C,0xA7, -0x00,0xD5,0xC7,0xFC,0xAB,0x6D,0x80,0x22,0x70,0xA5,0x0C,0xE0,0x5D,0x04,0x29,0x02, -0xFB,0xCB,0xA0,0x91,0xD1,0x7C,0xD6,0xC3,0x7E,0x50,0xD5,0x9D,0x58,0xBE,0x41,0x38, -0xEB,0xB9,0x75,0x3C,0x15,0xD9,0x9B,0xC9,0x4A,0x83,0x59,0xC0,0xDA,0x53,0xFD,0x33, -0xBB,0x36,0x18,0x9B,0x85,0x0F,0x15,0xDD,0xEE,0x2D,0xAC,0x76,0x93,0xB9,0xD9,0x01, -0x8D,0x48,0x10,0xA8,0xFB,0xF5,0x38,0x86,0xF1,0xDB,0x0A,0xC6,0xBD,0x84,0xA3,0x23, -0x41,0xDE,0xD6,0x77,0x6F,0x85,0xD4,0x85,0x1C,0x50,0xE0,0xAE,0x51,0x8A,0xBA,0x8D, -0x3E,0x76,0xE2,0xB9,0xCA,0x27,0xF2,0x5F,0x9F,0xEF,0x6E,0x59,0x0D,0x06,0xD8,0x2B, -0x17,0xA4,0xD2,0x7C,0x6B,0xBB,0x5F,0x14,0x1A,0x48,0x8F,0x1A,0x4C,0xE7,0xB3,0x47, -0x1C,0x8E,0x4C,0x45,0x2B,0x20,0xEE,0x48,0xDF,0xE7,0xDD,0x09,0x8E,0x18,0xA8,0xDA, -0x40,0x8D,0x92,0x26,0x11,0x53,0x61,0x73,0x5D,0xEB,0xBD,0xE7,0xC4,0x4D,0x29,0x37, -0x61,0xEB,0xAC,0x39,0x2D,0x67,0x2E,0x16,0xD6,0xF5,0x00,0x83,0x85,0xA1,0xCC,0x7F, -0x76,0xC4,0x7D,0xE4,0xB7,0x4B,0x66,0xEF,0x03,0x45,0x60,0x69,0xB6,0x0C,0x52,0x96, -0x92,0x84,0x5E,0xA6,0xA3,0xB5,0xA4,0x3E,0x2B,0xD9,0xCC,0xD8,0x1B,0x47,0xAA,0xF2, -0x44,0xDA,0x4F,0xF9,0x03,0xE8,0xF0,0x14,0xCB,0x3F,0xF3,0x83,0xDE,0xD0,0xC1,0x54, -0xE3,0xB7,0xE8,0x0A,0x37,0x4D,0x8B,0x20,0x59,0x03,0x30,0x19,0xA1,0x2C,0xC8,0xBD, -0x11,0x1F,0xDF,0xAE,0xC9,0x4A,0xC5,0xF3,0x27,0x66,0x66,0x86,0xAC,0x68,0x91,0xFF, -0xD9,0xE6,0x53,0x1C,0x0F,0x8B,0x5C,0x69,0x65,0x0A,0x26,0xC8,0x1E,0x34,0xC3,0x5D, -0x51,0x7B,0xD7,0xA9,0x9C,0x06,0xA1,0x36,0xDD,0xD5,0x89,0x94,0xBC,0xD9,0xE4,0x2D, -0x0C,0x5E,0x09,0x6C,0x08,0x97,0x7C,0xA3,0x3D,0x7C,0x93,0xFF,0x3F,0xA1,0x14,0xA7, -0xCF,0xB5,0x5D,0xEB,0xDB,0xDB,0x1C,0xC4,0x76,0xDF,0x88,0xB9,0xBD,0x45,0x05,0x95, -0x1B,0xAE,0xFC,0x46,0x6A,0x4C,0xAF,0x48,0xE3,0xCE,0xAE,0x0F,0xD2,0x7E,0xEB,0xE6, -0x6C,0x9C,0x4F,0x81,0x6A,0x7A,0x64,0xAC,0xBB,0x3E,0xD5,0xE7,0xCB,0x76,0x2E,0xC5, -0xA7,0x48,0xC1,0x5C,0x90,0x0F,0xCB,0xC8,0x3F,0xFA,0xE6,0x32,0xE1,0x8D,0x1B,0x6F, -0xA4,0xE6,0x8E,0xD8,0xF9,0x29,0x48,0x8A,0xCE,0x73,0xFE,0x2C, -}; - - -/* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Universal CA 2 */ -/* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Universal CA 2 */ - - -const unsigned char GeoTrust_Universal_CA_2_certificate[1392]={ -0x30,0x82,0x05,0x6C,0x30,0x82,0x03,0x54,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x47,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16, -0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73, -0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13, -0x17,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x55,0x6E,0x69,0x76,0x65,0x72, -0x73,0x61,0x6C,0x20,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D,0x30,0x34,0x30,0x33, -0x30,0x34,0x30,0x35,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x33,0x30, -0x34,0x30,0x35,0x30,0x30,0x30,0x30,0x5A,0x30,0x47,0x31,0x0B,0x30,0x09,0x06,0x03, -0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A, -0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31, -0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x47,0x65,0x6F,0x54,0x72,0x75, -0x73,0x74,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x20, -0x32,0x30,0x82,0x02,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x01,0x05,0x00,0x03,0x82,0x02,0x0F,0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02, -0x01,0x00,0xB3,0x54,0x52,0xC1,0xC9,0x3E,0xF2,0xD9,0xDC,0xB1,0x53,0x1A,0x59,0x29, -0xE7,0xB1,0xC3,0x45,0x28,0xE5,0xD7,0xD1,0xED,0xC5,0xC5,0x4B,0xA1,0xAA,0x74,0x7B, -0x57,0xAF,0x4A,0x26,0xFC,0xD8,0xF5,0x5E,0xA7,0x6E,0x19,0xDB,0x74,0x0C,0x4F,0x35, -0x5B,0x32,0x0B,0x01,0xE3,0xDB,0xEB,0x7A,0x77,0x35,0xEA,0xAA,0x5A,0xE0,0xD6,0xE8, -0xA1,0x57,0x94,0xF0,0x90,0xA3,0x74,0x56,0x94,0x44,0x30,0x03,0x1E,0x5C,0x4E,0x2B, -0x85,0x26,0x74,0x82,0x7A,0x0C,0x76,0xA0,0x6F,0x4D,0xCE,0x41,0x2D,0xA0,0x15,0x06, -0x14,0x5F,0xB7,0x42,0xCD,0x7B,0x8F,0x58,0x61,0x34,0xDC,0x2A,0x08,0xF9,0x2E,0xC3, -0x01,0xA6,0x22,0x44,0x1C,0x4C,0x07,0x82,0xE6,0x5B,0xCE,0xD0,0x4A,0x7C,0x04,0xD3, -0x19,0x73,0x27,0xF0,0xAA,0x98,0x7F,0x2E,0xAF,0x4E,0xEB,0x87,0x1E,0x24,0x77,0x6A, -0x5D,0xB6,0xE8,0x5B,0x45,0xBA,0xDC,0xC3,0xA1,0x05,0x6F,0x56,0x8E,0x8F,0x10,0x26, -0xA5,0x49,0xC3,0x2E,0xD7,0x41,0x87,0x22,0xE0,0x4F,0x86,0xCA,0x60,0xB5,0xEA,0xA1, -0x63,0xC0,0x01,0x97,0x10,0x79,0xBD,0x00,0x3C,0x12,0x6D,0x2B,0x15,0xB1,0xAC,0x4B, -0xB1,0xEE,0x18,0xB9,0x4E,0x96,0xDC,0xDC,0x76,0xFF,0x3B,0xBE,0xCF,0x5F,0x03,0xC0, -0xFC,0x3B,0xE8,0xBE,0x46,0x1B,0xFF,0xDA,0x40,0xC2,0x52,0xF7,0xFE,0xE3,0x3A,0xF7, -0x6A,0x77,0x35,0xD0,0xDA,0x8D,0xEB,0x5E,0x18,0x6A,0x31,0xC7,0x1E,0xBA,0x3C,0x1B, -0x28,0xD6,0x6B,0x54,0xC6,0xAA,0x5B,0xD7,0xA2,0x2C,0x1B,0x19,0xCC,0xA2,0x02,0xF6, -0x9B,0x59,0xBD,0x37,0x6B,0x86,0xB5,0x6D,0x82,0xBA,0xD8,0xEA,0xC9,0x56,0xBC,0xA9, -0x36,0x58,0xFD,0x3E,0x19,0xF3,0xED,0x0C,0x26,0xA9,0x93,0x38,0xF8,0x4F,0xC1,0x5D, -0x22,0x06,0xD0,0x97,0xEA,0xE1,0xAD,0xC6,0x55,0xE0,0x81,0x2B,0x28,0x83,0x3A,0xFA, -0xF4,0x7B,0x21,0x51,0x00,0xBE,0x52,0x38,0xCE,0xCD,0x66,0x79,0xA8,0xF4,0x81,0x56, -0xE2,0xD0,0x83,0x09,0x47,0x51,0x5B,0x50,0x6A,0xCF,0xDB,0x48,0x1A,0x5D,0x3E,0xF7, -0xCB,0xF6,0x65,0xF7,0x6C,0xF1,0x95,0xF8,0x02,0x3B,0x32,0x56,0x82,0x39,0x7A,0x5B, -0xBD,0x2F,0x89,0x1B,0xBF,0xA1,0xB4,0xE8,0xFF,0x7F,0x8D,0x8C,0xDF,0x03,0xF1,0x60, -0x4E,0x58,0x11,0x4C,0xEB,0xA3,0x3F,0x10,0x2B,0x83,0x9A,0x01,0x73,0xD9,0x94,0x6D, -0x84,0x00,0x27,0x66,0xAC,0xF0,0x70,0x40,0x09,0x42,0x92,0xAD,0x4F,0x93,0x0D,0x61, -0x09,0x51,0x24,0xD8,0x92,0xD5,0x0B,0x94,0x61,0xB2,0x87,0xB2,0xED,0xFF,0x9A,0x35, -0xFF,0x85,0x54,0xCA,0xED,0x44,0x43,0xAC,0x1B,0x3C,0x16,0x6B,0x48,0x4A,0x0A,0x1C, -0x40,0x88,0x1F,0x92,0xC2,0x0B,0x00,0x05,0xFF,0xF2,0xC8,0x02,0x4A,0xA4,0xAA,0xA9, -0xCC,0x99,0x96,0x9C,0x2F,0x58,0xE0,0x7D,0xE1,0xBE,0xBB,0x07,0xDC,0x5F,0x04,0x72, -0x5C,0x31,0x34,0xC3,0xEC,0x5F,0x2D,0xE0,0x3D,0x64,0x90,0x22,0xE6,0xD1,0xEC,0xB8, -0x2E,0xDD,0x59,0xAE,0xD9,0xA1,0x37,0xBF,0x54,0x35,0xDC,0x73,0x32,0x4F,0x8C,0x04, -0x1E,0x33,0xB2,0xC9,0x46,0xF1,0xD8,0x5C,0xC8,0x55,0x50,0xC9,0x68,0xBD,0xA8,0xBA, -0x36,0x09,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55, -0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03, -0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x76,0xF3,0x55,0xE1,0xFA,0xA4,0x36,0xFB,0xF0, -0x9F,0x5C,0x62,0x71,0xED,0x3C,0xF4,0x47,0x38,0x10,0x2B,0x30,0x1F,0x06,0x03,0x55, -0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x76,0xF3,0x55,0xE1,0xFA,0xA4,0x36,0xFB, -0xF0,0x9F,0x5C,0x62,0x71,0xED,0x3C,0xF4,0x47,0x38,0x10,0x2B,0x30,0x0E,0x06,0x03, -0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x02,0x01,0x00, -0x66,0xC1,0xC6,0x23,0xF3,0xD9,0xE0,0x2E,0x6E,0x5F,0xE8,0xCF,0xAE,0xB0,0xB0,0x25, -0x4D,0x2B,0xF8,0x3B,0x58,0x9B,0x40,0x24,0x37,0x5A,0xCB,0xAB,0x16,0x49,0xFF,0xB3, -0x75,0x79,0x33,0xA1,0x2F,0x6D,0x70,0x17,0x34,0x91,0xFE,0x67,0x7E,0x8F,0xEC,0x9B, -0xE5,0x5E,0x82,0xA9,0x55,0x1F,0x2F,0xDC,0xD4,0x51,0x07,0x12,0xFE,0xAC,0x16,0x3E, -0x2C,0x35,0xC6,0x63,0xFC,0xDC,0x10,0xEB,0x0D,0xA3,0xAA,0xD0,0x7C,0xCC,0xD1,0xD0, -0x2F,0x51,0x2E,0xC4,0x14,0x5A,0xDE,0xE8,0x19,0xE1,0x3E,0xC6,0xCC,0xA4,0x29,0xE7, -0x2E,0x84,0xAA,0x06,0x30,0x78,0x76,0x54,0x73,0x28,0x98,0x59,0x38,0xE0,0x00,0x0D, -0x62,0xD3,0x42,0x7D,0x21,0x9F,0xAE,0x3D,0x3A,0x8C,0xD5,0xFA,0x77,0x0D,0x18,0x2B, -0x16,0x0E,0x5F,0x36,0xE1,0xFC,0x2A,0xB5,0x30,0x24,0xCF,0xE0,0x63,0x0C,0x7B,0x58, -0x1A,0xFE,0x99,0xBA,0x42,0x12,0xB1,0x91,0xF4,0x7C,0x68,0xE2,0xC8,0xE8,0xAF,0x2C, -0xEA,0xC9,0x7E,0xAE,0xBB,0x2A,0x3D,0x0D,0x15,0xDC,0x34,0x95,0xB6,0x18,0x74,0xA8, -0x6A,0x0F,0xC7,0xB4,0xF4,0x13,0xC4,0xE4,0x5B,0xED,0x0A,0xD2,0xA4,0x97,0x4C,0x2A, -0xED,0x2F,0x6C,0x12,0x89,0x3D,0xF1,0x27,0x70,0xAA,0x6A,0x03,0x52,0x21,0x9F,0x40, -0xA8,0x67,0x50,0xF2,0xF3,0x5A,0x1F,0xDF,0xDF,0x23,0xF6,0xDC,0x78,0x4E,0xE6,0x98, -0x4F,0x55,0x3A,0x53,0xE3,0xEF,0xF2,0xF4,0x9F,0xC7,0x7C,0xD8,0x58,0xAF,0x29,0x22, -0x97,0xB8,0xE0,0xBD,0x91,0x2E,0xB0,0x76,0xEC,0x57,0x11,0xCF,0xEF,0x29,0x44,0xF3, -0xE9,0x85,0x7A,0x60,0x63,0xE4,0x5D,0x33,0x89,0x17,0xD9,0x31,0xAA,0xDA,0xD6,0xF3, -0x18,0x35,0x72,0xCF,0x87,0x2B,0x2F,0x63,0x23,0x84,0x5D,0x84,0x8C,0x3F,0x57,0xA0, -0x88,0xFC,0x99,0x91,0x28,0x26,0x69,0x99,0xD4,0x8F,0x97,0x44,0xBE,0x8E,0xD5,0x48, -0xB1,0xA4,0x28,0x29,0xF1,0x15,0xB4,0xE1,0xE5,0x9E,0xDD,0xF8,0x8F,0xA6,0x6F,0x26, -0xD7,0x09,0x3C,0x3A,0x1C,0x11,0x0E,0xA6,0x6C,0x37,0xF7,0xAD,0x44,0x87,0x2C,0x28, -0xC7,0xD8,0x74,0x82,0xB3,0xD0,0x6F,0x4A,0x57,0xBB,0x35,0x29,0x27,0xA0,0x8B,0xE8, -0x21,0xA7,0x87,0x64,0x36,0x5D,0xCC,0xD8,0x16,0xAC,0xC7,0xB2,0x27,0x40,0x92,0x55, -0x38,0x28,0x8D,0x51,0x6E,0xDD,0x14,0x67,0x53,0x6C,0x71,0x5C,0x26,0x84,0x4D,0x75, -0x5A,0xB6,0x7E,0x60,0x56,0xA9,0x4D,0xAD,0xFB,0x9B,0x1E,0x97,0xF3,0x0D,0xD9,0xD2, -0x97,0x54,0x77,0xDA,0x3D,0x12,0xB7,0xE0,0x1E,0xEF,0x08,0x06,0xAC,0xF9,0x85,0x87, -0xE9,0xA2,0xDC,0xAF,0x7E,0x18,0x12,0x83,0xFD,0x56,0x17,0x41,0x2E,0xD5,0x29,0x82, -0x7D,0x99,0xF4,0x31,0xF6,0x71,0xA9,0xCF,0x2C,0x01,0x27,0xA5,0x05,0xB9,0xAA,0xB2, -0x48,0x4E,0x2A,0xEF,0x9F,0x93,0x52,0x51,0x95,0x3C,0x52,0x73,0x8E,0x56,0x4C,0x17, -0x40,0xC0,0x09,0x28,0xE4,0x8B,0x6A,0x48,0x53,0xDB,0xEC,0xCD,0x55,0x55,0xF1,0xC6, -0xF8,0xE9,0xA2,0x2C,0x4C,0xA6,0xD1,0x26,0x5F,0x7E,0xAF,0x5A,0x4C,0xDA,0x1F,0xA6, -0xF2,0x1C,0x2C,0x7E,0xAE,0x02,0x16,0xD2,0x56,0xD0,0x2F,0x57,0x53,0x47,0xE8,0x92, -}; - - -/* subject:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA */ -/* issuer :/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA */ - - -const unsigned char GlobalSign_Root_CA_certificate[889]={ -0x30,0x82,0x03,0x75,0x30,0x82,0x02,0x5D,0xA0,0x03,0x02,0x01,0x02,0x02,0x0B,0x04, -0x00,0x00,0x00,0x00,0x01,0x15,0x4B,0x5A,0xC3,0x94,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x57,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x42,0x45,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04, -0x0A,0x13,0x10,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x6E,0x76, -0x2D,0x73,0x61,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0B,0x13,0x07,0x52,0x6F, -0x6F,0x74,0x20,0x43,0x41,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12, -0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20, -0x43,0x41,0x30,0x1E,0x17,0x0D,0x39,0x38,0x30,0x39,0x30,0x31,0x31,0x32,0x30,0x30, -0x30,0x30,0x5A,0x17,0x0D,0x32,0x38,0x30,0x31,0x32,0x38,0x31,0x32,0x30,0x30,0x30, -0x30,0x5A,0x30,0x57,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x42, -0x45,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0A,0x13,0x10,0x47,0x6C,0x6F,0x62, -0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x6E,0x76,0x2D,0x73,0x61,0x31,0x10,0x30,0x0E, -0x06,0x03,0x55,0x04,0x0B,0x13,0x07,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x31,0x1B, -0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53, -0x69,0x67,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82, -0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xDA,0x0E,0xE6,0x99, -0x8D,0xCE,0xA3,0xE3,0x4F,0x8A,0x7E,0xFB,0xF1,0x8B,0x83,0x25,0x6B,0xEA,0x48,0x1F, -0xF1,0x2A,0xB0,0xB9,0x95,0x11,0x04,0xBD,0xF0,0x63,0xD1,0xE2,0x67,0x66,0xCF,0x1C, -0xDD,0xCF,0x1B,0x48,0x2B,0xEE,0x8D,0x89,0x8E,0x9A,0xAF,0x29,0x80,0x65,0xAB,0xE9, -0xC7,0x2D,0x12,0xCB,0xAB,0x1C,0x4C,0x70,0x07,0xA1,0x3D,0x0A,0x30,0xCD,0x15,0x8D, -0x4F,0xF8,0xDD,0xD4,0x8C,0x50,0x15,0x1C,0xEF,0x50,0xEE,0xC4,0x2E,0xF7,0xFC,0xE9, -0x52,0xF2,0x91,0x7D,0xE0,0x6D,0xD5,0x35,0x30,0x8E,0x5E,0x43,0x73,0xF2,0x41,0xE9, -0xD5,0x6A,0xE3,0xB2,0x89,0x3A,0x56,0x39,0x38,0x6F,0x06,0x3C,0x88,0x69,0x5B,0x2A, -0x4D,0xC5,0xA7,0x54,0xB8,0x6C,0x89,0xCC,0x9B,0xF9,0x3C,0xCA,0xE5,0xFD,0x89,0xF5, -0x12,0x3C,0x92,0x78,0x96,0xD6,0xDC,0x74,0x6E,0x93,0x44,0x61,0xD1,0x8D,0xC7,0x46, -0xB2,0x75,0x0E,0x86,0xE8,0x19,0x8A,0xD5,0x6D,0x6C,0xD5,0x78,0x16,0x95,0xA2,0xE9, -0xC8,0x0A,0x38,0xEB,0xF2,0x24,0x13,0x4F,0x73,0x54,0x93,0x13,0x85,0x3A,0x1B,0xBC, -0x1E,0x34,0xB5,0x8B,0x05,0x8C,0xB9,0x77,0x8B,0xB1,0xDB,0x1F,0x20,0x91,0xAB,0x09, -0x53,0x6E,0x90,0xCE,0x7B,0x37,0x74,0xB9,0x70,0x47,0x91,0x22,0x51,0x63,0x16,0x79, -0xAE,0xB1,0xAE,0x41,0x26,0x08,0xC8,0x19,0x2B,0xD1,0x46,0xAA,0x48,0xD6,0x64,0x2A, -0xD7,0x83,0x34,0xFF,0x2C,0x2A,0xC1,0x6C,0x19,0x43,0x4A,0x07,0x85,0xE7,0xD3,0x7C, -0xF6,0x21,0x68,0xEF,0xEA,0xF2,0x52,0x9F,0x7F,0x93,0x90,0xCF,0x02,0x03,0x01,0x00, -0x01,0xA3,0x42,0x30,0x40,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04, -0x04,0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, -0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, -0x14,0x60,0x7B,0x66,0x1A,0x45,0x0D,0x97,0xCA,0x89,0x50,0x2F,0x7D,0x04,0xCD,0x34, -0xA8,0xFF,0xFC,0xFD,0x4B,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xD6,0x73,0xE7,0x7C,0x4F,0x76,0xD0, -0x8D,0xBF,0xEC,0xBA,0xA2,0xBE,0x34,0xC5,0x28,0x32,0xB5,0x7C,0xFC,0x6C,0x9C,0x2C, -0x2B,0xBD,0x09,0x9E,0x53,0xBF,0x6B,0x5E,0xAA,0x11,0x48,0xB6,0xE5,0x08,0xA3,0xB3, -0xCA,0x3D,0x61,0x4D,0xD3,0x46,0x09,0xB3,0x3E,0xC3,0xA0,0xE3,0x63,0x55,0x1B,0xF2, -0xBA,0xEF,0xAD,0x39,0xE1,0x43,0xB9,0x38,0xA3,0xE6,0x2F,0x8A,0x26,0x3B,0xEF,0xA0, -0x50,0x56,0xF9,0xC6,0x0A,0xFD,0x38,0xCD,0xC4,0x0B,0x70,0x51,0x94,0x97,0x98,0x04, -0xDF,0xC3,0x5F,0x94,0xD5,0x15,0xC9,0x14,0x41,0x9C,0xC4,0x5D,0x75,0x64,0x15,0x0D, -0xFF,0x55,0x30,0xEC,0x86,0x8F,0xFF,0x0D,0xEF,0x2C,0xB9,0x63,0x46,0xF6,0xAA,0xFC, -0xDF,0xBC,0x69,0xFD,0x2E,0x12,0x48,0x64,0x9A,0xE0,0x95,0xF0,0xA6,0xEF,0x29,0x8F, -0x01,0xB1,0x15,0xB5,0x0C,0x1D,0xA5,0xFE,0x69,0x2C,0x69,0x24,0x78,0x1E,0xB3,0xA7, -0x1C,0x71,0x62,0xEE,0xCA,0xC8,0x97,0xAC,0x17,0x5D,0x8A,0xC2,0xF8,0x47,0x86,0x6E, -0x2A,0xC4,0x56,0x31,0x95,0xD0,0x67,0x89,0x85,0x2B,0xF9,0x6C,0xA6,0x5D,0x46,0x9D, -0x0C,0xAA,0x82,0xE4,0x99,0x51,0xDD,0x70,0xB7,0xDB,0x56,0x3D,0x61,0xE4,0x6A,0xE1, -0x5C,0xD6,0xF6,0xFE,0x3D,0xDE,0x41,0xCC,0x07,0xAE,0x63,0x52,0xBF,0x53,0x53,0xF4, -0x2B,0xE9,0xC7,0xFD,0xB6,0xF7,0x82,0x5F,0x85,0xD2,0x41,0x18,0xDB,0x81,0xB3,0x04, -0x1C,0xC5,0x1F,0xA4,0x80,0x6F,0x15,0x20,0xC9,0xDE,0x0C,0x88,0x0A,0x1D,0xD6,0x66, -0x55,0xE2,0xFC,0x48,0xC9,0x29,0x26,0x69,0xE0, -}; - - -/* subject:/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign */ -/* issuer :/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign */ - - -const unsigned char GlobalSign_Root_CA___R2_certificate[958]={ -0x30,0x82,0x03,0xBA,0x30,0x82,0x02,0xA2,0xA0,0x03,0x02,0x01,0x02,0x02,0x0B,0x04, -0x00,0x00,0x00,0x00,0x01,0x0F,0x86,0x26,0xE6,0x0D,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x4C,0x31,0x20,0x30,0x1E,0x06, -0x03,0x55,0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E, -0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x32,0x31,0x13,0x30, -0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69, -0x67,0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47,0x6C,0x6F, -0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x31, -0x35,0x30,0x38,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x31,0x31,0x32,0x31,0x35, -0x30,0x38,0x30,0x30,0x30,0x30,0x5A,0x30,0x4C,0x31,0x20,0x30,0x1E,0x06,0x03,0x55, -0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x52, -0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x32,0x31,0x13,0x30,0x11,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E, -0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61, -0x6C,0x53,0x69,0x67,0x6E,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01, -0x0A,0x02,0x82,0x01,0x01,0x00,0xA6,0xCF,0x24,0x0E,0xBE,0x2E,0x6F,0x28,0x99,0x45, -0x42,0xC4,0xAB,0x3E,0x21,0x54,0x9B,0x0B,0xD3,0x7F,0x84,0x70,0xFA,0x12,0xB3,0xCB, -0xBF,0x87,0x5F,0xC6,0x7F,0x86,0xD3,0xB2,0x30,0x5C,0xD6,0xFD,0xAD,0xF1,0x7B,0xDC, -0xE5,0xF8,0x60,0x96,0x09,0x92,0x10,0xF5,0xD0,0x53,0xDE,0xFB,0x7B,0x7E,0x73,0x88, -0xAC,0x52,0x88,0x7B,0x4A,0xA6,0xCA,0x49,0xA6,0x5E,0xA8,0xA7,0x8C,0x5A,0x11,0xBC, -0x7A,0x82,0xEB,0xBE,0x8C,0xE9,0xB3,0xAC,0x96,0x25,0x07,0x97,0x4A,0x99,0x2A,0x07, -0x2F,0xB4,0x1E,0x77,0xBF,0x8A,0x0F,0xB5,0x02,0x7C,0x1B,0x96,0xB8,0xC5,0xB9,0x3A, -0x2C,0xBC,0xD6,0x12,0xB9,0xEB,0x59,0x7D,0xE2,0xD0,0x06,0x86,0x5F,0x5E,0x49,0x6A, -0xB5,0x39,0x5E,0x88,0x34,0xEC,0xBC,0x78,0x0C,0x08,0x98,0x84,0x6C,0xA8,0xCD,0x4B, -0xB4,0xA0,0x7D,0x0C,0x79,0x4D,0xF0,0xB8,0x2D,0xCB,0x21,0xCA,0xD5,0x6C,0x5B,0x7D, -0xE1,0xA0,0x29,0x84,0xA1,0xF9,0xD3,0x94,0x49,0xCB,0x24,0x62,0x91,0x20,0xBC,0xDD, -0x0B,0xD5,0xD9,0xCC,0xF9,0xEA,0x27,0x0A,0x2B,0x73,0x91,0xC6,0x9D,0x1B,0xAC,0xC8, -0xCB,0xE8,0xE0,0xA0,0xF4,0x2F,0x90,0x8B,0x4D,0xFB,0xB0,0x36,0x1B,0xF6,0x19,0x7A, -0x85,0xE0,0x6D,0xF2,0x61,0x13,0x88,0x5C,0x9F,0xE0,0x93,0x0A,0x51,0x97,0x8A,0x5A, -0xCE,0xAF,0xAB,0xD5,0xF7,0xAA,0x09,0xAA,0x60,0xBD,0xDC,0xD9,0x5F,0xDF,0x72,0xA9, -0x60,0x13,0x5E,0x00,0x01,0xC9,0x4A,0xFA,0x3F,0xA4,0xEA,0x07,0x03,0x21,0x02,0x8E, -0x82,0xCA,0x03,0xC2,0x9B,0x8F,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x9C,0x30,0x81, -0x99,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01, -0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01, -0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9B,0xE2,0x07, -0x57,0x67,0x1C,0x1E,0xC0,0x6A,0x06,0xDE,0x59,0xB4,0x9A,0x2D,0xDF,0xDC,0x19,0x86, -0x2E,0x30,0x36,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2F,0x30,0x2D,0x30,0x2B,0xA0,0x29, -0xA0,0x27,0x86,0x25,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x67, -0x6C,0x6F,0x62,0x61,0x6C,0x73,0x69,0x67,0x6E,0x2E,0x6E,0x65,0x74,0x2F,0x72,0x6F, -0x6F,0x74,0x2D,0x72,0x32,0x2E,0x63,0x72,0x6C,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, -0x04,0x18,0x30,0x16,0x80,0x14,0x9B,0xE2,0x07,0x57,0x67,0x1C,0x1E,0xC0,0x6A,0x06, -0xDE,0x59,0xB4,0x9A,0x2D,0xDF,0xDC,0x19,0x86,0x2E,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x99,0x81, -0x53,0x87,0x1C,0x68,0x97,0x86,0x91,0xEC,0xE0,0x4A,0xB8,0x44,0x0B,0xAB,0x81,0xAC, -0x27,0x4F,0xD6,0xC1,0xB8,0x1C,0x43,0x78,0xB3,0x0C,0x9A,0xFC,0xEA,0x2C,0x3C,0x6E, -0x61,0x1B,0x4D,0x4B,0x29,0xF5,0x9F,0x05,0x1D,0x26,0xC1,0xB8,0xE9,0x83,0x00,0x62, -0x45,0xB6,0xA9,0x08,0x93,0xB9,0xA9,0x33,0x4B,0x18,0x9A,0xC2,0xF8,0x87,0x88,0x4E, -0xDB,0xDD,0x71,0x34,0x1A,0xC1,0x54,0xDA,0x46,0x3F,0xE0,0xD3,0x2A,0xAB,0x6D,0x54, -0x22,0xF5,0x3A,0x62,0xCD,0x20,0x6F,0xBA,0x29,0x89,0xD7,0xDD,0x91,0xEE,0xD3,0x5C, -0xA2,0x3E,0xA1,0x5B,0x41,0xF5,0xDF,0xE5,0x64,0x43,0x2D,0xE9,0xD5,0x39,0xAB,0xD2, -0xA2,0xDF,0xB7,0x8B,0xD0,0xC0,0x80,0x19,0x1C,0x45,0xC0,0x2D,0x8C,0xE8,0xF8,0x2D, -0xA4,0x74,0x56,0x49,0xC5,0x05,0xB5,0x4F,0x15,0xDE,0x6E,0x44,0x78,0x39,0x87,0xA8, -0x7E,0xBB,0xF3,0x79,0x18,0x91,0xBB,0xF4,0x6F,0x9D,0xC1,0xF0,0x8C,0x35,0x8C,0x5D, -0x01,0xFB,0xC3,0x6D,0xB9,0xEF,0x44,0x6D,0x79,0x46,0x31,0x7E,0x0A,0xFE,0xA9,0x82, -0xC1,0xFF,0xEF,0xAB,0x6E,0x20,0xC4,0x50,0xC9,0x5F,0x9D,0x4D,0x9B,0x17,0x8C,0x0C, -0xE5,0x01,0xC9,0xA0,0x41,0x6A,0x73,0x53,0xFA,0xA5,0x50,0xB4,0x6E,0x25,0x0F,0xFB, -0x4C,0x18,0xF4,0xFD,0x52,0xD9,0x8E,0x69,0xB1,0xE8,0x11,0x0F,0xDE,0x88,0xD8,0xFB, -0x1D,0x49,0xF7,0xAA,0xDE,0x95,0xCF,0x20,0x78,0xC2,0x60,0x12,0xDB,0x25,0x40,0x8C, -0x6A,0xFC,0x7E,0x42,0x38,0x40,0x64,0x12,0xF7,0x9E,0x81,0xE1,0x93,0x2E, -}; - - -/* subject:/OU=GlobalSign Root CA - R3/O=GlobalSign/CN=GlobalSign */ -/* issuer :/OU=GlobalSign Root CA - R3/O=GlobalSign/CN=GlobalSign */ - - -const unsigned char GlobalSign_Root_CA___R3_certificate[867]={ -0x30,0x82,0x03,0x5F,0x30,0x82,0x02,0x47,0xA0,0x03,0x02,0x01,0x02,0x02,0x0B,0x04, -0x00,0x00,0x00,0x00,0x01,0x21,0x58,0x53,0x08,0xA2,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x4C,0x31,0x20,0x30,0x1E,0x06, -0x03,0x55,0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E, -0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x33,0x31,0x13,0x30, -0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69, -0x67,0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47,0x6C,0x6F, -0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x30,0x1E,0x17,0x0D,0x30,0x39,0x30,0x33,0x31, -0x38,0x31,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x33,0x31,0x38, -0x31,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x4C,0x31,0x20,0x30,0x1E,0x06,0x03,0x55, -0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x52, -0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x33,0x31,0x13,0x30,0x11,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E, -0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61, -0x6C,0x53,0x69,0x67,0x6E,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01, -0x0A,0x02,0x82,0x01,0x01,0x00,0xCC,0x25,0x76,0x90,0x79,0x06,0x78,0x22,0x16,0xF5, -0xC0,0x83,0xB6,0x84,0xCA,0x28,0x9E,0xFD,0x05,0x76,0x11,0xC5,0xAD,0x88,0x72,0xFC, -0x46,0x02,0x43,0xC7,0xB2,0x8A,0x9D,0x04,0x5F,0x24,0xCB,0x2E,0x4B,0xE1,0x60,0x82, -0x46,0xE1,0x52,0xAB,0x0C,0x81,0x47,0x70,0x6C,0xDD,0x64,0xD1,0xEB,0xF5,0x2C,0xA3, -0x0F,0x82,0x3D,0x0C,0x2B,0xAE,0x97,0xD7,0xB6,0x14,0x86,0x10,0x79,0xBB,0x3B,0x13, -0x80,0x77,0x8C,0x08,0xE1,0x49,0xD2,0x6A,0x62,0x2F,0x1F,0x5E,0xFA,0x96,0x68,0xDF, -0x89,0x27,0x95,0x38,0x9F,0x06,0xD7,0x3E,0xC9,0xCB,0x26,0x59,0x0D,0x73,0xDE,0xB0, -0xC8,0xE9,0x26,0x0E,0x83,0x15,0xC6,0xEF,0x5B,0x8B,0xD2,0x04,0x60,0xCA,0x49,0xA6, -0x28,0xF6,0x69,0x3B,0xF6,0xCB,0xC8,0x28,0x91,0xE5,0x9D,0x8A,0x61,0x57,0x37,0xAC, -0x74,0x14,0xDC,0x74,0xE0,0x3A,0xEE,0x72,0x2F,0x2E,0x9C,0xFB,0xD0,0xBB,0xBF,0xF5, -0x3D,0x00,0xE1,0x06,0x33,0xE8,0x82,0x2B,0xAE,0x53,0xA6,0x3A,0x16,0x73,0x8C,0xDD, -0x41,0x0E,0x20,0x3A,0xC0,0xB4,0xA7,0xA1,0xE9,0xB2,0x4F,0x90,0x2E,0x32,0x60,0xE9, -0x57,0xCB,0xB9,0x04,0x92,0x68,0x68,0xE5,0x38,0x26,0x60,0x75,0xB2,0x9F,0x77,0xFF, -0x91,0x14,0xEF,0xAE,0x20,0x49,0xFC,0xAD,0x40,0x15,0x48,0xD1,0x02,0x31,0x61,0x19, -0x5E,0xB8,0x97,0xEF,0xAD,0x77,0xB7,0x64,0x9A,0x7A,0xBF,0x5F,0xC1,0x13,0xEF,0x9B, -0x62,0xFB,0x0D,0x6C,0xE0,0x54,0x69,0x16,0xA9,0x03,0xDA,0x6E,0xE9,0x83,0x93,0x71, -0x76,0xC6,0x69,0x85,0x82,0x17,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30, -0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30, -0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF, -0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x8F,0xF0,0x4B,0x7F,0xA8, -0x2E,0x45,0x24,0xAE,0x4D,0x50,0xFA,0x63,0x9A,0x8B,0xDE,0xE2,0xDD,0x1B,0xBC,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82, -0x01,0x01,0x00,0x4B,0x40,0xDB,0xC0,0x50,0xAA,0xFE,0xC8,0x0C,0xEF,0xF7,0x96,0x54, -0x45,0x49,0xBB,0x96,0x00,0x09,0x41,0xAC,0xB3,0x13,0x86,0x86,0x28,0x07,0x33,0xCA, -0x6B,0xE6,0x74,0xB9,0xBA,0x00,0x2D,0xAE,0xA4,0x0A,0xD3,0xF5,0xF1,0xF1,0x0F,0x8A, -0xBF,0x73,0x67,0x4A,0x83,0xC7,0x44,0x7B,0x78,0xE0,0xAF,0x6E,0x6C,0x6F,0x03,0x29, -0x8E,0x33,0x39,0x45,0xC3,0x8E,0xE4,0xB9,0x57,0x6C,0xAA,0xFC,0x12,0x96,0xEC,0x53, -0xC6,0x2D,0xE4,0x24,0x6C,0xB9,0x94,0x63,0xFB,0xDC,0x53,0x68,0x67,0x56,0x3E,0x83, -0xB8,0xCF,0x35,0x21,0xC3,0xC9,0x68,0xFE,0xCE,0xDA,0xC2,0x53,0xAA,0xCC,0x90,0x8A, -0xE9,0xF0,0x5D,0x46,0x8C,0x95,0xDD,0x7A,0x58,0x28,0x1A,0x2F,0x1D,0xDE,0xCD,0x00, -0x37,0x41,0x8F,0xED,0x44,0x6D,0xD7,0x53,0x28,0x97,0x7E,0xF3,0x67,0x04,0x1E,0x15, -0xD7,0x8A,0x96,0xB4,0xD3,0xDE,0x4C,0x27,0xA4,0x4C,0x1B,0x73,0x73,0x76,0xF4,0x17, -0x99,0xC2,0x1F,0x7A,0x0E,0xE3,0x2D,0x08,0xAD,0x0A,0x1C,0x2C,0xFF,0x3C,0xAB,0x55, -0x0E,0x0F,0x91,0x7E,0x36,0xEB,0xC3,0x57,0x49,0xBE,0xE1,0x2E,0x2D,0x7C,0x60,0x8B, -0xC3,0x41,0x51,0x13,0x23,0x9D,0xCE,0xF7,0x32,0x6B,0x94,0x01,0xA8,0x99,0xE7,0x2C, -0x33,0x1F,0x3A,0x3B,0x25,0xD2,0x86,0x40,0xCE,0x3B,0x2C,0x86,0x78,0xC9,0x61,0x2F, -0x14,0xBA,0xEE,0xDB,0x55,0x6F,0xDF,0x84,0xEE,0x05,0x09,0x4D,0xBD,0x28,0xD8,0x72, -0xCE,0xD3,0x62,0x50,0x65,0x1E,0xEB,0x92,0x97,0x83,0x31,0xD9,0xB3,0xB5,0xCA,0x47, -0x58,0x3F,0x5F, -}; - - -/* subject:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority */ -/* issuer :/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority */ - - -const unsigned char Go_Daddy_Class_2_CA_certificate[1028]={ -0x30,0x82,0x04,0x00,0x30,0x82,0x02,0xE8,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x63,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x21, -0x30,0x1F,0x06,0x03,0x55,0x04,0x0A,0x13,0x18,0x54,0x68,0x65,0x20,0x47,0x6F,0x20, -0x44,0x61,0x64,0x64,0x79,0x20,0x47,0x72,0x6F,0x75,0x70,0x2C,0x20,0x49,0x6E,0x63, -0x2E,0x31,0x31,0x30,0x2F,0x06,0x03,0x55,0x04,0x0B,0x13,0x28,0x47,0x6F,0x20,0x44, -0x61,0x64,0x64,0x79,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x32,0x20,0x43,0x65,0x72, -0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F, -0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x34,0x30,0x36,0x32,0x39,0x31,0x37, -0x30,0x36,0x32,0x30,0x5A,0x17,0x0D,0x33,0x34,0x30,0x36,0x32,0x39,0x31,0x37,0x30, -0x36,0x32,0x30,0x5A,0x30,0x63,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x55,0x53,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0A,0x13,0x18,0x54,0x68, -0x65,0x20,0x47,0x6F,0x20,0x44,0x61,0x64,0x64,0x79,0x20,0x47,0x72,0x6F,0x75,0x70, -0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x31,0x30,0x2F,0x06,0x03,0x55,0x04,0x0B,0x13, -0x28,0x47,0x6F,0x20,0x44,0x61,0x64,0x64,0x79,0x20,0x43,0x6C,0x61,0x73,0x73,0x20, -0x32,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20, -0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x01,0x20,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0D, -0x00,0x30,0x82,0x01,0x08,0x02,0x82,0x01,0x01,0x00,0xDE,0x9D,0xD7,0xEA,0x57,0x18, -0x49,0xA1,0x5B,0xEB,0xD7,0x5F,0x48,0x86,0xEA,0xBE,0xDD,0xFF,0xE4,0xEF,0x67,0x1C, -0xF4,0x65,0x68,0xB3,0x57,0x71,0xA0,0x5E,0x77,0xBB,0xED,0x9B,0x49,0xE9,0x70,0x80, -0x3D,0x56,0x18,0x63,0x08,0x6F,0xDA,0xF2,0xCC,0xD0,0x3F,0x7F,0x02,0x54,0x22,0x54, -0x10,0xD8,0xB2,0x81,0xD4,0xC0,0x75,0x3D,0x4B,0x7F,0xC7,0x77,0xC3,0x3E,0x78,0xAB, -0x1A,0x03,0xB5,0x20,0x6B,0x2F,0x6A,0x2B,0xB1,0xC5,0x88,0x7E,0xC4,0xBB,0x1E,0xB0, -0xC1,0xD8,0x45,0x27,0x6F,0xAA,0x37,0x58,0xF7,0x87,0x26,0xD7,0xD8,0x2D,0xF6,0xA9, -0x17,0xB7,0x1F,0x72,0x36,0x4E,0xA6,0x17,0x3F,0x65,0x98,0x92,0xDB,0x2A,0x6E,0x5D, -0xA2,0xFE,0x88,0xE0,0x0B,0xDE,0x7F,0xE5,0x8D,0x15,0xE1,0xEB,0xCB,0x3A,0xD5,0xE2, -0x12,0xA2,0x13,0x2D,0xD8,0x8E,0xAF,0x5F,0x12,0x3D,0xA0,0x08,0x05,0x08,0xB6,0x5C, -0xA5,0x65,0x38,0x04,0x45,0x99,0x1E,0xA3,0x60,0x60,0x74,0xC5,0x41,0xA5,0x72,0x62, -0x1B,0x62,0xC5,0x1F,0x6F,0x5F,0x1A,0x42,0xBE,0x02,0x51,0x65,0xA8,0xAE,0x23,0x18, -0x6A,0xFC,0x78,0x03,0xA9,0x4D,0x7F,0x80,0xC3,0xFA,0xAB,0x5A,0xFC,0xA1,0x40,0xA4, -0xCA,0x19,0x16,0xFE,0xB2,0xC8,0xEF,0x5E,0x73,0x0D,0xEE,0x77,0xBD,0x9A,0xF6,0x79, -0x98,0xBC,0xB1,0x07,0x67,0xA2,0x15,0x0D,0xDD,0xA0,0x58,0xC6,0x44,0x7B,0x0A,0x3E, -0x62,0x28,0x5F,0xBA,0x41,0x07,0x53,0x58,0xCF,0x11,0x7E,0x38,0x74,0xC5,0xF8,0xFF, -0xB5,0x69,0x90,0x8F,0x84,0x74,0xEA,0x97,0x1B,0xAF,0x02,0x01,0x03,0xA3,0x81,0xC0, -0x30,0x81,0xBD,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xD2,0xC4, -0xB0,0xD2,0x91,0xD4,0x4C,0x11,0x71,0xB3,0x61,0xCB,0x3D,0xA1,0xFE,0xDD,0xA8,0x6A, -0xD4,0xE3,0x30,0x81,0x8D,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,0x85,0x30,0x81,0x82, -0x80,0x14,0xD2,0xC4,0xB0,0xD2,0x91,0xD4,0x4C,0x11,0x71,0xB3,0x61,0xCB,0x3D,0xA1, -0xFE,0xDD,0xA8,0x6A,0xD4,0xE3,0xA1,0x67,0xA4,0x65,0x30,0x63,0x31,0x0B,0x30,0x09, -0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x21,0x30,0x1F,0x06,0x03,0x55, -0x04,0x0A,0x13,0x18,0x54,0x68,0x65,0x20,0x47,0x6F,0x20,0x44,0x61,0x64,0x64,0x79, -0x20,0x47,0x72,0x6F,0x75,0x70,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x31,0x30,0x2F, -0x06,0x03,0x55,0x04,0x0B,0x13,0x28,0x47,0x6F,0x20,0x44,0x61,0x64,0x64,0x79,0x20, -0x43,0x6C,0x61,0x73,0x73,0x20,0x32,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, -0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x82, -0x01,0x00,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03, -0x82,0x01,0x01,0x00,0x32,0x4B,0xF3,0xB2,0xCA,0x3E,0x91,0xFC,0x12,0xC6,0xA1,0x07, -0x8C,0x8E,0x77,0xA0,0x33,0x06,0x14,0x5C,0x90,0x1E,0x18,0xF7,0x08,0xA6,0x3D,0x0A, -0x19,0xF9,0x87,0x80,0x11,0x6E,0x69,0xE4,0x96,0x17,0x30,0xFF,0x34,0x91,0x63,0x72, -0x38,0xEE,0xCC,0x1C,0x01,0xA3,0x1D,0x94,0x28,0xA4,0x31,0xF6,0x7A,0xC4,0x54,0xD7, -0xF6,0xE5,0x31,0x58,0x03,0xA2,0xCC,0xCE,0x62,0xDB,0x94,0x45,0x73,0xB5,0xBF,0x45, -0xC9,0x24,0xB5,0xD5,0x82,0x02,0xAD,0x23,0x79,0x69,0x8D,0xB8,0xB6,0x4D,0xCE,0xCF, -0x4C,0xCA,0x33,0x23,0xE8,0x1C,0x88,0xAA,0x9D,0x8B,0x41,0x6E,0x16,0xC9,0x20,0xE5, -0x89,0x9E,0xCD,0x3B,0xDA,0x70,0xF7,0x7E,0x99,0x26,0x20,0x14,0x54,0x25,0xAB,0x6E, -0x73,0x85,0xE6,0x9B,0x21,0x9D,0x0A,0x6C,0x82,0x0E,0xA8,0xF8,0xC2,0x0C,0xFA,0x10, -0x1E,0x6C,0x96,0xEF,0x87,0x0D,0xC4,0x0F,0x61,0x8B,0xAD,0xEE,0x83,0x2B,0x95,0xF8, -0x8E,0x92,0x84,0x72,0x39,0xEB,0x20,0xEA,0x83,0xED,0x83,0xCD,0x97,0x6E,0x08,0xBC, -0xEB,0x4E,0x26,0xB6,0x73,0x2B,0xE4,0xD3,0xF6,0x4C,0xFE,0x26,0x71,0xE2,0x61,0x11, -0x74,0x4A,0xFF,0x57,0x1A,0x87,0x0F,0x75,0x48,0x2E,0xCF,0x51,0x69,0x17,0xA0,0x02, -0x12,0x61,0x95,0xD5,0xD1,0x40,0xB2,0x10,0x4C,0xEE,0xC4,0xAC,0x10,0x43,0xA6,0xA5, -0x9E,0x0A,0xD5,0x95,0x62,0x9A,0x0D,0xCF,0x88,0x82,0xC5,0x32,0x0C,0xE4,0x2B,0x9F, -0x45,0xE6,0x0D,0x9F,0x28,0x9C,0xB1,0xB9,0x2A,0x5A,0x57,0xAD,0x37,0x0F,0xAF,0x1D, -0x7F,0xDB,0xBD,0x9F, -}; - - -/* subject:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 */ -/* issuer :/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 */ - - -const unsigned char Go_Daddy_Root_Certificate_Authority___G2_certificate[969]={ -0x30,0x82,0x03,0xC5,0x30,0x82,0x02,0xAD,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30, -0x81,0x83,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31, -0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x13,0x07,0x41,0x72,0x69,0x7A,0x6F,0x6E, -0x61,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x07,0x13,0x0A,0x53,0x63,0x6F,0x74, -0x74,0x73,0x64,0x61,0x6C,0x65,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13, -0x11,0x47,0x6F,0x44,0x61,0x64,0x64,0x79,0x2E,0x63,0x6F,0x6D,0x2C,0x20,0x49,0x6E, -0x63,0x2E,0x31,0x31,0x30,0x2F,0x06,0x03,0x55,0x04,0x03,0x13,0x28,0x47,0x6F,0x20, -0x44,0x61,0x64,0x64,0x79,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79, -0x20,0x2D,0x20,0x47,0x32,0x30,0x1E,0x17,0x0D,0x30,0x39,0x30,0x39,0x30,0x31,0x30, -0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x37,0x31,0x32,0x33,0x31,0x32,0x33, -0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x83,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, -0x06,0x13,0x02,0x55,0x53,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x13,0x07, -0x41,0x72,0x69,0x7A,0x6F,0x6E,0x61,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x07, -0x13,0x0A,0x53,0x63,0x6F,0x74,0x74,0x73,0x64,0x61,0x6C,0x65,0x31,0x1A,0x30,0x18, -0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x47,0x6F,0x44,0x61,0x64,0x64,0x79,0x2E,0x63, -0x6F,0x6D,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x31,0x30,0x2F,0x06,0x03,0x55,0x04, -0x03,0x13,0x28,0x47,0x6F,0x20,0x44,0x61,0x64,0x64,0x79,0x20,0x52,0x6F,0x6F,0x74, -0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74, -0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x32,0x30,0x82,0x01,0x22,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82, -0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBF,0x71,0x62,0x08, -0xF1,0xFA,0x59,0x34,0xF7,0x1B,0xC9,0x18,0xA3,0xF7,0x80,0x49,0x58,0xE9,0x22,0x83, -0x13,0xA6,0xC5,0x20,0x43,0x01,0x3B,0x84,0xF1,0xE6,0x85,0x49,0x9F,0x27,0xEA,0xF6, -0x84,0x1B,0x4E,0xA0,0xB4,0xDB,0x70,0x98,0xC7,0x32,0x01,0xB1,0x05,0x3E,0x07,0x4E, -0xEE,0xF4,0xFA,0x4F,0x2F,0x59,0x30,0x22,0xE7,0xAB,0x19,0x56,0x6B,0xE2,0x80,0x07, -0xFC,0xF3,0x16,0x75,0x80,0x39,0x51,0x7B,0xE5,0xF9,0x35,0xB6,0x74,0x4E,0xA9,0x8D, -0x82,0x13,0xE4,0xB6,0x3F,0xA9,0x03,0x83,0xFA,0xA2,0xBE,0x8A,0x15,0x6A,0x7F,0xDE, -0x0B,0xC3,0xB6,0x19,0x14,0x05,0xCA,0xEA,0xC3,0xA8,0x04,0x94,0x3B,0x46,0x7C,0x32, -0x0D,0xF3,0x00,0x66,0x22,0xC8,0x8D,0x69,0x6D,0x36,0x8C,0x11,0x18,0xB7,0xD3,0xB2, -0x1C,0x60,0xB4,0x38,0xFA,0x02,0x8C,0xCE,0xD3,0xDD,0x46,0x07,0xDE,0x0A,0x3E,0xEB, -0x5D,0x7C,0xC8,0x7C,0xFB,0xB0,0x2B,0x53,0xA4,0x92,0x62,0x69,0x51,0x25,0x05,0x61, -0x1A,0x44,0x81,0x8C,0x2C,0xA9,0x43,0x96,0x23,0xDF,0xAC,0x3A,0x81,0x9A,0x0E,0x29, -0xC5,0x1C,0xA9,0xE9,0x5D,0x1E,0xB6,0x9E,0x9E,0x30,0x0A,0x39,0xCE,0xF1,0x88,0x80, -0xFB,0x4B,0x5D,0xCC,0x32,0xEC,0x85,0x62,0x43,0x25,0x34,0x02,0x56,0x27,0x01,0x91, -0xB4,0x3B,0x70,0x2A,0x3F,0x6E,0xB1,0xE8,0x9C,0x88,0x01,0x7D,0x9F,0xD4,0xF9,0xDB, -0x53,0x6D,0x60,0x9D,0xBF,0x2C,0xE7,0x58,0xAB,0xB8,0x5F,0x46,0xFC,0xCE,0xC4,0x1B, -0x03,0x3C,0x09,0xEB,0x49,0x31,0x5C,0x69,0x46,0xB3,0xE0,0x47,0x02,0x03,0x01,0x00, -0x01,0xA3,0x42,0x30,0x40,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, -0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF, -0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, -0x14,0x3A,0x9A,0x85,0x07,0x10,0x67,0x28,0xB6,0xEF,0xF6,0xBD,0x05,0x41,0x6E,0x20, -0xC1,0x94,0xDA,0x0F,0xDE,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x99,0xDB,0x5D,0x79,0xD5,0xF9,0x97, -0x59,0x67,0x03,0x61,0xF1,0x7E,0x3B,0x06,0x31,0x75,0x2D,0xA1,0x20,0x8E,0x4F,0x65, -0x87,0xB4,0xF7,0xA6,0x9C,0xBC,0xD8,0xE9,0x2F,0xD0,0xDB,0x5A,0xEE,0xCF,0x74,0x8C, -0x73,0xB4,0x38,0x42,0xDA,0x05,0x7B,0xF8,0x02,0x75,0xB8,0xFD,0xA5,0xB1,0xD7,0xAE, -0xF6,0xD7,0xDE,0x13,0xCB,0x53,0x10,0x7E,0x8A,0x46,0xD1,0x97,0xFA,0xB7,0x2E,0x2B, -0x11,0xAB,0x90,0xB0,0x27,0x80,0xF9,0xE8,0x9F,0x5A,0xE9,0x37,0x9F,0xAB,0xE4,0xDF, -0x6C,0xB3,0x85,0x17,0x9D,0x3D,0xD9,0x24,0x4F,0x79,0x91,0x35,0xD6,0x5F,0x04,0xEB, -0x80,0x83,0xAB,0x9A,0x02,0x2D,0xB5,0x10,0xF4,0xD8,0x90,0xC7,0x04,0x73,0x40,0xED, -0x72,0x25,0xA0,0xA9,0x9F,0xEC,0x9E,0xAB,0x68,0x12,0x99,0x57,0xC6,0x8F,0x12,0x3A, -0x09,0xA4,0xBD,0x44,0xFD,0x06,0x15,0x37,0xC1,0x9B,0xE4,0x32,0xA3,0xED,0x38,0xE8, -0xD8,0x64,0xF3,0x2C,0x7E,0x14,0xFC,0x02,0xEA,0x9F,0xCD,0xFF,0x07,0x68,0x17,0xDB, -0x22,0x90,0x38,0x2D,0x7A,0x8D,0xD1,0x54,0xF1,0x69,0xE3,0x5F,0x33,0xCA,0x7A,0x3D, -0x7B,0x0A,0xE3,0xCA,0x7F,0x5F,0x39,0xE5,0xE2,0x75,0xBA,0xC5,0x76,0x18,0x33,0xCE, -0x2C,0xF0,0x2F,0x4C,0xAD,0xF7,0xB1,0xE7,0xCE,0x4F,0xA8,0xC4,0x9B,0x4A,0x54,0x06, -0xC5,0x7F,0x7D,0xD5,0x08,0x0F,0xE2,0x1C,0xFE,0x7E,0x17,0xB8,0xAC,0x5E,0xF6,0xD4, -0x16,0xB2,0x43,0x09,0x0C,0x4D,0xF6,0xA7,0x6B,0xB4,0x99,0x84,0x65,0xCA,0x7A,0x88, -0xE2,0xE2,0x44,0xBE,0x5C,0xF7,0xEA,0x1C,0xF5, -}; - - -/* subject:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root */ -/* issuer :/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root */ - - -const unsigned char GTE_CyberTrust_Global_Root_certificate[606]={ -0x30,0x82,0x02,0x5A,0x30,0x82,0x01,0xC3,0x02,0x02,0x01,0xA5,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x30,0x75,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x18,0x30,0x16,0x06,0x03, -0x55,0x04,0x0A,0x13,0x0F,0x47,0x54,0x45,0x20,0x43,0x6F,0x72,0x70,0x6F,0x72,0x61, -0x74,0x69,0x6F,0x6E,0x31,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x0B,0x13,0x1E,0x47, -0x54,0x45,0x20,0x43,0x79,0x62,0x65,0x72,0x54,0x72,0x75,0x73,0x74,0x20,0x53,0x6F, -0x6C,0x75,0x74,0x69,0x6F,0x6E,0x73,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x23,0x30, -0x21,0x06,0x03,0x55,0x04,0x03,0x13,0x1A,0x47,0x54,0x45,0x20,0x43,0x79,0x62,0x65, -0x72,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F, -0x6F,0x74,0x30,0x1E,0x17,0x0D,0x39,0x38,0x30,0x38,0x31,0x33,0x30,0x30,0x32,0x39, -0x30,0x30,0x5A,0x17,0x0D,0x31,0x38,0x30,0x38,0x31,0x33,0x32,0x33,0x35,0x39,0x30, -0x30,0x5A,0x30,0x75,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x18,0x30,0x16,0x06,0x03,0x55,0x04,0x0A,0x13,0x0F,0x47,0x54,0x45,0x20, -0x43,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x27,0x30,0x25,0x06, -0x03,0x55,0x04,0x0B,0x13,0x1E,0x47,0x54,0x45,0x20,0x43,0x79,0x62,0x65,0x72,0x54, -0x72,0x75,0x73,0x74,0x20,0x53,0x6F,0x6C,0x75,0x74,0x69,0x6F,0x6E,0x73,0x2C,0x20, -0x49,0x6E,0x63,0x2E,0x31,0x23,0x30,0x21,0x06,0x03,0x55,0x04,0x03,0x13,0x1A,0x47, -0x54,0x45,0x20,0x43,0x79,0x62,0x65,0x72,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C, -0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30, -0x81,0x89,0x02,0x81,0x81,0x00,0x95,0x0F,0xA0,0xB6,0xF0,0x50,0x9C,0xE8,0x7A,0xC7, -0x88,0xCD,0xDD,0x17,0x0E,0x2E,0xB0,0x94,0xD0,0x1B,0x3D,0x0E,0xF6,0x94,0xC0,0x8A, -0x94,0xC7,0x06,0xC8,0x90,0x97,0xC8,0xB8,0x64,0x1A,0x7A,0x7E,0x6C,0x3C,0x53,0xE1, -0x37,0x28,0x73,0x60,0x7F,0xB2,0x97,0x53,0x07,0x9F,0x53,0xF9,0x6D,0x58,0x94,0xD2, -0xAF,0x8D,0x6D,0x88,0x67,0x80,0xE6,0xED,0xB2,0x95,0xCF,0x72,0x31,0xCA,0xA5,0x1C, -0x72,0xBA,0x5C,0x02,0xE7,0x64,0x42,0xE7,0xF9,0xA9,0x2C,0xD6,0x3A,0x0D,0xAC,0x8D, -0x42,0xAA,0x24,0x01,0x39,0xE6,0x9C,0x3F,0x01,0x85,0x57,0x0D,0x58,0x87,0x45,0xF8, -0xD3,0x85,0xAA,0x93,0x69,0x26,0x85,0x70,0x48,0x80,0x3F,0x12,0x15,0xC7,0x79,0xB4, -0x1F,0x05,0x2F,0x3B,0x62,0x99,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A, -0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x03,0x81,0x81,0x00,0x6D,0xEB, -0x1B,0x09,0xE9,0x5E,0xD9,0x51,0xDB,0x67,0x22,0x61,0xA4,0x2A,0x3C,0x48,0x77,0xE3, -0xA0,0x7C,0xA6,0xDE,0x73,0xA2,0x14,0x03,0x85,0x3D,0xFB,0xAB,0x0E,0x30,0xC5,0x83, -0x16,0x33,0x81,0x13,0x08,0x9E,0x7B,0x34,0x4E,0xDF,0x40,0xC8,0x74,0xD7,0xB9,0x7D, -0xDC,0xF4,0x76,0x55,0x7D,0x9B,0x63,0x54,0x18,0xE9,0xF0,0xEA,0xF3,0x5C,0xB1,0xD9, -0x8B,0x42,0x1E,0xB9,0xC0,0x95,0x4E,0xBA,0xFA,0xD5,0xE2,0x7C,0xF5,0x68,0x61,0xBF, -0x8E,0xEC,0x05,0x97,0x5F,0x5B,0xB0,0xD7,0xA3,0x85,0x34,0xC4,0x24,0xA7,0x0D,0x0F, -0x95,0x93,0xEF,0xCB,0x94,0xD8,0x9E,0x1F,0x9D,0x5C,0x85,0x6D,0xC7,0xAA,0xAE,0x4F, -0x1F,0x22,0xB5,0xCD,0x95,0xAD,0xBA,0xA7,0xCC,0xF9,0xAB,0x0B,0x7A,0x7F, -}; - - -/* subject:/C=US/O=Network Solutions L.L.C./CN=Network Solutions Certificate Authority */ -/* issuer :/C=US/O=Network Solutions L.L.C./CN=Network Solutions Certificate Authority */ - - -const unsigned char Network_Solutions_Certificate_Authority_certificate[1002]={ -0x30,0x82,0x03,0xE6,0x30,0x82,0x02,0xCE,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x57, -0xCB,0x33,0x6F,0xC2,0x5C,0x16,0xE6,0x47,0x16,0x17,0xE3,0x90,0x31,0x68,0xE0,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x62, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x21,0x30, -0x1F,0x06,0x03,0x55,0x04,0x0A,0x13,0x18,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x20, -0x53,0x6F,0x6C,0x75,0x74,0x69,0x6F,0x6E,0x73,0x20,0x4C,0x2E,0x4C,0x2E,0x43,0x2E, -0x31,0x30,0x30,0x2E,0x06,0x03,0x55,0x04,0x03,0x13,0x27,0x4E,0x65,0x74,0x77,0x6F, -0x72,0x6B,0x20,0x53,0x6F,0x6C,0x75,0x74,0x69,0x6F,0x6E,0x73,0x20,0x43,0x65,0x72, -0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x30,0x31,0x30,0x30,0x30,0x30, -0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, -0x39,0x5A,0x30,0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0A,0x13,0x18,0x4E,0x65,0x74,0x77, -0x6F,0x72,0x6B,0x20,0x53,0x6F,0x6C,0x75,0x74,0x69,0x6F,0x6E,0x73,0x20,0x4C,0x2E, -0x4C,0x2E,0x43,0x2E,0x31,0x30,0x30,0x2E,0x06,0x03,0x55,0x04,0x03,0x13,0x27,0x4E, -0x65,0x74,0x77,0x6F,0x72,0x6B,0x20,0x53,0x6F,0x6C,0x75,0x74,0x69,0x6F,0x6E,0x73, -0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74, -0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82, -0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xE4,0xBC,0x7E,0x92,0x30,0x6D,0xC6,0xD8,0x8E, -0x2B,0x0B,0xBC,0x46,0xCE,0xE0,0x27,0x96,0xDE,0xDE,0xF9,0xFA,0x12,0xD3,0x3C,0x33, -0x73,0xB3,0x04,0x2F,0xBC,0x71,0x8C,0xE5,0x9F,0xB6,0x22,0x60,0x3E,0x5F,0x5D,0xCE, -0x09,0xFF,0x82,0x0C,0x1B,0x9A,0x51,0x50,0x1A,0x26,0x89,0xDD,0xD5,0x61,0x5D,0x19, -0xDC,0x12,0x0F,0x2D,0x0A,0xA2,0x43,0x5D,0x17,0xD0,0x34,0x92,0x20,0xEA,0x73,0xCF, -0x38,0x2C,0x06,0x26,0x09,0x7A,0x72,0xF7,0xFA,0x50,0x32,0xF8,0xC2,0x93,0xD3,0x69, -0xA2,0x23,0xCE,0x41,0xB1,0xCC,0xE4,0xD5,0x1F,0x36,0xD1,0x8A,0x3A,0xF8,0x8C,0x63, -0xE2,0x14,0x59,0x69,0xED,0x0D,0xD3,0x7F,0x6B,0xE8,0xB8,0x03,0xE5,0x4F,0x6A,0xE5, -0x98,0x63,0x69,0x48,0x05,0xBE,0x2E,0xFF,0x33,0xB6,0xE9,0x97,0x59,0x69,0xF8,0x67, -0x19,0xAE,0x93,0x61,0x96,0x44,0x15,0xD3,0x72,0xB0,0x3F,0xBC,0x6A,0x7D,0xEC,0x48, -0x7F,0x8D,0xC3,0xAB,0xAA,0x71,0x2B,0x53,0x69,0x41,0x53,0x34,0xB5,0xB0,0xB9,0xC5, -0x06,0x0A,0xC4,0xB0,0x45,0xF5,0x41,0x5D,0x6E,0x89,0x45,0x7B,0x3D,0x3B,0x26,0x8C, -0x74,0xC2,0xE5,0xD2,0xD1,0x7D,0xB2,0x11,0xD4,0xFB,0x58,0x32,0x22,0x9A,0x80,0xC9, -0xDC,0xFD,0x0C,0xE9,0x7F,0x5E,0x03,0x97,0xCE,0x3B,0x00,0x14,0x87,0x27,0x70,0x38, -0xA9,0x8E,0x6E,0xB3,0x27,0x76,0x98,0x51,0xE0,0x05,0xE3,0x21,0xAB,0x1A,0xD5,0x85, -0x22,0x3C,0x29,0xB5,0x9A,0x16,0xC5,0x80,0xA8,0xF4,0xBB,0x6B,0x30,0x8F,0x2F,0x46, -0x02,0xA2,0xB1,0x0C,0x22,0xE0,0xD3,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x97,0x30, -0x81,0x94,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x21,0x30,0xC9, -0xFB,0x00,0xD7,0x4E,0x98,0xDA,0x87,0xAA,0x2A,0xD0,0xA7,0x2E,0xB1,0x40,0x31,0xA7, -0x4C,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01, -0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01, -0x01,0xFF,0x30,0x52,0x06,0x03,0x55,0x1D,0x1F,0x04,0x4B,0x30,0x49,0x30,0x47,0xA0, -0x45,0xA0,0x43,0x86,0x41,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E, -0x6E,0x65,0x74,0x73,0x6F,0x6C,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x2F,0x4E,0x65, -0x74,0x77,0x6F,0x72,0x6B,0x53,0x6F,0x6C,0x75,0x74,0x69,0x6F,0x6E,0x73,0x43,0x65, -0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xBB,0xAE,0x4B,0xE7,0xB7,0x57, -0xEB,0x7F,0xAA,0x2D,0xB7,0x73,0x47,0x85,0x6A,0xC1,0xE4,0xA5,0x1D,0xE4,0xE7,0x3C, -0xE9,0xF4,0x59,0x65,0x77,0xB5,0x7A,0x5B,0x5A,0x8D,0x25,0x36,0xE0,0x7A,0x97,0x2E, -0x38,0xC0,0x57,0x60,0x83,0x98,0x06,0x83,0x9F,0xB9,0x76,0x7A,0x6E,0x50,0xE0,0xBA, -0x88,0x2C,0xFC,0x45,0xCC,0x18,0xB0,0x99,0x95,0x51,0x0E,0xEC,0x1D,0xB8,0x88,0xFF, -0x87,0x50,0x1C,0x82,0xC2,0xE3,0xE0,0x32,0x80,0xBF,0xA0,0x0B,0x47,0xC8,0xC3,0x31, -0xEF,0x99,0x67,0x32,0x80,0x4F,0x17,0x21,0x79,0x0C,0x69,0x5C,0xDE,0x5E,0x34,0xAE, -0x02,0xB5,0x26,0xEA,0x50,0xDF,0x7F,0x18,0x65,0x2C,0xC9,0xF2,0x63,0xE1,0xA9,0x07, -0xFE,0x7C,0x71,0x1F,0x6B,0x33,0x24,0x6A,0x1E,0x05,0xF7,0x05,0x68,0xC0,0x6A,0x12, -0xCB,0x2E,0x5E,0x61,0xCB,0xAE,0x28,0xD3,0x7E,0xC2,0xB4,0x66,0x91,0x26,0x5F,0x3C, -0x2E,0x24,0x5F,0xCB,0x58,0x0F,0xEB,0x28,0xEC,0xAF,0x11,0x96,0xF3,0xDC,0x7B,0x6F, -0xC0,0xA7,0x88,0xF2,0x53,0x77,0xB3,0x60,0x5E,0xAE,0xAE,0x28,0xDA,0x35,0x2C,0x6F, -0x34,0x45,0xD3,0x26,0xE1,0xDE,0xEC,0x5B,0x4F,0x27,0x6B,0x16,0x7C,0xBD,0x44,0x04, -0x18,0x82,0xB3,0x89,0x79,0x17,0x10,0x71,0x3D,0x7A,0xA2,0x16,0x4E,0xF5,0x01,0xCD, -0xA4,0x6C,0x65,0x68,0xA1,0x49,0x76,0x5C,0x43,0xC9,0xD8,0xBC,0x36,0x67,0x6C,0xA5, -0x94,0xB5,0xD4,0xCC,0xB9,0xBD,0x6A,0x35,0x56,0x21,0xDE,0xD8,0xC3,0xEB,0xFB,0xCB, -0xA4,0x60,0x4C,0xB0,0x55,0xA0,0xA0,0x7B,0x57,0xB2, -}; - - -/* subject:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 3 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com */ -/* issuer :/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 3 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com */ - - -const unsigned char RSA_Root_Certificate_1_certificate[747]={ -0x30,0x82,0x02,0xE7,0x30,0x82,0x02,0x50,0x02,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A, -0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0xBB,0x31,0x24,0x30, -0x22,0x06,0x03,0x55,0x04,0x07,0x13,0x1B,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74, -0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x65,0x74,0x77, -0x6F,0x72,0x6B,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x61, -0x6C,0x69,0x43,0x65,0x72,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x35,0x30,0x33, -0x06,0x03,0x55,0x04,0x0B,0x13,0x2C,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20, -0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x6F,0x6C,0x69,0x63,0x79,0x20,0x56, -0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, -0x69,0x74,0x79,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x68,0x74, -0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x61,0x6C,0x69,0x63,0x65,0x72, -0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x31,0x20,0x30,0x1E,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x09,0x01,0x16,0x11,0x69,0x6E,0x66,0x6F,0x40,0x76,0x61,0x6C,0x69, -0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x36, -0x32,0x36,0x30,0x30,0x32,0x32,0x33,0x33,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x32, -0x36,0x30,0x30,0x32,0x32,0x33,0x33,0x5A,0x30,0x81,0xBB,0x31,0x24,0x30,0x22,0x06, -0x03,0x55,0x04,0x07,0x13,0x1B,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20,0x56, -0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72, -0x6B,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x61,0x6C,0x69, -0x43,0x65,0x72,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x35,0x30,0x33,0x06,0x03, -0x55,0x04,0x0B,0x13,0x2C,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20,0x43,0x6C, -0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x6F,0x6C,0x69,0x63,0x79,0x20,0x56,0x61,0x6C, -0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74, -0x79,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x68,0x74,0x74,0x70, -0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x61,0x6C,0x69,0x63,0x65,0x72,0x74,0x2E, -0x63,0x6F,0x6D,0x2F,0x31,0x20,0x30,0x1E,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x09,0x01,0x16,0x11,0x69,0x6E,0x66,0x6F,0x40,0x76,0x61,0x6C,0x69,0x63,0x65, -0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02, -0x81,0x81,0x00,0xE3,0x98,0x51,0x96,0x1C,0xE8,0xD5,0xB1,0x06,0x81,0x6A,0x57,0xC3, -0x72,0x75,0x93,0xAB,0xCF,0x9E,0xA6,0xFC,0xF3,0x16,0x52,0xD6,0x2D,0x4D,0x9F,0x35, -0x44,0xA8,0x2E,0x04,0x4D,0x07,0x49,0x8A,0x38,0x29,0xF5,0x77,0x37,0xE7,0xB7,0xAB, -0x5D,0xDF,0x36,0x71,0x14,0x99,0x8F,0xDC,0xC2,0x92,0xF1,0xE7,0x60,0x92,0x97,0xEC, -0xD8,0x48,0xDC,0xBF,0xC1,0x02,0x20,0xC6,0x24,0xA4,0x28,0x4C,0x30,0x5A,0x76,0x6D, -0xB1,0x5C,0xF3,0xDD,0xDE,0x9E,0x10,0x71,0xA1,0x88,0xC7,0x5B,0x9B,0x41,0x6D,0xCA, -0xB0,0xB8,0x8E,0x15,0xEE,0xAD,0x33,0x2B,0xCF,0x47,0x04,0x5C,0x75,0x71,0x0A,0x98, -0x24,0x98,0x29,0xA7,0x49,0x59,0xA5,0xDD,0xF8,0xB7,0x43,0x62,0x61,0xF3,0xD3,0xE2, -0xD0,0x55,0x3F,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x56,0xBB,0x02,0x58,0x84, -0x67,0x08,0x2C,0xDF,0x1F,0xDB,0x7B,0x49,0x33,0xF5,0xD3,0x67,0x9D,0xF4,0xB4,0x0A, -0x10,0xB3,0xC9,0xC5,0x2C,0xE2,0x92,0x6A,0x71,0x78,0x27,0xF2,0x70,0x83,0x42,0xD3, -0x3E,0xCF,0xA9,0x54,0xF4,0xF1,0xD8,0x92,0x16,0x8C,0xD1,0x04,0xCB,0x4B,0xAB,0xC9, -0x9F,0x45,0xAE,0x3C,0x8A,0xA9,0xB0,0x71,0x33,0x5D,0xC8,0xC5,0x57,0xDF,0xAF,0xA8, -0x35,0xB3,0x7F,0x89,0x87,0xE9,0xE8,0x25,0x92,0xB8,0x7F,0x85,0x7A,0xAE,0xD6,0xBC, -0x1E,0x37,0x58,0x2A,0x67,0xC9,0x91,0xCF,0x2A,0x81,0x3E,0xED,0xC6,0x39,0xDF,0xC0, -0x3E,0x19,0x9C,0x19,0xCC,0x13,0x4D,0x82,0x41,0xB5,0x8C,0xDE,0xE0,0x3D,0x60,0x08, -0x20,0x0F,0x45,0x7E,0x6B,0xA2,0x7F,0xA3,0x8C,0x15,0xEE, -}; - - -/* subject:/C=US/O=Starfield Technologies, Inc./OU=Starfield Class 2 Certification Authority */ -/* issuer :/C=US/O=Starfield Technologies, Inc./OU=Starfield Class 2 Certification Authority */ - - -const unsigned char Starfield_Class_2_CA_certificate[1043]={ -0x30,0x82,0x04,0x0F,0x30,0x82,0x02,0xF7,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x68,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x25, -0x30,0x23,0x06,0x03,0x55,0x04,0x0A,0x13,0x1C,0x53,0x74,0x61,0x72,0x66,0x69,0x65, -0x6C,0x64,0x20,0x54,0x65,0x63,0x68,0x6E,0x6F,0x6C,0x6F,0x67,0x69,0x65,0x73,0x2C, -0x20,0x49,0x6E,0x63,0x2E,0x31,0x32,0x30,0x30,0x06,0x03,0x55,0x04,0x0B,0x13,0x29, -0x53,0x74,0x61,0x72,0x66,0x69,0x65,0x6C,0x64,0x20,0x43,0x6C,0x61,0x73,0x73,0x20, -0x32,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20, -0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x34,0x30, -0x36,0x32,0x39,0x31,0x37,0x33,0x39,0x31,0x36,0x5A,0x17,0x0D,0x33,0x34,0x30,0x36, -0x32,0x39,0x31,0x37,0x33,0x39,0x31,0x36,0x5A,0x30,0x68,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04, -0x0A,0x13,0x1C,0x53,0x74,0x61,0x72,0x66,0x69,0x65,0x6C,0x64,0x20,0x54,0x65,0x63, -0x68,0x6E,0x6F,0x6C,0x6F,0x67,0x69,0x65,0x73,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31, -0x32,0x30,0x30,0x06,0x03,0x55,0x04,0x0B,0x13,0x29,0x53,0x74,0x61,0x72,0x66,0x69, -0x65,0x6C,0x64,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x32,0x20,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, -0x69,0x74,0x79,0x30,0x82,0x01,0x20,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0D,0x00,0x30,0x82,0x01,0x08,0x02, -0x82,0x01,0x01,0x00,0xB7,0x32,0xC8,0xFE,0xE9,0x71,0xA6,0x04,0x85,0xAD,0x0C,0x11, -0x64,0xDF,0xCE,0x4D,0xEF,0xC8,0x03,0x18,0x87,0x3F,0xA1,0xAB,0xFB,0x3C,0xA6,0x9F, -0xF0,0xC3,0xA1,0xDA,0xD4,0xD8,0x6E,0x2B,0x53,0x90,0xFB,0x24,0xA4,0x3E,0x84,0xF0, -0x9E,0xE8,0x5F,0xEC,0xE5,0x27,0x44,0xF5,0x28,0xA6,0x3F,0x7B,0xDE,0xE0,0x2A,0xF0, -0xC8,0xAF,0x53,0x2F,0x9E,0xCA,0x05,0x01,0x93,0x1E,0x8F,0x66,0x1C,0x39,0xA7,0x4D, -0xFA,0x5A,0xB6,0x73,0x04,0x25,0x66,0xEB,0x77,0x7F,0xE7,0x59,0xC6,0x4A,0x99,0x25, -0x14,0x54,0xEB,0x26,0xC7,0xF3,0x7F,0x19,0xD5,0x30,0x70,0x8F,0xAF,0xB0,0x46,0x2A, -0xFF,0xAD,0xEB,0x29,0xED,0xD7,0x9F,0xAA,0x04,0x87,0xA3,0xD4,0xF9,0x89,0xA5,0x34, -0x5F,0xDB,0x43,0x91,0x82,0x36,0xD9,0x66,0x3C,0xB1,0xB8,0xB9,0x82,0xFD,0x9C,0x3A, -0x3E,0x10,0xC8,0x3B,0xEF,0x06,0x65,0x66,0x7A,0x9B,0x19,0x18,0x3D,0xFF,0x71,0x51, -0x3C,0x30,0x2E,0x5F,0xBE,0x3D,0x77,0x73,0xB2,0x5D,0x06,0x6C,0xC3,0x23,0x56,0x9A, -0x2B,0x85,0x26,0x92,0x1C,0xA7,0x02,0xB3,0xE4,0x3F,0x0D,0xAF,0x08,0x79,0x82,0xB8, -0x36,0x3D,0xEA,0x9C,0xD3,0x35,0xB3,0xBC,0x69,0xCA,0xF5,0xCC,0x9D,0xE8,0xFD,0x64, -0x8D,0x17,0x80,0x33,0x6E,0x5E,0x4A,0x5D,0x99,0xC9,0x1E,0x87,0xB4,0x9D,0x1A,0xC0, -0xD5,0x6E,0x13,0x35,0x23,0x5E,0xDF,0x9B,0x5F,0x3D,0xEF,0xD6,0xF7,0x76,0xC2,0xEA, -0x3E,0xBB,0x78,0x0D,0x1C,0x42,0x67,0x6B,0x04,0xD8,0xF8,0xD6,0xDA,0x6F,0x8B,0xF2, -0x44,0xA0,0x01,0xAB,0x02,0x01,0x03,0xA3,0x81,0xC5,0x30,0x81,0xC2,0x30,0x1D,0x06, -0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xBF,0x5F,0xB7,0xD1,0xCE,0xDD,0x1F,0x86, -0xF4,0x5B,0x55,0xAC,0xDC,0xD7,0x10,0xC2,0x0E,0xA9,0x88,0xE7,0x30,0x81,0x92,0x06, -0x03,0x55,0x1D,0x23,0x04,0x81,0x8A,0x30,0x81,0x87,0x80,0x14,0xBF,0x5F,0xB7,0xD1, -0xCE,0xDD,0x1F,0x86,0xF4,0x5B,0x55,0xAC,0xDC,0xD7,0x10,0xC2,0x0E,0xA9,0x88,0xE7, -0xA1,0x6C,0xA4,0x6A,0x30,0x68,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x55,0x53,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0A,0x13,0x1C,0x53,0x74, -0x61,0x72,0x66,0x69,0x65,0x6C,0x64,0x20,0x54,0x65,0x63,0x68,0x6E,0x6F,0x6C,0x6F, -0x67,0x69,0x65,0x73,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x32,0x30,0x30,0x06,0x03, -0x55,0x04,0x0B,0x13,0x29,0x53,0x74,0x61,0x72,0x66,0x69,0x65,0x6C,0x64,0x20,0x43, -0x6C,0x61,0x73,0x73,0x20,0x32,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, -0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x82,0x01, -0x00,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82, -0x01,0x01,0x00,0x05,0x9D,0x3F,0x88,0x9D,0xD1,0xC9,0x1A,0x55,0xA1,0xAC,0x69,0xF3, -0xF3,0x59,0xDA,0x9B,0x01,0x87,0x1A,0x4F,0x57,0xA9,0xA1,0x79,0x09,0x2A,0xDB,0xF7, -0x2F,0xB2,0x1E,0xCC,0xC7,0x5E,0x6A,0xD8,0x83,0x87,0xA1,0x97,0xEF,0x49,0x35,0x3E, -0x77,0x06,0x41,0x58,0x62,0xBF,0x8E,0x58,0xB8,0x0A,0x67,0x3F,0xEC,0xB3,0xDD,0x21, -0x66,0x1F,0xC9,0x54,0xFA,0x72,0xCC,0x3D,0x4C,0x40,0xD8,0x81,0xAF,0x77,0x9E,0x83, -0x7A,0xBB,0xA2,0xC7,0xF5,0x34,0x17,0x8E,0xD9,0x11,0x40,0xF4,0xFC,0x2C,0x2A,0x4D, -0x15,0x7F,0xA7,0x62,0x5D,0x2E,0x25,0xD3,0x00,0x0B,0x20,0x1A,0x1D,0x68,0xF9,0x17, -0xB8,0xF4,0xBD,0x8B,0xED,0x28,0x59,0xDD,0x4D,0x16,0x8B,0x17,0x83,0xC8,0xB2,0x65, -0xC7,0x2D,0x7A,0xA5,0xAA,0xBC,0x53,0x86,0x6D,0xDD,0x57,0xA4,0xCA,0xF8,0x20,0x41, -0x0B,0x68,0xF0,0xF4,0xFB,0x74,0xBE,0x56,0x5D,0x7A,0x79,0xF5,0xF9,0x1D,0x85,0xE3, -0x2D,0x95,0xBE,0xF5,0x71,0x90,0x43,0xCC,0x8D,0x1F,0x9A,0x00,0x0A,0x87,0x29,0xE9, -0x55,0x22,0x58,0x00,0x23,0xEA,0xE3,0x12,0x43,0x29,0x5B,0x47,0x08,0xDD,0x8C,0x41, -0x6A,0x65,0x06,0xA8,0xE5,0x21,0xAA,0x41,0xB4,0x95,0x21,0x95,0xB9,0x7D,0xD1,0x34, -0xAB,0x13,0xD6,0xAD,0xBC,0xDC,0xE2,0x3D,0x39,0xCD,0xBD,0x3E,0x75,0x70,0xA1,0x18, -0x59,0x03,0xC9,0x22,0xB4,0x8F,0x9C,0xD5,0x5E,0x2A,0xD7,0xA5,0xB6,0xD4,0x0A,0x6D, -0xF8,0xB7,0x40,0x11,0x46,0x9A,0x1F,0x79,0x0E,0x62,0xBF,0x0F,0x97,0xEC,0xE0,0x2F, -0x1F,0x17,0x94, -}; - - -/* subject:/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./CN=Starfield Root Certificate Authority - G2 */ -/* issuer :/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./CN=Starfield Root Certificate Authority - G2 */ - - -const unsigned char Starfield_Root_Certificate_Authority___G2_certificate[993]={ -0x30,0x82,0x03,0xDD,0x30,0x82,0x02,0xC5,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30, -0x81,0x8F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31, -0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x13,0x07,0x41,0x72,0x69,0x7A,0x6F,0x6E, -0x61,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x07,0x13,0x0A,0x53,0x63,0x6F,0x74, -0x74,0x73,0x64,0x61,0x6C,0x65,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0A,0x13, -0x1C,0x53,0x74,0x61,0x72,0x66,0x69,0x65,0x6C,0x64,0x20,0x54,0x65,0x63,0x68,0x6E, -0x6F,0x6C,0x6F,0x67,0x69,0x65,0x73,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x32,0x30, -0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x53,0x74,0x61,0x72,0x66,0x69,0x65,0x6C, -0x64,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, -0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47, -0x32,0x30,0x1E,0x17,0x0D,0x30,0x39,0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30,0x30, -0x30,0x5A,0x17,0x0D,0x33,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39, -0x5A,0x30,0x81,0x8F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x13,0x07,0x41,0x72,0x69,0x7A, -0x6F,0x6E,0x61,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x07,0x13,0x0A,0x53,0x63, -0x6F,0x74,0x74,0x73,0x64,0x61,0x6C,0x65,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04, -0x0A,0x13,0x1C,0x53,0x74,0x61,0x72,0x66,0x69,0x65,0x6C,0x64,0x20,0x54,0x65,0x63, -0x68,0x6E,0x6F,0x6C,0x6F,0x67,0x69,0x65,0x73,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31, -0x32,0x30,0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x53,0x74,0x61,0x72,0x66,0x69, -0x65,0x6C,0x64,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69, -0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D, -0x20,0x47,0x32,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02, -0x82,0x01,0x01,0x00,0xBD,0xED,0xC1,0x03,0xFC,0xF6,0x8F,0xFC,0x02,0xB1,0x6F,0x5B, -0x9F,0x48,0xD9,0x9D,0x79,0xE2,0xA2,0xB7,0x03,0x61,0x56,0x18,0xC3,0x47,0xB6,0xD7, -0xCA,0x3D,0x35,0x2E,0x89,0x43,0xF7,0xA1,0x69,0x9B,0xDE,0x8A,0x1A,0xFD,0x13,0x20, -0x9C,0xB4,0x49,0x77,0x32,0x29,0x56,0xFD,0xB9,0xEC,0x8C,0xDD,0x22,0xFA,0x72,0xDC, -0x27,0x61,0x97,0xEE,0xF6,0x5A,0x84,0xEC,0x6E,0x19,0xB9,0x89,0x2C,0xDC,0x84,0x5B, -0xD5,0x74,0xFB,0x6B,0x5F,0xC5,0x89,0xA5,0x10,0x52,0x89,0x46,0x55,0xF4,0xB8,0x75, -0x1C,0xE6,0x7F,0xE4,0x54,0xAE,0x4B,0xF8,0x55,0x72,0x57,0x02,0x19,0xF8,0x17,0x71, -0x59,0xEB,0x1E,0x28,0x07,0x74,0xC5,0x9D,0x48,0xBE,0x6C,0xB4,0xF4,0xA4,0xB0,0xF3, -0x64,0x37,0x79,0x92,0xC0,0xEC,0x46,0x5E,0x7F,0xE1,0x6D,0x53,0x4C,0x62,0xAF,0xCD, -0x1F,0x0B,0x63,0xBB,0x3A,0x9D,0xFB,0xFC,0x79,0x00,0x98,0x61,0x74,0xCF,0x26,0x82, -0x40,0x63,0xF3,0xB2,0x72,0x6A,0x19,0x0D,0x99,0xCA,0xD4,0x0E,0x75,0xCC,0x37,0xFB, -0x8B,0x89,0xC1,0x59,0xF1,0x62,0x7F,0x5F,0xB3,0x5F,0x65,0x30,0xF8,0xA7,0xB7,0x4D, -0x76,0x5A,0x1E,0x76,0x5E,0x34,0xC0,0xE8,0x96,0x56,0x99,0x8A,0xB3,0xF0,0x7F,0xA4, -0xCD,0xBD,0xDC,0x32,0x31,0x7C,0x91,0xCF,0xE0,0x5F,0x11,0xF8,0x6B,0xAA,0x49,0x5C, -0xD1,0x99,0x94,0xD1,0xA2,0xE3,0x63,0x5B,0x09,0x76,0xB5,0x56,0x62,0xE1,0x4B,0x74, -0x1D,0x96,0xD4,0x26,0xD4,0x08,0x04,0x59,0xD0,0x98,0x0E,0x0E,0xE6,0xDE,0xFC,0xC3, -0xEC,0x1F,0x90,0xF1,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x0F,0x06, -0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E, -0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D, -0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x7C,0x0C,0x32,0x1F,0xA7,0xD9,0x30, -0x7F,0xC4,0x7D,0x68,0xA3,0x62,0xA8,0xA1,0xCE,0xAB,0x07,0x5B,0x27,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01, -0x00,0x11,0x59,0xFA,0x25,0x4F,0x03,0x6F,0x94,0x99,0x3B,0x9A,0x1F,0x82,0x85,0x39, -0xD4,0x76,0x05,0x94,0x5E,0xE1,0x28,0x93,0x6D,0x62,0x5D,0x09,0xC2,0xA0,0xA8,0xD4, -0xB0,0x75,0x38,0xF1,0x34,0x6A,0x9D,0xE4,0x9F,0x8A,0x86,0x26,0x51,0xE6,0x2C,0xD1, -0xC6,0x2D,0x6E,0x95,0x20,0x4A,0x92,0x01,0xEC,0xB8,0x8A,0x67,0x7B,0x31,0xE2,0x67, -0x2E,0x8C,0x95,0x03,0x26,0x2E,0x43,0x9D,0x4A,0x31,0xF6,0x0E,0xB5,0x0C,0xBB,0xB7, -0xE2,0x37,0x7F,0x22,0xBA,0x00,0xA3,0x0E,0x7B,0x52,0xFB,0x6B,0xBB,0x3B,0xC4,0xD3, -0x79,0x51,0x4E,0xCD,0x90,0xF4,0x67,0x07,0x19,0xC8,0x3C,0x46,0x7A,0x0D,0x01,0x7D, -0xC5,0x58,0xE7,0x6D,0xE6,0x85,0x30,0x17,0x9A,0x24,0xC4,0x10,0xE0,0x04,0xF7,0xE0, -0xF2,0x7F,0xD4,0xAA,0x0A,0xFF,0x42,0x1D,0x37,0xED,0x94,0xE5,0x64,0x59,0x12,0x20, -0x77,0x38,0xD3,0x32,0x3E,0x38,0x81,0x75,0x96,0x73,0xFA,0x68,0x8F,0xB1,0xCB,0xCE, -0x1F,0xC5,0xEC,0xFA,0x9C,0x7E,0xCF,0x7E,0xB1,0xF1,0x07,0x2D,0xB6,0xFC,0xBF,0xCA, -0xA4,0xBF,0xD0,0x97,0x05,0x4A,0xBC,0xEA,0x18,0x28,0x02,0x90,0xBD,0x54,0x78,0x09, -0x21,0x71,0xD3,0xD1,0x7D,0x1D,0xD9,0x16,0xB0,0xA9,0x61,0x3D,0xD0,0x0A,0x00,0x22, -0xFC,0xC7,0x7B,0xCB,0x09,0x64,0x45,0x0B,0x3B,0x40,0x81,0xF7,0x7D,0x7C,0x32,0xF5, -0x98,0xCA,0x58,0x8E,0x7D,0x2A,0xEE,0x90,0x59,0x73,0x64,0xF9,0x36,0x74,0x5E,0x25, -0xA1,0xF5,0x66,0x05,0x2E,0x7F,0x39,0x15,0xA9,0x2A,0xFB,0x50,0x8B,0x8E,0x85,0x69, -0xF4, -}; - - -/* subject:/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./CN=Starfield Services Root Certificate Authority - G2 */ -/* issuer :/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./CN=Starfield Services Root Certificate Authority - G2 */ - - -const unsigned char Starfield_Services_Root_Certificate_Authority___G2_certificate[1011]={ -0x30,0x82,0x03,0xEF,0x30,0x82,0x02,0xD7,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30, -0x81,0x98,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31, -0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x13,0x07,0x41,0x72,0x69,0x7A,0x6F,0x6E, -0x61,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x07,0x13,0x0A,0x53,0x63,0x6F,0x74, -0x74,0x73,0x64,0x61,0x6C,0x65,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0A,0x13, -0x1C,0x53,0x74,0x61,0x72,0x66,0x69,0x65,0x6C,0x64,0x20,0x54,0x65,0x63,0x68,0x6E, -0x6F,0x6C,0x6F,0x67,0x69,0x65,0x73,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x3B,0x30, -0x39,0x06,0x03,0x55,0x04,0x03,0x13,0x32,0x53,0x74,0x61,0x72,0x66,0x69,0x65,0x6C, -0x64,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x52,0x6F,0x6F,0x74,0x20, -0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68, -0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x32,0x30,0x1E,0x17,0x0D,0x30,0x39, -0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x37,0x31, -0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x98,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,0x30,0x0E,0x06,0x03, -0x55,0x04,0x08,0x13,0x07,0x41,0x72,0x69,0x7A,0x6F,0x6E,0x61,0x31,0x13,0x30,0x11, -0x06,0x03,0x55,0x04,0x07,0x13,0x0A,0x53,0x63,0x6F,0x74,0x74,0x73,0x64,0x61,0x6C, -0x65,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0A,0x13,0x1C,0x53,0x74,0x61,0x72, -0x66,0x69,0x65,0x6C,0x64,0x20,0x54,0x65,0x63,0x68,0x6E,0x6F,0x6C,0x6F,0x67,0x69, -0x65,0x73,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04, -0x03,0x13,0x32,0x53,0x74,0x61,0x72,0x66,0x69,0x65,0x6C,0x64,0x20,0x53,0x65,0x72, -0x76,0x69,0x63,0x65,0x73,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79, -0x20,0x2D,0x20,0x47,0x32,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01, -0x0A,0x02,0x82,0x01,0x01,0x00,0xD5,0x0C,0x3A,0xC4,0x2A,0xF9,0x4E,0xE2,0xF5,0xBE, -0x19,0x97,0x5F,0x8E,0x88,0x53,0xB1,0x1F,0x3F,0xCB,0xCF,0x9F,0x20,0x13,0x6D,0x29, -0x3A,0xC8,0x0F,0x7D,0x3C,0xF7,0x6B,0x76,0x38,0x63,0xD9,0x36,0x60,0xA8,0x9B,0x5E, -0x5C,0x00,0x80,0xB2,0x2F,0x59,0x7F,0xF6,0x87,0xF9,0x25,0x43,0x86,0xE7,0x69,0x1B, -0x52,0x9A,0x90,0xE1,0x71,0xE3,0xD8,0x2D,0x0D,0x4E,0x6F,0xF6,0xC8,0x49,0xD9,0xB6, -0xF3,0x1A,0x56,0xAE,0x2B,0xB6,0x74,0x14,0xEB,0xCF,0xFB,0x26,0xE3,0x1A,0xBA,0x1D, -0x96,0x2E,0x6A,0x3B,0x58,0x94,0x89,0x47,0x56,0xFF,0x25,0xA0,0x93,0x70,0x53,0x83, -0xDA,0x84,0x74,0x14,0xC3,0x67,0x9E,0x04,0x68,0x3A,0xDF,0x8E,0x40,0x5A,0x1D,0x4A, -0x4E,0xCF,0x43,0x91,0x3B,0xE7,0x56,0xD6,0x00,0x70,0xCB,0x52,0xEE,0x7B,0x7D,0xAE, -0x3A,0xE7,0xBC,0x31,0xF9,0x45,0xF6,0xC2,0x60,0xCF,0x13,0x59,0x02,0x2B,0x80,0xCC, -0x34,0x47,0xDF,0xB9,0xDE,0x90,0x65,0x6D,0x02,0xCF,0x2C,0x91,0xA6,0xA6,0xE7,0xDE, -0x85,0x18,0x49,0x7C,0x66,0x4E,0xA3,0x3A,0x6D,0xA9,0xB5,0xEE,0x34,0x2E,0xBA,0x0D, -0x03,0xB8,0x33,0xDF,0x47,0xEB,0xB1,0x6B,0x8D,0x25,0xD9,0x9B,0xCE,0x81,0xD1,0x45, -0x46,0x32,0x96,0x70,0x87,0xDE,0x02,0x0E,0x49,0x43,0x85,0xB6,0x6C,0x73,0xBB,0x64, -0xEA,0x61,0x41,0xAC,0xC9,0xD4,0x54,0xDF,0x87,0x2F,0xC7,0x22,0xB2,0x26,0xCC,0x9F, -0x59,0x54,0x68,0x9F,0xFC,0xBE,0x2A,0x2F,0xC4,0x55,0x1C,0x75,0x40,0x60,0x17,0x85, -0x02,0x55,0x39,0x8B,0x7F,0x05,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30, -0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF, -0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06, -0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9C,0x5F,0x00,0xDF,0xAA, -0x01,0xD7,0x30,0x2B,0x38,0x88,0xA2,0xB8,0x6D,0x4A,0x9C,0xF2,0x11,0x91,0x83,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82, -0x01,0x01,0x00,0x4B,0x36,0xA6,0x84,0x77,0x69,0xDD,0x3B,0x19,0x9F,0x67,0x23,0x08, -0x6F,0x0E,0x61,0xC9,0xFD,0x84,0xDC,0x5F,0xD8,0x36,0x81,0xCD,0xD8,0x1B,0x41,0x2D, -0x9F,0x60,0xDD,0xC7,0x1A,0x68,0xD9,0xD1,0x6E,0x86,0xE1,0x88,0x23,0xCF,0x13,0xDE, -0x43,0xCF,0xE2,0x34,0xB3,0x04,0x9D,0x1F,0x29,0xD5,0xBF,0xF8,0x5E,0xC8,0xD5,0xC1, -0xBD,0xEE,0x92,0x6F,0x32,0x74,0xF2,0x91,0x82,0x2F,0xBD,0x82,0x42,0x7A,0xAD,0x2A, -0xB7,0x20,0x7D,0x4D,0xBC,0x7A,0x55,0x12,0xC2,0x15,0xEA,0xBD,0xF7,0x6A,0x95,0x2E, -0x6C,0x74,0x9F,0xCF,0x1C,0xB4,0xF2,0xC5,0x01,0xA3,0x85,0xD0,0x72,0x3E,0xAD,0x73, -0xAB,0x0B,0x9B,0x75,0x0C,0x6D,0x45,0xB7,0x8E,0x94,0xAC,0x96,0x37,0xB5,0xA0,0xD0, -0x8F,0x15,0x47,0x0E,0xE3,0xE8,0x83,0xDD,0x8F,0xFD,0xEF,0x41,0x01,0x77,0xCC,0x27, -0xA9,0x62,0x85,0x33,0xF2,0x37,0x08,0xEF,0x71,0xCF,0x77,0x06,0xDE,0xC8,0x19,0x1D, -0x88,0x40,0xCF,0x7D,0x46,0x1D,0xFF,0x1E,0xC7,0xE1,0xCE,0xFF,0x23,0xDB,0xC6,0xFA, -0x8D,0x55,0x4E,0xA9,0x02,0xE7,0x47,0x11,0x46,0x3E,0xF4,0xFD,0xBD,0x7B,0x29,0x26, -0xBB,0xA9,0x61,0x62,0x37,0x28,0xB6,0x2D,0x2A,0xF6,0x10,0x86,0x64,0xC9,0x70,0xA7, -0xD2,0xAD,0xB7,0x29,0x70,0x79,0xEA,0x3C,0xDA,0x63,0x25,0x9F,0xFD,0x68,0xB7,0x30, -0xEC,0x70,0xFB,0x75,0x8A,0xB7,0x6D,0x60,0x67,0xB2,0x1E,0xC8,0xB9,0xE9,0xD8,0xA8, -0x6F,0x02,0x8B,0x67,0x0D,0x4D,0x26,0x57,0x71,0xDA,0x20,0xFC,0xC1,0x4A,0x50,0x8D, -0xB1,0x28,0xBA, -}; - - -/* subject:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority */ -/* issuer :/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority */ - - -const unsigned char StartCom_Certification_Authority_certificate[1931]={ -0x30,0x82,0x07,0x87,0x30,0x82,0x05,0x6F,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x2D, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30, -0x7D,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x49,0x4C,0x31,0x16, -0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x53,0x74,0x61,0x72,0x74,0x43,0x6F, -0x6D,0x20,0x4C,0x74,0x64,0x2E,0x31,0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x0B,0x13, -0x22,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x44,0x69,0x67,0x69,0x74,0x61,0x6C,0x20, -0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x53,0x69,0x67,0x6E, -0x69,0x6E,0x67,0x31,0x29,0x30,0x27,0x06,0x03,0x55,0x04,0x03,0x13,0x20,0x53,0x74, -0x61,0x72,0x74,0x43,0x6F,0x6D,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, -0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E, -0x17,0x0D,0x30,0x36,0x30,0x39,0x31,0x37,0x31,0x39,0x34,0x36,0x33,0x37,0x5A,0x17, -0x0D,0x33,0x36,0x30,0x39,0x31,0x37,0x31,0x39,0x34,0x36,0x33,0x36,0x5A,0x30,0x7D, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x49,0x4C,0x31,0x16,0x30, -0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x53,0x74,0x61,0x72,0x74,0x43,0x6F,0x6D, -0x20,0x4C,0x74,0x64,0x2E,0x31,0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x0B,0x13,0x22, -0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x44,0x69,0x67,0x69,0x74,0x61,0x6C,0x20,0x43, -0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x53,0x69,0x67,0x6E,0x69, -0x6E,0x67,0x31,0x29,0x30,0x27,0x06,0x03,0x55,0x04,0x03,0x13,0x20,0x53,0x74,0x61, -0x72,0x74,0x43,0x6F,0x6D,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74, -0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x02, -0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00, -0x03,0x82,0x02,0x0F,0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02,0x01,0x00,0xC1,0x88, -0xDB,0x09,0xBC,0x6C,0x46,0x7C,0x78,0x9F,0x95,0x7B,0xB5,0x33,0x90,0xF2,0x72,0x62, -0xD6,0xC1,0x36,0x20,0x22,0x24,0x5E,0xCE,0xE9,0x77,0xF2,0x43,0x0A,0xA2,0x06,0x64, -0xA4,0xCC,0x8E,0x36,0xF8,0x38,0xE6,0x23,0xF0,0x6E,0x6D,0xB1,0x3C,0xDD,0x72,0xA3, -0x85,0x1C,0xA1,0xD3,0x3D,0xB4,0x33,0x2B,0xD3,0x2F,0xAF,0xFE,0xEA,0xB0,0x41,0x59, -0x67,0xB6,0xC4,0x06,0x7D,0x0A,0x9E,0x74,0x85,0xD6,0x79,0x4C,0x80,0x37,0x7A,0xDF, -0x39,0x05,0x52,0x59,0xF7,0xF4,0x1B,0x46,0x43,0xA4,0xD2,0x85,0x85,0xD2,0xC3,0x71, -0xF3,0x75,0x62,0x34,0xBA,0x2C,0x8A,0x7F,0x1E,0x8F,0xEE,0xED,0x34,0xD0,0x11,0xC7, -0x96,0xCD,0x52,0x3D,0xBA,0x33,0xD6,0xDD,0x4D,0xDE,0x0B,0x3B,0x4A,0x4B,0x9F,0xC2, -0x26,0x2F,0xFA,0xB5,0x16,0x1C,0x72,0x35,0x77,0xCA,0x3C,0x5D,0xE6,0xCA,0xE1,0x26, -0x8B,0x1A,0x36,0x76,0x5C,0x01,0xDB,0x74,0x14,0x25,0xFE,0xED,0xB5,0xA0,0x88,0x0F, -0xDD,0x78,0xCA,0x2D,0x1F,0x07,0x97,0x30,0x01,0x2D,0x72,0x79,0xFA,0x46,0xD6,0x13, -0x2A,0xA8,0xB9,0xA6,0xAB,0x83,0x49,0x1D,0xE5,0xF2,0xEF,0xDD,0xE4,0x01,0x8E,0x18, -0x0A,0x8F,0x63,0x53,0x16,0x85,0x62,0xA9,0x0E,0x19,0x3A,0xCC,0xB5,0x66,0xA6,0xC2, -0x6B,0x74,0x07,0xE4,0x2B,0xE1,0x76,0x3E,0xB4,0x6D,0xD8,0xF6,0x44,0xE1,0x73,0x62, -0x1F,0x3B,0xC4,0xBE,0xA0,0x53,0x56,0x25,0x6C,0x51,0x09,0xF7,0xAA,0xAB,0xCA,0xBF, -0x76,0xFD,0x6D,0x9B,0xF3,0x9D,0xDB,0xBF,0x3D,0x66,0xBC,0x0C,0x56,0xAA,0xAF,0x98, -0x48,0x95,0x3A,0x4B,0xDF,0xA7,0x58,0x50,0xD9,0x38,0x75,0xA9,0x5B,0xEA,0x43,0x0C, -0x02,0xFF,0x99,0xEB,0xE8,0x6C,0x4D,0x70,0x5B,0x29,0x65,0x9C,0xDD,0xAA,0x5D,0xCC, -0xAF,0x01,0x31,0xEC,0x0C,0xEB,0xD2,0x8D,0xE8,0xEA,0x9C,0x7B,0xE6,0x6E,0xF7,0x27, -0x66,0x0C,0x1A,0x48,0xD7,0x6E,0x42,0xE3,0x3F,0xDE,0x21,0x3E,0x7B,0xE1,0x0D,0x70, -0xFB,0x63,0xAA,0xA8,0x6C,0x1A,0x54,0xB4,0x5C,0x25,0x7A,0xC9,0xA2,0xC9,0x8B,0x16, -0xA6,0xBB,0x2C,0x7E,0x17,0x5E,0x05,0x4D,0x58,0x6E,0x12,0x1D,0x01,0xEE,0x12,0x10, -0x0D,0xC6,0x32,0x7F,0x18,0xFF,0xFC,0xF4,0xFA,0xCD,0x6E,0x91,0xE8,0x36,0x49,0xBE, -0x1A,0x48,0x69,0x8B,0xC2,0x96,0x4D,0x1A,0x12,0xB2,0x69,0x17,0xC1,0x0A,0x90,0xD6, -0xFA,0x79,0x22,0x48,0xBF,0xBA,0x7B,0x69,0xF8,0x70,0xC7,0xFA,0x7A,0x37,0xD8,0xD8, -0x0D,0xD2,0x76,0x4F,0x57,0xFF,0x90,0xB7,0xE3,0x91,0xD2,0xDD,0xEF,0xC2,0x60,0xB7, -0x67,0x3A,0xDD,0xFE,0xAA,0x9C,0xF0,0xD4,0x8B,0x7F,0x72,0x22,0xCE,0xC6,0x9F,0x97, -0xB6,0xF8,0xAF,0x8A,0xA0,0x10,0xA8,0xD9,0xFB,0x18,0xC6,0xB6,0xB5,0x5C,0x52,0x3C, -0x89,0xB6,0x19,0x2A,0x73,0x01,0x0A,0x0F,0x03,0xB3,0x12,0x60,0xF2,0x7A,0x2F,0x81, -0xDB,0xA3,0x6E,0xFF,0x26,0x30,0x97,0xF5,0x8B,0xDD,0x89,0x57,0xB6,0xAD,0x3D,0xB3, -0xAF,0x2B,0xC5,0xB7,0x76,0x02,0xF0,0xA5,0xD6,0x2B,0x9A,0x86,0x14,0x2A,0x72,0xF6, -0xE3,0x33,0x8C,0x5D,0x09,0x4B,0x13,0xDF,0xBB,0x8C,0x74,0x13,0x52,0x4B,0x02,0x03, -0x01,0x00,0x01,0xA3,0x82,0x02,0x10,0x30,0x82,0x02,0x0C,0x30,0x0F,0x06,0x03,0x55, -0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03, -0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03, -0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x4E,0x0B,0xEF,0x1A,0xA4,0x40,0x5B,0xA5,0x17, -0x69,0x87,0x30,0xCA,0x34,0x68,0x43,0xD0,0x41,0xAE,0xF2,0x30,0x1F,0x06,0x03,0x55, -0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x4E,0x0B,0xEF,0x1A,0xA4,0x40,0x5B,0xA5, -0x17,0x69,0x87,0x30,0xCA,0x34,0x68,0x43,0xD0,0x41,0xAE,0xF2,0x30,0x82,0x01,0x5A, -0x06,0x03,0x55,0x1D,0x20,0x04,0x82,0x01,0x51,0x30,0x82,0x01,0x4D,0x30,0x82,0x01, -0x49,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x81,0xB5,0x37,0x01,0x01,0x01,0x30,0x82, -0x01,0x38,0x30,0x2E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x22, -0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73,0x74,0x61,0x72,0x74, -0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x2F,0x70,0x6F,0x6C,0x69,0x63,0x79,0x2E,0x70, -0x64,0x66,0x30,0x34,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x28, -0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73,0x74,0x61,0x72,0x74, -0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x2F,0x69,0x6E,0x74,0x65,0x72,0x6D,0x65,0x64, -0x69,0x61,0x74,0x65,0x2E,0x70,0x64,0x66,0x30,0x81,0xCF,0x06,0x08,0x2B,0x06,0x01, -0x05,0x05,0x07,0x02,0x02,0x30,0x81,0xC2,0x30,0x27,0x16,0x20,0x53,0x74,0x61,0x72, -0x74,0x20,0x43,0x6F,0x6D,0x6D,0x65,0x72,0x63,0x69,0x61,0x6C,0x20,0x28,0x53,0x74, -0x61,0x72,0x74,0x43,0x6F,0x6D,0x29,0x20,0x4C,0x74,0x64,0x2E,0x30,0x03,0x02,0x01, -0x01,0x1A,0x81,0x96,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x20,0x4C,0x69,0x61,0x62, -0x69,0x6C,0x69,0x74,0x79,0x2C,0x20,0x72,0x65,0x61,0x64,0x20,0x74,0x68,0x65,0x20, -0x73,0x65,0x63,0x74,0x69,0x6F,0x6E,0x20,0x2A,0x4C,0x65,0x67,0x61,0x6C,0x20,0x4C, -0x69,0x6D,0x69,0x74,0x61,0x74,0x69,0x6F,0x6E,0x73,0x2A,0x20,0x6F,0x66,0x20,0x74, -0x68,0x65,0x20,0x53,0x74,0x61,0x72,0x74,0x43,0x6F,0x6D,0x20,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, -0x69,0x74,0x79,0x20,0x50,0x6F,0x6C,0x69,0x63,0x79,0x20,0x61,0x76,0x61,0x69,0x6C, -0x61,0x62,0x6C,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77, -0x77,0x77,0x2E,0x73,0x74,0x61,0x72,0x74,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x2F, -0x70,0x6F,0x6C,0x69,0x63,0x79,0x2E,0x70,0x64,0x66,0x30,0x11,0x06,0x09,0x60,0x86, -0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07,0x30,0x38,0x06, -0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,0x04,0x2B,0x16,0x29,0x53,0x74, -0x61,0x72,0x74,0x43,0x6F,0x6D,0x20,0x46,0x72,0x65,0x65,0x20,0x53,0x53,0x4C,0x20, -0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75, -0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x8E,0x8F,0xE7,0xDC,0x94, -0x79,0x7C,0xF1,0x85,0x7F,0x9F,0x49,0x6F,0x6B,0xCA,0x5D,0xFB,0x8C,0xFE,0x04,0xC5, -0xC1,0x62,0xD1,0x7D,0x42,0x8A,0xBC,0x53,0xB7,0x94,0x03,0x66,0x30,0x3F,0xB1,0xE7, -0x0A,0xA7,0x50,0x20,0x55,0x25,0x7F,0x76,0x7A,0x14,0x0D,0xEB,0x04,0x0E,0x40,0xE6, -0x3E,0xD8,0x88,0xAB,0x07,0x27,0x83,0xA9,0x75,0xA6,0x37,0x73,0xC7,0xFD,0x4B,0xD2, -0x4D,0xAD,0x17,0x40,0xC8,0x46,0xBE,0x3B,0x7F,0x51,0xFC,0xC3,0xB6,0x05,0x31,0xDC, -0xCD,0x85,0x22,0x4E,0x71,0xB7,0xF2,0x71,0x5E,0xB0,0x1A,0xC6,0xBA,0x93,0x8B,0x78, -0x92,0x4A,0x85,0xF8,0x78,0x0F,0x83,0xFE,0x2F,0xAD,0x2C,0xF7,0xE4,0xA4,0xBB,0x2D, -0xD0,0xE7,0x0D,0x3A,0xB8,0x3E,0xCE,0xF6,0x78,0xF6,0xAE,0x47,0x24,0xCA,0xA3,0x35, -0x36,0xCE,0xC7,0xC6,0x87,0x98,0xDA,0xEC,0xFB,0xE9,0xB2,0xCE,0x27,0x9B,0x88,0xC3, -0x04,0xA1,0xF6,0x0B,0x59,0x68,0xAF,0xC9,0xDB,0x10,0x0F,0x4D,0xF6,0x64,0x63,0x5C, -0xA5,0x12,0x6F,0x92,0xB2,0x93,0x94,0xC7,0x88,0x17,0x0E,0x93,0xB6,0x7E,0x62,0x8B, -0x90,0x7F,0xAB,0x4E,0x9F,0xFC,0xE3,0x75,0x14,0x4F,0x2A,0x32,0xDF,0x5B,0x0D,0xE0, -0xF5,0x7B,0x93,0x0D,0xAB,0xA1,0xCF,0x87,0xE1,0xA5,0x04,0x45,0xE8,0x3C,0x12,0xA5, -0x09,0xC5,0xB0,0xD1,0xB7,0x53,0xF3,0x60,0x14,0xBA,0x85,0x69,0x6A,0x21,0x7C,0x1F, -0x75,0x61,0x17,0x20,0x17,0x7B,0x6C,0x3B,0x41,0x29,0x5C,0xE1,0xAC,0x5A,0xD1,0xCD, -0x8C,0x9B,0xEB,0x60,0x1D,0x19,0xEC,0xF7,0xE5,0xB0,0xDA,0xF9,0x79,0x18,0xA5,0x45, -0x3F,0x49,0x43,0x57,0xD2,0xDD,0x24,0xD5,0x2C,0xA3,0xFD,0x91,0x8D,0x27,0xB5,0xE5, -0xEB,0x14,0x06,0x9A,0x4C,0x7B,0x21,0xBB,0x3A,0xAD,0x30,0x06,0x18,0xC0,0xD8,0xC1, -0x6B,0x2C,0x7F,0x59,0x5C,0x5D,0x91,0xB1,0x70,0x22,0x57,0xEB,0x8A,0x6B,0x48,0x4A, -0xD5,0x0F,0x29,0xEC,0xC6,0x40,0xC0,0x2F,0x88,0x4C,0x68,0x01,0x17,0x77,0xF4,0x24, -0x19,0x4F,0xBD,0xFA,0xE1,0xB2,0x20,0x21,0x4B,0xDD,0x1A,0xD8,0x29,0x7D,0xAA,0xB8, -0xDE,0x54,0xEC,0x21,0x55,0x80,0x6C,0x1E,0xF5,0x30,0xC8,0xA3,0x10,0xE5,0xB2,0xE6, -0x2A,0x14,0x31,0xC3,0x85,0x2D,0x8C,0x98,0xB1,0x86,0x5A,0x4F,0x89,0x59,0x2D,0xB9, -0xC7,0xF7,0x1C,0xC8,0x8A,0x7F,0xC0,0x9D,0x05,0x4A,0xE6,0x42,0x4F,0x62,0xA3,0x6D, -0x29,0xA4,0x1F,0x85,0xAB,0xDB,0xE5,0x81,0xC8,0xAD,0x2A,0x3D,0x4C,0x5D,0x5B,0x84, -0x26,0x71,0xC4,0x85,0x5E,0x71,0x24,0xCA,0xA5,0x1B,0x6C,0xD8,0x61,0xD3,0x1A,0xE0, -0x54,0xDB,0xCE,0xBA,0xA9,0x32,0xB5,0x22,0xF6,0x73,0x41,0x09,0x5D,0xB8,0x17,0x5D, -0x0E,0x0F,0x99,0x90,0xD6,0x47,0xDA,0x6F,0x0A,0x3A,0x62,0x28,0x14,0x67,0x82,0xD9, -0xF1,0xD0,0x80,0x59,0x9B,0xCB,0x31,0xD8,0x9B,0x0F,0x8C,0x77,0x4E,0xB5,0x68,0x8A, -0xF2,0x6C,0xF6,0x24,0x0E,0x2D,0x6C,0x70,0xC5,0x73,0xD1,0xDE,0x14,0xD0,0x71,0x8F, -0xB6,0xD3,0x7B,0x02,0xF6,0xE3,0xB8,0xD4,0x09,0x6E,0x6B,0x9E,0x75,0x84,0x39,0xE6, -0x7F,0x25,0xA5,0xF2,0x48,0x00,0xC0,0xA4,0x01,0xDA,0x3F, -}; - - -/* subject:/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 */ -/* issuer :/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 */ - - -const unsigned char StartCom_Certification_Authority_G2_certificate[1383]={ -0x30,0x82,0x05,0x63,0x30,0x82,0x03,0x4B,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x3B, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30, -0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x49,0x4C,0x31,0x16, -0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x53,0x74,0x61,0x72,0x74,0x43,0x6F, -0x6D,0x20,0x4C,0x74,0x64,0x2E,0x31,0x2C,0x30,0x2A,0x06,0x03,0x55,0x04,0x03,0x13, -0x23,0x53,0x74,0x61,0x72,0x74,0x43,0x6F,0x6D,0x20,0x43,0x65,0x72,0x74,0x69,0x66, -0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74, -0x79,0x20,0x47,0x32,0x30,0x1E,0x17,0x0D,0x31,0x30,0x30,0x31,0x30,0x31,0x30,0x31, -0x30,0x30,0x30,0x31,0x5A,0x17,0x0D,0x33,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35, -0x39,0x30,0x31,0x5A,0x30,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x49,0x4C,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x53,0x74, -0x61,0x72,0x74,0x43,0x6F,0x6D,0x20,0x4C,0x74,0x64,0x2E,0x31,0x2C,0x30,0x2A,0x06, -0x03,0x55,0x04,0x03,0x13,0x23,0x53,0x74,0x61,0x72,0x74,0x43,0x6F,0x6D,0x20,0x43, -0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74, -0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x47,0x32,0x30,0x82,0x02,0x22,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x02,0x0F, -0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02,0x01,0x00,0xB6,0x89,0x36,0x5B,0x07,0xB7, -0x20,0x36,0xBD,0x82,0xBB,0xE1,0x16,0x20,0x03,0x95,0x7A,0xAF,0x0E,0xA3,0x55,0xC9, -0x25,0x99,0x4A,0xC5,0xD0,0x56,0x41,0x87,0x90,0x4D,0x21,0x60,0xA4,0x14,0x87,0x3B, -0xCD,0xFD,0xB2,0x3E,0xB4,0x67,0x03,0x6A,0xED,0xE1,0x0F,0x4B,0xC0,0x91,0x85,0x70, -0x45,0xE0,0x42,0x9E,0xDE,0x29,0x23,0xD4,0x01,0x0D,0xA0,0x10,0x79,0xB8,0xDB,0x03, -0xBD,0xF3,0xA9,0x2F,0xD1,0xC6,0xE0,0x0F,0xCB,0x9E,0x8A,0x14,0x0A,0xB8,0xBD,0xF6, -0x56,0x62,0xF1,0xC5,0x72,0xB6,0x32,0x25,0xD9,0xB2,0xF3,0xBD,0x65,0xC5,0x0D,0x2C, -0x6E,0xD5,0x92,0x6F,0x18,0x8B,0x00,0x41,0x14,0x82,0x6F,0x40,0x20,0x26,0x7A,0x28, -0x0F,0xF5,0x1E,0x7F,0x27,0xF7,0x94,0xB1,0x37,0x3D,0xB7,0xC7,0x91,0xF7,0xE2,0x01, -0xEC,0xFD,0x94,0x89,0xE1,0xCC,0x6E,0xD3,0x36,0xD6,0x0A,0x19,0x79,0xAE,0xD7,0x34, -0x82,0x65,0xFF,0x7C,0x42,0xBB,0xB6,0xDD,0x0B,0xA6,0x34,0xAF,0x4B,0x60,0xFE,0x7F, -0x43,0x49,0x06,0x8B,0x8C,0x43,0xB8,0x56,0xF2,0xD9,0x7F,0x21,0x43,0x17,0xEA,0xA7, -0x48,0x95,0x01,0x75,0x75,0xEA,0x2B,0xA5,0x43,0x95,0xEA,0x15,0x84,0x9D,0x08,0x8D, -0x26,0x6E,0x55,0x9B,0xAB,0xDC,0xD2,0x39,0xD2,0x31,0x1D,0x60,0xE2,0xAC,0xCC,0x56, -0x45,0x24,0xF5,0x1C,0x54,0xAB,0xEE,0x86,0xDD,0x96,0x32,0x85,0xF8,0x4C,0x4F,0xE8, -0x95,0x76,0xB6,0x05,0xDD,0x36,0x23,0x67,0xBC,0xFF,0x15,0xE2,0xCA,0x3B,0xE6,0xA6, -0xEC,0x3B,0xEC,0x26,0x11,0x34,0x48,0x8D,0xF6,0x80,0x2B,0x1A,0x23,0x02,0xEB,0x8A, -0x1C,0x3A,0x76,0x2A,0x7B,0x56,0x16,0x1C,0x72,0x2A,0xB3,0xAA,0xE3,0x60,0xA5,0x00, -0x9F,0x04,0x9B,0xE2,0x6F,0x1E,0x14,0x58,0x5B,0xA5,0x6C,0x8B,0x58,0x3C,0xC3,0xBA, -0x4E,0x3A,0x5C,0xF7,0xE1,0x96,0x2B,0x3E,0xEF,0x07,0xBC,0xA4,0xE5,0x5D,0xCC,0x4D, -0x9F,0x0D,0xE1,0xDC,0xAA,0xBB,0xE1,0x6E,0x1A,0xEC,0x8F,0xE1,0xB6,0x4C,0x4D,0x79, -0x72,0x5D,0x17,0x35,0x0B,0x1D,0xD7,0xC1,0x47,0xDA,0x96,0x24,0xE0,0xD0,0x72,0xA8, -0x5A,0x5F,0x66,0x2D,0x10,0xDC,0x2F,0x2A,0x13,0xAE,0x26,0xFE,0x0A,0x1C,0x19,0xCC, -0xD0,0x3E,0x0B,0x9C,0xC8,0x09,0x2E,0xF9,0x5B,0x96,0x7A,0x47,0x9C,0xE9,0x7A,0xF3, -0x05,0x50,0x74,0x95,0x73,0x9E,0x30,0x09,0xF3,0x97,0x82,0x5E,0xE6,0x8F,0x39,0x08, -0x1E,0x59,0xE5,0x35,0x14,0x42,0x13,0xFF,0x00,0x9C,0xF7,0xBE,0xAA,0x50,0xCF,0xE2, -0x51,0x48,0xD7,0xB8,0x6F,0xAF,0xF8,0x4E,0x7E,0x33,0x98,0x92,0x14,0x62,0x3A,0x75, -0x63,0xCF,0x7B,0xFA,0xDE,0x82,0x3B,0xA9,0xBB,0x39,0xE2,0xC4,0xBD,0x2C,0x00,0x0E, -0xC8,0x17,0xAC,0x13,0xEF,0x4D,0x25,0x8E,0xD8,0xB3,0x90,0x2F,0xA9,0xDA,0x29,0x7D, -0x1D,0xAF,0x74,0x3A,0xB2,0x27,0xC0,0xC1,0x1E,0x3E,0x75,0xA3,0x16,0xA9,0xAF,0x7A, -0x22,0x5D,0x9F,0x13,0x1A,0xCF,0xA7,0xA0,0xEB,0xE3,0x86,0x0A,0xD3,0xFD,0xE6,0x96, -0x95,0xD7,0x23,0xC8,0x37,0xDD,0xC4,0x7C,0xAA,0x36,0xAC,0x98,0x1A,0x12,0xB1,0xE0, -0x4E,0xE8,0xB1,0x3B,0xF5,0xD6,0x6F,0xF1,0x30,0xD7,0x02,0x03,0x01,0x00,0x01,0xA3, -0x42,0x30,0x40,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, -0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, -0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x4B, -0xC5,0xB4,0x40,0x6B,0xAD,0x1C,0xB3,0xA5,0x1C,0x65,0x6E,0x46,0x36,0x89,0x87,0x05, -0x0C,0x0E,0xB6,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B, -0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x73,0x57,0x3F,0x2C,0xD5,0x95,0x32,0x7E,0x37, -0xDB,0x96,0x92,0xEB,0x19,0x5E,0x7E,0x53,0xE7,0x41,0xEC,0x11,0xB6,0x47,0xEF,0xB5, -0xDE,0xED,0x74,0x5C,0xC5,0xF1,0x8E,0x49,0xE0,0xFC,0x6E,0x99,0x13,0xCD,0x9F,0x8A, -0xDA,0xCD,0x3A,0x0A,0xD8,0x3A,0x5A,0x09,0x3F,0x5F,0x34,0xD0,0x2F,0x03,0xD2,0x66, -0x1D,0x1A,0xBD,0x9C,0x90,0x37,0xC8,0x0C,0x8E,0x07,0x5A,0x94,0x45,0x46,0x2A,0xE6, -0xBE,0x7A,0xDA,0xA1,0xA9,0xA4,0x69,0x12,0x92,0xB0,0x7D,0x36,0xD4,0x44,0x87,0xD7, -0x51,0xF1,0x29,0x63,0xD6,0x75,0xCD,0x16,0xE4,0x27,0x89,0x1D,0xF8,0xC2,0x32,0x48, -0xFD,0xDB,0x99,0xD0,0x8F,0x5F,0x54,0x74,0xCC,0xAC,0x67,0x34,0x11,0x62,0xD9,0x0C, -0x0A,0x37,0x87,0xD1,0xA3,0x17,0x48,0x8E,0xD2,0x17,0x1D,0xF6,0xD7,0xFD,0xDB,0x65, -0xEB,0xFD,0xA8,0xD4,0xF5,0xD6,0x4F,0xA4,0x5B,0x75,0xE8,0xC5,0xD2,0x60,0xB2,0xDB, -0x09,0x7E,0x25,0x8B,0x7B,0xBA,0x52,0x92,0x9E,0x3E,0xE8,0xC5,0x77,0xA1,0x3C,0xE0, -0x4A,0x73,0x6B,0x61,0xCF,0x86,0xDC,0x43,0xFF,0xFF,0x21,0xFE,0x23,0x5D,0x24,0x4A, -0xF5,0xD3,0x6D,0x0F,0x62,0x04,0x05,0x57,0x82,0xDA,0x6E,0xA4,0x33,0x25,0x79,0x4B, -0x2E,0x54,0x19,0x8B,0xCC,0x2C,0x3D,0x30,0xE9,0xD1,0x06,0xFF,0xE8,0x32,0x46,0xBE, -0xB5,0x33,0x76,0x77,0xA8,0x01,0x5D,0x96,0xC1,0xC1,0xD5,0xBE,0xAE,0x25,0xC0,0xC9, -0x1E,0x0A,0x09,0x20,0x88,0xA1,0x0E,0xC9,0xF3,0x6F,0x4D,0x82,0x54,0x00,0x20,0xA7, -0xD2,0x8F,0xE4,0x39,0x54,0x17,0x2E,0x8D,0x1E,0xB8,0x1B,0xBB,0x1B,0xBD,0x9A,0x4E, -0x3B,0x10,0x34,0xDC,0x9C,0x88,0x53,0xEF,0xA2,0x31,0x5B,0x58,0x4F,0x91,0x62,0xC8, -0xC2,0x9A,0x9A,0xCD,0x15,0x5D,0x38,0xA9,0xD6,0xBE,0xF8,0x13,0xB5,0x9F,0x12,0x69, -0xF2,0x50,0x62,0xAC,0xFB,0x17,0x37,0xF4,0xEE,0xB8,0x75,0x67,0x60,0x10,0xFB,0x83, -0x50,0xF9,0x44,0xB5,0x75,0x9C,0x40,0x17,0xB2,0xFE,0xFD,0x79,0x5D,0x6E,0x58,0x58, -0x5F,0x30,0xFC,0x00,0xAE,0xAF,0x33,0xC1,0x0E,0x4E,0x6C,0xBA,0xA7,0xA6,0xA1,0x7F, -0x32,0xDB,0x38,0xE0,0xB1,0x72,0x17,0x0A,0x2B,0x91,0xEC,0x6A,0x63,0x26,0xED,0x89, -0xD4,0x78,0xCC,0x74,0x1E,0x05,0xF8,0x6B,0xFE,0x8C,0x6A,0x76,0x39,0x29,0xAE,0x65, -0x23,0x12,0x95,0x08,0x22,0x1C,0x97,0xCE,0x5B,0x06,0xEE,0x0C,0xE2,0xBB,0xBC,0x1F, -0x44,0x93,0xF6,0xD8,0x38,0x45,0x05,0x21,0xED,0xE4,0xAD,0xAB,0x12,0xB6,0x03,0xA4, -0x42,0x2E,0x2D,0xC4,0x09,0x3A,0x03,0x67,0x69,0x84,0x9A,0xE1,0x59,0x90,0x8A,0x28, -0x85,0xD5,0x5D,0x74,0xB1,0xD1,0x0E,0x20,0x58,0x9B,0x13,0xA5,0xB0,0x63,0xA6,0xED, -0x7B,0x47,0xFD,0x45,0x55,0x30,0xA4,0xEE,0x9A,0xD4,0xE6,0xE2,0x87,0xEF,0x98,0xC9, -0x32,0x82,0x11,0x29,0x22,0xBC,0x00,0x0A,0x31,0x5E,0x2D,0x0F,0xC0,0x8E,0xE9,0x6B, -0xB2,0x8F,0x2E,0x06,0xD8,0xD1,0x91,0xC7,0xC6,0x12,0xF4,0x4C,0xFD,0x30,0x17,0xC3, -0xC1,0xDA,0x38,0x5B,0xE3,0xA9,0xEA,0xE6,0xA1,0xBA,0x79,0xEF,0x73,0xD8,0xB6,0x53, -0x57,0x2D,0xF6,0xD0,0xE1,0xD7,0x48, -}; - - -/* subject:/C=DE/O=TC TrustCenter GmbH/OU=TC TrustCenter Class 2 CA/CN=TC TrustCenter Class 2 CA II */ -/* issuer :/C=DE/O=TC TrustCenter GmbH/OU=TC TrustCenter Class 2 CA/CN=TC TrustCenter Class 2 CA II */ - - -const unsigned char TC_TrustCenter_Class_2_CA_II_certificate[1198]={ -0x30,0x82,0x04,0xAA,0x30,0x82,0x03,0x92,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x2E, -0x6A,0x00,0x01,0x00,0x02,0x1F,0xD7,0x52,0x21,0x2C,0x11,0x5C,0x3B,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x76,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06, -0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, -0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x22,0x30,0x20,0x06,0x03,0x55, -0x04,0x0B,0x13,0x19,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74, -0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x32,0x20,0x43,0x41,0x31,0x25,0x30, -0x23,0x06,0x03,0x55,0x04,0x03,0x13,0x1C,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74, -0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x32,0x20,0x43, -0x41,0x20,0x49,0x49,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x31,0x31,0x32,0x31,0x34, -0x33,0x38,0x34,0x33,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31,0x32,0x32,0x35, -0x39,0x35,0x39,0x5A,0x30,0x76,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43, -0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62, -0x48,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x0B,0x13,0x19,0x54,0x43,0x20,0x54, -0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73, -0x20,0x32,0x20,0x43,0x41,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x03,0x13,0x1C, -0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43, -0x6C,0x61,0x73,0x73,0x20,0x32,0x20,0x43,0x41,0x20,0x49,0x49,0x30,0x82,0x01,0x22, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03, -0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xAB,0x80,0x87, -0x9B,0x8E,0xF0,0xC3,0x7C,0x87,0xD7,0xE8,0x24,0x82,0x11,0xB3,0x3C,0xDD,0x43,0x62, -0xEE,0xF8,0xC3,0x45,0xDA,0xE8,0xE1,0xA0,0x5F,0xD1,0x2A,0xB2,0xEA,0x93,0x68,0xDF, -0xB4,0xC8,0xD6,0x43,0xE9,0xC4,0x75,0x59,0x7F,0xFC,0xE1,0x1D,0xF8,0x31,0x70,0x23, -0x1B,0x88,0x9E,0x27,0xB9,0x7B,0xFD,0x3A,0xD2,0xC9,0xA9,0xE9,0x14,0x2F,0x90,0xBE, -0x03,0x52,0xC1,0x49,0xCD,0xF6,0xFD,0xE4,0x08,0x66,0x0B,0x57,0x8A,0xA2,0x42,0xA0, -0xB8,0xD5,0x7F,0x69,0x5C,0x90,0x32,0xB2,0x97,0x0D,0xCA,0x4A,0xDC,0x46,0x3E,0x02, -0x55,0x89,0x53,0xE3,0x1A,0x5A,0xCB,0x36,0xC6,0x07,0x56,0xF7,0x8C,0xCF,0x11,0xF4, -0x4C,0xBB,0x30,0x70,0x04,0x95,0xA5,0xF6,0x39,0x8C,0xFD,0x73,0x81,0x08,0x7D,0x89, -0x5E,0x32,0x1E,0x22,0xA9,0x22,0x45,0x4B,0xB0,0x66,0x2E,0x30,0xCC,0x9F,0x65,0xFD, -0xFC,0xCB,0x81,0xA9,0xF1,0xE0,0x3B,0xAF,0xA3,0x86,0xD1,0x89,0xEA,0xC4,0x45,0x79, -0x50,0x5D,0xAE,0xE9,0x21,0x74,0x92,0x4D,0x8B,0x59,0x82,0x8F,0x94,0xE3,0xE9,0x4A, -0xF1,0xE7,0x49,0xB0,0x14,0xE3,0xF5,0x62,0xCB,0xD5,0x72,0xBD,0x1F,0xB9,0xD2,0x9F, -0xA0,0xCD,0xA8,0xFA,0x01,0xC8,0xD9,0x0D,0xDF,0xDA,0xFC,0x47,0x9D,0xB3,0xC8,0x54, -0xDF,0x49,0x4A,0xF1,0x21,0xA9,0xFE,0x18,0x4E,0xEE,0x48,0xD4,0x19,0xBB,0xEF,0x7D, -0xE4,0xE2,0x9D,0xCB,0x5B,0xB6,0x6E,0xFF,0xE3,0xCD,0x5A,0xE7,0x74,0x82,0x05,0xBA, -0x80,0x25,0x38,0xCB,0xE4,0x69,0x9E,0xAF,0x41,0xAA,0x1A,0x84,0xF5,0x02,0x03,0x01, -0x00,0x01,0xA3,0x82,0x01,0x34,0x30,0x82,0x01,0x30,0x30,0x0F,0x06,0x03,0x55,0x1D, -0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55, -0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55, -0x1D,0x0E,0x04,0x16,0x04,0x14,0xE3,0xAB,0x54,0x4C,0x80,0xA1,0xDB,0x56,0x43,0xB7, -0x91,0x4A,0xCB,0xF3,0x82,0x7A,0x13,0x5C,0x08,0xAB,0x30,0x81,0xED,0x06,0x03,0x55, -0x1D,0x1F,0x04,0x81,0xE5,0x30,0x81,0xE2,0x30,0x81,0xDF,0xA0,0x81,0xDC,0xA0,0x81, -0xD9,0x86,0x35,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72, -0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C, -0x2F,0x76,0x32,0x2F,0x74,0x63,0x5F,0x63,0x6C,0x61,0x73,0x73,0x5F,0x32,0x5F,0x63, -0x61,0x5F,0x49,0x49,0x2E,0x63,0x72,0x6C,0x86,0x81,0x9F,0x6C,0x64,0x61,0x70,0x3A, -0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65, -0x72,0x2E,0x64,0x65,0x2F,0x43,0x4E,0x3D,0x54,0x43,0x25,0x32,0x30,0x54,0x72,0x75, -0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25,0x32,0x30,0x43,0x6C,0x61,0x73,0x73, -0x25,0x32,0x30,0x32,0x25,0x32,0x30,0x43,0x41,0x25,0x32,0x30,0x49,0x49,0x2C,0x4F, -0x3D,0x54,0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65, -0x72,0x25,0x32,0x30,0x47,0x6D,0x62,0x48,0x2C,0x4F,0x55,0x3D,0x72,0x6F,0x6F,0x74, -0x63,0x65,0x72,0x74,0x73,0x2C,0x44,0x43,0x3D,0x74,0x72,0x75,0x73,0x74,0x63,0x65, -0x6E,0x74,0x65,0x72,0x2C,0x44,0x43,0x3D,0x64,0x65,0x3F,0x63,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x65,0x52,0x65,0x76,0x6F,0x63,0x61,0x74,0x69,0x6F,0x6E, -0x4C,0x69,0x73,0x74,0x3F,0x62,0x61,0x73,0x65,0x3F,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x8C,0xD7, -0xDF,0x7E,0xEE,0x1B,0x80,0x10,0xB3,0x83,0xF5,0xDB,0x11,0xEA,0x6B,0x4B,0xA8,0x92, -0x18,0xD9,0xF7,0x07,0x39,0xF5,0x2C,0xBE,0x06,0x75,0x7A,0x68,0x53,0x15,0x1C,0xEA, -0x4A,0xED,0x5E,0xFC,0x23,0xB2,0x13,0xA0,0xD3,0x09,0xFF,0xF6,0xF6,0x2E,0x6B,0x41, -0x71,0x79,0xCD,0xE2,0x6D,0xFD,0xAE,0x59,0x6B,0x85,0x1D,0xB8,0x4E,0x22,0x9A,0xED, -0x66,0x39,0x6E,0x4B,0x94,0xE6,0x55,0xFC,0x0B,0x1B,0x8B,0x77,0xC1,0x53,0x13,0x66, -0x89,0xD9,0x28,0xD6,0x8B,0xF3,0x45,0x4A,0x63,0xB7,0xFD,0x7B,0x0B,0x61,0x5D,0xB8, -0x6D,0xBE,0xC3,0xDC,0x5B,0x79,0xD2,0xED,0x86,0xE5,0xA2,0x4D,0xBE,0x5E,0x74,0x7C, -0x6A,0xED,0x16,0x38,0x1F,0x7F,0x58,0x81,0x5A,0x1A,0xEB,0x32,0x88,0x2D,0xB2,0xF3, -0x39,0x77,0x80,0xAF,0x5E,0xB6,0x61,0x75,0x29,0xDB,0x23,0x4D,0x88,0xCA,0x50,0x28, -0xCB,0x85,0xD2,0xD3,0x10,0xA2,0x59,0x6E,0xD3,0x93,0x54,0x00,0x7A,0xA2,0x46,0x95, -0x86,0x05,0x9C,0xA9,0x19,0x98,0xE5,0x31,0x72,0x0C,0x00,0xE2,0x67,0xD9,0x40,0xE0, -0x24,0x33,0x7B,0x6F,0x2C,0xB9,0x5C,0xAB,0x65,0x9D,0x2C,0xAC,0x76,0xEA,0x35,0x99, -0xF5,0x97,0xB9,0x0F,0x24,0xEC,0xC7,0x76,0x21,0x28,0x65,0xAE,0x57,0xE8,0x07,0x88, -0x75,0x4A,0x56,0xA0,0xD2,0x05,0x3A,0xA4,0xE6,0x8D,0x92,0x88,0x2C,0xF3,0xF2,0xE1, -0xC1,0xC6,0x61,0xDB,0x41,0xC5,0xC7,0x9B,0xF7,0x0E,0x1A,0x51,0x45,0xC2,0x61,0x6B, -0xDC,0x64,0x27,0x17,0x8C,0x5A,0xB7,0xDA,0x74,0x28,0xCD,0x97,0xE4,0xBD, -}; - - -/* subject:/C=DE/O=TC TrustCenter GmbH/OU=TC TrustCenter Class 3 CA/CN=TC TrustCenter Class 3 CA II */ -/* issuer :/C=DE/O=TC TrustCenter GmbH/OU=TC TrustCenter Class 3 CA/CN=TC TrustCenter Class 3 CA II */ - - -const unsigned char TC_TrustCenter_Class_3_CA_II_certificate[1198]={ -0x30,0x82,0x04,0xAA,0x30,0x82,0x03,0x92,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x4A, -0x47,0x00,0x01,0x00,0x02,0xE5,0xA0,0x5D,0xD6,0x3F,0x00,0x51,0xBF,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x76,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06, -0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, -0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x22,0x30,0x20,0x06,0x03,0x55, -0x04,0x0B,0x13,0x19,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74, -0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x41,0x31,0x25,0x30, -0x23,0x06,0x03,0x55,0x04,0x03,0x13,0x1C,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74, -0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x43, -0x41,0x20,0x49,0x49,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x31,0x31,0x32,0x31,0x34, -0x34,0x31,0x35,0x37,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31,0x32,0x32,0x35, -0x39,0x35,0x39,0x5A,0x30,0x76,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43, -0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62, -0x48,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x0B,0x13,0x19,0x54,0x43,0x20,0x54, -0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73, -0x20,0x33,0x20,0x43,0x41,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x03,0x13,0x1C, -0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43, -0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x41,0x20,0x49,0x49,0x30,0x82,0x01,0x22, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03, -0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xB4,0xE0,0xBB, -0x51,0xBB,0x39,0x5C,0x8B,0x04,0xC5,0x4C,0x79,0x1C,0x23,0x86,0x31,0x10,0x63,0x43, -0x55,0x27,0x3F,0xC6,0x45,0xC7,0xA4,0x3D,0xEC,0x09,0x0D,0x1A,0x1E,0x20,0xC2,0x56, -0x1E,0xDE,0x1B,0x37,0x07,0x30,0x22,0x2F,0x6F,0xF1,0x06,0xF1,0xAB,0xAD,0xD6,0xC8, -0xAB,0x61,0xA3,0x2F,0x43,0xC4,0xB0,0xB2,0x2D,0xFC,0xC3,0x96,0x69,0x7B,0x7E,0x8A, -0xE4,0xCC,0xC0,0x39,0x12,0x90,0x42,0x60,0xC9,0xCC,0x35,0x68,0xEE,0xDA,0x5F,0x90, -0x56,0x5F,0xCD,0x1C,0x4D,0x5B,0x58,0x49,0xEB,0x0E,0x01,0x4F,0x64,0xFA,0x2C,0x3C, -0x89,0x58,0xD8,0x2F,0x2E,0xE2,0xB0,0x68,0xE9,0x22,0x3B,0x75,0x89,0xD6,0x44,0x1A, -0x65,0xF2,0x1B,0x97,0x26,0x1D,0x28,0x6D,0xAC,0xE8,0xBD,0x59,0x1D,0x2B,0x24,0xF6, -0xD6,0x84,0x03,0x66,0x88,0x24,0x00,0x78,0x60,0xF1,0xF8,0xAB,0xFE,0x02,0xB2,0x6B, -0xFB,0x22,0xFB,0x35,0xE6,0x16,0xD1,0xAD,0xF6,0x2E,0x12,0xE4,0xFA,0x35,0x6A,0xE5, -0x19,0xB9,0x5D,0xDB,0x3B,0x1E,0x1A,0xFB,0xD3,0xFF,0x15,0x14,0x08,0xD8,0x09,0x6A, -0xBA,0x45,0x9D,0x14,0x79,0x60,0x7D,0xAF,0x40,0x8A,0x07,0x73,0xB3,0x93,0x96,0xD3, -0x74,0x34,0x8D,0x3A,0x37,0x29,0xDE,0x5C,0xEC,0xF5,0xEE,0x2E,0x31,0xC2,0x20,0xDC, -0xBE,0xF1,0x4F,0x7F,0x23,0x52,0xD9,0x5B,0xE2,0x64,0xD9,0x9C,0xAA,0x07,0x08,0xB5, -0x45,0xBD,0xD1,0xD0,0x31,0xC1,0xAB,0x54,0x9F,0xA9,0xD2,0xC3,0x62,0x60,0x03,0xF1, -0xBB,0x39,0x4A,0x92,0x4A,0x3D,0x0A,0xB9,0x9D,0xC5,0xA0,0xFE,0x37,0x02,0x03,0x01, -0x00,0x01,0xA3,0x82,0x01,0x34,0x30,0x82,0x01,0x30,0x30,0x0F,0x06,0x03,0x55,0x1D, -0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55, -0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55, -0x1D,0x0E,0x04,0x16,0x04,0x14,0xD4,0xA2,0xFC,0x9F,0xB3,0xC3,0xD8,0x03,0xD3,0x57, -0x5C,0x07,0xA4,0xD0,0x24,0xA7,0xC0,0xF2,0x00,0xD4,0x30,0x81,0xED,0x06,0x03,0x55, -0x1D,0x1F,0x04,0x81,0xE5,0x30,0x81,0xE2,0x30,0x81,0xDF,0xA0,0x81,0xDC,0xA0,0x81, -0xD9,0x86,0x35,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72, -0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C, -0x2F,0x76,0x32,0x2F,0x74,0x63,0x5F,0x63,0x6C,0x61,0x73,0x73,0x5F,0x33,0x5F,0x63, -0x61,0x5F,0x49,0x49,0x2E,0x63,0x72,0x6C,0x86,0x81,0x9F,0x6C,0x64,0x61,0x70,0x3A, -0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65, -0x72,0x2E,0x64,0x65,0x2F,0x43,0x4E,0x3D,0x54,0x43,0x25,0x32,0x30,0x54,0x72,0x75, -0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25,0x32,0x30,0x43,0x6C,0x61,0x73,0x73, -0x25,0x32,0x30,0x33,0x25,0x32,0x30,0x43,0x41,0x25,0x32,0x30,0x49,0x49,0x2C,0x4F, -0x3D,0x54,0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65, -0x72,0x25,0x32,0x30,0x47,0x6D,0x62,0x48,0x2C,0x4F,0x55,0x3D,0x72,0x6F,0x6F,0x74, -0x63,0x65,0x72,0x74,0x73,0x2C,0x44,0x43,0x3D,0x74,0x72,0x75,0x73,0x74,0x63,0x65, -0x6E,0x74,0x65,0x72,0x2C,0x44,0x43,0x3D,0x64,0x65,0x3F,0x63,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x65,0x52,0x65,0x76,0x6F,0x63,0x61,0x74,0x69,0x6F,0x6E, -0x4C,0x69,0x73,0x74,0x3F,0x62,0x61,0x73,0x65,0x3F,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x36,0x60, -0xE4,0x70,0xF7,0x06,0x20,0x43,0xD9,0x23,0x1A,0x42,0xF2,0xF8,0xA3,0xB2,0xB9,0x4D, -0x8A,0xB4,0xF3,0xC2,0x9A,0x55,0x31,0x7C,0xC4,0x3B,0x67,0x9A,0xB4,0xDF,0x4D,0x0E, -0x8A,0x93,0x4A,0x17,0x8B,0x1B,0x8D,0xCA,0x89,0xE1,0xCF,0x3A,0x1E,0xAC,0x1D,0xF1, -0x9C,0x32,0xB4,0x8E,0x59,0x76,0xA2,0x41,0x85,0x25,0x37,0xA0,0x13,0xD0,0xF5,0x7C, -0x4E,0xD5,0xEA,0x96,0xE2,0x6E,0x72,0xC1,0xBB,0x2A,0xFE,0x6C,0x6E,0xF8,0x91,0x98, -0x46,0xFC,0xC9,0x1B,0x57,0x5B,0xEA,0xC8,0x1A,0x3B,0x3F,0xB0,0x51,0x98,0x3C,0x07, -0xDA,0x2C,0x59,0x01,0xDA,0x8B,0x44,0xE8,0xE1,0x74,0xFD,0xA7,0x68,0xDD,0x54,0xBA, -0x83,0x46,0xEC,0xC8,0x46,0xB5,0xF8,0xAF,0x97,0xC0,0x3B,0x09,0x1C,0x8F,0xCE,0x72, -0x96,0x3D,0x33,0x56,0x70,0xBC,0x96,0xCB,0xD8,0xD5,0x7D,0x20,0x9A,0x83,0x9F,0x1A, -0xDC,0x39,0xF1,0xC5,0x72,0xA3,0x11,0x03,0xFD,0x3B,0x42,0x52,0x29,0xDB,0xE8,0x01, -0xF7,0x9B,0x5E,0x8C,0xD6,0x8D,0x86,0x4E,0x19,0xFA,0xBC,0x1C,0xBE,0xC5,0x21,0xA5, -0x87,0x9E,0x78,0x2E,0x36,0xDB,0x09,0x71,0xA3,0x72,0x34,0xF8,0x6C,0xE3,0x06,0x09, -0xF2,0x5E,0x56,0xA5,0xD3,0xDD,0x98,0xFA,0xD4,0xE6,0x06,0xF4,0xF0,0xB6,0x20,0x63, -0x4B,0xEA,0x29,0xBD,0xAA,0x82,0x66,0x1E,0xFB,0x81,0xAA,0xA7,0x37,0xAD,0x13,0x18, -0xE6,0x92,0xC3,0x81,0xC1,0x33,0xBB,0x88,0x1E,0xA1,0xE7,0xE2,0xB4,0xBD,0x31,0x6C, -0x0E,0x51,0x3D,0x6F,0xFB,0x96,0x56,0x80,0xE2,0x36,0x17,0xD1,0xDC,0xE4, -}; - - -/* subject:/C=DE/O=TC TrustCenter GmbH/OU=TC TrustCenter Universal CA/CN=TC TrustCenter Universal CA I */ -/* issuer :/C=DE/O=TC TrustCenter GmbH/OU=TC TrustCenter Universal CA/CN=TC TrustCenter Universal CA I */ - - -const unsigned char TC_TrustCenter_Universal_CA_I_certificate[993]={ -0x30,0x82,0x03,0xDD,0x30,0x82,0x02,0xC5,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x1D, -0xA2,0x00,0x01,0x00,0x02,0xEC,0xB7,0x60,0x80,0x78,0x8D,0xB6,0x06,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x79,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06, -0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, -0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55, -0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74, -0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31, -0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75, -0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73, -0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x33,0x32, -0x32,0x31,0x35,0x35,0x34,0x32,0x38,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31, -0x32,0x32,0x35,0x39,0x35,0x39,0x5A,0x30,0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, -0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13, -0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20, -0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x0B,0x13,0x1B,0x54, -0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E, -0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,0x26,0x30,0x24,0x06,0x03, -0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E, -0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41, -0x20,0x49,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82, -0x01,0x01,0x00,0xA4,0x77,0x23,0x96,0x44,0xAF,0x90,0xF4,0x31,0xA7,0x10,0xF4,0x26, -0x87,0x9C,0xF3,0x38,0xD9,0x0F,0x5E,0xDE,0xCF,0x41,0xE8,0x31,0xAD,0xC6,0x74,0x91, -0x24,0x96,0x78,0x1E,0x09,0xA0,0x9B,0x9A,0x95,0x4A,0x4A,0xF5,0x62,0x7C,0x02,0xA8, -0xCA,0xAC,0xFB,0x5A,0x04,0x76,0x39,0xDE,0x5F,0xF1,0xF9,0xB3,0xBF,0xF3,0x03,0x58, -0x55,0xD2,0xAA,0xB7,0xE3,0x04,0x22,0xD1,0xF8,0x94,0xDA,0x22,0x08,0x00,0x8D,0xD3, -0x7C,0x26,0x5D,0xCC,0x77,0x79,0xE7,0x2C,0x78,0x39,0xA8,0x26,0x73,0x0E,0xA2,0x5D, -0x25,0x69,0x85,0x4F,0x55,0x0E,0x9A,0xEF,0xC6,0xB9,0x44,0xE1,0x57,0x3D,0xDF,0x1F, -0x54,0x22,0xE5,0x6F,0x65,0xAA,0x33,0x84,0x3A,0xF3,0xCE,0x7A,0xBE,0x55,0x97,0xAE, -0x8D,0x12,0x0F,0x14,0x33,0xE2,0x50,0x70,0xC3,0x49,0x87,0x13,0xBC,0x51,0xDE,0xD7, -0x98,0x12,0x5A,0xEF,0x3A,0x83,0x33,0x92,0x06,0x75,0x8B,0x92,0x7C,0x12,0x68,0x7B, -0x70,0x6A,0x0F,0xB5,0x9B,0xB6,0x77,0x5B,0x48,0x59,0x9D,0xE4,0xEF,0x5A,0xAD,0xF3, -0xC1,0x9E,0xD4,0xD7,0x45,0x4E,0xCA,0x56,0x34,0x21,0xBC,0x3E,0x17,0x5B,0x6F,0x77, -0x0C,0x48,0x01,0x43,0x29,0xB0,0xDD,0x3F,0x96,0x6E,0xE6,0x95,0xAA,0x0C,0xC0,0x20, -0xB6,0xFD,0x3E,0x36,0x27,0x9C,0xE3,0x5C,0xCF,0x4E,0x81,0xDC,0x19,0xBB,0x91,0x90, -0x7D,0xEC,0xE6,0x97,0x04,0x1E,0x93,0xCC,0x22,0x49,0xD7,0x97,0x86,0xB6,0x13,0x0A, -0x3C,0x43,0x23,0x77,0x7E,0xF0,0xDC,0xE6,0xCD,0x24,0x1F,0x3B,0x83,0x9B,0x34,0x3A, -0x83,0x34,0xE3,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x1F,0x06,0x03, -0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE, -0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,0x30,0x0F,0x06, -0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E, -0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x1D, -0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE, -0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01, -0x00,0x28,0xD2,0xE0,0x86,0xD5,0xE6,0xF8,0x7B,0xF0,0x97,0xDC,0x22,0x6B,0x3B,0x95, -0x14,0x56,0x0F,0x11,0x30,0xA5,0x9A,0x4F,0x3A,0xB0,0x3A,0xE0,0x06,0xCB,0x65,0xF5, -0xED,0xC6,0x97,0x27,0xFE,0x25,0xF2,0x57,0xE6,0x5E,0x95,0x8C,0x3E,0x64,0x60,0x15, -0x5A,0x7F,0x2F,0x0D,0x01,0xC5,0xB1,0x60,0xFD,0x45,0x35,0xCF,0xF0,0xB2,0xBF,0x06, -0xD9,0xEF,0x5A,0xBE,0xB3,0x62,0x21,0xB4,0xD7,0xAB,0x35,0x7C,0x53,0x3E,0xA6,0x27, -0xF1,0xA1,0x2D,0xDA,0x1A,0x23,0x9D,0xCC,0xDD,0xEC,0x3C,0x2D,0x9E,0x27,0x34,0x5D, -0x0F,0xC2,0x36,0x79,0xBC,0xC9,0x4A,0x62,0x2D,0xED,0x6B,0xD9,0x7D,0x41,0x43,0x7C, -0xB6,0xAA,0xCA,0xED,0x61,0xB1,0x37,0x82,0x15,0x09,0x1A,0x8A,0x16,0x30,0xD8,0xEC, -0xC9,0xD6,0x47,0x72,0x78,0x4B,0x10,0x46,0x14,0x8E,0x5F,0x0E,0xAF,0xEC,0xC7,0x2F, -0xAB,0x10,0xD7,0xB6,0xF1,0x6E,0xEC,0x86,0xB2,0xC2,0xE8,0x0D,0x92,0x73,0xDC,0xA2, -0xF4,0x0F,0x3A,0xBF,0x61,0x23,0x10,0x89,0x9C,0x48,0x40,0x6E,0x70,0x00,0xB3,0xD3, -0xBA,0x37,0x44,0x58,0x11,0x7A,0x02,0x6A,0x88,0xF0,0x37,0x34,0xF0,0x19,0xE9,0xAC, -0xD4,0x65,0x73,0xF6,0x69,0x8C,0x64,0x94,0x3A,0x79,0x85,0x29,0xB0,0x16,0x2B,0x0C, -0x82,0x3F,0x06,0x9C,0xC7,0xFD,0x10,0x2B,0x9E,0x0F,0x2C,0xB6,0x9E,0xE3,0x15,0xBF, -0xD9,0x36,0x1C,0xBA,0x25,0x1A,0x52,0x3D,0x1A,0xEC,0x22,0x0C,0x1C,0xE0,0xA4,0xA2, -0x3D,0xF0,0xE8,0x39,0xCF,0x81,0xC0,0x7B,0xED,0x5D,0x1F,0x6F,0xC5,0xD0,0x0B,0xD7, -0x98, -}; - - -/* subject:/C=DE/O=TC TrustCenter GmbH/OU=TC TrustCenter Universal CA/CN=TC TrustCenter Universal CA III */ -/* issuer :/C=DE/O=TC TrustCenter GmbH/OU=TC TrustCenter Universal CA/CN=TC TrustCenter Universal CA III */ - - -const unsigned char TC_TrustCenter_Universal_CA_III_certificate[997]={ -0x30,0x82,0x03,0xE1,0x30,0x82,0x02,0xC9,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x63, -0x25,0x00,0x01,0x00,0x02,0x14,0x8D,0x33,0x15,0x02,0xE4,0x6C,0xF4,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x7B,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06, -0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, -0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55, -0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74, -0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31, -0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75, -0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73, -0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x49,0x49,0x30,0x1E,0x17,0x0D,0x30,0x39,0x30, -0x39,0x30,0x39,0x30,0x38,0x31,0x35,0x32,0x37,0x5A,0x17,0x0D,0x32,0x39,0x31,0x32, -0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x7B,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04, -0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65, -0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x0B,0x13, -0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20, -0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,0x28,0x30,0x26, -0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43, -0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20, -0x43,0x41,0x20,0x49,0x49,0x49,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82, -0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xC2,0xDA,0x9C,0x62,0xB0,0xB9,0x71,0x12,0xB0, -0x0B,0xC8,0x1A,0x57,0xB2,0xAE,0x83,0x14,0x99,0xB3,0x34,0x4B,0x9B,0x90,0xA2,0xC5, -0xE7,0xE7,0x2F,0x02,0xA0,0x4D,0x2D,0xA4,0xFA,0x85,0xDA,0x9B,0x25,0x85,0x2D,0x40, -0x28,0x20,0x6D,0xEA,0xE0,0xBD,0xB1,0x48,0x83,0x22,0x29,0x44,0x9F,0x4E,0x83,0xEE, -0x35,0x51,0x13,0x73,0x74,0xD5,0xBC,0xF2,0x30,0x66,0x94,0x53,0xC0,0x40,0x36,0x2F, -0x0C,0x84,0x65,0xCE,0x0F,0x6E,0xC2,0x58,0x93,0xE8,0x2C,0x0B,0x3A,0xE9,0xC1,0x8E, -0xFB,0xF2,0x6B,0xCA,0x3C,0xE2,0x9C,0x4E,0x8E,0xE4,0xF9,0x7D,0xD3,0x27,0x9F,0x1B, -0xD5,0x67,0x78,0x87,0x2D,0x7F,0x0B,0x47,0xB3,0xC7,0xE8,0xC9,0x48,0x7C,0xAF,0x2F, -0xCC,0x0A,0xD9,0x41,0xEF,0x9F,0xFE,0x9A,0xE1,0xB2,0xAE,0xF9,0x53,0xB5,0xE5,0xE9, -0x46,0x9F,0x60,0xE3,0xDF,0x8D,0xD3,0x7F,0xFB,0x96,0x7E,0xB3,0xB5,0x72,0xF8,0x4B, -0xAD,0x08,0x79,0xCD,0x69,0x89,0x40,0x27,0xF5,0x2A,0xC1,0xAD,0x43,0xEC,0xA4,0x53, -0xC8,0x61,0xB6,0xF7,0xD2,0x79,0x2A,0x67,0x18,0x76,0x48,0x6D,0x5B,0x25,0x01,0xD1, -0x26,0xC5,0xB7,0x57,0x69,0x23,0x15,0x5B,0x61,0x8A,0xAD,0xF0,0x1B,0x2D,0xD9,0xAF, -0x5C,0xF1,0x26,0x90,0x69,0xA9,0xD5,0x0C,0x40,0xF5,0x33,0x80,0x43,0x8F,0x9C,0xA3, -0x76,0x2A,0x45,0xB4,0xAF,0xBF,0x7F,0x3E,0x87,0x3F,0x76,0xC5,0xCD,0x2A,0xDE,0x20, -0xC5,0x16,0x58,0xCB,0xF9,0x1B,0xF5,0x0F,0xCB,0x0D,0x11,0x52,0x64,0xB8,0xD2,0x76, -0x62,0x77,0x83,0xF1,0x58,0x9F,0xFF,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61, -0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x56,0xE7,0xE1, -0x5B,0x25,0x43,0x80,0xE0,0xF6,0x8C,0xE1,0x71,0xBC,0x8E,0xE5,0x80,0x2F,0xC4,0x48, -0xE2,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01, -0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02, -0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x56,0xE7,0xE1, -0x5B,0x25,0x43,0x80,0xE0,0xF6,0x8C,0xE1,0x71,0xBC,0x8E,0xE5,0x80,0x2F,0xC4,0x48, -0xE2,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00, -0x03,0x82,0x01,0x01,0x00,0x83,0xC7,0xAF,0xEA,0x7F,0x4D,0x0A,0x3C,0x39,0xB1,0x68, -0xBE,0x7B,0x6D,0x89,0x2E,0xE9,0xB3,0x09,0xE7,0x18,0x57,0x8D,0x85,0x9A,0x17,0xF3, -0x76,0x42,0x50,0x13,0x0F,0xC7,0x90,0x6F,0x33,0xAD,0xC5,0x49,0x60,0x2B,0x6C,0x49, -0x58,0x19,0xD4,0xE2,0xBE,0xB7,0xBF,0xAB,0x49,0xBC,0x94,0xC8,0xAB,0xBE,0x28,0x6C, -0x16,0x68,0xE0,0xC8,0x97,0x46,0x20,0xA0,0x68,0x67,0x60,0x88,0x39,0x20,0x51,0xD8, -0x68,0x01,0x11,0xCE,0xA7,0xF6,0x11,0x07,0xF6,0xEC,0xEC,0xAC,0x1A,0x1F,0xB2,0x66, -0x6E,0x56,0x67,0x60,0x7A,0x74,0x5E,0xC0,0x6D,0x97,0x36,0xAE,0xB5,0x0D,0x5D,0x66, -0x73,0xC0,0x25,0x32,0x45,0xD8,0x4A,0x06,0x07,0x8F,0xC4,0xB7,0x07,0xB1,0x4D,0x06, -0x0D,0xE1,0xA5,0xEB,0xF4,0x75,0xCA,0xBA,0x9C,0xD0,0xBD,0xB3,0xD3,0x32,0x24,0x4C, -0xEE,0x7E,0xE2,0x76,0x04,0x4B,0x49,0x53,0xD8,0xF2,0xE9,0x54,0x33,0xFC,0xE5,0x71, -0x1F,0x3D,0x14,0x5C,0x96,0x4B,0xF1,0x3A,0xF2,0x00,0xBB,0x6C,0xB4,0xFA,0x96,0x55, -0x08,0x88,0x09,0xC1,0xCC,0x91,0x19,0x29,0xB0,0x20,0x2D,0xFF,0xCB,0x38,0xA4,0x40, -0xE1,0x17,0xBE,0x79,0x61,0x80,0xFF,0x07,0x03,0x86,0x4C,0x4E,0x7B,0x06,0x9F,0x11, -0x86,0x8D,0x89,0xEE,0x27,0xC4,0xDB,0xE2,0xBC,0x19,0x8E,0x0B,0xC3,0xC3,0x13,0xC7, -0x2D,0x03,0x63,0x3B,0xD3,0xE8,0xE4,0xA2,0x2A,0xC2,0x82,0x08,0x94,0x16,0x54,0xF0, -0xEF,0x1F,0x27,0x90,0x25,0xB8,0x0D,0x0E,0x28,0x1B,0x47,0x77,0x47,0xBD,0x1C,0xA8, -0x25,0xF1,0x94,0xB4,0x66, -}; - - -/* subject:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com */ -/* issuer :/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com */ - - -const unsigned char Thawte_Premium_Server_CA_certificate[811]={ -0x30,0x82,0x03,0x27,0x30,0x82,0x02,0x90,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x30, -0x81,0xCE,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x5A,0x41,0x31, -0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0C,0x57,0x65,0x73,0x74,0x65,0x72, -0x6E,0x20,0x43,0x61,0x70,0x65,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13, -0x09,0x43,0x61,0x70,0x65,0x20,0x54,0x6F,0x77,0x6E,0x31,0x1D,0x30,0x1B,0x06,0x03, -0x55,0x04,0x0A,0x13,0x14,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x6F,0x6E,0x73, -0x75,0x6C,0x74,0x69,0x6E,0x67,0x20,0x63,0x63,0x31,0x28,0x30,0x26,0x06,0x03,0x55, -0x04,0x0B,0x13,0x1F,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F, -0x6E,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,0x69,0x76,0x69,0x73, -0x69,0x6F,0x6E,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x54,0x68, -0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x65,0x6D,0x69,0x75,0x6D,0x20,0x53,0x65,0x72, -0x76,0x65,0x72,0x20,0x43,0x41,0x31,0x28,0x30,0x26,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x09,0x01,0x16,0x19,0x70,0x72,0x65,0x6D,0x69,0x75,0x6D,0x2D,0x73, -0x65,0x72,0x76,0x65,0x72,0x40,0x74,0x68,0x61,0x77,0x74,0x65,0x2E,0x63,0x6F,0x6D, -0x30,0x1E,0x17,0x0D,0x39,0x36,0x30,0x38,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30, -0x5A,0x17,0x0D,0x32,0x30,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A, -0x30,0x81,0xCE,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x5A,0x41, -0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0C,0x57,0x65,0x73,0x74,0x65, -0x72,0x6E,0x20,0x43,0x61,0x70,0x65,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07, -0x13,0x09,0x43,0x61,0x70,0x65,0x20,0x54,0x6F,0x77,0x6E,0x31,0x1D,0x30,0x1B,0x06, -0x03,0x55,0x04,0x0A,0x13,0x14,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x6F,0x6E, -0x73,0x75,0x6C,0x74,0x69,0x6E,0x67,0x20,0x63,0x63,0x31,0x28,0x30,0x26,0x06,0x03, -0x55,0x04,0x0B,0x13,0x1F,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69, -0x6F,0x6E,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,0x69,0x76,0x69, -0x73,0x69,0x6F,0x6E,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x54, -0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x65,0x6D,0x69,0x75,0x6D,0x20,0x53,0x65, -0x72,0x76,0x65,0x72,0x20,0x43,0x41,0x31,0x28,0x30,0x26,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x19,0x70,0x72,0x65,0x6D,0x69,0x75,0x6D,0x2D, -0x73,0x65,0x72,0x76,0x65,0x72,0x40,0x74,0x68,0x61,0x77,0x74,0x65,0x2E,0x63,0x6F, -0x6D,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xD2,0x36, -0x36,0x6A,0x8B,0xD7,0xC2,0x5B,0x9E,0xDA,0x81,0x41,0x62,0x8F,0x38,0xEE,0x49,0x04, -0x55,0xD6,0xD0,0xEF,0x1C,0x1B,0x95,0x16,0x47,0xEF,0x18,0x48,0x35,0x3A,0x52,0xF4, -0x2B,0x6A,0x06,0x8F,0x3B,0x2F,0xEA,0x56,0xE3,0xAF,0x86,0x8D,0x9E,0x17,0xF7,0x9E, -0xB4,0x65,0x75,0x02,0x4D,0xEF,0xCB,0x09,0xA2,0x21,0x51,0xD8,0x9B,0xD0,0x67,0xD0, -0xBA,0x0D,0x92,0x06,0x14,0x73,0xD4,0x93,0xCB,0x97,0x2A,0x00,0x9C,0x5C,0x4E,0x0C, -0xBC,0xFA,0x15,0x52,0xFC,0xF2,0x44,0x6E,0xDA,0x11,0x4A,0x6E,0x08,0x9F,0x2F,0x2D, -0xE3,0xF9,0xAA,0x3A,0x86,0x73,0xB6,0x46,0x53,0x58,0xC8,0x89,0x05,0xBD,0x83,0x11, -0xB8,0x73,0x3F,0xAA,0x07,0x8D,0xF4,0x42,0x4D,0xE7,0x40,0x9D,0x1C,0x37,0x02,0x03, -0x01,0x00,0x01,0xA3,0x13,0x30,0x11,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01, -0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x03,0x81,0x81,0x00,0x26,0x48,0x2C,0x16,0xC2, -0x58,0xFA,0xE8,0x16,0x74,0x0C,0xAA,0xAA,0x5F,0x54,0x3F,0xF2,0xD7,0xC9,0x78,0x60, -0x5E,0x5E,0x6E,0x37,0x63,0x22,0x77,0x36,0x7E,0xB2,0x17,0xC4,0x34,0xB9,0xF5,0x08, -0x85,0xFC,0xC9,0x01,0x38,0xFF,0x4D,0xBE,0xF2,0x16,0x42,0x43,0xE7,0xBB,0x5A,0x46, -0xFB,0xC1,0xC6,0x11,0x1F,0xF1,0x4A,0xB0,0x28,0x46,0xC9,0xC3,0xC4,0x42,0x7D,0xBC, -0xFA,0xAB,0x59,0x6E,0xD5,0xB7,0x51,0x88,0x11,0xE3,0xA4,0x85,0x19,0x6B,0x82,0x4C, -0xA4,0x0C,0x12,0xAD,0xE9,0xA4,0xAE,0x3F,0xF1,0xC3,0x49,0x65,0x9A,0x8C,0xC5,0xC8, -0x3E,0x25,0xB7,0x94,0x99,0xBB,0x92,0x32,0x71,0x07,0xF0,0x86,0x5E,0xED,0x50,0x27, -0xA6,0x0D,0xA6,0x23,0xF9,0xBB,0xCB,0xA6,0x07,0x14,0x42, -}; - - -/* subject:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA */ -/* issuer :/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA */ - - -const unsigned char thawte_Primary_Root_CA_certificate[1060]={ -0x30,0x82,0x04,0x20,0x30,0x82,0x03,0x08,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x34, -0x4E,0xD5,0x57,0x20,0xD5,0xED,0xEC,0x49,0xF4,0x2F,0xCE,0x37,0xDB,0x2B,0x6D,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, -0xA9,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15, -0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61,0x77,0x74,0x65,0x2C, -0x20,0x49,0x6E,0x63,0x2E,0x31,0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x0B,0x13,0x1F, -0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65, -0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,0x69,0x76,0x69,0x73,0x69,0x6F,0x6E,0x31, -0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x0B,0x13,0x2F,0x28,0x63,0x29,0x20,0x32,0x30, -0x30,0x36,0x20,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20, -0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64, -0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55, -0x04,0x03,0x13,0x16,0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6D,0x61, -0x72,0x79,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x36, -0x31,0x31,0x31,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x36,0x30, -0x37,0x31,0x36,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xA9,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03, -0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63, -0x2E,0x31,0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x0B,0x13,0x1F,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x72,0x76,0x69,0x63, -0x65,0x73,0x20,0x44,0x69,0x76,0x69,0x73,0x69,0x6F,0x6E,0x31,0x38,0x30,0x36,0x06, -0x03,0x55,0x04,0x0B,0x13,0x2F,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x74, -0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F, -0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65, -0x20,0x6F,0x6E,0x6C,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x13,0x16, -0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x52, -0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82, -0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xAC,0xA0,0xF0,0xFB,0x80,0x59,0xD4,0x9C,0xC7, -0xA4,0xCF,0x9D,0xA1,0x59,0x73,0x09,0x10,0x45,0x0C,0x0D,0x2C,0x6E,0x68,0xF1,0x6C, -0x5B,0x48,0x68,0x49,0x59,0x37,0xFC,0x0B,0x33,0x19,0xC2,0x77,0x7F,0xCC,0x10,0x2D, -0x95,0x34,0x1C,0xE6,0xEB,0x4D,0x09,0xA7,0x1C,0xD2,0xB8,0xC9,0x97,0x36,0x02,0xB7, -0x89,0xD4,0x24,0x5F,0x06,0xC0,0xCC,0x44,0x94,0x94,0x8D,0x02,0x62,0x6F,0xEB,0x5A, -0xDD,0x11,0x8D,0x28,0x9A,0x5C,0x84,0x90,0x10,0x7A,0x0D,0xBD,0x74,0x66,0x2F,0x6A, -0x38,0xA0,0xE2,0xD5,0x54,0x44,0xEB,0x1D,0x07,0x9F,0x07,0xBA,0x6F,0xEE,0xE9,0xFD, -0x4E,0x0B,0x29,0xF5,0x3E,0x84,0xA0,0x01,0xF1,0x9C,0xAB,0xF8,0x1C,0x7E,0x89,0xA4, -0xE8,0xA1,0xD8,0x71,0x65,0x0D,0xA3,0x51,0x7B,0xEE,0xBC,0xD2,0x22,0x60,0x0D,0xB9, -0x5B,0x9D,0xDF,0xBA,0xFC,0x51,0x5B,0x0B,0xAF,0x98,0xB2,0xE9,0x2E,0xE9,0x04,0xE8, -0x62,0x87,0xDE,0x2B,0xC8,0xD7,0x4E,0xC1,0x4C,0x64,0x1E,0xDD,0xCF,0x87,0x58,0xBA, -0x4A,0x4F,0xCA,0x68,0x07,0x1D,0x1C,0x9D,0x4A,0xC6,0xD5,0x2F,0x91,0xCC,0x7C,0x71, -0x72,0x1C,0xC5,0xC0,0x67,0xEB,0x32,0xFD,0xC9,0x92,0x5C,0x94,0xDA,0x85,0xC0,0x9B, -0xBF,0x53,0x7D,0x2B,0x09,0xF4,0x8C,0x9D,0x91,0x1F,0x97,0x6A,0x52,0xCB,0xDE,0x09, -0x36,0xA4,0x77,0xD8,0x7B,0x87,0x50,0x44,0xD5,0x3E,0x6E,0x29,0x69,0xFB,0x39,0x49, -0x26,0x1E,0x09,0xA5,0x80,0x7B,0x40,0x2D,0xEB,0xE8,0x27,0x85,0xC9,0xFE,0x61,0xFD, -0x7E,0xE6,0x7C,0x97,0x1D,0xD5,0x9D,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40, -0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01, -0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01, -0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x7B,0x5B,0x45,0xCF, -0xAF,0xCE,0xCB,0x7A,0xFD,0x31,0x92,0x1A,0x6A,0xB6,0xF3,0x46,0xEB,0x57,0x48,0x50, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03, -0x82,0x01,0x01,0x00,0x79,0x11,0xC0,0x4B,0xB3,0x91,0xB6,0xFC,0xF0,0xE9,0x67,0xD4, -0x0D,0x6E,0x45,0xBE,0x55,0xE8,0x93,0xD2,0xCE,0x03,0x3F,0xED,0xDA,0x25,0xB0,0x1D, -0x57,0xCB,0x1E,0x3A,0x76,0xA0,0x4C,0xEC,0x50,0x76,0xE8,0x64,0x72,0x0C,0xA4,0xA9, -0xF1,0xB8,0x8B,0xD6,0xD6,0x87,0x84,0xBB,0x32,0xE5,0x41,0x11,0xC0,0x77,0xD9,0xB3, -0x60,0x9D,0xEB,0x1B,0xD5,0xD1,0x6E,0x44,0x44,0xA9,0xA6,0x01,0xEC,0x55,0x62,0x1D, -0x77,0xB8,0x5C,0x8E,0x48,0x49,0x7C,0x9C,0x3B,0x57,0x11,0xAC,0xAD,0x73,0x37,0x8E, -0x2F,0x78,0x5C,0x90,0x68,0x47,0xD9,0x60,0x60,0xE6,0xFC,0x07,0x3D,0x22,0x20,0x17, -0xC4,0xF7,0x16,0xE9,0xC4,0xD8,0x72,0xF9,0xC8,0x73,0x7C,0xDF,0x16,0x2F,0x15,0xA9, -0x3E,0xFD,0x6A,0x27,0xB6,0xA1,0xEB,0x5A,0xBA,0x98,0x1F,0xD5,0xE3,0x4D,0x64,0x0A, -0x9D,0x13,0xC8,0x61,0xBA,0xF5,0x39,0x1C,0x87,0xBA,0xB8,0xBD,0x7B,0x22,0x7F,0xF6, -0xFE,0xAC,0x40,0x79,0xE5,0xAC,0x10,0x6F,0x3D,0x8F,0x1B,0x79,0x76,0x8B,0xC4,0x37, -0xB3,0x21,0x18,0x84,0xE5,0x36,0x00,0xEB,0x63,0x20,0x99,0xB9,0xE9,0xFE,0x33,0x04, -0xBB,0x41,0xC8,0xC1,0x02,0xF9,0x44,0x63,0x20,0x9E,0x81,0xCE,0x42,0xD3,0xD6,0x3F, -0x2C,0x76,0xD3,0x63,0x9C,0x59,0xDD,0x8F,0xA6,0xE1,0x0E,0xA0,0x2E,0x41,0xF7,0x2E, -0x95,0x47,0xCF,0xBC,0xFD,0x33,0xF3,0xF6,0x0B,0x61,0x7E,0x7E,0x91,0x2B,0x81,0x47, -0xC2,0x27,0x30,0xEE,0xA7,0x10,0x5D,0x37,0x8F,0x5C,0x39,0x2B,0xE4,0x04,0xF0,0x7B, -0x8D,0x56,0x8C,0x68, -}; - - -/* subject:/C=US/O=thawte, Inc./OU=(c) 2007 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA - G2 */ -/* issuer :/C=US/O=thawte, Inc./OU=(c) 2007 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA - G2 */ - - -const unsigned char thawte_Primary_Root_CA___G2_certificate[652]={ -0x30,0x82,0x02,0x88,0x30,0x82,0x02,0x0D,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x35, -0xFC,0x26,0x5C,0xD9,0x84,0x4F,0xC9,0x3D,0x26,0x3D,0x57,0x9B,0xAE,0xD7,0x56,0x30, -0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x30,0x81,0x84,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E, -0x63,0x2E,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x0B,0x13,0x2F,0x28,0x63,0x29, -0x20,0x32,0x30,0x30,0x37,0x20,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E, -0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69, -0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x24,0x30,0x22, -0x06,0x03,0x55,0x04,0x03,0x13,0x1B,0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72, -0x69,0x6D,0x61,0x72,0x79,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20, -0x47,0x32,0x30,0x1E,0x17,0x0D,0x30,0x37,0x31,0x31,0x30,0x35,0x30,0x30,0x30,0x30, -0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31,0x38,0x32,0x33,0x35,0x39,0x35, -0x39,0x5A,0x30,0x81,0x84,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61, -0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x38,0x30,0x36,0x06,0x03,0x55, -0x04,0x0B,0x13,0x2F,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x37,0x20,0x74,0x68,0x61, -0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20, -0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F, -0x6E,0x6C,0x79,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x03,0x13,0x1B,0x74,0x68, -0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x52,0x6F,0x6F, -0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x47,0x32,0x30,0x76,0x30,0x10,0x06,0x07,0x2A, -0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00, -0x04,0xA2,0xD5,0x9C,0x82,0x7B,0x95,0x9D,0xF1,0x52,0x78,0x87,0xFE,0x8A,0x16,0xBF, -0x05,0xE6,0xDF,0xA3,0x02,0x4F,0x0D,0x07,0xC6,0x00,0x51,0xBA,0x0C,0x02,0x52,0x2D, -0x22,0xA4,0x42,0x39,0xC4,0xFE,0x8F,0xEA,0xC9,0xC1,0xBE,0xD4,0x4D,0xFF,0x9F,0x7A, -0x9E,0xE2,0xB1,0x7C,0x9A,0xAD,0xA7,0x86,0x09,0x73,0x87,0xD1,0xE7,0x9A,0xE3,0x7A, -0xA5,0xAA,0x6E,0xFB,0xBA,0xB3,0x70,0xC0,0x67,0x88,0xA2,0x35,0xD4,0xA3,0x9A,0xB1, -0xFD,0xAD,0xC2,0xEF,0x31,0xFA,0xA8,0xB9,0xF3,0xFB,0x08,0xC6,0x91,0xD1,0xFB,0x29, -0x95,0xA3,0x42,0x30,0x40,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, -0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF, -0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, -0x14,0x9A,0xD8,0x00,0x30,0x00,0xE7,0x6B,0x7F,0x85,0x18,0xEE,0x8B,0xB6,0xCE,0x8A, -0x0C,0xF8,0x11,0xE1,0xBB,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03, -0x03,0x03,0x69,0x00,0x30,0x66,0x02,0x31,0x00,0xDD,0xF8,0xE0,0x57,0x47,0x5B,0xA7, -0xE6,0x0A,0xC3,0xBD,0xF5,0x80,0x8A,0x97,0x35,0x0D,0x1B,0x89,0x3C,0x54,0x86,0x77, -0x28,0xCA,0xA1,0xF4,0x79,0xDE,0xB5,0xE6,0x38,0xB0,0xF0,0x65,0x70,0x8C,0x7F,0x02, -0x54,0xC2,0xBF,0xFF,0xD8,0xA1,0x3E,0xD9,0xCF,0x02,0x31,0x00,0xC4,0x8D,0x94,0xFC, -0xDC,0x53,0xD2,0xDC,0x9D,0x78,0x16,0x1F,0x15,0x33,0x23,0x53,0x52,0xE3,0x5A,0x31, -0x5D,0x9D,0xCA,0xAE,0xBD,0x13,0x29,0x44,0x0D,0x27,0x5B,0xA8,0xE7,0x68,0x9C,0x12, -0xF7,0x58,0x3F,0x2E,0x72,0x02,0x57,0xA3,0x8F,0xA1,0x14,0x2E, -}; - - -/* subject:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2008 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA - G3 */ -/* issuer :/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2008 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA - G3 */ - - -const unsigned char thawte_Primary_Root_CA___G3_certificate[1070]={ -0x30,0x82,0x04,0x2A,0x30,0x82,0x03,0x12,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x60, -0x01,0x97,0xB7,0x46,0xA7,0xEA,0xB4,0xB4,0x9A,0xD6,0x4B,0x2F,0xF7,0x90,0xFB,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, -0xAE,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15, -0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61,0x77,0x74,0x65,0x2C, -0x20,0x49,0x6E,0x63,0x2E,0x31,0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x0B,0x13,0x1F, -0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65, -0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,0x69,0x76,0x69,0x73,0x69,0x6F,0x6E,0x31, -0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x0B,0x13,0x2F,0x28,0x63,0x29,0x20,0x32,0x30, -0x30,0x38,0x20,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20, -0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64, -0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x24,0x30,0x22,0x06,0x03,0x55, -0x04,0x03,0x13,0x1B,0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6D,0x61, -0x72,0x79,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x47,0x33,0x30, -0x1E,0x17,0x0D,0x30,0x38,0x30,0x34,0x30,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A, -0x17,0x0D,0x33,0x37,0x31,0x32,0x30,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30, -0x81,0xAE,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31, -0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61,0x77,0x74,0x65, -0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x0B,0x13, -0x1F,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53, -0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,0x69,0x76,0x69,0x73,0x69,0x6F,0x6E, -0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x0B,0x13,0x2F,0x28,0x63,0x29,0x20,0x32, -0x30,0x30,0x38,0x20,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E, -0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65, -0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x24,0x30,0x22,0x06,0x03, -0x55,0x04,0x03,0x13,0x1B,0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6D, -0x61,0x72,0x79,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x47,0x33, -0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01, -0x00,0xB2,0xBF,0x27,0x2C,0xFB,0xDB,0xD8,0x5B,0xDD,0x78,0x7B,0x1B,0x9E,0x77,0x66, -0x81,0xCB,0x3E,0xBC,0x7C,0xAE,0xF3,0xA6,0x27,0x9A,0x34,0xA3,0x68,0x31,0x71,0x38, -0x33,0x62,0xE4,0xF3,0x71,0x66,0x79,0xB1,0xA9,0x65,0xA3,0xA5,0x8B,0xD5,0x8F,0x60, -0x2D,0x3F,0x42,0xCC,0xAA,0x6B,0x32,0xC0,0x23,0xCB,0x2C,0x41,0xDD,0xE4,0xDF,0xFC, -0x61,0x9C,0xE2,0x73,0xB2,0x22,0x95,0x11,0x43,0x18,0x5F,0xC4,0xB6,0x1F,0x57,0x6C, -0x0A,0x05,0x58,0x22,0xC8,0x36,0x4C,0x3A,0x7C,0xA5,0xD1,0xCF,0x86,0xAF,0x88,0xA7, -0x44,0x02,0x13,0x74,0x71,0x73,0x0A,0x42,0x59,0x02,0xF8,0x1B,0x14,0x6B,0x42,0xDF, -0x6F,0x5F,0xBA,0x6B,0x82,0xA2,0x9D,0x5B,0xE7,0x4A,0xBD,0x1E,0x01,0x72,0xDB,0x4B, -0x74,0xE8,0x3B,0x7F,0x7F,0x7D,0x1F,0x04,0xB4,0x26,0x9B,0xE0,0xB4,0x5A,0xAC,0x47, -0x3D,0x55,0xB8,0xD7,0xB0,0x26,0x52,0x28,0x01,0x31,0x40,0x66,0xD8,0xD9,0x24,0xBD, -0xF6,0x2A,0xD8,0xEC,0x21,0x49,0x5C,0x9B,0xF6,0x7A,0xE9,0x7F,0x55,0x35,0x7E,0x96, -0x6B,0x8D,0x93,0x93,0x27,0xCB,0x92,0xBB,0xEA,0xAC,0x40,0xC0,0x9F,0xC2,0xF8,0x80, -0xCF,0x5D,0xF4,0x5A,0xDC,0xCE,0x74,0x86,0xA6,0x3E,0x6C,0x0B,0x53,0xCA,0xBD,0x92, -0xCE,0x19,0x06,0x72,0xE6,0x0C,0x5C,0x38,0x69,0xC7,0x04,0xD6,0xBC,0x6C,0xCE,0x5B, -0xF6,0xF7,0x68,0x9C,0xDC,0x25,0x15,0x48,0x88,0xA1,0xE9,0xA9,0xF8,0x98,0x9C,0xE0, -0xF3,0xD5,0x31,0x28,0x61,0x11,0x6C,0x67,0x96,0x8D,0x39,0x99,0xCB,0xC2,0x45,0x24, -0x39,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x0F,0x06,0x03,0x55,0x1D, -0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55, -0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55, -0x1D,0x0E,0x04,0x16,0x04,0x14,0xAD,0x6C,0xAA,0x94,0x60,0x9C,0xED,0xE4,0xFF,0xFA, -0x3E,0x0A,0x74,0x2B,0x63,0x03,0xF7,0xB6,0x59,0xBF,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x1A,0x40, -0xD8,0x95,0x65,0xAC,0x09,0x92,0x89,0xC6,0x39,0xF4,0x10,0xE5,0xA9,0x0E,0x66,0x53, -0x5D,0x78,0xDE,0xFA,0x24,0x91,0xBB,0xE7,0x44,0x51,0xDF,0xC6,0x16,0x34,0x0A,0xEF, -0x6A,0x44,0x51,0xEA,0x2B,0x07,0x8A,0x03,0x7A,0xC3,0xEB,0x3F,0x0A,0x2C,0x52,0x16, -0xA0,0x2B,0x43,0xB9,0x25,0x90,0x3F,0x70,0xA9,0x33,0x25,0x6D,0x45,0x1A,0x28,0x3B, -0x27,0xCF,0xAA,0xC3,0x29,0x42,0x1B,0xDF,0x3B,0x4C,0xC0,0x33,0x34,0x5B,0x41,0x88, -0xBF,0x6B,0x2B,0x65,0xAF,0x28,0xEF,0xB2,0xF5,0xC3,0xAA,0x66,0xCE,0x7B,0x56,0xEE, -0xB7,0xC8,0xCB,0x67,0xC1,0xC9,0x9C,0x1A,0x18,0xB8,0xC4,0xC3,0x49,0x03,0xF1,0x60, -0x0E,0x50,0xCD,0x46,0xC5,0xF3,0x77,0x79,0xF7,0xB6,0x15,0xE0,0x38,0xDB,0xC7,0x2F, -0x28,0xA0,0x0C,0x3F,0x77,0x26,0x74,0xD9,0x25,0x12,0xDA,0x31,0xDA,0x1A,0x1E,0xDC, -0x29,0x41,0x91,0x22,0x3C,0x69,0xA7,0xBB,0x02,0xF2,0xB6,0x5C,0x27,0x03,0x89,0xF4, -0x06,0xEA,0x9B,0xE4,0x72,0x82,0xE3,0xA1,0x09,0xC1,0xE9,0x00,0x19,0xD3,0x3E,0xD4, -0x70,0x6B,0xBA,0x71,0xA6,0xAA,0x58,0xAE,0xF4,0xBB,0xE9,0x6C,0xB6,0xEF,0x87,0xCC, -0x9B,0xBB,0xFF,0x39,0xE6,0x56,0x61,0xD3,0x0A,0xA7,0xC4,0x5C,0x4C,0x60,0x7B,0x05, -0x77,0x26,0x7A,0xBF,0xD8,0x07,0x52,0x2C,0x62,0xF7,0x70,0x63,0xD9,0x39,0xBC,0x6F, -0x1C,0xC2,0x79,0xDC,0x76,0x29,0xAF,0xCE,0xC5,0x2C,0x64,0x04,0x5E,0x88,0x36,0x6E, -0x31,0xD4,0x40,0x1A,0x62,0x34,0x36,0x3F,0x35,0x01,0xAE,0xAC,0x63,0xA0, -}; - - -/* subject:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Server CA/emailAddress=server-certs@thawte.com */ -/* issuer :/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Server CA/emailAddress=server-certs@thawte.com */ - - -const unsigned char Thawte_Server_CA_certificate[791]={ -0x30,0x82,0x03,0x13,0x30,0x82,0x02,0x7C,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x30, -0x81,0xC4,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x5A,0x41,0x31, -0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0C,0x57,0x65,0x73,0x74,0x65,0x72, -0x6E,0x20,0x43,0x61,0x70,0x65,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13, -0x09,0x43,0x61,0x70,0x65,0x20,0x54,0x6F,0x77,0x6E,0x31,0x1D,0x30,0x1B,0x06,0x03, -0x55,0x04,0x0A,0x13,0x14,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x6F,0x6E,0x73, -0x75,0x6C,0x74,0x69,0x6E,0x67,0x20,0x63,0x63,0x31,0x28,0x30,0x26,0x06,0x03,0x55, -0x04,0x0B,0x13,0x1F,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F, -0x6E,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,0x69,0x76,0x69,0x73, -0x69,0x6F,0x6E,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x54,0x68, -0x61,0x77,0x74,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,0x31,0x26, -0x30,0x24,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x17,0x73, -0x65,0x72,0x76,0x65,0x72,0x2D,0x63,0x65,0x72,0x74,0x73,0x40,0x74,0x68,0x61,0x77, -0x74,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x39,0x36,0x30,0x38,0x30,0x31, -0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x30,0x31,0x32,0x33,0x31,0x32, -0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xC4,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, -0x04,0x06,0x13,0x02,0x5A,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13, -0x0C,0x57,0x65,0x73,0x74,0x65,0x72,0x6E,0x20,0x43,0x61,0x70,0x65,0x31,0x12,0x30, -0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x61,0x70,0x65,0x20,0x54,0x6F,0x77, -0x6E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x54,0x68,0x61,0x77, -0x74,0x65,0x20,0x43,0x6F,0x6E,0x73,0x75,0x6C,0x74,0x69,0x6E,0x67,0x20,0x63,0x63, -0x31,0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x0B,0x13,0x1F,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65, -0x73,0x20,0x44,0x69,0x76,0x69,0x73,0x69,0x6F,0x6E,0x31,0x19,0x30,0x17,0x06,0x03, -0x55,0x04,0x03,0x13,0x10,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x53,0x65,0x72,0x76, -0x65,0x72,0x20,0x43,0x41,0x31,0x26,0x30,0x24,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x09,0x01,0x16,0x17,0x73,0x65,0x72,0x76,0x65,0x72,0x2D,0x63,0x65,0x72, -0x74,0x73,0x40,0x74,0x68,0x61,0x77,0x74,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9F, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03, -0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xD3,0xA4,0x50,0x6E,0xC8,0xFF, -0x56,0x6B,0xE6,0xCF,0x5D,0xB6,0xEA,0x0C,0x68,0x75,0x47,0xA2,0xAA,0xC2,0xDA,0x84, -0x25,0xFC,0xA8,0xF4,0x47,0x51,0xDA,0x85,0xB5,0x20,0x74,0x94,0x86,0x1E,0x0F,0x75, -0xC9,0xE9,0x08,0x61,0xF5,0x06,0x6D,0x30,0x6E,0x15,0x19,0x02,0xE9,0x52,0xC0,0x62, -0xDB,0x4D,0x99,0x9E,0xE2,0x6A,0x0C,0x44,0x38,0xCD,0xFE,0xBE,0xE3,0x64,0x09,0x70, -0xC5,0xFE,0xB1,0x6B,0x29,0xB6,0x2F,0x49,0xC8,0x3B,0xD4,0x27,0x04,0x25,0x10,0x97, -0x2F,0xE7,0x90,0x6D,0xC0,0x28,0x42,0x99,0xD7,0x4C,0x43,0xDE,0xC3,0xF5,0x21,0x6D, -0x54,0x9F,0x5D,0xC3,0x58,0xE1,0xC0,0xE4,0xD9,0x5B,0xB0,0xB8,0xDC,0xB4,0x7B,0xDF, -0x36,0x3A,0xC2,0xB5,0x66,0x22,0x12,0xD6,0x87,0x0D,0x02,0x03,0x01,0x00,0x01,0xA3, -0x13,0x30,0x11,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, -0x03,0x01,0x01,0xFF,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x04,0x05,0x00,0x03,0x81,0x81,0x00,0x07,0xFA,0x4C,0x69,0x5C,0xFB,0x95,0xCC,0x46, -0xEE,0x85,0x83,0x4D,0x21,0x30,0x8E,0xCA,0xD9,0xA8,0x6F,0x49,0x1A,0xE6,0xDA,0x51, -0xE3,0x60,0x70,0x6C,0x84,0x61,0x11,0xA1,0x1A,0xC8,0x48,0x3E,0x59,0x43,0x7D,0x4F, -0x95,0x3D,0xA1,0x8B,0xB7,0x0B,0x62,0x98,0x7A,0x75,0x8A,0xDD,0x88,0x4E,0x4E,0x9E, -0x40,0xDB,0xA8,0xCC,0x32,0x74,0xB9,0x6F,0x0D,0xC6,0xE3,0xB3,0x44,0x0B,0xD9,0x8A, -0x6F,0x9A,0x29,0x9B,0x99,0x18,0x28,0x3B,0xD1,0xE3,0x40,0x28,0x9A,0x5A,0x3C,0xD5, -0xB5,0xE7,0x20,0x1B,0x8B,0xCA,0xA4,0xAB,0x8D,0xE9,0x51,0xD9,0xE2,0x4C,0x2C,0x59, -0xA9,0xDA,0xB9,0xB2,0x75,0x1B,0xF6,0x42,0xF2,0xEF,0xC7,0xF2,0x18,0xF9,0x89,0xBC, -0xA3,0xFF,0x8A,0x23,0x2E,0x70,0x47, -}; - - -/* subject:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC */ -/* issuer :/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC */ - - -const unsigned char UTN_DATACorp_SGC_Root_CA_certificate[1122]={ -0x30,0x82,0x04,0x5E,0x30,0x82,0x03,0x46,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x44, -0xBE,0x0C,0x8B,0x50,0x00,0x21,0xB4,0x11,0xD3,0x2A,0x68,0x06,0xA9,0xAD,0x69,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, -0x93,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x13,0x02,0x55,0x54,0x31,0x17,0x30,0x15,0x06, -0x03,0x55,0x04,0x07,0x13,0x0E,0x53,0x61,0x6C,0x74,0x20,0x4C,0x61,0x6B,0x65,0x20, -0x43,0x69,0x74,0x79,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15,0x54, -0x68,0x65,0x20,0x55,0x53,0x45,0x52,0x54,0x52,0x55,0x53,0x54,0x20,0x4E,0x65,0x74, -0x77,0x6F,0x72,0x6B,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x68, -0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x75,0x73,0x65,0x72,0x74,0x72, -0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03, -0x13,0x12,0x55,0x54,0x4E,0x20,0x2D,0x20,0x44,0x41,0x54,0x41,0x43,0x6F,0x72,0x70, -0x20,0x53,0x47,0x43,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x36,0x32,0x34,0x31,0x38, -0x35,0x37,0x32,0x31,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x32,0x34,0x31,0x39,0x30, -0x36,0x33,0x30,0x5A,0x30,0x81,0x93,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, -0x13,0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x13,0x02,0x55, -0x54,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x07,0x13,0x0E,0x53,0x61,0x6C,0x74, -0x20,0x4C,0x61,0x6B,0x65,0x20,0x43,0x69,0x74,0x79,0x31,0x1E,0x30,0x1C,0x06,0x03, -0x55,0x04,0x0A,0x13,0x15,0x54,0x68,0x65,0x20,0x55,0x53,0x45,0x52,0x54,0x52,0x55, -0x53,0x54,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x21,0x30,0x1F,0x06,0x03, -0x55,0x04,0x0B,0x13,0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E, -0x75,0x73,0x65,0x72,0x74,0x72,0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x31,0x1B,0x30, -0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12,0x55,0x54,0x4E,0x20,0x2D,0x20,0x44,0x41, -0x54,0x41,0x43,0x6F,0x72,0x70,0x20,0x53,0x47,0x43,0x30,0x82,0x01,0x22,0x30,0x0D, -0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01, -0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xDF,0xEE,0x58,0x10,0xA2, -0x2B,0x6E,0x55,0xC4,0x8E,0xBF,0x2E,0x46,0x09,0xE7,0xE0,0x08,0x0F,0x2E,0x2B,0x7A, -0x13,0x94,0x1B,0xBD,0xF6,0xB6,0x80,0x8E,0x65,0x05,0x93,0x00,0x1E,0xBC,0xAF,0xE2, -0x0F,0x8E,0x19,0x0D,0x12,0x47,0xEC,0xAC,0xAD,0xA3,0xFA,0x2E,0x70,0xF8,0xDE,0x6E, -0xFB,0x56,0x42,0x15,0x9E,0x2E,0x5C,0xEF,0x23,0xDE,0x21,0xB9,0x05,0x76,0x27,0x19, -0x0F,0x4F,0xD6,0xC3,0x9C,0xB4,0xBE,0x94,0x19,0x63,0xF2,0xA6,0x11,0x0A,0xEB,0x53, -0x48,0x9C,0xBE,0xF2,0x29,0x3B,0x16,0xE8,0x1A,0xA0,0x4C,0xA6,0xC9,0xF4,0x18,0x59, -0x68,0xC0,0x70,0xF2,0x53,0x00,0xC0,0x5E,0x50,0x82,0xA5,0x56,0x6F,0x36,0xF9,0x4A, -0xE0,0x44,0x86,0xA0,0x4D,0x4E,0xD6,0x47,0x6E,0x49,0x4A,0xCB,0x67,0xD7,0xA6,0xC4, -0x05,0xB9,0x8E,0x1E,0xF4,0xFC,0xFF,0xCD,0xE7,0x36,0xE0,0x9C,0x05,0x6C,0xB2,0x33, -0x22,0x15,0xD0,0xB4,0xE0,0xCC,0x17,0xC0,0xB2,0xC0,0xF4,0xFE,0x32,0x3F,0x29,0x2A, -0x95,0x7B,0xD8,0xF2,0xA7,0x4E,0x0F,0x54,0x7C,0xA1,0x0D,0x80,0xB3,0x09,0x03,0xC1, -0xFF,0x5C,0xDD,0x5E,0x9A,0x3E,0xBC,0xAE,0xBC,0x47,0x8A,0x6A,0xAE,0x71,0xCA,0x1F, -0xB1,0x2A,0xB8,0x5F,0x42,0x05,0x0B,0xEC,0x46,0x30,0xD1,0x72,0x0B,0xCA,0xE9,0x56, -0x6D,0xF5,0xEF,0xDF,0x78,0xBE,0x61,0xBA,0xB2,0xA5,0xAE,0x04,0x4C,0xBC,0xA8,0xAC, -0x69,0x15,0x97,0xBD,0xEF,0xEB,0xB4,0x8C,0xBF,0x35,0xF8,0xD4,0xC3,0xD1,0x28,0x0E, -0x5C,0x3A,0x9F,0x70,0x18,0x33,0x20,0x77,0xC4,0xA2,0xAF,0x02,0x03,0x01,0x00,0x01, -0xA3,0x81,0xAB,0x30,0x81,0xA8,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03, -0x02,0x01,0xC6,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, -0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x53, -0x32,0xD1,0xB3,0xCF,0x7F,0xFA,0xE0,0xF1,0xA0,0x5D,0x85,0x4E,0x92,0xD2,0x9E,0x45, -0x1D,0xB4,0x4F,0x30,0x3D,0x06,0x03,0x55,0x1D,0x1F,0x04,0x36,0x30,0x34,0x30,0x32, -0xA0,0x30,0xA0,0x2E,0x86,0x2C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C, -0x2E,0x75,0x73,0x65,0x72,0x74,0x72,0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x55, -0x54,0x4E,0x2D,0x44,0x41,0x54,0x41,0x43,0x6F,0x72,0x70,0x53,0x47,0x43,0x2E,0x63, -0x72,0x6C,0x30,0x2A,0x06,0x03,0x55,0x1D,0x25,0x04,0x23,0x30,0x21,0x06,0x08,0x2B, -0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37, -0x0A,0x03,0x03,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,0x30,0x0D, -0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01, -0x01,0x00,0x27,0x35,0x97,0x00,0x8A,0x8B,0x28,0xBD,0xC6,0x33,0x30,0x1E,0x29,0xFC, -0xE2,0xF7,0xD5,0x98,0xD4,0x40,0xBB,0x60,0xCA,0xBF,0xAB,0x17,0x2C,0x09,0x36,0x7F, -0x50,0xFA,0x41,0xDC,0xAE,0x96,0x3A,0x0A,0x23,0x3E,0x89,0x59,0xC9,0xA3,0x07,0xED, -0x1B,0x37,0xAD,0xFC,0x7C,0xBE,0x51,0x49,0x5A,0xDE,0x3A,0x0A,0x54,0x08,0x16,0x45, -0xC2,0x99,0xB1,0x87,0xCD,0x8C,0x68,0xE0,0x69,0x03,0xE9,0xC4,0x4E,0x98,0xB2,0x3B, -0x8C,0x16,0xB3,0x0E,0xA0,0x0C,0x98,0x50,0x9B,0x93,0xA9,0x70,0x09,0xC8,0x2C,0xA3, -0x8F,0xDF,0x02,0xE4,0xE0,0x71,0x3A,0xF1,0xB4,0x23,0x72,0xA0,0xAA,0x01,0xDF,0xDF, -0x98,0x3E,0x14,0x50,0xA0,0x31,0x26,0xBD,0x28,0xE9,0x5A,0x30,0x26,0x75,0xF9,0x7B, -0x60,0x1C,0x8D,0xF3,0xCD,0x50,0x26,0x6D,0x04,0x27,0x9A,0xDF,0xD5,0x0D,0x45,0x47, -0x29,0x6B,0x2C,0xE6,0x76,0xD9,0xA9,0x29,0x7D,0x32,0xDD,0xC9,0x36,0x3C,0xBD,0xAE, -0x35,0xF1,0x11,0x9E,0x1D,0xBB,0x90,0x3F,0x12,0x47,0x4E,0x8E,0xD7,0x7E,0x0F,0x62, -0x73,0x1D,0x52,0x26,0x38,0x1C,0x18,0x49,0xFD,0x30,0x74,0x9A,0xC4,0xE5,0x22,0x2F, -0xD8,0xC0,0x8D,0xED,0x91,0x7A,0x4C,0x00,0x8F,0x72,0x7F,0x5D,0xDA,0xDD,0x1B,0x8B, -0x45,0x6B,0xE7,0xDD,0x69,0x97,0xA8,0xC5,0x56,0x4C,0x0F,0x0C,0xF6,0x9F,0x7A,0x91, -0x37,0xF6,0x97,0x82,0xE0,0xDD,0x71,0x69,0xFF,0x76,0x3F,0x60,0x4D,0x3C,0xCF,0xF7, -0x99,0xF9,0xC6,0x57,0xF4,0xC9,0x55,0x39,0x78,0xBA,0x2C,0x79,0xC9,0xA6,0x88,0x2B, -0xF4,0x08, -}; - - -/* subject:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware */ -/* issuer :/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware */ - - -const unsigned char UTN_USERFirst_Hardware_Root_CA_certificate[1144]={ -0x30,0x82,0x04,0x74,0x30,0x82,0x03,0x5C,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x44, -0xBE,0x0C,0x8B,0x50,0x00,0x24,0xB4,0x11,0xD3,0x36,0x2A,0xFE,0x65,0x0A,0xFD,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, -0x97,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x13,0x02,0x55,0x54,0x31,0x17,0x30,0x15,0x06, -0x03,0x55,0x04,0x07,0x13,0x0E,0x53,0x61,0x6C,0x74,0x20,0x4C,0x61,0x6B,0x65,0x20, -0x43,0x69,0x74,0x79,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15,0x54, -0x68,0x65,0x20,0x55,0x53,0x45,0x52,0x54,0x52,0x55,0x53,0x54,0x20,0x4E,0x65,0x74, -0x77,0x6F,0x72,0x6B,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x68, -0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x75,0x73,0x65,0x72,0x74,0x72, -0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03, -0x13,0x16,0x55,0x54,0x4E,0x2D,0x55,0x53,0x45,0x52,0x46,0x69,0x72,0x73,0x74,0x2D, -0x48,0x61,0x72,0x64,0x77,0x61,0x72,0x65,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x37, -0x30,0x39,0x31,0x38,0x31,0x30,0x34,0x32,0x5A,0x17,0x0D,0x31,0x39,0x30,0x37,0x30, -0x39,0x31,0x38,0x31,0x39,0x32,0x32,0x5A,0x30,0x81,0x97,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, -0x08,0x13,0x02,0x55,0x54,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x07,0x13,0x0E, -0x53,0x61,0x6C,0x74,0x20,0x4C,0x61,0x6B,0x65,0x20,0x43,0x69,0x74,0x79,0x31,0x1E, -0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15,0x54,0x68,0x65,0x20,0x55,0x53,0x45, -0x52,0x54,0x52,0x55,0x53,0x54,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x21, -0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, -0x77,0x77,0x77,0x2E,0x75,0x73,0x65,0x72,0x74,0x72,0x75,0x73,0x74,0x2E,0x63,0x6F, -0x6D,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x13,0x16,0x55,0x54,0x4E,0x2D, -0x55,0x53,0x45,0x52,0x46,0x69,0x72,0x73,0x74,0x2D,0x48,0x61,0x72,0x64,0x77,0x61, -0x72,0x65,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82, -0x01,0x01,0x00,0xB1,0xF7,0xC3,0x38,0x3F,0xB4,0xA8,0x7F,0xCF,0x39,0x82,0x51,0x67, -0xD0,0x6D,0x9F,0xD2,0xFF,0x58,0xF3,0xE7,0x9F,0x2B,0xEC,0x0D,0x89,0x54,0x99,0xB9, -0x38,0x99,0x16,0xF7,0xE0,0x21,0x79,0x48,0xC2,0xBB,0x61,0x74,0x12,0x96,0x1D,0x3C, -0x6A,0x72,0xD5,0x3C,0x10,0x67,0x3A,0x39,0xED,0x2B,0x13,0xCD,0x66,0xEB,0x95,0x09, -0x33,0xA4,0x6C,0x97,0xB1,0xE8,0xC6,0xEC,0xC1,0x75,0x79,0x9C,0x46,0x5E,0x8D,0xAB, -0xD0,0x6A,0xFD,0xB9,0x2A,0x55,0x17,0x10,0x54,0xB3,0x19,0xF0,0x9A,0xF6,0xF1,0xB1, -0x5D,0xB6,0xA7,0x6D,0xFB,0xE0,0x71,0x17,0x6B,0xA2,0x88,0xFB,0x00,0xDF,0xFE,0x1A, -0x31,0x77,0x0C,0x9A,0x01,0x7A,0xB1,0x32,0xE3,0x2B,0x01,0x07,0x38,0x6E,0xC3,0xA5, -0x5E,0x23,0xBC,0x45,0x9B,0x7B,0x50,0xC1,0xC9,0x30,0x8F,0xDB,0xE5,0x2B,0x7A,0xD3, -0x5B,0xFB,0x33,0x40,0x1E,0xA0,0xD5,0x98,0x17,0xBC,0x8B,0x87,0xC3,0x89,0xD3,0x5D, -0xA0,0x8E,0xB2,0xAA,0xAA,0xF6,0x8E,0x69,0x88,0x06,0xC5,0xFA,0x89,0x21,0xF3,0x08, -0x9D,0x69,0x2E,0x09,0x33,0x9B,0x29,0x0D,0x46,0x0F,0x8C,0xCC,0x49,0x34,0xB0,0x69, -0x51,0xBD,0xF9,0x06,0xCD,0x68,0xAD,0x66,0x4C,0xBC,0x3E,0xAC,0x61,0xBD,0x0A,0x88, -0x0E,0xC8,0xDF,0x3D,0xEE,0x7C,0x04,0x4C,0x9D,0x0A,0x5E,0x6B,0x91,0xD6,0xEE,0xC7, -0xED,0x28,0x8D,0xAB,0x4D,0x87,0x89,0x73,0xD0,0x6E,0xA4,0xD0,0x1E,0x16,0x8B,0x14, -0xE1,0x76,0x44,0x03,0x7F,0x63,0xAC,0xE4,0xCD,0x49,0x9C,0xC5,0x92,0xF4,0xAB,0x32, -0xA1,0x48,0x5B,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xB9,0x30,0x81,0xB6,0x30,0x0B, -0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0xC6,0x30,0x0F,0x06,0x03,0x55, -0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03, -0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xA1,0x72,0x5F,0x26,0x1B,0x28,0x98,0x43,0x95, -0x5D,0x07,0x37,0xD5,0x85,0x96,0x9D,0x4B,0xD2,0xC3,0x45,0x30,0x44,0x06,0x03,0x55, -0x1D,0x1F,0x04,0x3D,0x30,0x3B,0x30,0x39,0xA0,0x37,0xA0,0x35,0x86,0x33,0x68,0x74, -0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x75,0x73,0x65,0x72,0x74,0x72,0x75, -0x73,0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x55,0x54,0x4E,0x2D,0x55,0x53,0x45,0x52,0x46, -0x69,0x72,0x73,0x74,0x2D,0x48,0x61,0x72,0x64,0x77,0x61,0x72,0x65,0x2E,0x63,0x72, -0x6C,0x30,0x31,0x06,0x03,0x55,0x1D,0x25,0x04,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06, -0x01,0x05,0x05,0x07,0x03,0x01,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05, -0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06,0x06,0x08,0x2B,0x06,0x01,0x05, -0x05,0x07,0x03,0x07,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x47,0x19,0x0F,0xDE,0x74,0xC6,0x99,0x97, -0xAF,0xFC,0xAD,0x28,0x5E,0x75,0x8E,0xEB,0x2D,0x67,0xEE,0x4E,0x7B,0x2B,0xD7,0x0C, -0xFF,0xF6,0xDE,0xCB,0x55,0xA2,0x0A,0xE1,0x4C,0x54,0x65,0x93,0x60,0x6B,0x9F,0x12, -0x9C,0xAD,0x5E,0x83,0x2C,0xEB,0x5A,0xAE,0xC0,0xE4,0x2D,0xF4,0x00,0x63,0x1D,0xB8, -0xC0,0x6C,0xF2,0xCF,0x49,0xBB,0x4D,0x93,0x6F,0x06,0xA6,0x0A,0x22,0xB2,0x49,0x62, -0x08,0x4E,0xFF,0xC8,0xC8,0x14,0xB2,0x88,0x16,0x5D,0xE7,0x01,0xE4,0x12,0x95,0xE5, -0x45,0x34,0xB3,0x8B,0x69,0xBD,0xCF,0xB4,0x85,0x8F,0x75,0x51,0x9E,0x7D,0x3A,0x38, -0x3A,0x14,0x48,0x12,0xC6,0xFB,0xA7,0x3B,0x1A,0x8D,0x0D,0x82,0x40,0x07,0xE8,0x04, -0x08,0x90,0xA1,0x89,0xCB,0x19,0x50,0xDF,0xCA,0x1C,0x01,0xBC,0x1D,0x04,0x19,0x7B, -0x10,0x76,0x97,0x3B,0xEE,0x90,0x90,0xCA,0xC4,0x0E,0x1F,0x16,0x6E,0x75,0xEF,0x33, -0xF8,0xD3,0x6F,0x5B,0x1E,0x96,0xE3,0xE0,0x74,0x77,0x74,0x7B,0x8A,0xA2,0x6E,0x2D, -0xDD,0x76,0xD6,0x39,0x30,0x82,0xF0,0xAB,0x9C,0x52,0xF2,0x2A,0xC7,0xAF,0x49,0x5E, -0x7E,0xC7,0x68,0xE5,0x82,0x81,0xC8,0x6A,0x27,0xF9,0x27,0x88,0x2A,0xD5,0x58,0x50, -0x95,0x1F,0xF0,0x3B,0x1C,0x57,0xBB,0x7D,0x14,0x39,0x62,0x2B,0x9A,0xC9,0x94,0x92, -0x2A,0xA3,0x22,0x0C,0xFF,0x89,0x26,0x7D,0x5F,0x23,0x2B,0x47,0xD7,0x15,0x1D,0xA9, -0x6A,0x9E,0x51,0x0D,0x2A,0x51,0x9E,0x81,0xF9,0xD4,0x3B,0x5E,0x70,0x12,0x7F,0x10, -0x32,0x9C,0x1E,0xBB,0x9D,0xF8,0x66,0xA8, -}; - - -/* subject:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 1 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com */ -/* issuer :/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 1 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com */ - - -const unsigned char ValiCert_Class_1_VA_certificate[747]={ -0x30,0x82,0x02,0xE7,0x30,0x82,0x02,0x50,0x02,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A, -0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0xBB,0x31,0x24,0x30, -0x22,0x06,0x03,0x55,0x04,0x07,0x13,0x1B,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74, -0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x65,0x74,0x77, -0x6F,0x72,0x6B,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x61, -0x6C,0x69,0x43,0x65,0x72,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x35,0x30,0x33, -0x06,0x03,0x55,0x04,0x0B,0x13,0x2C,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20, -0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x50,0x6F,0x6C,0x69,0x63,0x79,0x20,0x56, -0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, -0x69,0x74,0x79,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x68,0x74, -0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x61,0x6C,0x69,0x63,0x65,0x72, -0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x31,0x20,0x30,0x1E,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x09,0x01,0x16,0x11,0x69,0x6E,0x66,0x6F,0x40,0x76,0x61,0x6C,0x69, -0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x36, -0x32,0x35,0x32,0x32,0x32,0x33,0x34,0x38,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x32, -0x35,0x32,0x32,0x32,0x33,0x34,0x38,0x5A,0x30,0x81,0xBB,0x31,0x24,0x30,0x22,0x06, -0x03,0x55,0x04,0x07,0x13,0x1B,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20,0x56, -0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72, -0x6B,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x61,0x6C,0x69, -0x43,0x65,0x72,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x35,0x30,0x33,0x06,0x03, -0x55,0x04,0x0B,0x13,0x2C,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20,0x43,0x6C, -0x61,0x73,0x73,0x20,0x31,0x20,0x50,0x6F,0x6C,0x69,0x63,0x79,0x20,0x56,0x61,0x6C, -0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74, -0x79,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x68,0x74,0x74,0x70, -0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x61,0x6C,0x69,0x63,0x65,0x72,0x74,0x2E, -0x63,0x6F,0x6D,0x2F,0x31,0x20,0x30,0x1E,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x09,0x01,0x16,0x11,0x69,0x6E,0x66,0x6F,0x40,0x76,0x61,0x6C,0x69,0x63,0x65, -0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02, -0x81,0x81,0x00,0xD8,0x59,0x82,0x7A,0x89,0xB8,0x96,0xBA,0xA6,0x2F,0x68,0x6F,0x58, -0x2E,0xA7,0x54,0x1C,0x06,0x6E,0xF4,0xEA,0x8D,0x48,0xBC,0x31,0x94,0x17,0xF0,0xF3, -0x4E,0xBC,0xB2,0xB8,0x35,0x92,0x76,0xB0,0xD0,0xA5,0xA5,0x01,0xD7,0x00,0x03,0x12, -0x22,0x19,0x08,0xF8,0xFF,0x11,0x23,0x9B,0xCE,0x07,0xF5,0xBF,0x69,0x1A,0x26,0xFE, -0x4E,0xE9,0xD1,0x7F,0x9D,0x2C,0x40,0x1D,0x59,0x68,0x6E,0xA6,0xF8,0x58,0xB0,0x9D, -0x1A,0x8F,0xD3,0x3F,0xF1,0xDC,0x19,0x06,0x81,0xA8,0x0E,0xE0,0x3A,0xDD,0xC8,0x53, -0x45,0x09,0x06,0xE6,0x0F,0x70,0xC3,0xFA,0x40,0xA6,0x0E,0xE2,0x56,0x05,0x0F,0x18, -0x4D,0xFC,0x20,0x82,0xD1,0x73,0x55,0x74,0x8D,0x76,0x72,0xA0,0x1D,0x9D,0x1D,0xC0, -0xDD,0x3F,0x71,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x50,0x68,0x3D,0x49,0xF4, -0x2C,0x1C,0x06,0x94,0xDF,0x95,0x60,0x7F,0x96,0x7B,0x17,0xFE,0x4F,0x71,0xAD,0x64, -0xC8,0xDD,0x77,0xD2,0xEF,0x59,0x55,0xE8,0x3F,0xE8,0x8E,0x05,0x2A,0x21,0xF2,0x07, -0xD2,0xB5,0xA7,0x52,0xFE,0x9C,0xB1,0xB6,0xE2,0x5B,0x77,0x17,0x40,0xEA,0x72,0xD6, -0x23,0xCB,0x28,0x81,0x32,0xC3,0x00,0x79,0x18,0xEC,0x59,0x17,0x89,0xC9,0xC6,0x6A, -0x1E,0x71,0xC9,0xFD,0xB7,0x74,0xA5,0x25,0x45,0x69,0xC5,0x48,0xAB,0x19,0xE1,0x45, -0x8A,0x25,0x6B,0x19,0xEE,0xE5,0xBB,0x12,0xF5,0x7F,0xF7,0xA6,0x8D,0x51,0xC3,0xF0, -0x9D,0x74,0xB7,0xA9,0x3E,0xA0,0xA5,0xFF,0xB6,0x49,0x03,0x13,0xDA,0x22,0xCC,0xED, -0x71,0x82,0x2B,0x99,0xCF,0x3A,0xB7,0xF5,0x2D,0x72,0xC8, -}; - - -/* subject:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com */ -/* issuer :/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com */ - - -const unsigned char ValiCert_Class_2_VA_certificate[747]={ -0x30,0x82,0x02,0xE7,0x30,0x82,0x02,0x50,0x02,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A, -0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0xBB,0x31,0x24,0x30, -0x22,0x06,0x03,0x55,0x04,0x07,0x13,0x1B,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74, -0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x65,0x74,0x77, -0x6F,0x72,0x6B,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x61, -0x6C,0x69,0x43,0x65,0x72,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x35,0x30,0x33, -0x06,0x03,0x55,0x04,0x0B,0x13,0x2C,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20, -0x43,0x6C,0x61,0x73,0x73,0x20,0x32,0x20,0x50,0x6F,0x6C,0x69,0x63,0x79,0x20,0x56, -0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, -0x69,0x74,0x79,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x68,0x74, -0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x61,0x6C,0x69,0x63,0x65,0x72, -0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x31,0x20,0x30,0x1E,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x09,0x01,0x16,0x11,0x69,0x6E,0x66,0x6F,0x40,0x76,0x61,0x6C,0x69, -0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x36, -0x32,0x36,0x30,0x30,0x31,0x39,0x35,0x34,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x32, -0x36,0x30,0x30,0x31,0x39,0x35,0x34,0x5A,0x30,0x81,0xBB,0x31,0x24,0x30,0x22,0x06, -0x03,0x55,0x04,0x07,0x13,0x1B,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20,0x56, -0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72, -0x6B,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x61,0x6C,0x69, -0x43,0x65,0x72,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x35,0x30,0x33,0x06,0x03, -0x55,0x04,0x0B,0x13,0x2C,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20,0x43,0x6C, -0x61,0x73,0x73,0x20,0x32,0x20,0x50,0x6F,0x6C,0x69,0x63,0x79,0x20,0x56,0x61,0x6C, -0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74, -0x79,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x68,0x74,0x74,0x70, -0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x61,0x6C,0x69,0x63,0x65,0x72,0x74,0x2E, -0x63,0x6F,0x6D,0x2F,0x31,0x20,0x30,0x1E,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x09,0x01,0x16,0x11,0x69,0x6E,0x66,0x6F,0x40,0x76,0x61,0x6C,0x69,0x63,0x65, -0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02, -0x81,0x81,0x00,0xCE,0x3A,0x71,0xCA,0xE5,0xAB,0xC8,0x59,0x92,0x55,0xD7,0xAB,0xD8, -0x74,0x0E,0xF9,0xEE,0xD9,0xF6,0x55,0x47,0x59,0x65,0x47,0x0E,0x05,0x55,0xDC,0xEB, -0x98,0x36,0x3C,0x5C,0x53,0x5D,0xD3,0x30,0xCF,0x38,0xEC,0xBD,0x41,0x89,0xED,0x25, -0x42,0x09,0x24,0x6B,0x0A,0x5E,0xB3,0x7C,0xDD,0x52,0x2D,0x4C,0xE6,0xD4,0xD6,0x7D, -0x5A,0x59,0xA9,0x65,0xD4,0x49,0x13,0x2D,0x24,0x4D,0x1C,0x50,0x6F,0xB5,0xC1,0x85, -0x54,0x3B,0xFE,0x71,0xE4,0xD3,0x5C,0x42,0xF9,0x80,0xE0,0x91,0x1A,0x0A,0x5B,0x39, -0x36,0x67,0xF3,0x3F,0x55,0x7C,0x1B,0x3F,0xB4,0x5F,0x64,0x73,0x34,0xE3,0xB4,0x12, -0xBF,0x87,0x64,0xF8,0xDA,0x12,0xFF,0x37,0x27,0xC1,0xB3,0x43,0xBB,0xEF,0x7B,0x6E, -0x2E,0x69,0xF7,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x3B,0x7F,0x50,0x6F,0x6F, -0x50,0x94,0x99,0x49,0x62,0x38,0x38,0x1F,0x4B,0xF8,0xA5,0xC8,0x3E,0xA7,0x82,0x81, -0xF6,0x2B,0xC7,0xE8,0xC5,0xCE,0xE8,0x3A,0x10,0x82,0xCB,0x18,0x00,0x8E,0x4D,0xBD, -0xA8,0x58,0x7F,0xA1,0x79,0x00,0xB5,0xBB,0xE9,0x8D,0xAF,0x41,0xD9,0x0F,0x34,0xEE, -0x21,0x81,0x19,0xA0,0x32,0x49,0x28,0xF4,0xC4,0x8E,0x56,0xD5,0x52,0x33,0xFD,0x50, -0xD5,0x7E,0x99,0x6C,0x03,0xE4,0xC9,0x4C,0xFC,0xCB,0x6C,0xAB,0x66,0xB3,0x4A,0x21, -0x8C,0xE5,0xB5,0x0C,0x32,0x3E,0x10,0xB2,0xCC,0x6C,0xA1,0xDC,0x9A,0x98,0x4C,0x02, -0x5B,0xF3,0xCE,0xB9,0x9E,0xA5,0x72,0x0E,0x4A,0xB7,0x3F,0x3C,0xE6,0x16,0x68,0xF8, -0xBE,0xED,0x74,0x4C,0xBC,0x5B,0xD5,0x62,0x1F,0x43,0xDD, -}; - - -/* subject:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority */ -/* issuer :/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority */ - - -const unsigned char Verisign_Class_3_Public_Primary_Certification_Authority_certificate[576]={ -0x30,0x82,0x02,0x3C,0x30,0x82,0x01,0xA5,0x02,0x10,0x3C,0x91,0x31,0xCB,0x1F,0xF6, -0xD0,0x1B,0x0E,0x9A,0xB8,0xD0,0x44,0xBF,0x12,0xBE,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x5F,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04, -0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63, -0x2E,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x0B,0x13,0x2E,0x43,0x6C,0x61,0x73, -0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61, -0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E, -0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x39,0x36, -0x30,0x31,0x32,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x38,0x30, -0x38,0x30,0x32,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x5F,0x31,0x0B,0x30,0x09, -0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55, -0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E, -0x63,0x2E,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x0B,0x13,0x2E,0x43,0x6C,0x61, -0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D, -0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F, -0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x81,0x9F,0x30,0x0D, -0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D, -0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC9,0x5C,0x59,0x9E,0xF2,0x1B,0x8A,0x01, -0x14,0xB4,0x10,0xDF,0x04,0x40,0xDB,0xE3,0x57,0xAF,0x6A,0x45,0x40,0x8F,0x84,0x0C, -0x0B,0xD1,0x33,0xD9,0xD9,0x11,0xCF,0xEE,0x02,0x58,0x1F,0x25,0xF7,0x2A,0xA8,0x44, -0x05,0xAA,0xEC,0x03,0x1F,0x78,0x7F,0x9E,0x93,0xB9,0x9A,0x00,0xAA,0x23,0x7D,0xD6, -0xAC,0x85,0xA2,0x63,0x45,0xC7,0x72,0x27,0xCC,0xF4,0x4C,0xC6,0x75,0x71,0xD2,0x39, -0xEF,0x4F,0x42,0xF0,0x75,0xDF,0x0A,0x90,0xC6,0x8E,0x20,0x6F,0x98,0x0F,0xF8,0xAC, -0x23,0x5F,0x70,0x29,0x36,0xA4,0xC9,0x86,0xE7,0xB1,0x9A,0x20,0xCB,0x53,0xA5,0x85, -0xE7,0x3D,0xBE,0x7D,0x9A,0xFE,0x24,0x45,0x33,0xDC,0x76,0x15,0xED,0x0F,0xA2,0x71, -0x64,0x4C,0x65,0x2E,0x81,0x68,0x45,0xA7,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00, -0x10,0x72,0x52,0xA9,0x05,0x14,0x19,0x32,0x08,0x41,0xF0,0xC5,0x6B,0x0A,0xCC,0x7E, -0x0F,0x21,0x19,0xCD,0xE4,0x67,0xDC,0x5F,0xA9,0x1B,0xE6,0xCA,0xE8,0x73,0x9D,0x22, -0xD8,0x98,0x6E,0x73,0x03,0x61,0x91,0xC5,0x7C,0xB0,0x45,0x40,0x6E,0x44,0x9D,0x8D, -0xB0,0xB1,0x96,0x74,0x61,0x2D,0x0D,0xA9,0x45,0xD2,0xA4,0x92,0x2A,0xD6,0x9A,0x75, -0x97,0x6E,0x3F,0x53,0xFD,0x45,0x99,0x60,0x1D,0xA8,0x2B,0x4C,0xF9,0x5E,0xA7,0x09, -0xD8,0x75,0x30,0xD7,0xD2,0x65,0x60,0x3D,0x67,0xD6,0x48,0x55,0x75,0x69,0x3F,0x91, -0xF5,0x48,0x0B,0x47,0x69,0x22,0x69,0x82,0x96,0xBE,0xC9,0xC8,0x38,0x86,0x4A,0x7A, -0x2C,0x73,0x19,0x48,0x69,0x4E,0x6B,0x7C,0x65,0xBF,0x0F,0xFC,0x70,0xCE,0x88,0x90, -}; - - -/* subject:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network */ -/* issuer :/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network */ - - -const unsigned char Verisign_Class_3_Public_Primary_Certification_Authority___G2_certificate[774]={ -0x30,0x82,0x03,0x02,0x30,0x82,0x02,0x6B,0x02,0x10,0x7D,0xD9,0xFE,0x07,0xCF,0xA8, -0x1E,0xB7,0x10,0x79,0x67,0xFB,0xA7,0x89,0x34,0xC6,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0xC1,0x31,0x0B,0x30,0x09, -0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55, -0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E, -0x63,0x2E,0x31,0x3C,0x30,0x3A,0x06,0x03,0x55,0x04,0x0B,0x13,0x33,0x43,0x6C,0x61, -0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D, -0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F, -0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x32, -0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x31, -0x39,0x39,0x38,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E, -0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69, -0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x1F,0x30,0x1D, -0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20, -0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x30,0x1E,0x17, -0x0D,0x39,0x38,0x30,0x35,0x31,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D, -0x32,0x38,0x30,0x38,0x30,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xC1, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30, -0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, -0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x3C,0x30,0x3A,0x06,0x03,0x55,0x04,0x0B,0x13, -0x33,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20, -0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, -0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20, -0x2D,0x20,0x47,0x32,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28, -0x63,0x29,0x20,0x31,0x39,0x39,0x38,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, -0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74, -0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79, -0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65,0x72,0x69,0x53, -0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72, -0x6B,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, -0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xCC,0x5E, -0xD1,0x11,0x5D,0x5C,0x69,0xD0,0xAB,0xD3,0xB9,0x6A,0x4C,0x99,0x1F,0x59,0x98,0x30, -0x8E,0x16,0x85,0x20,0x46,0x6D,0x47,0x3F,0xD4,0x85,0x20,0x84,0xE1,0x6D,0xB3,0xF8, -0xA4,0xED,0x0C,0xF1,0x17,0x0F,0x3B,0xF9,0xA7,0xF9,0x25,0xD7,0xC1,0xCF,0x84,0x63, -0xF2,0x7C,0x63,0xCF,0xA2,0x47,0xF2,0xC6,0x5B,0x33,0x8E,0x64,0x40,0x04,0x68,0xC1, -0x80,0xB9,0x64,0x1C,0x45,0x77,0xC7,0xD8,0x6E,0xF5,0x95,0x29,0x3C,0x50,0xE8,0x34, -0xD7,0x78,0x1F,0xA8,0xBA,0x6D,0x43,0x91,0x95,0x8F,0x45,0x57,0x5E,0x7E,0xC5,0xFB, -0xCA,0xA4,0x04,0xEB,0xEA,0x97,0x37,0x54,0x30,0x6F,0xBB,0x01,0x47,0x32,0x33,0xCD, -0xDC,0x57,0x9B,0x64,0x69,0x61,0xF8,0x9B,0x1D,0x1C,0x89,0x4F,0x5C,0x67,0x02,0x03, -0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x03,0x81,0x81,0x00,0x51,0x4D,0xCD,0xBE,0x5C,0xCB,0x98,0x19,0x9C,0x15, -0xB2,0x01,0x39,0x78,0x2E,0x4D,0x0F,0x67,0x70,0x70,0x99,0xC6,0x10,0x5A,0x94,0xA4, -0x53,0x4D,0x54,0x6D,0x2B,0xAF,0x0D,0x5D,0x40,0x8B,0x64,0xD3,0xD7,0xEE,0xDE,0x56, -0x61,0x92,0x5F,0xA6,0xC4,0x1D,0x10,0x61,0x36,0xD3,0x2C,0x27,0x3C,0xE8,0x29,0x09, -0xB9,0x11,0x64,0x74,0xCC,0xB5,0x73,0x9F,0x1C,0x48,0xA9,0xBC,0x61,0x01,0xEE,0xE2, -0x17,0xA6,0x0C,0xE3,0x40,0x08,0x3B,0x0E,0xE7,0xEB,0x44,0x73,0x2A,0x9A,0xF1,0x69, -0x92,0xEF,0x71,0x14,0xC3,0x39,0xAC,0x71,0xA7,0x91,0x09,0x6F,0xE4,0x71,0x06,0xB3, -0xBA,0x59,0x57,0x26,0x79,0x00,0xF6,0xF8,0x0D,0xA2,0x33,0x30,0x28,0xD4,0xAA,0x58, -0xA0,0x9D,0x9D,0x69,0x91,0xFD, -}; - - -/* subject:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 1999 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G3 */ -/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 1999 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G3 */ - - -const unsigned char Verisign_Class_3_Public_Primary_Certification_Authority___G3_certificate[1054]={ -0x30,0x82,0x04,0x1A,0x30,0x82,0x03,0x02,0x02,0x11,0x00,0x9B,0x7E,0x06,0x49,0xA3, -0x3E,0x62,0xB9,0xD5,0xEE,0x90,0x48,0x71,0x29,0xEF,0x57,0x30,0x0D,0x06,0x09,0x2A, -0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0xCA,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03, -0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49, -0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65, -0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74, -0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28, -0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, -0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74, -0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79, -0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69,0x53, -0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C, -0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x39,0x39,0x31,0x30,0x30, -0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x36,0x30,0x37,0x31,0x36, -0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xCA,0x31,0x0B,0x30,0x09,0x06,0x03, -0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A, -0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E, -0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65,0x72,0x69,0x53, -0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72, -0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28,0x63,0x29,0x20, -0x31,0x39,0x39,0x39,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49, -0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72, -0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30, -0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, -0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20, -0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, -0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20, -0x2D,0x20,0x47,0x33,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A, -0x02,0x82,0x01,0x01,0x00,0xCB,0xBA,0x9C,0x52,0xFC,0x78,0x1F,0x1A,0x1E,0x6F,0x1B, -0x37,0x73,0xBD,0xF8,0xC9,0x6B,0x94,0x12,0x30,0x4F,0xF0,0x36,0x47,0xF5,0xD0,0x91, -0x0A,0xF5,0x17,0xC8,0xA5,0x61,0xC1,0x16,0x40,0x4D,0xFB,0x8A,0x61,0x90,0xE5,0x76, -0x20,0xC1,0x11,0x06,0x7D,0xAB,0x2C,0x6E,0xA6,0xF5,0x11,0x41,0x8E,0xFA,0x2D,0xAD, -0x2A,0x61,0x59,0xA4,0x67,0x26,0x4C,0xD0,0xE8,0xBC,0x52,0x5B,0x70,0x20,0x04,0x58, -0xD1,0x7A,0xC9,0xA4,0x69,0xBC,0x83,0x17,0x64,0xAD,0x05,0x8B,0xBC,0xD0,0x58,0xCE, -0x8D,0x8C,0xF5,0xEB,0xF0,0x42,0x49,0x0B,0x9D,0x97,0x27,0x67,0x32,0x6E,0xE1,0xAE, -0x93,0x15,0x1C,0x70,0xBC,0x20,0x4D,0x2F,0x18,0xDE,0x92,0x88,0xE8,0x6C,0x85,0x57, -0x11,0x1A,0xE9,0x7E,0xE3,0x26,0x11,0x54,0xA2,0x45,0x96,0x55,0x83,0xCA,0x30,0x89, -0xE8,0xDC,0xD8,0xA3,0xED,0x2A,0x80,0x3F,0x7F,0x79,0x65,0x57,0x3E,0x15,0x20,0x66, -0x08,0x2F,0x95,0x93,0xBF,0xAA,0x47,0x2F,0xA8,0x46,0x97,0xF0,0x12,0xE2,0xFE,0xC2, -0x0A,0x2B,0x51,0xE6,0x76,0xE6,0xB7,0x46,0xB7,0xE2,0x0D,0xA6,0xCC,0xA8,0xC3,0x4C, -0x59,0x55,0x89,0xE6,0xE8,0x53,0x5C,0x1C,0xEA,0x9D,0xF0,0x62,0x16,0x0B,0xA7,0xC9, -0x5F,0x0C,0xF0,0xDE,0xC2,0x76,0xCE,0xAF,0xF7,0x6A,0xF2,0xFA,0x41,0xA6,0xA2,0x33, -0x14,0xC9,0xE5,0x7A,0x63,0xD3,0x9E,0x62,0x37,0xD5,0x85,0x65,0x9E,0x0E,0xE6,0x53, -0x24,0x74,0x1B,0x5E,0x1D,0x12,0x53,0x5B,0xC7,0x2C,0xE7,0x83,0x49,0x3B,0x15,0xAE, -0x8A,0x68,0xB9,0x57,0x97,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x11,0x14, -0x96,0xC1,0xAB,0x92,0x08,0xF7,0x3F,0x2F,0xC9,0xB2,0xFE,0xE4,0x5A,0x9F,0x64,0xDE, -0xDB,0x21,0x4F,0x86,0x99,0x34,0x76,0x36,0x57,0xDD,0xD0,0x15,0x2F,0xC5,0xAD,0x7F, -0x15,0x1F,0x37,0x62,0x73,0x3E,0xD4,0xE7,0x5F,0xCE,0x17,0x03,0xDB,0x35,0xFA,0x2B, -0xDB,0xAE,0x60,0x09,0x5F,0x1E,0x5F,0x8F,0x6E,0xBB,0x0B,0x3D,0xEA,0x5A,0x13,0x1E, -0x0C,0x60,0x6F,0xB5,0xC0,0xB5,0x23,0x22,0x2E,0x07,0x0B,0xCB,0xA9,0x74,0xCB,0x47, -0xBB,0x1D,0xC1,0xD7,0xA5,0x6B,0xCC,0x2F,0xD2,0x42,0xFD,0x49,0xDD,0xA7,0x89,0xCF, -0x53,0xBA,0xDA,0x00,0x5A,0x28,0xBF,0x82,0xDF,0xF8,0xBA,0x13,0x1D,0x50,0x86,0x82, -0xFD,0x8E,0x30,0x8F,0x29,0x46,0xB0,0x1E,0x3D,0x35,0xDA,0x38,0x62,0x16,0x18,0x4A, -0xAD,0xE6,0xB6,0x51,0x6C,0xDE,0xAF,0x62,0xEB,0x01,0xD0,0x1E,0x24,0xFE,0x7A,0x8F, -0x12,0x1A,0x12,0x68,0xB8,0xFB,0x66,0x99,0x14,0x14,0x45,0x5C,0xAE,0xE7,0xAE,0x69, -0x17,0x81,0x2B,0x5A,0x37,0xC9,0x5E,0x2A,0xF4,0xC6,0xE2,0xA1,0x5C,0x54,0x9B,0xA6, -0x54,0x00,0xCF,0xF0,0xF1,0xC1,0xC7,0x98,0x30,0x1A,0x3B,0x36,0x16,0xDB,0xA3,0x6E, -0xEA,0xFD,0xAD,0xB2,0xC2,0xDA,0xEF,0x02,0x47,0x13,0x8A,0xC0,0xF1,0xB3,0x31,0xAD, -0x4F,0x1C,0xE1,0x4F,0x9C,0xAF,0x0F,0x0C,0x9D,0xF7,0x78,0x0D,0xD8,0xF4,0x35,0x56, -0x80,0xDA,0xB7,0x6D,0x17,0x8F,0x9D,0x1E,0x81,0x64,0xE1,0xFE,0xC5,0x45,0xBA,0xAD, -0x6B,0xB9,0x0A,0x7A,0x4E,0x4F,0x4B,0x84,0xEE,0x4B,0xF1,0x7D,0xDD,0x11, -}; - - -/* subject:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2007 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G4 */ -/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2007 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G4 */ - - -const unsigned char VeriSign_Class_3_Public_Primary_Certification_Authority___G4_certificate[904]={ -0x30,0x82,0x03,0x84,0x30,0x82,0x03,0x0A,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x2F, -0x80,0xFE,0x23,0x8C,0x0E,0x22,0x0F,0x48,0x67,0x12,0x28,0x91,0x87,0xAC,0xB3,0x30, -0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x30,0x81,0xCA,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20, -0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56, -0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65, -0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31, -0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x37,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67, -0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75, -0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C, -0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69, -0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62, -0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, -0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x34,0x30,0x1E,0x17,0x0D,0x30,0x37,0x31,0x31, -0x30,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31, -0x38,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xCA,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04, -0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63, -0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65,0x72,0x69, -0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F, -0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28,0x63,0x29, -0x20,0x32,0x30,0x30,0x37,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20, -0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F, -0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x45, -0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69,0x53,0x69,0x67, -0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63, -0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69, -0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79, -0x20,0x2D,0x20,0x47,0x34,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, -0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0xA7,0x56,0x7A, -0x7C,0x52,0xDA,0x64,0x9B,0x0E,0x2D,0x5C,0xD8,0x5E,0xAC,0x92,0x3D,0xFE,0x01,0xE6, -0x19,0x4A,0x3D,0x14,0x03,0x4B,0xFA,0x60,0x27,0x20,0xD9,0x83,0x89,0x69,0xFA,0x54, -0xC6,0x9A,0x18,0x5E,0x55,0x2A,0x64,0xDE,0x06,0xF6,0x8D,0x4A,0x3B,0xAD,0x10,0x3C, -0x65,0x3D,0x90,0x88,0x04,0x89,0xE0,0x30,0x61,0xB3,0xAE,0x5D,0x01,0xA7,0x7B,0xDE, -0x7C,0xB2,0xBE,0xCA,0x65,0x61,0x00,0x86,0xAE,0xDA,0x8F,0x7B,0xD0,0x89,0xAD,0x4D, -0x1D,0x59,0x9A,0x41,0xB1,0xBC,0x47,0x80,0xDC,0x9E,0x62,0xC3,0xF9,0xA3,0x81,0xB2, -0x30,0x81,0xAF,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, -0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, -0x03,0x02,0x01,0x06,0x30,0x6D,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0C, -0x04,0x61,0x30,0x5F,0xA1,0x5D,0xA0,0x5B,0x30,0x59,0x30,0x57,0x30,0x55,0x16,0x09, -0x69,0x6D,0x61,0x67,0x65,0x2F,0x67,0x69,0x66,0x30,0x21,0x30,0x1F,0x30,0x07,0x06, -0x05,0x2B,0x0E,0x03,0x02,0x1A,0x04,0x14,0x8F,0xE5,0xD3,0x1A,0x86,0xAC,0x8D,0x8E, -0x6B,0xC3,0xCF,0x80,0x6A,0xD4,0x48,0x18,0x2C,0x7B,0x19,0x2E,0x30,0x25,0x16,0x23, -0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6C,0x6F,0x67,0x6F,0x2E,0x76,0x65,0x72,0x69, -0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x76,0x73,0x6C,0x6F,0x67,0x6F,0x2E, -0x67,0x69,0x66,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xB3,0x16, -0x91,0xFD,0xEE,0xA6,0x6E,0xE4,0xB5,0x2E,0x49,0x8F,0x87,0x78,0x81,0x80,0xEC,0xE5, -0xB1,0xB5,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x03,0x68, -0x00,0x30,0x65,0x02,0x30,0x66,0x21,0x0C,0x18,0x26,0x60,0x5A,0x38,0x7B,0x56,0x42, -0xE0,0xA7,0xFC,0x36,0x84,0x51,0x91,0x20,0x2C,0x76,0x4D,0x43,0x3D,0xC4,0x1D,0x84, -0x23,0xD0,0xAC,0xD6,0x7C,0x35,0x06,0xCE,0xCD,0x69,0xBD,0x90,0x0D,0xDB,0x6C,0x48, -0x42,0x1D,0x0E,0xAA,0x42,0x02,0x31,0x00,0x9C,0x3D,0x48,0x39,0x23,0x39,0x58,0x1A, -0x15,0x12,0x59,0x6A,0x9E,0xEF,0xD5,0x59,0xB2,0x1D,0x52,0x2C,0x99,0x71,0xCD,0xC7, -0x29,0xDF,0x1B,0x2A,0x61,0x7B,0x71,0xD1,0xDE,0xF3,0xC0,0xE5,0x0D,0x3A,0x4A,0xAA, -0x2D,0xA7,0xD8,0x86,0x2A,0xDD,0x2E,0x10, -}; - - -/* subject:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */ -/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */ - - -const unsigned char VeriSign_Class_3_Public_Primary_Certification_Authority___G5_certificate[1239]={ -0x30,0x82,0x04,0xD3,0x30,0x82,0x03,0xBB,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x18, -0xDA,0xD1,0x9E,0x26,0x7D,0xE8,0xBB,0x4A,0x21,0x58,0xCD,0xCC,0x6B,0x3B,0x4A,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, -0xCA,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, -0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67, -0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B, -0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74, -0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04, -0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69, -0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72, -0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20, -0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56, -0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20, -0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43, -0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74, -0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x35,0x30,0x1E,0x17,0x0D,0x30, -0x36,0x31,0x31,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x36, -0x30,0x37,0x31,0x36,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xCA,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06, -0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20, -0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56, -0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65, -0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31, -0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67, -0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75, -0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C, -0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69, -0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62, -0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, -0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x35,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00, -0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xAF,0x24,0x08,0x08,0x29,0x7A,0x35, -0x9E,0x60,0x0C,0xAA,0xE7,0x4B,0x3B,0x4E,0xDC,0x7C,0xBC,0x3C,0x45,0x1C,0xBB,0x2B, -0xE0,0xFE,0x29,0x02,0xF9,0x57,0x08,0xA3,0x64,0x85,0x15,0x27,0xF5,0xF1,0xAD,0xC8, -0x31,0x89,0x5D,0x22,0xE8,0x2A,0xAA,0xA6,0x42,0xB3,0x8F,0xF8,0xB9,0x55,0xB7,0xB1, -0xB7,0x4B,0xB3,0xFE,0x8F,0x7E,0x07,0x57,0xEC,0xEF,0x43,0xDB,0x66,0x62,0x15,0x61, -0xCF,0x60,0x0D,0xA4,0xD8,0xDE,0xF8,0xE0,0xC3,0x62,0x08,0x3D,0x54,0x13,0xEB,0x49, -0xCA,0x59,0x54,0x85,0x26,0xE5,0x2B,0x8F,0x1B,0x9F,0xEB,0xF5,0xA1,0x91,0xC2,0x33, -0x49,0xD8,0x43,0x63,0x6A,0x52,0x4B,0xD2,0x8F,0xE8,0x70,0x51,0x4D,0xD1,0x89,0x69, -0x7B,0xC7,0x70,0xF6,0xB3,0xDC,0x12,0x74,0xDB,0x7B,0x5D,0x4B,0x56,0xD3,0x96,0xBF, -0x15,0x77,0xA1,0xB0,0xF4,0xA2,0x25,0xF2,0xAF,0x1C,0x92,0x67,0x18,0xE5,0xF4,0x06, -0x04,0xEF,0x90,0xB9,0xE4,0x00,0xE4,0xDD,0x3A,0xB5,0x19,0xFF,0x02,0xBA,0xF4,0x3C, -0xEE,0xE0,0x8B,0xEB,0x37,0x8B,0xEC,0xF4,0xD7,0xAC,0xF2,0xF6,0xF0,0x3D,0xAF,0xDD, -0x75,0x91,0x33,0x19,0x1D,0x1C,0x40,0xCB,0x74,0x24,0x19,0x21,0x93,0xD9,0x14,0xFE, -0xAC,0x2A,0x52,0xC7,0x8F,0xD5,0x04,0x49,0xE4,0x8D,0x63,0x47,0x88,0x3C,0x69,0x83, -0xCB,0xFE,0x47,0xBD,0x2B,0x7E,0x4F,0xC5,0x95,0xAE,0x0E,0x9D,0xD4,0xD1,0x43,0xC0, -0x67,0x73,0xE3,0x14,0x08,0x7E,0xE5,0x3F,0x9F,0x73,0xB8,0x33,0x0A,0xCF,0x5D,0x3F, -0x34,0x87,0x96,0x8A,0xEE,0x53,0xE8,0x25,0x15,0x02,0x03,0x01,0x00,0x01,0xA3,0x81, -0xB2,0x30,0x81,0xAF,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05, -0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04, -0x04,0x03,0x02,0x01,0x06,0x30,0x6D,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01, -0x0C,0x04,0x61,0x30,0x5F,0xA1,0x5D,0xA0,0x5B,0x30,0x59,0x30,0x57,0x30,0x55,0x16, -0x09,0x69,0x6D,0x61,0x67,0x65,0x2F,0x67,0x69,0x66,0x30,0x21,0x30,0x1F,0x30,0x07, -0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x04,0x14,0x8F,0xE5,0xD3,0x1A,0x86,0xAC,0x8D, -0x8E,0x6B,0xC3,0xCF,0x80,0x6A,0xD4,0x48,0x18,0x2C,0x7B,0x19,0x2E,0x30,0x25,0x16, -0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6C,0x6F,0x67,0x6F,0x2E,0x76,0x65,0x72, -0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x76,0x73,0x6C,0x6F,0x67,0x6F, -0x2E,0x67,0x69,0x66,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x7F, -0xD3,0x65,0xA7,0xC2,0xDD,0xEC,0xBB,0xF0,0x30,0x09,0xF3,0x43,0x39,0xFA,0x02,0xAF, -0x33,0x31,0x33,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x93,0x24,0x4A,0x30,0x5F,0x62,0xCF,0xD8,0x1A, -0x98,0x2F,0x3D,0xEA,0xDC,0x99,0x2D,0xBD,0x77,0xF6,0xA5,0x79,0x22,0x38,0xEC,0xC4, -0xA7,0xA0,0x78,0x12,0xAD,0x62,0x0E,0x45,0x70,0x64,0xC5,0xE7,0x97,0x66,0x2D,0x98, -0x09,0x7E,0x5F,0xAF,0xD6,0xCC,0x28,0x65,0xF2,0x01,0xAA,0x08,0x1A,0x47,0xDE,0xF9, -0xF9,0x7C,0x92,0x5A,0x08,0x69,0x20,0x0D,0xD9,0x3E,0x6D,0x6E,0x3C,0x0D,0x6E,0xD8, -0xE6,0x06,0x91,0x40,0x18,0xB9,0xF8,0xC1,0xED,0xDF,0xDB,0x41,0xAA,0xE0,0x96,0x20, -0xC9,0xCD,0x64,0x15,0x38,0x81,0xC9,0x94,0xEE,0xA2,0x84,0x29,0x0B,0x13,0x6F,0x8E, -0xDB,0x0C,0xDD,0x25,0x02,0xDB,0xA4,0x8B,0x19,0x44,0xD2,0x41,0x7A,0x05,0x69,0x4A, -0x58,0x4F,0x60,0xCA,0x7E,0x82,0x6A,0x0B,0x02,0xAA,0x25,0x17,0x39,0xB5,0xDB,0x7F, -0xE7,0x84,0x65,0x2A,0x95,0x8A,0xBD,0x86,0xDE,0x5E,0x81,0x16,0x83,0x2D,0x10,0xCC, -0xDE,0xFD,0xA8,0x82,0x2A,0x6D,0x28,0x1F,0x0D,0x0B,0xC4,0xE5,0xE7,0x1A,0x26,0x19, -0xE1,0xF4,0x11,0x6F,0x10,0xB5,0x95,0xFC,0xE7,0x42,0x05,0x32,0xDB,0xCE,0x9D,0x51, -0x5E,0x28,0xB6,0x9E,0x85,0xD3,0x5B,0xEF,0xA5,0x7D,0x45,0x40,0x72,0x8E,0xB7,0x0E, -0x6B,0x0E,0x06,0xFB,0x33,0x35,0x48,0x71,0xB8,0x9D,0x27,0x8B,0xC4,0x65,0x5F,0x0D, -0x86,0x76,0x9C,0x44,0x7A,0xF6,0x95,0x5C,0xF6,0x5D,0x32,0x08,0x33,0xA4,0x54,0xB6, -0x18,0x3F,0x68,0x5C,0xF2,0x42,0x4A,0x85,0x38,0x54,0x83,0x5F,0xD1,0xE8,0x2C,0xF2, -0xAC,0x11,0xD6,0xA8,0xED,0x63,0x6A, -}; - - -/* subject:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 1999 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 4 Public Primary Certification Authority - G3 */ -/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 1999 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 4 Public Primary Certification Authority - G3 */ - - -const unsigned char Verisign_Class_4_Public_Primary_Certification_Authority___G3_certificate[1054]={ -0x30,0x82,0x04,0x1A,0x30,0x82,0x03,0x02,0x02,0x11,0x00,0xEC,0xA0,0xA7,0x8B,0x6E, -0x75,0x6A,0x01,0xCF,0xC4,0x7C,0xCC,0x2F,0x94,0x5E,0xD7,0x30,0x0D,0x06,0x09,0x2A, -0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0xCA,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03, -0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49, -0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65, -0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74, -0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28, -0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, -0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74, -0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79, -0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69,0x53, -0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x34,0x20,0x50,0x75,0x62,0x6C, -0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x39,0x39,0x31,0x30,0x30, -0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x36,0x30,0x37,0x31,0x36, -0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xCA,0x31,0x0B,0x30,0x09,0x06,0x03, -0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A, -0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E, -0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65,0x72,0x69,0x53, -0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72, -0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28,0x63,0x29,0x20, -0x31,0x39,0x39,0x39,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49, -0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72, -0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30, -0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, -0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x34,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20, -0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, -0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20, -0x2D,0x20,0x47,0x33,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, -0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A, -0x02,0x82,0x01,0x01,0x00,0xAD,0xCB,0xA5,0x11,0x69,0xC6,0x59,0xAB,0xF1,0x8F,0xB5, -0x19,0x0F,0x56,0xCE,0xCC,0xB5,0x1F,0x20,0xE4,0x9E,0x26,0x25,0x4B,0xE0,0x73,0x65, -0x89,0x59,0xDE,0xD0,0x83,0xE4,0xF5,0x0F,0xB5,0xBB,0xAD,0xF1,0x7C,0xE8,0x21,0xFC, -0xE4,0xE8,0x0C,0xEE,0x7C,0x45,0x22,0x19,0x76,0x92,0xB4,0x13,0xB7,0x20,0x5B,0x09, -0xFA,0x61,0xAE,0xA8,0xF2,0xA5,0x8D,0x85,0xC2,0x2A,0xD6,0xDE,0x66,0x36,0xD2,0x9B, -0x02,0xF4,0xA8,0x92,0x60,0x7C,0x9C,0x69,0xB4,0x8F,0x24,0x1E,0xD0,0x86,0x52,0xF6, -0x32,0x9C,0x41,0x58,0x1E,0x22,0xBD,0xCD,0x45,0x62,0x95,0x08,0x6E,0xD0,0x66,0xDD, -0x53,0xA2,0xCC,0xF0,0x10,0xDC,0x54,0x73,0x8B,0x04,0xA1,0x46,0x33,0x33,0x5C,0x17, -0x40,0xB9,0x9E,0x4D,0xD3,0xF3,0xBE,0x55,0x83,0xE8,0xB1,0x89,0x8E,0x5A,0x7C,0x9A, -0x96,0x22,0x90,0x3B,0x88,0x25,0xF2,0xD2,0x53,0x88,0x02,0x0C,0x0B,0x78,0xF2,0xE6, -0x37,0x17,0x4B,0x30,0x46,0x07,0xE4,0x80,0x6D,0xA6,0xD8,0x96,0x2E,0xE8,0x2C,0xF8, -0x11,0xB3,0x38,0x0D,0x66,0xA6,0x9B,0xEA,0xC9,0x23,0x5B,0xDB,0x8E,0xE2,0xF3,0x13, -0x8E,0x1A,0x59,0x2D,0xAA,0x02,0xF0,0xEC,0xA4,0x87,0x66,0xDC,0xC1,0x3F,0xF5,0xD8, -0xB9,0xF4,0xEC,0x82,0xC6,0xD2,0x3D,0x95,0x1D,0xE5,0xC0,0x4F,0x84,0xC9,0xD9,0xA3, -0x44,0x28,0x06,0x6A,0xD7,0x45,0xAC,0xF0,0x6B,0x6A,0xEF,0x4E,0x5F,0xF8,0x11,0x82, -0x1E,0x38,0x63,0x34,0x66,0x50,0xD4,0x3E,0x93,0x73,0xFA,0x30,0xC3,0x66,0xAD,0xFF, -0x93,0x2D,0x97,0xEF,0x03,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86, -0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x8F,0xFA, -0x25,0x6B,0x4F,0x5B,0xE4,0xA4,0x4E,0x27,0x55,0xAB,0x22,0x15,0x59,0x3C,0xCA,0xB5, -0x0A,0xD4,0x4A,0xDB,0xAB,0xDD,0xA1,0x5F,0x53,0xC5,0xA0,0x57,0x39,0xC2,0xCE,0x47, -0x2B,0xBE,0x3A,0xC8,0x56,0xBF,0xC2,0xD9,0x27,0x10,0x3A,0xB1,0x05,0x3C,0xC0,0x77, -0x31,0xBB,0x3A,0xD3,0x05,0x7B,0x6D,0x9A,0x1C,0x30,0x8C,0x80,0xCB,0x93,0x93,0x2A, -0x83,0xAB,0x05,0x51,0x82,0x02,0x00,0x11,0x67,0x6B,0xF3,0x88,0x61,0x47,0x5F,0x03, -0x93,0xD5,0x5B,0x0D,0xE0,0xF1,0xD4,0xA1,0x32,0x35,0x85,0xB2,0x3A,0xDB,0xB0,0x82, -0xAB,0xD1,0xCB,0x0A,0xBC,0x4F,0x8C,0x5B,0xC5,0x4B,0x00,0x3B,0x1F,0x2A,0x82,0xA6, -0x7E,0x36,0x85,0xDC,0x7E,0x3C,0x67,0x00,0xB5,0xE4,0x3B,0x52,0xE0,0xA8,0xEB,0x5D, -0x15,0xF9,0xC6,0x6D,0xF0,0xAD,0x1D,0x0E,0x85,0xB7,0xA9,0x9A,0x73,0x14,0x5A,0x5B, -0x8F,0x41,0x28,0xC0,0xD5,0xE8,0x2D,0x4D,0xA4,0x5E,0xCD,0xAA,0xD9,0xED,0xCE,0xDC, -0xD8,0xD5,0x3C,0x42,0x1D,0x17,0xC1,0x12,0x5D,0x45,0x38,0xC3,0x38,0xF3,0xFC,0x85, -0x2E,0x83,0x46,0x48,0xB2,0xD7,0x20,0x5F,0x92,0x36,0x8F,0xE7,0x79,0x0F,0x98,0x5E, -0x99,0xE8,0xF0,0xD0,0xA4,0xBB,0xF5,0x53,0xBD,0x2A,0xCE,0x59,0xB0,0xAF,0x6E,0x7F, -0x6C,0xBB,0xD2,0x1E,0x00,0xB0,0x21,0xED,0xF8,0x41,0x62,0x82,0xB9,0xD8,0xB2,0xC4, -0xBB,0x46,0x50,0xF3,0x31,0xC5,0x8F,0x01,0xA8,0x74,0xEB,0xF5,0x78,0x27,0xDA,0xE7, -0xF7,0x66,0x43,0xF3,0x9E,0x83,0x3E,0x20,0xAA,0xC3,0x35,0x60,0x91,0xCE, -}; - - -/* subject:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2008 VeriSign, Inc. - For authorized use only/CN=VeriSign Universal Root Certification Authority */ -/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2008 VeriSign, Inc. - For authorized use only/CN=VeriSign Universal Root Certification Authority */ - - -const unsigned char VeriSign_Universal_Root_Certification_Authority_certificate[1213]={ -0x30,0x82,0x04,0xB9,0x30,0x82,0x03,0xA1,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x40, -0x1A,0xC4,0x64,0x21,0xB3,0x13,0x21,0x03,0x0E,0xBB,0xE4,0x12,0x1A,0xC5,0x1D,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, -0xBD,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, -0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67, -0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B, -0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74, -0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04, -0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x38,0x20,0x56,0x65,0x72,0x69, -0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72, -0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20, -0x6F,0x6E,0x6C,0x79,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2F,0x56, -0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61, -0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, -0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E, -0x17,0x0D,0x30,0x38,0x30,0x34,0x30,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17, -0x0D,0x33,0x37,0x31,0x32,0x30,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81, -0xBD,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, -0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67, -0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B, -0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74, -0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04, -0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x38,0x20,0x56,0x65,0x72,0x69, -0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72, -0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20, -0x6F,0x6E,0x6C,0x79,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2F,0x56, -0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61, -0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, -0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82, -0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05, -0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xC7, -0x61,0x37,0x5E,0xB1,0x01,0x34,0xDB,0x62,0xD7,0x15,0x9B,0xFF,0x58,0x5A,0x8C,0x23, -0x23,0xD6,0x60,0x8E,0x91,0xD7,0x90,0x98,0x83,0x7A,0xE6,0x58,0x19,0x38,0x8C,0xC5, -0xF6,0xE5,0x64,0x85,0xB4,0xA2,0x71,0xFB,0xED,0xBD,0xB9,0xDA,0xCD,0x4D,0x00,0xB4, -0xC8,0x2D,0x73,0xA5,0xC7,0x69,0x71,0x95,0x1F,0x39,0x3C,0xB2,0x44,0x07,0x9C,0xE8, -0x0E,0xFA,0x4D,0x4A,0xC4,0x21,0xDF,0x29,0x61,0x8F,0x32,0x22,0x61,0x82,0xC5,0x87, -0x1F,0x6E,0x8C,0x7C,0x5F,0x16,0x20,0x51,0x44,0xD1,0x70,0x4F,0x57,0xEA,0xE3,0x1C, -0xE3,0xCC,0x79,0xEE,0x58,0xD8,0x0E,0xC2,0xB3,0x45,0x93,0xC0,0x2C,0xE7,0x9A,0x17, -0x2B,0x7B,0x00,0x37,0x7A,0x41,0x33,0x78,0xE1,0x33,0xE2,0xF3,0x10,0x1A,0x7F,0x87, -0x2C,0xBE,0xF6,0xF5,0xF7,0x42,0xE2,0xE5,0xBF,0x87,0x62,0x89,0x5F,0x00,0x4B,0xDF, -0xC5,0xDD,0xE4,0x75,0x44,0x32,0x41,0x3A,0x1E,0x71,0x6E,0x69,0xCB,0x0B,0x75,0x46, -0x08,0xD1,0xCA,0xD2,0x2B,0x95,0xD0,0xCF,0xFB,0xB9,0x40,0x6B,0x64,0x8C,0x57,0x4D, -0xFC,0x13,0x11,0x79,0x84,0xED,0x5E,0x54,0xF6,0x34,0x9F,0x08,0x01,0xF3,0x10,0x25, -0x06,0x17,0x4A,0xDA,0xF1,0x1D,0x7A,0x66,0x6B,0x98,0x60,0x66,0xA4,0xD9,0xEF,0xD2, -0x2E,0x82,0xF1,0xF0,0xEF,0x09,0xEA,0x44,0xC9,0x15,0x6A,0xE2,0x03,0x6E,0x33,0xD3, -0xAC,0x9F,0x55,0x00,0xC7,0xF6,0x08,0x6A,0x94,0xB9,0x5F,0xDC,0xE0,0x33,0xF1,0x84, -0x60,0xF9,0x5B,0x27,0x11,0xB4,0xFC,0x16,0xF2,0xBB,0x56,0x6A,0x80,0x25,0x8D,0x02, -0x03,0x01,0x00,0x01,0xA3,0x81,0xB2,0x30,0x81,0xAF,0x30,0x0F,0x06,0x03,0x55,0x1D, -0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55, -0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x6D,0x06,0x08,0x2B, -0x06,0x01,0x05,0x05,0x07,0x01,0x0C,0x04,0x61,0x30,0x5F,0xA1,0x5D,0xA0,0x5B,0x30, -0x59,0x30,0x57,0x30,0x55,0x16,0x09,0x69,0x6D,0x61,0x67,0x65,0x2F,0x67,0x69,0x66, -0x30,0x21,0x30,0x1F,0x30,0x07,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x04,0x14,0x8F, -0xE5,0xD3,0x1A,0x86,0xAC,0x8D,0x8E,0x6B,0xC3,0xCF,0x80,0x6A,0xD4,0x48,0x18,0x2C, -0x7B,0x19,0x2E,0x30,0x25,0x16,0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6C,0x6F, -0x67,0x6F,0x2E,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F, -0x76,0x73,0x6C,0x6F,0x67,0x6F,0x2E,0x67,0x69,0x66,0x30,0x1D,0x06,0x03,0x55,0x1D, -0x0E,0x04,0x16,0x04,0x14,0xB6,0x77,0xFA,0x69,0x48,0x47,0x9F,0x53,0x12,0xD5,0xC2, -0xEA,0x07,0x32,0x76,0x07,0xD1,0x97,0x07,0x19,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, -0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x4A,0xF8,0xF8, -0xB0,0x03,0xE6,0x2C,0x67,0x7B,0xE4,0x94,0x77,0x63,0xCC,0x6E,0x4C,0xF9,0x7D,0x0E, -0x0D,0xDC,0xC8,0xB9,0x35,0xB9,0x70,0x4F,0x63,0xFA,0x24,0xFA,0x6C,0x83,0x8C,0x47, -0x9D,0x3B,0x63,0xF3,0x9A,0xF9,0x76,0x32,0x95,0x91,0xB1,0x77,0xBC,0xAC,0x9A,0xBE, -0xB1,0xE4,0x31,0x21,0xC6,0x81,0x95,0x56,0x5A,0x0E,0xB1,0xC2,0xD4,0xB1,0xA6,0x59, -0xAC,0xF1,0x63,0xCB,0xB8,0x4C,0x1D,0x59,0x90,0x4A,0xEF,0x90,0x16,0x28,0x1F,0x5A, -0xAE,0x10,0xFB,0x81,0x50,0x38,0x0C,0x6C,0xCC,0xF1,0x3D,0xC3,0xF5,0x63,0xE3,0xB3, -0xE3,0x21,0xC9,0x24,0x39,0xE9,0xFD,0x15,0x66,0x46,0xF4,0x1B,0x11,0xD0,0x4D,0x73, -0xA3,0x7D,0x46,0xF9,0x3D,0xED,0xA8,0x5F,0x62,0xD4,0xF1,0x3F,0xF8,0xE0,0x74,0x57, -0x2B,0x18,0x9D,0x81,0xB4,0xC4,0x28,0xDA,0x94,0x97,0xA5,0x70,0xEB,0xAC,0x1D,0xBE, -0x07,0x11,0xF0,0xD5,0xDB,0xDD,0xE5,0x8C,0xF0,0xD5,0x32,0xB0,0x83,0xE6,0x57,0xE2, -0x8F,0xBF,0xBE,0xA1,0xAA,0xBF,0x3D,0x1D,0xB5,0xD4,0x38,0xEA,0xD7,0xB0,0x5C,0x3A, -0x4F,0x6A,0x3F,0x8F,0xC0,0x66,0x6C,0x63,0xAA,0xE9,0xD9,0xA4,0x16,0xF4,0x81,0xD1, -0x95,0x14,0x0E,0x7D,0xCD,0x95,0x34,0xD9,0xD2,0x8F,0x70,0x73,0x81,0x7B,0x9C,0x7E, -0xBD,0x98,0x61,0xD8,0x45,0x87,0x98,0x90,0xC5,0xEB,0x86,0x30,0xC6,0x35,0xBF,0xF0, -0xFF,0xC3,0x55,0x88,0x83,0x4B,0xEF,0x05,0x92,0x06,0x71,0xF2,0xB8,0x98,0x93,0xB7, -0xEC,0xCD,0x82,0x61,0xF1,0x38,0xE6,0x4F,0x97,0x98,0x2A,0x5A,0x8D, -}; - - -/* subject:/C=US/OU=www.xrampsecurity.com/O=XRamp Security Services Inc/CN=XRamp Global Certification Authority */ -/* issuer :/C=US/OU=www.xrampsecurity.com/O=XRamp Security Services Inc/CN=XRamp Global Certification Authority */ - - -const unsigned char XRamp_Global_CA_Root_certificate[1076]={ -0x30,0x82,0x04,0x30,0x30,0x82,0x03,0x18,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x50, -0x94,0x6C,0xEC,0x18,0xEA,0xD5,0x9C,0x4D,0xD5,0x97,0xEF,0x75,0x8F,0xA0,0xAD,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, -0x82,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1E, -0x30,0x1C,0x06,0x03,0x55,0x04,0x0B,0x13,0x15,0x77,0x77,0x77,0x2E,0x78,0x72,0x61, -0x6D,0x70,0x73,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x2E,0x63,0x6F,0x6D,0x31,0x24, -0x30,0x22,0x06,0x03,0x55,0x04,0x0A,0x13,0x1B,0x58,0x52,0x61,0x6D,0x70,0x20,0x53, -0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73, -0x20,0x49,0x6E,0x63,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x58, -0x52,0x61,0x6D,0x70,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, -0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x34,0x31,0x31,0x30,0x31,0x31,0x37,0x31, -0x34,0x30,0x34,0x5A,0x17,0x0D,0x33,0x35,0x30,0x31,0x30,0x31,0x30,0x35,0x33,0x37, -0x31,0x39,0x5A,0x30,0x81,0x82,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x55,0x53,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0B,0x13,0x15,0x77,0x77, -0x77,0x2E,0x78,0x72,0x61,0x6D,0x70,0x73,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x2E, -0x63,0x6F,0x6D,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x0A,0x13,0x1B,0x58,0x52, -0x61,0x6D,0x70,0x20,0x53,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x53,0x65,0x72, -0x76,0x69,0x63,0x65,0x73,0x20,0x49,0x6E,0x63,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55, -0x04,0x03,0x13,0x24,0x58,0x52,0x61,0x6D,0x70,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C, -0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41, -0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00, -0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0x98,0x24,0x1E,0xBD,0x15,0xB4,0xBA, -0xDF,0xC7,0x8C,0xA5,0x27,0xB6,0x38,0x0B,0x69,0xF3,0xB6,0x4E,0xA8,0x2C,0x2E,0x21, -0x1D,0x5C,0x44,0xDF,0x21,0x5D,0x7E,0x23,0x74,0xFE,0x5E,0x7E,0xB4,0x4A,0xB7,0xA6, -0xAD,0x1F,0xAE,0xE0,0x06,0x16,0xE2,0x9B,0x5B,0xD9,0x67,0x74,0x6B,0x5D,0x80,0x8F, -0x29,0x9D,0x86,0x1B,0xD9,0x9C,0x0D,0x98,0x6D,0x76,0x10,0x28,0x58,0xE4,0x65,0xB0, -0x7F,0x4A,0x98,0x79,0x9F,0xE0,0xC3,0x31,0x7E,0x80,0x2B,0xB5,0x8C,0xC0,0x40,0x3B, -0x11,0x86,0xD0,0xCB,0xA2,0x86,0x36,0x60,0xA4,0xD5,0x30,0x82,0x6D,0xD9,0x6E,0xD0, -0x0F,0x12,0x04,0x33,0x97,0x5F,0x4F,0x61,0x5A,0xF0,0xE4,0xF9,0x91,0xAB,0xE7,0x1D, -0x3B,0xBC,0xE8,0xCF,0xF4,0x6B,0x2D,0x34,0x7C,0xE2,0x48,0x61,0x1C,0x8E,0xF3,0x61, -0x44,0xCC,0x6F,0xA0,0x4A,0xA9,0x94,0xB0,0x4D,0xDA,0xE7,0xA9,0x34,0x7A,0x72,0x38, -0xA8,0x41,0xCC,0x3C,0x94,0x11,0x7D,0xEB,0xC8,0xA6,0x8C,0xB7,0x86,0xCB,0xCA,0x33, -0x3B,0xD9,0x3D,0x37,0x8B,0xFB,0x7A,0x3E,0x86,0x2C,0xE7,0x73,0xD7,0x0A,0x57,0xAC, -0x64,0x9B,0x19,0xEB,0xF4,0x0F,0x04,0x08,0x8A,0xAC,0x03,0x17,0x19,0x64,0xF4,0x5A, -0x25,0x22,0x8D,0x34,0x2C,0xB2,0xF6,0x68,0x1D,0x12,0x6D,0xD3,0x8A,0x1E,0x14,0xDA, -0xC4,0x8F,0xA6,0xE2,0x23,0x85,0xD5,0x7A,0x0D,0xBD,0x6A,0xE0,0xE9,0xEC,0xEC,0x17, -0xBB,0x42,0x1B,0x67,0xAA,0x25,0xED,0x45,0x83,0x21,0xFC,0xC1,0xC9,0x7C,0xD5,0x62, -0x3E,0xFA,0xF2,0xC5,0x2D,0xD3,0xFD,0xD4,0x65,0x02,0x03,0x01,0x00,0x01,0xA3,0x81, -0x9F,0x30,0x81,0x9C,0x30,0x13,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14, -0x02,0x04,0x06,0x1E,0x04,0x00,0x43,0x00,0x41,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F, -0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF, -0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, -0x04,0x14,0xC6,0x4F,0xA2,0x3D,0x06,0x63,0x84,0x09,0x9C,0xCE,0x62,0xE4,0x04,0xAC, -0x8D,0x5C,0xB5,0xE9,0xB6,0x1B,0x30,0x36,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2F,0x30, -0x2D,0x30,0x2B,0xA0,0x29,0xA0,0x27,0x86,0x25,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, -0x63,0x72,0x6C,0x2E,0x78,0x72,0x61,0x6D,0x70,0x73,0x65,0x63,0x75,0x72,0x69,0x74, -0x79,0x2E,0x63,0x6F,0x6D,0x2F,0x58,0x47,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x10, -0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x15,0x01,0x04,0x03,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03, -0x82,0x01,0x01,0x00,0x91,0x15,0x39,0x03,0x01,0x1B,0x67,0xFB,0x4A,0x1C,0xF9,0x0A, -0x60,0x5B,0xA1,0xDA,0x4D,0x97,0x62,0xF9,0x24,0x53,0x27,0xD7,0x82,0x64,0x4E,0x90, -0x2E,0xC3,0x49,0x1B,0x2B,0x9A,0xDC,0xFC,0xA8,0x78,0x67,0x35,0xF1,0x1D,0xF0,0x11, -0xBD,0xB7,0x48,0xE3,0x10,0xF6,0x0D,0xDF,0x3F,0xD2,0xC9,0xB6,0xAA,0x55,0xA4,0x48, -0xBA,0x02,0xDB,0xDE,0x59,0x2E,0x15,0x5B,0x3B,0x9D,0x16,0x7D,0x47,0xD7,0x37,0xEA, -0x5F,0x4D,0x76,0x12,0x36,0xBB,0x1F,0xD7,0xA1,0x81,0x04,0x46,0x20,0xA3,0x2C,0x6D, -0xA9,0x9E,0x01,0x7E,0x3F,0x29,0xCE,0x00,0x93,0xDF,0xFD,0xC9,0x92,0x73,0x89,0x89, -0x64,0x9E,0xE7,0x2B,0xE4,0x1C,0x91,0x2C,0xD2,0xB9,0xCE,0x7D,0xCE,0x6F,0x31,0x99, -0xD3,0xE6,0xBE,0xD2,0x1E,0x90,0xF0,0x09,0x14,0x79,0x5C,0x23,0xAB,0x4D,0xD2,0xDA, -0x21,0x1F,0x4D,0x99,0x79,0x9D,0xE1,0xCF,0x27,0x9F,0x10,0x9B,0x1C,0x88,0x0D,0xB0, -0x8A,0x64,0x41,0x31,0xB8,0x0E,0x6C,0x90,0x24,0xA4,0x9B,0x5C,0x71,0x8F,0xBA,0xBB, -0x7E,0x1C,0x1B,0xDB,0x6A,0x80,0x0F,0x21,0xBC,0xE9,0xDB,0xA6,0xB7,0x40,0xF4,0xB2, -0x8B,0xA9,0xB1,0xE4,0xEF,0x9A,0x1A,0xD0,0x3D,0x69,0x99,0xEE,0xA8,0x28,0xA3,0xE1, -0x3C,0xB3,0xF0,0xB2,0x11,0x9C,0xCF,0x7C,0x40,0xE6,0xDD,0xE7,0x43,0x7D,0xA2,0xD8, -0x3A,0xB5,0xA9,0x8D,0xF2,0x34,0x99,0xC4,0xD4,0x10,0xE1,0x06,0xFD,0x09,0x84,0x10, -0x3B,0xEE,0xC4,0x4C,0xF4,0xEC,0x27,0x7C,0x42,0xC2,0x74,0x7C,0x82,0x8A,0x09,0xC9, -0xB4,0x03,0x25,0xBC, -}; - - -const unsigned char* kSSLCertCertificateList[] = { - AddTrust_External_Root_certificate, - AddTrust_Low_Value_Services_Root_certificate, - AddTrust_Public_Services_Root_certificate, - AddTrust_Qualified_Certificates_Root_certificate, - AffirmTrust_Commercial_certificate, - AffirmTrust_Networking_certificate, - AffirmTrust_Premium_certificate, - AffirmTrust_Premium_ECC_certificate, - America_Online_Root_Certification_Authority_1_certificate, - America_Online_Root_Certification_Authority_2_certificate, - Baltimore_CyberTrust_Root_certificate, - Comodo_AAA_Services_root_certificate, - COMODO_Certification_Authority_certificate, - COMODO_ECC_Certification_Authority_certificate, - Comodo_Secure_Services_root_certificate, - Comodo_Trusted_Services_root_certificate, - Cybertrust_Global_Root_certificate, - DigiCert_Assured_ID_Root_CA_certificate, - DigiCert_Global_Root_CA_certificate, - DigiCert_High_Assurance_EV_Root_CA_certificate, - Entrust_net_Premium_2048_Secure_Server_CA_certificate, - Entrust_net_Secure_Server_CA_certificate, - Entrust_Root_Certification_Authority_certificate, - Equifax_Secure_CA_certificate, - Equifax_Secure_eBusiness_CA_1_certificate, - Equifax_Secure_eBusiness_CA_2_certificate, - Equifax_Secure_Global_eBusiness_CA_certificate, - GeoTrust_Global_CA_certificate, - GeoTrust_Global_CA_2_certificate, - GeoTrust_Primary_Certification_Authority_certificate, - GeoTrust_Primary_Certification_Authority___G2_certificate, - GeoTrust_Primary_Certification_Authority___G3_certificate, - GeoTrust_Universal_CA_certificate, - GeoTrust_Universal_CA_2_certificate, - GlobalSign_Root_CA_certificate, - GlobalSign_Root_CA___R2_certificate, - GlobalSign_Root_CA___R3_certificate, - Go_Daddy_Class_2_CA_certificate, - Go_Daddy_Root_Certificate_Authority___G2_certificate, - GTE_CyberTrust_Global_Root_certificate, - Network_Solutions_Certificate_Authority_certificate, - RSA_Root_Certificate_1_certificate, - Starfield_Class_2_CA_certificate, - Starfield_Root_Certificate_Authority___G2_certificate, - Starfield_Services_Root_Certificate_Authority___G2_certificate, - StartCom_Certification_Authority_certificate, - StartCom_Certification_Authority_G2_certificate, - TC_TrustCenter_Class_2_CA_II_certificate, - TC_TrustCenter_Class_3_CA_II_certificate, - TC_TrustCenter_Universal_CA_I_certificate, - TC_TrustCenter_Universal_CA_III_certificate, - Thawte_Premium_Server_CA_certificate, - thawte_Primary_Root_CA_certificate, - thawte_Primary_Root_CA___G2_certificate, - thawte_Primary_Root_CA___G3_certificate, - Thawte_Server_CA_certificate, - UTN_DATACorp_SGC_Root_CA_certificate, - UTN_USERFirst_Hardware_Root_CA_certificate, - ValiCert_Class_1_VA_certificate, - ValiCert_Class_2_VA_certificate, - Verisign_Class_3_Public_Primary_Certification_Authority_certificate, - Verisign_Class_3_Public_Primary_Certification_Authority___G2_certificate, - Verisign_Class_3_Public_Primary_Certification_Authority___G3_certificate, - VeriSign_Class_3_Public_Primary_Certification_Authority___G4_certificate, - VeriSign_Class_3_Public_Primary_Certification_Authority___G5_certificate, - Verisign_Class_4_Public_Primary_Certification_Authority___G3_certificate, - VeriSign_Universal_Root_Certification_Authority_certificate, - XRamp_Global_CA_Root_certificate, -}; - -const size_t kSSLCertCertificateSizeList[] = { - 1082, - 1052, - 1049, - 1058, - 848, - 848, - 1354, - 514, - 936, - 1448, - 891, - 1078, - 1057, - 653, - 1091, - 1095, - 933, - 955, - 947, - 969, - 1120, - 1244, - 1173, - 804, - 646, - 804, - 660, - 856, - 874, - 896, - 690, - 1026, - 1388, - 1392, - 889, - 958, - 867, - 1028, - 969, - 606, - 1002, - 747, - 1043, - 993, - 1011, - 1931, - 1383, - 1198, - 1198, - 993, - 997, - 811, - 1060, - 652, - 1070, - 791, - 1122, - 1144, - 747, - 747, - 576, - 774, - 1054, - 904, - 1239, - 1054, - 1213, - 1076, -}; - diff --git a/webrtc/base/sslsocketfactory.cc b/webrtc/base/sslsocketfactory.cc deleted file mode 100644 index 0e37ab84e..000000000 --- a/webrtc/base/sslsocketfactory.cc +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/autodetectproxy.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/httpcommon-inl.h" -#include "webrtc/base/socketadapters.h" -#include "webrtc/base/ssladapter.h" -#include "webrtc/base/sslsocketfactory.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// ProxySocketAdapter -// TODO: Consider combining AutoDetectProxy and ProxySocketAdapter. I think -// the socket adapter is the more appropriate idiom for automatic proxy -// detection. We may or may not want to combine proxydetect.* as well. -/////////////////////////////////////////////////////////////////////////////// - -class ProxySocketAdapter : public AsyncSocketAdapter { - public: - ProxySocketAdapter(SslSocketFactory* factory, int family, int type) - : AsyncSocketAdapter(NULL), factory_(factory), family_(family), - type_(type), detect_(NULL) { - } - virtual ~ProxySocketAdapter() { - Close(); - } - - virtual int Connect(const SocketAddress& addr) { - ASSERT(NULL == detect_); - ASSERT(NULL == socket_); - remote_ = addr; - if (remote_.IsAnyIP() && remote_.hostname().empty()) { - LOG_F(LS_ERROR) << "Empty address"; - return SOCKET_ERROR; - } - Url url("/", remote_.HostAsURIString(), remote_.port()); - detect_ = new AutoDetectProxy(factory_->agent_); - detect_->set_server_url(url.url()); - detect_->SignalWorkDone.connect(this, - &ProxySocketAdapter::OnProxyDetectionComplete); - detect_->Start(); - return SOCKET_ERROR; - } - virtual int GetError() const { - if (socket_) { - return socket_->GetError(); - } - return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL; - } - virtual int Close() { - if (socket_) { - return socket_->Close(); - } - if (detect_) { - detect_->Destroy(false); - detect_ = NULL; - } - return 0; - } - virtual ConnState GetState() const { - if (socket_) { - return socket_->GetState(); - } - return detect_ ? CS_CONNECTING : CS_CLOSED; - } - -private: - // AutoDetectProxy Slots - void OnProxyDetectionComplete(SignalThread* thread) { - ASSERT(detect_ == thread); - Attach(factory_->CreateProxySocket(detect_->proxy(), family_, type_)); - detect_->Release(); - detect_ = NULL; - if (0 == AsyncSocketAdapter::Connect(remote_)) { - SignalConnectEvent(this); - } else if (!IsBlockingError(socket_->GetError())) { - SignalCloseEvent(this, socket_->GetError()); - } - } - - SslSocketFactory* factory_; - int family_; - int type_; - SocketAddress remote_; - AutoDetectProxy* detect_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// SslSocketFactory -/////////////////////////////////////////////////////////////////////////////// - -Socket* SslSocketFactory::CreateSocket(int type) { - return CreateSocket(AF_INET, type); -} - -Socket* SslSocketFactory::CreateSocket(int family, int type) { - return factory_->CreateSocket(family, type); -} - -AsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) { - return CreateAsyncSocket(AF_INET, type); -} - -AsyncSocket* SslSocketFactory::CreateAsyncSocket(int family, int type) { - if (autodetect_proxy_) { - return new ProxySocketAdapter(this, family, type); - } else { - return CreateProxySocket(proxy_, family, type); - } -} - - -AsyncSocket* SslSocketFactory::CreateProxySocket(const ProxyInfo& proxy, - int family, - int type) { - AsyncSocket* socket = factory_->CreateAsyncSocket(family, type); - if (!socket) - return NULL; - - // Binary logging happens at the lowest level - if (!logging_label_.empty() && binary_mode_) { - socket = new LoggingSocketAdapter(socket, logging_level_, - logging_label_.c_str(), binary_mode_); - } - - if (proxy.type) { - AsyncSocket* proxy_socket = 0; - if (proxy_.type == PROXY_SOCKS5) { - proxy_socket = new AsyncSocksProxySocket(socket, proxy.address, - proxy.username, proxy.password); - } else { - // Note: we are trying unknown proxies as HTTPS currently - AsyncHttpsProxySocket* http_proxy = - new AsyncHttpsProxySocket(socket, agent_, proxy.address, - proxy.username, proxy.password); - http_proxy->SetForceConnect(force_connect_ || !hostname_.empty()); - proxy_socket = http_proxy; - } - if (!proxy_socket) { - delete socket; - return NULL; - } - socket = proxy_socket; // for our purposes the proxy is now the socket - } - - if (!hostname_.empty()) { - if (SSLAdapter* ssl_adapter = SSLAdapter::Create(socket)) { - ssl_adapter->set_ignore_bad_cert(ignore_bad_cert_); - ssl_adapter->StartSSL(hostname_.c_str(), true); - socket = ssl_adapter; - } else { - LOG_F(LS_ERROR) << "SSL unavailable"; - } - } - - // Regular logging occurs at the highest level - if (!logging_label_.empty() && !binary_mode_) { - socket = new LoggingSocketAdapter(socket, logging_level_, - logging_label_.c_str(), binary_mode_); - } - return socket; -} - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/sslsocketfactory.h b/webrtc/base/sslsocketfactory.h deleted file mode 100644 index edb23dbb8..000000000 --- a/webrtc/base/sslsocketfactory.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SSLSOCKETFACTORY_H__ -#define WEBRTC_BASE_SSLSOCKETFACTORY_H__ - -#include "webrtc/base/proxyinfo.h" -#include "webrtc/base/socketserver.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// SslSocketFactory -/////////////////////////////////////////////////////////////////////////////// - -class SslSocketFactory : public SocketFactory { - public: - SslSocketFactory(SocketFactory* factory, const std::string& user_agent) - : factory_(factory), agent_(user_agent), autodetect_proxy_(true), - force_connect_(false), logging_level_(LS_VERBOSE), binary_mode_(false), - ignore_bad_cert_(false) { - } - - void SetAutoDetectProxy() { - autodetect_proxy_ = true; - } - void SetForceConnect(bool force) { - force_connect_ = force; - } - void SetProxy(const ProxyInfo& proxy) { - autodetect_proxy_ = false; - proxy_ = proxy; - } - bool autodetect_proxy() const { return autodetect_proxy_; } - const ProxyInfo& proxy() const { return proxy_; } - - void UseSSL(const char* hostname) { hostname_ = hostname; } - void DisableSSL() { hostname_.clear(); } - void SetIgnoreBadCert(bool ignore) { ignore_bad_cert_ = ignore; } - bool ignore_bad_cert() const { return ignore_bad_cert_; } - - void SetLogging(LoggingSeverity level, const std::string& label, - bool binary_mode = false) { - logging_level_ = level; - logging_label_ = label; - binary_mode_ = binary_mode; - } - - // SocketFactory Interface - virtual Socket* CreateSocket(int type); - virtual Socket* CreateSocket(int family, int type); - - virtual AsyncSocket* CreateAsyncSocket(int type); - virtual AsyncSocket* CreateAsyncSocket(int family, int type); - - private: - friend class ProxySocketAdapter; - AsyncSocket* CreateProxySocket(const ProxyInfo& proxy, int family, int type); - - SocketFactory* factory_; - std::string agent_; - bool autodetect_proxy_, force_connect_; - ProxyInfo proxy_; - std::string hostname_, logging_label_; - LoggingSeverity logging_level_; - bool binary_mode_; - bool ignore_bad_cert_; -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_SSLSOCKETFACTORY_H__ diff --git a/webrtc/base/sslstreamadapter.cc b/webrtc/base/sslstreamadapter.cc deleted file mode 100644 index 44df2eedd..000000000 --- a/webrtc/base/sslstreamadapter.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#include "webrtc/base/sslstreamadapter.h" -#include "webrtc/base/sslconfig.h" - -#if SSL_USE_SCHANNEL - -// SChannel support for DTLS and peer-to-peer mode are not -// done. -#elif SSL_USE_OPENSSL // && !SSL_USE_SCHANNEL - -#include "webrtc/base/opensslstreamadapter.h" - -#elif SSL_USE_NSS // && !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL - -#include "webrtc/base/nssstreamadapter.h" - -#endif // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL && !SSL_USE_NSS - -/////////////////////////////////////////////////////////////////////////////// - -namespace rtc { - -SSLStreamAdapter* SSLStreamAdapter::Create(StreamInterface* stream) { -#if SSL_USE_SCHANNEL - return NULL; -#elif SSL_USE_OPENSSL // !SSL_USE_SCHANNEL - return new OpenSSLStreamAdapter(stream); -#elif SSL_USE_NSS // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL - return new NSSStreamAdapter(stream); -#else // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL && !SSL_USE_NSS - return NULL; -#endif -} - -// Note: this matches the logic above with SCHANNEL dominating -#if SSL_USE_SCHANNEL -bool SSLStreamAdapter::HaveDtls() { return false; } -bool SSLStreamAdapter::HaveDtlsSrtp() { return false; } -bool SSLStreamAdapter::HaveExporter() { return false; } -#elif SSL_USE_OPENSSL -bool SSLStreamAdapter::HaveDtls() { - return OpenSSLStreamAdapter::HaveDtls(); -} -bool SSLStreamAdapter::HaveDtlsSrtp() { - return OpenSSLStreamAdapter::HaveDtlsSrtp(); -} -bool SSLStreamAdapter::HaveExporter() { - return OpenSSLStreamAdapter::HaveExporter(); -} -#elif SSL_USE_NSS -bool SSLStreamAdapter::HaveDtls() { - return NSSStreamAdapter::HaveDtls(); -} -bool SSLStreamAdapter::HaveDtlsSrtp() { - return NSSStreamAdapter::HaveDtlsSrtp(); -} -bool SSLStreamAdapter::HaveExporter() { - return NSSStreamAdapter::HaveExporter(); -} -#endif // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL && !SSL_USE_NSS - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/sslstreamadapter.h b/webrtc/base/sslstreamadapter.h deleted file mode 100644 index ffe6b2f7b..000000000 --- a/webrtc/base/sslstreamadapter.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SSLSTREAMADAPTER_H_ -#define WEBRTC_BASE_SSLSTREAMADAPTER_H_ - -#include -#include - -#include "webrtc/base/stream.h" -#include "webrtc/base/sslidentity.h" - -namespace rtc { - -// SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS. -// After SSL has been started, the stream will only open on successful -// SSL verification of certificates, and the communication is -// encrypted of course. -// -// This class was written with SSLAdapter as a starting point. It -// offers a similar interface, with two differences: there is no -// support for a restartable SSL connection, and this class has a -// peer-to-peer mode. -// -// The SSL library requires initialization and cleanup. Static method -// for doing this are in SSLAdapter. They should possibly be moved out -// to a neutral class. - - -enum SSLRole { SSL_CLIENT, SSL_SERVER }; -enum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS }; - -// Errors for Read -- in the high range so no conflict with OpenSSL. -enum { SSE_MSG_TRUNC = 0xff0001 }; - -class SSLStreamAdapter : public StreamAdapterInterface { - public: - // Instantiate an SSLStreamAdapter wrapping the given stream, - // (using the selected implementation for the platform). - // Caller is responsible for freeing the returned object. - static SSLStreamAdapter* Create(StreamInterface* stream); - - explicit SSLStreamAdapter(StreamInterface* stream) - : StreamAdapterInterface(stream), ignore_bad_cert_(false) { } - - void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; } - bool ignore_bad_cert() const { return ignore_bad_cert_; } - - // Specify our SSL identity: key and certificate. Mostly this is - // only used in the peer-to-peer mode (unless we actually want to - // provide a client certificate to a server). - // SSLStream takes ownership of the SSLIdentity object and will - // free it when appropriate. Should be called no more than once on a - // given SSLStream instance. - virtual void SetIdentity(SSLIdentity* identity) = 0; - - // Call this to indicate that we are to play the server's role in - // the peer-to-peer mode. - // The default argument is for backward compatibility - // TODO(ekr@rtfm.com): rename this SetRole to reflect its new function - virtual void SetServerRole(SSLRole role = SSL_SERVER) = 0; - - // Do DTLS or TLS - virtual void SetMode(SSLMode mode) = 0; - - // The mode of operation is selected by calling either - // StartSSLWithServer or StartSSLWithPeer. - // Use of the stream prior to calling either of these functions will - // pass data in clear text. - // Calling one of these functions causes SSL negotiation to begin as - // soon as possible: right away if the underlying wrapped stream is - // already opened, or else as soon as it opens. - // - // These functions return a negative error code on failure. - // Returning 0 means success so far, but negotiation is probably not - // complete and will continue asynchronously. In that case, the - // exposed stream will open after successful negotiation and - // verification, or an SE_CLOSE event will be raised if negotiation - // fails. - - // StartSSLWithServer starts SSL negotiation with a server in - // traditional mode. server_name specifies the expected server name - // which the server's certificate needs to specify. - virtual int StartSSLWithServer(const char* server_name) = 0; - - // StartSSLWithPeer starts negotiation in the special peer-to-peer - // mode. - // Generally, SetIdentity() and possibly SetServerRole() should have - // been called before this. - // SetPeerCertificate() or SetPeerCertificateDigest() must also be called. - // It may be called after StartSSLWithPeer() but must be called before the - // underlying stream opens. - virtual int StartSSLWithPeer() = 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 - // obtained through some other secure channel (such as the XMPP - // channel). Unlike SetPeerCertificate(), this must specify the - // terminal certificate, not just a CA. - // SSLStream makes a copy of the digest value. - virtual bool SetPeerCertificateDigest(const std::string& digest_alg, - const unsigned char* digest_val, - size_t digest_len) = 0; - - // 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 - // Arguments are: - // label -- the exporter label. - // part of the RFC defining each exporter - // usage (IN) - // context/context_len -- a context to bind to for this connection; - // optional, can be NULL, 0 (IN) - // use_context -- whether to use the context value - // (needed to distinguish no context from - // zero-length ones). - // result -- where to put the computed value - // result_len -- the length of the computed value - virtual bool ExportKeyingMaterial(const std::string& label, - const uint8* context, - size_t context_len, - bool use_context, - uint8* result, - size_t result_len) { - return false; // Default is unsupported - } - - - // DTLS-SRTP interface - virtual bool SetDtlsSrtpCiphers(const std::vector& ciphers) { - return false; - } - - virtual bool GetDtlsSrtpCipher(std::string* cipher) { - return false; - } - - // Capabilities testing - static bool HaveDtls(); - static bool HaveDtlsSrtp(); - static bool HaveExporter(); - - // If true, the server certificate need not match the configured - // server_name, and in fact missing certificate authority and other - // verification errors are ignored. - bool ignore_bad_cert_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SSLSTREAMADAPTER_H_ diff --git a/webrtc/base/sslstreamadapter_unittest.cc b/webrtc/base/sslstreamadapter_unittest.cc deleted file mode 100644 index af78bfff5..000000000 --- a/webrtc/base/sslstreamadapter_unittest.cc +++ /dev/null @@ -1,940 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -#include -#include -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/helpers.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/ssladapter.h" -#include "webrtc/base/sslconfig.h" -#include "webrtc/base/sslidentity.h" -#include "webrtc/base/sslstreamadapter.h" -#include "webrtc/base/stream.h" - -static const int kBlockSize = 4096; -static const char kAES_CM_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80"; -static const char kAES_CM_HMAC_SHA1_32[] = "AES_CM_128_HMAC_SHA1_32"; -static const char kExporterLabel[] = "label"; -static const unsigned char kExporterContext[] = "context"; -static int kExporterContextLen = sizeof(kExporterContext); - -static const char kRSA_PRIVATE_KEY_PEM[] = - "-----BEGIN RSA PRIVATE KEY-----\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" - "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) \ - if (!(rtc::SSLStreamAdapter::feature())) { \ - LOG(LS_INFO) << "Feature disabled... skipping"; \ - return; \ - } - -class SSLStreamAdapterTestBase; - -class SSLDummyStream : public rtc::StreamInterface, - public sigslot::has_slots<> { - public: - explicit SSLDummyStream(SSLStreamAdapterTestBase *test, - const std::string &side, - rtc::FifoBuffer *in, - rtc::FifoBuffer *out) : - test_(test), - side_(side), - in_(in), - out_(out), - first_packet_(true) { - in_->SignalEvent.connect(this, &SSLDummyStream::OnEventIn); - out_->SignalEvent.connect(this, &SSLDummyStream::OnEventOut); - } - - virtual rtc::StreamState GetState() const { return rtc::SS_OPEN; } - - virtual rtc::StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - rtc::StreamResult r; - - r = in_->Read(buffer, buffer_len, read, error); - if (r == rtc::SR_BLOCK) - return rtc::SR_BLOCK; - if (r == rtc::SR_EOS) - return rtc::SR_EOS; - - if (r != rtc::SR_SUCCESS) { - ADD_FAILURE(); - return rtc::SR_ERROR; - } - - return rtc::SR_SUCCESS; - } - - // Catch readability events on in and pass them up. - virtual void OnEventIn(rtc::StreamInterface *stream, int sig, - int err) { - int mask = (rtc::SE_READ | rtc::SE_CLOSE); - - if (sig & mask) { - LOG(LS_INFO) << "SSLDummyStream::OnEvent side=" << side_ << " sig=" - << sig << " forwarding upward"; - PostEvent(sig & mask, 0); - } - } - - // Catch writeability events on out and pass them up. - virtual void OnEventOut(rtc::StreamInterface *stream, int sig, - int err) { - if (sig & rtc::SE_WRITE) { - LOG(LS_INFO) << "SSLDummyStream::OnEvent side=" << side_ << " sig=" - << sig << " forwarding upward"; - - PostEvent(sig & rtc::SE_WRITE, 0); - } - } - - // Write to the outgoing FifoBuffer - rtc::StreamResult WriteData(const void* data, size_t data_len, - size_t* written, int* error) { - return out_->Write(data, data_len, written, error); - } - - // Defined later - virtual rtc::StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - - virtual void Close() { - LOG(LS_INFO) << "Closing outbound stream"; - out_->Close(); - } - - private: - SSLStreamAdapterTestBase *test_; - const std::string side_; - rtc::FifoBuffer *in_; - rtc::FifoBuffer *out_; - bool first_packet_; -}; - -static const int kFifoBufferSize = 4096; - -class SSLStreamAdapterTestBase : public testing::Test, - public sigslot::has_slots<> { - public: - SSLStreamAdapterTestBase(const std::string& client_cert_pem, - const std::string& client_private_key_pem, - bool dtls) : - client_buffer_(kFifoBufferSize), server_buffer_(kFifoBufferSize), - client_stream_( - new SSLDummyStream(this, "c2s", &client_buffer_, &server_buffer_)), - server_stream_( - new SSLDummyStream(this, "s2c", &server_buffer_, &client_buffer_)), - client_ssl_(rtc::SSLStreamAdapter::Create(client_stream_)), - server_ssl_(rtc::SSLStreamAdapter::Create(server_stream_)), - client_identity_(NULL), server_identity_(NULL), - delay_(0), mtu_(1460), loss_(0), lose_first_packet_(false), - damage_(false), dtls_(dtls), - handshake_wait_(5000), identities_set_(false) { - // Set use of the test RNG to get predictable loss patterns. - rtc::SetRandomTestMode(true); - - // Set up the slots - client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent); - server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent); - - if (!client_cert_pem.empty() && !client_private_key_pem.empty()) { - client_identity_ = rtc::SSLIdentity::FromPEMStrings( - client_private_key_pem, client_cert_pem); - } else { - client_identity_ = rtc::SSLIdentity::Generate("client"); - } - server_identity_ = rtc::SSLIdentity::Generate("server"); - - client_ssl_->SetIdentity(client_identity_); - server_ssl_->SetIdentity(server_identity_); - } - - ~SSLStreamAdapterTestBase() { - // Put it back for the next test. - rtc::SetRandomTestMode(false); - } - - static void SetUpTestCase() { - rtc::InitializeSSL(); - } - - static void TearDownTestCase() { - rtc::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(rtc::SSLStreamAdapter::Create(client_stream_)); - server_ssl_.reset(rtc::SSLStreamAdapter::Create(server_stream_)); - - client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent); - server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent); - - rtc::SSLIdentityParams client_params; - client_params.common_name = "client"; - client_params.not_before = not_before; - client_params.not_after = not_after; - client_identity_ = rtc::SSLIdentity::GenerateForTest(client_params); - - rtc::SSLIdentityParams server_params; - server_params.common_name = "server"; - server_params.not_before = not_before; - server_params.not_after = not_after; - server_identity_ = rtc::SSLIdentity::GenerateForTest(server_params); - - client_ssl_->SetIdentity(client_identity_); - server_ssl_->SetIdentity(server_identity_); - } - - virtual void OnEvent(rtc::StreamInterface *stream, int sig, int err) { - LOG(LS_INFO) << "SSLStreamAdapterTestBase::OnEvent sig=" << sig; - - if (sig & rtc::SE_READ) { - ReadData(stream); - } - - if ((stream == client_ssl_.get()) && (sig & rtc::SE_WRITE)) { - WriteData(); - } - } - - void SetPeerIdentitiesByDigest(bool correct) { - unsigned char digest[20]; - size_t digest_len; - bool rv; - - LOG(LS_INFO) << "Setting peer identities by digest"; - - rv = server_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1, - digest, 20, - &digest_len); - ASSERT_TRUE(rv); - if (!correct) { - LOG(LS_INFO) << "Setting bogus digest for server cert"; - digest[0]++; - } - rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest, - digest_len); - ASSERT_TRUE(rv); - - - rv = client_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1, - digest, 20, &digest_len); - ASSERT_TRUE(rv); - if (!correct) { - LOG(LS_INFO) << "Setting bogus digest for client cert"; - digest[0]++; - } - rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest, - digest_len); - ASSERT_TRUE(rv); - - identities_set_ = true; - } - - void TestHandshake(bool expect_success = true) { - server_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : - rtc::SSL_MODE_TLS); - client_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : - rtc::SSL_MODE_TLS); - - if (!dtls_) { - // Make sure we simulate a reliable network for TLS. - // This is just a check to make sure that people don't write wrong - // tests. - ASSERT((mtu_ == 1460) && (loss_ == 0) && (lose_first_packet_ == 0)); - } - - if (!identities_set_) - SetPeerIdentitiesByDigest(true); - - // Start the handshake - int rv; - - server_ssl_->SetServerRole(); - rv = server_ssl_->StartSSLWithPeer(); - ASSERT_EQ(0, rv); - - rv = client_ssl_->StartSSLWithPeer(); - ASSERT_EQ(0, rv); - - // Now run the handshake - if (expect_success) { - EXPECT_TRUE_WAIT((client_ssl_->GetState() == rtc::SS_OPEN) - && (server_ssl_->GetState() == rtc::SS_OPEN), - handshake_wait_); - } else { - EXPECT_TRUE_WAIT(client_ssl_->GetState() == rtc::SS_CLOSED, - handshake_wait_); - } - } - - rtc::StreamResult DataWritten(SSLDummyStream *from, const void *data, - size_t data_len, size_t *written, - int *error) { - // Randomly drop loss_ percent of packets - if (rtc::CreateRandomId() % 100 < static_cast(loss_)) { - LOG(LS_INFO) << "Randomly dropping packet, size=" << data_len; - *written = data_len; - return rtc::SR_SUCCESS; - } - if (dtls_ && (data_len > mtu_)) { - LOG(LS_INFO) << "Dropping packet > mtu, size=" << data_len; - *written = data_len; - return rtc::SR_SUCCESS; - } - - // Optionally damage application data (type 23). Note that we don't damage - // handshake packets and we damage the last byte to keep the header - // intact but break the MAC. - if (damage_ && (*static_cast(data) == 23)) { - std::vector buf(data_len); - - LOG(LS_INFO) << "Damaging packet"; - - memcpy(&buf[0], data, data_len); - buf[data_len - 1]++; - - return from->WriteData(&buf[0], data_len, written, error); - } - - return from->WriteData(data, data_len, written, error); - } - - void SetDelay(int delay) { - delay_ = delay; - } - int GetDelay() { return delay_; } - - void SetLoseFirstPacket(bool lose) { - lose_first_packet_ = lose; - } - bool GetLoseFirstPacket() { return lose_first_packet_; } - - void SetLoss(int percent) { - loss_ = percent; - } - - void SetDamage() { - damage_ = true; - } - - void SetMtu(size_t mtu) { - mtu_ = mtu; - } - - void SetHandshakeWait(int wait) { - handshake_wait_ = wait; - } - - void SetDtlsSrtpCiphers(const std::vector &ciphers, - bool client) { - if (client) - client_ssl_->SetDtlsSrtpCiphers(ciphers); - else - server_ssl_->SetDtlsSrtpCiphers(ciphers); - } - - bool GetDtlsSrtpCipher(bool client, std::string *retval) { - if (client) - return client_ssl_->GetDtlsSrtpCipher(retval); - else - return server_ssl_->GetDtlsSrtpCipher(retval); - } - - bool GetPeerCertificate(bool client, rtc::SSLCertificate** cert) { - if (client) - return client_ssl_->GetPeerCertificate(cert); - else - return server_ssl_->GetPeerCertificate(cert); - } - - bool ExportKeyingMaterial(const char *label, - const unsigned char *context, - size_t context_len, - bool use_context, - bool client, - unsigned char *result, - size_t result_len) { - if (client) - return client_ssl_->ExportKeyingMaterial(label, - context, context_len, - use_context, - result, result_len); - else - return server_ssl_->ExportKeyingMaterial(label, - context, context_len, - use_context, - result, result_len); - } - - // To be implemented by subclasses. - virtual void WriteData() = 0; - virtual void ReadData(rtc::StreamInterface *stream) = 0; - virtual void TestTransfer(int size) = 0; - - protected: - rtc::FifoBuffer client_buffer_; - rtc::FifoBuffer server_buffer_; - SSLDummyStream *client_stream_; // freed by client_ssl_ destructor - SSLDummyStream *server_stream_; // freed by server_ssl_ destructor - rtc::scoped_ptr client_ssl_; - rtc::scoped_ptr server_ssl_; - rtc::SSLIdentity *client_identity_; // freed by client_ssl_ destructor - rtc::SSLIdentity *server_identity_; // freed by server_ssl_ destructor - int delay_; - size_t mtu_; - int loss_; - bool lose_first_packet_; - bool damage_; - bool dtls_; - int handshake_wait_; - bool identities_set_; -}; - -class SSLStreamAdapterTestTLS : public SSLStreamAdapterTestBase { - public: - SSLStreamAdapterTestTLS() : - SSLStreamAdapterTestBase("", "", false) { - }; - - // Test data transfer for TLS - virtual void TestTransfer(int size) { - LOG(LS_INFO) << "Starting transfer test with " << size << " bytes"; - // Create some dummy data to send. - size_t received; - - send_stream_.ReserveSize(size); - for (int i = 0; i < size; ++i) { - char ch = static_cast(i); - send_stream_.Write(&ch, 1, NULL, NULL); - } - send_stream_.Rewind(); - - // Prepare the receive stream. - recv_stream_.ReserveSize(size); - - // Start sending - WriteData(); - - // Wait for the client to close - EXPECT_TRUE_WAIT(server_ssl_->GetState() == rtc::SS_CLOSED, 10000); - - // Now check the data - recv_stream_.GetSize(&received); - - EXPECT_EQ(static_cast(size), received); - EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(), - recv_stream_.GetBuffer(), size)); - } - - void WriteData() { - size_t position, tosend, size; - rtc::StreamResult rv; - size_t sent; - char block[kBlockSize]; - - send_stream_.GetSize(&size); - if (!size) - return; - - for (;;) { - send_stream_.GetPosition(&position); - if (send_stream_.Read(block, sizeof(block), &tosend, NULL) != - rtc::SR_EOS) { - rv = client_ssl_->Write(block, tosend, &sent, 0); - - if (rv == rtc::SR_SUCCESS) { - send_stream_.SetPosition(position + sent); - LOG(LS_VERBOSE) << "Sent: " << position + sent; - } else if (rv == rtc::SR_BLOCK) { - LOG(LS_VERBOSE) << "Blocked..."; - send_stream_.SetPosition(position); - break; - } else { - ADD_FAILURE(); - break; - } - } else { - // Now close - LOG(LS_INFO) << "Wrote " << position << " bytes. Closing"; - client_ssl_->Close(); - break; - } - } - }; - - virtual void ReadData(rtc::StreamInterface *stream) { - char buffer[1600]; - size_t bread; - int err2; - rtc::StreamResult r; - - for (;;) { - r = stream->Read(buffer, sizeof(buffer), &bread, &err2); - - if (r == rtc::SR_ERROR || r == rtc::SR_EOS) { - // Unfortunately, errors are the way that the stream adapter - // signals close in OpenSSL - stream->Close(); - return; - } - - if (r == rtc::SR_BLOCK) - break; - - ASSERT_EQ(rtc::SR_SUCCESS, r); - LOG(LS_INFO) << "Read " << bread; - - recv_stream_.Write(buffer, bread, NULL, NULL); - } - } - - private: - rtc::MemoryStream send_stream_; - rtc::MemoryStream recv_stream_; -}; - -class SSLStreamAdapterTestDTLS : public SSLStreamAdapterTestBase { - public: - SSLStreamAdapterTestDTLS() : - SSLStreamAdapterTestBase("", "", true), - packet_size_(1000), count_(0), sent_(0) { - } - - SSLStreamAdapterTestDTLS(const std::string& cert_pem, - const std::string& private_key_pem) : - SSLStreamAdapterTestBase(cert_pem, private_key_pem, true), - packet_size_(1000), count_(0), sent_(0) { - } - - virtual void WriteData() { - unsigned char *packet = new unsigned char[1600]; - - do { - memset(packet, sent_ & 0xff, packet_size_); - *(reinterpret_cast(packet)) = sent_; - - size_t sent; - int rv = client_ssl_->Write(packet, packet_size_, &sent, 0); - if (rv == rtc::SR_SUCCESS) { - LOG(LS_VERBOSE) << "Sent: " << sent_; - sent_++; - } else if (rv == rtc::SR_BLOCK) { - LOG(LS_VERBOSE) << "Blocked..."; - break; - } else { - ADD_FAILURE(); - break; - } - } while (sent_ < count_); - - delete [] packet; - } - - virtual void ReadData(rtc::StreamInterface *stream) { - unsigned char buffer[2000]; - size_t bread; - int err2; - rtc::StreamResult r; - - for (;;) { - r = stream->Read(buffer, 2000, &bread, &err2); - - if (r == rtc::SR_ERROR) { - // Unfortunately, errors are the way that the stream adapter - // signals close right now - stream->Close(); - return; - } - - if (r == rtc::SR_BLOCK) - break; - - ASSERT_EQ(rtc::SR_SUCCESS, r); - LOG(LS_INFO) << "Read " << bread; - - // Now parse the datagram - ASSERT_EQ(packet_size_, bread); - unsigned char* ptr_to_buffer = buffer; - uint32_t packet_num = *(reinterpret_cast(ptr_to_buffer)); - - for (size_t i = 4; i < packet_size_; i++) { - ASSERT_EQ((packet_num & 0xff), buffer[i]); - } - received_.insert(packet_num); - } - } - - virtual void TestTransfer(int count) { - count_ = count; - - WriteData(); - - EXPECT_TRUE_WAIT(sent_ == count_, 10000); - LOG(LS_INFO) << "sent_ == " << sent_; - - if (damage_) { - WAIT(false, 2000); - EXPECT_EQ(0U, received_.size()); - } else if (loss_ == 0) { - EXPECT_EQ_WAIT(static_cast(sent_), received_.size(), 1000); - } else { - LOG(LS_INFO) << "Sent " << sent_ << " packets; received " << - received_.size(); - } - }; - - private: - size_t packet_size_; - int count_; - int sent_; - std::set received_; -}; - - -rtc::StreamResult SSLDummyStream::Write(const void* data, size_t data_len, - size_t* written, int* error) { - *written = data_len; - - LOG(LS_INFO) << "Writing to loopback " << data_len; - - if (first_packet_) { - first_packet_ = false; - if (test_->GetLoseFirstPacket()) { - LOG(LS_INFO) << "Losing initial packet of length " << data_len; - return rtc::SR_SUCCESS; - } - } - - return test_->DataWritten(this, data, data_len, written, error); - - return rtc::SR_SUCCESS; -}; - -class SSLStreamAdapterTestDTLSFromPEMStrings : public SSLStreamAdapterTestDTLS { - public: - SSLStreamAdapterTestDTLSFromPEMStrings() : - SSLStreamAdapterTestDTLS(kCERT_PEM, kRSA_PRIVATE_KEY_PEM) { - } -}; - -// Basic tests: TLS - -// Test that we cannot read/write if we have not yet handshaked. -// This test only applies to NSS because OpenSSL has passthrough -// semantics for I/O before the handshake is started. -#if SSL_USE_NSS -TEST_F(SSLStreamAdapterTestTLS, TestNoReadWriteBeforeConnect) { - rtc::StreamResult rv; - char block[kBlockSize]; - size_t dummy; - - rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL); - ASSERT_EQ(rtc::SR_BLOCK, rv); - - rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL); - ASSERT_EQ(rtc::SR_BLOCK, rv); -} -#endif - - -// Test that we can make a handshake work -TEST_F(SSLStreamAdapterTestTLS, TestTLSConnect) { - TestHandshake(); -}; - -// Test transfer -- trivial -TEST_F(SSLStreamAdapterTestTLS, TestTLSTransfer) { - TestHandshake(); - TestTransfer(100000); -}; - -// Test read-write after close. -TEST_F(SSLStreamAdapterTestTLS, ReadWriteAfterClose) { - TestHandshake(); - TestTransfer(100000); - client_ssl_->Close(); - - rtc::StreamResult rv; - char block[kBlockSize]; - size_t dummy; - - // It's an error to write after closed. - rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL); - ASSERT_EQ(rtc::SR_ERROR, rv); - - // But after closed read gives you EOS. - rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL); - ASSERT_EQ(rtc::SR_EOS, rv); -}; - -// Test a handshake with a bogus peer digest -TEST_F(SSLStreamAdapterTestTLS, TestTLSBogusDigest) { - SetPeerIdentitiesByDigest(false); - TestHandshake(false); -}; - -// Test moving a bunch of data - -// Basic tests: DTLS -// Test that we can make a handshake work -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSConnect) { - MAYBE_SKIP_TEST(HaveDtls); - TestHandshake(); -}; - -// Test that we can make a handshake work if the first packet in -// each direction is lost. This gives us predictable loss -// rather than having to tune random -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacket) { - MAYBE_SKIP_TEST(HaveDtls); - SetLoseFirstPacket(true); - TestHandshake(); -}; - -// Test a handshake with loss and delay -TEST_F(SSLStreamAdapterTestDTLS, - TestDTLSConnectWithLostFirstPacketDelay2s) { - MAYBE_SKIP_TEST(HaveDtls); - SetLoseFirstPacket(true); - SetDelay(2000); - SetHandshakeWait(20000); - TestHandshake(); -}; - -// Test a handshake with small MTU -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSConnectWithSmallMtu) { - MAYBE_SKIP_TEST(HaveDtls); - SetMtu(700); - SetHandshakeWait(20000); - TestHandshake(); -}; - -// Test transfer -- trivial -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSTransfer) { - MAYBE_SKIP_TEST(HaveDtls); - TestHandshake(); - TestTransfer(100); -}; - -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSTransferWithLoss) { - MAYBE_SKIP_TEST(HaveDtls); - TestHandshake(); - SetLoss(10); - TestTransfer(100); -}; - -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSTransferWithDamage) { - MAYBE_SKIP_TEST(HaveDtls); - SetDamage(); // Must be called first because first packet - // write happens at end of handshake. - TestHandshake(); - TestTransfer(100); -}; - -// Test DTLS-SRTP with all high ciphers -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSSrtpHigh) { - MAYBE_SKIP_TEST(HaveDtlsSrtp); - std::vector high; - high.push_back(kAES_CM_HMAC_SHA1_80); - SetDtlsSrtpCiphers(high, true); - SetDtlsSrtpCiphers(high, false); - TestHandshake(); - - std::string client_cipher; - ASSERT_TRUE(GetDtlsSrtpCipher(true, &client_cipher)); - std::string server_cipher; - ASSERT_TRUE(GetDtlsSrtpCipher(false, &server_cipher)); - - ASSERT_EQ(client_cipher, server_cipher); - ASSERT_EQ(client_cipher, kAES_CM_HMAC_SHA1_80); -}; - -// Test DTLS-SRTP with all low ciphers -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSSrtpLow) { - MAYBE_SKIP_TEST(HaveDtlsSrtp); - std::vector low; - low.push_back(kAES_CM_HMAC_SHA1_32); - SetDtlsSrtpCiphers(low, true); - SetDtlsSrtpCiphers(low, false); - TestHandshake(); - - std::string client_cipher; - ASSERT_TRUE(GetDtlsSrtpCipher(true, &client_cipher)); - std::string server_cipher; - ASSERT_TRUE(GetDtlsSrtpCipher(false, &server_cipher)); - - ASSERT_EQ(client_cipher, server_cipher); - ASSERT_EQ(client_cipher, kAES_CM_HMAC_SHA1_32); -}; - - -// Test DTLS-SRTP with a mismatch -- should not converge -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSSrtpHighLow) { - MAYBE_SKIP_TEST(HaveDtlsSrtp); - std::vector high; - high.push_back(kAES_CM_HMAC_SHA1_80); - std::vector low; - low.push_back(kAES_CM_HMAC_SHA1_32); - SetDtlsSrtpCiphers(high, true); - SetDtlsSrtpCiphers(low, false); - TestHandshake(); - - std::string client_cipher; - ASSERT_FALSE(GetDtlsSrtpCipher(true, &client_cipher)); - std::string server_cipher; - ASSERT_FALSE(GetDtlsSrtpCipher(false, &server_cipher)); -}; - -// Test DTLS-SRTP with each side being mixed -- should select high -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSSrtpMixed) { - MAYBE_SKIP_TEST(HaveDtlsSrtp); - std::vector mixed; - mixed.push_back(kAES_CM_HMAC_SHA1_80); - mixed.push_back(kAES_CM_HMAC_SHA1_32); - SetDtlsSrtpCiphers(mixed, true); - SetDtlsSrtpCiphers(mixed, false); - TestHandshake(); - - std::string client_cipher; - ASSERT_TRUE(GetDtlsSrtpCipher(true, &client_cipher)); - std::string server_cipher; - ASSERT_TRUE(GetDtlsSrtpCipher(false, &server_cipher)); - - ASSERT_EQ(client_cipher, server_cipher); - ASSERT_EQ(client_cipher, kAES_CM_HMAC_SHA1_80); -}; - -// Test an exporter -TEST_F(SSLStreamAdapterTestDTLS, TestDTLSExporter) { - MAYBE_SKIP_TEST(HaveExporter); - TestHandshake(); - unsigned char client_out[20]; - unsigned char server_out[20]; - - bool result; - result = ExportKeyingMaterial(kExporterLabel, - kExporterContext, kExporterContextLen, - true, true, - client_out, sizeof(client_out)); - ASSERT_TRUE(result); - - result = ExportKeyingMaterial(kExporterLabel, - kExporterContext, kExporterContextLen, - true, false, - server_out, sizeof(server_out)); - ASSERT_TRUE(result); - - 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); - TestHandshake(); - TestTransfer(100); -} - -// Test getting the remote certificate. -TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) { - MAYBE_SKIP_TEST(HaveDtls); - - // Peer certificates haven't been received yet. - rtc::scoped_ptr client_peer_cert; - ASSERT_FALSE(GetPeerCertificate(true, client_peer_cert.accept())); - ASSERT_FALSE(client_peer_cert != NULL); - - rtc::scoped_ptr server_peer_cert; - ASSERT_FALSE(GetPeerCertificate(false, server_peer_cert.accept())); - ASSERT_FALSE(server_peer_cert != NULL); - - TestHandshake(); - - // The client should have a peer certificate after the handshake. - ASSERT_TRUE(GetPeerCertificate(true, client_peer_cert.accept())); - ASSERT_TRUE(client_peer_cert != NULL); - - // It's not kCERT_PEM. - std::string client_peer_string = client_peer_cert->ToPEMString(); - ASSERT_NE(kCERT_PEM, client_peer_string); - - // It must not have a chain, because the test certs are self-signed. - rtc::SSLCertChain* client_peer_chain; - ASSERT_FALSE(client_peer_cert->GetChain(&client_peer_chain)); - - // The server should have a peer certificate after the handshake. - ASSERT_TRUE(GetPeerCertificate(false, server_peer_cert.accept())); - ASSERT_TRUE(server_peer_cert != NULL); - - // It's kCERT_PEM - ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString()); - - // It must not have a chain, because the test certs are self-signed. - rtc::SSLCertChain* server_peer_chain; - ASSERT_FALSE(server_peer_cert->GetChain(&server_peer_chain)); -} diff --git a/webrtc/base/sslstreamadapterhelper.cc b/webrtc/base/sslstreamadapterhelper.cc deleted file mode 100644 index d9c6afd40..000000000 --- a/webrtc/base/sslstreamadapterhelper.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -#include - -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#include "webrtc/base/sslstreamadapterhelper.h" - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -void SSLStreamAdapterHelper::SetIdentity(SSLIdentity* identity) { - ASSERT(identity_.get() == NULL); - identity_.reset(identity); -} - -void SSLStreamAdapterHelper::SetServerRole(SSLRole role) { - role_ = role; -} - -int SSLStreamAdapterHelper::StartSSLWithServer(const char* server_name) { - ASSERT(server_name != NULL && server_name[0] != '\0'); - ssl_server_name_ = server_name; - return StartSSL(); -} - -int SSLStreamAdapterHelper::StartSSLWithPeer() { - ASSERT(ssl_server_name_.empty()); - // It is permitted to specify peer_certificate_ only later. - return StartSSL(); -} - -void SSLStreamAdapterHelper::SetMode(SSLMode mode) { - ASSERT(state_ == SSL_NONE); - ssl_mode_ = mode; -} - -StreamState SSLStreamAdapterHelper::GetState() const { - switch (state_) { - case SSL_WAIT: - case SSL_CONNECTING: - return SS_OPENING; - case SSL_CONNECTED: - return SS_OPEN; - default: - return SS_CLOSED; - }; - // not reached -} - -bool SSLStreamAdapterHelper::GetPeerCertificate(SSLCertificate** cert) const { - if (!peer_certificate_) - return false; - - *cert = peer_certificate_->GetReference(); - return true; -} - -bool SSLStreamAdapterHelper::SetPeerCertificateDigest( - const std::string &digest_alg, - const unsigned char* digest_val, - size_t digest_len) { - ASSERT(peer_certificate_.get() == NULL); - ASSERT(peer_certificate_digest_algorithm_.empty()); - ASSERT(ssl_server_name_.empty()); - size_t expected_len; - - if (!GetDigestLength(digest_alg, &expected_len)) { - LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg; - return false; - } - if (expected_len != digest_len) - return false; - - peer_certificate_digest_value_.SetData(digest_val, digest_len); - peer_certificate_digest_algorithm_ = digest_alg; - - return true; -} - -void SSLStreamAdapterHelper::Error(const char* context, int err, bool signal) { - LOG(LS_WARNING) << "SSLStreamAdapterHelper::Error(" - << context << ", " << err << "," << signal << ")"; - state_ = SSL_ERROR; - ssl_error_code_ = err; - Cleanup(); - if (signal) - StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err); -} - -void SSLStreamAdapterHelper::Close() { - Cleanup(); - ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR); - StreamAdapterInterface::Close(); -} - -int SSLStreamAdapterHelper::StartSSL() { - ASSERT(state_ == SSL_NONE); - - if (StreamAdapterInterface::GetState() != SS_OPEN) { - state_ = SSL_WAIT; - return 0; - } - - state_ = SSL_CONNECTING; - int err = BeginSSL(); - if (err) { - Error("BeginSSL", err, false); - return err; - } - - return 0; -} - -} // namespace rtc - diff --git a/webrtc/base/sslstreamadapterhelper.h b/webrtc/base/sslstreamadapterhelper.h deleted file mode 100644 index ef06597b8..000000000 --- a/webrtc/base/sslstreamadapterhelper.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SSLSTREAMADAPTERHELPER_H_ -#define WEBRTC_BASE_SSLSTREAMADAPTERHELPER_H_ - -#include -#include - -#include "webrtc/base/buffer.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/sslidentity.h" -#include "webrtc/base/sslstreamadapter.h" - -namespace rtc { - -// SSLStreamAdapterHelper : A stream adapter which implements much -// of the logic that is common between the known implementations -// (NSS and OpenSSL) -class SSLStreamAdapterHelper : public SSLStreamAdapter { - public: - explicit SSLStreamAdapterHelper(StreamInterface* stream) - : SSLStreamAdapter(stream), - state_(SSL_NONE), - role_(SSL_CLIENT), - ssl_error_code_(0), // Not meaningful yet - ssl_mode_(SSL_MODE_TLS) {} - - - // Overrides of SSLStreamAdapter - virtual void SetIdentity(SSLIdentity* identity); - virtual void SetServerRole(SSLRole role = SSL_SERVER); - virtual void SetMode(SSLMode mode); - - virtual int StartSSLWithServer(const char* server_name); - virtual int StartSSLWithPeer(); - - virtual bool SetPeerCertificateDigest(const std::string& digest_alg, - const unsigned char* digest_val, - size_t digest_len); - virtual bool GetPeerCertificate(SSLCertificate** cert) const; - virtual StreamState GetState() const; - virtual void Close(); - - protected: - // Internal helper methods - // The following method returns 0 on success and a negative - // error code on failure. The error code may be either -1 or - // from the impl on some other error cases, so it can't really be - // interpreted unfortunately. - - // Perform SSL negotiation steps. - int ContinueSSL(); - - // Error handler helper. signal is given as true for errors in - // asynchronous contexts (when an error code was not returned - // through some other method), and in that case an SE_CLOSE event is - // raised on the stream with the specified error. - // A 0 error means a graceful close, otherwise there is not really enough - // context to interpret the error code. - virtual void Error(const char* context, int err, bool signal); - - // Must be implemented by descendents - virtual int BeginSSL() = 0; - virtual void Cleanup() = 0; - virtual bool GetDigestLength(const std::string& algorithm, - size_t* length) = 0; - - enum SSLState { - // Before calling one of the StartSSL methods, data flows - // in clear text. - SSL_NONE, - SSL_WAIT, // waiting for the stream to open to start SSL negotiation - SSL_CONNECTING, // SSL negotiation in progress - SSL_CONNECTED, // SSL stream successfully established - SSL_ERROR, // some SSL error occurred, stream is closed - SSL_CLOSED // Clean close - }; - - // MSG_MAX is the maximum generic stream message number. - enum { MSG_DTLS_TIMEOUT = MSG_MAX + 1 }; - - SSLState state_; - SSLRole role_; - int ssl_error_code_; // valid when state_ == SSL_ERROR - - // Our key and certificate, mostly useful in peer-to-peer mode. - scoped_ptr identity_; - // in traditional mode, the server name that the server's certificate - // must specify. Empty in peer-to-peer mode. - std::string ssl_server_name_; - // The peer's certificate. Only used for GetPeerCertificate. - scoped_ptr peer_certificate_; - - // The digest of the certificate that the peer must present. - Buffer peer_certificate_digest_value_; - std::string peer_certificate_digest_algorithm_; - - // Do DTLS or not - SSLMode ssl_mode_; - - private: - // Go from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT, - // depending on whether the underlying stream is already open or - // not. Returns 0 on success and a negative value on error. - int StartSSL(); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SSLSTREAMADAPTERHELPER_H_ diff --git a/webrtc/base/stream.cc b/webrtc/base/stream.cc deleted file mode 100644 index 9aa10d773..000000000 --- a/webrtc/base/stream.cc +++ /dev/null @@ -1,1335 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_POSIX) -#include -#endif // WEBRTC_POSIX -#include -#include -#include -#include -#include "webrtc/base/basictypes.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/messagequeue.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#define fileno _fileno -#endif - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// StreamInterface -/////////////////////////////////////////////////////////////////////////////// -StreamInterface::~StreamInterface() { -} - -StreamResult StreamInterface::WriteAll(const void* data, size_t data_len, - size_t* written, int* error) { - StreamResult result = SR_SUCCESS; - size_t total_written = 0, current_written; - while (total_written < data_len) { - result = Write(static_cast(data) + total_written, - data_len - total_written, ¤t_written, error); - if (result != SR_SUCCESS) - break; - total_written += current_written; - } - if (written) - *written = total_written; - return result; -} - -StreamResult StreamInterface::ReadAll(void* buffer, size_t buffer_len, - size_t* read, int* error) { - StreamResult result = SR_SUCCESS; - size_t total_read = 0, current_read; - while (total_read < buffer_len) { - result = Read(static_cast(buffer) + total_read, - buffer_len - total_read, ¤t_read, error); - if (result != SR_SUCCESS) - break; - total_read += current_read; - } - if (read) - *read = total_read; - return result; -} - -StreamResult StreamInterface::ReadLine(std::string* line) { - line->clear(); - StreamResult result = SR_SUCCESS; - while (true) { - char ch; - result = Read(&ch, sizeof(ch), NULL, NULL); - if (result != SR_SUCCESS) { - break; - } - if (ch == '\n') { - break; - } - line->push_back(ch); - } - if (!line->empty()) { // give back the line we've collected so far with - result = SR_SUCCESS; // a success code. Otherwise return the last code - } - return result; -} - -void StreamInterface::PostEvent(Thread* t, int events, int err) { - t->Post(this, MSG_POST_EVENT, new StreamEventData(events, err)); -} - -void StreamInterface::PostEvent(int events, int err) { - PostEvent(Thread::Current(), events, err); -} - -StreamInterface::StreamInterface() { -} - -void StreamInterface::OnMessage(Message* msg) { - if (MSG_POST_EVENT == msg->message_id) { - StreamEventData* pe = static_cast(msg->pdata); - SignalEvent(this, pe->events, pe->error); - delete msg->pdata; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// StreamAdapterInterface -/////////////////////////////////////////////////////////////////////////////// - -StreamAdapterInterface::StreamAdapterInterface(StreamInterface* stream, - bool owned) - : stream_(stream), owned_(owned) { - if (NULL != stream_) - stream_->SignalEvent.connect(this, &StreamAdapterInterface::OnEvent); -} - -void StreamAdapterInterface::Attach(StreamInterface* stream, bool owned) { - if (NULL != stream_) - stream_->SignalEvent.disconnect(this); - if (owned_) - delete stream_; - stream_ = stream; - owned_ = owned; - if (NULL != stream_) - stream_->SignalEvent.connect(this, &StreamAdapterInterface::OnEvent); -} - -StreamInterface* StreamAdapterInterface::Detach() { - if (NULL != stream_) - stream_->SignalEvent.disconnect(this); - StreamInterface* stream = stream_; - stream_ = NULL; - return stream; -} - -StreamAdapterInterface::~StreamAdapterInterface() { - if (owned_) - delete stream_; -} - -/////////////////////////////////////////////////////////////////////////////// -// StreamTap -/////////////////////////////////////////////////////////////////////////////// - -StreamTap::StreamTap(StreamInterface* stream, StreamInterface* tap) - : StreamAdapterInterface(stream), tap_(), tap_result_(SR_SUCCESS), - tap_error_(0) { - AttachTap(tap); -} - -void StreamTap::AttachTap(StreamInterface* tap) { - tap_.reset(tap); -} - -StreamInterface* StreamTap::DetachTap() { - return tap_.release(); -} - -StreamResult StreamTap::GetTapResult(int* error) { - if (error) { - *error = tap_error_; - } - return tap_result_; -} - -StreamResult StreamTap::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - size_t backup_read; - if (!read) { - read = &backup_read; - } - StreamResult res = StreamAdapterInterface::Read(buffer, buffer_len, - read, error); - if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) { - tap_result_ = tap_->WriteAll(buffer, *read, NULL, &tap_error_); - } - return res; -} - -StreamResult StreamTap::Write(const void* data, size_t data_len, - size_t* written, int* error) { - size_t backup_written; - if (!written) { - written = &backup_written; - } - StreamResult res = StreamAdapterInterface::Write(data, data_len, - written, error); - if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) { - tap_result_ = tap_->WriteAll(data, *written, NULL, &tap_error_); - } - return res; -} - -/////////////////////////////////////////////////////////////////////////////// -// StreamSegment -/////////////////////////////////////////////////////////////////////////////// - -StreamSegment::StreamSegment(StreamInterface* stream) - : StreamAdapterInterface(stream), start_(SIZE_UNKNOWN), pos_(0), - length_(SIZE_UNKNOWN) { - // It's ok for this to fail, in which case start_ is left as SIZE_UNKNOWN. - stream->GetPosition(&start_); -} - -StreamSegment::StreamSegment(StreamInterface* stream, size_t length) - : StreamAdapterInterface(stream), start_(SIZE_UNKNOWN), pos_(0), - length_(length) { - // It's ok for this to fail, in which case start_ is left as SIZE_UNKNOWN. - stream->GetPosition(&start_); -} - -StreamResult StreamSegment::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - if (SIZE_UNKNOWN != length_) { - if (pos_ >= length_) - return SR_EOS; - buffer_len = _min(buffer_len, length_ - pos_); - } - size_t backup_read; - if (!read) { - read = &backup_read; - } - StreamResult result = StreamAdapterInterface::Read(buffer, buffer_len, - read, error); - if (SR_SUCCESS == result) { - pos_ += *read; - } - return result; -} - -bool StreamSegment::SetPosition(size_t position) { - if (SIZE_UNKNOWN == start_) - return false; // Not seekable - if ((SIZE_UNKNOWN != length_) && (position > length_)) - return false; // Seek past end of segment - if (!StreamAdapterInterface::SetPosition(start_ + position)) - return false; - pos_ = position; - return true; -} - -bool StreamSegment::GetPosition(size_t* position) const { - if (SIZE_UNKNOWN == start_) - return false; // Not seekable - if (!StreamAdapterInterface::GetPosition(position)) - return false; - if (position) { - ASSERT(*position >= start_); - *position -= start_; - } - return true; -} - -bool StreamSegment::GetSize(size_t* size) const { - if (!StreamAdapterInterface::GetSize(size)) - return false; - if (size) { - if (SIZE_UNKNOWN != start_) { - ASSERT(*size >= start_); - *size -= start_; - } - if (SIZE_UNKNOWN != length_) { - *size = _min(*size, length_); - } - } - return true; -} - -bool StreamSegment::GetAvailable(size_t* size) const { - if (!StreamAdapterInterface::GetAvailable(size)) - return false; - if (size && (SIZE_UNKNOWN != length_)) - *size = _min(*size, length_ - pos_); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// NullStream -/////////////////////////////////////////////////////////////////////////////// - -NullStream::NullStream() { -} - -NullStream::~NullStream() { -} - -StreamState NullStream::GetState() const { - return SS_OPEN; -} - -StreamResult NullStream::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - if (error) *error = -1; - return SR_ERROR; -} - -StreamResult NullStream::Write(const void* data, size_t data_len, - size_t* written, int* error) { - if (written) *written = data_len; - return SR_SUCCESS; -} - -void NullStream::Close() { -} - -/////////////////////////////////////////////////////////////////////////////// -// FileStream -/////////////////////////////////////////////////////////////////////////////// - -FileStream::FileStream() : file_(NULL) { -} - -FileStream::~FileStream() { - FileStream::Close(); -} - -bool FileStream::Open(const std::string& filename, const char* mode, - int* error) { - Close(); -#if defined(WEBRTC_WIN) - std::wstring wfilename; - if (Utf8ToWindowsFilename(filename, &wfilename)) { - file_ = _wfopen(wfilename.c_str(), ToUtf16(mode).c_str()); - } else { - if (error) { - *error = -1; - return false; - } - } -#else - file_ = fopen(filename.c_str(), mode); -#endif - if (!file_ && error) { - *error = errno; - } - return (file_ != NULL); -} - -bool FileStream::OpenShare(const std::string& filename, const char* mode, - int shflag, int* error) { - Close(); -#if defined(WEBRTC_WIN) - std::wstring wfilename; - if (Utf8ToWindowsFilename(filename, &wfilename)) { - file_ = _wfsopen(wfilename.c_str(), ToUtf16(mode).c_str(), shflag); - if (!file_ && error) { - *error = errno; - return false; - } - return file_ != NULL; - } else { - if (error) { - *error = -1; - } - return false; - } -#else - return Open(filename, mode, error); -#endif -} - -bool FileStream::DisableBuffering() { - if (!file_) - return false; - return (setvbuf(file_, NULL, _IONBF, 0) == 0); -} - -StreamState FileStream::GetState() const { - return (file_ == NULL) ? SS_CLOSED : SS_OPEN; -} - -StreamResult FileStream::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - if (!file_) - return SR_EOS; - size_t result = fread(buffer, 1, buffer_len, file_); - if ((result == 0) && (buffer_len > 0)) { - if (feof(file_)) - return SR_EOS; - if (error) - *error = errno; - return SR_ERROR; - } - if (read) - *read = result; - return SR_SUCCESS; -} - -StreamResult FileStream::Write(const void* data, size_t data_len, - size_t* written, int* error) { - if (!file_) - return SR_EOS; - size_t result = fwrite(data, 1, data_len, file_); - if ((result == 0) && (data_len > 0)) { - if (error) - *error = errno; - return SR_ERROR; - } - if (written) - *written = result; - return SR_SUCCESS; -} - -void FileStream::Close() { - if (file_) { - DoClose(); - file_ = NULL; - } -} - -bool FileStream::SetPosition(size_t position) { - if (!file_) - return false; - return (fseek(file_, static_cast(position), SEEK_SET) == 0); -} - -bool FileStream::GetPosition(size_t* position) const { - ASSERT(NULL != position); - if (!file_) - return false; - long result = ftell(file_); - if (result < 0) - return false; - if (position) - *position = result; - return true; -} - -bool FileStream::GetSize(size_t* size) const { - ASSERT(NULL != size); - if (!file_) - return false; - struct stat file_stats; - if (fstat(fileno(file_), &file_stats) != 0) - return false; - if (size) - *size = file_stats.st_size; - return true; -} - -bool FileStream::GetAvailable(size_t* size) const { - ASSERT(NULL != size); - if (!GetSize(size)) - return false; - long result = ftell(file_); - if (result < 0) - return false; - if (size) - *size -= result; - return true; -} - -bool FileStream::ReserveSize(size_t size) { - // TODO: extend the file to the proper length - return true; -} - -bool FileStream::GetSize(const std::string& filename, size_t* size) { - struct stat file_stats; - if (stat(filename.c_str(), &file_stats) != 0) - return false; - *size = file_stats.st_size; - return true; -} - -bool FileStream::Flush() { - if (file_) { - return (0 == fflush(file_)); - } - // try to flush empty file? - ASSERT(false); - return false; -} - -#if defined(WEBRTC_POSIX) && !defined(__native_client__) - -bool FileStream::TryLock() { - if (file_ == NULL) { - // Stream not open. - ASSERT(false); - return false; - } - - return flock(fileno(file_), LOCK_EX|LOCK_NB) == 0; -} - -bool FileStream::Unlock() { - if (file_ == NULL) { - // Stream not open. - ASSERT(false); - return false; - } - - return flock(fileno(file_), LOCK_UN) == 0; -} - -#endif - -void FileStream::DoClose() { - fclose(file_); -} - -CircularFileStream::CircularFileStream(size_t max_size) - : max_write_size_(max_size), - position_(0), - marked_position_(max_size / 2), - last_write_position_(0), - read_segment_(READ_LATEST), - read_segment_available_(0) { -} - -bool CircularFileStream::Open( - const std::string& filename, const char* mode, int* error) { - if (!FileStream::Open(filename.c_str(), mode, error)) - return false; - - if (strchr(mode, "r") != NULL) { // Opened in read mode. - // Check if the buffer has been overwritten and determine how to read the - // log in time sequence. - size_t file_size; - GetSize(&file_size); - if (file_size == position_) { - // The buffer has not been overwritten yet. Read 0 .. file_size - read_segment_ = READ_LATEST; - read_segment_available_ = file_size; - } else { - // The buffer has been over written. There are three segments: The first - // one is 0 .. marked_position_, which is the marked earliest log. The - // second one is position_ .. file_size, which is the middle log. The - // last one is marked_position_ .. position_, which is the latest log. - read_segment_ = READ_MARKED; - read_segment_available_ = marked_position_; - last_write_position_ = position_; - } - - // Read from the beginning. - position_ = 0; - SetPosition(position_); - } - - return true; -} - -StreamResult CircularFileStream::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - if (read_segment_available_ == 0) { - size_t file_size; - switch (read_segment_) { - case READ_MARKED: // Finished READ_MARKED and start READ_MIDDLE. - read_segment_ = READ_MIDDLE; - position_ = last_write_position_; - SetPosition(position_); - GetSize(&file_size); - read_segment_available_ = file_size - position_; - break; - - case READ_MIDDLE: // Finished READ_MIDDLE and start READ_LATEST. - read_segment_ = READ_LATEST; - position_ = marked_position_; - SetPosition(position_); - read_segment_available_ = last_write_position_ - position_; - break; - - default: // Finished READ_LATEST and return EOS. - return rtc::SR_EOS; - } - } - - size_t local_read; - if (!read) read = &local_read; - - size_t to_read = rtc::_min(buffer_len, read_segment_available_); - rtc::StreamResult result - = rtc::FileStream::Read(buffer, to_read, read, error); - if (result == rtc::SR_SUCCESS) { - read_segment_available_ -= *read; - position_ += *read; - } - return result; -} - -StreamResult CircularFileStream::Write(const void* data, size_t data_len, - size_t* written, int* error) { - if (position_ >= max_write_size_) { - ASSERT(position_ == max_write_size_); - position_ = marked_position_; - SetPosition(position_); - } - - size_t local_written; - if (!written) written = &local_written; - - size_t to_eof = max_write_size_ - position_; - size_t to_write = rtc::_min(data_len, to_eof); - rtc::StreamResult result - = rtc::FileStream::Write(data, to_write, written, error); - if (result == rtc::SR_SUCCESS) { - position_ += *written; - } - return result; -} - -AsyncWriteStream::~AsyncWriteStream() { - write_thread_->Clear(this, 0, NULL); - ClearBufferAndWrite(); - - CritScope cs(&crit_stream_); - stream_.reset(); -} - -// This is needed by some stream writers, such as RtpDumpWriter. -bool AsyncWriteStream::GetPosition(size_t* position) const { - CritScope cs(&crit_stream_); - return stream_->GetPosition(position); -} - -// This is needed by some stream writers, such as the plugin log writers. -StreamResult AsyncWriteStream::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - CritScope cs(&crit_stream_); - return stream_->Read(buffer, buffer_len, read, error); -} - -void AsyncWriteStream::Close() { - if (state_ == SS_CLOSED) { - return; - } - - write_thread_->Clear(this, 0, NULL); - ClearBufferAndWrite(); - - CritScope cs(&crit_stream_); - stream_->Close(); - state_ = SS_CLOSED; -} - -StreamResult AsyncWriteStream::Write(const void* data, size_t data_len, - size_t* written, int* error) { - if (state_ == SS_CLOSED) { - return SR_ERROR; - } - - size_t previous_buffer_length = 0; - { - CritScope cs(&crit_buffer_); - previous_buffer_length = buffer_.length(); - buffer_.AppendData(data, data_len); - } - - if (previous_buffer_length == 0) { - // If there's stuff already in the buffer, then we already called - // Post and the write_thread_ hasn't pulled it out yet, so we - // don't need to re-Post. - write_thread_->Post(this, 0, NULL); - } - // Return immediately, assuming that it works. - if (written) { - *written = data_len; - } - return SR_SUCCESS; -} - -void AsyncWriteStream::OnMessage(rtc::Message* pmsg) { - ClearBufferAndWrite(); -} - -bool AsyncWriteStream::Flush() { - if (state_ == SS_CLOSED) { - return false; - } - - ClearBufferAndWrite(); - - CritScope cs(&crit_stream_); - return stream_->Flush(); -} - -void AsyncWriteStream::ClearBufferAndWrite() { - Buffer to_write; - { - CritScope cs_buffer(&crit_buffer_); - buffer_.TransferTo(&to_write); - } - - if (to_write.length() > 0) { - CritScope cs(&crit_stream_); - stream_->WriteAll(to_write.data(), to_write.length(), NULL, NULL); - } -} - -#if defined(WEBRTC_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. -POpenStream::~POpenStream() { - POpenStream::Close(); -} - -bool POpenStream::Open(const std::string& subcommand, - const char* mode, - int* error) { - Close(); - file_ = popen(subcommand.c_str(), mode); - if (file_ == NULL) { - if (error) - *error = errno; - return false; - } - return true; -} - -bool POpenStream::OpenShare(const std::string& subcommand, const char* mode, - int shflag, int* error) { - return Open(subcommand, mode, error); -} - -void POpenStream::DoClose() { - wait_status_ = pclose(file_); -} - -#endif - -/////////////////////////////////////////////////////////////////////////////// -// MemoryStream -/////////////////////////////////////////////////////////////////////////////// - -MemoryStreamBase::MemoryStreamBase() - : buffer_(NULL), buffer_length_(0), data_length_(0), - seek_position_(0) { -} - -StreamState MemoryStreamBase::GetState() const { - return SS_OPEN; -} - -StreamResult MemoryStreamBase::Read(void* buffer, size_t bytes, - size_t* bytes_read, int* error) { - if (seek_position_ >= data_length_) { - return SR_EOS; - } - size_t available = data_length_ - seek_position_; - if (bytes > available) { - // Read partial buffer - bytes = available; - } - memcpy(buffer, &buffer_[seek_position_], bytes); - seek_position_ += bytes; - if (bytes_read) { - *bytes_read = bytes; - } - return SR_SUCCESS; -} - -StreamResult MemoryStreamBase::Write(const void* buffer, size_t bytes, - size_t* bytes_written, int* error) { - size_t available = buffer_length_ - seek_position_; - if (0 == available) { - // Increase buffer size to the larger of: - // a) new position rounded up to next 256 bytes - // b) double the previous length - size_t new_buffer_length = _max(((seek_position_ + bytes) | 0xFF) + 1, - buffer_length_ * 2); - StreamResult result = DoReserve(new_buffer_length, error); - if (SR_SUCCESS != result) { - return result; - } - ASSERT(buffer_length_ >= new_buffer_length); - available = buffer_length_ - seek_position_; - } - - if (bytes > available) { - bytes = available; - } - memcpy(&buffer_[seek_position_], buffer, bytes); - seek_position_ += bytes; - if (data_length_ < seek_position_) { - data_length_ = seek_position_; - } - if (bytes_written) { - *bytes_written = bytes; - } - return SR_SUCCESS; -} - -void MemoryStreamBase::Close() { - // nothing to do -} - -bool MemoryStreamBase::SetPosition(size_t position) { - if (position > data_length_) - return false; - seek_position_ = position; - return true; -} - -bool MemoryStreamBase::GetPosition(size_t* position) const { - if (position) - *position = seek_position_; - return true; -} - -bool MemoryStreamBase::GetSize(size_t* size) const { - if (size) - *size = data_length_; - return true; -} - -bool MemoryStreamBase::GetAvailable(size_t* size) const { - if (size) - *size = data_length_ - seek_position_; - return true; -} - -bool MemoryStreamBase::ReserveSize(size_t size) { - return (SR_SUCCESS == DoReserve(size, NULL)); -} - -StreamResult MemoryStreamBase::DoReserve(size_t size, int* error) { - return (buffer_length_ >= size) ? SR_SUCCESS : SR_EOS; -} - -/////////////////////////////////////////////////////////////////////////////// - -MemoryStream::MemoryStream() - : buffer_alloc_(NULL) { -} - -MemoryStream::MemoryStream(const char* data) - : buffer_alloc_(NULL) { - SetData(data, strlen(data)); -} - -MemoryStream::MemoryStream(const void* data, size_t length) - : buffer_alloc_(NULL) { - SetData(data, length); -} - -MemoryStream::~MemoryStream() { - delete [] buffer_alloc_; -} - -void MemoryStream::SetData(const void* data, size_t length) { - data_length_ = buffer_length_ = length; - delete [] buffer_alloc_; - buffer_alloc_ = new char[buffer_length_ + kAlignment]; - buffer_ = reinterpret_cast(ALIGNP(buffer_alloc_, kAlignment)); - memcpy(buffer_, data, data_length_); - seek_position_ = 0; -} - -StreamResult MemoryStream::DoReserve(size_t size, int* error) { - if (buffer_length_ >= size) - return SR_SUCCESS; - - if (char* new_buffer_alloc = new char[size + kAlignment]) { - char* new_buffer = reinterpret_cast( - ALIGNP(new_buffer_alloc, kAlignment)); - memcpy(new_buffer, buffer_, data_length_); - delete [] buffer_alloc_; - buffer_alloc_ = new_buffer_alloc; - buffer_ = new_buffer; - buffer_length_ = size; - return SR_SUCCESS; - } - - if (error) { - *error = ENOMEM; - } - return SR_ERROR; -} - -/////////////////////////////////////////////////////////////////////////////// - -ExternalMemoryStream::ExternalMemoryStream() { -} - -ExternalMemoryStream::ExternalMemoryStream(void* data, size_t length) { - SetData(data, length); -} - -ExternalMemoryStream::~ExternalMemoryStream() { -} - -void ExternalMemoryStream::SetData(void* data, size_t length) { - data_length_ = buffer_length_ = length; - buffer_ = static_cast(data); - seek_position_ = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// FifoBuffer -/////////////////////////////////////////////////////////////////////////////// - -FifoBuffer::FifoBuffer(size_t size) - : state_(SS_OPEN), buffer_(new char[size]), buffer_length_(size), - data_length_(0), read_position_(0), owner_(Thread::Current()) { - // all events are done on the owner_ thread -} - -FifoBuffer::FifoBuffer(size_t size, Thread* owner) - : state_(SS_OPEN), buffer_(new char[size]), buffer_length_(size), - data_length_(0), read_position_(0), owner_(owner) { - // all events are done on the owner_ thread -} - -FifoBuffer::~FifoBuffer() { -} - -bool FifoBuffer::GetBuffered(size_t* size) const { - CritScope cs(&crit_); - *size = data_length_; - return true; -} - -bool FifoBuffer::SetCapacity(size_t size) { - CritScope cs(&crit_); - if (data_length_ > size) { - return false; - } - - if (size != buffer_length_) { - char* buffer = new char[size]; - const size_t copy = data_length_; - const size_t tail_copy = _min(copy, buffer_length_ - read_position_); - memcpy(buffer, &buffer_[read_position_], tail_copy); - memcpy(buffer + tail_copy, &buffer_[0], copy - tail_copy); - buffer_.reset(buffer); - read_position_ = 0; - buffer_length_ = size; - } - return true; -} - -StreamResult FifoBuffer::ReadOffset(void* buffer, size_t bytes, - size_t offset, size_t* bytes_read) { - CritScope cs(&crit_); - return ReadOffsetLocked(buffer, bytes, offset, bytes_read); -} - -StreamResult FifoBuffer::WriteOffset(const void* buffer, size_t bytes, - size_t offset, size_t* bytes_written) { - CritScope cs(&crit_); - return WriteOffsetLocked(buffer, bytes, offset, bytes_written); -} - -StreamState FifoBuffer::GetState() const { - return state_; -} - -StreamResult FifoBuffer::Read(void* buffer, size_t bytes, - size_t* bytes_read, int* error) { - CritScope cs(&crit_); - const bool was_writable = data_length_ < buffer_length_; - size_t copy = 0; - StreamResult result = ReadOffsetLocked(buffer, bytes, 0, ©); - - if (result == SR_SUCCESS) { - // If read was successful then adjust the read position and number of - // bytes buffered. - read_position_ = (read_position_ + copy) % buffer_length_; - data_length_ -= copy; - if (bytes_read) { - *bytes_read = copy; - } - - // if we were full before, and now we're not, post an event - if (!was_writable && copy > 0) { - PostEvent(owner_, SE_WRITE, 0); - } - } - return result; -} - -StreamResult FifoBuffer::Write(const void* buffer, size_t bytes, - size_t* bytes_written, int* error) { - CritScope cs(&crit_); - - const bool was_readable = (data_length_ > 0); - size_t copy = 0; - StreamResult result = WriteOffsetLocked(buffer, bytes, 0, ©); - - if (result == SR_SUCCESS) { - // If write was successful then adjust the number of readable bytes. - data_length_ += copy; - if (bytes_written) { - *bytes_written = copy; - } - - // if we didn't have any data to read before, and now we do, post an event - if (!was_readable && copy > 0) { - PostEvent(owner_, SE_READ, 0); - } - } - return result; -} - -void FifoBuffer::Close() { - CritScope cs(&crit_); - state_ = SS_CLOSED; -} - -const void* FifoBuffer::GetReadData(size_t* size) { - CritScope cs(&crit_); - *size = (read_position_ + data_length_ <= buffer_length_) ? - data_length_ : buffer_length_ - read_position_; - return &buffer_[read_position_]; -} - -void FifoBuffer::ConsumeReadData(size_t size) { - CritScope cs(&crit_); - ASSERT(size <= data_length_); - const bool was_writable = data_length_ < buffer_length_; - read_position_ = (read_position_ + size) % buffer_length_; - data_length_ -= size; - if (!was_writable && size > 0) { - PostEvent(owner_, SE_WRITE, 0); - } -} - -void* FifoBuffer::GetWriteBuffer(size_t* size) { - CritScope cs(&crit_); - if (state_ == SS_CLOSED) { - return NULL; - } - - // if empty, reset the write position to the beginning, so we can get - // the biggest possible block - if (data_length_ == 0) { - read_position_ = 0; - } - - const size_t write_position = (read_position_ + data_length_) - % buffer_length_; - *size = (write_position > read_position_ || data_length_ == 0) ? - buffer_length_ - write_position : read_position_ - write_position; - return &buffer_[write_position]; -} - -void FifoBuffer::ConsumeWriteBuffer(size_t size) { - CritScope cs(&crit_); - ASSERT(size <= buffer_length_ - data_length_); - const bool was_readable = (data_length_ > 0); - data_length_ += size; - if (!was_readable && size > 0) { - PostEvent(owner_, SE_READ, 0); - } -} - -bool FifoBuffer::GetWriteRemaining(size_t* size) const { - CritScope cs(&crit_); - *size = buffer_length_ - data_length_; - return true; -} - -StreamResult FifoBuffer::ReadOffsetLocked(void* buffer, - size_t bytes, - size_t offset, - size_t* bytes_read) { - if (offset >= data_length_) { - return (state_ != SS_CLOSED) ? SR_BLOCK : SR_EOS; - } - - const size_t available = data_length_ - offset; - const size_t read_position = (read_position_ + offset) % buffer_length_; - const size_t copy = _min(bytes, available); - const size_t tail_copy = _min(copy, buffer_length_ - read_position); - char* const p = static_cast(buffer); - memcpy(p, &buffer_[read_position], tail_copy); - memcpy(p + tail_copy, &buffer_[0], copy - tail_copy); - - if (bytes_read) { - *bytes_read = copy; - } - return SR_SUCCESS; -} - -StreamResult FifoBuffer::WriteOffsetLocked(const void* buffer, - size_t bytes, - size_t offset, - size_t* bytes_written) { - if (state_ == SS_CLOSED) { - return SR_EOS; - } - - if (data_length_ + offset >= buffer_length_) { - return SR_BLOCK; - } - - const size_t available = buffer_length_ - data_length_ - offset; - const size_t write_position = (read_position_ + data_length_ + offset) - % buffer_length_; - const size_t copy = _min(bytes, available); - const size_t tail_copy = _min(copy, buffer_length_ - write_position); - const char* const p = static_cast(buffer); - memcpy(&buffer_[write_position], p, tail_copy); - memcpy(&buffer_[0], p + tail_copy, copy - tail_copy); - - if (bytes_written) { - *bytes_written = copy; - } - return SR_SUCCESS; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// LoggingAdapter -/////////////////////////////////////////////////////////////////////////////// - -LoggingAdapter::LoggingAdapter(StreamInterface* stream, LoggingSeverity level, - const std::string& label, bool hex_mode) - : StreamAdapterInterface(stream), level_(level), hex_mode_(hex_mode) { - set_label(label); -} - -void LoggingAdapter::set_label(const std::string& label) { - label_.assign("["); - label_.append(label); - label_.append("]"); -} - -StreamResult LoggingAdapter::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - size_t local_read; if (!read) read = &local_read; - StreamResult result = StreamAdapterInterface::Read(buffer, buffer_len, read, - error); - if (result == SR_SUCCESS) { - LogMultiline(level_, label_.c_str(), true, buffer, *read, hex_mode_, &lms_); - } - return result; -} - -StreamResult LoggingAdapter::Write(const void* data, size_t data_len, - size_t* written, int* error) { - size_t local_written; - if (!written) written = &local_written; - StreamResult result = StreamAdapterInterface::Write(data, data_len, written, - error); - if (result == SR_SUCCESS) { - LogMultiline(level_, label_.c_str(), false, data, *written, hex_mode_, - &lms_); - } - return result; -} - -void LoggingAdapter::Close() { - LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_); - LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_); - LOG_V(level_) << label_ << " Closed locally"; - StreamAdapterInterface::Close(); -} - -void LoggingAdapter::OnEvent(StreamInterface* stream, int events, int err) { - if (events & SE_OPEN) { - LOG_V(level_) << label_ << " Open"; - } else if (events & SE_CLOSE) { - LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_); - LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_); - LOG_V(level_) << label_ << " Closed with error: " << err; - } - StreamAdapterInterface::OnEvent(stream, events, err); -} - -/////////////////////////////////////////////////////////////////////////////// -// StringStream - Reads/Writes to an external std::string -/////////////////////////////////////////////////////////////////////////////// - -StringStream::StringStream(std::string& str) - : str_(str), read_pos_(0), read_only_(false) { -} - -StringStream::StringStream(const std::string& str) - : str_(const_cast(str)), read_pos_(0), read_only_(true) { -} - -StreamState StringStream::GetState() const { - return SS_OPEN; -} - -StreamResult StringStream::Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - size_t available = _min(buffer_len, str_.size() - read_pos_); - if (!available) - return SR_EOS; - memcpy(buffer, str_.data() + read_pos_, available); - read_pos_ += available; - if (read) - *read = available; - return SR_SUCCESS; -} - -StreamResult StringStream::Write(const void* data, size_t data_len, - size_t* written, int* error) { - if (read_only_) { - if (error) { - *error = -1; - } - return SR_ERROR; - } - str_.append(static_cast(data), - static_cast(data) + data_len); - if (written) - *written = data_len; - return SR_SUCCESS; -} - -void StringStream::Close() { -} - -bool StringStream::SetPosition(size_t position) { - if (position > str_.size()) - return false; - read_pos_ = position; - return true; -} - -bool StringStream::GetPosition(size_t* position) const { - if (position) - *position = read_pos_; - return true; -} - -bool StringStream::GetSize(size_t* size) const { - if (size) - *size = str_.size(); - return true; -} - -bool StringStream::GetAvailable(size_t* size) const { - if (size) - *size = str_.size() - read_pos_; - return true; -} - -bool StringStream::ReserveSize(size_t size) { - if (read_only_) - return false; - str_.reserve(size); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// StreamReference -/////////////////////////////////////////////////////////////////////////////// - -StreamReference::StreamReference(StreamInterface* stream) - : StreamAdapterInterface(stream, false) { - // owner set to false so the destructor does not free the stream. - stream_ref_count_ = new StreamRefCount(stream); -} - -StreamInterface* StreamReference::NewReference() { - stream_ref_count_->AddReference(); - return new StreamReference(stream_ref_count_, stream()); -} - -StreamReference::~StreamReference() { - stream_ref_count_->Release(); -} - -StreamReference::StreamReference(StreamRefCount* stream_ref_count, - StreamInterface* stream) - : StreamAdapterInterface(stream, false), - stream_ref_count_(stream_ref_count) { -} - -/////////////////////////////////////////////////////////////////////////////// - -StreamResult Flow(StreamInterface* source, - char* buffer, size_t buffer_len, - StreamInterface* sink, - size_t* data_len /* = NULL */) { - ASSERT(buffer_len > 0); - - StreamResult result; - size_t count, read_pos, write_pos; - if (data_len) { - read_pos = *data_len; - } else { - read_pos = 0; - } - - bool end_of_stream = false; - do { - // Read until buffer is full, end of stream, or error - while (!end_of_stream && (read_pos < buffer_len)) { - result = source->Read(buffer + read_pos, buffer_len - read_pos, - &count, NULL); - if (result == SR_EOS) { - end_of_stream = true; - } else if (result != SR_SUCCESS) { - if (data_len) { - *data_len = read_pos; - } - return result; - } else { - read_pos += count; - } - } - - // Write until buffer is empty, or error (including end of stream) - write_pos = 0; - while (write_pos < read_pos) { - result = sink->Write(buffer + write_pos, read_pos - write_pos, - &count, NULL); - if (result != SR_SUCCESS) { - if (data_len) { - *data_len = read_pos - write_pos; - if (write_pos > 0) { - memmove(buffer, buffer + write_pos, *data_len); - } - } - return result; - } - write_pos += count; - } - - read_pos = 0; - } while (!end_of_stream); - - if (data_len) { - *data_len = 0; - } - return SR_SUCCESS; -} - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/stream.h b/webrtc/base/stream.h deleted file mode 100644 index 00ded372c..000000000 --- a/webrtc/base/stream.h +++ /dev/null @@ -1,820 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_STREAM_H_ -#define WEBRTC_BASE_STREAM_H_ - -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/buffer.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/messagequeue.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/sigslot.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// StreamInterface is a generic asynchronous stream interface, supporting read, -// write, and close operations, and asynchronous signalling of state changes. -// The interface is designed with file, memory, and socket implementations in -// mind. Some implementations offer extended operations, such as seeking. -/////////////////////////////////////////////////////////////////////////////// - -// The following enumerations are declared outside of the StreamInterface -// class for brevity in use. - -// The SS_OPENING state indicates that the stream will signal open or closed -// in the future. -enum StreamState { SS_CLOSED, SS_OPENING, SS_OPEN }; - -// Stream read/write methods return this value to indicate various success -// and failure conditions described below. -enum StreamResult { SR_ERROR, SR_SUCCESS, SR_BLOCK, SR_EOS }; - -// StreamEvents are used to asynchronously signal state transitionss. The flags -// may be combined. -// SE_OPEN: The stream has transitioned to the SS_OPEN state -// SE_CLOSE: The stream has transitioned to the SS_CLOSED state -// SE_READ: Data is available, so Read is likely to not return SR_BLOCK -// SE_WRITE: Data can be written, so Write is likely to not return SR_BLOCK -enum StreamEvent { SE_OPEN = 1, SE_READ = 2, SE_WRITE = 4, SE_CLOSE = 8 }; - -class Thread; - -struct StreamEventData : public MessageData { - int events, error; - StreamEventData(int ev, int er) : events(ev), error(er) { } -}; - -class StreamInterface : public MessageHandler { - public: - enum { - MSG_POST_EVENT = 0xF1F1, MSG_MAX = MSG_POST_EVENT - }; - - virtual ~StreamInterface(); - - virtual StreamState GetState() const = 0; - - // Read attempts to fill buffer of size buffer_len. Write attempts to send - // data_len bytes stored in data. The variables read and write are set only - // on SR_SUCCESS (see below). Likewise, error is only set on SR_ERROR. - // Read and Write return a value indicating: - // SR_ERROR: an error occurred, which is returned in a non-null error - // argument. Interpretation of the error requires knowledge of the - // stream's concrete type, which limits its usefulness. - // SR_SUCCESS: some number of bytes were successfully written, which is - // returned in a non-null read/write argument. - // SR_BLOCK: the stream is in non-blocking mode, and the operation would - // block, or the stream is in SS_OPENING state. - // SR_EOS: the end-of-stream has been reached, or the stream is in the - // SS_CLOSED state. - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error) = 0; - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error) = 0; - // Attempt to transition to the SS_CLOSED state. SE_CLOSE will not be - // signalled as a result of this call. - virtual void Close() = 0; - - // Streams may signal one or more StreamEvents to indicate state changes. - // The first argument identifies the stream on which the state change occured. - // The second argument is a bit-wise combination of StreamEvents. - // If SE_CLOSE is signalled, then the third argument is the associated error - // code. Otherwise, the value is undefined. - // Note: Not all streams will support asynchronous event signalling. However, - // SS_OPENING and SR_BLOCK returned from stream member functions imply that - // certain events will be raised in the future. - sigslot::signal3 SignalEvent; - - // Like calling SignalEvent, but posts a message to the specified thread, - // which will call SignalEvent. This helps unroll the stack and prevent - // re-entrancy. - void PostEvent(Thread* t, int events, int err); - // Like the aforementioned method, but posts to the current thread. - void PostEvent(int events, int err); - - // - // OPTIONAL OPERATIONS - // - // Not all implementations will support the following operations. In general, - // a stream will only support an operation if it reasonably efficient to do - // so. For example, while a socket could buffer incoming data to support - // seeking, it will not do so. Instead, a buffering stream adapter should - // be used. - // - // Even though several of these operations are related, you should - // always use whichever operation is most relevant. For example, you may - // be tempted to use GetSize() and GetPosition() to deduce the result of - // GetAvailable(). However, a stream which is read-once may support the - // latter operation but not the former. - // - - // The following four methods are used to avoid copying data multiple times. - - // GetReadData returns a pointer to a buffer which is owned by the stream. - // The buffer contains data_len bytes. NULL is returned if no data is - // available, or if the method fails. If the caller processes the data, it - // must call ConsumeReadData with the number of processed bytes. GetReadData - // does not require a matching call to ConsumeReadData if the data is not - // processed. Read and ConsumeReadData invalidate the buffer returned by - // GetReadData. - virtual const void* GetReadData(size_t* data_len) { return NULL; } - virtual void ConsumeReadData(size_t used) {} - - // GetWriteBuffer returns a pointer to a buffer which is owned by the stream. - // The buffer has a capacity of buf_len bytes. NULL is returned if there is - // no buffer available, or if the method fails. The call may write data to - // the buffer, and then call ConsumeWriteBuffer with the number of bytes - // written. GetWriteBuffer does not require a matching call to - // ConsumeWriteData if no data is written. Write, ForceWrite, and - // ConsumeWriteData invalidate the buffer returned by GetWriteBuffer. - // TODO: Allow the caller to specify a minimum buffer size. If the specified - // amount of buffer is not yet available, return NULL and Signal SE_WRITE - // when it is available. If the requested amount is too large, return an - // error. - virtual void* GetWriteBuffer(size_t* buf_len) { return NULL; } - virtual void ConsumeWriteBuffer(size_t used) {} - - // Write data_len bytes found in data, circumventing any throttling which - // would could cause SR_BLOCK to be returned. Returns true if all the data - // was written. Otherwise, the method is unsupported, or an unrecoverable - // error occurred, and the error value is set. This method should be used - // sparingly to write critical data which should not be throttled. A stream - // which cannot circumvent its blocking constraints should not implement this - // method. - // NOTE: This interface is being considered experimentally at the moment. It - // would be used by JUDP and BandwidthStream as a way to circumvent certain - // soft limits in writing. - //virtual bool ForceWrite(const void* data, size_t data_len, int* error) { - // if (error) *error = -1; - // return false; - //} - - // Seek to a byte offset from the beginning of the stream. Returns false if - // the stream does not support seeking, or cannot seek to the specified - // position. - virtual bool SetPosition(size_t position) { return false; } - - // Get the byte offset of the current position from the start of the stream. - // Returns false if the position is not known. - virtual bool GetPosition(size_t* position) const { return false; } - - // Get the byte length of the entire stream. Returns false if the length - // is not known. - virtual bool GetSize(size_t* size) const { return false; } - - // Return the number of Read()-able bytes remaining before end-of-stream. - // Returns false if not known. - virtual bool GetAvailable(size_t* size) const { return false; } - - // Return the number of Write()-able bytes remaining before end-of-stream. - // Returns false if not known. - virtual bool GetWriteRemaining(size_t* size) const { return false; } - - // Return true if flush is successful. - virtual bool Flush() { return false; } - - // Communicates the amount of data which will be written to the stream. The - // stream may choose to preallocate memory to accomodate this data. The - // stream may return false to indicate that there is not enough room (ie, - // Write will return SR_EOS/SR_ERROR at some point). Note that calling this - // function should not affect the existing state of data in the stream. - virtual bool ReserveSize(size_t size) { return true; } - - // - // CONVENIENCE METHODS - // - // These methods are implemented in terms of other methods, for convenience. - // - - // Seek to the start of the stream. - inline bool Rewind() { return SetPosition(0); } - - // WriteAll is a helper function which repeatedly calls Write until all the - // data is written, or something other than SR_SUCCESS is returned. Note that - // unlike Write, the argument 'written' is always set, and may be non-zero - // on results other than SR_SUCCESS. The remaining arguments have the - // same semantics as Write. - StreamResult WriteAll(const void* data, size_t data_len, - size_t* written, int* error); - - // Similar to ReadAll. Calls Read until buffer_len bytes have been read, or - // until a non-SR_SUCCESS result is returned. 'read' is always set. - StreamResult ReadAll(void* buffer, size_t buffer_len, - size_t* read, int* error); - - // ReadLine is a helper function which repeatedly calls Read until it hits - // the end-of-line character, or something other than SR_SUCCESS. - // TODO: this is too inefficient to keep here. Break this out into a buffered - // readline object or adapter - StreamResult ReadLine(std::string* line); - - protected: - StreamInterface(); - - // MessageHandler Interface - virtual void OnMessage(Message* msg); - - private: - DISALLOW_EVIL_CONSTRUCTORS(StreamInterface); -}; - -/////////////////////////////////////////////////////////////////////////////// -// StreamAdapterInterface is a convenient base-class for adapting a stream. -// By default, all operations are pass-through. Override the methods that you -// require adaptation. Streams should really be upgraded to reference-counted. -// In the meantime, use the owned flag to indicate whether the adapter should -// own the adapted stream. -/////////////////////////////////////////////////////////////////////////////// - -class StreamAdapterInterface : public StreamInterface, - public sigslot::has_slots<> { - public: - explicit StreamAdapterInterface(StreamInterface* stream, bool owned = true); - - // Core Stream Interface - virtual StreamState GetState() const { - return stream_->GetState(); - } - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - return stream_->Read(buffer, buffer_len, read, error); - } - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error) { - return stream_->Write(data, data_len, written, error); - } - virtual void Close() { - stream_->Close(); - } - - // Optional Stream Interface - /* Note: Many stream adapters were implemented prior to this Read/Write - interface. Therefore, a simple pass through of data in those cases may - be broken. At a later time, we should do a once-over pass of all - adapters, and make them compliant with these interfaces, after which this - code can be uncommented. - virtual const void* GetReadData(size_t* data_len) { - return stream_->GetReadData(data_len); - } - virtual void ConsumeReadData(size_t used) { - stream_->ConsumeReadData(used); - } - - virtual void* GetWriteBuffer(size_t* buf_len) { - return stream_->GetWriteBuffer(buf_len); - } - virtual void ConsumeWriteBuffer(size_t used) { - stream_->ConsumeWriteBuffer(used); - } - */ - - /* Note: This interface is currently undergoing evaluation. - virtual bool ForceWrite(const void* data, size_t data_len, int* error) { - return stream_->ForceWrite(data, data_len, error); - } - */ - - virtual bool SetPosition(size_t position) { - return stream_->SetPosition(position); - } - virtual bool GetPosition(size_t* position) const { - return stream_->GetPosition(position); - } - virtual bool GetSize(size_t* size) const { - return stream_->GetSize(size); - } - virtual bool GetAvailable(size_t* size) const { - return stream_->GetAvailable(size); - } - virtual bool GetWriteRemaining(size_t* size) const { - return stream_->GetWriteRemaining(size); - } - virtual bool ReserveSize(size_t size) { - return stream_->ReserveSize(size); - } - virtual bool Flush() { - return stream_->Flush(); - } - - void Attach(StreamInterface* stream, bool owned = true); - StreamInterface* Detach(); - - protected: - virtual ~StreamAdapterInterface(); - - // Note that the adapter presents itself as the origin of the stream events, - // since users of the adapter may not recognize the adapted object. - virtual void OnEvent(StreamInterface* stream, int events, int err) { - SignalEvent(this, events, err); - } - StreamInterface* stream() { return stream_; } - - private: - StreamInterface* stream_; - bool owned_; - DISALLOW_EVIL_CONSTRUCTORS(StreamAdapterInterface); -}; - -/////////////////////////////////////////////////////////////////////////////// -// StreamTap is a non-modifying, pass-through adapter, which copies all data -// in either direction to the tap. Note that errors or blocking on writing to -// the tap will prevent further tap writes from occurring. -/////////////////////////////////////////////////////////////////////////////// - -class StreamTap : public StreamAdapterInterface { - public: - explicit StreamTap(StreamInterface* stream, StreamInterface* tap); - - void AttachTap(StreamInterface* tap); - StreamInterface* DetachTap(); - StreamResult GetTapResult(int* error); - - // StreamAdapterInterface Interface - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - - private: - scoped_ptr tap_; - StreamResult tap_result_; - int tap_error_; - DISALLOW_EVIL_CONSTRUCTORS(StreamTap); -}; - -/////////////////////////////////////////////////////////////////////////////// -// StreamSegment adapts a read stream, to expose a subset of the adapted -// stream's data. This is useful for cases where a stream contains multiple -// documents concatenated together. StreamSegment can expose a subset of -// the data as an independent stream, including support for rewinding and -// seeking. -/////////////////////////////////////////////////////////////////////////////// - -class StreamSegment : public StreamAdapterInterface { - public: - // The current position of the adapted stream becomes the beginning of the - // segment. If a length is specified, it bounds the length of the segment. - explicit StreamSegment(StreamInterface* stream); - explicit StreamSegment(StreamInterface* stream, size_t length); - - // StreamAdapterInterface Interface - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - virtual bool SetPosition(size_t position); - virtual bool GetPosition(size_t* position) const; - virtual bool GetSize(size_t* size) const; - virtual bool GetAvailable(size_t* size) const; - - private: - size_t start_, pos_, length_; - DISALLOW_EVIL_CONSTRUCTORS(StreamSegment); -}; - -/////////////////////////////////////////////////////////////////////////////// -// NullStream gives errors on read, and silently discards all written data. -/////////////////////////////////////////////////////////////////////////////// - -class NullStream : public StreamInterface { - public: - NullStream(); - virtual ~NullStream(); - - // StreamInterface Interface - virtual StreamState GetState() const; - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - virtual void Close(); -}; - -/////////////////////////////////////////////////////////////////////////////// -// FileStream is a simple implementation of a StreamInterface, which does not -// support asynchronous notification. -/////////////////////////////////////////////////////////////////////////////// - -class FileStream : public StreamInterface { - public: - FileStream(); - virtual ~FileStream(); - - // The semantics of filename and mode are the same as stdio's fopen - virtual bool Open(const std::string& filename, const char* mode, int* error); - virtual bool OpenShare(const std::string& filename, const char* mode, - int shflag, int* error); - - // By default, reads and writes are buffered for efficiency. Disabling - // buffering causes writes to block until the bytes on disk are updated. - virtual bool DisableBuffering(); - - virtual StreamState GetState() const; - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - virtual void Close(); - virtual bool SetPosition(size_t position); - virtual bool GetPosition(size_t* position) const; - virtual bool GetSize(size_t* size) const; - virtual bool GetAvailable(size_t* size) const; - virtual bool ReserveSize(size_t size); - - virtual bool Flush(); - -#if defined(WEBRTC_POSIX) && !defined(__native_client__) - // Tries to aquire an exclusive lock on the file. - // Use OpenShare(...) on win32 to get similar functionality. - bool TryLock(); - bool Unlock(); -#endif - - // Note: Deprecated in favor of Filesystem::GetFileSize(). - static bool GetSize(const std::string& filename, size_t* size); - - protected: - virtual void DoClose(); - - FILE* file_; - - private: - DISALLOW_EVIL_CONSTRUCTORS(FileStream); -}; - -// A stream that caps the output at a certain size, dropping content from the -// middle of the logical stream and maintaining equal parts of the start/end of -// the logical stream. -class CircularFileStream : public FileStream { - public: - explicit CircularFileStream(size_t max_size); - - virtual bool Open(const std::string& filename, const char* mode, int* error); - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - - private: - enum ReadSegment { - READ_MARKED, // Read 0 .. marked_position_ - READ_MIDDLE, // Read position_ .. file_size - READ_LATEST, // Read marked_position_ .. position_ if the buffer was - // overwritten or 0 .. position_ otherwise. - }; - - size_t max_write_size_; - size_t position_; - size_t marked_position_; - size_t last_write_position_; - ReadSegment read_segment_; - 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 { - public: - // Takes ownership of the stream, but not the thread. - AsyncWriteStream(StreamInterface* stream, rtc::Thread* write_thread) - : stream_(stream), - write_thread_(write_thread), - state_(stream ? stream->GetState() : SS_CLOSED) { - } - - virtual ~AsyncWriteStream(); - - // StreamInterface Interface - virtual StreamState GetState() const { return state_; } - // This is needed by some stream writers, such as RtpDumpWriter. - virtual bool GetPosition(size_t* position) const; - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - virtual void Close(); - virtual bool Flush(); - - protected: - // From MessageHandler - virtual void OnMessage(rtc::Message* pmsg); - virtual void ClearBufferAndWrite(); - - private: - rtc::scoped_ptr stream_; - Thread* write_thread_; - StreamState state_; - Buffer buffer_; - mutable CriticalSection crit_stream_; - CriticalSection crit_buffer_; - - DISALLOW_EVIL_CONSTRUCTORS(AsyncWriteStream); -}; - - -#if defined(WEBRTC_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. -class POpenStream : public FileStream { - public: - POpenStream() : wait_status_(-1) {} - virtual ~POpenStream(); - - virtual bool Open(const std::string& subcommand, const char* mode, - int* error); - // Same as Open(). shflag is ignored. - virtual bool OpenShare(const std::string& subcommand, const char* mode, - int shflag, int* error); - - // Returns the wait status from the last Close() of an Open()'ed stream, or - // -1 if no Open()+Close() has been done on this object. Meaning of the number - // is documented in "man 2 wait". - int GetWaitStatus() const { return wait_status_; } - - protected: - virtual void DoClose(); - - private: - int wait_status_; -}; -#endif // WEBRTC_POSIX - -/////////////////////////////////////////////////////////////////////////////// -// MemoryStream is a simple implementation of a StreamInterface over in-memory -// data. Data is read and written at the current seek position. Reads return -// end-of-stream when they reach the end of data. Writes actually extend the -// end of data mark. -/////////////////////////////////////////////////////////////////////////////// - -class MemoryStreamBase : public StreamInterface { - public: - virtual StreamState GetState() const; - virtual StreamResult Read(void* buffer, size_t bytes, size_t* bytes_read, - int* error); - virtual StreamResult Write(const void* buffer, size_t bytes, - size_t* bytes_written, int* error); - virtual void Close(); - virtual bool SetPosition(size_t position); - virtual bool GetPosition(size_t* position) const; - virtual bool GetSize(size_t* size) const; - virtual bool GetAvailable(size_t* size) const; - virtual bool ReserveSize(size_t size); - - char* GetBuffer() { return buffer_; } - const char* GetBuffer() const { return buffer_; } - - protected: - MemoryStreamBase(); - - virtual StreamResult DoReserve(size_t size, int* error); - - // Invariant: 0 <= seek_position <= data_length_ <= buffer_length_ - char* buffer_; - size_t buffer_length_; - size_t data_length_; - size_t seek_position_; - - private: - DISALLOW_EVIL_CONSTRUCTORS(MemoryStreamBase); -}; - -// MemoryStream dynamically resizes to accomodate written data. - -class MemoryStream : public MemoryStreamBase { - public: - MemoryStream(); - explicit MemoryStream(const char* data); // Calls SetData(data, strlen(data)) - MemoryStream(const void* data, size_t length); // Calls SetData(data, length) - virtual ~MemoryStream(); - - void SetData(const void* data, size_t length); - - protected: - virtual StreamResult DoReserve(size_t size, int* error); - // Memory Streams are aligned for efficiency. - static const int kAlignment = 16; - char* buffer_alloc_; -}; - -// ExternalMemoryStream adapts an external memory buffer, so writes which would -// extend past the end of the buffer will return end-of-stream. - -class ExternalMemoryStream : public MemoryStreamBase { - public: - ExternalMemoryStream(); - ExternalMemoryStream(void* data, size_t length); - virtual ~ExternalMemoryStream(); - - void SetData(void* data, size_t length); -}; - -// FifoBuffer allows for efficient, thread-safe buffering of data between -// writer and reader. As the data can wrap around the end of the buffer, -// MemoryStreamBase can't help us here. - -class FifoBuffer : public StreamInterface { - public: - // Creates a FIFO buffer with the specified capacity. - explicit FifoBuffer(size_t length); - // Creates a FIFO buffer with the specified capacity and owner - FifoBuffer(size_t length, Thread* owner); - virtual ~FifoBuffer(); - // Gets the amount of data currently readable from the buffer. - bool GetBuffered(size_t* data_len) const; - // Resizes the buffer to the specified capacity. Fails if data_length_ > size - bool SetCapacity(size_t length); - - // Read into |buffer| with an offset from the current read position, offset - // is specified in number of bytes. - // This method doesn't adjust read position nor the number of available - // bytes, user has to call ConsumeReadData() to do this. - StreamResult ReadOffset(void* buffer, size_t bytes, size_t offset, - size_t* bytes_read); - - // Write |buffer| with an offset from the current write position, offset is - // specified in number of bytes. - // This method doesn't adjust the number of buffered bytes, user has to call - // ConsumeWriteBuffer() to do this. - StreamResult WriteOffset(const void* buffer, size_t bytes, size_t offset, - size_t* bytes_written); - - // StreamInterface methods - virtual StreamState GetState() const; - virtual StreamResult Read(void* buffer, size_t bytes, - size_t* bytes_read, int* error); - virtual StreamResult Write(const void* buffer, size_t bytes, - size_t* bytes_written, int* error); - virtual void Close(); - virtual const void* GetReadData(size_t* data_len); - virtual void ConsumeReadData(size_t used); - virtual void* GetWriteBuffer(size_t* buf_len); - virtual void ConsumeWriteBuffer(size_t used); - virtual bool GetWriteRemaining(size_t* size) const; - - private: - // Helper method that implements ReadOffset. Caller must acquire a lock - // when calling this method. - StreamResult ReadOffsetLocked(void* buffer, size_t bytes, size_t offset, - size_t* bytes_read); - - // Helper method that implements WriteOffset. Caller must acquire a lock - // when calling this method. - StreamResult WriteOffsetLocked(const void* buffer, size_t bytes, - size_t offset, size_t* bytes_written); - - StreamState state_; // keeps the opened/closed state of the stream - scoped_ptr buffer_; // the allocated buffer - size_t buffer_length_; // size of the allocated buffer - size_t data_length_; // amount of readable data in the buffer - size_t read_position_; // offset to the readable data - Thread* owner_; // stream callbacks are dispatched on this thread - mutable CriticalSection crit_; // object lock - DISALLOW_EVIL_CONSTRUCTORS(FifoBuffer); -}; - -/////////////////////////////////////////////////////////////////////////////// - -class LoggingAdapter : public StreamAdapterInterface { - public: - LoggingAdapter(StreamInterface* stream, LoggingSeverity level, - const std::string& label, bool hex_mode = false); - - void set_label(const std::string& label); - - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - virtual void Close(); - - protected: - virtual void OnEvent(StreamInterface* stream, int events, int err); - - private: - LoggingSeverity level_; - std::string label_; - bool hex_mode_; - LogMultilineState lms_; - - DISALLOW_EVIL_CONSTRUCTORS(LoggingAdapter); -}; - -/////////////////////////////////////////////////////////////////////////////// -// StringStream - Reads/Writes to an external std::string -/////////////////////////////////////////////////////////////////////////////// - -class StringStream : public StreamInterface { - public: - explicit StringStream(std::string& str); - explicit StringStream(const std::string& str); - - virtual StreamState GetState() const; - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error); - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error); - virtual void Close(); - virtual bool SetPosition(size_t position); - virtual bool GetPosition(size_t* position) const; - virtual bool GetSize(size_t* size) const; - virtual bool GetAvailable(size_t* size) const; - virtual bool ReserveSize(size_t size); - - private: - std::string& str_; - size_t read_pos_; - bool read_only_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// StreamReference - A reference counting stream adapter -/////////////////////////////////////////////////////////////////////////////// - -// Keep in mind that the streams and adapters defined in this file are -// not thread-safe, so this has limited uses. - -// A StreamRefCount holds the reference count and a pointer to the -// wrapped stream. It deletes the wrapped stream when there are no -// more references. We can then have multiple StreamReference -// instances pointing to one StreamRefCount, all wrapping the same -// stream. - -class StreamReference : public StreamAdapterInterface { - class StreamRefCount; - public: - // Constructor for the first reference to a stream - // Note: get more references through NewReference(). Use this - // constructor only once on a given stream. - explicit StreamReference(StreamInterface* stream); - StreamInterface* GetStream() { return stream(); } - StreamInterface* NewReference(); - virtual ~StreamReference(); - - private: - class StreamRefCount { - public: - explicit StreamRefCount(StreamInterface* stream) - : stream_(stream), ref_count_(1) { - } - void AddReference() { - CritScope lock(&cs_); - ++ref_count_; - } - void Release() { - int ref_count; - { // Atomic ops would have been a better fit here. - CritScope lock(&cs_); - ref_count = --ref_count_; - } - if (ref_count == 0) { - delete stream_; - delete this; - } - } - private: - StreamInterface* stream_; - int ref_count_; - CriticalSection cs_; - DISALLOW_EVIL_CONSTRUCTORS(StreamRefCount); - }; - - // Constructor for adding references - explicit StreamReference(StreamRefCount* stream_ref_count, - StreamInterface* stream); - - StreamRefCount* stream_ref_count_; - DISALLOW_EVIL_CONSTRUCTORS(StreamReference); -}; - -/////////////////////////////////////////////////////////////////////////////// - -// Flow attempts to move bytes from source to sink via buffer of size -// buffer_len. The function returns SR_SUCCESS when source reaches -// end-of-stream (returns SR_EOS), and all the data has been written successful -// to sink. Alternately, if source returns SR_BLOCK or SR_ERROR, or if sink -// returns SR_BLOCK, SR_ERROR, or SR_EOS, then the function immediately returns -// with the unexpected StreamResult value. -// data_len is the length of the valid data in buffer. in case of error -// this is the data that read from source but can't move to destination. -// as a pass in parameter, it indicates data in buffer that should move to sink -StreamResult Flow(StreamInterface* source, - char* buffer, size_t buffer_len, - StreamInterface* sink, size_t* data_len = NULL); - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_STREAM_H_ diff --git a/webrtc/base/stream_unittest.cc b/webrtc/base/stream_unittest.cc deleted file mode 100644 index a6664d716..000000000 --- a/webrtc/base/stream_unittest.cc +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/stream.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// TestStream -/////////////////////////////////////////////////////////////////////////////// - -class TestStream : public StreamInterface { - public: - TestStream() : pos_(0) { } - - virtual StreamState GetState() const { return SS_OPEN; } - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - unsigned char* uc_buffer = static_cast(buffer); - for (size_t i = 0; i < buffer_len; ++i) { - uc_buffer[i] = static_cast(pos_++); - } - if (read) - *read = buffer_len; - return SR_SUCCESS; - } - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error) { - if (error) - *error = -1; - return SR_ERROR; - } - virtual void Close() { } - virtual bool SetPosition(size_t position) { - pos_ = position; - return true; - } - virtual bool GetPosition(size_t* position) const { - if (position) *position = pos_; - return true; - } - virtual bool GetSize(size_t* size) const { - return false; - } - virtual bool GetAvailable(size_t* size) const { - return false; - } - - private: - size_t pos_; -}; - -bool VerifyTestBuffer(unsigned char* buffer, size_t len, - unsigned char value) { - bool passed = true; - for (size_t i = 0; i < len; ++i) { - if (buffer[i] != value++) { - passed = false; - break; - } - } - // Ensure that we don't pass again without re-writing - memset(buffer, 0, len); - return passed; -} - -void SeekTest(StreamInterface* stream, const unsigned char value) { - size_t bytes; - unsigned char buffer[13] = { 0 }; - const size_t kBufSize = sizeof(buffer); - - EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); - EXPECT_EQ(bytes, kBufSize); - EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, value)); - EXPECT_TRUE(stream->GetPosition(&bytes)); - EXPECT_EQ(13U, bytes); - - EXPECT_TRUE(stream->SetPosition(7)); - - EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); - EXPECT_EQ(bytes, kBufSize); - EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, value + 7)); - EXPECT_TRUE(stream->GetPosition(&bytes)); - EXPECT_EQ(20U, bytes); -} - -TEST(StreamSegment, TranslatesPosition) { - TestStream* test = new TestStream; - // Verify behavior of original stream - SeekTest(test, 0); - StreamSegment* segment = new StreamSegment(test); - // Verify behavior of adapted stream (all values offset by 20) - SeekTest(segment, 20); - delete segment; -} - -TEST(StreamSegment, SupportsArtificialTermination) { - TestStream* test = new TestStream; - - size_t bytes; - unsigned char buffer[5000] = { 0 }; - const size_t kBufSize = sizeof(buffer); - - { - StreamInterface* stream = test; - - // Read a lot of bytes - EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); - EXPECT_EQ(bytes, kBufSize); - EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, 0)); - - // Test seeking far ahead - EXPECT_TRUE(stream->SetPosition(12345)); - - // Read a bunch more bytes - EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); - EXPECT_EQ(bytes, kBufSize); - EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, 12345 % 256)); - } - - // Create a segment of test stream in range [100,600) - EXPECT_TRUE(test->SetPosition(100)); - StreamSegment* segment = new StreamSegment(test, 500); - - { - StreamInterface* stream = segment; - - EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); - EXPECT_EQ(500U, bytes); - EXPECT_TRUE(VerifyTestBuffer(buffer, 500, 100)); - EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_EOS); - - // Test seeking past "end" of stream - EXPECT_FALSE(stream->SetPosition(12345)); - EXPECT_FALSE(stream->SetPosition(501)); - - // Test seeking to end (edge case) - EXPECT_TRUE(stream->SetPosition(500)); - EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_EOS); - - // Test seeking to start - EXPECT_TRUE(stream->SetPosition(0)); - EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); - EXPECT_EQ(500U, bytes); - EXPECT_TRUE(VerifyTestBuffer(buffer, 500, 100)); - EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_EOS); - } - - delete segment; -} - -TEST(FifoBufferTest, TestAll) { - const size_t kSize = 16; - const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; - char out[kSize * 2]; - void* p; - const void* q; - size_t bytes; - FifoBuffer buf(kSize); - StreamInterface* stream = &buf; - - // Test assumptions about base state - EXPECT_EQ(SS_OPEN, stream->GetState()); - EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); - EXPECT_TRUE(NULL != stream->GetReadData(&bytes)); - EXPECT_EQ((size_t)0, bytes); - stream->ConsumeReadData(0); - EXPECT_TRUE(NULL != stream->GetWriteBuffer(&bytes)); - EXPECT_EQ(kSize, bytes); - stream->ConsumeWriteBuffer(0); - - // Try a full write - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); - EXPECT_EQ(kSize, bytes); - - // Try a write that should block - EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, NULL)); - - // Try a full read - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); - EXPECT_EQ(kSize, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize)); - - // Try a read that should block - EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); - - // Try a too-big write - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 2, &bytes, NULL)); - EXPECT_EQ(bytes, kSize); - - // Try a too-big read - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, NULL)); - EXPECT_EQ(kSize, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize)); - - // Try some small writes and reads - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize / 2)); - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize / 2)); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize / 2)); - - // Try wraparound reads and writes in the following pattern - // WWWWWWWWWWWW.... 0123456789AB.... - // RRRRRRRRXXXX.... ........89AB.... - // WWWW....XXXXWWWW 4567....89AB0123 - // XXXX....RRRRXXXX 4567........0123 - // XXXXWWWWWWWWXXXX 4567012345670123 - // RRRRXXXXXXXXRRRR ....01234567.... - // ....RRRRRRRR.... ................ - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, NULL)); - EXPECT_EQ(kSize * 3 / 4, bytes); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize / 2)); - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 4, &bytes, NULL)); - EXPECT_EQ(kSize / 4 , bytes); - EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4)); - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2 , bytes); - EXPECT_EQ(0, memcmp(in, out, kSize / 2)); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); - EXPECT_EQ(kSize / 2 , bytes); - EXPECT_EQ(0, memcmp(in, out, kSize / 2)); - - // Use GetWriteBuffer to reset the read_position for the next tests - stream->GetWriteBuffer(&bytes); - stream->ConsumeWriteBuffer(0); - - // Try using GetReadData to do a full read - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); - q = stream->GetReadData(&bytes); - EXPECT_TRUE(NULL != q); - EXPECT_EQ(kSize, bytes); - EXPECT_EQ(0, memcmp(q, in, kSize)); - stream->ConsumeReadData(kSize); - EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); - - // Try using GetReadData to do some small reads - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); - q = stream->GetReadData(&bytes); - EXPECT_TRUE(NULL != q); - EXPECT_EQ(kSize, bytes); - EXPECT_EQ(0, memcmp(q, in, kSize / 2)); - stream->ConsumeReadData(kSize / 2); - q = stream->GetReadData(&bytes); - EXPECT_TRUE(NULL != q); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(0, memcmp(q, in + kSize / 2, kSize / 2)); - stream->ConsumeReadData(kSize / 2); - EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); - - // Try using GetReadData in a wraparound case - // WWWWWWWWWWWWWWWW 0123456789ABCDEF - // RRRRRRRRRRRRXXXX ............CDEF - // WWWWWWWW....XXXX 01234567....CDEF - // ............RRRR 01234567........ - // RRRRRRRR........ ................ - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, NULL)); - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); - q = stream->GetReadData(&bytes); - EXPECT_TRUE(NULL != q); - EXPECT_EQ(kSize / 4, bytes); - EXPECT_EQ(0, memcmp(q, in + kSize * 3 / 4, kSize / 4)); - stream->ConsumeReadData(kSize / 4); - q = stream->GetReadData(&bytes); - EXPECT_TRUE(NULL != q); - EXPECT_EQ(kSize / 2, bytes); - EXPECT_EQ(0, memcmp(q, in, kSize / 2)); - stream->ConsumeReadData(kSize / 2); - - // Use GetWriteBuffer to reset the read_position for the next tests - stream->GetWriteBuffer(&bytes); - stream->ConsumeWriteBuffer(0); - - // Try using GetWriteBuffer to do a full write - p = stream->GetWriteBuffer(&bytes); - EXPECT_TRUE(NULL != p); - EXPECT_EQ(kSize, bytes); - memcpy(p, in, kSize); - stream->ConsumeWriteBuffer(kSize); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); - EXPECT_EQ(kSize, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize)); - - // Try using GetWriteBuffer to do some small writes - p = stream->GetWriteBuffer(&bytes); - EXPECT_TRUE(NULL != p); - EXPECT_EQ(kSize, bytes); - memcpy(p, in, kSize / 2); - stream->ConsumeWriteBuffer(kSize / 2); - p = stream->GetWriteBuffer(&bytes); - EXPECT_TRUE(NULL != p); - EXPECT_EQ(kSize / 2, bytes); - memcpy(p, in + kSize / 2, kSize / 2); - stream->ConsumeWriteBuffer(kSize / 2); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); - EXPECT_EQ(kSize, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize)); - - // Try using GetWriteBuffer in a wraparound case - // WWWWWWWWWWWW.... 0123456789AB.... - // RRRRRRRRXXXX.... ........89AB.... - // ........XXXXWWWW ........89AB0123 - // WWWW....XXXXXXXX 4567....89AB0123 - // RRRR....RRRRRRRR ................ - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, NULL)); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); - p = stream->GetWriteBuffer(&bytes); - EXPECT_TRUE(NULL != p); - EXPECT_EQ(kSize / 4, bytes); - memcpy(p, in, kSize / 4); - stream->ConsumeWriteBuffer(kSize / 4); - p = stream->GetWriteBuffer(&bytes); - EXPECT_TRUE(NULL != p); - EXPECT_EQ(kSize / 2, bytes); - memcpy(p, in + kSize / 4, kSize / 4); - stream->ConsumeWriteBuffer(kSize / 4); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, NULL)); - EXPECT_EQ(kSize * 3 / 4, bytes); - EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4)); - EXPECT_EQ(0, memcmp(in, out + kSize / 4, kSize / 4)); - - // Check that the stream is now empty - EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); - - // Try growing the buffer - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); - EXPECT_EQ(kSize, bytes); - EXPECT_TRUE(buf.SetCapacity(kSize * 2)); - EXPECT_EQ(SR_SUCCESS, stream->Write(in + kSize, kSize, &bytes, NULL)); - EXPECT_EQ(kSize, bytes); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, NULL)); - EXPECT_EQ(kSize * 2, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize * 2)); - - // Try shrinking the buffer - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); - EXPECT_EQ(kSize, bytes); - EXPECT_TRUE(buf.SetCapacity(kSize)); - EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, NULL)); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); - EXPECT_EQ(kSize, bytes); - EXPECT_EQ(0, memcmp(in, out, kSize)); - - // Write to the stream, close it, read the remaining bytes - EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); - stream->Close(); - EXPECT_EQ(SS_CLOSED, stream->GetState()); - EXPECT_EQ(SR_EOS, stream->Write(in, kSize / 2, &bytes, NULL)); - EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); - EXPECT_EQ(0, memcmp(in, out, kSize / 2)); - EXPECT_EQ(SR_EOS, stream->Read(out, kSize / 2, &bytes, NULL)); -} - -TEST(FifoBufferTest, FullBufferCheck) { - FifoBuffer buff(10); - buff.ConsumeWriteBuffer(10); - - size_t free; - EXPECT_TRUE(buff.GetWriteBuffer(&free) != NULL); - EXPECT_EQ(0U, free); -} - -TEST(FifoBufferTest, WriteOffsetAndReadOffset) { - const size_t kSize = 16; - const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; - char out[kSize * 2]; - FifoBuffer buf(kSize); - - // Write 14 bytes. - EXPECT_EQ(SR_SUCCESS, buf.Write(in, 14, NULL, NULL)); - - // Make sure data is in |buf|. - size_t buffered; - EXPECT_TRUE(buf.GetBuffered(&buffered)); - EXPECT_EQ(14u, buffered); - - // Read 10 bytes. - buf.ConsumeReadData(10); - - // There should be now 12 bytes of available space. - size_t remaining; - EXPECT_TRUE(buf.GetWriteRemaining(&remaining)); - EXPECT_EQ(12u, remaining); - - // Write at offset 12, this should fail. - EXPECT_EQ(SR_BLOCK, buf.WriteOffset(in, 10, 12, NULL)); - - // Write 8 bytes at offset 4, this wraps around the buffer. - EXPECT_EQ(SR_SUCCESS, buf.WriteOffset(in, 8, 4, NULL)); - - // Number of available space remains the same until we call - // ConsumeWriteBuffer(). - EXPECT_TRUE(buf.GetWriteRemaining(&remaining)); - EXPECT_EQ(12u, remaining); - buf.ConsumeWriteBuffer(12); - - // There's 4 bytes bypassed and 4 bytes no read so skip them and verify the - // 8 bytes written. - size_t read; - EXPECT_EQ(SR_SUCCESS, buf.ReadOffset(out, 8, 8, &read)); - EXPECT_EQ(8u, read); - EXPECT_EQ(0, memcmp(out, in, 8)); - - // There should still be 16 bytes available for reading. - EXPECT_TRUE(buf.GetBuffered(&buffered)); - EXPECT_EQ(16u, buffered); - - // Read at offset 16, this should fail since we don't have that much data. - EXPECT_EQ(SR_BLOCK, buf.ReadOffset(out, 10, 16, NULL)); -} - -TEST(AsyncWriteTest, TestWrite) { - FifoBuffer* buf = new FifoBuffer(100); - AsyncWriteStream stream(buf, Thread::Current()); - EXPECT_EQ(SS_OPEN, stream.GetState()); - - // Write "abc". Will go to the logging thread, which is the current - // thread. - stream.Write("abc", 3, NULL, NULL); - char bytes[100]; - size_t count; - // Messages on the thread's queue haven't been processed, so "abc" - // hasn't been written yet. - EXPECT_NE(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 0, &count)); - // Now we process the messages on the thread's queue, so "abc" has - // been written. - EXPECT_TRUE_WAIT(SR_SUCCESS == buf->ReadOffset(&bytes, 3, 0, &count), 10); - EXPECT_EQ(3u, count); - EXPECT_EQ(0, memcmp(bytes, "abc", 3)); - - // Write "def". Will go to the logging thread, which is the current - // thread. - stream.Write("d", 1, &count, NULL); - stream.Write("e", 1, &count, NULL); - stream.Write("f", 1, &count, NULL); - EXPECT_EQ(1u, count); - // Messages on the thread's queue haven't been processed, so "def" - // hasn't been written yet. - EXPECT_NE(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 3, &count)); - // Flush() causes the message to be processed, so "def" has now been - // written. - stream.Flush(); - EXPECT_EQ(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 3, &count)); - EXPECT_EQ(3u, count); - EXPECT_EQ(0, memcmp(bytes, "def", 3)); - - // Write "xyz". Will go to the logging thread, which is the current - // thread. - stream.Write("xyz", 3, &count, NULL); - EXPECT_EQ(3u, count); - // Messages on the thread's queue haven't been processed, so "xyz" - // hasn't been written yet. - EXPECT_NE(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 6, &count)); - // Close() causes the message to be processed, so "xyz" has now been - // written. - stream.Close(); - EXPECT_EQ(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 6, &count)); - EXPECT_EQ(3u, count); - EXPECT_EQ(0, memcmp(bytes, "xyz", 3)); - EXPECT_EQ(SS_CLOSED, stream.GetState()); - - // Is't closed, so the writes should fail. - EXPECT_EQ(SR_ERROR, stream.Write("000", 3, NULL, NULL)); - -} - -} // namespace rtc diff --git a/webrtc/base/stringdigest.h b/webrtc/base/stringdigest.h deleted file mode 100644 index 7cf6f329a..000000000 --- a/webrtc/base/stringdigest.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_STRINGDIGEST_H_ -#define WEBRTC_BASE_STRINGDIGEST_H_ - -// TODO: Update remaining callers to use messagedigest.h instead -#include "webrtc/base/messagedigest.h" - -#endif // WEBRTC_BASE_STRINGDIGEST_H_ diff --git a/webrtc/base/stringencode.cc b/webrtc/base/stringencode.cc deleted file mode 100644 index 1e0a1493c..000000000 --- a/webrtc/base/stringencode.cc +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/stringencode.h" - -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/common.h" -#include "webrtc/base/stringutils.h" - -namespace rtc { - -///////////////////////////////////////////////////////////////////////////// -// String Encoding Utilities -///////////////////////////////////////////////////////////////////////////// - -size_t escape(char * buffer, size_t buflen, - const char * source, size_t srclen, - const char * illegal, char escape) { - ASSERT(NULL != buffer); // TODO: estimate output size - if (buflen <= 0) - return 0; - - size_t srcpos = 0, bufpos = 0; - while ((srcpos < srclen) && (bufpos + 1 < buflen)) { - char ch = source[srcpos++]; - if ((ch == escape) || ::strchr(illegal, ch)) { - if (bufpos + 2 >= buflen) - break; - buffer[bufpos++] = escape; - } - buffer[bufpos++] = ch; - } - - buffer[bufpos] = '\0'; - return bufpos; -} - -size_t unescape(char * buffer, size_t buflen, - const char * source, size_t srclen, - char escape) { - ASSERT(NULL != buffer); // TODO: estimate output size - if (buflen <= 0) - return 0; - - size_t srcpos = 0, bufpos = 0; - while ((srcpos < srclen) && (bufpos + 1 < buflen)) { - char ch = source[srcpos++]; - if ((ch == escape) && (srcpos < srclen)) { - ch = source[srcpos++]; - } - buffer[bufpos++] = ch; - } - buffer[bufpos] = '\0'; - return bufpos; -} - -size_t encode(char * buffer, size_t buflen, - const char * source, size_t srclen, - const char * illegal, char escape) { - ASSERT(NULL != buffer); // TODO: estimate output size - if (buflen <= 0) - return 0; - - size_t srcpos = 0, bufpos = 0; - while ((srcpos < srclen) && (bufpos + 1 < buflen)) { - char ch = source[srcpos++]; - if ((ch != escape) && !::strchr(illegal, ch)) { - buffer[bufpos++] = ch; - } else if (bufpos + 3 >= buflen) { - break; - } else { - buffer[bufpos+0] = escape; - buffer[bufpos+1] = hex_encode((static_cast(ch) >> 4) & 0xF); - buffer[bufpos+2] = hex_encode((static_cast(ch) ) & 0xF); - bufpos += 3; - } - } - buffer[bufpos] = '\0'; - return bufpos; -} - -size_t decode(char * buffer, size_t buflen, - const char * source, size_t srclen, - char escape) { - if (buflen <= 0) - return 0; - - unsigned char h1, h2; - size_t srcpos = 0, bufpos = 0; - while ((srcpos < srclen) && (bufpos + 1 < buflen)) { - char ch = source[srcpos++]; - if ((ch == escape) - && (srcpos + 1 < srclen) - && hex_decode(source[srcpos], &h1) - && hex_decode(source[srcpos+1], &h2)) { - buffer[bufpos++] = (h1 << 4) | h2; - srcpos += 2; - } else { - buffer[bufpos++] = ch; - } - } - buffer[bufpos] = '\0'; - return bufpos; -} - -const char* unsafe_filename_characters() { - // It might be better to have a single specification which is the union of - // all operating systems, unless one system is overly restrictive. -#if defined(WEBRTC_WIN) - return "\\/:*?\"<>|"; -#else // !WEBRTC_WIN - // TODO - ASSERT(false); - return ""; -#endif // !WEBRTC_WIN -} - -const unsigned char URL_UNSAFE = 0x1; // 0-33 "#$%&+,/:;<=>?@[\]^`{|} 127 -const unsigned char XML_UNSAFE = 0x2; // "&'<> -const unsigned char HTML_UNSAFE = 0x2; // "&'<> - -// ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 6 5 7 8 9 : ; < = > ? -//@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ -//` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ - -const unsigned char ASCII_CLASS[128] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,0,3,1,1,1,3,2,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,3,1,3,1, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1, -}; - -size_t url_encode(char * buffer, size_t buflen, - const char * source, size_t srclen) { - if (NULL == buffer) - return srclen * 3 + 1; - if (buflen <= 0) - return 0; - - size_t srcpos = 0, bufpos = 0; - while ((srcpos < srclen) && (bufpos + 1 < buflen)) { - unsigned char ch = source[srcpos++]; - if ((ch < 128) && (ASCII_CLASS[ch] & URL_UNSAFE)) { - if (bufpos + 3 >= buflen) { - break; - } - buffer[bufpos+0] = '%'; - buffer[bufpos+1] = hex_encode((ch >> 4) & 0xF); - buffer[bufpos+2] = hex_encode((ch ) & 0xF); - bufpos += 3; - } else { - buffer[bufpos++] = ch; - } - } - buffer[bufpos] = '\0'; - return bufpos; -} - -size_t url_decode(char * buffer, size_t buflen, - const char * source, size_t srclen) { - if (NULL == buffer) - return srclen + 1; - if (buflen <= 0) - return 0; - - unsigned char h1, h2; - size_t srcpos = 0, bufpos = 0; - while ((srcpos < srclen) && (bufpos + 1 < buflen)) { - unsigned char ch = source[srcpos++]; - if (ch == '+') { - buffer[bufpos++] = ' '; - } else if ((ch == '%') - && (srcpos + 1 < srclen) - && hex_decode(source[srcpos], &h1) - && hex_decode(source[srcpos+1], &h2)) - { - buffer[bufpos++] = (h1 << 4) | h2; - srcpos += 2; - } else { - buffer[bufpos++] = ch; - } - } - buffer[bufpos] = '\0'; - return bufpos; -} - -size_t utf8_decode(const char* source, size_t srclen, unsigned long* value) { - const unsigned char* s = reinterpret_cast(source); - if ((s[0] & 0x80) == 0x00) { // Check s[0] == 0xxxxxxx - *value = s[0]; - return 1; - } - if ((srclen < 2) || ((s[1] & 0xC0) != 0x80)) { // Check s[1] != 10xxxxxx - return 0; - } - // Accumulate the trailer byte values in value16, and combine it with the - // relevant bits from s[0], once we've determined the sequence length. - unsigned long value16 = (s[1] & 0x3F); - if ((s[0] & 0xE0) == 0xC0) { // Check s[0] == 110xxxxx - *value = ((s[0] & 0x1F) << 6) | value16; - return 2; - } - if ((srclen < 3) || ((s[2] & 0xC0) != 0x80)) { // Check s[2] != 10xxxxxx - return 0; - } - value16 = (value16 << 6) | (s[2] & 0x3F); - if ((s[0] & 0xF0) == 0xE0) { // Check s[0] == 1110xxxx - *value = ((s[0] & 0x0F) << 12) | value16; - return 3; - } - if ((srclen < 4) || ((s[3] & 0xC0) != 0x80)) { // Check s[3] != 10xxxxxx - return 0; - } - value16 = (value16 << 6) | (s[3] & 0x3F); - if ((s[0] & 0xF8) == 0xF0) { // Check s[0] == 11110xxx - *value = ((s[0] & 0x07) << 18) | value16; - return 4; - } - return 0; -} - -size_t utf8_encode(char* buffer, size_t buflen, unsigned long value) { - if ((value <= 0x7F) && (buflen >= 1)) { - buffer[0] = static_cast(value); - return 1; - } - if ((value <= 0x7FF) && (buflen >= 2)) { - buffer[0] = 0xC0 | static_cast(value >> 6); - buffer[1] = 0x80 | static_cast(value & 0x3F); - return 2; - } - if ((value <= 0xFFFF) && (buflen >= 3)) { - buffer[0] = 0xE0 | static_cast(value >> 12); - buffer[1] = 0x80 | static_cast((value >> 6) & 0x3F); - buffer[2] = 0x80 | static_cast(value & 0x3F); - return 3; - } - if ((value <= 0x1FFFFF) && (buflen >= 4)) { - buffer[0] = 0xF0 | static_cast(value >> 18); - buffer[1] = 0x80 | static_cast((value >> 12) & 0x3F); - buffer[2] = 0x80 | static_cast((value >> 6) & 0x3F); - buffer[3] = 0x80 | static_cast(value & 0x3F); - return 4; - } - return 0; -} - -size_t html_encode(char * buffer, size_t buflen, - const char * source, size_t srclen) { - ASSERT(NULL != buffer); // TODO: estimate output size - if (buflen <= 0) - return 0; - - size_t srcpos = 0, bufpos = 0; - while ((srcpos < srclen) && (bufpos + 1 < buflen)) { - unsigned char ch = source[srcpos]; - if (ch < 128) { - srcpos += 1; - if (ASCII_CLASS[ch] & HTML_UNSAFE) { - const char * escseq = 0; - size_t esclen = 0; - switch (ch) { - case '<': escseq = "<"; esclen = 4; break; - case '>': escseq = ">"; esclen = 4; break; - case '\'': escseq = "'"; esclen = 5; break; - case '\"': escseq = """; esclen = 6; break; - case '&': escseq = "&"; esclen = 5; break; - default: ASSERT(false); - } - if (bufpos + esclen >= buflen) { - break; - } - memcpy(buffer + bufpos, escseq, esclen); - bufpos += esclen; - } else { - buffer[bufpos++] = ch; - } - } else { - // Largest value is 0x1FFFFF => � (10 characters) - char escseq[11]; - unsigned long val; - if (size_t vallen = utf8_decode(&source[srcpos], srclen - srcpos, &val)) { - srcpos += vallen; - } else { - // Not a valid utf8 sequence, just use the raw character. - val = static_cast(source[srcpos++]); - } - size_t esclen = sprintfn(escseq, ARRAY_SIZE(escseq), "&#%lu;", val); - if (bufpos + esclen >= buflen) { - break; - } - memcpy(buffer + bufpos, escseq, esclen); - bufpos += esclen; - } - } - buffer[bufpos] = '\0'; - return bufpos; -} - -size_t html_decode(char * buffer, size_t buflen, - const char * source, size_t srclen) { - ASSERT(NULL != buffer); // TODO: estimate output size - return xml_decode(buffer, buflen, source, srclen); -} - -size_t xml_encode(char * buffer, size_t buflen, - const char * source, size_t srclen) { - ASSERT(NULL != buffer); // TODO: estimate output size - if (buflen <= 0) - return 0; - - size_t srcpos = 0, bufpos = 0; - while ((srcpos < srclen) && (bufpos + 1 < buflen)) { - unsigned char ch = source[srcpos++]; - if ((ch < 128) && (ASCII_CLASS[ch] & XML_UNSAFE)) { - const char * escseq = 0; - size_t esclen = 0; - switch (ch) { - case '<': escseq = "<"; esclen = 4; break; - case '>': escseq = ">"; esclen = 4; break; - case '\'': escseq = "'"; esclen = 6; break; - case '\"': escseq = """; esclen = 6; break; - case '&': escseq = "&"; esclen = 5; break; - default: ASSERT(false); - } - if (bufpos + esclen >= buflen) { - break; - } - memcpy(buffer + bufpos, escseq, esclen); - bufpos += esclen; - } else { - buffer[bufpos++] = ch; - } - } - buffer[bufpos] = '\0'; - return bufpos; -} - -size_t xml_decode(char * buffer, size_t buflen, - const char * source, size_t srclen) { - ASSERT(NULL != buffer); // TODO: estimate output size - if (buflen <= 0) - return 0; - - size_t srcpos = 0, bufpos = 0; - while ((srcpos < srclen) && (bufpos + 1 < buflen)) { - unsigned char ch = source[srcpos++]; - if (ch != '&') { - buffer[bufpos++] = ch; - } else if ((srcpos + 2 < srclen) - && (memcmp(source + srcpos, "lt;", 3) == 0)) { - buffer[bufpos++] = '<'; - srcpos += 3; - } else if ((srcpos + 2 < srclen) - && (memcmp(source + srcpos, "gt;", 3) == 0)) { - buffer[bufpos++] = '>'; - srcpos += 3; - } else if ((srcpos + 4 < srclen) - && (memcmp(source + srcpos, "apos;", 5) == 0)) { - buffer[bufpos++] = '\''; - srcpos += 5; - } else if ((srcpos + 4 < srclen) - && (memcmp(source + srcpos, "quot;", 5) == 0)) { - buffer[bufpos++] = '\"'; - srcpos += 5; - } else if ((srcpos + 3 < srclen) - && (memcmp(source + srcpos, "amp;", 4) == 0)) { - buffer[bufpos++] = '&'; - srcpos += 4; - } else if ((srcpos < srclen) && (source[srcpos] == '#')) { - int int_base = 10; - if ((srcpos + 1 < srclen) && (source[srcpos+1] == 'x')) { - int_base = 16; - srcpos += 1; - } - char * ptr; - // TODO: Fix hack (ptr may go past end of data) - unsigned long val = strtoul(source + srcpos + 1, &ptr, int_base); - if ((static_cast(ptr - source) < srclen) && (*ptr == ';')) { - srcpos = ptr - source + 1; - } else { - // Not a valid escape sequence. - break; - } - if (size_t esclen = utf8_encode(buffer + bufpos, buflen - bufpos, val)) { - bufpos += esclen; - } else { - // Not enough room to encode the character, or illegal character - break; - } - } else { - // Unrecognized escape sequence. - break; - } - } - buffer[bufpos] = '\0'; - return bufpos; -} - -static const char HEX[] = "0123456789abcdef"; - -char hex_encode(unsigned char val) { - ASSERT(val < 16); - return (val < 16) ? HEX[val] : '!'; -} - -bool hex_decode(char ch, unsigned char* val) { - if ((ch >= '0') && (ch <= '9')) { - *val = ch - '0'; - } else if ((ch >= 'A') && (ch <= 'Z')) { - *val = (ch - 'A') + 10; - } else if ((ch >= 'a') && (ch <= 'z')) { - *val = (ch - 'a') + 10; - } else { - return false; - } - return true; -} - -size_t hex_encode(char* buffer, size_t buflen, - const char* csource, size_t srclen) { - return hex_encode_with_delimiter(buffer, buflen, csource, srclen, 0); -} - -size_t hex_encode_with_delimiter(char* buffer, size_t buflen, - const char* csource, size_t srclen, - char delimiter) { - ASSERT(NULL != buffer); // TODO: estimate output size - if (buflen == 0) - return 0; - - // Init and check bounds. - const unsigned char* bsource = - reinterpret_cast(csource); - size_t srcpos = 0, bufpos = 0; - size_t needed = delimiter ? (srclen * 3) : (srclen * 2 + 1); - if (buflen < needed) - return 0; - - while (srcpos < srclen) { - unsigned char ch = bsource[srcpos++]; - buffer[bufpos ] = hex_encode((ch >> 4) & 0xF); - buffer[bufpos+1] = hex_encode((ch ) & 0xF); - bufpos += 2; - - // Don't write a delimiter after the last byte. - if (delimiter && (srcpos < srclen)) { - buffer[bufpos] = delimiter; - ++bufpos; - } - } - - // Null terminate. - buffer[bufpos] = '\0'; - return bufpos; -} - -std::string hex_encode(const char* source, size_t srclen) { - return hex_encode_with_delimiter(source, srclen, 0); -} - -std::string hex_encode_with_delimiter(const char* source, size_t srclen, - char delimiter) { - const size_t kBufferSize = srclen * 3; - char* buffer = STACK_ARRAY(char, kBufferSize); - size_t length = hex_encode_with_delimiter(buffer, kBufferSize, - source, srclen, delimiter); - ASSERT(srclen == 0 || length > 0); - return std::string(buffer, length); -} - -size_t hex_decode(char * cbuffer, size_t buflen, - const char * source, size_t srclen) { - return hex_decode_with_delimiter(cbuffer, buflen, source, srclen, 0); -} - -size_t hex_decode_with_delimiter(char* cbuffer, size_t buflen, - const char* source, size_t srclen, - char delimiter) { - ASSERT(NULL != cbuffer); // TODO: estimate output size - if (buflen == 0) - return 0; - - // Init and bounds check. - unsigned char* bbuffer = reinterpret_cast(cbuffer); - size_t srcpos = 0, bufpos = 0; - size_t needed = (delimiter) ? (srclen + 1) / 3 : srclen / 2; - if (buflen < needed) - return 0; - - while (srcpos < srclen) { - if ((srclen - srcpos) < 2) { - // This means we have an odd number of bytes. - return 0; - } - - unsigned char h1, h2; - if (!hex_decode(source[srcpos], &h1) || - !hex_decode(source[srcpos + 1], &h2)) - return 0; - - bbuffer[bufpos++] = (h1 << 4) | h2; - srcpos += 2; - - // Remove the delimiter if needed. - if (delimiter && (srclen - srcpos) > 1) { - if (source[srcpos] != delimiter) - return 0; - ++srcpos; - } - } - - return bufpos; -} - -size_t hex_decode(char* buffer, size_t buflen, const std::string& source) { - return hex_decode_with_delimiter(buffer, buflen, source, 0); -} -size_t hex_decode_with_delimiter(char* buffer, size_t buflen, - const std::string& source, char delimiter) { - return hex_decode_with_delimiter(buffer, buflen, - source.c_str(), source.length(), delimiter); -} - -size_t transform(std::string& value, size_t maxlen, const std::string& source, - Transform t) { - char* buffer = STACK_ARRAY(char, maxlen + 1); - size_t length = t(buffer, maxlen + 1, source.data(), source.length()); - value.assign(buffer, length); - return length; -} - -std::string s_transform(const std::string& source, Transform t) { - // Ask transformation function to approximate the destination size (returns upper bound) - size_t maxlen = t(NULL, 0, source.data(), source.length()); - char * buffer = STACK_ARRAY(char, maxlen); - size_t len = t(buffer, maxlen, source.data(), source.length()); - std::string result(buffer, len); - return result; -} - -size_t tokenize(const std::string& source, char delimiter, - std::vector* fields) { - ASSERT(NULL != fields); - fields->clear(); - size_t last = 0; - for (size_t i = 0; i < source.length(); ++i) { - if (source[i] == delimiter) { - if (i != last) { - fields->push_back(source.substr(last, i - last)); - } - last = i + 1; - } - } - if (last != source.length()) { - fields->push_back(source.substr(last, source.length() - last)); - } - return fields->size(); -} - -size_t tokenize_append(const std::string& source, char delimiter, - std::vector* fields) { - if (!fields) return 0; - - std::vector new_fields; - tokenize(source, delimiter, &new_fields); - fields->insert(fields->end(), new_fields.begin(), new_fields.end()); - return fields->size(); -} - -size_t tokenize(const std::string& source, char delimiter, char start_mark, - char end_mark, std::vector* fields) { - if (!fields) return 0; - fields->clear(); - - std::string remain_source = source; - while (!remain_source.empty()) { - size_t start_pos = remain_source.find(start_mark); - if (std::string::npos == start_pos) break; - std::string pre_mark; - if (start_pos > 0) { - pre_mark = remain_source.substr(0, start_pos - 1); - } - - ++start_pos; - size_t end_pos = remain_source.find(end_mark, start_pos); - if (std::string::npos == end_pos) break; - - // We have found the matching marks. First tokenize the pre-mask. Then add - // the marked part as a single field. Finally, loop back for the post-mark. - tokenize_append(pre_mark, delimiter, fields); - fields->push_back(remain_source.substr(start_pos, end_pos - start_pos)); - remain_source = remain_source.substr(end_pos + 1); - } - - return tokenize_append(remain_source, delimiter, fields); -} - -size_t split(const std::string& source, char delimiter, - std::vector* fields) { - ASSERT(NULL != fields); - fields->clear(); - size_t last = 0; - for (size_t i = 0; i < source.length(); ++i) { - if (source[i] == delimiter) { - fields->push_back(source.substr(last, i - last)); - last = i + 1; - } - } - fields->push_back(source.substr(last, source.length() - last)); - return fields->size(); -} - -char make_char_safe_for_filename(char c) { - if (c < 32) - return '_'; - - switch (c) { - case '<': - case '>': - case ':': - case '"': - case '/': - case '\\': - case '|': - case '*': - case '?': - return '_'; - - default: - return c; - } -} - -/* -void sprintf(std::string& value, size_t maxlen, const char * format, ...) { - char * buffer = STACK_ARRAY(char, maxlen + 1); - va_list args; - va_start(args, format); - value.assign(buffer, vsprintfn(buffer, maxlen + 1, format, args)); - va_end(args); -} -*/ - -///////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/stringencode.h b/webrtc/base/stringencode.h deleted file mode 100644 index b6c666f98..000000000 --- a/webrtc/base/stringencode.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_STRINGENCODE_H_ -#define WEBRTC_BASE_STRINGENCODE_H_ - -#include -#include -#include - -#include "webrtc/base/common.h" - -namespace rtc { - -////////////////////////////////////////////////////////////////////// -// String Encoding Utilities -////////////////////////////////////////////////////////////////////// - -// Convert an unsigned value to it's utf8 representation. Returns the length -// of the encoded string, or 0 if the encoding is longer than buflen - 1. -size_t utf8_encode(char* buffer, size_t buflen, unsigned long value); -// Decode the utf8 encoded value pointed to by source. Returns the number of -// bytes used by the encoding, or 0 if the encoding is invalid. -size_t utf8_decode(const char* source, size_t srclen, unsigned long* value); - -// Escaping prefixes illegal characters with the escape character. Compact, but -// illegal characters still appear in the string. -size_t escape(char * buffer, size_t buflen, - const char * source, size_t srclen, - const char * illegal, char escape); -// Note: in-place unescaping (buffer == source) is allowed. -size_t unescape(char * buffer, size_t buflen, - const char * source, size_t srclen, - char escape); - -// Encoding replaces illegal characters with the escape character and 2 hex -// chars, so it's a little less compact than escape, but completely removes -// illegal characters. note that hex digits should not be used as illegal -// characters. -size_t encode(char * buffer, size_t buflen, - const char * source, size_t srclen, - const char * illegal, char escape); -// Note: in-place decoding (buffer == source) is allowed. -size_t decode(char * buffer, size_t buflen, - const char * source, size_t srclen, - char escape); - -// Returns a list of characters that may be unsafe for use in the name of a -// file, suitable for passing to the 'illegal' member of escape or encode. -const char* unsafe_filename_characters(); - -// url_encode is an encode operation with a predefined set of illegal characters -// and escape character (for use in URLs, obviously). -size_t url_encode(char * buffer, size_t buflen, - const char * source, size_t srclen); -// Note: in-place decoding (buffer == source) is allowed. -size_t url_decode(char * buffer, size_t buflen, - const char * source, size_t srclen); - -// html_encode prevents data embedded in html from containing markup. -size_t html_encode(char * buffer, size_t buflen, - const char * source, size_t srclen); -// Note: in-place decoding (buffer == source) is allowed. -size_t html_decode(char * buffer, size_t buflen, - const char * source, size_t srclen); - -// xml_encode makes data suitable for inside xml attributes and values. -size_t xml_encode(char * buffer, size_t buflen, - const char * source, size_t srclen); -// Note: in-place decoding (buffer == source) is allowed. -size_t xml_decode(char * buffer, size_t buflen, - const char * source, size_t srclen); - -// Convert an unsigned value from 0 to 15 to the hex character equivalent... -char hex_encode(unsigned char val); -// ...and vice-versa. -bool hex_decode(char ch, unsigned char* val); - -// hex_encode shows the hex representation of binary data in ascii. -size_t hex_encode(char* buffer, size_t buflen, - const char* source, size_t srclen); - -// hex_encode, but separate each byte representation with a delimiter. -// |delimiter| == 0 means no delimiter -// If the buffer is too short, we return 0 -size_t hex_encode_with_delimiter(char* buffer, size_t buflen, - const char* source, size_t srclen, - char delimiter); - -// Helper functions for hex_encode. -std::string hex_encode(const char* source, size_t srclen); -std::string hex_encode_with_delimiter(const char* source, size_t srclen, - char delimiter); - -// hex_decode converts ascii hex to binary. -size_t hex_decode(char* buffer, size_t buflen, - const char* source, size_t srclen); - -// hex_decode, assuming that there is a delimiter between every byte -// pair. -// |delimiter| == 0 means no delimiter -// If the buffer is too short or the data is invalid, we return 0. -size_t hex_decode_with_delimiter(char* buffer, size_t buflen, - const char* source, size_t srclen, - char delimiter); - -// Helper functions for hex_decode. -size_t hex_decode(char* buffer, size_t buflen, const std::string& source); -size_t hex_decode_with_delimiter(char* buffer, size_t buflen, - const std::string& source, char delimiter); - -// Apply any suitable string transform (including the ones above) to an STL -// string. Stack-allocated temporary space is used for the transformation, -// so value and source may refer to the same string. -typedef size_t (*Transform)(char * buffer, size_t buflen, - const char * source, size_t srclen); -size_t transform(std::string& value, size_t maxlen, const std::string& source, - Transform t); - -// Return the result of applying transform t to source. -std::string s_transform(const std::string& source, Transform t); - -// Convenience wrappers. -inline std::string s_url_encode(const std::string& source) { - return s_transform(source, url_encode); -} -inline std::string s_url_decode(const std::string& source) { - return s_transform(source, url_decode); -} - -// Splits the source string into multiple fields separated by delimiter, -// with duplicates of delimiter creating empty fields. -size_t split(const std::string& source, char delimiter, - std::vector* fields); - -// Splits the source string into multiple fields separated by delimiter, -// with duplicates of delimiter ignored. Trailing delimiter ignored. -size_t tokenize(const std::string& source, char delimiter, - std::vector* fields); - -// Tokenize and append the tokens to fields. Return the new size of fields. -size_t tokenize_append(const std::string& source, char delimiter, - std::vector* fields); - -// Splits the source string into multiple fields separated by delimiter, with -// duplicates of delimiter ignored. Trailing delimiter ignored. A substring in -// between the start_mark and the end_mark is treated as a single field. Return -// the size of fields. For example, if source is "filename -// \"/Library/Application Support/media content.txt\"", delimiter is ' ', and -// the start_mark and end_mark are '"', this method returns two fields: -// "filename" and "/Library/Application Support/media content.txt". -size_t tokenize(const std::string& source, char delimiter, char start_mark, - char end_mark, std::vector* fields); - -// Safe sprintf to std::string -//void sprintf(std::string& value, size_t maxlen, const char * format, ...) -// PRINTF_FORMAT(3); - -// Convert arbitrary values to/from a string. - -template -static bool ToString(const T &t, std::string* s) { - ASSERT(NULL != s); - std::ostringstream oss; - oss << std::boolalpha << t; - *s = oss.str(); - return !oss.fail(); -} - -template -static bool FromString(const std::string& s, T* t) { - ASSERT(NULL != t); - std::istringstream iss(s); - iss >> std::boolalpha >> *t; - return !iss.fail(); -} - -// Inline versions of the string conversion routines. - -template -static inline std::string ToString(const T& val) { - std::string str; ToString(val, &str); return str; -} - -template -static inline T FromString(const std::string& str) { - T val; FromString(str, &val); return val; -} - -template -static inline T FromString(const T& defaultValue, const std::string& str) { - T val(defaultValue); FromString(str, &val); return val; -} - -// simple function to strip out characters which shouldn't be -// used in filenames -char make_char_safe_for_filename(char c); - -////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_STRINGENCODE_H__ diff --git a/webrtc/base/stringencode_unittest.cc b/webrtc/base/stringencode_unittest.cc deleted file mode 100644 index c9e726ecb..000000000 --- a/webrtc/base/stringencode_unittest.cc +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/common.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/stringutils.h" - -namespace rtc { - -TEST(Utf8EncodeTest, EncodeDecode) { - const struct Utf8Test { - const char* encoded; - size_t encsize, enclen; - unsigned long decoded; - } kTests[] = { - { "a ", 5, 1, 'a' }, - { "\x7F ", 5, 1, 0x7F }, - { "\xC2\x80 ", 5, 2, 0x80 }, - { "\xDF\xBF ", 5, 2, 0x7FF }, - { "\xE0\xA0\x80 ", 5, 3, 0x800 }, - { "\xEF\xBF\xBF ", 5, 3, 0xFFFF }, - { "\xF0\x90\x80\x80 ", 5, 4, 0x10000 }, - { "\xF0\x90\x80\x80 ", 3, 0, 0x10000 }, - { "\xF0\xF0\x80\x80 ", 5, 0, 0 }, - { "\xF0\x90\x80 ", 5, 0, 0 }, - { "\x90\x80\x80 ", 5, 0, 0 }, - { NULL, 0, 0 }, - }; - for (size_t i = 0; kTests[i].encoded; ++i) { - unsigned long val = 0; - ASSERT_EQ(kTests[i].enclen, utf8_decode(kTests[i].encoded, - kTests[i].encsize, - &val)); - unsigned long result = (kTests[i].enclen == 0) ? 0 : kTests[i].decoded; - ASSERT_EQ(result, val); - - if (kTests[i].decoded == 0) { - // Not an interesting encoding test case - continue; - } - - char buffer[5]; - memset(buffer, 0x01, ARRAY_SIZE(buffer)); - ASSERT_EQ(kTests[i].enclen, utf8_encode(buffer, - kTests[i].encsize, - kTests[i].decoded)); - ASSERT_TRUE(memcmp(buffer, kTests[i].encoded, kTests[i].enclen) == 0); - // Make sure remainder of buffer is unchanged - ASSERT_TRUE(memory_check(buffer + kTests[i].enclen, - 0x1, - ARRAY_SIZE(buffer) - kTests[i].enclen)); - } -} - -class HexEncodeTest : public testing::Test { - public: - HexEncodeTest() : enc_res_(0), dec_res_(0) { - for (size_t i = 0; i < sizeof(data_); ++i) { - data_[i] = (i + 128) & 0xff; - } - memset(decoded_, 0x7f, sizeof(decoded_)); - } - - char data_[10]; - char encoded_[31]; - char decoded_[11]; - size_t enc_res_; - size_t dec_res_; -}; - -// Test that we can convert to/from hex with no delimiter. -TEST_F(HexEncodeTest, TestWithNoDelimiter) { - enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_)); - ASSERT_EQ(sizeof(data_) * 2, enc_res_); - ASSERT_STREQ("80818283848586878889", encoded_); - dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); - ASSERT_EQ(sizeof(data_), dec_res_); - ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); -} - -// Test that we can convert to/from hex with a colon delimiter. -TEST_F(HexEncodeTest, TestWithDelimiter) { - enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), - data_, sizeof(data_), ':'); - ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); - ASSERT_STREQ("80:81:82:83:84:85:86:87:88:89", encoded_); - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), - encoded_, enc_res_, ':'); - ASSERT_EQ(sizeof(data_), dec_res_); - ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); -} - -// Test that encoding with one delimiter and decoding with another fails. -TEST_F(HexEncodeTest, TestWithWrongDelimiter) { - enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), - data_, sizeof(data_), ':'); - ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), - encoded_, enc_res_, '/'); - ASSERT_EQ(0U, dec_res_); -} - -// Test that encoding without a delimiter and decoding with one fails. -TEST_F(HexEncodeTest, TestExpectedDelimiter) { - enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_)); - ASSERT_EQ(sizeof(data_) * 2, enc_res_); - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), - encoded_, enc_res_, ':'); - ASSERT_EQ(0U, dec_res_); -} - -// Test that encoding with a delimiter and decoding without one fails. -TEST_F(HexEncodeTest, TestExpectedNoDelimiter) { - enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), - data_, sizeof(data_), ':'); - ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); - dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); - ASSERT_EQ(0U, dec_res_); -} - -// Test that we handle a zero-length buffer with no delimiter. -TEST_F(HexEncodeTest, TestZeroLengthNoDelimiter) { - enc_res_ = hex_encode(encoded_, sizeof(encoded_), "", 0); - ASSERT_EQ(0U, enc_res_); - dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); - ASSERT_EQ(0U, dec_res_); -} - -// Test that we handle a zero-length buffer with a delimiter. -TEST_F(HexEncodeTest, TestZeroLengthWithDelimiter) { - enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), "", 0, ':'); - ASSERT_EQ(0U, enc_res_); - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), - encoded_, enc_res_, ':'); - ASSERT_EQ(0U, dec_res_); -} - -// Test the std::string variants that take no delimiter. -TEST_F(HexEncodeTest, TestHelpersNoDelimiter) { - std::string result = hex_encode(data_, sizeof(data_)); - ASSERT_EQ("80818283848586878889", result); - dec_res_ = hex_decode(decoded_, sizeof(decoded_), result); - ASSERT_EQ(sizeof(data_), dec_res_); - ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); -} - -// Test the std::string variants that use a delimiter. -TEST_F(HexEncodeTest, TestHelpersWithDelimiter) { - std::string result = hex_encode_with_delimiter(data_, sizeof(data_), ':'); - ASSERT_EQ("80:81:82:83:84:85:86:87:88:89", result); - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), result, ':'); - ASSERT_EQ(sizeof(data_), dec_res_); - ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); -} - -// Test that encoding into a too-small output buffer (without delimiter) fails. -TEST_F(HexEncodeTest, TestEncodeTooShort) { - enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 2, - data_, sizeof(data_), 0); - ASSERT_EQ(0U, enc_res_); -} - -// Test that encoding into a too-small output buffer (with delimiter) fails. -TEST_F(HexEncodeTest, TestEncodeWithDelimiterTooShort) { - enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 3 - 1, - data_, sizeof(data_), ':'); - ASSERT_EQ(0U, enc_res_); -} - -// Test that decoding into a too-small output buffer fails. -TEST_F(HexEncodeTest, TestDecodeTooShort) { - dec_res_ = hex_decode_with_delimiter(decoded_, 4, "0123456789", 10, 0); - ASSERT_EQ(0U, dec_res_); - ASSERT_EQ(0x7f, decoded_[4]); -} - -// Test that decoding non-hex data fails. -TEST_F(HexEncodeTest, TestDecodeBogusData) { - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "xyz", 3, 0); - ASSERT_EQ(0U, dec_res_); -} - -// Test that decoding an odd number of hex characters fails. -TEST_F(HexEncodeTest, TestDecodeOddHexDigits) { - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "012", 3, 0); - ASSERT_EQ(0U, dec_res_); -} - -// Test that decoding a string with too many delimiters fails. -TEST_F(HexEncodeTest, TestDecodeWithDelimiterTooManyDelimiters) { - dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01::23::45::67", 14, ':'); - ASSERT_EQ(0U, dec_res_); -} - -// Test that decoding a string with a leading delimiter fails. -TEST_F(HexEncodeTest, TestDecodeWithDelimiterLeadingDelimiter) { - dec_res_ = hex_decode_with_delimiter(decoded_, 4, ":01:23:45:67", 12, ':'); - ASSERT_EQ(0U, dec_res_); -} - -// Test that decoding a string with a trailing delimiter fails. -TEST_F(HexEncodeTest, TestDecodeWithDelimiterTrailingDelimiter) { - dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01:23:45:67:", 12, ':'); - ASSERT_EQ(0U, dec_res_); -} - -// Tests counting substrings. -TEST(TokenizeTest, CountSubstrings) { - std::vector fields; - - EXPECT_EQ(5ul, tokenize("one two three four five", ' ', &fields)); - fields.clear(); - EXPECT_EQ(1ul, tokenize("one", ' ', &fields)); - - // Extra spaces should be ignored. - fields.clear(); - EXPECT_EQ(5ul, tokenize(" one two three four five ", ' ', &fields)); - fields.clear(); - EXPECT_EQ(1ul, tokenize(" one ", ' ', &fields)); - fields.clear(); - EXPECT_EQ(0ul, tokenize(" ", ' ', &fields)); -} - -// Tests comparing substrings. -TEST(TokenizeTest, CompareSubstrings) { - std::vector fields; - - tokenize("find middle one", ' ', &fields); - ASSERT_EQ(3ul, fields.size()); - ASSERT_STREQ("middle", fields.at(1).c_str()); - fields.clear(); - - // Extra spaces should be ignored. - tokenize(" find middle one ", ' ', &fields); - ASSERT_EQ(3ul, fields.size()); - ASSERT_STREQ("middle", fields.at(1).c_str()); - fields.clear(); - tokenize(" ", ' ', &fields); - ASSERT_EQ(0ul, fields.size()); -} - -TEST(TokenizeTest, TokenizeAppend) { - ASSERT_EQ(0ul, tokenize_append("A B C", ' ', NULL)); - - std::vector fields; - - tokenize_append("A B C", ' ', &fields); - ASSERT_EQ(3ul, fields.size()); - ASSERT_STREQ("B", fields.at(1).c_str()); - - tokenize_append("D E", ' ', &fields); - ASSERT_EQ(5ul, fields.size()); - ASSERT_STREQ("B", fields.at(1).c_str()); - ASSERT_STREQ("E", fields.at(4).c_str()); -} - -TEST(TokenizeTest, TokenizeWithMarks) { - ASSERT_EQ(0ul, tokenize("D \"A B", ' ', '(', ')', NULL)); - - std::vector fields; - tokenize("A B C", ' ', '"', '"', &fields); - ASSERT_EQ(3ul, fields.size()); - ASSERT_STREQ("C", fields.at(2).c_str()); - - tokenize("\"A B\" C", ' ', '"', '"', &fields); - ASSERT_EQ(2ul, fields.size()); - ASSERT_STREQ("A B", fields.at(0).c_str()); - - tokenize("D \"A B\" C", ' ', '"', '"', &fields); - ASSERT_EQ(3ul, fields.size()); - ASSERT_STREQ("D", fields.at(0).c_str()); - ASSERT_STREQ("A B", fields.at(1).c_str()); - - tokenize("D \"A B\" C \"E F\"", ' ', '"', '"', &fields); - ASSERT_EQ(4ul, fields.size()); - ASSERT_STREQ("D", fields.at(0).c_str()); - ASSERT_STREQ("A B", fields.at(1).c_str()); - ASSERT_STREQ("E F", fields.at(3).c_str()); - - // No matching marks. - tokenize("D \"A B", ' ', '"', '"', &fields); - ASSERT_EQ(3ul, fields.size()); - ASSERT_STREQ("D", fields.at(0).c_str()); - ASSERT_STREQ("\"A", fields.at(1).c_str()); - - tokenize("D (A B) C (E F) G", ' ', '(', ')', &fields); - ASSERT_EQ(5ul, fields.size()); - ASSERT_STREQ("D", fields.at(0).c_str()); - ASSERT_STREQ("A B", fields.at(1).c_str()); - ASSERT_STREQ("E F", fields.at(3).c_str()); -} - -// Tests counting substrings. -TEST(SplitTest, CountSubstrings) { - std::vector fields; - - EXPECT_EQ(5ul, split("one,two,three,four,five", ',', &fields)); - fields.clear(); - EXPECT_EQ(1ul, split("one", ',', &fields)); - - // Empty fields between commas count. - fields.clear(); - EXPECT_EQ(5ul, split("one,,three,four,five", ',', &fields)); - fields.clear(); - EXPECT_EQ(3ul, split(",three,", ',', &fields)); - fields.clear(); - EXPECT_EQ(1ul, split("", ',', &fields)); -} - -// Tests comparing substrings. -TEST(SplitTest, CompareSubstrings) { - std::vector fields; - - split("find,middle,one", ',', &fields); - ASSERT_EQ(3ul, fields.size()); - ASSERT_STREQ("middle", fields.at(1).c_str()); - fields.clear(); - - // Empty fields between commas count. - split("find,,middle,one", ',', &fields); - ASSERT_EQ(4ul, fields.size()); - ASSERT_STREQ("middle", fields.at(2).c_str()); - fields.clear(); - split("", ',', &fields); - ASSERT_EQ(1ul, fields.size()); - ASSERT_STREQ("", fields.at(0).c_str()); -} - -TEST(BoolTest, DecodeValid) { - bool value; - EXPECT_TRUE(FromString("true", &value)); - EXPECT_TRUE(value); - EXPECT_TRUE(FromString("true,", &value)); - EXPECT_TRUE(value); - EXPECT_TRUE(FromString("true , true", &value)); - EXPECT_TRUE(value); - EXPECT_TRUE(FromString("true ,\n false", &value)); - EXPECT_TRUE(value); - EXPECT_TRUE(FromString(" true \n", &value)); - EXPECT_TRUE(value); - - EXPECT_TRUE(FromString("false", &value)); - EXPECT_FALSE(value); - EXPECT_TRUE(FromString(" false ", &value)); - EXPECT_FALSE(value); - EXPECT_TRUE(FromString(" false, ", &value)); - EXPECT_FALSE(value); - - EXPECT_TRUE(FromString("true\n")); - EXPECT_FALSE(FromString("false\n")); -} - -TEST(BoolTest, DecodeInvalid) { - bool value; - EXPECT_FALSE(FromString("True", &value)); - EXPECT_FALSE(FromString("TRUE", &value)); - EXPECT_FALSE(FromString("False", &value)); - EXPECT_FALSE(FromString("FALSE", &value)); - EXPECT_FALSE(FromString("0", &value)); - EXPECT_FALSE(FromString("1", &value)); - EXPECT_FALSE(FromString("0,", &value)); - EXPECT_FALSE(FromString("1,", &value)); - EXPECT_FALSE(FromString("1,0", &value)); - EXPECT_FALSE(FromString("1.", &value)); - EXPECT_FALSE(FromString("1.0", &value)); - EXPECT_FALSE(FromString("", &value)); - EXPECT_FALSE(FromString("false\nfalse")); -} - -TEST(BoolTest, RoundTrip) { - bool value; - EXPECT_TRUE(FromString(ToString(true), &value)); - EXPECT_TRUE(value); - EXPECT_TRUE(FromString(ToString(false), &value)); - EXPECT_FALSE(value); -} -} // namespace rtc diff --git a/webrtc/base/stringutils.cc b/webrtc/base/stringutils.cc deleted file mode 100644 index 041708d3d..000000000 --- a/webrtc/base/stringutils.cc +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/stringutils.h" -#include "webrtc/base/common.h" - -namespace rtc { - -bool memory_check(const void* memory, int c, size_t count) { - const char* char_memory = static_cast(memory); - char char_c = static_cast(c); - for (size_t i = 0; i < count; ++i) { - if (char_memory[i] != char_c) { - return false; - } - } - return true; -} - -bool string_match(const char* target, const char* pattern) { - while (*pattern) { - if (*pattern == '*') { - if (!*++pattern) { - return true; - } - while (*target) { - if ((toupper(*pattern) == toupper(*target)) - && string_match(target + 1, pattern + 1)) { - return true; - } - ++target; - } - return false; - } else { - if (toupper(*pattern) != toupper(*target)) { - return false; - } - ++target; - ++pattern; - } - } - return !*target; -} - -#if defined(WEBRTC_WIN) -int ascii_string_compare(const wchar_t* s1, const char* s2, size_t n, - CharacterTransformation transformation) { - wchar_t c1, c2; - while (true) { - if (n-- == 0) return 0; - c1 = transformation(*s1); - // Double check that characters are not UTF-8 - ASSERT(static_cast(*s2) < 128); - // Note: *s2 gets implicitly promoted to wchar_t - c2 = transformation(*s2); - if (c1 != c2) return (c1 < c2) ? -1 : 1; - if (!c1) return 0; - ++s1; - ++s2; - } -} - -size_t asccpyn(wchar_t* buffer, size_t buflen, - const char* source, size_t srclen) { - if (buflen <= 0) - return 0; - - if (srclen == SIZE_UNKNOWN) { - srclen = strlenn(source, buflen - 1); - } else if (srclen >= buflen) { - srclen = buflen - 1; - } -#if _DEBUG - // Double check that characters are not UTF-8 - for (size_t pos = 0; pos < srclen; ++pos) - ASSERT(static_cast(source[pos]) < 128); -#endif // _DEBUG - std::copy(source, source + srclen, buffer); - buffer[srclen] = 0; - return srclen; -} - -#endif // WEBRTC_WIN - -void replace_substrs(const char *search, - size_t search_len, - const char *replace, - size_t replace_len, - std::string *s) { - size_t pos = 0; - while ((pos = s->find(search, pos, search_len)) != std::string::npos) { - s->replace(pos, search_len, replace, replace_len); - pos += replace_len; - } -} - -bool starts_with(const char *s1, const char *s2) { - return strncmp(s1, s2, strlen(s2)) == 0; -} - -bool ends_with(const char *s1, const char *s2) { - size_t s1_length = strlen(s1); - size_t s2_length = strlen(s2); - - if (s2_length > s1_length) { - return false; - } - - const char* start = s1 + (s1_length - s2_length); - return strncmp(start, s2, s2_length) == 0; -} - -static const char kWhitespace[] = " \n\r\t"; - -std::string string_trim(const std::string& s) { - std::string::size_type first = s.find_first_not_of(kWhitespace); - std::string::size_type last = s.find_last_not_of(kWhitespace); - - if (first == std::string::npos || last == std::string::npos) { - return std::string(""); - } - - return s.substr(first, last - first + 1); -} - -} // namespace rtc diff --git a/webrtc/base/stringutils.h b/webrtc/base/stringutils.h deleted file mode 100644 index 25990e0af..000000000 --- a/webrtc/base/stringutils.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_STRINGUTILS_H__ -#define WEBRTC_BASE_STRINGUTILS_H__ - -#include -#include -#include -#include - -#if defined(WEBRTC_WIN) -#include -#include -#define alloca _alloca -#endif // WEBRTC_WIN - -#if defined(WEBRTC_POSIX) -#ifdef BSD -#include -#else // BSD -#include -#endif // !BSD -#endif // WEBRTC_POSIX - -#include - -#include "webrtc/base/basictypes.h" - -/////////////////////////////////////////////////////////////////////////////// -// Generic string/memory utilities -/////////////////////////////////////////////////////////////////////////////// - -#define STACK_ARRAY(TYPE, LEN) static_cast(::alloca((LEN)*sizeof(TYPE))) - -namespace rtc { - -// Complement to memset. Verifies memory consists of count bytes of value c. -bool memory_check(const void* memory, int c, size_t count); - -// Determines whether the simple wildcard pattern matches target. -// Alpha characters in pattern match case-insensitively. -// Asterisks in pattern match 0 or more characters. -// Ex: string_match("www.TEST.GOOGLE.COM", "www.*.com") -> true -bool string_match(const char* target, const char* pattern); - -} // namespace rtc - -/////////////////////////////////////////////////////////////////////////////// -// Rename a bunch of common string functions so they are consistent across -// platforms and between char and wchar_t variants. -// Here is the full list of functions that are unified: -// strlen, strcmp, stricmp, strncmp, strnicmp -// strchr, vsnprintf, strtoul, tolowercase -// tolowercase is like tolower, but not compatible with end-of-file value -// -// It's not clear if we will ever use wchar_t strings on unix. In theory, -// all strings should be Utf8 all the time, except when interfacing with Win32 -// APIs that require Utf16. -/////////////////////////////////////////////////////////////////////////////// - -inline char tolowercase(char c) { - return static_cast(tolower(c)); -} - -#if defined(WEBRTC_WIN) - -inline size_t strlen(const wchar_t* s) { - return wcslen(s); -} -inline int strcmp(const wchar_t* s1, const wchar_t* s2) { - return wcscmp(s1, s2); -} -inline int stricmp(const wchar_t* s1, const wchar_t* s2) { - return _wcsicmp(s1, s2); -} -inline int strncmp(const wchar_t* s1, const wchar_t* s2, size_t n) { - return wcsncmp(s1, s2, n); -} -inline int strnicmp(const wchar_t* s1, const wchar_t* s2, size_t n) { - return _wcsnicmp(s1, s2, n); -} -inline const wchar_t* strchr(const wchar_t* s, wchar_t c) { - return wcschr(s, c); -} -inline const wchar_t* strstr(const wchar_t* haystack, const wchar_t* needle) { - return wcsstr(haystack, needle); -} -#ifndef vsnprintf -inline int vsnprintf(wchar_t* buf, size_t n, const wchar_t* fmt, va_list args) { - return _vsnwprintf(buf, n, fmt, args); -} -#endif // !vsnprintf -inline unsigned long strtoul(const wchar_t* snum, wchar_t** end, int base) { - return wcstoul(snum, end, base); -} -inline wchar_t tolowercase(wchar_t c) { - return static_cast(towlower(c)); -} - -#endif // WEBRTC_WIN - -#if defined(WEBRTC_POSIX) - -inline int _stricmp(const char* s1, const char* s2) { - return strcasecmp(s1, s2); -} -inline int _strnicmp(const char* s1, const char* s2, size_t n) { - return strncasecmp(s1, s2, n); -} - -#endif // WEBRTC_POSIX - -/////////////////////////////////////////////////////////////////////////////// -// Traits simplifies porting string functions to be CTYPE-agnostic -/////////////////////////////////////////////////////////////////////////////// - -namespace rtc { - -const size_t SIZE_UNKNOWN = static_cast(-1); - -template -struct Traits { - // STL string type - //typedef XXX string; - // Null-terminated string - //inline static const CTYPE* empty_str(); -}; - -/////////////////////////////////////////////////////////////////////////////// -// String utilities which work with char or wchar_t -/////////////////////////////////////////////////////////////////////////////// - -template -inline const CTYPE* nonnull(const CTYPE* str, const CTYPE* def_str = NULL) { - return str ? str : (def_str ? def_str : Traits::empty_str()); -} - -template -const CTYPE* strchr(const CTYPE* str, const CTYPE* chs) { - for (size_t i=0; str[i]; ++i) { - for (size_t j=0; chs[j]; ++j) { - if (str[i] == chs[j]) { - return str + i; - } - } - } - return 0; -} - -template -const CTYPE* strchrn(const CTYPE* str, size_t slen, CTYPE ch) { - for (size_t i=0; i -size_t strlenn(const CTYPE* buffer, size_t buflen) { - size_t bufpos = 0; - while (buffer[bufpos] && (bufpos < buflen)) { - ++bufpos; - } - return bufpos; -} - -// Safe versions of strncpy, strncat, snprintf and vsnprintf that always -// null-terminate. - -template -size_t strcpyn(CTYPE* buffer, size_t buflen, - const CTYPE* source, size_t srclen = SIZE_UNKNOWN) { - if (buflen <= 0) - return 0; - - if (srclen == SIZE_UNKNOWN) { - srclen = strlenn(source, buflen - 1); - } else if (srclen >= buflen) { - srclen = buflen - 1; - } - memcpy(buffer, source, srclen * sizeof(CTYPE)); - buffer[srclen] = 0; - return srclen; -} - -template -size_t strcatn(CTYPE* buffer, size_t buflen, - const CTYPE* source, size_t srclen = SIZE_UNKNOWN) { - if (buflen <= 0) - return 0; - - size_t bufpos = strlenn(buffer, buflen - 1); - return bufpos + strcpyn(buffer + bufpos, buflen - bufpos, source, srclen); -} - -// Some compilers (clang specifically) require vsprintfn be defined before -// sprintfn. -template -size_t vsprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, - va_list args) { - int len = vsnprintf(buffer, buflen, format, args); - if ((len < 0) || (static_cast(len) >= buflen)) { - len = static_cast(buflen - 1); - buffer[len] = 0; - } - return len; -} - -template -size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...); -template -size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...) { - va_list args; - va_start(args, format); - size_t len = vsprintfn(buffer, buflen, format, args); - va_end(args); - return len; -} - -/////////////////////////////////////////////////////////////////////////////// -// Allow safe comparing and copying ascii (not UTF-8) with both wide and -// non-wide character strings. -/////////////////////////////////////////////////////////////////////////////// - -inline int asccmp(const char* s1, const char* s2) { - return strcmp(s1, s2); -} -inline int ascicmp(const char* s1, const char* s2) { - return _stricmp(s1, s2); -} -inline int ascncmp(const char* s1, const char* s2, size_t n) { - return strncmp(s1, s2, n); -} -inline int ascnicmp(const char* s1, const char* s2, size_t n) { - return _strnicmp(s1, s2, n); -} -inline size_t asccpyn(char* buffer, size_t buflen, - const char* source, size_t srclen = SIZE_UNKNOWN) { - return strcpyn(buffer, buflen, source, srclen); -} - -#if defined(WEBRTC_WIN) - -typedef wchar_t(*CharacterTransformation)(wchar_t); -inline wchar_t identity(wchar_t c) { return c; } -int ascii_string_compare(const wchar_t* s1, const char* s2, size_t n, - CharacterTransformation transformation); - -inline int asccmp(const wchar_t* s1, const char* s2) { - return ascii_string_compare(s1, s2, static_cast(-1), identity); -} -inline int ascicmp(const wchar_t* s1, const char* s2) { - return ascii_string_compare(s1, s2, static_cast(-1), tolowercase); -} -inline int ascncmp(const wchar_t* s1, const char* s2, size_t n) { - return ascii_string_compare(s1, s2, n, identity); -} -inline int ascnicmp(const wchar_t* s1, const char* s2, size_t n) { - return ascii_string_compare(s1, s2, n, tolowercase); -} -size_t asccpyn(wchar_t* buffer, size_t buflen, - const char* source, size_t srclen = SIZE_UNKNOWN); - -#endif // WEBRTC_WIN - -/////////////////////////////////////////////////////////////////////////////// -// Traits specializations -/////////////////////////////////////////////////////////////////////////////// - -template<> -struct Traits { - typedef std::string string; - inline static const char* empty_str() { return ""; } -}; - -/////////////////////////////////////////////////////////////////////////////// -// Traits specializations (Windows only, currently) -/////////////////////////////////////////////////////////////////////////////// - -#if defined(WEBRTC_WIN) - -template<> -struct Traits { - typedef std::wstring string; - inline static const wchar_t* Traits::empty_str() { return L""; } -}; - -#endif // WEBRTC_WIN - -// Replaces all occurrences of "search" with "replace". -void replace_substrs(const char *search, - size_t search_len, - const char *replace, - size_t replace_len, - std::string *s); - -// True iff s1 starts with s2. -bool starts_with(const char *s1, const char *s2); - -// True iff s1 ends with s2. -bool ends_with(const char *s1, const char *s2); - -// Remove leading and trailing whitespaces. -std::string string_trim(const std::string& s); - -} // namespace rtc - -#endif // WEBRTC_BASE_STRINGUTILS_H__ diff --git a/webrtc/base/stringutils_unittest.cc b/webrtc/base/stringutils_unittest.cc deleted file mode 100644 index b82290d0a..000000000 --- a/webrtc/base/stringutils_unittest.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/common.h" - -namespace rtc { - -// Tests for string_match(). - -TEST(string_matchTest, Matches) { - EXPECT_TRUE( string_match("A.B.C.D", "a.b.c.d")); - EXPECT_TRUE( string_match("www.TEST.GOOGLE.COM", "www.*.com")); - EXPECT_TRUE( string_match("127.0.0.1", "12*.0.*1")); - EXPECT_TRUE( string_match("127.1.0.21", "12*.0.*1")); - EXPECT_FALSE(string_match("127.0.0.0", "12*.0.*1")); - EXPECT_FALSE(string_match("127.0.0.0", "12*.0.*1")); - EXPECT_FALSE(string_match("127.1.1.21", "12*.0.*1")); -} - -// It's not clear if we will ever use wchar_t strings on unix. In theory, -// all strings should be Utf8 all the time, except when interfacing with Win32 -// APIs that require Utf16. - -#if defined(WEBRTC_WIN) - -// Tests for ascii_string_compare(). - -// Tests NULL input. -TEST(ascii_string_compareTest, NullInput) { - // The following results in an access violation in - // ascii_string_compare. Is this a bug or by design? stringutils.h - // should document the expected behavior in this case. - - // EXPECT_EQ(0, ascii_string_compare(NULL, NULL, 1, identity)); -} - -// Tests comparing two strings of different lengths. -TEST(ascii_string_compareTest, DifferentLengths) { - EXPECT_EQ(-1, ascii_string_compare(L"Test", "Test1", 5, identity)); -} - -// Tests the case where the buffer size is smaller than the string -// lengths. -TEST(ascii_string_compareTest, SmallBuffer) { - EXPECT_EQ(0, ascii_string_compare(L"Test", "Test1", 3, identity)); -} - -// Tests the case where the buffer is not full. -TEST(ascii_string_compareTest, LargeBuffer) { - EXPECT_EQ(0, ascii_string_compare(L"Test", "Test", 10, identity)); -} - -// Tests comparing two eqaul strings. -TEST(ascii_string_compareTest, Equal) { - EXPECT_EQ(0, ascii_string_compare(L"Test", "Test", 5, identity)); - EXPECT_EQ(0, ascii_string_compare(L"TeSt", "tEsT", 5, tolowercase)); -} - -// Tests comparing a smller string to a larger one. -TEST(ascii_string_compareTest, LessThan) { - EXPECT_EQ(-1, ascii_string_compare(L"abc", "abd", 4, identity)); - EXPECT_EQ(-1, ascii_string_compare(L"ABC", "abD", 5, tolowercase)); -} - -// Tests comparing a larger string to a smaller one. -TEST(ascii_string_compareTest, GreaterThan) { - EXPECT_EQ(1, ascii_string_compare(L"xyz", "xy", 5, identity)); - EXPECT_EQ(1, ascii_string_compare(L"abc", "ABB", 5, tolowercase)); -} -#endif // WEBRTC_WIN - -TEST(string_trim_Test, Trimming) { - EXPECT_EQ("temp", string_trim("\n\r\t temp \n\r\t")); - EXPECT_EQ("temp\n\r\t temp", string_trim(" temp\n\r\t temp ")); - EXPECT_EQ("temp temp", string_trim("temp temp")); - EXPECT_EQ("", string_trim(" \r\n\t")); - EXPECT_EQ("", string_trim("")); -} - -TEST(string_startsTest, StartsWith) { - EXPECT_TRUE(starts_with("foobar", "foo")); - EXPECT_TRUE(starts_with("foobar", "foobar")); - EXPECT_TRUE(starts_with("foobar", "")); - EXPECT_TRUE(starts_with("", "")); - EXPECT_FALSE(starts_with("foobar", "bar")); - EXPECT_FALSE(starts_with("foobar", "foobarbaz")); - EXPECT_FALSE(starts_with("", "f")); -} - -TEST(string_endsTest, EndsWith) { - EXPECT_TRUE(ends_with("foobar", "bar")); - EXPECT_TRUE(ends_with("foobar", "foobar")); - EXPECT_TRUE(ends_with("foobar", "")); - EXPECT_TRUE(ends_with("", "")); - EXPECT_FALSE(ends_with("foobar", "foo")); - EXPECT_FALSE(ends_with("foobar", "foobarbaz")); - EXPECT_FALSE(ends_with("", "f")); -} - -} // namespace rtc diff --git a/webrtc/base/systeminfo.cc b/webrtc/base/systeminfo.cc deleted file mode 100644 index 213c272b3..000000000 --- a/webrtc/base/systeminfo.cc +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/systeminfo.h" - -#if defined(WEBRTC_WIN) -#include -#ifndef EXCLUDE_D3D9 -#include -#endif -#include // for __cpuid() -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include -#include -#elif defined(WEBRTC_LINUX) -#include -#endif -#if defined(WEBRTC_MAC) -#include -#endif - -#if defined(WEBRTC_WIN) -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/win32.h" -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include "webrtc/base/macconversion.h" -#elif defined(WEBRTC_LINUX) -#include "webrtc/base/linux.h" -#endif -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/stringutils.h" - -namespace rtc { - -// See Also: http://msdn.microsoft.com/en-us/library/ms683194(v=vs.85).aspx -#if defined(WEBRTC_WIN) -typedef BOOL (WINAPI *LPFN_GLPI)( - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, - PDWORD); - -static void GetProcessorInformation(int* physical_cpus, int* cache_size) { - // GetLogicalProcessorInformation() is available on Windows XP SP3 and beyond. - LPFN_GLPI glpi = reinterpret_cast(GetProcAddress( - GetModuleHandle(L"kernel32"), - "GetLogicalProcessorInformation")); - if (NULL == glpi) { - return; - } - // Determine buffer size, allocate and get processor information. - // Size can change between calls (unlikely), so a loop is done. - DWORD return_length = 0; - scoped_ptr infos; - while (!glpi(infos.get(), &return_length)) { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - infos.reset(new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[ - return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)]); - } else { - return; - } - } - *physical_cpus = 0; - *cache_size = 0; - for (size_t i = 0; - i < return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) { - if (infos[i].Relationship == RelationProcessorCore) { - ++*physical_cpus; - } else if (infos[i].Relationship == RelationCache) { - int next_cache_size = static_cast(infos[i].Cache.Size); - if (next_cache_size >= *cache_size) { - *cache_size = next_cache_size; - } - } - } - return; -} -#else -// TODO(fbarchard): Use gcc 4.4 provided cpuid intrinsic -// 32 bit fpic requires ebx be preserved -#if (defined(__pic__) || defined(__APPLE__)) && defined(__i386__) -static inline void __cpuid(int cpu_info[4], int info_type) { - __asm__ volatile ( // NOLINT - "mov %%ebx, %%edi\n" - "cpuid\n" - "xchg %%edi, %%ebx\n" - : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) - : "a"(info_type) - ); // NOLINT -} -#elif defined(__i386__) || defined(__x86_64__) -static inline void __cpuid(int cpu_info[4], int info_type) { - __asm__ volatile ( // NOLINT - "cpuid\n" - : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) - : "a"(info_type) - ); // NOLINT -} -#endif -#endif // WEBRTC_WIN - -// Note(fbarchard): -// Family and model are extended family and extended model. 8 bits each. -SystemInfo::SystemInfo() - : physical_cpus_(1), logical_cpus_(1), cache_size_(0), - cpu_family_(0), cpu_model_(0), cpu_stepping_(0), - cpu_speed_(0), memory_(0) { - // Initialize the basic information. -#if defined(__arm__) || defined(_M_ARM) - cpu_arch_ = SI_ARCH_ARM; -#elif defined(__x86_64__) || defined(_M_X64) - cpu_arch_ = SI_ARCH_X64; -#elif defined(__i386__) || defined(_M_IX86) - cpu_arch_ = SI_ARCH_X86; -#else - cpu_arch_ = SI_ARCH_UNKNOWN; -#endif - -#if defined(WEBRTC_WIN) - SYSTEM_INFO si; - GetSystemInfo(&si); - logical_cpus_ = si.dwNumberOfProcessors; - GetProcessorInformation(&physical_cpus_, &cache_size_); - if (physical_cpus_ <= 0) { - physical_cpus_ = logical_cpus_; - } - cpu_family_ = si.wProcessorLevel; - cpu_model_ = si.wProcessorRevision >> 8; - cpu_stepping_ = si.wProcessorRevision & 0xFF; -#elif defined(WEBRTC_MAC) - uint32_t sysctl_value; - size_t length = sizeof(sysctl_value); - if (!sysctlbyname("hw.physicalcpu_max", &sysctl_value, &length, NULL, 0)) { - physical_cpus_ = static_cast(sysctl_value); - } - length = sizeof(sysctl_value); - if (!sysctlbyname("hw.logicalcpu_max", &sysctl_value, &length, NULL, 0)) { - logical_cpus_ = static_cast(sysctl_value); - } - uint64_t sysctl_value64; - length = sizeof(sysctl_value64); - if (!sysctlbyname("hw.l3cachesize", &sysctl_value64, &length, NULL, 0)) { - cache_size_ = static_cast(sysctl_value64); - } - if (!cache_size_) { - length = sizeof(sysctl_value64); - if (!sysctlbyname("hw.l2cachesize", &sysctl_value64, &length, NULL, 0)) { - cache_size_ = static_cast(sysctl_value64); - } - } - length = sizeof(sysctl_value); - if (!sysctlbyname("machdep.cpu.family", &sysctl_value, &length, NULL, 0)) { - cpu_family_ = static_cast(sysctl_value); - } - length = sizeof(sysctl_value); - if (!sysctlbyname("machdep.cpu.model", &sysctl_value, &length, NULL, 0)) { - cpu_model_ = static_cast(sysctl_value); - } - length = sizeof(sysctl_value); - if (!sysctlbyname("machdep.cpu.stepping", &sysctl_value, &length, NULL, 0)) { - cpu_stepping_ = static_cast(sysctl_value); - } -#elif defined(__native_client__) - // TODO(ryanpetrie): Implement this via PPAPI when it's available. -#else // WEBRTC_LINUX - ProcCpuInfo proc_info; - if (proc_info.LoadFromSystem()) { - proc_info.GetNumCpus(&logical_cpus_); - proc_info.GetNumPhysicalCpus(&physical_cpus_); - proc_info.GetCpuFamily(&cpu_family_); -#if defined(CPU_X86) - // These values only apply to x86 systems. - proc_info.GetSectionIntValue(0, "model", &cpu_model_); - proc_info.GetSectionIntValue(0, "stepping", &cpu_stepping_); - proc_info.GetSectionIntValue(0, "cpu MHz", &cpu_speed_); - proc_info.GetSectionIntValue(0, "cache size", &cache_size_); - cache_size_ *= 1024; -#endif - } - // ProcCpuInfo reads cpu speed from "cpu MHz" under /proc/cpuinfo. - // But that number is a moving target which can change on-the-fly according to - // many factors including system workload. - // See /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors. - // The one in /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq is more - // accurate. We use it as our cpu speed when it is available. - // cpuinfo_max_freq is measured in KHz and requires conversion to MHz. - int max_freq = rtc::ReadCpuMaxFreq(); - if (max_freq > 0) { - cpu_speed_ = max_freq / 1000; - } -#endif -// For L2 CacheSize see also -// http://www.flounder.com/cpuid_explorer2.htm#CPUID(0x800000006) -#ifdef CPU_X86 - if (cache_size_ == 0) { - int cpu_info[4]; - __cpuid(cpu_info, 0x80000000); // query maximum extended cpuid function. - if (static_cast(cpu_info[0]) >= 0x80000006) { - __cpuid(cpu_info, 0x80000006); - cache_size_ = (cpu_info[2] >> 16) * 1024; - } - } -#endif -} - -// Return the number of cpu threads available to the system. -int SystemInfo::GetMaxCpus() { - return logical_cpus_; -} - -// Return the number of cpu cores available to the system. -int SystemInfo::GetMaxPhysicalCpus() { - return physical_cpus_; -} - -// Return the number of cpus available to the process. Since affinity can be -// changed on the fly, do not cache this value. -// Can be affected by heat. -int SystemInfo::GetCurCpus() { - int cur_cpus; -#if defined(WEBRTC_WIN) - DWORD_PTR process_mask, system_mask; - ::GetProcessAffinityMask(::GetCurrentProcess(), &process_mask, &system_mask); - for (cur_cpus = 0; process_mask; ++cur_cpus) { - // Sparse-ones algorithm. There are slightly faster methods out there but - // they are unintuitive and won't make a difference on a single dword. - process_mask &= (process_mask - 1); - } -#elif defined(WEBRTC_MAC) - uint32_t sysctl_value; - size_t length = sizeof(sysctl_value); - int error = sysctlbyname("hw.ncpu", &sysctl_value, &length, NULL, 0); - cur_cpus = !error ? static_cast(sysctl_value) : 1; -#else - // Linux, Solaris, WEBRTC_ANDROID - cur_cpus = static_cast(sysconf(_SC_NPROCESSORS_ONLN)); -#endif - return cur_cpus; -} - -// Return the type of this CPU. -SystemInfo::Architecture SystemInfo::GetCpuArchitecture() { - return cpu_arch_; -} - -// Returns the vendor string from the cpu, e.g. "GenuineIntel", "AuthenticAMD". -// See "Intel Processor Identification and the CPUID Instruction" -// (Intel document number: 241618) -std::string SystemInfo::GetCpuVendor() { - if (cpu_vendor_.empty()) { -#if defined(CPU_X86) - int cpu_info[4]; - __cpuid(cpu_info, 0); - cpu_info[0] = cpu_info[1]; // Reorder output - cpu_info[1] = cpu_info[3]; - cpu_info[2] = cpu_info[2]; - cpu_info[3] = 0; - cpu_vendor_ = std::string(reinterpret_cast(&cpu_info[0])); -#elif defined(CPU_ARM) - cpu_vendor_ = std::string("ARM"); -#else - cpu_vendor_ = std::string("Undefined"); -#endif - } - return cpu_vendor_; -} - -int SystemInfo::GetCpuCacheSize() { - return cache_size_; -} - -// Return the "family" of this CPU. -int SystemInfo::GetCpuFamily() { - return cpu_family_; -} - -// Return the "model" of this CPU. -int SystemInfo::GetCpuModel() { - return cpu_model_; -} - -// Return the "stepping" of this CPU. -int SystemInfo::GetCpuStepping() { - return cpu_stepping_; -} - -// Return the clockrate of the primary processor in Mhz. This value can be -// cached. Returns -1 on error. -int SystemInfo::GetMaxCpuSpeed() { - if (cpu_speed_) { - return cpu_speed_; - } -#if defined(WEBRTC_WIN) - HKEY key; - static const WCHAR keyName[] = - L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName , 0, KEY_QUERY_VALUE, &key) - == ERROR_SUCCESS) { - DWORD data, len; - len = sizeof(data); - - if (RegQueryValueEx(key, L"~Mhz", 0, 0, reinterpret_cast(&data), - &len) == ERROR_SUCCESS) { - cpu_speed_ = data; - } else { - LOG(LS_WARNING) << "Failed to query registry value HKLM\\" << keyName - << "\\~Mhz"; - cpu_speed_ = -1; - } - - RegCloseKey(key); - } else { - LOG(LS_WARNING) << "Failed to open registry key HKLM\\" << keyName; - cpu_speed_ = -1; - } -#elif defined(WEBRTC_MAC) - uint64_t sysctl_value; - size_t length = sizeof(sysctl_value); - int error = sysctlbyname("hw.cpufrequency_max", &sysctl_value, &length, - NULL, 0); - cpu_speed_ = !error ? static_cast(sysctl_value/1000000) : -1; -#else - // TODO(fbarchard): Implement using proc/cpuinfo - cpu_speed_ = 0; -#endif - return cpu_speed_; -} - -// Dynamically check the current clockrate, which could be reduced because of -// powersaving profiles. Eventually for windows we want to query WMI for -// root\WMI::ProcessorPerformance.InstanceName="Processor_Number_0".frequency -int SystemInfo::GetCurCpuSpeed() { -#if defined(WEBRTC_WIN) - // TODO(fbarchard): Add WMI check, requires COM initialization - // NOTE(fbarchard): Testable on Sandy Bridge. - return GetMaxCpuSpeed(); -#elif defined(WEBRTC_MAC) - uint64_t sysctl_value; - size_t length = sizeof(sysctl_value); - int error = sysctlbyname("hw.cpufrequency", &sysctl_value, &length, NULL, 0); - return !error ? static_cast(sysctl_value/1000000) : GetMaxCpuSpeed(); -#else // WEBRTC_LINUX - // TODO(fbarchard): Use proc/cpuinfo for Cur speed on Linux. - return GetMaxCpuSpeed(); -#endif -} - -// Returns the amount of installed physical memory in Bytes. Cacheable. -// Returns -1 on error. -int64 SystemInfo::GetMemorySize() { - if (memory_) { - return memory_; - } - -#if defined(WEBRTC_WIN) - MEMORYSTATUSEX status = {0}; - status.dwLength = sizeof(status); - - if (GlobalMemoryStatusEx(&status)) { - memory_ = status.ullTotalPhys; - } else { - LOG_GLE(LS_WARNING) << "GlobalMemoryStatusEx failed."; - memory_ = -1; - } - -#elif defined(WEBRTC_MAC) - size_t len = sizeof(memory_); - int error = sysctlbyname("hw.memsize", &memory_, &len, NULL, 0); - if (error || memory_ == 0) { - memory_ = -1; - } -#else // WEBRTC_LINUX - memory_ = static_cast(sysconf(_SC_PHYS_PAGES)) * - static_cast(sysconf(_SC_PAGESIZE)); - if (memory_ < 0) { - LOG(LS_WARNING) << "sysconf(_SC_PHYS_PAGES) failed." - << "sysconf(_SC_PHYS_PAGES) " << sysconf(_SC_PHYS_PAGES) - << "sysconf(_SC_PAGESIZE) " << sysconf(_SC_PAGESIZE); - memory_ = -1; - } -#endif - - return memory_; -} - - -// Return the name of the machine model we are currently running on. -// This is a human readable string that consists of the name and version -// number of the hardware, i.e 'MacBookAir1,1'. Returns an empty string if -// model can not be determined. The string is cached for subsequent calls. -std::string SystemInfo::GetMachineModel() { - if (!machine_model_.empty()) { - return machine_model_; - } - -#if defined(WEBRTC_MAC) - char buffer[128]; - size_t length = sizeof(buffer); - int error = sysctlbyname("hw.model", buffer, &length, NULL, 0); - if (!error) { - machine_model_.assign(buffer, length - 1); - } else { - machine_model_.clear(); - } -#else - machine_model_ = "Not available"; -#endif - - return machine_model_; -} - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -// Helper functions to query IOKit for video hardware properties. -static CFTypeRef SearchForProperty(io_service_t port, CFStringRef name) { - return IORegistryEntrySearchCFProperty(port, kIOServicePlane, - name, kCFAllocatorDefault, - kIORegistryIterateRecursively | kIORegistryIterateParents); -} - -static void GetProperty(io_service_t port, CFStringRef name, int* value) { - if (!value) return; - CFTypeRef ref = SearchForProperty(port, name); - if (ref) { - CFTypeID refType = CFGetTypeID(ref); - if (CFNumberGetTypeID() == refType) { - CFNumberRef number = reinterpret_cast(ref); - p_convertCFNumberToInt(number, value); - } else if (CFDataGetTypeID() == refType) { - CFDataRef data = reinterpret_cast(ref); - if (CFDataGetLength(data) == sizeof(UInt32)) { - *value = *reinterpret_cast(CFDataGetBytePtr(data)); - } - } - CFRelease(ref); - } -} - -static void GetProperty(io_service_t port, CFStringRef name, - std::string* value) { - if (!value) return; - CFTypeRef ref = SearchForProperty(port, name); - if (ref) { - CFTypeID refType = CFGetTypeID(ref); - if (CFStringGetTypeID() == refType) { - CFStringRef stringRef = reinterpret_cast(ref); - p_convertHostCFStringRefToCPPString(stringRef, *value); - } else if (CFDataGetTypeID() == refType) { - CFDataRef dataRef = reinterpret_cast(ref); - *value = std::string(reinterpret_cast( - CFDataGetBytePtr(dataRef)), CFDataGetLength(dataRef)); - } - CFRelease(ref); - } -} -#endif - -// Fills a struct with information on the graphics adapater and returns true -// iff successful. -bool SystemInfo::GetGpuInfo(GpuInfo *info) { - if (!info) return false; -#if defined(WEBRTC_WIN) && !defined(EXCLUDE_D3D9) - D3DADAPTER_IDENTIFIER9 identifier; - HRESULT hr = E_FAIL; - HINSTANCE d3d_lib = LoadLibrary(L"d3d9.dll"); - - if (d3d_lib) { - typedef IDirect3D9* (WINAPI *D3DCreate9Proc)(UINT); - D3DCreate9Proc d3d_create_proc = reinterpret_cast( - GetProcAddress(d3d_lib, "Direct3DCreate9")); - if (d3d_create_proc) { - IDirect3D9* d3d = d3d_create_proc(D3D_SDK_VERSION); - if (d3d) { - hr = d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier); - d3d->Release(); - } - } - FreeLibrary(d3d_lib); - } - - if (hr != D3D_OK) { - LOG(LS_ERROR) << "Failed to access Direct3D9 information."; - return false; - } - - info->device_name = identifier.DeviceName; - info->description = identifier.Description; - info->vendor_id = identifier.VendorId; - info->device_id = identifier.DeviceId; - info->driver = identifier.Driver; - // driver_version format: product.version.subversion.build - std::stringstream ss; - ss << HIWORD(identifier.DriverVersion.HighPart) << "." - << LOWORD(identifier.DriverVersion.HighPart) << "." - << HIWORD(identifier.DriverVersion.LowPart) << "." - << LOWORD(identifier.DriverVersion.LowPart); - info->driver_version = ss.str(); - return true; -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - // We'll query the IOKit for the gpu of the main display. - io_service_t display_service_port = CGDisplayIOServicePort( - kCGDirectMainDisplay); - GetProperty(display_service_port, CFSTR("vendor-id"), &info->vendor_id); - GetProperty(display_service_port, CFSTR("device-id"), &info->device_id); - GetProperty(display_service_port, CFSTR("model"), &info->description); - return true; -#else // WEBRTC_LINUX - // TODO(fbarchard): Implement this on Linux - return false; -#endif -} -} // namespace rtc diff --git a/webrtc/base/systeminfo.h b/webrtc/base/systeminfo.h deleted file mode 100644 index 44088629b..000000000 --- a/webrtc/base/systeminfo.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_SYSTEMINFO_H__ -#define WEBRTC_BASE_SYSTEMINFO_H__ - -#include - -#include "webrtc/base/basictypes.h" - -namespace rtc { - -class SystemInfo { - public: - enum Architecture { - SI_ARCH_UNKNOWN = -1, - SI_ARCH_X86 = 0, - SI_ARCH_X64 = 1, - SI_ARCH_ARM = 2 - }; - - SystemInfo(); - - // The number of CPU Cores in the system. - int GetMaxPhysicalCpus(); - // The number of CPU Threads in the system. - int GetMaxCpus(); - // The number of CPU Threads currently available to this process. - int GetCurCpus(); - // Identity of the CPUs. - Architecture GetCpuArchitecture(); - std::string GetCpuVendor(); - int GetCpuFamily(); - int GetCpuModel(); - int GetCpuStepping(); - // Return size of CPU cache in bytes. Uses largest available cache (L3). - int GetCpuCacheSize(); - // Estimated speed of the CPUs, in MHz. e.g. 2400 for 2.4 GHz - int GetMaxCpuSpeed(); - int GetCurCpuSpeed(); - // Total amount of physical memory, in bytes. - int64 GetMemorySize(); - // The model name of the machine, e.g. "MacBookAir1,1" - std::string GetMachineModel(); - - // The gpu identifier - struct GpuInfo { - GpuInfo() : vendor_id(0), device_id(0) {} - std::string device_name; - std::string description; - int vendor_id; - int device_id; - std::string driver; - std::string driver_version; - }; - bool GetGpuInfo(GpuInfo *info); - - private: - int physical_cpus_; - int logical_cpus_; - int cache_size_; - Architecture cpu_arch_; - std::string cpu_vendor_; - int cpu_family_; - int cpu_model_; - int cpu_stepping_; - int cpu_speed_; - int64 memory_; - std::string machine_model_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_SYSTEMINFO_H__ diff --git a/webrtc/base/systeminfo_unittest.cc b/webrtc/base/systeminfo_unittest.cc deleted file mode 100644 index fec553582..000000000 --- a/webrtc/base/systeminfo_unittest.cc +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/systeminfo.h" - -#if defined(CPU_X86) || defined(CPU_ARM) -TEST(SystemInfoTest, CpuVendorNonEmpty) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CpuVendor: " << info.GetCpuVendor(); - EXPECT_FALSE(info.GetCpuVendor().empty()); -} - -// Tests Vendor identification is Intel or AMD. -// See Also http://en.wikipedia.org/wiki/CPUID -TEST(SystemInfoTest, CpuVendorIntelAMDARM) { - rtc::SystemInfo info; -#if defined(CPU_X86) - EXPECT_TRUE(rtc::string_match(info.GetCpuVendor().c_str(), - "GenuineIntel") || - rtc::string_match(info.GetCpuVendor().c_str(), - "AuthenticAMD")); -#elif defined(CPU_ARM) - EXPECT_TRUE(rtc::string_match(info.GetCpuVendor().c_str(), "ARM")); -#endif -} -#endif // defined(CPU_X86) || defined(CPU_ARM) - -// Tests CpuArchitecture matches expectations. -TEST(SystemInfoTest, GetCpuArchitecture) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CpuArchitecture: " << info.GetCpuArchitecture(); - rtc::SystemInfo::Architecture architecture = info.GetCpuArchitecture(); -#if defined(CPU_X86) || defined(CPU_ARM) - if (sizeof(intptr_t) == 8) { - EXPECT_EQ(rtc::SystemInfo::SI_ARCH_X64, architecture); - } else if (sizeof(intptr_t) == 4) { -#if defined(CPU_ARM) - EXPECT_EQ(rtc::SystemInfo::SI_ARCH_ARM, architecture); -#else - EXPECT_EQ(rtc::SystemInfo::SI_ARCH_X86, architecture); -#endif - } -#endif -} - -// Tests Cpu Cache Size -TEST(SystemInfoTest, CpuCacheSize) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CpuCacheSize: " << info.GetCpuCacheSize(); - EXPECT_GE(info.GetCpuCacheSize(), 8192); // 8 KB min cache - EXPECT_LE(info.GetCpuCacheSize(), 1024 * 1024 * 1024); // 1 GB max cache -} - -// Tests MachineModel is set. On Mac test machine model is known. -TEST(SystemInfoTest, MachineModelKnown) { - rtc::SystemInfo info; - EXPECT_FALSE(info.GetMachineModel().empty()); - const char *machine_model = info.GetMachineModel().c_str(); - LOG(LS_INFO) << "MachineModel: " << machine_model; - bool known = true; -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - // Full list as of May 2012. Update when new OSX based models are added. - known = rtc::string_match(machine_model, "MacBookPro*") || - rtc::string_match(machine_model, "MacBookAir*") || - rtc::string_match(machine_model, "MacBook*") || - rtc::string_match(machine_model, "MacPro*") || - rtc::string_match(machine_model, "Macmini*") || - rtc::string_match(machine_model, "iMac*") || - rtc::string_match(machine_model, "Xserve*"); -#elif !defined(WEBRTC_IOS) - // All other machines return Not available. - known = rtc::string_match(info.GetMachineModel().c_str(), - "Not available"); -#endif - if (!known) { - LOG(LS_WARNING) << "Machine Model Unknown: " << machine_model; - } -} - -// Tests maximum cpu clockrate. -TEST(SystemInfoTest, CpuMaxCpuSpeed) { - rtc::SystemInfo info; - LOG(LS_INFO) << "MaxCpuSpeed: " << info.GetMaxCpuSpeed(); - EXPECT_GT(info.GetMaxCpuSpeed(), 0); - EXPECT_LT(info.GetMaxCpuSpeed(), 100000); // 100 Ghz -} - -// Tests current cpu clockrate. -TEST(SystemInfoTest, CpuCurCpuSpeed) { - rtc::SystemInfo info; - LOG(LS_INFO) << "MaxCurSpeed: " << info.GetCurCpuSpeed(); - EXPECT_GT(info.GetCurCpuSpeed(), 0); - EXPECT_LT(info.GetMaxCpuSpeed(), 100000); -} - -// Tests physical memory size. -TEST(SystemInfoTest, MemorySize) { - rtc::SystemInfo info; - LOG(LS_INFO) << "MemorySize: " << info.GetMemorySize(); - EXPECT_GT(info.GetMemorySize(), -1); -} - -// Tests number of logical cpus available to the system. -TEST(SystemInfoTest, MaxCpus) { - rtc::SystemInfo info; - LOG(LS_INFO) << "MaxCpus: " << info.GetMaxCpus(); - EXPECT_GT(info.GetMaxCpus(), 0); -} - -// Tests number of physical cpus available to the system. -TEST(SystemInfoTest, MaxPhysicalCpus) { - rtc::SystemInfo info; - LOG(LS_INFO) << "MaxPhysicalCpus: " << info.GetMaxPhysicalCpus(); - EXPECT_GT(info.GetMaxPhysicalCpus(), 0); - EXPECT_LE(info.GetMaxPhysicalCpus(), info.GetMaxCpus()); -} - -// Tests number of logical cpus available to the process. -TEST(SystemInfoTest, CurCpus) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CurCpus: " << info.GetCurCpus(); - EXPECT_GT(info.GetCurCpus(), 0); - EXPECT_LE(info.GetCurCpus(), info.GetMaxCpus()); -} - -#ifdef CPU_X86 -// CPU family/model/stepping is only available on X86. The following tests -// that they are set when running on x86 CPUs. Valid Family/Model/Stepping -// values are non-zero on known CPUs. - -// Tests Intel CPU Family identification. -TEST(SystemInfoTest, CpuFamily) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CpuFamily: " << info.GetCpuFamily(); - EXPECT_GT(info.GetCpuFamily(), 0); -} - -// Tests Intel CPU Model identification. -TEST(SystemInfoTest, CpuModel) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CpuModel: " << info.GetCpuModel(); - EXPECT_GT(info.GetCpuModel(), 0); -} - -// Tests Intel CPU Stepping identification. -TEST(SystemInfoTest, CpuStepping) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CpuStepping: " << info.GetCpuStepping(); - EXPECT_GT(info.GetCpuStepping(), 0); -} -#else // CPU_X86 -// If not running on x86 CPU the following tests expect the functions to -// return 0. -TEST(SystemInfoTest, CpuFamily) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CpuFamily: " << info.GetCpuFamily(); - EXPECT_EQ(0, info.GetCpuFamily()); -} - -// Tests Intel CPU Model identification. -TEST(SystemInfoTest, CpuModel) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CpuModel: " << info.GetCpuModel(); - EXPECT_EQ(0, info.GetCpuModel()); -} - -// Tests Intel CPU Stepping identification. -TEST(SystemInfoTest, CpuStepping) { - rtc::SystemInfo info; - LOG(LS_INFO) << "CpuStepping: " << info.GetCpuStepping(); - EXPECT_EQ(0, info.GetCpuStepping()); -} -#endif // CPU_X86 - -#if WEBRTC_WIN && !defined(EXCLUDE_D3D9) -TEST(SystemInfoTest, GpuInfo) { - rtc::SystemInfo info; - rtc::SystemInfo::GpuInfo gi; - EXPECT_TRUE(info.GetGpuInfo(&gi)); - LOG(LS_INFO) << "GpuDriver: " << gi.driver; - EXPECT_FALSE(gi.driver.empty()); - LOG(LS_INFO) << "GpuDriverVersion: " << gi.driver_version; - EXPECT_FALSE(gi.driver_version.empty()); -} -#endif diff --git a/webrtc/base/task.cc b/webrtc/base/task.cc deleted file mode 100644 index ed9f42626..000000000 --- a/webrtc/base/task.cc +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/task.h" -#include "webrtc/base/common.h" -#include "webrtc/base/taskrunner.h" - -namespace rtc { - -int32 Task::unique_id_seed_ = 0; - -Task::Task(TaskParent *parent) - : TaskParent(this, parent), - state_(STATE_INIT), - blocked_(false), - done_(false), - aborted_(false), - busy_(false), - error_(false), - start_time_(0), - timeout_time_(0), - timeout_seconds_(0), - timeout_suspended_(false) { - unique_id_ = unique_id_seed_++; - - // sanity check that we didn't roll-over our id seed - ASSERT(unique_id_ < unique_id_seed_); -} - -Task::~Task() { - // Is this task being deleted in the correct manner? - ASSERT(!done_ || GetRunner()->is_ok_to_delete(this)); - ASSERT(state_ == STATE_INIT || done_); - ASSERT(state_ == STATE_INIT || blocked_); - - // If the task is being deleted without being done, it - // means that it hasn't been removed from its parent. - // This happens if a task is deleted outside of TaskRunner. - if (!done_) { - Stop(); - } -} - -int64 Task::CurrentTime() { - return GetRunner()->CurrentTime(); -} - -int64 Task::ElapsedTime() { - return CurrentTime() - start_time_; -} - -void Task::Start() { - if (state_ != STATE_INIT) - return; - // Set the start time before starting the task. Otherwise if the task - // finishes quickly and deletes the Task object, setting start_time_ - // will crash. - start_time_ = CurrentTime(); - GetRunner()->StartTask(this); -} - -void Task::Step() { - if (done_) { -#ifdef _DEBUG - // we do not know how !blocked_ happens when done_ - should be impossible. - // But it causes problems, so in retail build, we force blocked_, and - // under debug we assert. - ASSERT(blocked_); -#else - blocked_ = true; -#endif - return; - } - - // Async Error() was called - if (error_) { - done_ = true; - state_ = STATE_ERROR; - blocked_ = true; -// obsolete - an errored task is not considered done now -// SignalDone(); - - Stop(); -#ifdef _DEBUG - // verify that stop removed this from its parent - ASSERT(!parent()->IsChildTask(this)); -#endif - return; - } - - busy_ = true; - int new_state = Process(state_); - busy_ = false; - - if (aborted_) { - Abort(true); // no need to wake because we're awake - return; - } - - if (new_state == STATE_BLOCKED) { - blocked_ = true; - // Let the timeout continue - } else { - state_ = new_state; - blocked_ = false; - ResetTimeout(); - } - - if (new_state == STATE_DONE) { - done_ = true; - } else if (new_state == STATE_ERROR) { - done_ = true; - error_ = true; - } - - if (done_) { -// obsolete - call this yourself -// SignalDone(); - - Stop(); -#if _DEBUG - // verify that stop removed this from its parent - ASSERT(!parent()->IsChildTask(this)); -#endif - blocked_ = true; - } -} - -void Task::Abort(bool nowake) { - // Why only check for done_ (instead of "aborted_ || done_")? - // - // If aborted_ && !done_, it means the logic for aborting still - // needs to be executed (because busy_ must have been true when - // Abort() was previously called). - if (done_) - return; - aborted_ = true; - if (!busy_) { - done_ = true; - blocked_ = true; - error_ = true; - - // "done_" is set before calling "Stop()" to ensure that this code - // doesn't execute more than once (recursively) for the same task. - Stop(); -#ifdef _DEBUG - // verify that stop removed this from its parent - ASSERT(!parent()->IsChildTask(this)); -#endif - if (!nowake) { - // WakeTasks to self-delete. - // Don't call Wake() because it is a no-op after "done_" is set. - // Even if Wake() did run, it clears "blocked_" which isn't desireable. - GetRunner()->WakeTasks(); - } - } -} - -void Task::Wake() { - if (done_) - return; - if (blocked_) { - blocked_ = false; - GetRunner()->WakeTasks(); - } -} - -void Task::Error() { - if (error_ || done_) - return; - error_ = true; - Wake(); -} - -std::string Task::GetStateName(int state) const { - switch (state) { - case STATE_BLOCKED: return "BLOCKED"; - case STATE_INIT: return "INIT"; - case STATE_START: return "START"; - case STATE_DONE: return "DONE"; - case STATE_ERROR: return "ERROR"; - case STATE_RESPONSE: return "RESPONSE"; - } - return "??"; -} - -int Task::Process(int state) { - int newstate = STATE_ERROR; - - if (TimedOut()) { - ClearTimeout(); - newstate = OnTimeout(); - SignalTimeout(); - } else { - switch (state) { - case STATE_INIT: - newstate = STATE_START; - break; - case STATE_START: - newstate = ProcessStart(); - break; - case STATE_RESPONSE: - newstate = ProcessResponse(); - break; - case STATE_DONE: - case STATE_ERROR: - newstate = STATE_BLOCKED; - break; - } - } - - return newstate; -} - -void Task::Stop() { - // No need to wake because we're either awake or in abort - TaskParent::OnStopped(this); -} - -void Task::set_timeout_seconds(const int timeout_seconds) { - timeout_seconds_ = timeout_seconds; - ResetTimeout(); -} - -bool Task::TimedOut() { - return timeout_seconds_ && - timeout_time_ && - CurrentTime() >= timeout_time_; -} - -void Task::ResetTimeout() { - int64 previous_timeout_time = timeout_time_; - bool timeout_allowed = (state_ != STATE_INIT) - && (state_ != STATE_DONE) - && (state_ != STATE_ERROR); - if (timeout_seconds_ && timeout_allowed && !timeout_suspended_) - timeout_time_ = CurrentTime() + - (timeout_seconds_ * kSecToMsec * kMsecTo100ns); - else - timeout_time_ = 0; - - GetRunner()->UpdateTaskTimeout(this, previous_timeout_time); -} - -void Task::ClearTimeout() { - int64 previous_timeout_time = timeout_time_; - timeout_time_ = 0; - GetRunner()->UpdateTaskTimeout(this, previous_timeout_time); -} - -void Task::SuspendTimeout() { - if (!timeout_suspended_) { - timeout_suspended_ = true; - ResetTimeout(); - } -} - -void Task::ResumeTimeout() { - if (timeout_suspended_) { - timeout_suspended_ = false; - ResetTimeout(); - } -} - -} // namespace rtc diff --git a/webrtc/base/task.h b/webrtc/base/task.h deleted file mode 100644 index 77d767a78..000000000 --- a/webrtc/base/task.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TASK_H__ -#define WEBRTC_BASE_TASK_H__ - -#include -#include "webrtc/base/basictypes.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/taskparent.h" - -///////////////////////////////////////////////////////////////////// -// -// TASK -// -///////////////////////////////////////////////////////////////////// -// -// Task is a state machine infrastructure. States are pushed forward by -// pushing forwards a TaskRunner that holds on to all Tasks. The purpose -// of Task is threefold: -// -// (1) It manages ongoing work on the UI thread. Multitasking without -// threads, keeping it easy, keeping it real. :-) It does this by -// organizing a set of states for each task. When you return from your -// Process*() function, you return an integer for the next state. You do -// not go onto the next state yourself. Every time you enter a state, -// you check to see if you can do anything yet. If not, you return -// STATE_BLOCKED. If you _could_ do anything, do not return -// STATE_BLOCKED - even if you end up in the same state, return -// STATE_mysamestate. When you are done, return STATE_DONE and then the -// task will self-delete sometime afterwards. -// -// (2) It helps you avoid all those reentrancy problems when you chain -// too many triggers on one thread. Basically if you want to tell a task -// to process something for you, you feed your task some information and -// then you Wake() it. Don't tell it to process it right away. If it -// might be working on something as you send it information, you may want -// to have a queue in the task. -// -// (3) Finally it helps manage parent tasks and children. If a parent -// task gets aborted, all the children tasks are too. The nice thing -// about this, for example, is if you have one parent task that -// represents, say, and Xmpp connection, then you can spawn a whole bunch -// of infinite lifetime child tasks and now worry about cleaning them up. -// When the parent task goes to STATE_DONE, the task engine will make -// sure all those children are aborted and get deleted. -// -// Notice that Task has a few built-in states, e.g., -// -// STATE_INIT - the task isn't running yet -// STATE_START - the task is in its first state -// STATE_RESPONSE - the task is in its second state -// STATE_DONE - the task is done -// -// STATE_ERROR - indicates an error - we should audit the error code in -// light of any usage of it to see if it should be improved. When I -// first put down the task stuff I didn't have a good sense of what was -// needed for Abort and Error, and now the subclasses of Task will ground -// the design in a stronger way. -// -// STATE_NEXT - the first undefined state number. (like WM_USER) - you -// can start defining more task states there. -// -// When you define more task states, just override Process(int state) and -// add your own switch statement. If you want to delegate to -// Task::Process, you can effectively delegate to its switch statement. -// No fancy method pointers or such - this is all just pretty low tech, -// easy to debug, and fast. -// -// Also notice that Task has some primitive built-in timeout functionality. -// -// A timeout is defined as "the task stays in STATE_BLOCKED longer than -// timeout_seconds_." -// -// Descendant classes can override this behavior by calling the -// various protected methods to change the timeout behavior. For -// instance, a descendand might call SuspendTimeout() when it knows -// that it isn't waiting for anything that might timeout, but isn't -// yet in the STATE_DONE state. -// - -namespace rtc { - -// Executes a sequence of steps -class Task : public TaskParent { - public: - Task(TaskParent *parent); - virtual ~Task(); - - int32 unique_id() { return unique_id_; } - - void Start(); - void Step(); - int GetState() const { return state_; } - bool HasError() const { return (GetState() == STATE_ERROR); } - bool Blocked() const { return blocked_; } - bool IsDone() const { return done_; } - int64 ElapsedTime(); - - // Called from outside to stop task without any more callbacks - void Abort(bool nowake = false); - - bool TimedOut(); - - int64 timeout_time() const { return timeout_time_; } - int timeout_seconds() const { return timeout_seconds_; } - void set_timeout_seconds(int timeout_seconds); - - sigslot::signal0<> SignalTimeout; - - // Called inside the task to signal that the task may be unblocked - void Wake(); - - protected: - - enum { - STATE_BLOCKED = -1, - STATE_INIT = 0, - STATE_START = 1, - STATE_DONE = 2, - STATE_ERROR = 3, - STATE_RESPONSE = 4, - STATE_NEXT = 5, // Subclasses which need more states start here and higher - }; - - // Called inside to advise that the task should wake and signal an error - void Error(); - - int64 CurrentTime(); - - virtual std::string GetStateName(int state) const; - virtual int Process(int state); - virtual void Stop(); - virtual int ProcessStart() = 0; - virtual int ProcessResponse() { return STATE_DONE; } - - void ResetTimeout(); - void ClearTimeout(); - - void SuspendTimeout(); - void ResumeTimeout(); - - protected: - virtual int OnTimeout() { - // by default, we are finished after timing out - return STATE_DONE; - } - - private: - void Done(); - - int state_; - bool blocked_; - bool done_; - bool aborted_; - bool busy_; - bool error_; - int64 start_time_; - int64 timeout_time_; - int timeout_seconds_; - bool timeout_suspended_; - int32 unique_id_; - - static int32 unique_id_seed_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_TASK_H__ diff --git a/webrtc/base/task_unittest.cc b/webrtc/base/task_unittest.cc deleted file mode 100644 index 8831259c6..000000000 --- a/webrtc/base/task_unittest.cc +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if defined(WEBRTC_POSIX) -#include -#endif // WEBRTC_POSIX - -// TODO: Remove this once the cause of sporadic failures in these -// tests is tracked down. -#include - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#endif // WEBRTC_WIN - -#include "webrtc/base/common.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/task.h" -#include "webrtc/base/taskrunner.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { - -static int64 GetCurrentTime() { - return static_cast(Time()) * 10000; -} - -// feel free to change these numbers. Note that '0' won't work, though -#define STUCK_TASK_COUNT 5 -#define HAPPY_TASK_COUNT 20 - -// this is a generic timeout task which, when it signals timeout, will -// include the unique ID of the task in the signal (we don't use this -// in production code because we haven't yet had occasion to generate -// an array of the same types of task) - -class IdTimeoutTask : public Task, public sigslot::has_slots<> { - public: - explicit IdTimeoutTask(TaskParent *parent) : Task(parent) { - SignalTimeout.connect(this, &IdTimeoutTask::OnLocalTimeout); - } - - sigslot::signal1 SignalTimeoutId; - sigslot::signal1 SignalDoneId; - - virtual int ProcessStart() { - return STATE_RESPONSE; - } - - void OnLocalTimeout() { - SignalTimeoutId(unique_id()); - } - - protected: - virtual void Stop() { - SignalDoneId(unique_id()); - Task::Stop(); - } -}; - -class StuckTask : public IdTimeoutTask { - public: - explicit StuckTask(TaskParent *parent) : IdTimeoutTask(parent) {} - virtual int ProcessStart() { - return STATE_BLOCKED; - } -}; - -class HappyTask : public IdTimeoutTask { - public: - explicit HappyTask(TaskParent *parent) : IdTimeoutTask(parent) { - time_to_perform_ = rand() % (STUCK_TASK_COUNT / 2); - } - virtual int ProcessStart() { - if (ElapsedTime() > (time_to_perform_ * 1000 * 10000)) - return STATE_RESPONSE; - else - return STATE_BLOCKED; - } - - private: - int time_to_perform_; -}; - -// simple implementation of a task runner which uses Windows' -// GetSystemTimeAsFileTime() to get the current clock ticks - -class MyTaskRunner : public TaskRunner { - public: - virtual void WakeTasks() { RunTasks(); } - virtual int64 CurrentTime() { - return GetCurrentTime(); - } - - bool timeout_change() const { - return timeout_change_; - } - - void clear_timeout_change() { - timeout_change_ = false; - } - protected: - virtual void OnTimeoutChange() { - timeout_change_ = true; - } - bool timeout_change_; -}; - -// -// this unit test is primarily concerned (for now) with the timeout -// functionality in tasks. It works as follows: -// -// * Create a bunch of tasks, some "stuck" (ie., guaranteed to timeout) -// and some "happy" (will immediately finish). -// * Set the timeout on the "stuck" tasks to some number of seconds between -// 1 and the number of stuck tasks -// * Start all the stuck & happy tasks in random order -// * Wait "number of stuck tasks" seconds and make sure everything timed out - -class TaskTest : public sigslot::has_slots<> { - public: - TaskTest() {} - - // no need to delete any tasks; the task runner owns them - ~TaskTest() {} - - void Start() { - // create and configure tasks - for (int i = 0; i < STUCK_TASK_COUNT; ++i) { - stuck_[i].task_ = new StuckTask(&task_runner_); - stuck_[i].task_->SignalTimeoutId.connect(this, - &TaskTest::OnTimeoutStuck); - stuck_[i].timed_out_ = false; - stuck_[i].xlat_ = stuck_[i].task_->unique_id(); - stuck_[i].task_->set_timeout_seconds(i + 1); - LOG(LS_INFO) << "Task " << stuck_[i].xlat_ << " created with timeout " - << stuck_[i].task_->timeout_seconds(); - } - - for (int i = 0; i < HAPPY_TASK_COUNT; ++i) { - happy_[i].task_ = new HappyTask(&task_runner_); - happy_[i].task_->SignalTimeoutId.connect(this, - &TaskTest::OnTimeoutHappy); - happy_[i].task_->SignalDoneId.connect(this, - &TaskTest::OnDoneHappy); - happy_[i].timed_out_ = false; - happy_[i].xlat_ = happy_[i].task_->unique_id(); - } - - // start all the tasks in random order - int stuck_index = 0; - int happy_index = 0; - for (int i = 0; i < STUCK_TASK_COUNT + HAPPY_TASK_COUNT; ++i) { - if ((stuck_index < STUCK_TASK_COUNT) && - (happy_index < HAPPY_TASK_COUNT)) { - if (rand() % 2 == 1) { - stuck_[stuck_index++].task_->Start(); - } else { - happy_[happy_index++].task_->Start(); - } - } else if (stuck_index < STUCK_TASK_COUNT) { - stuck_[stuck_index++].task_->Start(); - } else { - happy_[happy_index++].task_->Start(); - } - } - - for (int i = 0; i < STUCK_TASK_COUNT; ++i) { - std::cout << "Stuck task #" << i << " timeout is " << - stuck_[i].task_->timeout_seconds() << " at " << - stuck_[i].task_->timeout_time() << std::endl; - } - - // just a little self-check to make sure we started all the tasks - ASSERT_EQ(STUCK_TASK_COUNT, stuck_index); - ASSERT_EQ(HAPPY_TASK_COUNT, happy_index); - - // run the unblocked tasks - LOG(LS_INFO) << "Running tasks"; - task_runner_.RunTasks(); - - std::cout << "Start time is " << GetCurrentTime() << std::endl; - - // give all the stuck tasks time to timeout - for (int i = 0; !task_runner_.AllChildrenDone() && i < STUCK_TASK_COUNT; - ++i) { - Thread::Current()->ProcessMessages(1000); - for (int j = 0; j < HAPPY_TASK_COUNT; ++j) { - if (happy_[j].task_) { - happy_[j].task_->Wake(); - } - } - LOG(LS_INFO) << "Polling tasks"; - task_runner_.PollTasks(); - } - - // We see occasional test failures here due to the stuck tasks not having - // timed-out yet, which seems like it should be impossible. To help track - // this down we have added logging of the timing information, which we send - // directly to stdout so that we get it in opt builds too. - std::cout << "End time is " << GetCurrentTime() << std::endl; - } - - void OnTimeoutStuck(const int id) { - LOG(LS_INFO) << "Timed out task " << id; - - int i; - for (i = 0; i < STUCK_TASK_COUNT; ++i) { - if (stuck_[i].xlat_ == id) { - stuck_[i].timed_out_ = true; - stuck_[i].task_ = NULL; - break; - } - } - - // getting a bad ID here is a failure, but let's continue - // running to see what else might go wrong - EXPECT_LT(i, STUCK_TASK_COUNT); - } - - void OnTimeoutHappy(const int id) { - int i; - for (i = 0; i < HAPPY_TASK_COUNT; ++i) { - if (happy_[i].xlat_ == id) { - happy_[i].timed_out_ = true; - happy_[i].task_ = NULL; - break; - } - } - - // getting a bad ID here is a failure, but let's continue - // running to see what else might go wrong - EXPECT_LT(i, HAPPY_TASK_COUNT); - } - - void OnDoneHappy(const int id) { - int i; - for (i = 0; i < HAPPY_TASK_COUNT; ++i) { - if (happy_[i].xlat_ == id) { - happy_[i].task_ = NULL; - break; - } - } - - // getting a bad ID here is a failure, but let's continue - // running to see what else might go wrong - EXPECT_LT(i, HAPPY_TASK_COUNT); - } - - void check_passed() { - EXPECT_TRUE(task_runner_.AllChildrenDone()); - - // make sure none of our happy tasks timed out - for (int i = 0; i < HAPPY_TASK_COUNT; ++i) { - EXPECT_FALSE(happy_[i].timed_out_); - } - - // make sure all of our stuck tasks timed out - for (int i = 0; i < STUCK_TASK_COUNT; ++i) { - EXPECT_TRUE(stuck_[i].timed_out_); - if (!stuck_[i].timed_out_) { - std::cout << "Stuck task #" << i << " timeout is at " - << stuck_[i].task_->timeout_time() << std::endl; - } - } - - std::cout.flush(); - } - - private: - struct TaskInfo { - IdTimeoutTask *task_; - bool timed_out_; - int xlat_; - }; - - MyTaskRunner task_runner_; - TaskInfo stuck_[STUCK_TASK_COUNT]; - TaskInfo happy_[HAPPY_TASK_COUNT]; -}; - -TEST(start_task_test, Timeout) { - TaskTest task_test; - task_test.Start(); - task_test.check_passed(); -} - -// Test for aborting the task while it is running - -class AbortTask : public Task { - public: - explicit AbortTask(TaskParent *parent) : Task(parent) { - set_timeout_seconds(1); - } - - virtual int ProcessStart() { - Abort(); - return STATE_NEXT; - } - private: - DISALLOW_EVIL_CONSTRUCTORS(AbortTask); -}; - -class TaskAbortTest : public sigslot::has_slots<> { - public: - TaskAbortTest() {} - - // no need to delete any tasks; the task runner owns them - ~TaskAbortTest() {} - - void Start() { - Task *abort_task = new AbortTask(&task_runner_); - abort_task->SignalTimeout.connect(this, &TaskAbortTest::OnTimeout); - abort_task->Start(); - - // run the task - task_runner_.RunTasks(); - } - - private: - void OnTimeout() { - FAIL() << "Task timed out instead of aborting."; - } - - MyTaskRunner task_runner_; - DISALLOW_EVIL_CONSTRUCTORS(TaskAbortTest); -}; - -TEST(start_task_test, Abort) { - TaskAbortTest abort_test; - abort_test.Start(); -} - -// Test for aborting a task to verify that it does the Wake operation -// which gets it deleted. - -class SetBoolOnDeleteTask : public Task { - public: - SetBoolOnDeleteTask(TaskParent *parent, bool *set_when_deleted) - : Task(parent), - set_when_deleted_(set_when_deleted) { - EXPECT_TRUE(NULL != set_when_deleted); - EXPECT_FALSE(*set_when_deleted); - } - - virtual ~SetBoolOnDeleteTask() { - *set_when_deleted_ = true; - } - - virtual int ProcessStart() { - return STATE_BLOCKED; - } - - private: - bool* set_when_deleted_; - DISALLOW_EVIL_CONSTRUCTORS(SetBoolOnDeleteTask); -}; - -class AbortShouldWakeTest : public sigslot::has_slots<> { - public: - AbortShouldWakeTest() {} - - // no need to delete any tasks; the task runner owns them - ~AbortShouldWakeTest() {} - - void Start() { - bool task_deleted = false; - Task *task_to_abort = new SetBoolOnDeleteTask(&task_runner_, &task_deleted); - task_to_abort->Start(); - - // Task::Abort() should call TaskRunner::WakeTasks(). WakeTasks calls - // TaskRunner::RunTasks() immediately which should delete the task. - task_to_abort->Abort(); - EXPECT_TRUE(task_deleted); - - if (!task_deleted) { - // avoid a crash (due to referencing a local variable) - // if the test fails. - task_runner_.RunTasks(); - } - } - - private: - void OnTimeout() { - FAIL() << "Task timed out instead of aborting."; - } - - MyTaskRunner task_runner_; - DISALLOW_EVIL_CONSTRUCTORS(AbortShouldWakeTest); -}; - -TEST(start_task_test, AbortShouldWake) { - AbortShouldWakeTest abort_should_wake_test; - abort_should_wake_test.Start(); -} - -// Validate that TaskRunner's OnTimeoutChange gets called appropriately -// * When a task calls UpdateTaskTimeout -// * When the next timeout task time, times out -class TimeoutChangeTest : public sigslot::has_slots<> { - public: - TimeoutChangeTest() - : task_count_(ARRAY_SIZE(stuck_tasks_)) {} - - // no need to delete any tasks; the task runner owns them - ~TimeoutChangeTest() {} - - void Start() { - for (int i = 0; i < task_count_; ++i) { - stuck_tasks_[i] = new StuckTask(&task_runner_); - stuck_tasks_[i]->set_timeout_seconds(i + 2); - stuck_tasks_[i]->SignalTimeoutId.connect(this, - &TimeoutChangeTest::OnTimeoutId); - } - - for (int i = task_count_ - 1; i >= 0; --i) { - stuck_tasks_[i]->Start(); - } - task_runner_.clear_timeout_change(); - - // At this point, our timeouts are set as follows - // task[0] is 2 seconds, task[1] at 3 seconds, etc. - - stuck_tasks_[0]->set_timeout_seconds(2); - // Now, task[0] is 2 seconds, task[1] at 3 seconds... - // so timeout change shouldn't be called. - EXPECT_FALSE(task_runner_.timeout_change()); - task_runner_.clear_timeout_change(); - - stuck_tasks_[0]->set_timeout_seconds(1); - // task[0] is 1 seconds, task[1] at 3 seconds... - // The smallest timeout got smaller so timeout change be called. - EXPECT_TRUE(task_runner_.timeout_change()); - task_runner_.clear_timeout_change(); - - stuck_tasks_[1]->set_timeout_seconds(2); - // task[0] is 1 seconds, task[1] at 2 seconds... - // The smallest timeout is still 1 second so no timeout change. - EXPECT_FALSE(task_runner_.timeout_change()); - task_runner_.clear_timeout_change(); - - while (task_count_ > 0) { - int previous_count = task_count_; - task_runner_.PollTasks(); - if (previous_count != task_count_) { - // We only get here when a task times out. When that - // happens, the timeout change should get called because - // the smallest timeout is now in the past. - EXPECT_TRUE(task_runner_.timeout_change()); - task_runner_.clear_timeout_change(); - } - Thread::Current()->socketserver()->Wait(500, false); - } - } - - private: - void OnTimeoutId(const int id) { - for (int i = 0; i < ARRAY_SIZE(stuck_tasks_); ++i) { - if (stuck_tasks_[i] && stuck_tasks_[i]->unique_id() == id) { - task_count_--; - stuck_tasks_[i] = NULL; - break; - } - } - } - - MyTaskRunner task_runner_; - StuckTask* (stuck_tasks_[3]); - int task_count_; - DISALLOW_EVIL_CONSTRUCTORS(TimeoutChangeTest); -}; - -TEST(start_task_test, TimeoutChange) { - TimeoutChangeTest timeout_change_test; - timeout_change_test.Start(); -} - -class DeleteTestTaskRunner : public TaskRunner { - public: - DeleteTestTaskRunner() { - } - virtual void WakeTasks() { } - virtual int64 CurrentTime() { - return GetCurrentTime(); - } - private: - DISALLOW_EVIL_CONSTRUCTORS(DeleteTestTaskRunner); -}; - -TEST(unstarted_task_test, DeleteTask) { - // This test ensures that we don't - // crash if a task is deleted without running it. - DeleteTestTaskRunner task_runner; - HappyTask* happy_task = new HappyTask(&task_runner); - happy_task->Start(); - - // try deleting the task directly - HappyTask* child_happy_task = new HappyTask(happy_task); - delete child_happy_task; - - // run the unblocked tasks - task_runner.RunTasks(); -} - -TEST(unstarted_task_test, DoNotDeleteTask1) { - // This test ensures that we don't - // crash if a task runner is deleted without - // running a certain task. - DeleteTestTaskRunner task_runner; - HappyTask* happy_task = new HappyTask(&task_runner); - happy_task->Start(); - - HappyTask* child_happy_task = new HappyTask(happy_task); - child_happy_task->Start(); - - // Never run the tasks -} - -TEST(unstarted_task_test, DoNotDeleteTask2) { - // This test ensures that we don't - // crash if a taskrunner is delete with a - // task that has never been started. - DeleteTestTaskRunner task_runner; - HappyTask* happy_task = new HappyTask(&task_runner); - happy_task->Start(); - - // Do not start the task. - // Note: this leaks memory, so don't do this. - // Instead, always run your tasks or delete them. - new HappyTask(happy_task); - - // run the unblocked tasks - task_runner.RunTasks(); -} - -} // namespace rtc diff --git a/webrtc/base/taskparent.cc b/webrtc/base/taskparent.cc deleted file mode 100644 index edc146fd2..000000000 --- a/webrtc/base/taskparent.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/taskparent.h" - -#include "webrtc/base/task.h" -#include "webrtc/base/taskrunner.h" - -namespace rtc { - -TaskParent::TaskParent(Task* derived_instance, TaskParent *parent) - : parent_(parent) { - ASSERT(derived_instance != NULL); - ASSERT(parent != NULL); - runner_ = parent->GetRunner(); - parent_->AddChild(derived_instance); - Initialize(); -} - -TaskParent::TaskParent(TaskRunner *derived_instance) - : parent_(NULL), - runner_(derived_instance) { - ASSERT(derived_instance != NULL); - Initialize(); -} - -// Does common initialization of member variables -void TaskParent::Initialize() { - children_.reset(new ChildSet()); - child_error_ = false; -} - -void TaskParent::AddChild(Task *child) { - children_->insert(child); -} - -#ifdef _DEBUG -bool TaskParent::IsChildTask(Task *task) { - ASSERT(task != NULL); - return task->parent_ == this && children_->find(task) != children_->end(); -} -#endif - -bool TaskParent::AllChildrenDone() { - for (ChildSet::iterator it = children_->begin(); - it != children_->end(); - ++it) { - if (!(*it)->IsDone()) - return false; - } - return true; -} - -bool TaskParent::AnyChildError() { - return child_error_; -} - -void TaskParent::AbortAllChildren() { - if (children_->size() > 0) { -#ifdef _DEBUG - runner_->IncrementAbortCount(); -#endif - - ChildSet copy = *children_; - for (ChildSet::iterator it = copy.begin(); it != copy.end(); ++it) { - (*it)->Abort(true); // Note we do not wake - } - -#ifdef _DEBUG - runner_->DecrementAbortCount(); -#endif - } -} - -void TaskParent::OnStopped(Task *task) { - AbortAllChildren(); - parent_->OnChildStopped(task); -} - -void TaskParent::OnChildStopped(Task *child) { - if (child->HasError()) - child_error_ = true; - children_->erase(child); -} - -} // namespace rtc diff --git a/webrtc/base/taskparent.h b/webrtc/base/taskparent.h deleted file mode 100644 index a3832024e..000000000 --- a/webrtc/base/taskparent.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TASKPARENT_H__ -#define WEBRTC_BASE_TASKPARENT_H__ - -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/scoped_ptr.h" - -namespace rtc { - -class Task; -class TaskRunner; - -class TaskParent { - public: - TaskParent(Task *derived_instance, TaskParent *parent); - explicit TaskParent(TaskRunner *derived_instance); - virtual ~TaskParent() { } - - TaskParent *GetParent() { return parent_; } - TaskRunner *GetRunner() { return runner_; } - - bool AllChildrenDone(); - bool AnyChildError(); -#ifdef _DEBUG - bool IsChildTask(Task *task); -#endif - - protected: - void OnStopped(Task *task); - void AbortAllChildren(); - TaskParent *parent() { - return parent_; - } - - private: - void Initialize(); - void OnChildStopped(Task *child); - void AddChild(Task *child); - - TaskParent *parent_; - TaskRunner *runner_; - bool child_error_; - typedef std::set ChildSet; - scoped_ptr children_; - DISALLOW_EVIL_CONSTRUCTORS(TaskParent); -}; - - -} // namespace rtc - -#endif // WEBRTC_BASE_TASKPARENT_H__ diff --git a/webrtc/base/taskrunner.cc b/webrtc/base/taskrunner.cc deleted file mode 100644 index bc4ab5e44..000000000 --- a/webrtc/base/taskrunner.cc +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/taskrunner.h" - -#include "webrtc/base/common.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/task.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -TaskRunner::TaskRunner() - : TaskParent(this), - next_timeout_task_(NULL), - tasks_running_(false) -#ifdef _DEBUG - , abort_count_(0), - deleting_task_(NULL) -#endif -{ -} - -TaskRunner::~TaskRunner() { - // this kills and deletes children silently! - AbortAllChildren(); - InternalRunTasks(true); -} - -void TaskRunner::StartTask(Task * task) { - tasks_.push_back(task); - - // the task we just started could be about to timeout -- - // make sure our "next timeout task" is correct - UpdateTaskTimeout(task, 0); - - WakeTasks(); -} - -void TaskRunner::RunTasks() { - InternalRunTasks(false); -} - -void TaskRunner::InternalRunTasks(bool in_destructor) { - // This shouldn't run while an abort is happening. - // If that occurs, then tasks may be deleted in this method, - // but pointers to them will still be in the - // "ChildSet copy" in TaskParent::AbortAllChildren. - // Subsequent use of those task may cause data corruption or crashes. - ASSERT(!abort_count_); - // Running continues until all tasks are Blocked (ok for a small # of tasks) - if (tasks_running_) { - return; // don't reenter - } - - tasks_running_ = true; - - int64 previous_timeout_time = next_task_timeout(); - - int did_run = true; - while (did_run) { - did_run = false; - // use indexing instead of iterators because tasks_ may grow - for (size_t i = 0; i < tasks_.size(); ++i) { - while (!tasks_[i]->Blocked()) { - tasks_[i]->Step(); - did_run = true; - } - } - } - // Tasks are deleted when running has paused - bool need_timeout_recalc = false; - for (size_t i = 0; i < tasks_.size(); ++i) { - if (tasks_[i]->IsDone()) { - Task* task = tasks_[i]; - if (next_timeout_task_ && - task->unique_id() == next_timeout_task_->unique_id()) { - next_timeout_task_ = NULL; - need_timeout_recalc = true; - } - -#ifdef _DEBUG - deleting_task_ = task; -#endif - delete task; -#ifdef _DEBUG - deleting_task_ = NULL; -#endif - tasks_[i] = NULL; - } - } - // Finally, remove nulls - std::vector::iterator it; - it = std::remove(tasks_.begin(), - tasks_.end(), - reinterpret_cast(NULL)); - - tasks_.erase(it, tasks_.end()); - - if (need_timeout_recalc) - RecalcNextTimeout(NULL); - - // Make sure that adjustments are done to account - // for any timeout changes (but don't call this - // while being destroyed since it calls a pure virtual function). - if (!in_destructor) - CheckForTimeoutChange(previous_timeout_time); - - tasks_running_ = false; -} - -void TaskRunner::PollTasks() { - // see if our "next potentially timed-out task" has indeed timed out. - // If it has, wake it up, then queue up the next task in line - // Repeat while we have new timed-out tasks. - // TODO: We need to guard against WakeTasks not updating - // next_timeout_task_. Maybe also add documentation in the header file once - // we understand this code better. - Task* old_timeout_task = NULL; - while (next_timeout_task_ && - old_timeout_task != next_timeout_task_ && - next_timeout_task_->TimedOut()) { - old_timeout_task = next_timeout_task_; - next_timeout_task_->Wake(); - WakeTasks(); - } -} - -int64 TaskRunner::next_task_timeout() const { - if (next_timeout_task_) { - return next_timeout_task_->timeout_time(); - } - return 0; -} - -// this function gets called frequently -- when each task changes -// state to something other than DONE, ERROR or BLOCKED, it calls -// ResetTimeout(), which will call this function to make sure that -// the next timeout-able task hasn't changed. The logic in this function -// prevents RecalcNextTimeout() from getting called in most cases, -// effectively making the task scheduler O-1 instead of O-N - -void TaskRunner::UpdateTaskTimeout(Task* task, - int64 previous_task_timeout_time) { - ASSERT(task != NULL); - int64 previous_timeout_time = next_task_timeout(); - bool task_is_timeout_task = next_timeout_task_ != NULL && - task->unique_id() == next_timeout_task_->unique_id(); - if (task_is_timeout_task) { - previous_timeout_time = previous_task_timeout_time; - } - - // if the relevant task has a timeout, then - // check to see if it's closer than the current - // "about to timeout" task - if (task->timeout_time()) { - if (next_timeout_task_ == NULL || - (task->timeout_time() <= next_timeout_task_->timeout_time())) { - next_timeout_task_ = task; - } - } else if (task_is_timeout_task) { - // otherwise, if the task doesn't have a timeout, - // and it used to be our "about to timeout" task, - // walk through all the tasks looking for the real - // "about to timeout" task - RecalcNextTimeout(task); - } - - // Note when task_running_, then the running routine - // (TaskRunner::InternalRunTasks) is responsible for calling - // CheckForTimeoutChange. - if (!tasks_running_) { - CheckForTimeoutChange(previous_timeout_time); - } -} - -void TaskRunner::RecalcNextTimeout(Task *exclude_task) { - // walk through all the tasks looking for the one - // which satisfies the following: - // it's not finished already - // we're not excluding it - // it has the closest timeout time - - int64 next_timeout_time = 0; - next_timeout_task_ = NULL; - - for (size_t i = 0; i < tasks_.size(); ++i) { - Task *task = tasks_[i]; - // if the task isn't complete, and it actually has a timeout time - if (!task->IsDone() && (task->timeout_time() > 0)) - // if it doesn't match our "exclude" task - if (exclude_task == NULL || - exclude_task->unique_id() != task->unique_id()) - // if its timeout time is sooner than our current timeout time - if (next_timeout_time == 0 || - task->timeout_time() <= next_timeout_time) { - // set this task as our next-to-timeout - next_timeout_time = task->timeout_time(); - next_timeout_task_ = task; - } - } -} - -void TaskRunner::CheckForTimeoutChange(int64 previous_timeout_time) { - int64 next_timeout = next_task_timeout(); - bool timeout_change = (previous_timeout_time == 0 && next_timeout != 0) || - next_timeout < previous_timeout_time || - (previous_timeout_time <= CurrentTime() && - previous_timeout_time != next_timeout); - if (timeout_change) { - OnTimeoutChange(); - } -} - -} // namespace rtc diff --git a/webrtc/base/taskrunner.h b/webrtc/base/taskrunner.h deleted file mode 100644 index 629c2d3ac..000000000 --- a/webrtc/base/taskrunner.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TASKRUNNER_H__ -#define WEBRTC_BASE_TASKRUNNER_H__ - -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/taskparent.h" - -namespace rtc { -class Task; - -const int64 kSecToMsec = 1000; -const int64 kMsecTo100ns = 10000; -const int64 kSecTo100ns = kSecToMsec * kMsecTo100ns; - -class TaskRunner : public TaskParent, public sigslot::has_slots<> { - public: - TaskRunner(); - virtual ~TaskRunner(); - - virtual void WakeTasks() = 0; - - // Returns the current time in 100ns units. It is used for - // determining timeouts. The origin is not important, only - // the units and that rollover while the computer is running. - // - // On Windows, GetSystemTimeAsFileTime is the typical implementation. - virtual int64 CurrentTime() = 0 ; - - void StartTask(Task *task); - void RunTasks(); - void PollTasks(); - - void UpdateTaskTimeout(Task *task, int64 previous_task_timeout_time); - -#ifdef _DEBUG - bool is_ok_to_delete(Task* task) { - return task == deleting_task_; - } - - void IncrementAbortCount() { - ++abort_count_; - } - - void DecrementAbortCount() { - --abort_count_; - } -#endif - - // Returns the next absolute time when a task times out - // OR "0" if there is no next timeout. - int64 next_task_timeout() const; - - protected: - // The primary usage of this method is to know if - // a callback timer needs to be set-up or adjusted. - // This method will be called - // * when the next_task_timeout() becomes a smaller value OR - // * when next_task_timeout() has changed values and the previous - // value is in the past. - // - // If the next_task_timeout moves to the future, this method will *not* - // get called (because it subclass should check next_task_timeout() - // when its timer goes off up to see if it needs to set-up a new timer). - // - // Note that this maybe called conservatively. In that it may be - // called when no time change has happened. - virtual void OnTimeoutChange() { - // by default, do nothing. - } - - private: - void InternalRunTasks(bool in_destructor); - void CheckForTimeoutChange(int64 previous_timeout_time); - - std::vector tasks_; - Task *next_timeout_task_; - bool tasks_running_; -#ifdef _DEBUG - int abort_count_; - Task* deleting_task_; -#endif - - void RecalcNextTimeout(Task *exclude_task); -}; - -} // namespace rtc - -#endif // TASK_BASE_TASKRUNNER_H__ diff --git a/webrtc/base/template_util.h b/webrtc/base/template_util.h deleted file mode 100644 index f0bf39c5f..000000000 --- a/webrtc/base/template_util.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TEMPLATE_UTIL_H_ -#define WEBRTC_BASE_TEMPLATE_UTIL_H_ - -#include // For size_t. - -namespace rtc { - -// template definitions from tr1 - -template -struct integral_constant { - static const T value = v; - typedef T value_type; - typedef integral_constant type; -}; - -template const T integral_constant::value; - -typedef integral_constant true_type; -typedef integral_constant false_type; - -template struct is_pointer : false_type {}; -template struct is_pointer : true_type {}; - -template struct is_same : public false_type {}; -template struct is_same : true_type {}; - -template struct is_array : public false_type {}; -template struct is_array : public true_type {}; -template struct is_array : public true_type {}; - -template struct is_non_const_reference : false_type {}; -template struct is_non_const_reference : true_type {}; -template struct is_non_const_reference : false_type {}; - -template struct is_void : false_type {}; -template <> struct is_void : true_type {}; - -namespace internal { - -// Types YesType and NoType are guaranteed such that sizeof(YesType) < -// sizeof(NoType). -typedef char YesType; - -struct NoType { - YesType dummy[2]; -}; - -// This class is an implementation detail for is_convertible, and you -// don't need to know how it works to use is_convertible. For those -// who care: we declare two different functions, one whose argument is -// of type To and one with a variadic argument list. We give them -// return types of different size, so we can use sizeof to trick the -// compiler into telling us which function it would have chosen if we -// had called it with an argument of type From. See Alexandrescu's -// _Modern C++ Design_ for more details on this sort of trick. - -struct ConvertHelper { - template - static YesType Test(To); - - template - static NoType Test(...); - - template - static From& Create(); -}; - -// Used to determine if a type is a struct/union/class. Inspired by Boost's -// is_class type_trait implementation. -struct IsClassHelper { - template - static YesType Test(void(C::*)(void)); - - template - static NoType Test(...); -}; - -} // namespace internal - -// Inherits from true_type if From is convertible to To, false_type otherwise. -// -// Note that if the type is convertible, this will be a true_type REGARDLESS -// of whether or not the conversion would emit a warning. -template -struct is_convertible - : integral_constant( - internal::ConvertHelper::Create())) == - sizeof(internal::YesType)> { -}; - -template -struct is_class - : integral_constant(0)) == - sizeof(internal::YesType)> { -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_TEMPLATE_UTIL_H_ diff --git a/webrtc/base/testbase64.h b/webrtc/base/testbase64.h deleted file mode 100644 index 39dd00ce3..000000000 --- a/webrtc/base/testbase64.h +++ /dev/null @@ -1,5 +0,0 @@ -/* This file was generated by googleclient/talk/binary2header.sh */ - -static unsigned char testbase64[] = { -0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xe1, 0x0d, 0x07, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x01, 0x0e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x9e, 0x01, 0x0f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xbe, 0x01, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xc3, 0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcc, 0x01, 0x1b, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd4, 0x01, 0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x31, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xdc, 0x01, 0x32, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x3c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x04, 0x02, 0x13, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x02, 0xc4, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x53, 0x4f, 0x4e, 0x59, 0x00, 0x44, 0x53, 0x43, 0x2d, 0x50, 0x32, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20, 0x37, 0x2e, 0x30, 0x00, 0x32, 0x30, 0x30, 0x37, 0x3a, 0x30, 0x31, 0x3a, 0x33, 0x30, 0x20, 0x32, 0x33, 0x3a, 0x31, 0x30, 0x3a, 0x30, 0x34, 0x00, 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58, 0x20, 0x31, 0x30, 0x2e, 0x34, 0x2e, 0x38, 0x00, 0x00, 0x1c, 0x82, 0x9a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x6a, 0x82, 0x9d, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x72, 0x88, 0x22, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x88, 0x27, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x64, 0x00, 0x00, 0x90, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x32, 0x32, 0x30, 0x90, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x02, 0x7a, 0x90, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x02, 0x8e, 0x91, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x00, 0x91, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xa2, 0x92, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xaa, 0x92, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xb2, 0x92, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x92, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x92, 0x09, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x92, 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xba, 0xa0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x31, 0x30, 0x30, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0xa3, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0xa3, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x09, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0a, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0a, 0x32, 0x30, 0x30, 0x37, 0x3a, 0x30, 0x31, 0x3a, 0x32, 0x30, 0x20, 0x32, 0x33, 0x3a, 0x30, 0x35, 0x3a, 0x35, 0x32, 0x00, 0x32, 0x30, 0x30, 0x37, 0x3a, 0x30, 0x31, 0x3a, 0x32, 0x30, 0x20, 0x32, 0x33, 0x3a, 0x30, 0x35, 0x3a, 0x35, 0x32, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x12, 0x01, 0x1b, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x1a, 0x01, 0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x22, 0x02, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xed, 0x00, 0x0c, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x5f, 0x43, 0x4d, 0x00, 0x02, 0xff, 0xee, 0x00, 0x0e, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x00, 0x64, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0c, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0c, 0x09, 0x09, 0x0c, 0x11, 0x0b, 0x0a, 0x0b, 0x11, 0x15, 0x0f, 0x0c, 0x0c, 0x0f, 0x15, 0x18, 0x13, 0x13, 0x15, 0x13, 0x13, 0x18, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x01, 0x0d, 0x0b, 0x0b, 0x0d, 0x0e, 0x0d, 0x10, 0x0e, 0x0e, 0x10, 0x14, 0x0e, 0x0e, 0x0e, 0x14, 0x14, 0x0e, 0x0e, 0x0e, 0x0e, 0x14, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x64, 0x00, 0x64, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xdd, 0x00, 0x04, 0x00, 0x07, 0xff, 0xc4, 0x01, 0x3f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x01, 0x04, 0x01, 0x03, 0x02, 0x04, 0x02, 0x05, 0x07, 0x06, 0x08, 0x05, 0x03, 0x0c, 0x33, 0x01, 0x00, 0x02, 0x11, 0x03, 0x04, 0x21, 0x12, 0x31, 0x05, 0x41, 0x51, 0x61, 0x13, 0x22, 0x71, 0x81, 0x32, 0x06, 0x14, 0x91, 0xa1, 0xb1, 0x42, 0x23, 0x24, 0x15, 0x52, 0xc1, 0x62, 0x33, 0x34, 0x72, 0x82, 0xd1, 0x43, 0x07, 0x25, 0x92, 0x53, 0xf0, 0xe1, 0xf1, 0x63, 0x73, 0x35, 0x16, 0xa2, 0xb2, 0x83, 0x26, 0x44, 0x93, 0x54, 0x64, 0x45, 0xc2, 0xa3, 0x74, 0x36, 0x17, 0xd2, 0x55, 0xe2, 0x65, 0xf2, 0xb3, 0x84, 0xc3, 0xd3, 0x75, 0xe3, 0xf3, 0x46, 0x27, 0x94, 0xa4, 0x85, 0xb4, 0x95, 0xc4, 0xd4, 0xe4, 0xf4, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5, 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7, 0x11, 0x00, 0x02, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x06, 0x05, 0x35, 0x01, 0x00, 0x02, 0x11, 0x03, 0x21, 0x31, 0x12, 0x04, 0x41, 0x51, 0x61, 0x71, 0x22, 0x13, 0x05, 0x32, 0x81, 0x91, 0x14, 0xa1, 0xb1, 0x42, 0x23, 0xc1, 0x52, 0xd1, 0xf0, 0x33, 0x24, 0x62, 0xe1, 0x72, 0x82, 0x92, 0x43, 0x53, 0x15, 0x63, 0x73, 0x34, 0xf1, 0x25, 0x06, 0x16, 0xa2, 0xb2, 0x83, 0x07, 0x26, 0x35, 0xc2, 0xd2, 0x44, 0x93, 0x54, 0xa3, 0x17, 0x64, 0x45, 0x55, 0x36, 0x74, 0x65, 0xe2, 0xf2, 0xb3, 0x84, 0xc3, 0xd3, 0x75, 0xe3, 0xf3, 0x46, 0x94, 0xa4, 0x85, 0xb4, 0x95, 0xc4, 0xd4, 0xe4, 0xf4, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5, 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xf2, 0xed, 0xb2, 0x8d, 0x4d, 0x45, 0xcd, 0x2f, 0x3f, 0x44, 0x68, 0x93, 0xc3, 0x58, 0xc8, 0xf1, 0x1f, 0x8a, 0x33, 0x86, 0xda, 0x58, 0xc1, 0xa0, 0x02, 0x4f, 0xc4, 0xa1, 0x69, 0xa5, 0x9b, 0x5b, 0x4b, 0x84, 0x73, 0xdf, 0xc9, 0x15, 0xf8, 0xe3, 0xd1, 0x0e, 0x07, 0x93, 0xf3, 0xd1, 0x0f, 0x1c, 0x17, 0xef, 0x2e, 0x3b, 0x5b, 0xdc, 0xff, 0x00, 0xdf, 0x42, 0xbf, 0x8f, 0x8e, 0xdc, 0x82, 0xca, 0xd8, 0x37, 0x11, 0xa9, 0x3d, 0x82, 0x69, 0x2b, 0xc4, 0x6d, 0xc9, 0x75, 0x25, 0xbc, 0xf7, 0xec, 0xa1, 0xb5, 0x74, 0x19, 0x5d, 0x2e, 0x8a, 0x9a, 0x4b, 0x89, 0x7d, 0xc4, 0x68, 0xc6, 0xf6, 0xfe, 0xb2, 0xa0, 0x30, 0x1d, 0x60, 0x86, 0x88, 0x8d, 0x49, 0x3e, 0x01, 0x11, 0x20, 0xa3, 0x8c, 0xb9, 0xb1, 0xaa, 0x62, 0xad, 0xbf, 0x18, 0x97, 0x43, 0x47, 0x1d, 0xd2, 0xaf, 0x04, 0xd9, 0xb8, 0xc8, 0x0d, 0x68, 0xe4, 0xf7, 0x3e, 0x48, 0xf1, 0x05, 0xbc, 0x25, 0xaa, 0x07, 0x71, 0xd9, 0x14, 0x78, 0xf6, 0x49, 0xb5, 0x90, 0xfd, 0xa7, 0xc6, 0x14, 0xfd, 0x1b, 0x1c, 0xff, 0x00, 0x4d, 0x8d, 0x2e, 0x73, 0x8c, 0x35, 0xa3, 0x52, 0x4f, 0x92, 0x48, 0xa6, 0x1a, 0x24, 0xb6, 0x2a, 0xfa, 0xa5, 0x9e, 0x60, 0x64, 0x39, 0x94, 0x13, 0xcb, 0x27, 0x73, 0x80, 0xf3, 0x0c, 0xf6, 0xff, 0x00, 0xd2, 0x5a, 0x78, 0xbf, 0x53, 0x71, 0xf6, 0x01, 0x75, 0xb6, 0x97, 0x6a, 0x25, 0xa1, 0xad, 0x1f, 0xf4, 0xb7, 0x23, 0x48, 0xb7, 0x94, 0x84, 0x97, 0x5b, 0xff, 0x00, 0x32, 0xa9, 0xdd, 0xfc, 0xed, 0x9b, 0x7e, 0x0d, 0x9e, 0x52, 0x4a, 0x95, 0x61, 0xff, 0xd0, 0xf3, 0x3b, 0xa7, 0x70, 0xee, 0x01, 0x8f, 0xb9, 0x59, 0xfa, 0x7e, 0xdf, 0xe4, 0xc8, 0xf9, 0x2a, 0xc2, 0x5c, 0x63, 0xc3, 0x54, 0x67, 0x87, 0x6e, 0x10, 0x35, 0x68, 0xd4, 0x79, 0x1e, 0x53, 0x4a, 0xe0, 0xdc, 0xe9, 0xb8, 0x1f, 0x6a, 0xda, 0x6c, 0x25, 0x94, 0x37, 0xb0, 0xd0, 0xb8, 0xad, 0x67, 0xe4, 0x55, 0x8a, 0x5b, 0x8b, 0x82, 0xc0, 0x6f, 0x76, 0x80, 0x34, 0x49, 0x05, 0x2e, 0x9e, 0xc6, 0x1c, 0x66, 0x31, 0xba, 0x10, 0x23, 0xe0, 0xaf, 0xe1, 0x61, 0x53, 0x43, 0x8d, 0x81, 0xb3, 0x67, 0xef, 0x9e, 0x49, 0x2a, 0x12, 0x6c, 0xb6, 0x63, 0x1a, 0x0c, 0x31, 0xba, 0x55, 0xcd, 0xac, 0xfa, 0x8e, 0xdf, 0x91, 0x6e, 0x91, 0xd9, 0xb3, 0xc9, 0x73, 0x90, 0x7a, 0xab, 0x6a, 0xc2, 0xa4, 0x60, 0xe2, 0x8f, 0xd2, 0x38, 0x03, 0x7d, 0x9e, 0x0d, 0xff, 0x00, 0xcc, 0xd6, 0xd3, 0x6b, 0x71, 0x67, 0xd2, 0x3e, 0x64, 0x72, 0xab, 0xdb, 0x8d, 0x54, 0x39, 0xc5, 0x83, 0x6b, 0x3d, 0xee, 0x2e, 0xd4, 0x92, 0x3c, 0x4a, 0x56, 0xba, 0xb4, 0x79, 0x5c, 0xf7, 0xb2, 0x96, 0x6c, 0x8d, 0xaf, 0x80, 0x48, 0x3c, 0xf0, 0xb2, 0x1f, 0x63, 0x9c, 0xe9, 0x3f, 0x24, 0x5c, 0xdb, 0xdd, 0x76, 0x43, 0xde, 0xfd, 0x5c, 0xe3, 0x24, 0xfc, 0x50, 0x00, 0x93, 0x0a, 0x78, 0x8a, 0x0d, 0x49, 0xca, 0xcf, 0x93, 0x63, 0x1b, 0x7d, 0xd7, 0x57, 0x50, 0xd5, 0xef, 0x70, 0x6b, 0x4f, 0xc7, 0x45, 0xdb, 0x74, 0x9e, 0x8d, 0x5e, 0x33, 0x83, 0xd8, 0x37, 0xdd, 0xc3, 0xac, 0x3d, 0xbf, 0x92, 0xc5, 0x5b, 0xea, 0xbf, 0xd5, 0x62, 0xc0, 0xdc, 0xbc, 0xbd, 0x2d, 0x22, 0x5a, 0xcf, 0xdd, 0x69, 0xff, 0x00, 0xd1, 0x8e, 0x5d, 0xa5, 0x38, 0xb5, 0xb0, 0x00, 0xc6, 0xc4, 0x24, 0x4a, 0xd6, 0x8d, 0x18, 0x04, 0x49, 0x88, 0x9e, 0x55, 0xd6, 0x61, 0xb0, 0xc1, 0x70, 0x32, 0xdd, 0x3c, 0x95, 0xda, 0xf1, 0xfe, 0xf5, 0x62, 0xbc, 0x76, 0x8e, 0x75, 0x28, 0x02, 0xa2, 0xe7, 0x7d, 0x92, 0xb9, 0x84, 0x96, 0x96, 0xda, 0xf7, 0x70, 0x12, 0x4e, 0x5a, 0xff, 0x00, 0xff, 0xd1, 0xf3, 0x7a, 0x21, 0xaf, 0xde, 0xef, 0xa2, 0x22, 0x55, 0xfc, 0x5a, 0xbd, 0x42, 0xfb, 0x08, 0xfa, 0x67, 0x4f, 0x82, 0xcd, 0x6d, 0x85, 0xc0, 0x56, 0x3b, 0x90, 0xb7, 0xf0, 0x2a, 0x0e, 0x63, 0x58, 0x3b, 0xf2, 0xa3, 0x9e, 0x8c, 0xb8, 0x86, 0xbe, 0x49, 0xf1, 0x2c, 0x0c, 0x86, 0xb4, 0x4c, 0x69, 0xe4, 0xaf, 0x6e, 0xcc, 0x6b, 0x7d, 0x46, 0xb3, 0x70, 0xec, 0x38, 0x51, 0x7d, 0x02, 0x8a, 0xc7, 0xa6, 0xd9, 0x20, 0x68, 0x0f, 0x8f, 0x8a, 0xcf, 0xc9, 0xc2, 0xea, 0x59, 0x5b, 0x48, 0xb0, 0x91, 0xae, 0xe6, 0xc9, 0x03, 0xc9, 0x30, 0x51, 0x66, 0xd4, 0x0d, 0xad, 0xbd, 0x5f, 0x53, 0xcc, 0x6b, 0xb6, 0x90, 0x5a, 0x3b, 0x83, 0x0b, 0x43, 0x17, 0x31, 0xd6, 0xc3, 0x6e, 0x12, 0x3b, 0x79, 0xac, 0xc1, 0x89, 0x47, 0xd9, 0xe8, 0x63, 0x98, 0x45, 0xed, 0x6c, 0x5a, 0xf1, 0xa0, 0x27, 0xc5, 0x5b, 0xc3, 0x6f, 0xa6, 0xe0, 0x1c, 0x7d, 0xb3, 0xa2, 0x69, 0x34, 0x7b, 0xae, 0x1a, 0x8d, 0x45, 0x17, 0x9d, 0xeb, 0xfd, 0x21, 0xd8, 0xb9, 0xae, 0xb5, 0x80, 0xbb, 0x1e, 0xd2, 0x5c, 0xd7, 0x78, 0x13, 0xf9, 0xae, 0x4b, 0xea, 0xc7, 0x4a, 0x39, 0xbd, 0x55, 0xb3, 0xed, 0x66, 0x38, 0xf5, 0x09, 0x22, 0x41, 0x23, 0xe8, 0x37, 0xfb, 0x4b, 0xa1, 0xeb, 0xd6, 0xfe, 0x88, 0x31, 0xbf, 0x41, 0xc0, 0xee, 0xd2, 0x74, 0x02, 0x78, 0x53, 0xfa, 0x97, 0x43, 0x19, 0x85, 0x65, 0xff, 0x00, 0x9d, 0x71, 0x33, 0xe4, 0x1a, 0x7d, 0x8d, 0x53, 0x42, 0x56, 0x35, 0x6b, 0xe5, 0x80, 0x06, 0xc7, 0x57, 0xa7, 0xc4, 0xa9, 0xdb, 0xb6, 0x81, 0x1f, 0xeb, 0xd9, 0x69, 0x56, 0xc2, 0xd0, 0x00, 0xe5, 0x55, 0xc0, 0x12, 0xc2, 0xd7, 0x4e, 0xa2, 0x5a, 0x7c, 0x0a, 0xd0, 0x63, 0x9a, 0xd1, 0xaf, 0xd2, 0xe2, 0x3c, 0x12, 0x62, 0x66, 0xc6, 0x42, 0x23, 0x5a, 0x49, 0x8f, 0x10, 0xa2, 0xd2, 0x3e, 0x28, 0x9d, 0xc4, 0x88, 0x09, 0x29, 0x16, 0xc3, 0x3c, 0x24, 0x8d, 0xe6, 0x92, 0x72, 0x1f, 0xff, 0xd2, 0xf3, 0xbb, 0xb0, 0xfe, 0xcb, 0x99, 0xe9, 0xce, 0xf6, 0x88, 0x2d, 0x77, 0x91, 0x5b, 0x3d, 0x3d, 0xd0, 0xe6, 0x90, 0xa9, 0x65, 0x57, 0x38, 0x95, 0xdd, 0xcb, 0x9a, 0x7d, 0xce, 0xf2, 0x3f, 0x44, 0x23, 0x60, 0x58, 0x76, 0xe9, 0xca, 0x8c, 0xea, 0x1b, 0x31, 0x02, 0x32, 0x23, 0xea, 0xee, 0xb1, 0xcd, 0xb0, 0xc7, 0x87, 0x74, 0x7a, 0xeb, 0x70, 0x1a, 0x71, 0xe1, 0xfe, 0xe4, 0x1c, 0x1d, 0xae, 0xe5, 0x69, 0xd8, 0xfa, 0x99, 0x50, 0x0d, 0x1a, 0xf7, 0x2a, 0x3a, 0x0c, 0xf4, 0x1a, 0x8e, 0xc7, 0x27, 0x5d, 0xbf, 0x18, 0x41, 0xdc, 0xc2, 0xf0, 0x7f, 0x74, 0xf6, 0x3a, 0x22, 0x66, 0xdb, 0x68, 0xc6, 0x80, 0x48, 0x6b, 0x88, 0x06, 0x39, 0x0d, 0xee, 0xaa, 0x1f, 0xb3, 0xd5, 0x1b, 0x83, 0xd8, 0x3b, 0x38, 0x8f, 0x69, 0xfe, 0xdf, 0xd1, 0x4d, 0x29, 0xa1, 0x4c, 0x7a, 0xf4, 0xbf, 0xa7, 0x92, 0xcf, 0xa5, 0x20, 0x08, 0xf3, 0xf6, 0xff, 0x00, 0x15, 0xbb, 0xd1, 0x31, 0xd9, 0x5e, 0x3d, 0x75, 0x56, 0x36, 0x88, 0x00, 0x81, 0xe0, 0x16, 0x5e, 0x55, 0x74, 0x3f, 0x00, 0x9d, 0xe0, 0xcc, 0x69, 0xe7, 0x3a, 0x2d, 0xbe, 0x90, 0x00, 0xa9, 0xae, 0xef, 0x1f, 0x95, 0x4b, 0x0d, 0x9a, 0xdc, 0xc7, 0x45, 0xfe, 0xb1, 0x7d, 0x60, 0xa7, 0xa1, 0xe0, 0x1f, 0x4e, 0x1d, 0x99, 0x69, 0x02, 0x9a, 0xcf, 0x1f, 0xca, 0x7b, 0xbf, 0x90, 0xc5, 0xc2, 0xb3, 0xeb, 0x57, 0xd6, 0x03, 0x6b, 0xae, 0x39, 0xb6, 0x82, 0xe3, 0x31, 0xa1, 0x68, 0xf2, 0x6b, 0x5c, 0x12, 0xfa, 0xe1, 0x91, 0x66, 0x47, 0x5d, 0xb8, 0x3b, 0x4f, 0x44, 0x36, 0xb6, 0x8f, 0x28, 0xdd, 0xff, 0x00, 0x7e, 0x46, 0xab, 0x12, 0x2b, 0x65, 0x55, 0x32, 0xa7, 0x62, 0xb6, 0xbd, 0xf7, 0x64, 0x10, 0xdb, 0x03, 0x9f, 0x1b, 0x9e, 0xc7, 0xd9, 0xb8, 0x3b, 0x1f, 0x67, 0xf3, 0x6c, 0x52, 0x80, 0xd7, 0x7d, 0x0f, 0xea, 0x7f, 0x5d, 0x1d, 0x67, 0xa6, 0x0b, 0x1e, 0x47, 0xda, 0x69, 0x3b, 0x2e, 0x03, 0xc7, 0xf3, 0x5f, 0x1f, 0xf0, 0x8b, 0xa1, 0x02, 0x46, 0xba, 0x79, 0xaf, 0x32, 0xff, 0x00, 0x16, 0xad, 0xca, 0x1d, 0x57, 0x2a, 0xdc, 0x79, 0x18, 0x41, 0xb0, 0xf6, 0x9e, 0xe4, 0x9f, 0xd0, 0x8f, 0xeb, 0x31, 0xab, 0xd2, 0x83, 0xa4, 0xcb, 0x8c, 0xb8, 0xa0, 0x42, 0x12, 0x7b, 0x67, 0x9f, 0x2f, 0xf5, 0x09, 0x26, 0x96, 0xc4, 0xce, 0xa9, 0x20, 0xa7, 0xff, 0xd3, 0xf3, 0x2f, 0xb4, 0x5d, 0xe9, 0x0a, 0xb7, 0x9f, 0x4c, 0x19, 0xdb, 0x3a, 0x2d, 0x5e, 0x94, 0xfd, 0xc4, 0xb7, 0xc5, 0x62, 0xf9, 0x2b, 0xfd, 0x2e, 0xe3, 0x5d, 0xe0, 0x7c, 0x13, 0x48, 0xd1, 0x92, 0x12, 0xa9, 0x0b, 0x7a, 0xbc, 0x2d, 0xc2, 0x7f, 0x92, 0x60, 0xab, 0x4e, 0x79, 0x2e, 0x00, 0xf0, 0xaa, 0xe1, 0xda, 0x3d, 0x43, 0xfc, 0xad, 0x55, 0xbb, 0x80, 0x79, 0x81, 0xa0, 0xe6, 0x54, 0x32, 0x6d, 0x02, 0xbe, 0xf3, 0x61, 0x81, 0xa8, 0x44, 0x14, 0x03, 0x59, 0x0e, 0x1c, 0xf6, 0x1f, 0xdc, 0xb2, 0xec, 0xa3, 0x23, 0x77, 0xe8, 0x6e, 0x70, 0xf2, 0x25, 0x1f, 0x1f, 0x17, 0xa9, 0x6d, 0x71, 0x36, 0x97, 0x47, 0x00, 0xa4, 0x02, 0xe0, 0x2c, 0x7c, 0xc1, 0xab, 0xd5, 0x31, 0x85, 0x35, 0xd4, 0xe6, 0x13, 0x02, 0xd6, 0x4b, 0x67, 0x48, 0x2b, 0xa9, 0xe9, 0x2e, 0x02, 0xb6, 0x4f, 0x82, 0xe5, 0x7a, 0x95, 0x19, 0xc6, 0x87, 0x3d, 0xfb, 0xa2, 0xb8, 0x79, 0x1e, 0x4d, 0x3b, 0x96, 0xcf, 0x4f, 0xbd, 0xcd, 0xa2, 0xa2, 0x1f, 0xa0, 0x82, 0xd3, 0xfc, 0x97, 0x05, 0x24, 0x36, 0x6b, 0xf3, 0x31, 0xa2, 0x35, 0x79, 0xef, 0xad, 0xf8, 0xae, 0xaf, 0xaf, 0xd8, 0xf2, 0xd8, 0x6d, 0xed, 0x6b, 0xda, 0x7b, 0x18, 0x1b, 0x5d, 0xff, 0x00, 0x52, 0xb1, 0x6d, 0xf0, 0x81, 0x31, 0xca, 0xf4, 0x6e, 0xb1, 0x80, 0xce, 0xb1, 0x84, 0xc0, 0x21, 0xb7, 0xd6, 0x77, 0x31, 0xd1, 0x27, 0xc1, 0xcd, 0xfe, 0xd2, 0xe3, 0xec, 0xe8, 0x1d, 0x45, 0x96, 0xb0, 0x9a, 0xb7, 0x87, 0x3f, 0x68, 0x2d, 0xf7, 0x01, 0x1f, 0xbe, 0xd1, 0xf4, 0x7f, 0xb4, 0xa4, 0x0d, 0x77, 0xbb, 0xfa, 0x8f, 0x80, 0x3a, 0x7f, 0x43, 0xaa, 0xe2, 0xdf, 0xd2, 0x65, 0x7e, 0x95, 0xe4, 0x0f, 0x1f, 0xa1, 0xfe, 0x6b, 0x16, 0x9f, 0x52, 0xfa, 0xc1, 0xd3, 0xba, 0x6d, 0x26, 0xdc, 0xac, 0x86, 0xd4, 0xd9, 0x0d, 0x31, 0x2e, 0x74, 0x9e, 0xdb, 0x59, 0x2e, 0x55, 0xe8, 0xc9, 0xb2, 0x96, 0xd5, 0x4b, 0x9f, 0xb8, 0x6d, 0xda, 0x1c, 0x04, 0x09, 0x03, 0xfe, 0x8a, 0xc6, 0xfa, 0xd3, 0xf5, 0x6a, 0xbe, 0xbb, 0x5b, 0x2e, 0xc6, 0xb5, 0x94, 0xe6, 0xd5, 0x20, 0x97, 0x7d, 0x1b, 0x1b, 0xf9, 0xad, 0x7c, 0x7d, 0x17, 0xb7, 0xf3, 0x1e, 0x92, 0x1b, 0x7f, 0xf8, 0xe0, 0x7d, 0x59, 0xdd, 0xfd, 0x32, 0xd8, 0x8f, 0xa5, 0xe8, 0x3a, 0x12, 0x5c, 0x3f, 0xfc, 0xc4, 0xfa, 0xc3, 0xb3, 0x77, 0xa7, 0x56, 0xed, 0xdb, 0x76, 0x7a, 0x8d, 0xdd, 0x1f, 0xbf, 0xfd, 0x44, 0x92, 0x56, 0x8f, 0xff, 0xd4, 0xf2, 0xe8, 0x86, 0x17, 0x1e, 0xfa, 0x04, 0x56, 0x4b, 0x43, 0x6c, 0x6f, 0x2d, 0xe5, 0x46, 0x01, 0x64, 0x2b, 0x14, 0x32, 0x5b, 0xb4, 0xa0, 0x52, 0x1d, 0xde, 0x9b, 0x94, 0xdb, 0xab, 0x6b, 0x81, 0xf7, 0x05, 0xb0, 0xd7, 0x07, 0xb2, 0x27, 0x55, 0xc6, 0x57, 0x65, 0xd8, 0x76, 0x6e, 0x64, 0xed, 0xee, 0x16, 0xce, 0x27, 0x57, 0x63, 0xda, 0x0c, 0xc2, 0x8e, 0x51, 0x67, 0x84, 0xfa, 0x1d, 0xdd, 0x62, 0xc7, 0x07, 0xe9, 0xf7, 0xa3, 0xd6, 0x6c, 0x02, 0x41, 0x55, 0x31, 0xf3, 0x2b, 0xb3, 0xba, 0x2b, 0x2e, 0x68, 0x24, 0x1d, 0x47, 0x64, 0xca, 0xa6, 0x50, 0x41, 0x65, 0x90, 0x6c, 0xb1, 0xa5, 0xae, 0x33, 0x23, 0x51, 0xe4, 0xab, 0x7d, 0x5d, 0xcb, 0xb6, 0xcc, 0x37, 0xd0, 0x40, 0x73, 0x71, 0xde, 0x58, 0x09, 0xe7, 0x6f, 0x2c, 0x44, 0xc9, 0xc9, 0xae, 0xba, 0x9d, 0x63, 0x88, 0x01, 0xa0, 0x95, 0x9d, 0xf5, 0x3f, 0x2a, 0xe6, 0x67, 0xdb, 0x50, 0x83, 0x55, 0xad, 0x36, 0x3e, 0x78, 0x10, 0x74, 0x77, 0xfd, 0x2d, 0xaa, 0x4c, 0x7d, 0x58, 0x73, 0x91, 0xa0, 0x0f, 0x51, 0x45, 0xb7, 0x33, 0xdd, 0x58, 0x69, 0x1d, 0xd8, 0x0c, 0x9f, 0x96, 0x88, 0x19, 0x99, 0x19, 0xac, 0xcf, 0xa3, 0xd2, 0xad, 0xb5, 0xdb, 0x76, 0x8f, 0xad, 0xc4, 0xea, 0xcf, 0xdf, 0x7e, 0xdf, 0xdd, 0xfc, 0xd5, 0xa3, 0x5e, 0x43, 0x2b, 0x6b, 0xb2, 0xad, 0x3b, 0x6a, 0xa4, 0x13, 0xa7, 0x04, 0xac, 0x7a, 0x6f, 0xb3, 0x23, 0x26, 0xcc, 0xfb, 0xb4, 0x75, 0x8e, 0x01, 0x83, 0xf7, 0x58, 0x3e, 0x8b, 0x53, 0xa7, 0x2a, 0x1a, 0x31, 0x42, 0x36, 0x5d, 0x4c, 0x9a, 0xf2, 0xdc, 0xc6, 0xfe, 0x98, 0xb4, 0x34, 0xcb, 0x48, 0x0a, 0x8f, 0xdb, 0xb2, 0xeb, 0x76, 0xd6, 0x07, 0x5c, 0x59, 0xc9, 0x64, 0x8f, 0x93, 0xa7, 0x73, 0x16, 0x83, 0xaf, 0x0e, 0xa4, 0x33, 0xef, 0x50, 0xc5, 0x0c, 0xda, 0x59, 0x10, 0x06, 0x8a, 0x2e, 0x29, 0x0e, 0xac, 0xc2, 0x31, 0x3d, 0x36, 0x69, 0x7e, 0xd6, 0xcc, 0xf5, 0x3d, 0x6f, 0xb3, 0xeb, 0x1b, 0x76, 0xef, 0x3b, 0xa3, 0xfa, 0xc9, 0x2b, 0x5f, 0x66, 0x6f, 0xa9, 0x1e, 0x73, 0xf2, 0x49, 0x2e, 0x39, 0xf7, 0x4f, 0xb7, 0x8d, 0xff, 0xd5, 0xf3, 0x26, 0xfe, 0x0a, 0xc5, 0x1b, 0xa7, 0xcb, 0xb2, 0xcf, 0x49, 0x03, 0xb2, 0x46, 0xee, 0xd9, 0xd9, 0xb3, 0xf4, 0x9f, 0x25, 0x4a, 0xdf, 0x4b, 0x77, 0xe8, 0x27, 0xd4, 0xef, 0x1c, 0x2a, 0x29, 0x26, 0xc5, 0x7c, 0x9d, 0x6c, 0x7f, 0xb7, 0x6e, 0x1b, 0x26, 0x7f, 0x05, 0xa3, 0xfe, 0x53, 0x8d, 0x62, 0x57, 0x30, 0x92, 0x12, 0xfa, 0x2f, 0x86, 0xdf, 0xa4, 0xec, 0x67, 0xfe, 0xd0, 0xf4, 0xff, 0x00, 0x4d, 0xfc, 0xdf, 0x78, 0xe1, 0x68, 0x7d, 0x54, 0x99, 0xbf, 0x6f, 0xf3, 0xbe, 0xdf, 0x8e, 0xdd, 0x7f, 0xef, 0xeb, 0x97, 0x49, 0x3e, 0x3b, 0x7f, 0x06, 0x2c, 0x9f, 0x37, 0x5f, 0xf0, 0x9f, 0x4c, 0xeb, 0x7b, 0xbf, 0x67, 0x55, 0xe8, 0xff, 0x00, 0x31, 0xbc, 0x7a, 0x9e, 0x31, 0xdb, 0xfe, 0x92, 0xae, 0x37, 0x7a, 0x4d, 0xdb, 0xe2, 0x17, 0x9d, 0xa4, 0xa3, 0xc9, 0xba, 0xfc, 0x7b, 0x7d, 0x5f, 0x52, 0xa7, 0x7e, 0xd1, 0x28, 0xf8, 0xf3, 0xb0, 0xc7, 0x32, 0xbc, 0x99, 0x24, 0xc5, 0xe3, 0xab, 0xeb, 0x1f, 0xa4, 0xf5, 0xfc, 0xe1, 0x25, 0xe4, 0xe9, 0x24, 0x97, 0xff, 0xd9, 0xff, 0xed, 0x2e, 0x1c, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20, 0x33, 0x2e, 0x30, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x1c, 0x02, 0x00, 0x00, 0x02, 0x00, 0x02, 0x1c, 0x02, 0x78, 0x00, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xfb, 0x09, 0xa6, 0xbd, 0x07, 0x4c, 0x2a, 0x36, 0x9d, 0x8f, 0xe2, 0xcc, 0x57, 0xa9, 0xac, 0x85, 0x38, 0x42, 0x49, 0x4d, 0x03, 0xea, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xb0, 0x3c, 0x3f, 0x78, 0x6d, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20, 0x50, 0x4c, 0x49, 0x53, 0x54, 0x20, 0x31, 0x2e, 0x30, 0x2f, 0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x54, 0x44, 0x73, 0x2f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x2d, 0x31, 0x2e, 0x30, 0x2e, 0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a, 0x3c, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x48, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x48, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x2d, 0x33, 0x30, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x34, 0x31, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x30, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x31, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x2d, 0x33, 0x30, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x34, 0x31, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x30, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x53, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x53, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x31, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x2d, 0x33, 0x30, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x34, 0x31, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x30, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x56, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x56, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x2d, 0x33, 0x30, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x34, 0x31, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x30, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x56, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x56, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x31, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x2d, 0x33, 0x30, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x34, 0x31, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x30, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x73, 0x75, 0x62, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x70, 0x61, 0x70, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x30, 0x2e, 0x30, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x30, 0x2e, 0x30, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x37, 0x33, 0x34, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x35, 0x37, 0x36, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x2d, 0x33, 0x30, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x34, 0x31, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x30, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x61, 0x70, 0x65, 0x72, 0x52, 0x65, 0x63, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x50, 0x4d, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x61, 0x70, 0x65, 0x72, 0x52, 0x65, 0x63, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x2d, 0x31, 0x38, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x2d, 0x31, 0x38, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x37, 0x37, 0x34, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x35, 0x39, 0x34, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x2d, 0x33, 0x30, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x34, 0x31, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x30, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x4d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x6d, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x4d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x6e, 0x61, 0x2d, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x6d, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x54, 0x31, 0x37, 0x3a, 0x34, 0x39, 0x3a, 0x33, 0x36, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x31, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x4d, 0x55, 0x6e, 0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x6d, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x4d, 0x55, 0x6e, 0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x30, 0x2e, 0x30, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x30, 0x2e, 0x30, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x37, 0x33, 0x34, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x35, 0x37, 0x36, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x2d, 0x33, 0x30, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x34, 0x31, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x30, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x4d, 0x55, 0x6e, 0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x61, 0x70, 0x65, 0x72, 0x52, 0x65, 0x63, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x6d, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x4d, 0x55, 0x6e, 0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x61, 0x70, 0x65, 0x72, 0x52, 0x65, 0x63, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x2d, 0x31, 0x38, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x2d, 0x31, 0x38, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x37, 0x37, 0x34, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x35, 0x39, 0x34, 0x3c, 0x2f, 0x72, 0x65, 0x61, 0x6c, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x2d, 0x33, 0x30, 0x54, 0x32, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x34, 0x31, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x30, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x70, 0x64, 0x2e, 0x50, 0x4d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x6d, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x70, 0x64, 0x2e, 0x50, 0x4d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x55, 0x53, 0x20, 0x4c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x6d, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x44, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x30, 0x37, 0x2d, 0x30, 0x31, 0x54, 0x31, 0x37, 0x3a, 0x34, 0x39, 0x3a, 0x33, 0x36, 0x5a, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x31, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x3c, 0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x41, 0x50, 0x49, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x30, 0x30, 0x2e, 0x32, 0x30, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x63, 0x6b, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2f, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x41, 0x50, 0x49, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x30, 0x30, 0x2e, 0x32, 0x30, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x63, 0x6b, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2f, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e, 0x0a, 0x38, 0x42, 0x49, 0x4d, 0x03, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x02, 0xde, 0x02, 0x40, 0xff, 0xee, 0xff, 0xee, 0x03, 0x06, 0x02, 0x52, 0x03, 0x67, 0x05, 0x28, 0x03, 0xfc, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x02, 0xd8, 0x02, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01, 0x7f, 0xff, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x08, 0x00, 0x19, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x03, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x38, 0x42, 0x49, 0x4d, 0x03, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x42, 0x49, 0x4d, 0x03, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x2f, 0x66, 0x66, 0x00, 0x01, 0x00, 0x6c, 0x66, 0x66, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2f, 0x66, 0x66, 0x00, 0x01, 0x00, 0xa1, 0x99, 0x9a, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x42, 0x49, 0x4d, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe8, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x03, 0x45, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x08, 0x00, 0x44, 0x00, 0x53, 0x00, 0x43, 0x00, 0x30, 0x00, 0x32, 0x00, 0x33, 0x00, 0x32, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x75, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x4f, 0x62, 0x6a, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x63, 0x74, 0x31, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x54, 0x6f, 0x70, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x65, 0x66, 0x74, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x74, 0x6f, 0x6d, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x52, 0x67, 0x68, 0x74, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x06, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x73, 0x56, 0x6c, 0x4c, 0x73, 0x00, 0x00, 0x00, 0x01, 0x4f, 0x62, 0x6a, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x49, 0x44, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x00, 0x00, 0x00, 0x0c, 0x45, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x54, 0x79, 0x70, 0x65, 0x65, 0x6e, 0x75, 0x6d, 0x00, 0x00, 0x00, 0x0a, 0x45, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6d, 0x67, 0x20, 0x00, 0x00, 0x00, 0x06, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x4f, 0x62, 0x6a, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x63, 0x74, 0x31, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x54, 0x6f, 0x70, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x65, 0x66, 0x74, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x74, 0x6f, 0x6d, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x52, 0x67, 0x68, 0x74, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, 0x6c, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x75, 0x6c, 0x6c, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x73, 0x67, 0x65, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x61, 0x6c, 0x74, 0x54, 0x61, 0x67, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x63, 0x65, 0x6c, 0x6c, 0x54, 0x65, 0x78, 0x74, 0x49, 0x73, 0x48, 0x54, 0x4d, 0x4c, 0x62, 0x6f, 0x6f, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x54, 0x65, 0x78, 0x74, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x68, 0x6f, 0x72, 0x7a, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x00, 0x00, 0x00, 0x0f, 0x45, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x48, 0x6f, 0x72, 0x7a, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x09, 0x76, 0x65, 0x72, 0x74, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x00, 0x00, 0x00, 0x0f, 0x45, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x74, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x0b, 0x62, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x65, 0x6e, 0x75, 0x6d, 0x00, 0x00, 0x00, 0x11, 0x45, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x42, 0x47, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x09, 0x74, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x73, 0x65, 0x74, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x6c, 0x65, 0x66, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x65, 0x74, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x4f, 0x75, 0x74, 0x73, 0x65, 0x74, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x65, 0x74, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0x09, 0xdd, 0x00, 0x18, 0x00, 0x01, 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xed, 0x00, 0x0c, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x5f, 0x43, 0x4d, 0x00, 0x02, 0xff, 0xee, 0x00, 0x0e, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x00, 0x64, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0c, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0c, 0x09, 0x09, 0x0c, 0x11, 0x0b, 0x0a, 0x0b, 0x11, 0x15, 0x0f, 0x0c, 0x0c, 0x0f, 0x15, 0x18, 0x13, 0x13, 0x15, 0x13, 0x13, 0x18, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x01, 0x0d, 0x0b, 0x0b, 0x0d, 0x0e, 0x0d, 0x10, 0x0e, 0x0e, 0x10, 0x14, 0x0e, 0x0e, 0x0e, 0x14, 0x14, 0x0e, 0x0e, 0x0e, 0x0e, 0x14, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x64, 0x00, 0x64, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xdd, 0x00, 0x04, 0x00, 0x07, 0xff, 0xc4, 0x01, 0x3f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x01, 0x04, 0x01, 0x03, 0x02, 0x04, 0x02, 0x05, 0x07, 0x06, 0x08, 0x05, 0x03, 0x0c, 0x33, 0x01, 0x00, 0x02, 0x11, 0x03, 0x04, 0x21, 0x12, 0x31, 0x05, 0x41, 0x51, 0x61, 0x13, 0x22, 0x71, 0x81, 0x32, 0x06, 0x14, 0x91, 0xa1, 0xb1, 0x42, 0x23, 0x24, 0x15, 0x52, 0xc1, 0x62, 0x33, 0x34, 0x72, 0x82, 0xd1, 0x43, 0x07, 0x25, 0x92, 0x53, 0xf0, 0xe1, 0xf1, 0x63, 0x73, 0x35, 0x16, 0xa2, 0xb2, 0x83, 0x26, 0x44, 0x93, 0x54, 0x64, 0x45, 0xc2, 0xa3, 0x74, 0x36, 0x17, 0xd2, 0x55, 0xe2, 0x65, 0xf2, 0xb3, 0x84, 0xc3, 0xd3, 0x75, 0xe3, 0xf3, 0x46, 0x27, 0x94, 0xa4, 0x85, 0xb4, 0x95, 0xc4, 0xd4, 0xe4, 0xf4, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5, 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7, 0x11, 0x00, 0x02, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x06, 0x05, 0x35, 0x01, 0x00, 0x02, 0x11, 0x03, 0x21, 0x31, 0x12, 0x04, 0x41, 0x51, 0x61, 0x71, 0x22, 0x13, 0x05, 0x32, 0x81, 0x91, 0x14, 0xa1, 0xb1, 0x42, 0x23, 0xc1, 0x52, 0xd1, 0xf0, 0x33, 0x24, 0x62, 0xe1, 0x72, 0x82, 0x92, 0x43, 0x53, 0x15, 0x63, 0x73, 0x34, 0xf1, 0x25, 0x06, 0x16, 0xa2, 0xb2, 0x83, 0x07, 0x26, 0x35, 0xc2, 0xd2, 0x44, 0x93, 0x54, 0xa3, 0x17, 0x64, 0x45, 0x55, 0x36, 0x74, 0x65, 0xe2, 0xf2, 0xb3, 0x84, 0xc3, 0xd3, 0x75, 0xe3, 0xf3, 0x46, 0x94, 0xa4, 0x85, 0xb4, 0x95, 0xc4, 0xd4, 0xe4, 0xf4, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5, 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xf2, 0xed, 0xb2, 0x8d, 0x4d, 0x45, 0xcd, 0x2f, 0x3f, 0x44, 0x68, 0x93, 0xc3, 0x58, 0xc8, 0xf1, 0x1f, 0x8a, 0x33, 0x86, 0xda, 0x58, 0xc1, 0xa0, 0x02, 0x4f, 0xc4, 0xa1, 0x69, 0xa5, 0x9b, 0x5b, 0x4b, 0x84, 0x73, 0xdf, 0xc9, 0x15, 0xf8, 0xe3, 0xd1, 0x0e, 0x07, 0x93, 0xf3, 0xd1, 0x0f, 0x1c, 0x17, 0xef, 0x2e, 0x3b, 0x5b, 0xdc, 0xff, 0x00, 0xdf, 0x42, 0xbf, 0x8f, 0x8e, 0xdc, 0x82, 0xca, 0xd8, 0x37, 0x11, 0xa9, 0x3d, 0x82, 0x69, 0x2b, 0xc4, 0x6d, 0xc9, 0x75, 0x25, 0xbc, 0xf7, 0xec, 0xa1, 0xb5, 0x74, 0x19, 0x5d, 0x2e, 0x8a, 0x9a, 0x4b, 0x89, 0x7d, 0xc4, 0x68, 0xc6, 0xf6, 0xfe, 0xb2, 0xa0, 0x30, 0x1d, 0x60, 0x86, 0x88, 0x8d, 0x49, 0x3e, 0x01, 0x11, 0x20, 0xa3, 0x8c, 0xb9, 0xb1, 0xaa, 0x62, 0xad, 0xbf, 0x18, 0x97, 0x43, 0x47, 0x1d, 0xd2, 0xaf, 0x04, 0xd9, 0xb8, 0xc8, 0x0d, 0x68, 0xe4, 0xf7, 0x3e, 0x48, 0xf1, 0x05, 0xbc, 0x25, 0xaa, 0x07, 0x71, 0xd9, 0x14, 0x78, 0xf6, 0x49, 0xb5, 0x90, 0xfd, 0xa7, 0xc6, 0x14, 0xfd, 0x1b, 0x1c, 0xff, 0x00, 0x4d, 0x8d, 0x2e, 0x73, 0x8c, 0x35, 0xa3, 0x52, 0x4f, 0x92, 0x48, 0xa6, 0x1a, 0x24, 0xb6, 0x2a, 0xfa, 0xa5, 0x9e, 0x60, 0x64, 0x39, 0x94, 0x13, 0xcb, 0x27, 0x73, 0x80, 0xf3, 0x0c, 0xf6, 0xff, 0x00, 0xd2, 0x5a, 0x78, 0xbf, 0x53, 0x71, 0xf6, 0x01, 0x75, 0xb6, 0x97, 0x6a, 0x25, 0xa1, 0xad, 0x1f, 0xf4, 0xb7, 0x23, 0x48, 0xb7, 0x94, 0x84, 0x97, 0x5b, 0xff, 0x00, 0x32, 0xa9, 0xdd, 0xfc, 0xed, 0x9b, 0x7e, 0x0d, 0x9e, 0x52, 0x4a, 0x95, 0x61, 0xff, 0xd0, 0xf3, 0x3b, 0xa7, 0x70, 0xee, 0x01, 0x8f, 0xb9, 0x59, 0xfa, 0x7e, 0xdf, 0xe4, 0xc8, 0xf9, 0x2a, 0xc2, 0x5c, 0x63, 0xc3, 0x54, 0x67, 0x87, 0x6e, 0x10, 0x35, 0x68, 0xd4, 0x79, 0x1e, 0x53, 0x4a, 0xe0, 0xdc, 0xe9, 0xb8, 0x1f, 0x6a, 0xda, 0x6c, 0x25, 0x94, 0x37, 0xb0, 0xd0, 0xb8, 0xad, 0x67, 0xe4, 0x55, 0x8a, 0x5b, 0x8b, 0x82, 0xc0, 0x6f, 0x76, 0x80, 0x34, 0x49, 0x05, 0x2e, 0x9e, 0xc6, 0x1c, 0x66, 0x31, 0xba, 0x10, 0x23, 0xe0, 0xaf, 0xe1, 0x61, 0x53, 0x43, 0x8d, 0x81, 0xb3, 0x67, 0xef, 0x9e, 0x49, 0x2a, 0x12, 0x6c, 0xb6, 0x63, 0x1a, 0x0c, 0x31, 0xba, 0x55, 0xcd, 0xac, 0xfa, 0x8e, 0xdf, 0x91, 0x6e, 0x91, 0xd9, 0xb3, 0xc9, 0x73, 0x90, 0x7a, 0xab, 0x6a, 0xc2, 0xa4, 0x60, 0xe2, 0x8f, 0xd2, 0x38, 0x03, 0x7d, 0x9e, 0x0d, 0xff, 0x00, 0xcc, 0xd6, 0xd3, 0x6b, 0x71, 0x67, 0xd2, 0x3e, 0x64, 0x72, 0xab, 0xdb, 0x8d, 0x54, 0x39, 0xc5, 0x83, 0x6b, 0x3d, 0xee, 0x2e, 0xd4, 0x92, 0x3c, 0x4a, 0x56, 0xba, 0xb4, 0x79, 0x5c, 0xf7, 0xb2, 0x96, 0x6c, 0x8d, 0xaf, 0x80, 0x48, 0x3c, 0xf0, 0xb2, 0x1f, 0x63, 0x9c, 0xe9, 0x3f, 0x24, 0x5c, 0xdb, 0xdd, 0x76, 0x43, 0xde, 0xfd, 0x5c, 0xe3, 0x24, 0xfc, 0x50, 0x00, 0x93, 0x0a, 0x78, 0x8a, 0x0d, 0x49, 0xca, 0xcf, 0x93, 0x63, 0x1b, 0x7d, 0xd7, 0x57, 0x50, 0xd5, 0xef, 0x70, 0x6b, 0x4f, 0xc7, 0x45, 0xdb, 0x74, 0x9e, 0x8d, 0x5e, 0x33, 0x83, 0xd8, 0x37, 0xdd, 0xc3, 0xac, 0x3d, 0xbf, 0x92, 0xc5, 0x5b, 0xea, 0xbf, 0xd5, 0x62, 0xc0, 0xdc, 0xbc, 0xbd, 0x2d, 0x22, 0x5a, 0xcf, 0xdd, 0x69, 0xff, 0x00, 0xd1, 0x8e, 0x5d, 0xa5, 0x38, 0xb5, 0xb0, 0x00, 0xc6, 0xc4, 0x24, 0x4a, 0xd6, 0x8d, 0x18, 0x04, 0x49, 0x88, 0x9e, 0x55, 0xd6, 0x61, 0xb0, 0xc1, 0x70, 0x32, 0xdd, 0x3c, 0x95, 0xda, 0xf1, 0xfe, 0xf5, 0x62, 0xbc, 0x76, 0x8e, 0x75, 0x28, 0x02, 0xa2, 0xe7, 0x7d, 0x92, 0xb9, 0x84, 0x96, 0x96, 0xda, 0xf7, 0x70, 0x12, 0x4e, 0x5a, 0xff, 0x00, 0xff, 0xd1, 0xf3, 0x7a, 0x21, 0xaf, 0xde, 0xef, 0xa2, 0x22, 0x55, 0xfc, 0x5a, 0xbd, 0x42, 0xfb, 0x08, 0xfa, 0x67, 0x4f, 0x82, 0xcd, 0x6d, 0x85, 0xc0, 0x56, 0x3b, 0x90, 0xb7, 0xf0, 0x2a, 0x0e, 0x63, 0x58, 0x3b, 0xf2, 0xa3, 0x9e, 0x8c, 0xb8, 0x86, 0xbe, 0x49, 0xf1, 0x2c, 0x0c, 0x86, 0xb4, 0x4c, 0x69, 0xe4, 0xaf, 0x6e, 0xcc, 0x6b, 0x7d, 0x46, 0xb3, 0x70, 0xec, 0x38, 0x51, 0x7d, 0x02, 0x8a, 0xc7, 0xa6, 0xd9, 0x20, 0x68, 0x0f, 0x8f, 0x8a, 0xcf, 0xc9, 0xc2, 0xea, 0x59, 0x5b, 0x48, 0xb0, 0x91, 0xae, 0xe6, 0xc9, 0x03, 0xc9, 0x30, 0x51, 0x66, 0xd4, 0x0d, 0xad, 0xbd, 0x5f, 0x53, 0xcc, 0x6b, 0xb6, 0x90, 0x5a, 0x3b, 0x83, 0x0b, 0x43, 0x17, 0x31, 0xd6, 0xc3, 0x6e, 0x12, 0x3b, 0x79, 0xac, 0xc1, 0x89, 0x47, 0xd9, 0xe8, 0x63, 0x98, 0x45, 0xed, 0x6c, 0x5a, 0xf1, 0xa0, 0x27, 0xc5, 0x5b, 0xc3, 0x6f, 0xa6, 0xe0, 0x1c, 0x7d, 0xb3, 0xa2, 0x69, 0x34, 0x7b, 0xae, 0x1a, 0x8d, 0x45, 0x17, 0x9d, 0xeb, 0xfd, 0x21, 0xd8, 0xb9, 0xae, 0xb5, 0x80, 0xbb, 0x1e, 0xd2, 0x5c, 0xd7, 0x78, 0x13, 0xf9, 0xae, 0x4b, 0xea, 0xc7, 0x4a, 0x39, 0xbd, 0x55, 0xb3, 0xed, 0x66, 0x38, 0xf5, 0x09, 0x22, 0x41, 0x23, 0xe8, 0x37, 0xfb, 0x4b, 0xa1, 0xeb, 0xd6, 0xfe, 0x88, 0x31, 0xbf, 0x41, 0xc0, 0xee, 0xd2, 0x74, 0x02, 0x78, 0x53, 0xfa, 0x97, 0x43, 0x19, 0x85, 0x65, 0xff, 0x00, 0x9d, 0x71, 0x33, 0xe4, 0x1a, 0x7d, 0x8d, 0x53, 0x42, 0x56, 0x35, 0x6b, 0xe5, 0x80, 0x06, 0xc7, 0x57, 0xa7, 0xc4, 0xa9, 0xdb, 0xb6, 0x81, 0x1f, 0xeb, 0xd9, 0x69, 0x56, 0xc2, 0xd0, 0x00, 0xe5, 0x55, 0xc0, 0x12, 0xc2, 0xd7, 0x4e, 0xa2, 0x5a, 0x7c, 0x0a, 0xd0, 0x63, 0x9a, 0xd1, 0xaf, 0xd2, 0xe2, 0x3c, 0x12, 0x62, 0x66, 0xc6, 0x42, 0x23, 0x5a, 0x49, 0x8f, 0x10, 0xa2, 0xd2, 0x3e, 0x28, 0x9d, 0xc4, 0x88, 0x09, 0x29, 0x16, 0xc3, 0x3c, 0x24, 0x8d, 0xe6, 0x92, 0x72, 0x1f, 0xff, 0xd2, 0xf3, 0xbb, 0xb0, 0xfe, 0xcb, 0x99, 0xe9, 0xce, 0xf6, 0x88, 0x2d, 0x77, 0x91, 0x5b, 0x3d, 0x3d, 0xd0, 0xe6, 0x90, 0xa9, 0x65, 0x57, 0x38, 0x95, 0xdd, 0xcb, 0x9a, 0x7d, 0xce, 0xf2, 0x3f, 0x44, 0x23, 0x60, 0x58, 0x76, 0xe9, 0xca, 0x8c, 0xea, 0x1b, 0x31, 0x02, 0x32, 0x23, 0xea, 0xee, 0xb1, 0xcd, 0xb0, 0xc7, 0x87, 0x74, 0x7a, 0xeb, 0x70, 0x1a, 0x71, 0xe1, 0xfe, 0xe4, 0x1c, 0x1d, 0xae, 0xe5, 0x69, 0xd8, 0xfa, 0x99, 0x50, 0x0d, 0x1a, 0xf7, 0x2a, 0x3a, 0x0c, 0xf4, 0x1a, 0x8e, 0xc7, 0x27, 0x5d, 0xbf, 0x18, 0x41, 0xdc, 0xc2, 0xf0, 0x7f, 0x74, 0xf6, 0x3a, 0x22, 0x66, 0xdb, 0x68, 0xc6, 0x80, 0x48, 0x6b, 0x88, 0x06, 0x39, 0x0d, 0xee, 0xaa, 0x1f, 0xb3, 0xd5, 0x1b, 0x83, 0xd8, 0x3b, 0x38, 0x8f, 0x69, 0xfe, 0xdf, 0xd1, 0x4d, 0x29, 0xa1, 0x4c, 0x7a, 0xf4, 0xbf, 0xa7, 0x92, 0xcf, 0xa5, 0x20, 0x08, 0xf3, 0xf6, 0xff, 0x00, 0x15, 0xbb, 0xd1, 0x31, 0xd9, 0x5e, 0x3d, 0x75, 0x56, 0x36, 0x88, 0x00, 0x81, 0xe0, 0x16, 0x5e, 0x55, 0x74, 0x3f, 0x00, 0x9d, 0xe0, 0xcc, 0x69, 0xe7, 0x3a, 0x2d, 0xbe, 0x90, 0x00, 0xa9, 0xae, 0xef, 0x1f, 0x95, 0x4b, 0x0d, 0x9a, 0xdc, 0xc7, 0x45, 0xfe, 0xb1, 0x7d, 0x60, 0xa7, 0xa1, 0xe0, 0x1f, 0x4e, 0x1d, 0x99, 0x69, 0x02, 0x9a, 0xcf, 0x1f, 0xca, 0x7b, 0xbf, 0x90, 0xc5, 0xc2, 0xb3, 0xeb, 0x57, 0xd6, 0x03, 0x6b, 0xae, 0x39, 0xb6, 0x82, 0xe3, 0x31, 0xa1, 0x68, 0xf2, 0x6b, 0x5c, 0x12, 0xfa, 0xe1, 0x91, 0x66, 0x47, 0x5d, 0xb8, 0x3b, 0x4f, 0x44, 0x36, 0xb6, 0x8f, 0x28, 0xdd, 0xff, 0x00, 0x7e, 0x46, 0xab, 0x12, 0x2b, 0x65, 0x55, 0x32, 0xa7, 0x62, 0xb6, 0xbd, 0xf7, 0x64, 0x10, 0xdb, 0x03, 0x9f, 0x1b, 0x9e, 0xc7, 0xd9, 0xb8, 0x3b, 0x1f, 0x67, 0xf3, 0x6c, 0x52, 0x80, 0xd7, 0x7d, 0x0f, 0xea, 0x7f, 0x5d, 0x1d, 0x67, 0xa6, 0x0b, 0x1e, 0x47, 0xda, 0x69, 0x3b, 0x2e, 0x03, 0xc7, 0xf3, 0x5f, 0x1f, 0xf0, 0x8b, 0xa1, 0x02, 0x46, 0xba, 0x79, 0xaf, 0x32, 0xff, 0x00, 0x16, 0xad, 0xca, 0x1d, 0x57, 0x2a, 0xdc, 0x79, 0x18, 0x41, 0xb0, 0xf6, 0x9e, 0xe4, 0x9f, 0xd0, 0x8f, 0xeb, 0x31, 0xab, 0xd2, 0x83, 0xa4, 0xcb, 0x8c, 0xb8, 0xa0, 0x42, 0x12, 0x7b, 0x67, 0x9f, 0x2f, 0xf5, 0x09, 0x26, 0x96, 0xc4, 0xce, 0xa9, 0x20, 0xa7, 0xff, 0xd3, 0xf3, 0x2f, 0xb4, 0x5d, 0xe9, 0x0a, 0xb7, 0x9f, 0x4c, 0x19, 0xdb, 0x3a, 0x2d, 0x5e, 0x94, 0xfd, 0xc4, 0xb7, 0xc5, 0x62, 0xf9, 0x2b, 0xfd, 0x2e, 0xe3, 0x5d, 0xe0, 0x7c, 0x13, 0x48, 0xd1, 0x92, 0x12, 0xa9, 0x0b, 0x7a, 0xbc, 0x2d, 0xc2, 0x7f, 0x92, 0x60, 0xab, 0x4e, 0x79, 0x2e, 0x00, 0xf0, 0xaa, 0xe1, 0xda, 0x3d, 0x43, 0xfc, 0xad, 0x55, 0xbb, 0x80, 0x79, 0x81, 0xa0, 0xe6, 0x54, 0x32, 0x6d, 0x02, 0xbe, 0xf3, 0x61, 0x81, 0xa8, 0x44, 0x14, 0x03, 0x59, 0x0e, 0x1c, 0xf6, 0x1f, 0xdc, 0xb2, 0xec, 0xa3, 0x23, 0x77, 0xe8, 0x6e, 0x70, 0xf2, 0x25, 0x1f, 0x1f, 0x17, 0xa9, 0x6d, 0x71, 0x36, 0x97, 0x47, 0x00, 0xa4, 0x02, 0xe0, 0x2c, 0x7c, 0xc1, 0xab, 0xd5, 0x31, 0x85, 0x35, 0xd4, 0xe6, 0x13, 0x02, 0xd6, 0x4b, 0x67, 0x48, 0x2b, 0xa9, 0xe9, 0x2e, 0x02, 0xb6, 0x4f, 0x82, 0xe5, 0x7a, 0x95, 0x19, 0xc6, 0x87, 0x3d, 0xfb, 0xa2, 0xb8, 0x79, 0x1e, 0x4d, 0x3b, 0x96, 0xcf, 0x4f, 0xbd, 0xcd, 0xa2, 0xa2, 0x1f, 0xa0, 0x82, 0xd3, 0xfc, 0x97, 0x05, 0x24, 0x36, 0x6b, 0xf3, 0x31, 0xa2, 0x35, 0x79, 0xef, 0xad, 0xf8, 0xae, 0xaf, 0xaf, 0xd8, 0xf2, 0xd8, 0x6d, 0xed, 0x6b, 0xda, 0x7b, 0x18, 0x1b, 0x5d, 0xff, 0x00, 0x52, 0xb1, 0x6d, 0xf0, 0x81, 0x31, 0xca, 0xf4, 0x6e, 0xb1, 0x80, 0xce, 0xb1, 0x84, 0xc0, 0x21, 0xb7, 0xd6, 0x77, 0x31, 0xd1, 0x27, 0xc1, 0xcd, 0xfe, 0xd2, 0xe3, 0xec, 0xe8, 0x1d, 0x45, 0x96, 0xb0, 0x9a, 0xb7, 0x87, 0x3f, 0x68, 0x2d, 0xf7, 0x01, 0x1f, 0xbe, 0xd1, 0xf4, 0x7f, 0xb4, 0xa4, 0x0d, 0x77, 0xbb, 0xfa, 0x8f, 0x80, 0x3a, 0x7f, 0x43, 0xaa, 0xe2, 0xdf, 0xd2, 0x65, 0x7e, 0x95, 0xe4, 0x0f, 0x1f, 0xa1, 0xfe, 0x6b, 0x16, 0x9f, 0x52, 0xfa, 0xc1, 0xd3, 0xba, 0x6d, 0x26, 0xdc, 0xac, 0x86, 0xd4, 0xd9, 0x0d, 0x31, 0x2e, 0x74, 0x9e, 0xdb, 0x59, 0x2e, 0x55, 0xe8, 0xc9, 0xb2, 0x96, 0xd5, 0x4b, 0x9f, 0xb8, 0x6d, 0xda, 0x1c, 0x04, 0x09, 0x03, 0xfe, 0x8a, 0xc6, 0xfa, 0xd3, 0xf5, 0x6a, 0xbe, 0xbb, 0x5b, 0x2e, 0xc6, 0xb5, 0x94, 0xe6, 0xd5, 0x20, 0x97, 0x7d, 0x1b, 0x1b, 0xf9, 0xad, 0x7c, 0x7d, 0x17, 0xb7, 0xf3, 0x1e, 0x92, 0x1b, 0x7f, 0xf8, 0xe0, 0x7d, 0x59, 0xdd, 0xfd, 0x32, 0xd8, 0x8f, 0xa5, 0xe8, 0x3a, 0x12, 0x5c, 0x3f, 0xfc, 0xc4, 0xfa, 0xc3, 0xb3, 0x77, 0xa7, 0x56, 0xed, 0xdb, 0x76, 0x7a, 0x8d, 0xdd, 0x1f, 0xbf, 0xfd, 0x44, 0x92, 0x56, 0x8f, 0xff, 0xd4, 0xf2, 0xe8, 0x86, 0x17, 0x1e, 0xfa, 0x04, 0x56, 0x4b, 0x43, 0x6c, 0x6f, 0x2d, 0xe5, 0x46, 0x01, 0x64, 0x2b, 0x14, 0x32, 0x5b, 0xb4, 0xa0, 0x52, 0x1d, 0xde, 0x9b, 0x94, 0xdb, 0xab, 0x6b, 0x81, 0xf7, 0x05, 0xb0, 0xd7, 0x07, 0xb2, 0x27, 0x55, 0xc6, 0x57, 0x65, 0xd8, 0x76, 0x6e, 0x64, 0xed, 0xee, 0x16, 0xce, 0x27, 0x57, 0x63, 0xda, 0x0c, 0xc2, 0x8e, 0x51, 0x67, 0x84, 0xfa, 0x1d, 0xdd, 0x62, 0xc7, 0x07, 0xe9, 0xf7, 0xa3, 0xd6, 0x6c, 0x02, 0x41, 0x55, 0x31, 0xf3, 0x2b, 0xb3, 0xba, 0x2b, 0x2e, 0x68, 0x24, 0x1d, 0x47, 0x64, 0xca, 0xa6, 0x50, 0x41, 0x65, 0x90, 0x6c, 0xb1, 0xa5, 0xae, 0x33, 0x23, 0x51, 0xe4, 0xab, 0x7d, 0x5d, 0xcb, 0xb6, 0xcc, 0x37, 0xd0, 0x40, 0x73, 0x71, 0xde, 0x58, 0x09, 0xe7, 0x6f, 0x2c, 0x44, 0xc9, 0xc9, 0xae, 0xba, 0x9d, 0x63, 0x88, 0x01, 0xa0, 0x95, 0x9d, 0xf5, 0x3f, 0x2a, 0xe6, 0x67, 0xdb, 0x50, 0x83, 0x55, 0xad, 0x36, 0x3e, 0x78, 0x10, 0x74, 0x77, 0xfd, 0x2d, 0xaa, 0x4c, 0x7d, 0x58, 0x73, 0x91, 0xa0, 0x0f, 0x51, 0x45, 0xb7, 0x33, 0xdd, 0x58, 0x69, 0x1d, 0xd8, 0x0c, 0x9f, 0x96, 0x88, 0x19, 0x99, 0x19, 0xac, 0xcf, 0xa3, 0xd2, 0xad, 0xb5, 0xdb, 0x76, 0x8f, 0xad, 0xc4, 0xea, 0xcf, 0xdf, 0x7e, 0xdf, 0xdd, 0xfc, 0xd5, 0xa3, 0x5e, 0x43, 0x2b, 0x6b, 0xb2, 0xad, 0x3b, 0x6a, 0xa4, 0x13, 0xa7, 0x04, 0xac, 0x7a, 0x6f, 0xb3, 0x23, 0x26, 0xcc, 0xfb, 0xb4, 0x75, 0x8e, 0x01, 0x83, 0xf7, 0x58, 0x3e, 0x8b, 0x53, 0xa7, 0x2a, 0x1a, 0x31, 0x42, 0x36, 0x5d, 0x4c, 0x9a, 0xf2, 0xdc, 0xc6, 0xfe, 0x98, 0xb4, 0x34, 0xcb, 0x48, 0x0a, 0x8f, 0xdb, 0xb2, 0xeb, 0x76, 0xd6, 0x07, 0x5c, 0x59, 0xc9, 0x64, 0x8f, 0x93, 0xa7, 0x73, 0x16, 0x83, 0xaf, 0x0e, 0xa4, 0x33, 0xef, 0x50, 0xc5, 0x0c, 0xda, 0x59, 0x10, 0x06, 0x8a, 0x2e, 0x29, 0x0e, 0xac, 0xc2, 0x31, 0x3d, 0x36, 0x69, 0x7e, 0xd6, 0xcc, 0xf5, 0x3d, 0x6f, 0xb3, 0xeb, 0x1b, 0x76, 0xef, 0x3b, 0xa3, 0xfa, 0xc9, 0x2b, 0x5f, 0x66, 0x6f, 0xa9, 0x1e, 0x73, 0xf2, 0x49, 0x2e, 0x39, 0xf7, 0x4f, 0xb7, 0x8d, 0xff, 0xd5, 0xf3, 0x26, 0xfe, 0x0a, 0xc5, 0x1b, 0xa7, 0xcb, 0xb2, 0xcf, 0x49, 0x03, 0xb2, 0x46, 0xee, 0xd9, 0xd9, 0xb3, 0xf4, 0x9f, 0x25, 0x4a, 0xdf, 0x4b, 0x77, 0xe8, 0x27, 0xd4, 0xef, 0x1c, 0x2a, 0x29, 0x26, 0xc5, 0x7c, 0x9d, 0x6c, 0x7f, 0xb7, 0x6e, 0x1b, 0x26, 0x7f, 0x05, 0xa3, 0xfe, 0x53, 0x8d, 0x62, 0x57, 0x30, 0x92, 0x12, 0xfa, 0x2f, 0x86, 0xdf, 0xa4, 0xec, 0x67, 0xfe, 0xd0, 0xf4, 0xff, 0x00, 0x4d, 0xfc, 0xdf, 0x78, 0xe1, 0x68, 0x7d, 0x54, 0x99, 0xbf, 0x6f, 0xf3, 0xbe, 0xdf, 0x8e, 0xdd, 0x7f, 0xef, 0xeb, 0x97, 0x49, 0x3e, 0x3b, 0x7f, 0x06, 0x2c, 0x9f, 0x37, 0x5f, 0xf0, 0x9f, 0x4c, 0xeb, 0x7b, 0xbf, 0x67, 0x55, 0xe8, 0xff, 0x00, 0x31, 0xbc, 0x7a, 0x9e, 0x31, 0xdb, 0xfe, 0x92, 0xae, 0x37, 0x7a, 0x4d, 0xdb, 0xe2, 0x17, 0x9d, 0xa4, 0xa3, 0xc9, 0xba, 0xfc, 0x7b, 0x7d, 0x5f, 0x52, 0xa7, 0x7e, 0xd1, 0x28, 0xf8, 0xf3, 0xb0, 0xc7, 0x32, 0xbc, 0x99, 0x24, 0xc5, 0xe3, 0xab, 0xeb, 0x1f, 0xa4, 0xf5, 0xfc, 0xe1, 0x25, 0xe4, 0xe9, 0x24, 0x97, 0xff, 0xd9, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x41, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x00, 0x00, 0x13, 0x00, 0x41, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x20, 0x00, 0x37, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xff, 0xe1, 0x15, 0x67, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x00, 0x3c, 0x3f, 0x78, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x3d, 0x27, 0xef, 0xbb, 0xbf, 0x27, 0x20, 0x69, 0x64, 0x3d, 0x27, 0x57, 0x35, 0x4d, 0x30, 0x4d, 0x70, 0x43, 0x65, 0x68, 0x69, 0x48, 0x7a, 0x72, 0x65, 0x53, 0x7a, 0x4e, 0x54, 0x63, 0x7a, 0x6b, 0x63, 0x39, 0x64, 0x27, 0x3f, 0x3e, 0x0a, 0x3c, 0x3f, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2d, 0x78, 0x61, 0x70, 0x2d, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x20, 0x65, 0x73, 0x63, 0x3d, 0x22, 0x43, 0x52, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 0x78, 0x3a, 0x78, 0x61, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x27, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x27, 0x20, 0x78, 0x3a, 0x78, 0x61, 0x70, 0x74, 0x6b, 0x3d, 0x27, 0x58, 0x4d, 0x50, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x20, 0x32, 0x2e, 0x38, 0x2e, 0x32, 0x2d, 0x33, 0x33, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x31, 0x2e, 0x35, 0x27, 0x3e, 0x0a, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x27, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x69, 0x58, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x58, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x27, 0x3e, 0x0a, 0x0a, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x27, 0x75, 0x75, 0x69, 0x64, 0x3a, 0x32, 0x32, 0x64, 0x30, 0x32, 0x62, 0x30, 0x61, 0x2d, 0x62, 0x32, 0x34, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x62, 0x2d, 0x38, 0x61, 0x66, 0x38, 0x2d, 0x39, 0x31, 0x64, 0x35, 0x34, 0x30, 0x33, 0x66, 0x39, 0x32, 0x66, 0x39, 0x27, 0x0a, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x70, 0x64, 0x66, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x64, 0x66, 0x2f, 0x31, 0x2e, 0x33, 0x2f, 0x27, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x70, 0x64, 0x66, 0x3a, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x64, 0x20, 0x2d, 0x2d, 0x3e, 0x0a, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x0a, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x27, 0x75, 0x75, 0x69, 0x64, 0x3a, 0x32, 0x32, 0x64, 0x30, 0x32, 0x62, 0x30, 0x61, 0x2d, 0x62, 0x32, 0x34, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x62, 0x2d, 0x38, 0x61, 0x66, 0x38, 0x2d, 0x39, 0x31, 0x64, 0x35, 0x34, 0x30, 0x33, 0x66, 0x39, 0x32, 0x66, 0x39, 0x27, 0x0a, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x27, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x3a, 0x43, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x64, 0x20, 0x2d, 0x2d, 0x3e, 0x0a, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x0a, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x27, 0x75, 0x75, 0x69, 0x64, 0x3a, 0x32, 0x32, 0x64, 0x30, 0x32, 0x62, 0x30, 0x61, 0x2d, 0x62, 0x32, 0x34, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x62, 0x2d, 0x38, 0x61, 0x66, 0x38, 0x2d, 0x39, 0x31, 0x64, 0x35, 0x34, 0x30, 0x33, 0x66, 0x39, 0x32, 0x66, 0x39, 0x27, 0x0a, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x61, 0x70, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x27, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x78, 0x61, 0x70, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x64, 0x20, 0x2d, 0x2d, 0x3e, 0x0a, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x0a, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x27, 0x75, 0x75, 0x69, 0x64, 0x3a, 0x32, 0x32, 0x64, 0x30, 0x32, 0x62, 0x30, 0x61, 0x2d, 0x62, 0x32, 0x34, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x62, 0x2d, 0x38, 0x61, 0x66, 0x38, 0x2d, 0x39, 0x31, 0x64, 0x35, 0x34, 0x30, 0x33, 0x66, 0x39, 0x32, 0x66, 0x39, 0x27, 0x0a, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x61, 0x70, 0x4d, 0x4d, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x6d, 0x6d, 0x2f, 0x27, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x78, 0x61, 0x70, 0x4d, 0x4d, 0x3a, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x3e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x64, 0x6f, 0x63, 0x69, 0x64, 0x3a, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x3a, 0x32, 0x32, 0x64, 0x30, 0x32, 0x62, 0x30, 0x36, 0x2d, 0x62, 0x32, 0x34, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x62, 0x2d, 0x38, 0x61, 0x66, 0x38, 0x2d, 0x39, 0x31, 0x64, 0x35, 0x34, 0x30, 0x33, 0x66, 0x39, 0x32, 0x66, 0x39, 0x3c, 0x2f, 0x78, 0x61, 0x70, 0x4d, 0x4d, 0x3a, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x3e, 0x0a, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x0a, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x27, 0x75, 0x75, 0x69, 0x64, 0x3a, 0x32, 0x32, 0x64, 0x30, 0x32, 0x62, 0x30, 0x61, 0x2d, 0x62, 0x32, 0x34, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x62, 0x2d, 0x38, 0x61, 0x66, 0x38, 0x2d, 0x39, 0x31, 0x64, 0x35, 0x34, 0x30, 0x33, 0x66, 0x39, 0x32, 0x66, 0x39, 0x27, 0x0a, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x27, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x41, 0x6c, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x6c, 0x69, 0x20, 0x78, 0x6d, 0x6c, 0x3a, 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x27, 0x78, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x27, 0x3e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x6c, 0x69, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x41, 0x6c, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x0a, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x61, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x3c, 0x3f, 0x78, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x3d, 0x27, 0x77, 0x27, 0x3f, 0x3e, 0xff, 0xee, 0x00, 0x0e, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x00, 0x64, 0x40, 0x00, 0x00, 0x00, 0x01, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x06, 0x04, 0x03, 0x04, 0x06, 0x07, 0x05, 0x04, 0x04, 0x05, 0x07, 0x08, 0x06, 0x06, 0x07, 0x06, 0x06, 0x08, 0x0a, 0x08, 0x09, 0x09, 0x09, 0x09, 0x08, 0x0a, 0x0a, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0a, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x01, 0x04, 0x05, 0x05, 0x08, 0x07, 0x08, 0x0f, 0x0a, 0x0a, 0x0f, 0x14, 0x0e, 0x0e, 0x0e, 0x14, 0x14, 0x0e, 0x0e, 0x0e, 0x0e, 0x14, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x64, 0x00, 0x64, 0x03, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xdd, 0x00, 0x04, 0x00, 0x0d, 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x03, 0x02, 0x06, 0x01, 0x00, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x02, 0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x02, 0x06, 0x07, 0x03, 0x04, 0x02, 0x06, 0x02, 0x73, 0x01, 0x02, 0x03, 0x11, 0x04, 0x00, 0x05, 0x21, 0x12, 0x31, 0x41, 0x51, 0x06, 0x13, 0x61, 0x22, 0x71, 0x81, 0x14, 0x32, 0x91, 0xa1, 0x07, 0x15, 0xb1, 0x42, 0x23, 0xc1, 0x52, 0xd1, 0xe1, 0x33, 0x16, 0x62, 0xf0, 0x24, 0x72, 0x82, 0xf1, 0x25, 0x43, 0x34, 0x53, 0x92, 0xa2, 0xb2, 0x63, 0x73, 0xc2, 0x35, 0x44, 0x27, 0x93, 0xa3, 0xb3, 0x36, 0x17, 0x54, 0x64, 0x74, 0xc3, 0xd2, 0xe2, 0x08, 0x26, 0x83, 0x09, 0x0a, 0x18, 0x19, 0x84, 0x94, 0x45, 0x46, 0xa4, 0xb4, 0x56, 0xd3, 0x55, 0x28, 0x1a, 0xf2, 0xe3, 0xf3, 0xc4, 0xd4, 0xe4, 0xf4, 0x65, 0x75, 0x85, 0x95, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, 0xb8, 0xc8, 0xd8, 0xe8, 0xf8, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9, 0xb9, 0xc9, 0xd9, 0xe9, 0xf9, 0x2a, 0x3a, 0x4a, 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa, 0x11, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x05, 0x05, 0x04, 0x05, 0x06, 0x04, 0x08, 0x03, 0x03, 0x6d, 0x01, 0x00, 0x02, 0x11, 0x03, 0x04, 0x21, 0x12, 0x31, 0x41, 0x05, 0x51, 0x13, 0x61, 0x22, 0x06, 0x71, 0x81, 0x91, 0x32, 0xa1, 0xb1, 0xf0, 0x14, 0xc1, 0xd1, 0xe1, 0x23, 0x42, 0x15, 0x52, 0x62, 0x72, 0xf1, 0x33, 0x24, 0x34, 0x43, 0x82, 0x16, 0x92, 0x53, 0x25, 0xa2, 0x63, 0xb2, 0xc2, 0x07, 0x73, 0xd2, 0x35, 0xe2, 0x44, 0x83, 0x17, 0x54, 0x93, 0x08, 0x09, 0x0a, 0x18, 0x19, 0x26, 0x36, 0x45, 0x1a, 0x27, 0x64, 0x74, 0x55, 0x37, 0xf2, 0xa3, 0xb3, 0xc3, 0x28, 0x29, 0xd3, 0xe3, 0xf3, 0x84, 0x94, 0xa4, 0xb4, 0xc4, 0xd4, 0xe4, 0xf4, 0x65, 0x75, 0x85, 0x95, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5, 0x46, 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, 0xb8, 0xc8, 0xd8, 0xe8, 0xf8, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9, 0xb9, 0xc9, 0xd9, 0xe9, 0xf9, 0x2a, 0x3a, 0x4a, 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xf0, 0x67, 0xa6, 0x5c, 0x0f, 0x01, 0xd4, 0x7e, 0x18, 0x12, 0x98, 0xe9, 0xd6, 0x2d, 0x34, 0x6d, 0x70, 0xdf, 0xdc, 0xa1, 0xe3, 0xec, 0x5b, 0xfb, 0x32, 0x24, 0xb2, 0x01, 0x1f, 0x15, 0xa4, 0x52, 0x4a, 0x82, 0x31, 0xf1, 0xfe, 0xd1, 0x3d, 0x14, 0x64, 0x49, 0x64, 0x22, 0x98, 0xcf, 0xa5, 0x46, 0x6c, 0x16, 0x55, 0x71, 0x56, 0x62, 0x28, 0x07, 0xc5, 0x45, 0x15, 0xa0, 0xc8, 0x89, 0x33, 0xe1, 0x63, 0xd2, 0xd8, 0x34, 0x44, 0x17, 0xa0, 0x2c, 0x4d, 0x16, 0xbb, 0xed, 0xdc, 0xf8, 0x64, 0xc1, 0x6b, 0x31, 0x42, 0x18, 0x8e, 0xc7, 0xb5, 0x2a, 0x7d, 0xb2, 0x56, 0xc5, 0x61, 0x8c, 0xf2, 0xa0, 0x1b, 0x1e, 0x83, 0x0d, 0xa1, 0x63, 0x50, 0x1f, 0x97, 0x7c, 0x2a, 0xa9, 0x1a, 0x9a, 0x86, 0x4f, 0xb4, 0xb4, 0x38, 0x0a, 0xa6, 0x0b, 0xb8, 0x0c, 0x05, 0x14, 0xf8, 0x76, 0x3e, 0x19, 0x14, 0xb6, 0x78, 0xf8, 0x8c, 0x2a, 0xd5, 0x01, 0xdc, 0x6f, 0x8a, 0x1a, 0xe3, 0x8d, 0xab, 0xff, 0xd0, 0xf0, 0xec, 0xe9, 0x15, 0xb5, 0xb9, 0x5a, 0x7c, 0x4c, 0xa2, 0x9e, 0x24, 0xf5, 0xca, 0xc6, 0xe5, 0x99, 0xd9, 0x34, 0x99, 0x04, 0x3a, 0x7d, 0xb5, 0xba, 0xd5, 0x51, 0x63, 0x0e, 0xc7, 0xc5, 0x9b, 0x73, 0xf8, 0xe4, 0x6f, 0x76, 0xca, 0xd9, 0xda, 0x54, 0x6d, 0x72, 0x2e, 0x1a, 0x57, 0x11, 0x44, 0x40, 0x0d, 0x27, 0x7a, 0x0f, 0xd9, 0x5f, 0x12, 0x69, 0x4c, 0x84, 0xcd, 0x36, 0xe3, 0x85, 0xb2, 0xcd, 0x2f, 0x4a, 0x8b, 0x58, 0x36, 0xf6, 0x76, 0xa8, 0x64, 0x64, 0x3c, 0xa4, 0x93, 0xaa, 0x25, 0x3c, 0x49, 0xda, 0xa4, 0xe5, 0x26, 0x54, 0xe4, 0x8c, 0x7c, 0x5c, 0x93, 0x4d, 0x67, 0xc9, 0x3a, 0x6e, 0x9f, 0x13, 0xb4, 0xce, 0xf7, 0x3a, 0x9b, 0xad, 0x52, 0xd6, 0x2a, 0xd1, 0x49, 0xee, 0xc7, 0xf8, 0x64, 0x46, 0x42, 0x4e, 0xcd, 0x92, 0xc2, 0x00, 0xdd, 0x8a, 0x47, 0xe5, 0x69, 0x6e, 0xd4, 0xa4, 0x08, 0x16, 0x83, 0x9c, 0x8c, 0xdd, 0x95, 0x6b, 0xb9, 0xf6, 0xef, 0x97, 0x78, 0x94, 0xe3, 0x78, 0x04, 0xa4, 0xf3, 0xe8, 0xee, 0x64, 0xe1, 0x12, 0x10, 0x05, 0x6a, 0xc7, 0xc0, 0x6f, 0x53, 0xf3, 0xc9, 0x89, 0xb4, 0x9c, 0x4e, 0xb4, 0xf2, 0xd3, 0xde, 0x7a, 0xd2, 0x19, 0x16, 0x38, 0x61, 0x5d, 0xd9, 0x88, 0x05, 0x9c, 0xf4, 0x0a, 0x0f, 0x5f, 0x73, 0x84, 0xe4, 0xa4, 0xc7, 0x0d, 0xa5, 0xf1, 0x59, 0xba, 0x5c, 0x08, 0x98, 0x6f, 0xc8, 0x20, 0xfa, 0x4e, 0x4e, 0xf6, 0x69, 0xe1, 0xa2, 0x89, 0xfd, 0x1f, 0x77, 0x2c, 0xe6, 0xce, 0xd6, 0x17, 0x9a, 0x69, 0xdb, 0xd3, 0x86, 0x18, 0xc1, 0x67, 0x77, 0x26, 0x80, 0x28, 0x1b, 0x93, 0x88, 0x41, 0x0f, 0x40, 0xb0, 0xfc, 0x87, 0xf3, 0x43, 0x98, 0xd7, 0x58, 0x96, 0xdb, 0x4d, 0x91, 0x88, 0xe5, 0x6c, 0x58, 0xdc, 0x5c, 0x2a, 0xf7, 0x2c, 0xb1, 0xfc, 0x20, 0x8f, 0x02, 0xd9, 0x65, 0x06, 0xbe, 0x26, 0x6f, 0xa2, 0x7f, 0xce, 0x3d, 0x69, 0x26, 0xdd, 0x13, 0x52, 0xbf, 0xbd, 0x92, 0x62, 0x59, 0x4c, 0x90, 0xac, 0x50, 0x45, 0x5e, 0xbb, 0x09, 0x03, 0x12, 0x29, 0x84, 0x00, 0xc4, 0xc9, 0x11, 0xff, 0x00, 0x42, 0xe7, 0xa7, 0x7a, 0xd4, 0xfd, 0x21, 0x79, 0xe9, 0x78, 0x71, 0x8b, 0x95, 0x39, 0x75, 0xaf, 0x4e, 0x98, 0x78, 0x42, 0x38, 0xdf, 0xff, 0xd1, 0xf0, 0xe6, 0xa0, 0x58, 0xc8, 0x84, 0x9a, 0xaa, 0x30, 0x55, 0xf9, 0x0a, 0x6f, 0x90, 0x0c, 0xca, 0x72, 0x48, 0xb8, 0x1e, 0x89, 0xa7, 0x23, 0x17, 0x24, 0xff, 0x00, 0x61, 0xb6, 0x54, 0x76, 0x6e, 0x1b, 0xa7, 0xbe, 0x50, 0xf2, 0xc1, 0xd7, 0x4c, 0x52, 0x5e, 0x33, 0x5b, 0xe9, 0x10, 0xf4, 0x54, 0x3c, 0x5e, 0x77, 0xee, 0x49, 0xec, 0x2b, 0xb6, 0x63, 0xe4, 0xc9, 0xc3, 0xef, 0x73, 0xf0, 0xe1, 0x32, 0x1b, 0xf2, 0x7a, 0x05, 0xce, 0xad, 0x65, 0xa1, 0x98, 0xb4, 0x0f, 0x2a, 0x5b, 0x23, 0xeb, 0x12, 0x00, 0x88, 0xb0, 0xa8, 0x66, 0x46, 0x3d, 0xea, 0x7b, 0xfb, 0x9e, 0x99, 0x89, 0xbc, 0x8d, 0x97, 0x3a, 0x34, 0x05, 0x32, 0x5d, 0x1f, 0xc9, 0x1a, 0x8c, 0x36, 0x8c, 0x6f, 0x66, 0xfa, 0xc6, 0xb7, 0x7d, 0xf0, 0x94, 0x04, 0xf0, 0x88, 0xc9, 0xd5, 0x9d, 0x8d, 0x4b, 0x11, 0xd4, 0x9f, 0xbb, 0x25, 0xc5, 0xdc, 0xa2, 0x03, 0x99, 0x4b, 0xbc, 0xf3, 0x0d, 0x97, 0x96, 0x74, 0xe5, 0xf2, 0xb6, 0x80, 0x95, 0xbd, 0x99, 0x15, 0xf5, 0x4b, 0xd2, 0x37, 0x58, 0x46, 0xd4, 0x27, 0xc5, 0xce, 0xc1, 0x7c, 0x30, 0x8e, 0x68, 0x94, 0x7b, 0x9e, 0x6d, 0xe6, 0x7b, 0x9b, 0x5d, 0x3a, 0xd8, 0xdb, 0x32, 0xfa, 0x77, 0x65, 0x15, 0xe4, 0x57, 0xa7, 0x21, 0x55, 0x04, 0x57, 0xef, 0xd8, 0x66, 0x56, 0x38, 0x19, 0x1b, 0xe8, 0xe0, 0x67, 0x98, 0xc7, 0x1a, 0x1c, 0xde, 0x71, 0x71, 0x79, 0x2c, 0xf2, 0xfa, 0x8c, 0x48, 0xec, 0xb5, 0x24, 0x9a, 0x0c, 0xce, 0x75, 0x29, 0xae, 0x8c, 0x67, 0xd4, 0xb5, 0x0b, 0x4b, 0x04, 0x05, 0xef, 0x2e, 0x66, 0x8e, 0x18, 0x08, 0x15, 0xdd, 0x8f, 0x11, 0xb0, 0xeb, 0x4c, 0x04, 0x5b, 0x21, 0x2a, 0x7d, 0x41, 0xe4, 0x4f, 0xcb, 0xcb, 0x5d, 0x12, 0x45, 0xb8, 0xb7, 0x53, 0x71, 0xaa, 0x9f, 0x86, 0x5b, 0xd6, 0x50, 0x4a, 0xed, 0xba, 0x46, 0x77, 0x00, 0x13, 0xd4, 0x8c, 0x85, 0xd3, 0x12, 0x6d, 0xeb, 0x1a, 0x67, 0x95, 0xd9, 0x39, 0x39, 0x50, 0xac, 0xff, 0x00, 0x6f, 0xc4, 0xff, 0x00, 0x1c, 0x81, 0x92, 0xb2, 0x6b, 0x6d, 0x02, 0xdd, 0xbd, 0x36, 0x92, 0x36, 0x2d, 0x1f, 0xc0, 0x2a, 0x0b, 0x28, 0x1b, 0x91, 0x41, 0xf4, 0x9c, 0xb6, 0x25, 0x81, 0x46, 0xfe, 0x81, 0xb5, 0xad, 0x3d, 0xba, 0x57, 0xb7, 0xf9, 0xf6, 0xc9, 0xb0, 0x7f, 0xff, 0xd2, 0xf0, 0xe2, 0x86, 0x95, 0xc4, 0x67, 0x7e, 0x3f, 0x11, 0xf7, 0xa8, 0x19, 0x06, 0x69, 0x8d, 0xca, 0xca, 0x24, 0x8f, 0xd3, 0x52, 0x24, 0x89, 0x47, 0x25, 0x1f, 0xcb, 0x20, 0xf8, 0xb2, 0xb2, 0x76, 0x6e, 0x88, 0x36, 0xf6, 0x6f, 0x2a, 0xc1, 0x6e, 0xfa, 0x45, 0xad, 0xbc, 0x3f, 0x0b, 0x46, 0x81, 0x4d, 0x46, 0xea, 0x7a, 0x9a, 0x83, 0x9a, 0xa9, 0xdd, 0xbb, 0xec, 0x7b, 0x06, 0x5b, 0xe5, 0xcf, 0x2e, 0x69, 0xfa, 0x5c, 0xcd, 0x7b, 0x14, 0x5e, 0xa5, 0xee, 0xf5, 0xb8, 0x7d, 0xdd, 0x99, 0xba, 0xef, 0x91, 0x16, 0x5b, 0x36, 0xb6, 0x65, 0x0d, 0xac, 0xb2, 0x5b, 0xed, 0x34, 0x81, 0x7a, 0xbb, 0x46, 0x40, 0x6a, 0x9e, 0xb4, 0x39, 0x31, 0x13, 0x49, 0xda, 0xd2, 0x9b, 0xed, 0x1e, 0xc4, 0x24, 0xb3, 0x35, 0xb2, 0x88, 0x60, 0x06, 0xe6, 0x56, 0x98, 0x96, 0x79, 0x1e, 0x31, 0x51, 0xc9, 0x8f, 0xcb, 0x00, 0xe6, 0xb3, 0xe4, 0xf9, 0x2b, 0xcc, 0x7a, 0x94, 0xda, 0x96, 0xa9, 0x71, 0x77, 0x70, 0x79, 0xcd, 0x33, 0x97, 0x76, 0x3f, 0xcc, 0xc6, 0xa6, 0x9f, 0x2e, 0x99, 0xb9, 0xc6, 0x2a, 0x21, 0xe6, 0x73, 0xca, 0xe6, 0x4a, 0x51, 0x1a, 0x99, 0x1c, 0x28, 0x04, 0x93, 0xd0, 0x0e, 0xa4, 0xe4, 0xda, 0x5f, 0x50, 0xfe, 0x4a, 0xfe, 0x48, 0xb5, 0xb2, 0xc1, 0xe6, 0x1f, 0x31, 0x7e, 0xef, 0x52, 0x91, 0x43, 0xc3, 0x6e, 0x77, 0xf4, 0x22, 0x6d, 0xbf, 0xe4, 0x63, 0x0e, 0xbf, 0xca, 0x36, 0xeb, 0x5c, 0x84, 0xa5, 0x48, 0x7d, 0x3b, 0x61, 0xa1, 0xdb, 0x5b, 0x2c, 0x71, 0xda, 0x45, 0xc4, 0x28, 0x00, 0x81, 0xdb, 0x31, 0xc9, 0xb4, 0xb2, 0x3b, 0x5d, 0x27, 0xa5, 0x05, 0x1b, 0xc7, 0xdb, 0x10, 0xa9, 0xbd, 0xa6, 0x93, 0x0c, 0x75, 0xe4, 0x39, 0x35, 0x41, 0x3d, 0xc5, 0x06, 0xdb, 0x8e, 0xfd, 0x46, 0x5b, 0x1d, 0x98, 0x95, 0x4f, 0x46, 0xdb, 0xd5, 0xfb, 0x29, 0x5e, 0x9d, 0x0d, 0x32, 0xeb, 0x61, 0x4f, 0xff, 0xd3, 0xf1, 0x46, 0x9a, 0x16, 0x1b, 0x91, 0x71, 0x28, 0xac, 0x4a, 0x14, 0x30, 0x3e, 0x19, 0x54, 0xb9, 0x36, 0xc7, 0x9b, 0x2d, 0xd1, 0x6c, 0x45, 0xe3, 0xdc, 0xde, 0xc8, 0x95, 0x5b, 0x87, 0xf8, 0x41, 0x1d, 0x10, 0x54, 0x01, 0x98, 0x79, 0x25, 0xd1, 0xda, 0xe9, 0xe1, 0xb5, 0x9e, 0xac, 0xeb, 0x42, 0xba, 0x8e, 0xdf, 0x8c, 0x31, 0x21, 0x70, 0xb4, 0x5d, 0xbe, 0xc5, 0x7c, 0x2b, 0xed, 0xe1, 0x94, 0x18, 0xb9, 0x51, 0x3d, 0x03, 0x2c, 0x13, 0x6b, 0xf1, 0x42, 0x6e, 0xe2, 0xb7, 0x12, 0xa0, 0xdd, 0x50, 0x9f, 0x4f, 0x6f, 0xa7, 0x6f, 0xc7, 0x03, 0x61, 0xa0, 0x83, 0xb5, 0xf3, 0x97, 0x98, 0x20, 0x9c, 0x44, 0xea, 0xd0, 0xad, 0x48, 0x64, 0x90, 0x21, 0xd8, 0x9f, 0xa7, 0xa6, 0x44, 0xca, 0x99, 0xc6, 0x36, 0xcb, 0x74, 0x5d, 0x7e, 0x5b, 0xfe, 0x31, 0x6a, 0x31, 0xf3, 0x8c, 0xd0, 0xad, 0x40, 0xa3, 0x1f, 0x7c, 0x44, 0xd6, 0x51, 0xd9, 0xe0, 0x5f, 0x9a, 0x7e, 0x41, 0x9f, 0x40, 0xf3, 0x14, 0xba, 0x85, 0xba, 0x34, 0xba, 0x2d, 0xfb, 0x34, 0xd0, 0xcf, 0x4f, 0xb0, 0xce, 0x6a, 0x51, 0xe9, 0xb0, 0x20, 0xf4, 0xf1, 0x19, 0xb2, 0xc3, 0x90, 0x11, 0x4e, 0x97, 0x55, 0x80, 0x83, 0xc4, 0x17, 0x7e, 0x4c, 0x79, 0x19, 0xfc, 0xd1, 0xe7, 0x78, 0x4b, 0x91, 0x1d, 0xae, 0x92, 0xa6, 0xf6, 0x46, 0x75, 0xe4, 0xad, 0x22, 0x1f, 0xdd, 0xa1, 0x07, 0xb3, 0x1e, 0xfe, 0xd9, 0x92, 0xeb, 0x4b, 0xed, 0xfd, 0x0a, 0xc2, 0x63, 0x27, 0xa4, 0x88, 0x17, 0x60, 0x49, 0x35, 0xdc, 0x8e, 0xa5, 0x7d, 0xab, 0xd3, 0x28, 0x90, 0x50, 0xcd, 0xed, 0x2d, 0xda, 0x15, 0x55, 0x51, 0xf1, 0x1a, 0x0a, 0xf7, 0x39, 0x5d, 0xaa, 0x77, 0x6f, 0x01, 0x8e, 0xa7, 0x7d, 0xfa, 0xff, 0x00, 0x66, 0x10, 0xa8, 0xb8, 0x63, 0x76, 0x90, 0xa8, 0x20, 0x06, 0x56, 0xdb, 0x61, 0xda, 0xbd, 0x4f, 0xcb, 0x24, 0x15, 0x0f, 0xf5, 0x66, 0xe5, 0x5f, 0x4c, 0x53, 0xc3, 0xb7, 0xce, 0x99, 0x6b, 0x17, 0xff, 0xd4, 0xf0, 0xec, 0x57, 0x6f, 0x32, 0xa5, 0xa4, 0x43, 0x76, 0x75, 0xa9, 0xf1, 0x03, 0xfa, 0x64, 0x08, 0x6c, 0x8e, 0xfb, 0x3d, 0x7f, 0xcb, 0x16, 0x2b, 0x3d, 0xbc, 0x16, 0xa3, 0x66, 0x6d, 0x98, 0xfb, 0x1e, 0xb9, 0xac, 0xc8, 0x77, 0xb7, 0x7d, 0x01, 0xb3, 0x37, 0xb8, 0xd3, 0x46, 0x95, 0x68, 0x86, 0xd2, 0x2e, 0x4e, 0xab, 0xf0, 0x23, 0x11, 0x4e, 0x5f, 0xcd, 0x98, 0xe7, 0x25, 0x96, 0x71, 0x83, 0x0f, 0xd6, 0x3c, 0xb9, 0xe7, 0x0d, 0x7c, 0x41, 0x22, 0x5e, 0xb3, 0x20, 0x0c, 0x65, 0x80, 0xc8, 0x63, 0x8e, 0xbb, 0x95, 0xa5, 0x07, 0xeb, 0xcc, 0xac, 0x73, 0x83, 0x4e, 0x5c, 0x59, 0x09, 0xd8, 0xec, 0xc8, 0x57, 0x41, 0xd3, 0x4e, 0x95, 0xa5, 0x5b, 0x4b, 0x6a, 0xcb, 0xab, 0x43, 0x10, 0x4b, 0xeb, 0x85, 0xa2, 0x2c, 0x8e, 0x3f, 0x68, 0x54, 0xf5, 0x00, 0xd3, 0x97, 0x7a, 0x65, 0x79, 0xa6, 0x24, 0x76, 0x6f, 0xd3, 0x62, 0x96, 0x30, 0x78, 0xcb, 0x21, 0xf2, 0xf4, 0x22, 0xce, 0x54, 0x8e, 0x46, 0x26, 0x10, 0x7e, 0x0a, 0xf5, 0xd8, 0xf5, 0x1f, 0x31, 0x98, 0x83, 0x73, 0xb3, 0x91, 0xcd, 0x67, 0xe6, 0x7d, 0xe8, 0x16, 0x69, 0x6f, 0x10, 0x1f, 0x54, 0x9a, 0x37, 0xf5, 0x41, 0x5e, 0x7f, 0x0a, 0x29, 0x62, 0x02, 0xf8, 0x9c, 0xc8, 0x8c, 0x77, 0x6a, 0x99, 0xa0, 0x89, 0xff, 0x00, 0x9c, 0x74, 0xd2, 0xed, 0xed, 0xfc, 0xbb, 0x7b, 0xaa, 0x9a, 0x7d, 0x62, 0xfe, 0x46, 0x2d, 0xfe, 0x4c, 0x51, 0x31, 0x11, 0xa9, 0xf6, 0xef, 0x9b, 0x30, 0x5e, 0x7b, 0x38, 0xdd, 0xf4, 0x7f, 0x95, 0x94, 0xbc, 0x12, 0x43, 0x30, 0x6a, 0xb2, 0xf3, 0x86, 0x40, 0x3e, 0xcb, 0xd7, 0x6a, 0xd7, 0xb1, 0xe9, 0x8f, 0x37, 0x19, 0x97, 0x41, 0x2c, 0x71, 0x20, 0xf5, 0x36, 0x9c, 0x55, 0x78, 0x1d, 0x8a, 0x91, 0xd7, 0x11, 0x14, 0x5a, 0x3e, 0x19, 0x03, 0x10, 0x6b, 0xca, 0xbd, 0x86, 0xf8, 0x9d, 0x95, 0x18, 0x36, 0x65, 0x2e, 0xbc, 0x54, 0x1f, 0xa2, 0x99, 0x00, 0x59, 0x2a, 0x6f, 0x5e, 0x55, 0x15, 0xe9, 0x5f, 0xc3, 0x2f, 0xb6, 0x14, 0xff, 0x00, 0xff, 0xd5, 0xf1, 0x95, 0xfe, 0x80, 0x74, 0x0d, 0x7c, 0xd9, 0x89, 0x3d, 0x78, 0x57, 0x8b, 0xc5, 0x28, 0xe8, 0x55, 0xf7, 0x1f, 0x48, 0xca, 0x38, 0xb8, 0x83, 0x9f, 0x93, 0x07, 0x85, 0x3a, 0x7a, 0x6f, 0x95, 0x66, 0x2b, 0x2c, 0x4c, 0x0d, 0x14, 0x00, 0x3e, 0x9c, 0xc3, 0x98, 0x76, 0xb8, 0x45, 0xbd, 0x02, 0xde, 0x48, 0xee, 0xdc, 0xa0, 0x15, 0xe2, 0x2b, 0xc8, 0x8a, 0x8a, 0xfd, 0x3b, 0x66, 0x3f, 0x00, 0x73, 0x84, 0x2d, 0x36, 0xb5, 0xb5, 0x9e, 0x35, 0x1c, 0x29, 0xc4, 0xfe, 0xc8, 0x04, 0x7f, 0xc4, 0x69, 0x91, 0xe1, 0x67, 0x2c, 0x4a, 0xd2, 0xe9, 0x4e, 0xe3, 0xd4, 0xf4, 0x81, 0x5a, 0x12, 0xc5, 0x41, 0x3f, 0x79, 0x38, 0x9b, 0x60, 0x20, 0x07, 0x34, 0xb0, 0xc9, 0x03, 0x5c, 0x23, 0x03, 0x53, 0x13, 0x56, 0x88, 0xdf, 0x09, 0xda, 0x9b, 0xd3, 0xb6, 0x52, 0x0e, 0xec, 0xe4, 0x29, 0x24, 0xfc, 0xd0, 0xe7, 0x75, 0xe5, 0x57, 0x6b, 0x61, 0xfb, 0xf0, 0xca, 0xaa, 0x57, 0xa8, 0xe6, 0x78, 0x1a, 0x7d, 0xf9, 0x95, 0x8a, 0x5e, 0xa0, 0xe3, 0x67, 0x8f, 0xa0, 0xbd, 0x5b, 0xf2, 0xdf, 0x4a, 0x82, 0xcb, 0x4a, 0xb3, 0xb0, 0xb4, 0x41, 0x0a, 0x70, 0x48, 0xd9, 0x57, 0x60, 0x51, 0x3a, 0x8f, 0xbc, 0xe6, 0x7b, 0xcb, 0xe4, 0x3b, 0xa7, 0x3f, 0x9b, 0x9f, 0x9a, 0xba, 0x77, 0xe5, 0x5f, 0x95, 0x9c, 0x59, 0x94, 0x9f, 0xcd, 0x37, 0x8c, 0xa9, 0xa6, 0xd9, 0x39, 0xaa, 0xd0, 0x7d, 0xa9, 0x1c, 0x03, 0x5e, 0x09, 0xff, 0x00, 0x0c, 0x76, 0xcb, 0x62, 0x2d, 0xa5, 0xf2, 0x85, 0xbf, 0xe7, 0x87, 0xe6, 0xa3, 0x5e, 0x4d, 0xa8, 0xc9, 0xe6, 0x8b, 0xd5, 0x69, 0x5c, 0xb0, 0x4a, 0xab, 0xc4, 0xb5, 0x35, 0x0a, 0xaa, 0xea, 0x40, 0x03, 0xa0, 0xf6, 0xcb, 0x40, 0x4d, 0x3e, 0xdb, 0xff, 0x00, 0x9c, 0x7f, 0xfc, 0xce, 0x4f, 0xcc, 0xbf, 0x26, 0x25, 0xe5, 0xd3, 0x2f, 0xe9, 0xdd, 0x3d, 0xfe, 0xab, 0xa9, 0xaa, 0xd2, 0xa6, 0x40, 0x2a, 0xb2, 0x71, 0x00, 0x01, 0xea, 0x0d, 0xe8, 0x3a, 0x64, 0x25, 0x16, 0x1c, 0x8b, 0xd9, 0x51, 0x39, 0x28, 0x12, 0x51, 0x41, 0xfd, 0xa3, 0xd2, 0xb9, 0x4f, 0x0d, 0x33, 0xb5, 0xf4, 0x87, 0x9d, 0x79, 0x0e, 0xb4, 0xaf, 0x6a, 0xf8, 0xf1, 0xf0, 0xc9, 0xda, 0xbf, 0xff, 0xd6, 0xf2, 0xc6, 0xb5, 0x68, 0x64, 0xd0, 0x6d, 0x35, 0x20, 0x39, 0xcd, 0x13, 0x0f, 0x5e, 0x61, 0xfc, 0x8f, 0x40, 0x8b, 0x5e, 0xe0, 0x66, 0x1c, 0x4f, 0xaa, 0x9d, 0xe6, 0xa6, 0x1e, 0x91, 0x2e, 0xa9, 0x87, 0x95, 0xee, 0x9c, 0xc5, 0x55, 0x34, 0x60, 0x40, 0xae, 0x57, 0x30, 0xd9, 0xa7, 0x95, 0xbd, 0x6f, 0xcb, 0x26, 0x39, 0x40, 0x0d, 0x4e, 0xc0, 0x9f, 0x9e, 0x50, 0x5d, 0xac, 0x79, 0x33, 0x8b, 0xbb, 0x9b, 0x3b, 0x6b, 0x35, 0x48, 0x54, 0x09, 0x29, 0x56, 0x7f, 0xe1, 0x86, 0x72, 0x00, 0x2c, 0x6e, 0xf7, 0x63, 0x3e, 0x63, 0xbd, 0xbd, 0x5d, 0x20, 0x2a, 0xb3, 0xa4, 0x33, 0x48, 0xab, 0x21, 0x43, 0xf1, 0x2c, 0x47, 0xed, 0x1d, 0xbc, 0x73, 0x18, 0x9b, 0x64, 0x28, 0x96, 0x3a, 0xc7, 0x49, 0xb0, 0xf4, 0xcc, 0xe9, 0x73, 0x6c, 0xb4, 0xf8, 0x67, 0x92, 0x32, 0x21, 0x70, 0x7b, 0x89, 0x05, 0x57, 0xef, 0x38, 0x28, 0x94, 0x4a, 0x7d, 0x13, 0x7d, 0x6a, 0xd3, 0x4c, 0xb8, 0xf2, 0xc3, 0xc8, 0x2e, 0x03, 0xf3, 0xe2, 0x7d, 0x33, 0xb7, 0xc5, 0xcc, 0x71, 0x03, 0xc6, 0xb9, 0x64, 0x06, 0xe2, 0x9a, 0xf2, 0x4f, 0xd2, 0x6d, 0xe9, 0xfe, 0x41, 0x45, 0x5b, 0x18, 0x66, 0xa5, 0x64, 0x09, 0xf4, 0xd5, 0xb7, 0xcd, 0x93, 0xc7, 0xcf, 0x9b, 0xe5, 0x6f, 0xf9, 0xc8, 0x0d, 0x56, 0xeb, 0x59, 0xfc, 0xce, 0xd5, 0x12, 0x61, 0xc4, 0x69, 0xe9, 0x0d, 0xa4, 0x4b, 0xfe, 0x48, 0x40, 0xd5, 0x3e, 0xe4, 0xb6, 0x64, 0x8e, 0x4c, 0x02, 0x61, 0x65, 0xa0, 0x14, 0xb4, 0xb6, 0xb0, 0xb1, 0xb6, 0xb2, 0x97, 0xcb, 0xf1, 0x5a, 0x2d, 0xc6, 0xa5, 0xac, 0xb4, 0x70, 0x5d, 0xc7, 0x3d, 0xc1, 0x51, 0x24, 0x91, 0xc9, 0x31, 0x75, 0x6b, 0x70, 0x9f, 0x14, 0x68, 0x01, 0x46, 0xe4, 0xb5, 0xa3, 0x17, 0xcb, 0x40, 0x61, 0x6f, 0x47, 0xff, 0x00, 0x9c, 0x3a, 0x8f, 0x5b, 0x4f, 0x3c, 0x6b, 0xb7, 0xfa, 0x30, 0x91, 0x3c, 0xa4, 0xb1, 0x95, 0xb9, 0x82, 0x42, 0x0a, 0xbc, 0x8e, 0xe4, 0xdb, 0xa9, 0xef, 0xc9, 0x17, 0x91, 0x24, 0x7c, 0xb2, 0x05, 0x64, 0xfb, 0x75, 0x64, 0x32, 0x39, 0x69, 0x5b, 0x9c, 0xad, 0xb9, 0xdb, 0xa7, 0xb5, 0x3b, 0x53, 0x2a, 0x21, 0x41, 0x44, 0xf3, 0x8b, 0x8f, 0x2e, 0x43, 0x9d, 0x2b, 0xd4, 0x57, 0x23, 0x41, 0x36, 0xff, 0x00, 0xff, 0xd7, 0xf0, 0xc0, 0xd5, 0xb5, 0x11, 0x64, 0xb6, 0x3f, 0x59, 0x90, 0xd9, 0xab, 0x06, 0xf4, 0x79, 0x7c, 0x3b, 0x74, 0xc8, 0x08, 0x8b, 0xb6, 0xe3, 0x96, 0x55, 0x57, 0xb3, 0x3e, 0xf2, 0x35, 0xc7, 0xd6, 0x0b, 0x45, 0x5d, 0xdc, 0x8a, 0x7d, 0xd9, 0x8d, 0x94, 0x3b, 0x3d, 0x1c, 0x9e, 0xc3, 0xe5, 0xc3, 0x2c, 0x7c, 0xc5, 0x0f, 0xee, 0xdb, 0x8b, 0x0c, 0xc4, 0x26, 0x9d, 0xa0, 0x9a, 0x7d, 0x2c, 0xe5, 0xe4, 0x55, 0x7f, 0xee, 0xc1, 0x15, 0x04, 0xd0, 0x12, 0x3c, 0x72, 0x89, 0x1b, 0x2c, 0xcc, 0xa8, 0x2a, 0x8b, 0x87, 0xbb, 0x63, 0x1a, 0x28, 0x65, 0xf0, 0xed, 0xf2, 0xc3, 0xc2, 0x0a, 0x06, 0x4a, 0x46, 0xc7, 0xa5, 0xa3, 0x59, 0xc8, 0xb2, 0xc7, 0x45, 0x22, 0x9c, 0x14, 0x54, 0x10, 0x46, 0xf5, 0x1d, 0x32, 0x5c, 0x14, 0x14, 0xe4, 0x32, 0x2f, 0x3a, 0xf3, 0xb6, 0x90, 0x9a, 0x6d, 0xae, 0x9f, 0x3d, 0xab, 0xb8, 0x8a, 0x3b, 0xf8, 0x39, 0x44, 0x58, 0xf0, 0x08, 0xd5, 0x14, 0xa5, 0x7b, 0x65, 0x98, 0x8e, 0xfb, 0xb5, 0x67, 0x87, 0xa5, 0xef, 0x5e, 0x44, 0x96, 0x35, 0xb5, 0xb6, 0x59, 0x36, 0xfd, 0xd8, 0xa0, 0xf1, 0x20, 0x53, 0x33, 0xc0, 0x79, 0x59, 0x73, 0x7c, 0xd7, 0xf9, 0xfb, 0xa2, 0xcd, 0x67, 0xf9, 0xa7, 0x7b, 0x72, 0xf1, 0x71, 0x83, 0x53, 0x86, 0x0b, 0x98, 0x24, 0x22, 0x8a, 0xcc, 0x88, 0x23, 0x7f, 0xb8, 0xae, 0xf9, 0x7c, 0x50, 0x1e, 0x5f, 0x7c, 0x48, 0x21, 0x44, 0x6b, 0xce, 0x9b, 0xb0, 0x1b, 0x9e, 0xf5, 0xaf, 0x8e, 0x4d, 0x5f, 0x7a, 0x7f, 0xce, 0x34, 0xf9, 0x5d, 0x3c, 0xa3, 0xf9, 0x69, 0x63, 0xa9, 0x3c, 0x27, 0xeb, 0xda, 0xe1, 0x37, 0xd7, 0x2e, 0xaa, 0xdb, 0x06, 0xda, 0x30, 0x49, 0xfe, 0x54, 0x03, 0x03, 0x49, 0xdc, 0xb3, 0xaf, 0x38, 0xfe, 0x6a, 0xf9, 0x47, 0xc9, 0x3a, 0x74, 0x97, 0xfa, 0xf6, 0xaf, 0x15, 0x85, 0xb8, 0x75, 0x89, 0xb8, 0x87, 0x9a, 0x72, 0xee, 0x2a, 0x14, 0x24, 0x60, 0xb1, 0xa8, 0xdf, 0x07, 0x0b, 0x2d, 0xcb, 0xcf, 0x7f, 0xe8, 0x6a, 0xff, 0x00, 0x26, 0xbd, 0x6a, 0x7f, 0x89, 0x2f, 0xf8, 0x52, 0x9e, 0xb7, 0xe8, 0xb9, 0xb8, 0x57, 0xc2, 0x95, 0xe9, 0x8f, 0x08, 0x5a, 0x2f, 0xff, 0xd0, 0xf0, 0x4d, 0x40, 0xaa, 0xd7, 0x00, 0x64, 0xcb, 0x3c, 0x97, 0xa8, 0xb5, 0x9e, 0xa3, 0x1a, 0xd6, 0x84, 0x95, 0x3f, 0x45, 0x72, 0x9c, 0xa2, 0xc3, 0x99, 0xa5, 0x9d, 0x49, 0xf4, 0x17, 0x97, 0xaf, 0x63, 0x17, 0x52, 0x6f, 0xf0, 0xc8, 0x43, 0x6f, 0x9a, 0xe9, 0x07, 0x70, 0x0e, 0xec, 0x83, 0x51, 0x44, 0xb8, 0x61, 0x1a, 0x9e, 0x11, 0xd3, 0x91, 0x60, 0x68, 0x6b, 0xd3, 0x31, 0x4f, 0x36, 0xd3, 0x4c, 0x52, 0xef, 0x4c, 0xd5, 0x0c, 0xc4, 0x69, 0xda, 0x94, 0xc8, 0x3a, 0xf0, 0x66, 0x07, 0x73, 0xe0, 0x40, 0xfd, 0x79, 0x93, 0x12, 0x1c, 0x9c, 0x32, 0xc7, 0xfc, 0x41, 0x33, 0xd2, 0xb4, 0x6f, 0x38, 0x98, 0x65, 0x76, 0xbf, 0x69, 0x42, 0xd0, 0xaa, 0xc9, 0xde, 0x95, 0xad, 0x28, 0x46, 0x4e, 0xac, 0x39, 0x77, 0x80, 0x11, 0xbf, 0xd8, 0xc7, 0x7c, 0xe1, 0xa5, 0xf9, 0x92, 0x4d, 0x32, 0x5b, 0x8b, 0x93, 0x27, 0xa7, 0x68, 0x56, 0xe2, 0x45, 0xda, 0x85, 0x61, 0x6e, 0x67, 0xad, 0x6b, 0xb0, 0x38, 0xc2, 0x81, 0xe4, 0xc7, 0x52, 0x31, 0x1c, 0x67, 0x86, 0x5b, 0xbd, 0x37, 0xca, 0x7a, 0x94, 0xb1, 0x69, 0xb6, 0x2e, 0xb7, 0x15, 0x48, 0xc2, 0xb4, 0x52, 0x53, 0xac, 0x32, 0xaf, 0xb1, 0xed, 0x9b, 0x10, 0x36, 0x78, 0x5c, 0x9f, 0x51, 0x64, 0x1f, 0x98, 0x3e, 0x58, 0xb6, 0xfc, 0xc8, 0xf2, 0xe5, 0xbc, 0x68, 0x52, 0x2d, 0x5a, 0xd1, 0x84, 0xb6, 0xf3, 0x95, 0x0e, 0xc0, 0x85, 0xe2, 0xcb, 0xd8, 0xd1, 0xbb, 0xe4, 0xc1, 0xa6, 0x97, 0xce, 0x17, 0x5f, 0x95, 0xde, 0x6d, 0xb6, 0xbe, 0xb7, 0x69, 0x34, 0xf3, 0x3c, 0x72, 0xcf, 0xe8, 0xa3, 0x45, 0x49, 0x95, 0x4a, 0x90, 0x3e, 0x35, 0x5a, 0x95, 0x1d, 0xfe, 0x21, 0x93, 0x4d, 0xbe, 0xd2, 0xd2, 0xf5, 0x8b, 0xbd, 0x32, 0x2d, 0x3f, 0x4c, 0x9a, 0xe4, 0xca, 0x9e, 0x90, 0x85, 0x65, 0x55, 0x08, 0x85, 0x91, 0x01, 0x3b, 0x0a, 0x05, 0xe9, 0xb0, 0xc0, 0x5a, 0xc3, 0xcd, 0x3f, 0x3b, 0x7f, 0x26, 0xec, 0xff, 0x00, 0x35, 0x6d, 0x6d, 0xb5, 0x3d, 0x16, 0xfe, 0x0d, 0x3b, 0xcd, 0x96, 0x01, 0x92, 0x46, 0x9e, 0xa2, 0x0b, 0xc8, 0xb7, 0x28, 0x92, 0x71, 0xfb, 0x2e, 0xa7, 0xec, 0x3d, 0x0f, 0xc2, 0x68, 0x71, 0x05, 0x95, 0xd3, 0xe7, 0x9f, 0xfa, 0x16, 0x2f, 0xcd, 0x7f, 0x43, 0xd6, 0xfa, 0xa5, 0x97, 0xab, 0xeb, 0x7a, 0x5f, 0x55, 0xfa, 0xec, 0x5e, 0xaf, 0x0f, 0xf7, 0xed, 0x2b, 0x4e, 0x15, 0xff, 0x00, 0x65, 0xdf, 0x8e, 0x14, 0xf1, 0xbf, 0xff, 0xd1, 0xf0, 0x5a, 0xa7, 0x18, 0x5e, 0x56, 0x1f, 0x68, 0x71, 0x5f, 0xa7, 0xbe, 0x2a, 0x98, 0xdb, 0xfa, 0x90, 0x24, 0x37, 0xb0, 0xfd, 0xb8, 0xa8, 0x58, 0x78, 0xae, 0x43, 0xc9, 0xb4, 0x6d, 0xbb, 0xda, 0x3c, 0xa1, 0xad, 0x43, 0xa8, 0xda, 0xc5, 0x2a, 0x3d, 0x26, 0x5a, 0x02, 0x2b, 0xbe, 0x60, 0x64, 0x8d, 0x17, 0x6f, 0x8b, 0x20, 0x90, 0x7a, 0x3c, 0x32, 0x8b, 0xa8, 0x02, 0xf3, 0xfd, 0xe0, 0x1b, 0x11, 0x98, 0x66, 0x3b, 0xb9, 0x62, 0x54, 0x83, 0x36, 0xf2, 0xa4, 0xe4, 0x29, 0x34, 0xeb, 0xc8, 0x74, 0xae, 0x0d, 0xc3, 0x65, 0x82, 0x13, 0x6b, 0x57, 0xba, 0x54, 0xe4, 0x8c, 0x41, 0x1b, 0x75, 0xa7, 0xe0, 0x72, 0x5c, 0x4c, 0x84, 0x50, 0x5a, 0xb3, 0xdd, 0xdd, 0xc3, 0x24, 0x33, 0xb1, 0x60, 0xe0, 0x86, 0x52, 0x45, 0x38, 0xd2, 0x87, 0x24, 0x26, 0x6d, 0x8c, 0xe1, 0x41, 0x25, 0xfc, 0xa3, 0xd7, 0x2f, 0x6f, 0x3c, 0xbf, 0x73, 0xa5, 0xb2, 0x2c, 0xd1, 0x69, 0x17, 0x2f, 0x6b, 0x14, 0x8c, 0x0f, 0x21, 0x0d, 0x79, 0x46, 0x09, 0x15, 0xed, 0xb7, 0x4e, 0xd9, 0xb9, 0x8b, 0xcb, 0xe4, 0xa2, 0x5e, 0xa3, 0xa6, 0xdf, 0x6a, 0x36, 0xe4, 0xcd, 0x69, 0x1c, 0x4e, 0x84, 0x7c, 0x76, 0xab, 0x21, 0x67, 0xa8, 0xa7, 0xd9, 0xf8, 0x4d, 0x2b, 0xf3, 0xc3, 0x4d, 0x49, 0x57, 0x98, 0x75, 0x6f, 0x31, 0xda, 0xf9, 0xa3, 0x4b, 0xfd, 0x1f, 0x69, 0x1d, 0xae, 0xa1, 0xa9, 0x7e, 0xee, 0xe6, 0xd2, 0x79, 0x18, 0xf3, 0xb5, 0x1f, 0xee, 0xd9, 0x0a, 0x01, 0x4e, 0x3f, 0xb3, 0x4d, 0xf2, 0x9c, 0xb9, 0x04, 0x05, 0xb7, 0xe2, 0x87, 0x1e, 0xdd, 0x19, 0x3e, 0xaf, 0x6b, 0xae, 0xcb, 0x6d, 0x13, 0x0d, 0x45, 0xa2, 0x8e, 0x06, 0xe5, 0x13, 0x2a, 0x02, 0x01, 0x5e, 0x82, 0xb5, 0x04, 0xe6, 0x11, 0xd4, 0xcd, 0xda, 0x43, 0x49, 0x8e, 0xb7, 0xdc, 0xb1, 0x51, 0xe6, 0x4d, 0x76, 0xd2, 0x61, 0x15, 0xaa, 0x4b, 0xa8, 0xc9, 0x6e, 0x49, 0x79, 0x20, 0xe6, 0x8c, 0x49, 0xad, 0x43, 0x16, 0xe4, 0xa7, 0xaf, 0x43, 0xd3, 0x26, 0x35, 0x75, 0xcd, 0xa8, 0xe8, 0x87, 0x46, 0xbf, 0xc7, 0x9a, 0xff, 0x00, 0xd6, 0xbf, 0x48, 0xfe, 0x88, 0xfd, 0xe7, 0x0f, 0xab, 0xfa, 0x3f, 0x58, 0x7f, 0x5f, 0x8d, 0x3f, 0x9f, 0xa7, 0x5e, 0xd4, 0xc3, 0xf9, 0xd1, 0x7c, 0xb6, 0x47, 0xe4, 0x3a, 0x5b, 0xff, 0xd2, 0xf0, 0xb7, 0xa6, 0x1e, 0xdf, 0xd3, 0xf6, 0xa5, 0x71, 0x54, 0xdb, 0x4b, 0x80, 0x3c, 0x42, 0x26, 0xee, 0x29, 0xbe, 0x51, 0x23, 0x4e, 0x44, 0x05, 0x84, 0x45, 0xa5, 0xd5, 0xf7, 0x97, 0x2e, 0xfd, 0x6b, 0x6a, 0x98, 0x09, 0xab, 0xc7, 0xfc, 0x46, 0x3b, 0x4c, 0x26, 0x32, 0x30, 0x3e, 0x4f, 0x49, 0xd0, 0xfc, 0xfb, 0x05, 0xd4, 0x4a, 0x7d, 0x40, 0xac, 0x3a, 0x8e, 0x84, 0x1c, 0xc5, 0x96, 0x2a, 0x73, 0xe1, 0x9c, 0x16, 0x6d, 0xa5, 0x79, 0x86, 0xd6, 0xec, 0x80, 0x5a, 0xa0, 0xf5, 0xca, 0xcc, 0x5c, 0xa1, 0x2b, 0x1b, 0x26, 0x30, 0x6a, 0x31, 0x46, 0xcf, 0x1c, 0x87, 0x94, 0x64, 0x9e, 0x3d, 0xb6, 0xf0, 0xca, 0xa8, 0x39, 0x51, 0x99, 0x42, 0x6b, 0x1a, 0xc5, 0xa5, 0xa5, 0x94, 0xf7, 0x92, 0xc8, 0xaa, 0xb1, 0x23, 0x30, 0x04, 0xf8, 0x0e, 0x9f, 0x4e, 0x4a, 0x11, 0xb2, 0xd5, 0x9b, 0x25, 0x06, 0x1b, 0xff, 0x00, 0x38, 0xfd, 0xad, 0xdf, 0xda, 0xf9, 0xa2, 0xfe, 0xc5, 0x42, 0xbe, 0x9b, 0x7f, 0x0b, 0xdd, 0xdd, 0x07, 0xaf, 0x14, 0x68, 0xd8, 0x71, 0x6d, 0xbb, 0x90, 0xfc, 0x73, 0x6e, 0xf2, 0xf2, 0xdd, 0xf4, 0xad, 0xa6, 0xab, 0x6d, 0x69, 0x14, 0xfa, 0xee, 0xa0, 0xe2, 0x0b, 0x0d, 0x39, 0x19, 0xfe, 0x11, 0xc5, 0x1a, 0x4a, 0x1d, 0x8f, 0x73, 0x4f, 0xf8, 0x96, 0x0b, 0x40, 0x8d, 0xec, 0xf3, 0x6d, 0x3f, 0x52, 0xba, 0xd6, 0x35, 0x8b, 0xbf, 0x36, 0x6a, 0x5f, 0x0d, 0xc5, 0xdc, 0xa8, 0xb6, 0xa8, 0x7a, 0xc5, 0x6c, 0x9b, 0x22, 0x0f, 0xa3, 0x73, 0x9a, 0xbc, 0xb3, 0xe2, 0x36, 0xed, 0xb1, 0x43, 0x80, 0x53, 0xd0, 0xa7, 0xd4, 0x44, 0xfa, 0x7a, 0xda, 0x83, 0xbd, 0x3e, 0x2f, 0xa7, 0x2b, 0xad, 0x9b, 0xb8, 0x8d, 0xa8, 0xe8, 0x91, 0xdb, 0xfa, 0x2d, 0x6f, 0xc3, 0x8a, 0x2d, 0x56, 0xa3, 0xad, 0x4f, 0x5c, 0xa4, 0x0d, 0xdc, 0xa3, 0xca, 0xd0, 0xbf, 0xa1, 0xe3, 0xfa, 0xe7, 0x0f, 0xf2, 0xb9, 0x57, 0xbf, 0x1a, 0xe4, 0xb8, 0x57, 0xc5, 0xdd, 0xff, 0xd3, 0xf0, 0xcc, 0x5d, 0x7b, 0x70, 0xc5, 0x53, 0x6d, 0x2f, 0xd5, 0xe4, 0x69, 0xfd, 0xdf, 0xec, 0xd7, 0xad, 0x7d, 0xb2, 0x8c, 0x8d, 0xd8, 0xed, 0x91, 0x9f, 0x43, 0xea, 0xe7, 0xeb, 0x94, 0xad, 0x3e, 0x1e, 0x95, 0xfc, 0x72, 0x81, 0x7d, 0x1c, 0x9d, 0xba, 0xb1, 0x7b, 0xdf, 0xa9, 0x7a, 0xdf, 0xee, 0x2f, 0xd4, 0xfa, 0xe7, 0xed, 0x7a, 0x7f, 0xdd, 0xff, 0x00, 0xb2, 0xae, 0x64, 0x0b, 0xea, 0xe3, 0x9a, 0xbf, 0x4a, 0x6f, 0xa4, 0xff, 0x00, 0x89, 0xbd, 0x45, 0xfa, 0xb5, 0x79, 0xf7, 0xeb, 0xc7, 0xe9, 0xae, 0x57, 0x2e, 0x17, 0x23, 0x1f, 0x89, 0xd1, 0x99, 0x8f, 0xf1, 0xa7, 0x11, 0xcf, 0xd3, 0xf5, 0x29, 0xb5, 0x6b, 0xd3, 0xe8, 0xcc, 0x7f, 0x45, 0xb9, 0xa3, 0xc5, 0x62, 0xbe, 0x68, 0xff, 0x00, 0x15, 0xfd, 0x4c, 0xfe, 0x90, 0xaf, 0xd4, 0xab, 0xf1, 0x7a, 0x7f, 0x62, 0x9d, 0xab, 0xdf, 0x32, 0xb1, 0x70, 0x5e, 0xdc, 0xdc, 0x2d, 0x47, 0x8b, 0x5e, 0xae, 0x4c, 0xbf, 0xf2, 0x37, 0x9f, 0x3d, 0x5b, 0xd2, 0xff, 0x00, 0x8e, 0x87, 0xee, 0x29, 0x5a, 0xf2, 0xf4, 0xaa, 0xd4, 0xa5, 0x36, 0xa7, 0x3a, 0x57, 0xfd, 0x8e, 0x64, 0x3a, 0xf2, 0xf6, 0xbf, 0xcc, 0x7f, 0x5b, 0xfc, 0x23, 0xa7, 0xfe, 0x8e, 0xff, 0x00, 0x8e, 0x37, 0xd6, 0x63, 0xfa, 0xe5, 0x2b, 0xcb, 0x87, 0xec, 0xd6, 0xbd, 0xb9, 0x7d, 0xac, 0xc7, 0xcd, 0x7c, 0x2d, 0xf8, 0x2b, 0x89, 0x26, 0x8f, 0xd4, 0xfa, 0x94, 0x3e, 0x85, 0x29, 0xc9, 0x69, 0xfc, 0x33, 0x58, 0x5d, 0x9c, 0x79, 0xb2, 0xbb, 0x0f, 0xac, 0x7a, 0x2b, 0xea, 0x75, 0xef, 0x92, 0x0c, 0x53, 0x3d, 0x2f, 0xd4, 0xfa, 0xbb, 0xfa, 0x74, 0xf5, 0x39, 0x9a, 0xd7, 0xe7, 0x80, 0x53, 0x79, 0xba, 0x5b, 0xfe, 0x97, 0xfa, 0x4b, 0xfc, 0xba, 0x7f, 0xb1, 0xc7, 0xab, 0x1e, 0x8f, 0xff, 0xd9 -}; diff --git a/webrtc/base/testclient.cc b/webrtc/base/testclient.cc deleted file mode 100644 index 32670e21a..000000000 --- a/webrtc/base/testclient.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/testclient.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { - -// DESIGN: Each packet received is put it into a list of packets. -// Callers can retrieve received packets from any thread by calling -// NextPacket. - -TestClient::TestClient(AsyncPacketSocket* socket) - : socket_(socket), ready_to_send_(false) { - packets_ = new std::vector(); - socket_->SignalReadPacket.connect(this, &TestClient::OnPacket); - socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend); -} - -TestClient::~TestClient() { - delete socket_; - for (unsigned i = 0; i < packets_->size(); i++) - delete (*packets_)[i]; - delete packets_; -} - -bool TestClient::CheckConnState(AsyncPacketSocket::State state) { - // Wait for our timeout value until the socket reaches the desired state. - uint32 end = TimeAfter(kTimeout); - while (socket_->GetState() != state && TimeUntil(end) > 0) - Thread::Current()->ProcessMessages(1); - return (socket_->GetState() == state); -} - -int TestClient::Send(const char* buf, size_t size) { - rtc::PacketOptions options; - return socket_->Send(buf, size, options); -} - -int TestClient::SendTo(const char* buf, size_t size, - const SocketAddress& dest) { - rtc::PacketOptions options; - return socket_->SendTo(buf, size, dest, options); -} - -TestClient::Packet* TestClient::NextPacket() { - // If no packets are currently available, we go into a get/dispatch loop for - // at most 1 second. If, during the loop, a packet arrives, then we can stop - // early and return it. - - // Note that the case where no packet arrives is important. We often want to - // test that a packet does not arrive. - - // Note also that we only try to pump our current thread's message queue. - // Pumping another thread's queue could lead to messages being dispatched from - // the wrong thread to non-thread-safe objects. - - uint32 end = TimeAfter(kTimeout); - while (TimeUntil(end) > 0) { - { - CritScope cs(&crit_); - if (packets_->size() != 0) { - break; - } - } - Thread::Current()->ProcessMessages(1); - } - - // Return the first packet placed in the queue. - Packet* packet = NULL; - CritScope cs(&crit_); - if (packets_->size() > 0) { - packet = packets_->front(); - packets_->erase(packets_->begin()); - } - - return packet; -} - -bool TestClient::CheckNextPacket(const char* buf, size_t size, - SocketAddress* addr) { - bool res = false; - Packet* packet = NextPacket(); - if (packet) { - res = (packet->size == size && memcmp(packet->buf, buf, size) == 0); - if (addr) - *addr = packet->addr; - delete packet; - } - return res; -} - -bool TestClient::CheckNoPacket() { - bool res; - Packet* packet = NextPacket(); - res = (packet == NULL); - delete packet; - return res; -} - -int TestClient::GetError() { - return socket_->GetError(); -} - -int TestClient::SetOption(Socket::Option opt, int value) { - return socket_->SetOption(opt, value); -} - -bool TestClient::ready_to_send() const { - return ready_to_send_; -} - -void TestClient::OnPacket(AsyncPacketSocket* socket, const char* buf, - size_t size, const SocketAddress& remote_addr, - const PacketTime& packet_time) { - CritScope cs(&crit_); - packets_->push_back(new Packet(remote_addr, buf, size)); -} - -void TestClient::OnReadyToSend(AsyncPacketSocket* socket) { - ready_to_send_ = true; -} - -TestClient::Packet::Packet(const SocketAddress& a, const char* b, size_t s) - : addr(a), buf(0), size(s) { - buf = new char[size]; - memcpy(buf, b, size); -} - -TestClient::Packet::Packet(const Packet& p) - : addr(p.addr), buf(0), size(p.size) { - buf = new char[size]; - memcpy(buf, p.buf, size); -} - -TestClient::Packet::~Packet() { - delete[] buf; -} - -} // namespace rtc diff --git a/webrtc/base/testclient.h b/webrtc/base/testclient.h deleted file mode 100644 index d56f948b0..000000000 --- a/webrtc/base/testclient.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TESTCLIENT_H_ -#define WEBRTC_BASE_TESTCLIENT_H_ - -#include -#include "webrtc/base/asyncudpsocket.h" -#include "webrtc/base/criticalsection.h" - -namespace rtc { - -// A simple client that can send TCP or UDP data and check that it receives -// what it expects to receive. Useful for testing server functionality. -class TestClient : public sigslot::has_slots<> { - public: - // Records the contents of a packet that was received. - struct Packet { - Packet(const SocketAddress& a, const char* b, size_t s); - Packet(const Packet& p); - virtual ~Packet(); - - SocketAddress addr; - char* buf; - size_t size; - }; - - // Creates a client that will send and receive with the given socket and - // will post itself messages with the given thread. - explicit TestClient(AsyncPacketSocket* socket); - ~TestClient(); - - SocketAddress address() const { return socket_->GetLocalAddress(); } - SocketAddress remote_address() const { return socket_->GetRemoteAddress(); } - - // Checks that the socket moves to the specified connect state. - bool CheckConnState(AsyncPacketSocket::State state); - - // Checks that the socket is connected to the remote side. - bool CheckConnected() { - return CheckConnState(AsyncPacketSocket::STATE_CONNECTED); - } - - // Sends using the clients socket. - int Send(const char* buf, size_t size); - - // Sends using the clients socket to the given destination. - int SendTo(const char* buf, size_t size, const SocketAddress& dest); - - // Returns the next packet received by the client or 0 if none is received - // within a reasonable amount of time. The caller must delete the packet - // when done with it. - Packet* NextPacket(); - - // Checks that the next packet has the given contents. Returns the remote - // address that the packet was sent from. - bool CheckNextPacket(const char* buf, size_t len, SocketAddress* addr); - - // Checks that no packets have arrived or will arrive in the next second. - bool CheckNoPacket(); - - int GetError(); - int SetOption(Socket::Option opt, int value); - - bool ready_to_send() const; - - private: - static const int kTimeout = 1000; - // Workaround for the fact that AsyncPacketSocket::GetConnState doesn't exist. - Socket::ConnState GetState(); - // Slot for packets read on the socket. - void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t len, - const SocketAddress& remote_addr, - const PacketTime& packet_time); - void OnReadyToSend(AsyncPacketSocket* socket); - - CriticalSection crit_; - AsyncPacketSocket* socket_; - std::vector* packets_; - bool ready_to_send_; - DISALLOW_EVIL_CONSTRUCTORS(TestClient); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_TESTCLIENT_H_ diff --git a/webrtc/base/testclient_unittest.cc b/webrtc/base/testclient_unittest.cc deleted file mode 100644 index c28266867..000000000 --- a/webrtc/base/testclient_unittest.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/nethelpers.h" -#include "webrtc/base/physicalsocketserver.h" -#include "webrtc/base/testclient.h" -#include "webrtc/base/testechoserver.h" -#include "webrtc/base/thread.h" - -using namespace rtc; - -void TestUdpInternal(const SocketAddress& loopback) { - Thread *main = Thread::Current(); - AsyncSocket* socket = main->socketserver() - ->CreateAsyncSocket(loopback.family(), SOCK_DGRAM); - socket->Bind(loopback); - - TestClient client(new AsyncUDPSocket(socket)); - SocketAddress addr = client.address(), from; - EXPECT_EQ(3, client.SendTo("foo", 3, addr)); - EXPECT_TRUE(client.CheckNextPacket("foo", 3, &from)); - EXPECT_EQ(from, addr); - EXPECT_TRUE(client.CheckNoPacket()); -} - -void TestTcpInternal(const SocketAddress& loopback) { - Thread *main = Thread::Current(); - TestEchoServer server(main, loopback); - - AsyncSocket* socket = main->socketserver() - ->CreateAsyncSocket(loopback.family(), SOCK_STREAM); - AsyncTCPSocket* tcp_socket = AsyncTCPSocket::Create( - socket, loopback, server.address()); - ASSERT_TRUE(tcp_socket != NULL); - - TestClient client(tcp_socket); - SocketAddress addr = client.address(), from; - EXPECT_TRUE(client.CheckConnected()); - EXPECT_EQ(3, client.Send("foo", 3)); - EXPECT_TRUE(client.CheckNextPacket("foo", 3, &from)); - EXPECT_EQ(from, server.address()); - EXPECT_TRUE(client.CheckNoPacket()); -} - -// Tests whether the TestClient can send UDP to itself. -TEST(TestClientTest, TestUdpIPv4) { - TestUdpInternal(SocketAddress("127.0.0.1", 0)); -} - -TEST(TestClientTest, TestUdpIPv6) { - if (HasIPv6Enabled()) { - TestUdpInternal(SocketAddress("::1", 0)); - } else { - LOG(LS_INFO) << "Skipping IPv6 test."; - } -} - -// Tests whether the TestClient can connect to a server and exchange data. -TEST(TestClientTest, TestTcpIPv4) { - TestTcpInternal(SocketAddress("127.0.0.1", 0)); -} - -TEST(TestClientTest, TestTcpIPv6) { - if (HasIPv6Enabled()) { - TestTcpInternal(SocketAddress("::1", 0)); - } else { - LOG(LS_INFO) << "Skipping IPv6 test."; - } -} diff --git a/webrtc/base/testechoserver.h b/webrtc/base/testechoserver.h deleted file mode 100644 index 733b320dd..000000000 --- a/webrtc/base/testechoserver.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TESTECHOSERVER_H_ -#define WEBRTC_BASE_TESTECHOSERVER_H_ - -#include -#include "webrtc/base/asynctcpsocket.h" -#include "webrtc/base/socketaddress.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -// A test echo server, echoes back any packets sent to it. -// Useful for unit tests. -class TestEchoServer : public sigslot::has_slots<> { - public: - TestEchoServer(Thread* thread, const SocketAddress& addr) - : server_socket_(thread->socketserver()->CreateAsyncSocket(addr.family(), - SOCK_STREAM)) { - server_socket_->Bind(addr); - server_socket_->Listen(5); - server_socket_->SignalReadEvent.connect(this, &TestEchoServer::OnAccept); - } - ~TestEchoServer() { - for (ClientList::iterator it = client_sockets_.begin(); - it != client_sockets_.end(); ++it) { - delete *it; - } - } - - SocketAddress address() const { return server_socket_->GetLocalAddress(); } - - private: - void OnAccept(AsyncSocket* socket) { - AsyncSocket* raw_socket = socket->Accept(NULL); - if (raw_socket) { - AsyncTCPSocket* packet_socket = new AsyncTCPSocket(raw_socket, false); - packet_socket->SignalReadPacket.connect(this, &TestEchoServer::OnPacket); - packet_socket->SignalClose.connect(this, &TestEchoServer::OnClose); - client_sockets_.push_back(packet_socket); - } - } - void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size, - const SocketAddress& remote_addr, - const PacketTime& packet_time) { - rtc::PacketOptions options; - socket->Send(buf, size, options); - } - void OnClose(AsyncPacketSocket* socket, int err) { - ClientList::iterator it = - std::find(client_sockets_.begin(), client_sockets_.end(), socket); - client_sockets_.erase(it); - Thread::Current()->Dispose(socket); - } - - typedef std::list ClientList; - scoped_ptr server_socket_; - ClientList client_sockets_; - DISALLOW_EVIL_CONSTRUCTORS(TestEchoServer); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_TESTECHOSERVER_H_ diff --git a/webrtc/base/testutils.h b/webrtc/base/testutils.h deleted file mode 100644 index a148d9161..000000000 --- a/webrtc/base/testutils.h +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TESTUTILS_H__ -#define WEBRTC_BASE_TESTUTILS_H__ - -// Utilities for testing rtc infrastructure in unittests - -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) -#include -#include - -// X defines a few macros that stomp on types that gunit.h uses. -#undef None -#undef Bool -#endif - -#include -#include -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/common.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/nethelpers.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/stringencode.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/thread.h" - -namespace testing { - -using namespace rtc; - -/////////////////////////////////////////////////////////////////////////////// -// StreamSink - Monitor asynchronously signalled events from StreamInterface -// or AsyncSocket (which should probably be a StreamInterface. -/////////////////////////////////////////////////////////////////////////////// - -// Note: Any event that is an error is treaded as SSE_ERROR instead of that -// event. - -enum StreamSinkEvent { - SSE_OPEN = SE_OPEN, - SSE_READ = SE_READ, - SSE_WRITE = SE_WRITE, - SSE_CLOSE = SE_CLOSE, - SSE_ERROR = 16 -}; - -class StreamSink : public sigslot::has_slots<> { - public: - void Monitor(StreamInterface* stream) { - stream->SignalEvent.connect(this, &StreamSink::OnEvent); - events_.erase(stream); - } - void Unmonitor(StreamInterface* stream) { - stream->SignalEvent.disconnect(this); - // In case you forgot to unmonitor a previous object with this address - events_.erase(stream); - } - bool Check(StreamInterface* stream, StreamSinkEvent event, bool reset = true) { - return DoCheck(stream, event, reset); - } - int Events(StreamInterface* stream, bool reset = true) { - return DoEvents(stream, reset); - } - - void Monitor(AsyncSocket* socket) { - socket->SignalConnectEvent.connect(this, &StreamSink::OnConnectEvent); - socket->SignalReadEvent.connect(this, &StreamSink::OnReadEvent); - socket->SignalWriteEvent.connect(this, &StreamSink::OnWriteEvent); - socket->SignalCloseEvent.connect(this, &StreamSink::OnCloseEvent); - // In case you forgot to unmonitor a previous object with this address - events_.erase(socket); - } - void Unmonitor(AsyncSocket* socket) { - socket->SignalConnectEvent.disconnect(this); - socket->SignalReadEvent.disconnect(this); - socket->SignalWriteEvent.disconnect(this); - socket->SignalCloseEvent.disconnect(this); - events_.erase(socket); - } - bool Check(AsyncSocket* socket, StreamSinkEvent event, bool reset = true) { - return DoCheck(socket, event, reset); - } - int Events(AsyncSocket* socket, bool reset = true) { - return DoEvents(socket, reset); - } - - private: - typedef std::map EventMap; - - void OnEvent(StreamInterface* stream, int events, int error) { - if (error) { - events = SSE_ERROR; - } - AddEvents(stream, events); - } - void OnConnectEvent(AsyncSocket* socket) { - AddEvents(socket, SSE_OPEN); - } - void OnReadEvent(AsyncSocket* socket) { - AddEvents(socket, SSE_READ); - } - void OnWriteEvent(AsyncSocket* socket) { - AddEvents(socket, SSE_WRITE); - } - void OnCloseEvent(AsyncSocket* socket, int error) { - AddEvents(socket, (0 == error) ? SSE_CLOSE : SSE_ERROR); - } - - void AddEvents(void* obj, int events) { - EventMap::iterator it = events_.find(obj); - if (events_.end() == it) { - events_.insert(EventMap::value_type(obj, events)); - } else { - it->second |= events; - } - } - bool DoCheck(void* obj, StreamSinkEvent event, bool reset) { - EventMap::iterator it = events_.find(obj); - if ((events_.end() == it) || (0 == (it->second & event))) { - return false; - } - if (reset) { - it->second &= ~event; - } - return true; - } - int DoEvents(void* obj, bool reset) { - EventMap::iterator it = events_.find(obj); - if (events_.end() == it) - return 0; - int events = it->second; - if (reset) { - it->second = 0; - } - return events; - } - - EventMap events_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// StreamSource - Implements stream interface and simulates asynchronous -// events on the stream, without a network. Also buffers written data. -/////////////////////////////////////////////////////////////////////////////// - -class StreamSource : public StreamInterface { -public: - StreamSource() { - Clear(); - } - - void Clear() { - readable_data_.clear(); - written_data_.clear(); - state_ = SS_CLOSED; - read_block_ = 0; - write_block_ = SIZE_UNKNOWN; - } - void QueueString(const char* data) { - QueueData(data, strlen(data)); - } - void QueueStringF(const char* format, ...) { - va_list args; - va_start(args, format); - char buffer[1024]; - size_t len = vsprintfn(buffer, sizeof(buffer), format, args); - ASSERT(len < sizeof(buffer) - 1); - va_end(args); - QueueData(buffer, len); - } - void QueueData(const char* data, size_t len) { - readable_data_.insert(readable_data_.end(), data, data + len); - if ((SS_OPEN == state_) && (readable_data_.size() == len)) { - SignalEvent(this, SE_READ, 0); - } - } - std::string ReadData() { - std::string data; - // avoid accessing written_data_[0] if it is undefined - if (written_data_.size() > 0) { - data.insert(0, &written_data_[0], written_data_.size()); - } - written_data_.clear(); - return data; - } - void SetState(StreamState state) { - int events = 0; - if ((SS_OPENING == state_) && (SS_OPEN == state)) { - events |= SE_OPEN; - if (!readable_data_.empty()) { - events |= SE_READ; - } - } else if ((SS_CLOSED != state_) && (SS_CLOSED == state)) { - events |= SE_CLOSE; - } - state_ = state; - if (events) { - SignalEvent(this, events, 0); - } - } - // Will cause Read to block when there are pos bytes in the read queue. - void SetReadBlock(size_t pos) { read_block_ = pos; } - // Will cause Write to block when there are pos bytes in the write queue. - void SetWriteBlock(size_t pos) { write_block_ = pos; } - - virtual StreamState GetState() const { return state_; } - virtual StreamResult Read(void* buffer, size_t buffer_len, - size_t* read, int* error) { - if (SS_CLOSED == state_) { - if (error) *error = -1; - return SR_ERROR; - } - if ((SS_OPENING == state_) || (readable_data_.size() <= read_block_)) { - return SR_BLOCK; - } - size_t count = _min(buffer_len, readable_data_.size() - read_block_); - memcpy(buffer, &readable_data_[0], count); - size_t new_size = readable_data_.size() - count; - // Avoid undefined access beyond the last element of the vector. - // This only happens when new_size is 0. - if (count < readable_data_.size()) { - memmove(&readable_data_[0], &readable_data_[count], new_size); - } - readable_data_.resize(new_size); - if (read) *read = count; - return SR_SUCCESS; - } - virtual StreamResult Write(const void* data, size_t data_len, - size_t* written, int* error) { - if (SS_CLOSED == state_) { - if (error) *error = -1; - return SR_ERROR; - } - if (SS_OPENING == state_) { - return SR_BLOCK; - } - if (SIZE_UNKNOWN != write_block_) { - if (written_data_.size() >= write_block_) { - return SR_BLOCK; - } - if (data_len > (write_block_ - written_data_.size())) { - data_len = write_block_ - written_data_.size(); - } - } - if (written) *written = data_len; - const char* cdata = static_cast(data); - written_data_.insert(written_data_.end(), cdata, cdata + data_len); - return SR_SUCCESS; - } - virtual void Close() { state_ = SS_CLOSED; } - -private: - typedef std::vector Buffer; - Buffer readable_data_, written_data_; - StreamState state_; - size_t read_block_, write_block_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// SocketTestClient -// Creates a simulated client for testing. Works on real and virtual networks. -/////////////////////////////////////////////////////////////////////////////// - -class SocketTestClient : public sigslot::has_slots<> { -public: - SocketTestClient() { - Init(NULL, AF_INET); - } - SocketTestClient(AsyncSocket* socket) { - Init(socket, socket->GetLocalAddress().family()); - } - SocketTestClient(const SocketAddress& address) { - Init(NULL, address.family()); - socket_->Connect(address); - } - - AsyncSocket* socket() { return socket_.get(); } - - void QueueString(const char* data) { - QueueData(data, strlen(data)); - } - void QueueStringF(const char* format, ...) { - va_list args; - va_start(args, format); - char buffer[1024]; - size_t len = vsprintfn(buffer, sizeof(buffer), format, args); - ASSERT(len < sizeof(buffer) - 1); - va_end(args); - QueueData(buffer, len); - } - void QueueData(const char* data, size_t len) { - send_buffer_.insert(send_buffer_.end(), data, data + len); - if (Socket::CS_CONNECTED == socket_->GetState()) { - Flush(); - } - } - std::string ReadData() { - std::string data(&recv_buffer_[0], recv_buffer_.size()); - recv_buffer_.clear(); - return data; - } - - bool IsConnected() const { - return (Socket::CS_CONNECTED == socket_->GetState()); - } - bool IsClosed() const { - return (Socket::CS_CLOSED == socket_->GetState()); - } - -private: - typedef std::vector Buffer; - - void Init(AsyncSocket* socket, int family) { - if (!socket) { - socket = Thread::Current()->socketserver() - ->CreateAsyncSocket(family, SOCK_STREAM); - } - socket_.reset(socket); - socket_->SignalConnectEvent.connect(this, - &SocketTestClient::OnConnectEvent); - socket_->SignalReadEvent.connect(this, &SocketTestClient::OnReadEvent); - socket_->SignalWriteEvent.connect(this, &SocketTestClient::OnWriteEvent); - socket_->SignalCloseEvent.connect(this, &SocketTestClient::OnCloseEvent); - } - - void Flush() { - size_t sent = 0; - while (sent < send_buffer_.size()) { - int result = socket_->Send(&send_buffer_[sent], - send_buffer_.size() - sent); - if (result > 0) { - sent += result; - } else { - break; - } - } - size_t new_size = send_buffer_.size() - sent; - memmove(&send_buffer_[0], &send_buffer_[sent], new_size); - send_buffer_.resize(new_size); - } - - void OnConnectEvent(AsyncSocket* socket) { - if (!send_buffer_.empty()) { - Flush(); - } - } - void OnReadEvent(AsyncSocket* socket) { - char data[64 * 1024]; - int result = socket_->Recv(data, ARRAY_SIZE(data)); - if (result > 0) { - recv_buffer_.insert(recv_buffer_.end(), data, data + result); - } - } - void OnWriteEvent(AsyncSocket* socket) { - if (!send_buffer_.empty()) { - Flush(); - } - } - void OnCloseEvent(AsyncSocket* socket, int error) { - } - - scoped_ptr socket_; - Buffer send_buffer_, recv_buffer_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// SocketTestServer -// Creates a simulated server for testing. Works on real and virtual networks. -/////////////////////////////////////////////////////////////////////////////// - -class SocketTestServer : public sigslot::has_slots<> { - public: - SocketTestServer(const SocketAddress& address) - : socket_(Thread::Current()->socketserver() - ->CreateAsyncSocket(address.family(), SOCK_STREAM)) - { - socket_->SignalReadEvent.connect(this, &SocketTestServer::OnReadEvent); - socket_->Bind(address); - socket_->Listen(5); - } - virtual ~SocketTestServer() { - clear(); - } - - size_t size() const { return clients_.size(); } - SocketTestClient* client(size_t index) const { return clients_[index]; } - SocketTestClient* operator[](size_t index) const { return client(index); } - - void clear() { - for (size_t i=0; i(socket_->Accept(NULL)); - if (!accepted) - return; - clients_.push_back(new SocketTestClient(accepted)); - } - - scoped_ptr socket_; - std::vector clients_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Generic Utilities -/////////////////////////////////////////////////////////////////////////////// - -inline bool ReadFile(const char* filename, std::string* contents) { - FILE* fp = fopen(filename, "rb"); - if (!fp) - return false; - char buffer[1024*64]; - size_t read; - contents->clear(); - while ((read = fread(buffer, 1, sizeof(buffer), fp))) { - contents->append(buffer, read); - } - bool success = (0 != feof(fp)); - fclose(fp); - return success; -} - -/////////////////////////////////////////////////////////////////////////////// -// Unittest predicates which are similar to STREQ, but for raw memory -/////////////////////////////////////////////////////////////////////////////// - -inline AssertionResult CmpHelperMemEq(const char* expected_expression, - const char* expected_length_expression, - const char* actual_expression, - const char* actual_length_expression, - const void* expected, - size_t expected_length, - const void* actual, - size_t actual_length) -{ - if ((expected_length == actual_length) - && (0 == memcmp(expected, actual, expected_length))) { - return AssertionSuccess(); - } - - Message msg; - msg << "Value of: " << actual_expression - << " [" << actual_length_expression << "]"; - if (true) { //!actual_value.Equals(actual_expression)) { - size_t buffer_size = actual_length * 2 + 1; - char* buffer = STACK_ARRAY(char, buffer_size); - hex_encode(buffer, buffer_size, - reinterpret_cast(actual), actual_length); - msg << "\n Actual: " << buffer << " [" << actual_length << "]"; - } - - msg << "\nExpected: " << expected_expression - << " [" << expected_length_expression << "]"; - if (true) { //!expected_value.Equals(expected_expression)) { - size_t buffer_size = expected_length * 2 + 1; - char* buffer = STACK_ARRAY(char, buffer_size); - hex_encode(buffer, buffer_size, - reinterpret_cast(expected), expected_length); - msg << "\nWhich is: " << buffer << " [" << expected_length << "]"; - } - - return AssertionFailure(msg); -} - -inline AssertionResult CmpHelperFileEq(const char* expected_expression, - const char* expected_length_expression, - const char* actual_filename, - const void* expected, - size_t expected_length, - const char* filename) -{ - std::string contents; - if (!ReadFile(filename, &contents)) { - Message msg; - msg << "File '" << filename << "' could not be read."; - return AssertionFailure(msg); - } - return CmpHelperMemEq(expected_expression, expected_length_expression, - actual_filename, "", - expected, expected_length, - contents.c_str(), contents.size()); -} - -#define EXPECT_MEMEQ(expected, expected_length, actual, actual_length) \ - EXPECT_PRED_FORMAT4(::testing::CmpHelperMemEq, expected, expected_length, \ - actual, actual_length) - -#define ASSERT_MEMEQ(expected, expected_length, actual, actual_length) \ - ASSERT_PRED_FORMAT4(::testing::CmpHelperMemEq, expected, expected_length, \ - actual, actual_length) - -#define EXPECT_FILEEQ(expected, expected_length, filename) \ - EXPECT_PRED_FORMAT3(::testing::CmpHelperFileEq, expected, expected_length, \ - filename) - -#define ASSERT_FILEEQ(expected, expected_length, filename) \ - ASSERT_PRED_FORMAT3(::testing::CmpHelperFileEq, expected, expected_length, \ - filename) - -/////////////////////////////////////////////////////////////////////////////// -// Helpers for initializing constant memory with integers in a particular byte -// order -/////////////////////////////////////////////////////////////////////////////// - -#define BYTE_CAST(x) static_cast((x) & 0xFF) - -// Declare a N-bit integer as a little-endian sequence of bytes -#define LE16(x) BYTE_CAST(((uint16)x) >> 0), BYTE_CAST(((uint16)x) >> 8) - -#define LE32(x) BYTE_CAST(((uint32)x) >> 0), BYTE_CAST(((uint32)x) >> 8), \ - BYTE_CAST(((uint32)x) >> 16), BYTE_CAST(((uint32)x) >> 24) - -#define LE64(x) BYTE_CAST(((uint64)x) >> 0), BYTE_CAST(((uint64)x) >> 8), \ - BYTE_CAST(((uint64)x) >> 16), BYTE_CAST(((uint64)x) >> 24), \ - BYTE_CAST(((uint64)x) >> 32), BYTE_CAST(((uint64)x) >> 40), \ - BYTE_CAST(((uint64)x) >> 48), BYTE_CAST(((uint64)x) >> 56) - -// Declare a N-bit integer as a big-endian (Internet) sequence of bytes -#define BE16(x) BYTE_CAST(((uint16)x) >> 8), BYTE_CAST(((uint16)x) >> 0) - -#define BE32(x) BYTE_CAST(((uint32)x) >> 24), BYTE_CAST(((uint32)x) >> 16), \ - BYTE_CAST(((uint32)x) >> 8), BYTE_CAST(((uint32)x) >> 0) - -#define BE64(x) BYTE_CAST(((uint64)x) >> 56), BYTE_CAST(((uint64)x) >> 48), \ - BYTE_CAST(((uint64)x) >> 40), BYTE_CAST(((uint64)x) >> 32), \ - BYTE_CAST(((uint64)x) >> 24), BYTE_CAST(((uint64)x) >> 16), \ - BYTE_CAST(((uint64)x) >> 8), BYTE_CAST(((uint64)x) >> 0) - -// Declare a N-bit integer as a this-endian (local machine) sequence of bytes -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 1 -#endif // BIG_ENDIAN - -#if BIG_ENDIAN -#define TE16 BE16 -#define TE32 BE32 -#define TE64 BE64 -#else // !BIG_ENDIAN -#define TE16 LE16 -#define TE32 LE32 -#define TE64 LE64 -#endif // !BIG_ENDIAN - -/////////////////////////////////////////////////////////////////////////////// - -// Helpers for determining if X/screencasting is available (on linux). - -#define MAYBE_SKIP_SCREENCAST_TEST() \ - if (!testing::IsScreencastingAvailable()) { \ - LOG(LS_WARNING) << "Skipping test, since it doesn't have the requisite " \ - << "X environment for screen capture."; \ - return; \ - } \ - -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) -struct XDisplay { - XDisplay() : display_(XOpenDisplay(NULL)) { } - ~XDisplay() { if (display_) XCloseDisplay(display_); } - bool IsValid() const { return display_ != NULL; } - operator Display*() { return display_; } - private: - Display* display_; -}; -#endif - -// Returns true if screencasting is available. When false, anything that uses -// screencasting features may fail. -inline bool IsScreencastingAvailable() { -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - XDisplay display; - if (!display.IsValid()) { - 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; -} -} // namespace testing - -#endif // WEBRTC_BASE_TESTUTILS_H__ diff --git a/webrtc/base/thread.cc b/webrtc/base/thread.cc deleted file mode 100644 index 0e4f0f35f..000000000 --- a/webrtc/base/thread.cc +++ /dev/null @@ -1,567 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/thread.h" - -#ifndef __has_feature -#define __has_feature(x) 0 // Compatibility with non-clang or LLVM compilers. -#endif // __has_feature - -#if defined(WEBRTC_WIN) -#include -#elif defined(WEBRTC_POSIX) -#include -#endif - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/base/timeutils.h" - -#if !__has_feature(objc_arc) && (defined(WEBRTC_MAC)) -#include "webrtc/base/maccocoathreadhelper.h" -#include "webrtc/base/scoped_autorelease_pool.h" -#endif - -namespace rtc { - -ThreadManager* ThreadManager::Instance() { - LIBJINGLE_DEFINE_STATIC_LOCAL(ThreadManager, thread_manager, ()); - return &thread_manager; -} - -// static -Thread* Thread::Current() { - return ThreadManager::Instance()->CurrentThread(); -} - -#if defined(WEBRTC_POSIX) -ThreadManager::ThreadManager() { - pthread_key_create(&key_, NULL); -#ifndef NO_MAIN_THREAD_WRAPPING - WrapCurrentThread(); -#endif -#if !__has_feature(objc_arc) && (defined(WEBRTC_MAC)) - // Under Automatic Reference Counting (ARC), you cannot use autorelease pools - // directly. Instead, you use @autoreleasepool blocks instead. Also, we are - // maintaining thread safety using immutability within context of GCD dispatch - // queues in this case. - InitCocoaMultiThreading(); -#endif -} - -ThreadManager::~ThreadManager() { -#if __has_feature(objc_arc) - @autoreleasepool -#elif defined(WEBRTC_MAC) - // This is called during exit, at which point apparently no NSAutoreleasePools - // are available; but we might still need them to do cleanup (or we get the - // "no autoreleasepool in place, just leaking" warning when exiting). - ScopedAutoreleasePool pool; -#endif - { - UnwrapCurrentThread(); - pthread_key_delete(key_); - } -} - -Thread *ThreadManager::CurrentThread() { - return static_cast(pthread_getspecific(key_)); -} - -void ThreadManager::SetCurrentThread(Thread *thread) { - pthread_setspecific(key_, thread); -} -#endif - -#if defined(WEBRTC_WIN) -ThreadManager::ThreadManager() { - key_ = TlsAlloc(); -#ifndef NO_MAIN_THREAD_WRAPPING - WrapCurrentThread(); -#endif -} - -ThreadManager::~ThreadManager() { - UnwrapCurrentThread(); - TlsFree(key_); -} - -Thread *ThreadManager::CurrentThread() { - return static_cast(TlsGetValue(key_)); -} - -void ThreadManager::SetCurrentThread(Thread *thread) { - TlsSetValue(key_, thread); -} -#endif - -Thread *ThreadManager::WrapCurrentThread() { - Thread* result = CurrentThread(); - if (NULL == result) { - result = new Thread(); - result->WrapCurrentWithThreadManager(this); - } - return result; -} - -void ThreadManager::UnwrapCurrentThread() { - Thread* t = CurrentThread(); - if (t && !(t->IsOwned())) { - t->UnwrapCurrent(); - delete t; - } -} - -struct ThreadInit { - Thread* thread; - Runnable* runnable; -}; - -Thread::Thread(SocketServer* ss) - : MessageQueue(ss), - priority_(PRIORITY_NORMAL), - started_(false), -#if defined(WEBRTC_WIN) - thread_(NULL), - thread_id_(0), -#endif - owned_(true), - delete_self_when_complete_(false) { - SetName("Thread", this); // default name -} - -Thread::~Thread() { - Stop(); - if (active_) - Clear(NULL); -} - -bool Thread::SleepMs(int milliseconds) { -#if defined(WEBRTC_WIN) - ::Sleep(milliseconds); - return true; -#else - // POSIX has both a usleep() and a nanosleep(), but the former is deprecated, - // so we use nanosleep() even though it has greater precision than necessary. - struct timespec ts; - ts.tv_sec = milliseconds / 1000; - ts.tv_nsec = (milliseconds % 1000) * 1000000; - int ret = nanosleep(&ts, NULL); - if (ret != 0) { - LOG_ERR(LS_WARNING) << "nanosleep() returning early"; - return false; - } - return true; -#endif -} - -bool Thread::SetName(const std::string& name, const void* obj) { - if (started_) return false; - name_ = name; - if (obj) { - char buf[16]; - sprintfn(buf, sizeof(buf), " 0x%p", obj); - name_ += buf; - } - return true; -} - -bool Thread::SetPriority(ThreadPriority priority) { -#if defined(WEBRTC_WIN) - if (started_) { - BOOL ret = FALSE; - if (priority == PRIORITY_NORMAL) { - ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_NORMAL); - } else if (priority == PRIORITY_HIGH) { - ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_HIGHEST); - } else if (priority == PRIORITY_ABOVE_NORMAL) { - ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL); - } else if (priority == PRIORITY_IDLE) { - ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_IDLE); - } - if (!ret) { - return false; - } - } - priority_ = priority; - return true; -#else - // TODO: Implement for Linux/Mac if possible. - if (started_) return false; - priority_ = priority; - return true; -#endif -} - -bool Thread::Start(Runnable* runnable) { - ASSERT(owned_); - if (!owned_) return false; - ASSERT(!started_); - if (started_) return false; - - Restart(); // reset fStop_ if the thread is being restarted - - // Make sure that ThreadManager is created on the main thread before - // we start a new thread. - ThreadManager::Instance(); - - ThreadInit* init = new ThreadInit; - init->thread = this; - init->runnable = runnable; -#if defined(WEBRTC_WIN) - DWORD flags = 0; - if (priority_ != PRIORITY_NORMAL) { - flags = CREATE_SUSPENDED; - } - thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreRun, init, flags, - &thread_id_); - if (thread_) { - started_ = true; - if (priority_ != PRIORITY_NORMAL) { - SetPriority(priority_); - ::ResumeThread(thread_); - } - } else { - return false; - } -#elif defined(WEBRTC_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 - // individual thread (only whole process), so let's not support it. - LOG(LS_WARNING) << "PRIORITY_IDLE not supported"; - } else { - // Set real-time round-robin policy. - if (pthread_attr_setschedpolicy(&attr, SCHED_RR) != 0) { - LOG(LS_ERROR) << "pthread_attr_setschedpolicy"; - } - struct sched_param param; - if (pthread_attr_getschedparam(&attr, ¶m) != 0) { - LOG(LS_ERROR) << "pthread_attr_getschedparam"; - } else { - // The numbers here are arbitrary. - if (priority_ == PRIORITY_HIGH) { - param.sched_priority = 6; // 6 = HIGH - } else { - ASSERT(priority_ == PRIORITY_ABOVE_NORMAL); - param.sched_priority = 4; // 4 = ABOVE_NORMAL - } - if (pthread_attr_setschedparam(&attr, ¶m) != 0) { - LOG(LS_ERROR) << "pthread_attr_setschedparam"; - } - } - } - } -#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; -#endif - return true; -} - -void Thread::Join() { - if (started_) { - ASSERT(!IsCurrent()); -#if defined(WEBRTC_WIN) - WaitForSingleObject(thread_, INFINITE); - CloseHandle(thread_); - thread_ = NULL; - thread_id_ = 0; -#elif defined(WEBRTC_POSIX) - void *pv; - pthread_join(thread_, &pv); -#endif - started_ = false; - } -} - -#if defined(WEBRTC_WIN) -// As seen on MSDN. -// http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.71).aspx -#define MSDEV_SET_THREAD_NAME 0x406D1388 -typedef struct tagTHREADNAME_INFO { - DWORD dwType; - LPCSTR szName; - DWORD dwThreadID; - DWORD dwFlags; -} THREADNAME_INFO; - -void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName) { - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = szThreadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try { - RaiseException(MSDEV_SET_THREAD_NAME, 0, sizeof(info) / sizeof(DWORD), - reinterpret_cast(&info)); - } - __except(EXCEPTION_CONTINUE_EXECUTION) { - } -} -#endif // WEBRTC_WIN - -void* Thread::PreRun(void* pv) { - ThreadInit* init = static_cast(pv); - ThreadManager::Instance()->SetCurrentThread(init->thread); -#if defined(WEBRTC_WIN) - SetThreadName(GetCurrentThreadId(), init->thread->name_.c_str()); -#elif defined(WEBRTC_POSIX) - // TODO: See if naming exists for pthreads. -#endif -#if __has_feature(objc_arc) - @autoreleasepool -#elif defined(WEBRTC_MAC) - // Make sure the new thread has an autoreleasepool - ScopedAutoreleasePool pool; -#endif - { - if (init->runnable) { - init->runnable->Run(init->thread); - } else { - init->thread->Run(); - } - if (init->thread->delete_self_when_complete_) { - init->thread->started_ = false; - delete init->thread; - } - delete init; - return NULL; - } -} - -void Thread::Run() { - ProcessMessages(kForever); -} - -bool Thread::IsOwned() { - return owned_; -} - -void Thread::Stop() { - MessageQueue::Quit(); - Join(); -} - -void Thread::Send(MessageHandler *phandler, uint32 id, MessageData *pdata) { - if (fStop_) - return; - - // Sent messages are sent to the MessageHandler directly, in the context - // of "thread", like Win32 SendMessage. If in the right context, - // call the handler directly. - - Message msg; - msg.phandler = phandler; - msg.message_id = id; - msg.pdata = pdata; - if (IsCurrent()) { - phandler->OnMessage(&msg); - return; - } - - AutoThread thread; - Thread *current_thread = Thread::Current(); - ASSERT(current_thread != NULL); // AutoThread ensures this - - bool ready = false; - { - CritScope cs(&crit_); - EnsureActive(); - _SendMessage smsg; - smsg.thread = current_thread; - smsg.msg = msg; - smsg.ready = &ready; - sendlist_.push_back(smsg); - } - - // Wait for a reply - - ss_->WakeUp(); - - bool waited = false; - crit_.Enter(); - while (!ready) { - crit_.Leave(); - current_thread->ReceiveSends(); - current_thread->socketserver()->Wait(kForever, false); - waited = true; - crit_.Enter(); - } - crit_.Leave(); - - // Our Wait loop above may have consumed some WakeUp events for this - // MessageQueue, that weren't relevant to this Send. Losing these WakeUps can - // cause problems for some SocketServers. - // - // Concrete example: - // Win32SocketServer on thread A calls Send on thread B. While processing the - // message, thread B Posts a message to A. We consume the wakeup for that - // Post while waiting for the Send to complete, which means that when we exit - // this loop, we need to issue another WakeUp, or else the Posted message - // won't be processed in a timely manner. - - if (waited) { - current_thread->socketserver()->WakeUp(); - } -} - -void Thread::ReceiveSends() { - // Receive a sent message. Cleanup scenarios: - // - thread sending exits: We don't allow this, since thread can exit - // only via Join, so Send must complete. - // - thread receiving exits: Wakeup/set ready in Thread::Clear() - // - object target cleared: Wakeup/set ready in Thread::Clear() - crit_.Enter(); - while (!sendlist_.empty()) { - _SendMessage smsg = sendlist_.front(); - sendlist_.pop_front(); - crit_.Leave(); - smsg.msg.phandler->OnMessage(&smsg.msg); - crit_.Enter(); - *smsg.ready = true; - smsg.thread->socketserver()->WakeUp(); - } - crit_.Leave(); -} - -void Thread::Clear(MessageHandler *phandler, uint32 id, - MessageList* removed) { - CritScope cs(&crit_); - - // Remove messages on sendlist_ with phandler - // Object target cleared: remove from send list, wakeup/set ready - // if sender not NULL. - - std::list<_SendMessage>::iterator iter = sendlist_.begin(); - while (iter != sendlist_.end()) { - _SendMessage smsg = *iter; - if (smsg.msg.Match(phandler, id)) { - if (removed) { - removed->push_back(smsg.msg); - } else { - delete smsg.msg.pdata; - } - iter = sendlist_.erase(iter); - *smsg.ready = true; - smsg.thread->socketserver()->WakeUp(); - continue; - } - ++iter; - } - - MessageQueue::Clear(phandler, id, removed); -} - -bool Thread::ProcessMessages(int cmsLoop) { - uint32 msEnd = (kForever == cmsLoop) ? 0 : TimeAfter(cmsLoop); - int cmsNext = cmsLoop; - - while (true) { -#if __has_feature(objc_arc) - @autoreleasepool -#elif defined(WEBRTC_MAC) - // see: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSAutoreleasePool_Class/Reference/Reference.html - // Each thread is supposed to have an autorelease pool. Also for event loops - // like this, autorelease pool needs to be created and drained/released - // for each cycle. - ScopedAutoreleasePool pool; -#endif - { - Message msg; - if (!Get(&msg, cmsNext)) - return !IsQuitting(); - Dispatch(&msg); - - if (cmsLoop != kForever) { - cmsNext = TimeUntil(msEnd); - if (cmsNext < 0) - return true; - } - } - } -} - -bool Thread::WrapCurrent() { - return WrapCurrentWithThreadManager(ThreadManager::Instance()); -} - -bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager) { - if (started_) - return false; -#if defined(WEBRTC_WIN) - // We explicitly ask for no rights other than synchronization. - // This gives us the best chance of succeeding. - thread_ = OpenThread(SYNCHRONIZE, FALSE, GetCurrentThreadId()); - if (!thread_) { - LOG_GLE(LS_ERROR) << "Unable to get handle to thread."; - return false; - } - thread_id_ = GetCurrentThreadId(); -#elif defined(WEBRTC_POSIX) - thread_ = pthread_self(); -#endif - owned_ = false; - started_ = true; - thread_manager->SetCurrentThread(this); - return true; -} - -void Thread::UnwrapCurrent() { - // Clears the platform-specific thread-specific storage. - ThreadManager::Instance()->SetCurrentThread(NULL); -#if defined(WEBRTC_WIN) - if (!CloseHandle(thread_)) { - LOG_GLE(LS_ERROR) << "When unwrapping thread, failed to close handle."; - } -#endif - started_ = false; -} - - -AutoThread::AutoThread(SocketServer* ss) : Thread(ss) { - if (!ThreadManager::Instance()->CurrentThread()) { - ThreadManager::Instance()->SetCurrentThread(this); - } -} - -AutoThread::~AutoThread() { - Stop(); - if (ThreadManager::Instance()->CurrentThread() == this) { - ThreadManager::Instance()->SetCurrentThread(NULL); - } -} - -#if defined(WEBRTC_WIN) -void ComThread::Run() { - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); - ASSERT(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) { - Thread::Run(); - CoUninitialize(); - } else { - LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr; - } -} -#endif - -} // namespace rtc diff --git a/webrtc/base/thread.h b/webrtc/base/thread.h deleted file mode 100644 index 986335d98..000000000 --- a/webrtc/base/thread.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_THREAD_H_ -#define WEBRTC_BASE_THREAD_H_ - -#include -#include -#include -#include - -#if defined(WEBRTC_POSIX) -#include -#endif -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/messagequeue.h" - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#endif - -namespace rtc { - -class Thread; - -class ThreadManager { - public: - ThreadManager(); - ~ThreadManager(); - - static ThreadManager* Instance(); - - Thread* CurrentThread(); - void SetCurrentThread(Thread* thread); - - // Returns a thread object with its thread_ ivar set - // to whatever the OS uses to represent the thread. - // If there already *is* a Thread object corresponding to this thread, - // this method will return that. Otherwise it creates a new Thread - // object whose wrapped() method will return true, and whose - // handle will, on Win32, be opened with only synchronization privileges - - // if you need more privilegs, rather than changing this method, please - // write additional code to adjust the privileges, or call a different - // factory method of your own devising, because this one gets used in - // unexpected contexts (like inside browser plugins) and it would be a - // shame to break it. It is also conceivable on Win32 that we won't even - // be able to get synchronization privileges, in which case the result - // will have a NULL handle. - Thread *WrapCurrentThread(); - void UnwrapCurrentThread(); - - private: -#if defined(WEBRTC_POSIX) - pthread_key_t key_; -#endif - -#if defined(WEBRTC_WIN) - DWORD key_; -#endif - - DISALLOW_COPY_AND_ASSIGN(ThreadManager); -}; - -struct _SendMessage { - _SendMessage() {} - Thread *thread; - Message msg; - bool *ready; -}; - -enum ThreadPriority { - PRIORITY_IDLE = -1, - PRIORITY_NORMAL = 0, - PRIORITY_ABOVE_NORMAL = 1, - PRIORITY_HIGH = 2, -}; - -class Runnable { - public: - virtual ~Runnable() {} - virtual void Run(Thread* thread) = 0; - - protected: - Runnable() {} - - private: - DISALLOW_COPY_AND_ASSIGN(Runnable); -}; - -// WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread(). - -class Thread : public MessageQueue { - public: - explicit Thread(SocketServer* ss = NULL); - // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or - // guarantee Stop() is explicitly called before the subclass is destroyed). - // This is required to avoid a data race between the destructor modifying the - // vtable, and the Thread::PreRun calling the virtual method Run(). - virtual ~Thread(); - - static Thread* Current(); - - bool IsCurrent() const { - return Current() == this; - } - - // Sleeps the calling thread for the specified number of milliseconds, during - // which time no processing is performed. Returns false if sleeping was - // interrupted by a signal (POSIX only). - static bool SleepMs(int millis); - - // Sets the thread's name, for debugging. Must be called before Start(). - // If |obj| is non-NULL, its value is appended to |name|. - const std::string& name() const { return name_; } - bool SetName(const std::string& name, const void* obj); - - // Sets the thread's priority. Must be called before Start(). - ThreadPriority priority() const { return priority_; } - 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 - // underlying OS thread. - virtual void Stop(); - - // By default, Thread::Run() calls ProcessMessages(kForever). To do other - // work, override Run(). To receive and dispatch messages, call - // ProcessMessages occasionally. - virtual void Run(); - - virtual void Send(MessageHandler *phandler, uint32 id = 0, - MessageData *pdata = NULL); - - // Convenience method to invoke a functor on another thread. Caller must - // provide the |ReturnT| template argument, which cannot (easily) be deduced. - // Uses Send() internally, which blocks the current thread until execution - // is complete. - // Ex: bool result = thread.Invoke(&MyFunctionReturningBool); - template - ReturnT Invoke(const FunctorT& functor) { - FunctorMessageHandler handler(functor); - Send(&handler); - return handler.result(); - } - - // From MessageQueue - virtual void Clear(MessageHandler *phandler, uint32 id = MQID_ANY, - MessageList* removed = NULL); - virtual void ReceiveSends(); - - // ProcessMessages will process I/O and dispatch messages until: - // 1) cms milliseconds have elapsed (returns true) - // 2) Stop() is called (returns false) - bool ProcessMessages(int cms); - - // Returns true if this is a thread that we created using the standard - // constructor, false if it was created by a call to - // ThreadManager::WrapCurrentThread(). The main thread of an application - // is generally not owned, since the OS representation of the thread - // obviously exists before we can get to it. - // You cannot call Start on non-owned threads. - bool IsOwned(); - -#if defined(WEBRTC_WIN) - HANDLE GetHandle() const { - return thread_; - } - DWORD GetId() const { - return thread_id_; - } -#elif defined(WEBRTC_POSIX) - pthread_t GetPThread() { - return thread_; - } -#endif - - // This method should be called when thread is created using non standard - // method, like derived implementation of rtc::Thread and it can not be - // started by calling Start(). This will set started flag to true and - // owned to false. This must be called from the current thread. - // NOTE: These methods should be used by the derived classes only, added here - // only for testing. - bool WrapCurrent(); - void UnwrapCurrent(); - - protected: - // Blocks the calling thread until this thread has terminated. - void Join(); - - private: - static void *PreRun(void *pv); - - // ThreadManager calls this instead WrapCurrent() because - // ThreadManager::Instance() cannot be used while ThreadManager is - // being created. - bool WrapCurrentWithThreadManager(ThreadManager* thread_manager); - - std::list<_SendMessage> sendlist_; - std::string name_; - ThreadPriority priority_; - bool started_; - -#if defined(WEBRTC_POSIX) - pthread_t thread_; -#endif - -#if defined(WEBRTC_WIN) - HANDLE thread_; - DWORD thread_id_; -#endif - - bool owned_; - bool delete_self_when_complete_; - - friend class ThreadManager; - - DISALLOW_COPY_AND_ASSIGN(Thread); -}; - -// AutoThread automatically installs itself at construction -// uninstalls at destruction, if a Thread object is -// _not already_ associated with the current OS thread. - -class AutoThread : public Thread { - public: - explicit AutoThread(SocketServer* ss = 0); - virtual ~AutoThread(); - - private: - DISALLOW_COPY_AND_ASSIGN(AutoThread); -}; - -// Win32 extension for threads that need to use COM -#if defined(WEBRTC_WIN) -class ComThread : public Thread { - public: - ComThread() {} - virtual ~ComThread() { Stop(); } - - protected: - virtual void Run(); - - private: - DISALLOW_COPY_AND_ASSIGN(ComThread); -}; -#endif - -// Provides an easy way to install/uninstall a socketserver on a thread. -class SocketServerScope { - public: - explicit SocketServerScope(SocketServer* ss) { - old_ss_ = Thread::Current()->socketserver(); - Thread::Current()->set_socketserver(ss); - } - ~SocketServerScope() { - Thread::Current()->set_socketserver(old_ss_); - } - - private: - SocketServer* old_ss_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(SocketServerScope); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_THREAD_H_ diff --git a/webrtc/base/thread_unittest.cc b/webrtc/base/thread_unittest.cc deleted file mode 100644 index 22eb6bab7..000000000 --- a/webrtc/base/thread_unittest.cc +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/asyncinvoker.h" -#include "webrtc/base/asyncudpsocket.h" -#include "webrtc/base/event.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/physicalsocketserver.h" -#include "webrtc/base/socketaddress.h" -#include "webrtc/base/thread.h" - -#if defined(WEBRTC_WIN) -#include // NOLINT -#endif - -using namespace rtc; - -// Generates a sequence of numbers (collaboratively). -class TestGenerator { - public: - TestGenerator() : last(0), count(0) {} - - int Next(int prev) { - int result = prev + last; - last = result; - count += 1; - return result; - } - - int last; - int count; -}; - -struct TestMessage : public MessageData { - explicit TestMessage(int v) : value(v) {} - virtual ~TestMessage() {} - - int value; -}; - -// Receives on a socket and sends by posting messages. -class SocketClient : public TestGenerator, public sigslot::has_slots<> { - public: - SocketClient(AsyncSocket* socket, const SocketAddress& addr, - Thread* post_thread, MessageHandler* phandler) - : socket_(AsyncUDPSocket::Create(socket, addr)), - post_thread_(post_thread), - post_handler_(phandler) { - socket_->SignalReadPacket.connect(this, &SocketClient::OnPacket); - } - - ~SocketClient() { - delete socket_; - } - - SocketAddress address() const { return socket_->GetLocalAddress(); } - - void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size, - const SocketAddress& remote_addr, - const PacketTime& packet_time) { - EXPECT_EQ(size, sizeof(uint32)); - uint32 prev = reinterpret_cast(buf)[0]; - uint32 result = Next(prev); - - post_thread_->PostDelayed(200, post_handler_, 0, new TestMessage(result)); - } - - private: - AsyncUDPSocket* socket_; - Thread* post_thread_; - MessageHandler* post_handler_; -}; - -// Receives messages and sends on a socket. -class MessageClient : public MessageHandler, public TestGenerator { - public: - MessageClient(Thread* pth, Socket* socket) - : socket_(socket) { - } - - virtual ~MessageClient() { - delete socket_; - } - - virtual void OnMessage(Message *pmsg) { - TestMessage* msg = static_cast(pmsg->pdata); - int result = Next(msg->value); - EXPECT_GE(socket_->Send(&result, sizeof(result)), 0); - delete msg; - } - - private: - Socket* socket_; -}; - -class CustomThread : public rtc::Thread { - public: - CustomThread() {} - virtual ~CustomThread() { Stop(); } - bool Start() { return false; } -}; - - -// A thread that does nothing when it runs and signals an event -// when it is destroyed. -class SignalWhenDestroyedThread : public Thread { - public: - SignalWhenDestroyedThread(Event* event) - : event_(event) { - } - - virtual ~SignalWhenDestroyedThread() { - Stop(); - event_->Set(); - } - - virtual void Run() { - // Do nothing. - } - - private: - Event* event_; -}; - -// Function objects to test Thread::Invoke. -struct FunctorA { - int operator()() { return 42; } -}; -class FunctorB { - public: - 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) { - const SocketAddress addr("127.0.0.1", 0); - - // Create the messaging client on its own thread. - Thread th1; - Socket* socket = th1.socketserver()->CreateAsyncSocket(addr.family(), - SOCK_DGRAM); - MessageClient msg_client(&th1, socket); - - // Create the socket client on its own thread. - Thread th2; - AsyncSocket* asocket = - th2.socketserver()->CreateAsyncSocket(addr.family(), SOCK_DGRAM); - SocketClient sock_client(asocket, addr, &th1, &msg_client); - - socket->Connect(sock_client.address()); - - th1.Start(); - th2.Start(); - - // Get the messages started. - th1.PostDelayed(100, &msg_client, 0, new TestMessage(1)); - - // Give the clients a little while to run. - // Messages will be processed at 100, 300, 500, 700, 900. - Thread* th_main = Thread::Current(); - th_main->ProcessMessages(1000); - - // Stop the sending client. Give the receiver a bit longer to run, in case - // it is running on a machine that is under load (e.g. the build machine). - th1.Stop(); - th_main->ProcessMessages(200); - th2.Stop(); - - // Make sure the results were correct - EXPECT_EQ(5, msg_client.count); - EXPECT_EQ(34, msg_client.last); - EXPECT_EQ(5, sock_client.count); - EXPECT_EQ(55, sock_client.last); -} - -// Test that setting thread names doesn't cause a malfunction. -// There's no easy way to verify the name was set properly at this time. -TEST(ThreadTest, Names) { - // Default name - Thread *thread; - thread = new Thread(); - EXPECT_TRUE(thread->Start()); - thread->Stop(); - delete thread; - thread = new Thread(); - // Name with no object parameter - EXPECT_TRUE(thread->SetName("No object", NULL)); - EXPECT_TRUE(thread->Start()); - thread->Stop(); - delete thread; - // Really long name - thread = new Thread(); - EXPECT_TRUE(thread->SetName("Abcdefghijklmnopqrstuvwxyz1234567890", this)); - EXPECT_TRUE(thread->Start()); - thread->Stop(); - delete thread; -} - -// Test that setting thread priorities doesn't cause a malfunction. -// There's no easy way to verify the priority was set properly at this time. -TEST(ThreadTest, Priorities) { - Thread *thread; - thread = new Thread(); - EXPECT_TRUE(thread->SetPriority(PRIORITY_HIGH)); - EXPECT_TRUE(thread->Start()); - thread->Stop(); - delete thread; - thread = new Thread(); - EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL)); - EXPECT_TRUE(thread->Start()); - thread->Stop(); - delete thread; - - thread = new Thread(); - EXPECT_TRUE(thread->Start()); -#if defined(WEBRTC_WIN) - EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL)); -#else - EXPECT_FALSE(thread->SetPriority(PRIORITY_ABOVE_NORMAL)); -#endif - thread->Stop(); - delete thread; - -} - -TEST(ThreadTest, Wrap) { - Thread* current_thread = Thread::Current(); - current_thread->UnwrapCurrent(); - CustomThread* cthread = new CustomThread(); - EXPECT_TRUE(cthread->WrapCurrent()); - EXPECT_TRUE(cthread->started()); - EXPECT_FALSE(cthread->IsOwned()); - cthread->UnwrapCurrent(); - EXPECT_FALSE(cthread->started()); - 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(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(FunctorA())); - bool called = false; - FunctorB f2(&called); - thread.Invoke(f2); - EXPECT_TRUE(called); - // Try calling bare functions. - struct LocalFuncs { - static int Func1() { return 999; } - static void Func2() {} - }; - EXPECT_EQ(999, thread.Invoke(&LocalFuncs::Func1)); - thread.Invoke(&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(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(&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(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(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(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback, - static_cast(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(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback, - static_cast(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(Thread::Current(), - FunctorB(&flag1)); - invoker.AsyncInvoke(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(Thread::Current(), - FunctorB(&flag1), - 5); - invoker.AsyncInvoke(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); -} - - -#if defined(WEBRTC_WIN) -class ComThreadTest : public testing::Test, public MessageHandler { - public: - ComThreadTest() : done_(false) {} - protected: - virtual void OnMessage(Message* message) { - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); - // S_FALSE means the thread was already inited for a multithread apartment. - EXPECT_EQ(S_FALSE, hr); - if (SUCCEEDED(hr)) { - CoUninitialize(); - } - done_ = true; - } - bool done_; -}; - -TEST_F(ComThreadTest, ComInited) { - Thread* thread = new ComThread(); - EXPECT_TRUE(thread->Start()); - thread->Post(this, 0); - EXPECT_TRUE_WAIT(done_, 1000); - delete thread; -} -#endif diff --git a/webrtc/base/timeutils.cc b/webrtc/base/timeutils.cc deleted file mode 100644 index aefa28518..000000000 --- a/webrtc/base/timeutils.cc +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#if defined(WEBRTC_POSIX) -#include -#if defined(WEBRTC_MAC) -#include -#endif -#endif - -#if defined(WEBRTC_WIN) -#define WIN32_LEAN_AND_MEAN -#include -#include -#endif - -#include "webrtc/base/common.h" -#include "webrtc/base/timeutils.h" - -#define EFFICIENT_IMPLEMENTATION 1 - -namespace rtc { - -const uint32 HALF = 0x80000000; - -uint64 TimeNanos() { - int64 ticks = 0; -#if defined(WEBRTC_MAC) - static mach_timebase_info_data_t timebase; - if (timebase.denom == 0) { - // Get the timebase if this is the first time we run. - // Recommended by Apple's QA1398. - VERIFY(KERN_SUCCESS == mach_timebase_info(&timebase)); - } - // Use timebase to convert absolute time tick units into nanoseconds. - ticks = mach_absolute_time() * timebase.numer / timebase.denom; -#elif defined(WEBRTC_POSIX) - struct timespec ts; - // TODO: Do we need to handle the case when CLOCK_MONOTONIC - // is not supported? - clock_gettime(CLOCK_MONOTONIC, &ts); - ticks = kNumNanosecsPerSec * static_cast(ts.tv_sec) + - static_cast(ts.tv_nsec); -#elif defined(WEBRTC_WIN) - static volatile LONG last_timegettime = 0; - static volatile int64 num_wrap_timegettime = 0; - volatile LONG* last_timegettime_ptr = &last_timegettime; - DWORD now = timeGetTime(); - // Atomically update the last gotten time - DWORD old = InterlockedExchange(last_timegettime_ptr, now); - if (now < old) { - // If now is earlier than old, there may have been a race between - // threads. - // 0x0fffffff ~3.1 days, the code will not take that long to execute - // so it must have been a wrap around. - if (old > 0xf0000000 && now < 0x0fffffff) { - num_wrap_timegettime++; - } - } - ticks = now + (num_wrap_timegettime << 32); - // TODO: Calculate with nanosecond precision. Otherwise, we're just - // wasting a multiply and divide when doing Time() on Windows. - ticks = ticks * kNumNanosecsPerMillisec; -#endif - return ticks; -} - -uint32 Time() { - return static_cast(TimeNanos() / kNumNanosecsPerMillisec); -} - -uint64 TimeMicros() { - return static_cast(TimeNanos() / kNumNanosecsPerMicrosec); -} - -#if defined(WEBRTC_WIN) -static const uint64 kFileTimeToUnixTimeEpochOffset = 116444736000000000ULL; - -struct timeval { - long tv_sec, tv_usec; // NOLINT -}; - -// Emulate POSIX gettimeofday(). -// Based on breakpad/src/third_party/glog/src/utilities.cc -static int gettimeofday(struct timeval *tv, void *tz) { - // FILETIME is measured in tens of microseconds since 1601-01-01 UTC. - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - - LARGE_INTEGER li; - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - - // Convert to seconds and microseconds since Unix time Epoch. - int64 micros = (li.QuadPart - kFileTimeToUnixTimeEpochOffset) / 10; - tv->tv_sec = static_cast(micros / kNumMicrosecsPerSec); // NOLINT - tv->tv_usec = static_cast(micros % kNumMicrosecsPerSec); // NOLINT - - return 0; -} - -// Emulate POSIX gmtime_r(). -static struct tm *gmtime_r(const time_t *timep, struct tm *result) { - // On Windows, gmtime is thread safe. - struct tm *tm = gmtime(timep); // NOLINT - if (tm == NULL) { - return NULL; - } - *result = *tm; - return result; -} -#endif // WEBRTC_WIN - -void CurrentTmTime(struct tm *tm, int *microseconds) { - struct timeval timeval; - if (gettimeofday(&timeval, NULL) < 0) { - // Incredibly unlikely code path. - timeval.tv_sec = timeval.tv_usec = 0; - } - time_t secs = timeval.tv_sec; - gmtime_r(&secs, tm); - *microseconds = timeval.tv_usec; -} - -uint32 TimeAfter(int32 elapsed) { - ASSERT(elapsed >= 0); - ASSERT(static_cast(elapsed) < HALF); - return Time() + elapsed; -} - -bool TimeIsBetween(uint32 earlier, uint32 middle, uint32 later) { - if (earlier <= later) { - return ((earlier <= middle) && (middle <= later)); - } else { - return !((later < middle) && (middle < earlier)); - } -} - -bool TimeIsLaterOrEqual(uint32 earlier, uint32 later) { -#if EFFICIENT_IMPLEMENTATION - int32 diff = later - earlier; - return (diff >= 0 && static_cast(diff) < HALF); -#else - const bool later_or_equal = TimeIsBetween(earlier, later, earlier + HALF); - return later_or_equal; -#endif -} - -bool TimeIsLater(uint32 earlier, uint32 later) { -#if EFFICIENT_IMPLEMENTATION - int32 diff = later - earlier; - return (diff > 0 && static_cast(diff) < HALF); -#else - const bool earlier_or_equal = TimeIsBetween(later, earlier, later + HALF); - return !earlier_or_equal; -#endif -} - -int32 TimeDiff(uint32 later, uint32 earlier) { -#if EFFICIENT_IMPLEMENTATION - return later - earlier; -#else - const bool later_or_equal = TimeIsBetween(earlier, later, earlier + HALF); - if (later_or_equal) { - if (earlier <= later) { - return static_cast(later - earlier); - } else { - return static_cast(later + (UINT32_MAX - earlier) + 1); - } - } else { - if (later <= earlier) { - return -static_cast(earlier - later); - } else { - return -static_cast(earlier + (UINT32_MAX - later) + 1); - } - } -#endif -} - -} // namespace rtc diff --git a/webrtc/base/timeutils.h b/webrtc/base/timeutils.h deleted file mode 100644 index bdf73cc03..000000000 --- a/webrtc/base/timeutils.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2005 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TIMEUTILS_H_ -#define WEBRTC_BASE_TIMEUTILS_H_ - -#include - -#include "webrtc/base/basictypes.h" - -namespace rtc { - -static const int64 kNumMillisecsPerSec = INT64_C(1000); -static const int64 kNumMicrosecsPerSec = INT64_C(1000000); -static const int64 kNumNanosecsPerSec = INT64_C(1000000000); - -static const int64 kNumMicrosecsPerMillisec = kNumMicrosecsPerSec / - kNumMillisecsPerSec; -static const int64 kNumNanosecsPerMillisec = kNumNanosecsPerSec / - kNumMillisecsPerSec; -static const int64 kNumNanosecsPerMicrosec = kNumNanosecsPerSec / - kNumMicrosecsPerSec; - -// January 1970, in NTP milliseconds. -static const int64 kJan1970AsNtpMillisecs = INT64_C(2208988800000); - -typedef uint32 TimeStamp; - -// Returns the current time in milliseconds. -uint32 Time(); -// Returns the current time in microseconds. -uint64 TimeMicros(); -// Returns the current time in nanoseconds. -uint64 TimeNanos(); - -// Stores current time in *tm and microseconds in *microseconds. -void CurrentTmTime(struct tm *tm, int *microseconds); - -// Returns a future timestamp, 'elapsed' milliseconds from now. -uint32 TimeAfter(int32 elapsed); - -// Comparisons between time values, which can wrap around. -bool TimeIsBetween(uint32 earlier, uint32 middle, uint32 later); // Inclusive -bool TimeIsLaterOrEqual(uint32 earlier, uint32 later); // Inclusive -bool TimeIsLater(uint32 earlier, uint32 later); // Exclusive - -// Returns the later of two timestamps. -inline uint32 TimeMax(uint32 ts1, uint32 ts2) { - return TimeIsLaterOrEqual(ts1, ts2) ? ts2 : ts1; -} - -// Returns the earlier of two timestamps. -inline uint32 TimeMin(uint32 ts1, uint32 ts2) { - return TimeIsLaterOrEqual(ts1, ts2) ? ts1 : ts2; -} - -// Number of milliseconds that would elapse between 'earlier' and 'later' -// timestamps. The value is negative if 'later' occurs before 'earlier'. -int32 TimeDiff(uint32 later, uint32 earlier); - -// The number of milliseconds that have elapsed since 'earlier'. -inline int32 TimeSince(uint32 earlier) { - return TimeDiff(Time(), earlier); -} - -// The number of milliseconds that will elapse between now and 'later'. -inline int32 TimeUntil(uint32 later) { - return TimeDiff(later, Time()); -} - -// Converts a unix timestamp in nanoseconds to an NTP timestamp in ms. -inline int64 UnixTimestampNanosecsToNtpMillisecs(int64 unix_ts_ns) { - return unix_ts_ns / kNumNanosecsPerMillisec + kJan1970AsNtpMillisecs; -} - -} // namespace rtc - -#endif // WEBRTC_BASE_TIMEUTILS_H_ diff --git a/webrtc/base/timeutils_unittest.cc b/webrtc/base/timeutils_unittest.cc deleted file mode 100644 index 86a18179c..000000000 --- a/webrtc/base/timeutils_unittest.cc +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/common.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { - -TEST(TimeTest, TimeInMs) { - uint32 ts_earlier = Time(); - Thread::SleepMs(100); - uint32 ts_now = Time(); - // Allow for the thread to wakeup ~20ms early. - EXPECT_GE(ts_now, ts_earlier + 80); - // Make sure the Time is not returning in smaller unit like microseconds. - EXPECT_LT(ts_now, ts_earlier + 1000); -} - -TEST(TimeTest, Comparison) { - // Obtain two different times, in known order - TimeStamp ts_earlier = Time(); - Thread::SleepMs(100); - TimeStamp ts_now = Time(); - EXPECT_NE(ts_earlier, ts_now); - - // Common comparisons - EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_now)); - EXPECT_TRUE( TimeIsLater( ts_earlier, ts_now)); - EXPECT_FALSE(TimeIsLaterOrEqual(ts_now, ts_earlier)); - EXPECT_FALSE(TimeIsLater( ts_now, ts_earlier)); - - // Edge cases - EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_earlier)); - EXPECT_FALSE(TimeIsLater( ts_earlier, ts_earlier)); - - // Obtain a third time - TimeStamp ts_later = TimeAfter(100); - EXPECT_NE(ts_now, ts_later); - EXPECT_TRUE( TimeIsLater(ts_now, ts_later)); - EXPECT_TRUE( TimeIsLater(ts_earlier, ts_later)); - - // Common comparisons - EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_now, ts_later)); - EXPECT_FALSE(TimeIsBetween(ts_earlier, ts_later, ts_now)); - EXPECT_FALSE(TimeIsBetween(ts_now, ts_earlier, ts_later)); - EXPECT_TRUE( TimeIsBetween(ts_now, ts_later, ts_earlier)); - EXPECT_TRUE( TimeIsBetween(ts_later, ts_earlier, ts_now)); - EXPECT_FALSE(TimeIsBetween(ts_later, ts_now, ts_earlier)); - - // Edge cases - EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_earlier)); - EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_later)); - EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_later, ts_later)); - - // Earlier of two times - EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier)); - EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_now)); - EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later)); - EXPECT_EQ(ts_earlier, TimeMin(ts_now, ts_earlier)); - EXPECT_EQ(ts_earlier, TimeMin(ts_later, ts_earlier)); - - // Later of two times - EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier)); - EXPECT_EQ(ts_now, TimeMax(ts_earlier, ts_now)); - EXPECT_EQ(ts_later, TimeMax(ts_earlier, ts_later)); - EXPECT_EQ(ts_now, TimeMax(ts_now, ts_earlier)); - EXPECT_EQ(ts_later, TimeMax(ts_later, ts_earlier)); -} - -TEST(TimeTest, Intervals) { - TimeStamp ts_earlier = Time(); - TimeStamp ts_later = TimeAfter(500); - - // We can't depend on ts_later and ts_earlier to be exactly 500 apart - // since time elapses between the calls to Time() and TimeAfter(500) - EXPECT_LE(500, TimeDiff(ts_later, ts_earlier)); - EXPECT_GE(-500, TimeDiff(ts_earlier, ts_later)); - - // Time has elapsed since ts_earlier - EXPECT_GE(TimeSince(ts_earlier), 0); - - // ts_earlier is earlier than now, so TimeUntil ts_earlier is -ve - EXPECT_LE(TimeUntil(ts_earlier), 0); - - // ts_later likely hasn't happened yet, so TimeSince could be -ve - // but within 500 - EXPECT_GE(TimeSince(ts_later), -500); - - // TimeUntil ts_later is at most 500 - EXPECT_LE(TimeUntil(ts_later), 500); -} - -TEST(TimeTest, BoundaryComparison) { - // Obtain two different times, in known order - TimeStamp ts_earlier = static_cast(-50); - TimeStamp ts_later = ts_earlier + 100; - EXPECT_NE(ts_earlier, ts_later); - - // Common comparisons - EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_later)); - EXPECT_TRUE( TimeIsLater( ts_earlier, ts_later)); - EXPECT_FALSE(TimeIsLaterOrEqual(ts_later, ts_earlier)); - EXPECT_FALSE(TimeIsLater( ts_later, ts_earlier)); - - // Earlier of two times - EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier)); - EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later)); - EXPECT_EQ(ts_earlier, TimeMin(ts_later, ts_earlier)); - - // Later of two times - EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier)); - EXPECT_EQ(ts_later, TimeMax(ts_earlier, ts_later)); - EXPECT_EQ(ts_later, TimeMax(ts_later, ts_earlier)); - - // Interval - EXPECT_EQ(100, TimeDiff(ts_later, ts_earlier)); - EXPECT_EQ(-100, TimeDiff(ts_earlier, ts_later)); -} - -TEST(TimeTest, DISABLED_CurrentTmTime) { - struct tm tm; - int microseconds; - - time_t before = ::time(NULL); - CurrentTmTime(&tm, µseconds); - time_t after = ::time(NULL); - - // Assert that 'tm' represents a time between 'before' and 'after'. - // mktime() uses local time, so we have to compensate for that. - time_t local_delta = before - ::mktime(::gmtime(&before)); // NOLINT - time_t t = ::mktime(&tm) + local_delta; - - EXPECT_TRUE(before <= t && t <= after); - EXPECT_TRUE(0 <= microseconds && microseconds < 1000000); -} - -} // namespace rtc diff --git a/webrtc/base/timing.cc b/webrtc/base/timing.cc deleted file mode 100644 index aa1fc4290..000000000 --- a/webrtc/base/timing.cc +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/timing.h" -#include "webrtc/base/timeutils.h" - -#if defined(WEBRTC_POSIX) -#include -#include -#include -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include -#include -#endif -#elif defined(WEBRTC_WIN) -#include -#include "webrtc/base/win32.h" -#endif - -namespace rtc { - -Timing::Timing() { -#if defined(WEBRTC_WIN) - // This may fail, but we handle failure gracefully in the methods - // that use it (use alternative sleep method). - // - // TODO: Make it possible for user to tell if IdleWait will - // be done at lesser resolution because of this. - timer_handle_ = CreateWaitableTimer(NULL, // Security attributes. - FALSE, // Manual reset? - NULL); // Timer name. -#endif -} - -Timing::~Timing() { -#if defined(WEBRTC_WIN) - if (timer_handle_ != NULL) - CloseHandle(timer_handle_); -#endif -} - -double Timing::WallTimeNow() { -#if defined(WEBRTC_POSIX) - struct timeval time; - gettimeofday(&time, NULL); - // Convert from second (1.0) and microsecond (1e-6). - return (static_cast(time.tv_sec) + - static_cast(time.tv_usec) * 1.0e-6); - -#elif defined(WEBRTC_WIN) - struct _timeb time; - _ftime(&time); - // Convert from second (1.0) and milliseconds (1e-3). - return (static_cast(time.time) + - static_cast(time.millitm) * 1.0e-3); -#endif -} - -double Timing::TimerNow() { - return (static_cast(TimeNanos()) / kNumNanosecsPerSec); -} - -double Timing::BusyWait(double period) { - double start_time = TimerNow(); - while (TimerNow() - start_time < period) { - } - return TimerNow() - start_time; -} - -double Timing::IdleWait(double period) { - double start_time = TimerNow(); - -#if defined(WEBRTC_POSIX) - double sec_int, sec_frac = modf(period, &sec_int); - struct timespec ts; - ts.tv_sec = static_cast(sec_int); - ts.tv_nsec = static_cast(sec_frac * 1.0e9); // NOLINT - - // NOTE(liulk): for the NOLINT above, long is the appropriate POSIX - // type. - - // POSIX nanosleep may be interrupted by signals. - while (nanosleep(&ts, &ts) == -1 && errno == EINTR) { - } - -#elif defined(WEBRTC_WIN) - if (timer_handle_ != NULL) { - LARGE_INTEGER due_time; - - // Negative indicates relative time. The unit is 100 nanoseconds. - due_time.QuadPart = -LONGLONG(period * 1.0e7); - - SetWaitableTimer(timer_handle_, &due_time, 0, NULL, NULL, TRUE); - WaitForSingleObject(timer_handle_, INFINITE); - } else { - // Still attempts to sleep with lesser resolution. - // The unit is in milliseconds. - Sleep(DWORD(period * 1.0e3)); - } -#endif - - return TimerNow() - start_time; -} - -} // namespace rtc diff --git a/webrtc/base/timing.h b/webrtc/base/timing.h deleted file mode 100644 index 58b17a9fb..000000000 --- a/webrtc/base/timing.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TIMING_H_ -#define WEBRTC_BASE_TIMING_H_ - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32.h" -#endif - -namespace rtc { - -class Timing { - public: - Timing(); - virtual ~Timing(); - - // WallTimeNow() returns the current wall-clock time in seconds, - // within 10 milliseconds resolution. - virtual double WallTimeNow(); - - // TimerNow() is like WallTimeNow(), but is monotonically - // increasing. It returns seconds in resolution of 10 microseconds - // or better. Although timer and wall-clock time have the same - // timing unit, they do not necessarily correlate because wall-clock - // time may be adjusted backwards, hence not monotonic. - // Made virtual so we can make a fake one. - virtual double TimerNow(); - - // BusyWait() exhausts CPU as long as the time elapsed is less than - // the specified interval in seconds. Returns the actual waiting - // time based on TimerNow() measurement. - double BusyWait(double period); - - // IdleWait() relinquishes control of CPU for specified period in - // seconds. It uses highest resolution sleep mechanism as possible, - // but does not otherwise guarantee the accuracy. Returns the - // actual waiting time based on TimerNow() measurement. - // - // This function is not re-entrant for an object. Create a fresh - // Timing object for each thread. - double IdleWait(double period); - - private: -#if defined(WEBRTC_WIN) - HANDLE timer_handle_; -#endif -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_TIMING_H_ diff --git a/webrtc/base/transformadapter.cc b/webrtc/base/transformadapter.cc deleted file mode 100644 index 76b750c29..000000000 --- a/webrtc/base/transformadapter.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/transformadapter.h" - -#include - -#include "webrtc/base/common.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// - -TransformAdapter::TransformAdapter(StreamInterface * stream, - TransformInterface * transform, - bool direction_read) - : StreamAdapterInterface(stream), transform_(transform), - direction_read_(direction_read), state_(ST_PROCESSING), len_(0) { -} - -TransformAdapter::~TransformAdapter() { - TransformAdapter::Close(); - delete transform_; -} - -StreamResult -TransformAdapter::Read(void * buffer, size_t buffer_len, - size_t * read, int * error) { - if (!direction_read_) - return SR_EOS; - - while (state_ != ST_ERROR) { - if (state_ == ST_COMPLETE) - return SR_EOS; - - // Buffer more data - if ((state_ == ST_PROCESSING) && (len_ < sizeof(buffer_))) { - size_t subread; - StreamResult result = StreamAdapterInterface::Read( - buffer_ + len_, - sizeof(buffer_) - len_, - &subread, - &error_); - if (result == SR_BLOCK) { - return SR_BLOCK; - } else if (result == SR_ERROR) { - state_ = ST_ERROR; - break; - } else if (result == SR_EOS) { - state_ = ST_FLUSHING; - } else { - len_ += subread; - } - } - - // Process buffered data - size_t in_len = len_; - size_t out_len = buffer_len; - StreamResult result = transform_->Transform(buffer_, &in_len, - buffer, &out_len, - (state_ == ST_FLUSHING)); - ASSERT(result != SR_BLOCK); - if (result == SR_EOS) { - // Note: Don't signal SR_EOS this iteration, unless out_len is zero - state_ = ST_COMPLETE; - } else if (result == SR_ERROR) { - state_ = ST_ERROR; - error_ = -1; // TODO: propagate error - break; - } else if ((out_len == 0) && (state_ == ST_FLUSHING)) { - // If there is no output AND no more input, then something is wrong - state_ = ST_ERROR; - error_ = -1; // TODO: better error code? - break; - } - - len_ -= in_len; - if (len_ > 0) - memmove(buffer_, buffer_ + in_len, len_); - - if (out_len == 0) - continue; - - if (read) - *read = out_len; - return SR_SUCCESS; - } - - if (error) - *error = error_; - return SR_ERROR; -} - -StreamResult -TransformAdapter::Write(const void * data, size_t data_len, - size_t * written, int * error) { - if (direction_read_) - return SR_EOS; - - size_t bytes_written = 0; - while (state_ != ST_ERROR) { - if (state_ == ST_COMPLETE) - return SR_EOS; - - if (len_ < sizeof(buffer_)) { - // Process buffered data - size_t in_len = data_len; - size_t out_len = sizeof(buffer_) - len_; - StreamResult result = transform_->Transform(data, &in_len, - buffer_ + len_, &out_len, - (state_ == ST_FLUSHING)); - - ASSERT(result != SR_BLOCK); - if (result == SR_EOS) { - // Note: Don't signal SR_EOS this iteration, unless no data written - state_ = ST_COMPLETE; - } else if (result == SR_ERROR) { - ASSERT(false); // When this happens, think about what should be done - state_ = ST_ERROR; - error_ = -1; // TODO: propagate error - break; - } - - len_ = out_len; - bytes_written = in_len; - } - - size_t pos = 0; - while (pos < len_) { - size_t subwritten; - StreamResult result = StreamAdapterInterface::Write(buffer_ + pos, - len_ - pos, - &subwritten, - &error_); - if (result == SR_BLOCK) { - ASSERT(false); // TODO: we should handle this - return SR_BLOCK; - } else if (result == SR_ERROR) { - state_ = ST_ERROR; - break; - } else if (result == SR_EOS) { - state_ = ST_COMPLETE; - break; - } - - pos += subwritten; - } - - len_ -= pos; - if (len_ > 0) - memmove(buffer_, buffer_ + pos, len_); - - if (bytes_written == 0) - continue; - - if (written) - *written = bytes_written; - return SR_SUCCESS; - } - - if (error) - *error = error_; - return SR_ERROR; -} - -void -TransformAdapter::Close() { - if (!direction_read_ && (state_ == ST_PROCESSING)) { - state_ = ST_FLUSHING; - do { - Write(0, 0, NULL, NULL); - } while (state_ == ST_FLUSHING); - } - state_ = ST_COMPLETE; - StreamAdapterInterface::Close(); -} - -} // namespace rtc diff --git a/webrtc/base/transformadapter.h b/webrtc/base/transformadapter.h deleted file mode 100644 index ad24438ea..000000000 --- a/webrtc/base/transformadapter.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_TRANSFORMADAPTER_H__ -#define WEBRTC_BASE_TRANSFORMADAPTER_H__ - -#include "webrtc/base/stream.h" - -namespace rtc { -/////////////////////////////////////////////////////////////////////////////// - -class TransformInterface { -public: - virtual ~TransformInterface() { } - - // Transform should convert the in_len bytes of input into the out_len-sized - // output buffer. If flush is true, there will be no more data following - // input. - // After the transformation, in_len contains the number of bytes consumed, and - // out_len contains the number of bytes ready in output. - // Note: Transform should not return SR_BLOCK, as there is no asynchronous - // notification available. - virtual StreamResult Transform(const void * input, size_t * in_len, - void * output, size_t * out_len, - bool flush) = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// - -// TransformAdapter causes all data passed through to be transformed by the -// supplied TransformInterface object, which may apply compression, encryption, -// etc. - -class TransformAdapter : public StreamAdapterInterface { -public: - // Note that the transformation is unidirectional, in the direction specified - // by the constructor. Operations in the opposite direction result in SR_EOS. - TransformAdapter(StreamInterface * stream, - TransformInterface * transform, - bool direction_read); - virtual ~TransformAdapter(); - - virtual StreamResult Read(void * buffer, size_t buffer_len, - size_t * read, int * error); - virtual StreamResult Write(const void * data, size_t data_len, - size_t * written, int * error); - virtual void Close(); - - // Apriori, we can't tell what the transformation does to the stream length. - virtual bool GetAvailable(size_t* size) const { return false; } - virtual bool ReserveSize(size_t size) { return true; } - - // Transformations might not be restartable - virtual bool Rewind() { return false; } - -private: - enum State { ST_PROCESSING, ST_FLUSHING, ST_COMPLETE, ST_ERROR }; - enum { BUFFER_SIZE = 1024 }; - - TransformInterface * transform_; - bool direction_read_; - State state_; - int error_; - - char buffer_[BUFFER_SIZE]; - size_t len_; -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_TRANSFORMADAPTER_H__ diff --git a/webrtc/base/unittest_main.cc b/webrtc/base/unittest_main.cc deleted file mode 100644 index c7adb7931..000000000 --- a/webrtc/base/unittest_main.cc +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2007 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -// -// A reuseable entry point for gunit tests. - -#if defined(WEBRTC_WIN) -#include -#endif - -#include "webrtc/base/flags.h" -#include "webrtc/base/fileutils.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/pathutils.h" - -DEFINE_bool(help, false, "prints this message"); -DEFINE_string(log, "", "logging options to use"); -#if defined(WEBRTC_WIN) -DEFINE_int(crt_break_alloc, -1, "memory allocation to break on"); -DEFINE_bool(default_error_handlers, false, - "leave the default exception/dbg handler functions in place"); - -void TestInvalidParameterHandler(const wchar_t* expression, - const wchar_t* function, - const wchar_t* file, - unsigned int line, - uintptr_t pReserved) { - LOG(LS_ERROR) << "InvalidParameter Handler called. Exiting."; - LOG(LS_ERROR) << expression << std::endl << function << std::endl << file - << std::endl << line; - exit(1); -} -void TestPureCallHandler() { - LOG(LS_ERROR) << "Purecall Handler called. Exiting."; - exit(1); -} -int TestCrtReportHandler(int report_type, char* msg, int* retval) { - LOG(LS_ERROR) << "CrtReport Handler called..."; - LOG(LS_ERROR) << msg; - if (report_type == _CRT_ASSERT) { - exit(1); - } else { - *retval = 0; - return TRUE; - } -} -#endif // WEBRTC_WIN - -rtc::Pathname GetTalkDirectory() { - // Locate talk directory. - rtc::Pathname path = rtc::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 = rtc::Filesystem::GetCurrentDirectory(); - path.AppendFolder("talk"); - // Make sure the folder exist. - if (!rtc::Filesystem::IsFolder(path)) { - path.clear(); - } - } - return path; -} - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - FlagList::SetFlagsFromCommandLine(&argc, argv, false); - if (FLAG_help) { - FlagList::Print(NULL, false); - return 0; - } - -#if defined(WEBRTC_WIN) - if (!FLAG_default_error_handlers) { - // Make sure any errors don't throw dialogs hanging the test run. - _set_invalid_parameter_handler(TestInvalidParameterHandler); - _set_purecall_handler(TestPureCallHandler); - _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestCrtReportHandler); - } - -#ifdef _DEBUG // Turn on memory leak checking on Windows. - _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF |_CRTDBG_LEAK_CHECK_DF); - if (FLAG_crt_break_alloc >= 0) { - _crtBreakAlloc = FLAG_crt_break_alloc; - } -#endif // _DEBUG -#endif // WEBRTC_WIN - - rtc::Filesystem::SetOrganizationName("google"); - rtc::Filesystem::SetApplicationName("unittest"); - - // By default, log timestamps. Allow overrides by used of a --log flag. - rtc::LogMessage::LogTimestamps(); - if (*FLAG_log != '\0') { - rtc::LogMessage::ConfigureLogging(FLAG_log, "unittest.log"); - } - - int res = RUN_ALL_TESTS(); - - // clean up logging so we don't appear to leak memory. - rtc::LogMessage::ConfigureLogging("", ""); - -#if defined(WEBRTC_WIN) - // Unhook crt function so that we don't ever log after statics have been - // uninitialized. - if (!FLAG_default_error_handlers) - _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestCrtReportHandler); -#endif - - return res; -} diff --git a/webrtc/base/unixfilesystem.cc b/webrtc/base/unixfilesystem.cc deleted file mode 100644 index 081d561db..000000000 --- a/webrtc/base/unixfilesystem.cc +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/unixfilesystem.h" - -#include -#include -#include -#include -#include - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include -#include -#include -#include "webrtc/base/macutils.h" -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) - -#if defined(WEBRTC_POSIX) && !defined(WEBRTC_MAC) || defined(WEBRTC_IOS) -#include -#if defined(WEBRTC_ANDROID) -#include -#elif !defined(__native_client__) -#include -#endif // !defined(__native_client__) -#include -#include -#include -#endif // WEBRTC_POSIX && !WEBRTC_MAC || WEBRTC_IOS - -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) -#include -#include -#endif - -#if defined(__native_client__) && !defined(__GLIBC__) -#include -#endif - -#include "webrtc/base/fileutils.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/stringutils.h" - -#if defined(WEBRTC_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(rtc::Pathname* path); -#endif - -namespace rtc { - -#if !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS) -char* UnixFilesystem::app_temp_path_ = NULL; -#else -char* UnixFilesystem::provided_app_data_folder_ = NULL; -char* UnixFilesystem::provided_app_temp_folder_ = NULL; - -void UnixFilesystem::SetAppDataFolder(const std::string& folder) { - delete [] provided_app_data_folder_; - provided_app_data_folder_ = CopyString(folder); -} - -void UnixFilesystem::SetAppTempFolder(const std::string& folder) { - delete [] provided_app_temp_folder_; - provided_app_temp_folder_ = CopyString(folder); -} -#endif - -UnixFilesystem::UnixFilesystem() { -#if defined(WEBRTC_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(); - if ((len == 0) || (pathname[len - 1] != '/')) - return false; - - struct stat st; - int res = ::stat(pathname.c_str(), &st); - if (res == 0) { - // Something exists at this location, check if it is a directory - return S_ISDIR(st.st_mode) != 0; - } else if (errno != ENOENT) { - // Unexpected error - return false; - } - - // Directory doesn't exist, look up one directory level - do { - --len; - } while ((len > 0) && (pathname[len - 1] != '/')); - - if (!CreateFolder(Pathname(pathname.substr(0, len)), mode)) { - return false; - } - - LOG(LS_INFO) << "Creating folder: " << pathname; - return (0 == ::mkdir(pathname.c_str(), mode)); -} - -bool UnixFilesystem::CreateFolder(const Pathname &path) { - return CreateFolder(path, 0755); -} - -FileStream *UnixFilesystem::OpenFile(const Pathname &filename, - const std::string &mode) { - FileStream *fs = new FileStream(); - if (fs && !fs->Open(filename.pathname().c_str(), mode.c_str(), NULL)) { - delete fs; - fs = NULL; - } - return fs; -} - -bool UnixFilesystem::CreatePrivateFile(const Pathname &filename) { - int fd = open(filename.pathname().c_str(), - O_RDWR | O_CREAT | O_EXCL, - S_IRUSR | S_IWUSR); - if (fd < 0) { - LOG_ERR(LS_ERROR) << "open() failed."; - return false; - } - // Don't need to keep the file descriptor. - if (close(fd) < 0) { - LOG_ERR(LS_ERROR) << "close() failed."; - // Continue. - } - return true; -} - -bool UnixFilesystem::DeleteFile(const Pathname &filename) { - LOG(LS_INFO) << "Deleting file:" << filename.pathname(); - - if (!IsFile(filename)) { - ASSERT(IsFile(filename)); - return false; - } - return ::unlink(filename.pathname().c_str()) == 0; -} - -bool UnixFilesystem::DeleteEmptyFolder(const Pathname &folder) { - LOG(LS_INFO) << "Deleting folder" << folder.pathname(); - - if (!IsFolder(folder)) { - ASSERT(IsFolder(folder)); - return false; - } - std::string no_slash(folder.pathname(), 0, folder.pathname().length()-1); - return ::rmdir(no_slash.c_str()) == 0; -} - -bool UnixFilesystem::GetTemporaryFolder(Pathname &pathname, bool create, - const std::string *append) { -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - FSRef fr; - if (0 != FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, - kCreateFolder, &fr)) - return false; - unsigned char buffer[NAME_MAX+1]; - if (0 != FSRefMakePath(&fr, buffer, ARRAY_SIZE(buffer))) - return false; - pathname.SetPathname(reinterpret_cast(buffer), ""); -#elif defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) - ASSERT(provided_app_temp_folder_ != NULL); - pathname.SetPathname(provided_app_temp_folder_, ""); -#else // !WEBRTC_MAC || WEBRTC_IOS && !WEBRTC_ANDROID - if (const char* tmpdir = getenv("TMPDIR")) { - pathname.SetPathname(tmpdir, ""); - } else if (const char* tmp = getenv("TMP")) { - pathname.SetPathname(tmp, ""); - } else { -#ifdef P_tmpdir - pathname.SetPathname(P_tmpdir, ""); -#else // !P_tmpdir - pathname.SetPathname("/tmp/", ""); -#endif // !P_tmpdir - } -#endif // !WEBRTC_MAC || WEBRTC_IOS && !WEBRTC_ANDROID - if (append) { - ASSERT(!append->empty()); - pathname.AppendFolder(*append); - } - return !create || CreateFolder(pathname); -} - -std::string UnixFilesystem::TempFilename(const Pathname &dir, - const std::string &prefix) { - int len = dir.pathname().size() + prefix.size() + 2 + 6; - char *tempname = new char[len]; - - snprintf(tempname, len, "%s/%sXXXXXX", dir.pathname().c_str(), - prefix.c_str()); - int fd = ::mkstemp(tempname); - if (fd != -1) - ::close(fd); - std::string ret(tempname); - delete[] tempname; - - return ret; -} - -bool UnixFilesystem::MoveFile(const Pathname &old_path, - const Pathname &new_path) { - if (!IsFile(old_path)) { - ASSERT(IsFile(old_path)); - return false; - } - LOG(LS_VERBOSE) << "Moving " << old_path.pathname() - << " to " << new_path.pathname(); - if (rename(old_path.pathname().c_str(), new_path.pathname().c_str()) != 0) { - if (errno != EXDEV) - return false; - if (!CopyFile(old_path, new_path)) - return false; - if (!DeleteFile(old_path)) - return false; - } - return true; -} - -bool UnixFilesystem::MoveFolder(const Pathname &old_path, - const Pathname &new_path) { - if (!IsFolder(old_path)) { - ASSERT(IsFolder(old_path)); - return false; - } - LOG(LS_VERBOSE) << "Moving " << old_path.pathname() - << " to " << new_path.pathname(); - if (rename(old_path.pathname().c_str(), new_path.pathname().c_str()) != 0) { - if (errno != EXDEV) - return false; - if (!CopyFolder(old_path, new_path)) - return false; - if (!DeleteFolderAndContents(old_path)) - return false; - } - return true; -} - -bool UnixFilesystem::IsFolder(const Pathname &path) { - struct stat st; - if (stat(path.pathname().c_str(), &st) < 0) - return false; - return S_ISDIR(st.st_mode); -} - -bool UnixFilesystem::CopyFile(const Pathname &old_path, - const Pathname &new_path) { - LOG(LS_VERBOSE) << "Copying " << old_path.pathname() - << " to " << new_path.pathname(); - char buf[256]; - size_t len; - - StreamInterface *source = OpenFile(old_path, "rb"); - if (!source) - return false; - - StreamInterface *dest = OpenFile(new_path, "wb"); - if (!dest) { - delete source; - return false; - } - - while (source->Read(buf, sizeof(buf), &len, NULL) == SR_SUCCESS) - dest->Write(buf, len, NULL, NULL); - - delete source; - delete dest; - return true; -} - -bool UnixFilesystem::IsTemporaryPath(const Pathname& pathname) { -#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) - ASSERT(provided_app_temp_folder_ != NULL); -#endif - - const char* const kTempPrefixes[] = { -#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) - provided_app_temp_folder_, -#else - "/tmp/", "/var/tmp/", -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - "/private/tmp/", "/private/var/tmp/", "/private/var/folders/", -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) -#endif // WEBRTC_ANDROID || WEBRTC_IOS - }; - for (size_t i = 0; i < ARRAY_SIZE(kTempPrefixes); ++i) { - if (0 == strncmp(pathname.pathname().c_str(), kTempPrefixes[i], - strlen(kTempPrefixes[i]))) - return true; - } - return false; -} - -bool UnixFilesystem::IsFile(const Pathname& pathname) { - struct stat st; - int res = ::stat(pathname.pathname().c_str(), &st); - // Treat symlinks, named pipes, etc. all as files. - return res == 0 && !S_ISDIR(st.st_mode); -} - -bool UnixFilesystem::IsAbsent(const Pathname& pathname) { - struct stat st; - int res = ::stat(pathname.pathname().c_str(), &st); - // Note: we specifically maintain ENOTDIR as an error, because that implies - // that you could not call CreateFolder(pathname). - return res != 0 && ENOENT == errno; -} - -bool UnixFilesystem::GetFileSize(const Pathname& pathname, size_t *size) { - struct stat st; - if (::stat(pathname.pathname().c_str(), &st) != 0) - return false; - *size = st.st_size; - return true; -} - -bool UnixFilesystem::GetFileTime(const Pathname& path, FileTimeType which, - time_t* time) { - struct stat st; - if (::stat(path.pathname().c_str(), &st) != 0) - return false; - switch (which) { - case FTT_CREATED: - *time = st.st_ctime; - break; - case FTT_MODIFIED: - *time = st.st_mtime; - break; - case FTT_ACCESSED: - *time = st.st_atime; - break; - default: - return false; - } - return true; -} - -bool UnixFilesystem::GetAppPathname(Pathname* path) { -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - ProcessSerialNumber psn = { 0, kCurrentProcess }; - CFDictionaryRef procinfo = ProcessInformationCopyDictionary(&psn, - kProcessDictionaryIncludeAllInformationMask); - if (NULL == procinfo) - return false; - CFStringRef cfpath = (CFStringRef) CFDictionaryGetValue(procinfo, - kIOBundleExecutableKey); - std::string path8; - bool success = ToUtf8(cfpath, &path8); - CFRelease(procinfo); - if (success) - path->SetPathname(path8); - return success; -#elif defined(__native_client__) - return false; -#elif IOS - IOSAppName(path); - return true; -#else // WEBRTC_MAC && !defined(WEBRTC_IOS) - 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); - return true; -#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) -} - -bool UnixFilesystem::GetAppDataFolder(Pathname* path, bool per_user) { - ASSERT(!organization_name_.empty()); - ASSERT(!application_name_.empty()); - - // First get the base directory for app data. -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - if (per_user) { - // Use ~/Library/Application Support/// - FSRef fr; - if (0 != FSFindFolder(kUserDomain, kApplicationSupportFolderType, - kCreateFolder, &fr)) - return false; - unsigned char buffer[NAME_MAX+1]; - if (0 != FSRefMakePath(&fr, buffer, ARRAY_SIZE(buffer))) - return false; - path->SetPathname(reinterpret_cast(buffer), ""); - } else { - // TODO - return false; - } -#elif defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) // && !WEBRTC_MAC || WEBRTC_IOS - ASSERT(provided_app_data_folder_ != NULL); - path->SetPathname(provided_app_data_folder_, ""); -#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) // && !WEBRTC_MAC && !WEBRTC_IOS && !WEBRTC_ANDROID - if (per_user) { - // We follow the recommendations in - // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html - // It specifies separate directories for data and config files, but - // GetAppDataFolder() does not distinguish. We just return the config dir - // path. - const char* xdg_config_home = getenv("XDG_CONFIG_HOME"); - if (xdg_config_home) { - path->SetPathname(xdg_config_home, ""); - } else { - // XDG says to default to $HOME/.config. We also support falling back to - // other synonyms for HOME if for some reason it is not defined. - const char* homedir; - if (const char* home = getenv("HOME")) { - homedir = home; - } else if (const char* dotdir = getenv("DOTDIR")) { - homedir = dotdir; - } else if (passwd* pw = getpwuid(geteuid())) { - homedir = pw->pw_dir; - } else { - return false; - } - path->SetPathname(homedir, ""); - path->AppendFolder(".config"); - } - } else { - // XDG does not define a standard directory for writable global data. Let's - // just use this. - path->SetPathname("/var/cache/", ""); - } -#endif // !WEBRTC_MAC && !WEBRTC_LINUX - - // Now add on a sub-path for our app. -#if defined(WEBRTC_MAC) || defined(WEBRTC_ANDROID) - path->AppendFolder(organization_name_); - path->AppendFolder(application_name_); -#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - // XDG says to use a single directory level, so we concatenate the org and app - // name with a hyphen. We also do the Linuxy thing and convert to all - // lowercase with no spaces. - std::string subdir(organization_name_); - subdir.append("-"); - subdir.append(application_name_); - replace_substrs(" ", 1, "", 0, &subdir); - std::transform(subdir.begin(), subdir.end(), subdir.begin(), ::tolower); - path->AppendFolder(subdir); -#endif - 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. - if (0 != ::chmod(path->pathname().c_str(), 0700)) { - LOG_ERR(LS_ERROR) << "Can't set mode on " << path; - return false; - } -#endif - return true; -} - -bool UnixFilesystem::GetAppTempFolder(Pathname* path) { -#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) - ASSERT(provided_app_temp_folder_ != NULL); - path->SetPathname(provided_app_temp_folder_); - return true; -#else - ASSERT(!application_name_.empty()); - // TODO: Consider whether we are worried about thread safety. - if (app_temp_path_ != NULL && strlen(app_temp_path_) > 0) { - path->SetPathname(app_temp_path_); - return true; - } - - // Create a random directory as /tmp/-- - char buffer[128]; - sprintfn(buffer, ARRAY_SIZE(buffer), "-%d-%d", - static_cast(getpid()), - static_cast(time(0))); - std::string folder(application_name_); - folder.append(buffer); - if (!GetTemporaryFolder(*path, true, &folder)) - return false; - - delete [] app_temp_path_; - app_temp_path_ = CopyString(path->pathname()); - // TODO: atexit(DeleteFolderAndContents(app_temp_path_)); - return true; -#endif -} - -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 - // symlink, so we don't jump out of the target disk inadvertently. - Pathname existing_path(path.folder(), ""); - while (!existing_path.folder().empty() && IsAbsent(existing_path)) { - existing_path.SetFolder(existing_path.parent_folder()); - } -#if defined(WEBRTC_ANDROID) - struct statfs vfs; - memset(&vfs, 0, sizeof(vfs)); - if (0 != statfs(existing_path.pathname().c_str(), &vfs)) - return false; -#else - struct statvfs vfs; - memset(&vfs, 0, sizeof(vfs)); - if (0 != statvfs(existing_path.pathname().c_str(), &vfs)) - return false; -#endif // WEBRTC_ANDROID -#if defined(WEBRTC_LINUX) - *freebytes = static_cast(vfs.f_bsize) * vfs.f_bavail; -#elif defined(WEBRTC_MAC) - *freebytes = static_cast(vfs.f_frsize) * vfs.f_bavail; -#endif - - return true; -#endif // !__native_client__ -} - -Pathname UnixFilesystem::GetCurrentDirectory() { - Pathname cwd; - char buffer[PATH_MAX]; - char *path = getcwd(buffer, PATH_MAX); - - if (!path) { - LOG_ERR(LS_ERROR) << "getcwd() failed"; - return cwd; // returns empty pathname - } - cwd.SetFolder(std::string(path)); - - return cwd; -} - -char* UnixFilesystem::CopyString(const std::string& str) { - size_t size = str.length() + 1; - - char* buf = new char[size]; - if (!buf) { - return NULL; - } - - strcpyn(buf, size, str.c_str()); - return buf; -} - -} // namespace rtc - -#if defined(__native_client__) -extern "C" int __attribute__((weak)) -link(const char* oldpath, const char* newpath) { - errno = EACCES; - return -1; -} -#endif diff --git a/webrtc/base/unixfilesystem.h b/webrtc/base/unixfilesystem.h deleted file mode 100644 index 7b6c20edd..000000000 --- a/webrtc/base/unixfilesystem.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_UNIXFILESYSTEM_H_ -#define WEBRTC_BASE_UNIXFILESYSTEM_H_ - -#include - -#include "webrtc/base/fileutils.h" - -namespace rtc { - -class UnixFilesystem : public FilesystemInterface { - public: - UnixFilesystem(); - virtual ~UnixFilesystem(); - -#if defined(WEBRTC_ANDROID) || defined(WEBRTC_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. 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 - - // Opens a file. Returns an open StreamInterface if function succeeds. - // Otherwise, returns NULL. - virtual FileStream *OpenFile(const Pathname &filename, - const std::string &mode); - - // Atomically creates an empty file accessible only to the current user if one - // does not already exist at the given path, otherwise fails. - virtual bool CreatePrivateFile(const Pathname &filename); - - // This will attempt to delete the file located at filename. - // It will fail with VERIY if you pass it a non-existant file, or a directory. - virtual bool DeleteFile(const Pathname &filename); - - // This will attempt to delete the folder located at 'folder' - // It ASSERTs and returns false if you pass it a non-existant folder or a - // plain file. - virtual bool DeleteEmptyFolder(const Pathname &folder); - - // Creates a directory. This will call itself recursively to create /foo/bar - // even if /foo does not exist. All created directories are created with the - // given mode. - // Returns TRUE if function succeeds - virtual bool CreateFolder(const Pathname &pathname, mode_t mode); - - // As above, with mode = 0755. - virtual bool CreateFolder(const Pathname &pathname); - - // This moves a file from old_path to new_path, where "file" can be a plain - // file or directory, which will be moved recursively. - // Returns true if function succeeds. - virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path); - virtual bool MoveFolder(const Pathname &old_path, const Pathname &new_path); - - // This copies a file from old_path to _new_path where "file" can be a plain - // file or directory, which will be copied recursively. - // Returns true if function succeeds - virtual bool CopyFile(const Pathname &old_path, const Pathname &new_path); - - // Returns true if a pathname is a directory - virtual bool IsFolder(const Pathname& pathname); - - // Returns true if pathname represents a temporary location on the system. - virtual bool IsTemporaryPath(const Pathname& pathname); - - // Returns true of pathname represents an existing file - virtual bool IsFile(const Pathname& pathname); - - // Returns true if pathname refers to no filesystem object, every parent - // directory either exists, or is also absent. - virtual bool IsAbsent(const Pathname& pathname); - - virtual std::string TempFilename(const Pathname &dir, - const std::string &prefix); - - // A folder appropriate for storing temporary files (Contents are - // automatically deleted when the program exists) - virtual bool GetTemporaryFolder(Pathname &path, bool create, - const std::string *append); - - virtual bool GetFileSize(const Pathname& path, size_t* size); - virtual bool GetFileTime(const Pathname& path, FileTimeType which, - time_t* time); - - // Returns the path to the running application. - virtual bool GetAppPathname(Pathname* path); - - virtual bool GetAppDataFolder(Pathname* path, bool per_user); - - // Get a temporary folder that is unique to the current user and application. - virtual bool GetAppTempFolder(Pathname* path); - - virtual bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes); - - // Returns the absolute path of the current directory. - virtual Pathname GetCurrentDirectory(); - - private: -#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) - static char* provided_app_data_folder_; - static char* provided_app_temp_folder_; -#else - static char* app_temp_path_; -#endif - - static char* CopyString(const std::string& str); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_UNIXFILESYSTEM_H_ diff --git a/webrtc/base/urlencode.cc b/webrtc/base/urlencode.cc deleted file mode 100644 index 5619e05cb..000000000 --- a/webrtc/base/urlencode.cc +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/urlencode.h" - -#include "webrtc/base/common.h" -#include "webrtc/base/stringutils.h" - -static int HexPairValue(const char * code) { - int value = 0; - const char * pch = code; - for (;;) { - int digit = *pch++; - if (digit >= '0' && digit <= '9') { - value += digit - '0'; - } - else if (digit >= 'A' && digit <= 'F') { - value += digit - 'A' + 10; - } - else if (digit >= 'a' && digit <= 'f') { - value += digit - 'a' + 10; - } - else { - return -1; - } - if (pch == code + 2) - return value; - value <<= 4; - } -} - -int InternalUrlDecode(const char *source, char *dest, - bool encode_space_as_plus) { - char * start = dest; - - while (*source) { - switch (*source) { - case '+': - if (encode_space_as_plus) { - *(dest++) = ' '; - } else { - *dest++ = *source; - } - break; - case '%': - if (source[1] && source[2]) { - int value = HexPairValue(source + 1); - if (value >= 0) { - *(dest++) = value; - source += 2; - } - else { - *dest++ = '?'; - } - } - else { - *dest++ = '?'; - } - break; - default: - *dest++ = *source; - } - source++; - } - - *dest = 0; - return static_cast(dest - start); -} - -int UrlDecode(const char *source, char *dest) { - return InternalUrlDecode(source, dest, true); -} - -int UrlDecodeWithoutEncodingSpaceAsPlus(const char *source, char *dest) { - return InternalUrlDecode(source, dest, false); -} - -bool IsValidUrlChar(char ch, bool unsafe_only) { - if (unsafe_only) { - return !(ch <= ' ' || strchr("\\\"^&`<>[]{}", ch)); - } else { - return isalnum(ch) || strchr("-_.!~*'()", ch); - } -} - -int InternalUrlEncode(const char *source, char *dest, unsigned int max, - bool encode_space_as_plus, bool unsafe_only) { - static const char *digits = "0123456789ABCDEF"; - if (max == 0) { - return 0; - } - - char *start = dest; - while (static_cast(dest - start) < max && *source) { - unsigned char ch = static_cast(*source); - if (*source == ' ' && encode_space_as_plus && !unsafe_only) { - *dest++ = '+'; - } else if (IsValidUrlChar(ch, unsafe_only)) { - *dest++ = *source; - } else { - if (static_cast(dest - start) + 4 > max) { - break; - } - *dest++ = '%'; - *dest++ = digits[(ch >> 4) & 0x0F]; - *dest++ = digits[ ch & 0x0F]; - } - source++; - } - ASSERT(static_cast(dest - start) < max); - *dest = 0; - - return static_cast(dest - start); -} - -int UrlEncode(const char *source, char *dest, unsigned max) { - return InternalUrlEncode(source, dest, max, true, false); -} - -int UrlEncodeWithoutEncodingSpaceAsPlus(const char *source, char *dest, - unsigned max) { - return InternalUrlEncode(source, dest, max, false, false); -} - -int UrlEncodeOnlyUnsafeChars(const char *source, char *dest, unsigned max) { - return InternalUrlEncode(source, dest, max, false, true); -} - -std::string -InternalUrlDecodeString(const std::string & encoded, - bool encode_space_as_plus) { - size_t needed_length = encoded.length() + 1; - char* buf = STACK_ARRAY(char, needed_length); - InternalUrlDecode(encoded.c_str(), buf, encode_space_as_plus); - return buf; -} - -std::string -UrlDecodeString(const std::string & encoded) { - return InternalUrlDecodeString(encoded, true); -} - -std::string -UrlDecodeStringWithoutEncodingSpaceAsPlus(const std::string & encoded) { - return InternalUrlDecodeString(encoded, false); -} - -std::string -InternalUrlEncodeString(const std::string & decoded, - bool encode_space_as_plus, - bool unsafe_only) { - int needed_length = static_cast(decoded.length()) * 3 + 1; - char* buf = STACK_ARRAY(char, needed_length); - InternalUrlEncode(decoded.c_str(), buf, needed_length, - encode_space_as_plus, unsafe_only); - return buf; -} - -std::string -UrlEncodeString(const std::string & decoded) { - return InternalUrlEncodeString(decoded, true, false); -} - -std::string -UrlEncodeStringWithoutEncodingSpaceAsPlus(const std::string & decoded) { - return InternalUrlEncodeString(decoded, false, false); -} - -std::string -UrlEncodeStringForOnlyUnsafeChars(const std::string & decoded) { - return InternalUrlEncodeString(decoded, false, true); -} diff --git a/webrtc/base/urlencode.h b/webrtc/base/urlencode.h deleted file mode 100644 index 6195f8380..000000000 --- a/webrtc/base/urlencode.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2008 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef _URLENCODE_H_ -#define _URLENCODE_H_ - -#include - -// Decode all encoded characters. Also decode + as space. -int UrlDecode(const char *source, char *dest); - -// Decode all encoded characters. -int UrlDecodeWithoutEncodingSpaceAsPlus(const char *source, char *dest); - -// Encode all characters except alphas, numbers, and -_.!~*'() -// Also encode space as +. -int UrlEncode(const char *source, char *dest, unsigned max); - -// Encode all characters except alphas, numbers, and -_.!~*'() -int UrlEncodeWithoutEncodingSpaceAsPlus(const char *source, char *dest, - unsigned max); - -// Encode only unsafe chars, including \ "^&`<>[]{} -// Also encode space as %20, instead of + -int UrlEncodeOnlyUnsafeChars(const char *source, char *dest, unsigned max); - -std::string UrlDecodeString(const std::string & encoded); -std::string UrlDecodeStringWithoutEncodingSpaceAsPlus( - const std::string & encoded); -std::string UrlEncodeString(const std::string & decoded); -std::string UrlEncodeStringWithoutEncodingSpaceAsPlus( - const std::string & decoded); -std::string UrlEncodeStringForOnlyUnsafeChars(const std::string & decoded); - -#endif - diff --git a/webrtc/base/urlencode_unittest.cc b/webrtc/base/urlencode_unittest.cc deleted file mode 100644 index 2214fbf2a..000000000 --- a/webrtc/base/urlencode_unittest.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/common.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/urlencode.h" - -TEST(Urlencode, SourceTooLong) { - char source[] = "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" - "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"; - char dest[1]; - ASSERT_EQ(0, UrlEncode(source, dest, ARRAY_SIZE(dest))); - ASSERT_EQ('\0', dest[0]); - - dest[0] = 'a'; - ASSERT_EQ(0, UrlEncode(source, dest, 0)); - ASSERT_EQ('a', dest[0]); -} - -TEST(Urlencode, OneCharacterConversion) { - char source[] = "^"; - char dest[4]; - ASSERT_EQ(3, UrlEncode(source, dest, ARRAY_SIZE(dest))); - ASSERT_STREQ("%5E", dest); -} - -TEST(Urlencode, ShortDestinationNoEncoding) { - // In this case we have a destination that would not be - // big enough to hold an encoding but is big enough to - // hold the text given. - char source[] = "aa"; - char dest[3]; - ASSERT_EQ(2, UrlEncode(source, dest, ARRAY_SIZE(dest))); - ASSERT_STREQ("aa", dest); -} - -TEST(Urlencode, ShortDestinationEncoding) { - // In this case we have a destination that is not - // big enough to hold the encoding. - char source[] = "&"; - char dest[3]; - ASSERT_EQ(0, UrlEncode(source, dest, ARRAY_SIZE(dest))); - ASSERT_EQ('\0', dest[0]); -} - -TEST(Urlencode, Encoding1) { - char source[] = "A^ "; - char dest[8]; - ASSERT_EQ(5, UrlEncode(source, dest, ARRAY_SIZE(dest))); - ASSERT_STREQ("A%5E+", dest); -} - -TEST(Urlencode, Encoding2) { - char source[] = "A^ "; - char dest[8]; - ASSERT_EQ(7, UrlEncodeWithoutEncodingSpaceAsPlus(source, dest, - ARRAY_SIZE(dest))); - ASSERT_STREQ("A%5E%20", dest); -} - -TEST(Urldecode, Decoding1) { - char source[] = "A%5E+"; - char dest[8]; - ASSERT_EQ(3, UrlDecode(source, dest)); - ASSERT_STREQ("A^ ", dest); -} - -TEST(Urldecode, Decoding2) { - char source[] = "A%5E+"; - char dest[8]; - ASSERT_EQ(3, UrlDecodeWithoutEncodingSpaceAsPlus(source, dest)); - ASSERT_STREQ("A^+", dest); -} diff --git a/webrtc/base/versionparsing.cc b/webrtc/base/versionparsing.cc deleted file mode 100644 index c3f982ff6..000000000 --- a/webrtc/base/versionparsing.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/versionparsing.h" - -#include - -namespace rtc { - -bool ParseVersionString(const std::string& version_str, - int num_expected_segments, - int version[]) { - size_t pos = 0; - for (int i = 0;;) { - size_t dot_pos = version_str.find('.', pos); - size_t n; - if (dot_pos == std::string::npos) { - // npos here is a special value meaning "to the end of the string" - n = std::string::npos; - } else { - n = dot_pos - pos; - } - - version[i] = atoi(version_str.substr(pos, n).c_str()); - - if (++i >= num_expected_segments) break; - - if (dot_pos == std::string::npos) { - // Previous segment was not terminated by a dot, but there's supposed to - // be more segments, so that's an error. - return false; - } - pos = dot_pos + 1; - } - return true; -} - -int CompareVersions(const int version1[], - const int version2[], - int num_segments) { - for (int i = 0; i < num_segments; ++i) { - int diff = version1[i] - version2[i]; - if (diff != 0) { - return diff; - } - } - return 0; -} - -} // namespace rtc diff --git a/webrtc/base/versionparsing.h b/webrtc/base/versionparsing.h deleted file mode 100644 index be2d33238..000000000 --- a/webrtc/base/versionparsing.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_VERSIONPARSING_H_ -#define WEBRTC_BASE_VERSIONPARSING_H_ - -#include - -namespace rtc { - -// Parses a version string into an array. "num_expected_segments" must be the -// number of numerical segments that the version is expected to have (e.g., -// "1.1.2.0" has 4). "version" must be an array of that length to hold the -// parsed numbers. -// Returns "true" iff successful. -bool ParseVersionString(const std::string& version_str, - int num_expected_segments, - int version[]); - -// Computes the lexicographical order of two versions. The return value -// indicates the order in the standard way (e.g., see strcmp()). -int CompareVersions(const int version1[], - const int version2[], - int num_segments); - -} // namespace rtc - -#endif // WEBRTC_BASE_VERSIONPARSING_H_ diff --git a/webrtc/base/versionparsing_unittest.cc b/webrtc/base/versionparsing_unittest.cc deleted file mode 100644 index 51156991a..000000000 --- a/webrtc/base/versionparsing_unittest.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/versionparsing.h" - -#include "webrtc/base/gunit.h" - -namespace rtc { - -static const int kExampleSegments = 4; - -typedef int ExampleVersion[kExampleSegments]; - -TEST(VersionParsing, TestGoodParse) { - ExampleVersion ver; - std::string str1("1.1.2.0"); - static const ExampleVersion expect1 = {1, 1, 2, 0}; - EXPECT_TRUE(ParseVersionString(str1, kExampleSegments, ver)); - EXPECT_EQ(0, CompareVersions(ver, expect1, kExampleSegments)); - std::string str2("2.0.0.1"); - static const ExampleVersion expect2 = {2, 0, 0, 1}; - EXPECT_TRUE(ParseVersionString(str2, kExampleSegments, ver)); - EXPECT_EQ(0, CompareVersions(ver, expect2, kExampleSegments)); -} - -TEST(VersionParsing, TestBadParse) { - ExampleVersion ver; - std::string str1("1.1.2"); - EXPECT_FALSE(ParseVersionString(str1, kExampleSegments, ver)); - std::string str2(""); - EXPECT_FALSE(ParseVersionString(str2, kExampleSegments, ver)); - std::string str3("garbarge"); - EXPECT_FALSE(ParseVersionString(str3, kExampleSegments, ver)); -} - -TEST(VersionParsing, TestCompare) { - static const ExampleVersion ver1 = {1, 0, 21, 0}; - static const ExampleVersion ver2 = {1, 1, 2, 0}; - static const ExampleVersion ver3 = {1, 1, 3, 0}; - static const ExampleVersion ver4 = {1, 1, 3, 9861}; - - // Test that every combination of comparisons has the expected outcome. - EXPECT_EQ(0, CompareVersions(ver1, ver1, kExampleSegments)); - EXPECT_EQ(0, CompareVersions(ver2, ver2, kExampleSegments)); - EXPECT_EQ(0, CompareVersions(ver3, ver3, kExampleSegments)); - EXPECT_EQ(0, CompareVersions(ver4, ver4, kExampleSegments)); - - EXPECT_GT(0, CompareVersions(ver1, ver2, kExampleSegments)); - EXPECT_LT(0, CompareVersions(ver2, ver1, kExampleSegments)); - - EXPECT_GT(0, CompareVersions(ver1, ver3, kExampleSegments)); - EXPECT_LT(0, CompareVersions(ver3, ver1, kExampleSegments)); - - EXPECT_GT(0, CompareVersions(ver1, ver4, kExampleSegments)); - EXPECT_LT(0, CompareVersions(ver4, ver1, kExampleSegments)); - - EXPECT_GT(0, CompareVersions(ver2, ver3, kExampleSegments)); - EXPECT_LT(0, CompareVersions(ver3, ver2, kExampleSegments)); - - EXPECT_GT(0, CompareVersions(ver2, ver4, kExampleSegments)); - EXPECT_LT(0, CompareVersions(ver4, ver2, kExampleSegments)); - - EXPECT_GT(0, CompareVersions(ver3, ver4, kExampleSegments)); - EXPECT_LT(0, CompareVersions(ver4, ver3, kExampleSegments)); -} - -} // namespace rtc diff --git a/webrtc/base/virtualsocket_unittest.cc b/webrtc/base/virtualsocket_unittest.cc deleted file mode 100644 index 253d2c5be..000000000 --- a/webrtc/base/virtualsocket_unittest.cc +++ /dev/null @@ -1,1001 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#if defined(WEBRTC_POSIX) -#include -#endif - -#include "webrtc/base/logging.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/testclient.h" -#include "webrtc/base/testutils.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" -#include "webrtc/base/virtualsocketserver.h" - -using namespace rtc; - -// Sends at a constant rate but with random packet sizes. -struct Sender : public MessageHandler { - Sender(Thread* th, AsyncSocket* s, uint32 rt) - : thread(th), socket(new AsyncUDPSocket(s)), - done(false), rate(rt), count(0) { - last_send = rtc::Time(); - thread->PostDelayed(NextDelay(), this, 1); - } - - uint32 NextDelay() { - uint32 size = (rand() % 4096) + 1; - return 1000 * size / rate; - } - - void OnMessage(Message* pmsg) { - ASSERT_EQ(1u, pmsg->message_id); - - if (done) - return; - - uint32 cur_time = rtc::Time(); - uint32 delay = cur_time - last_send; - uint32 size = rate * delay / 1000; - size = std::min(size, 4096); - size = std::max(size, sizeof(uint32)); - - count += size; - memcpy(dummy, &cur_time, sizeof(cur_time)); - socket->Send(dummy, size, options); - - last_send = cur_time; - thread->PostDelayed(NextDelay(), this, 1); - } - - Thread* thread; - scoped_ptr socket; - rtc::PacketOptions options; - bool done; - uint32 rate; // bytes per second - uint32 count; - uint32 last_send; - char dummy[4096]; -}; - -struct Receiver : public MessageHandler, public sigslot::has_slots<> { - Receiver(Thread* th, AsyncSocket* s, uint32 bw) - : thread(th), socket(new AsyncUDPSocket(s)), bandwidth(bw), done(false), - count(0), sec_count(0), sum(0), sum_sq(0), samples(0) { - socket->SignalReadPacket.connect(this, &Receiver::OnReadPacket); - thread->PostDelayed(1000, this, 1); - } - - ~Receiver() { - thread->Clear(this); - } - - void OnReadPacket(AsyncPacketSocket* s, const char* data, size_t size, - const SocketAddress& remote_addr, - const PacketTime& packet_time) { - ASSERT_EQ(socket.get(), s); - ASSERT_GE(size, 4U); - - count += size; - sec_count += size; - - uint32 send_time = *reinterpret_cast(data); - uint32 recv_time = rtc::Time(); - uint32 delay = recv_time - send_time; - sum += delay; - sum_sq += delay * delay; - samples += 1; - } - - void OnMessage(Message* pmsg) { - ASSERT_EQ(1u, pmsg->message_id); - - if (done) - return; - - // It is always possible for us to receive more than expected because - // packets can be further delayed in delivery. - if (bandwidth > 0) - ASSERT_TRUE(sec_count <= 5 * bandwidth / 4); - sec_count = 0; - thread->PostDelayed(1000, this, 1); - } - - Thread* thread; - scoped_ptr socket; - uint32 bandwidth; - bool done; - size_t count; - size_t sec_count; - double sum; - double sum_sq; - uint32 samples; -}; - -class VirtualSocketServerTest : public testing::Test { - public: - VirtualSocketServerTest() : ss_(new VirtualSocketServer(NULL)), - kIPv4AnyAddress(IPAddress(INADDR_ANY), 0), - kIPv6AnyAddress(IPAddress(in6addr_any), 0) { - } - - void CheckAddressIncrementalization(const SocketAddress& post, - const SocketAddress& pre) { - EXPECT_EQ(post.port(), pre.port() + 1); - IPAddress post_ip = post.ipaddr(); - IPAddress pre_ip = pre.ipaddr(); - EXPECT_EQ(pre_ip.family(), post_ip.family()); - if (post_ip.family() == AF_INET) { - in_addr pre_ipv4 = pre_ip.ipv4_address(); - in_addr post_ipv4 = post_ip.ipv4_address(); - int difference = ntohl(post_ipv4.s_addr) - ntohl(pre_ipv4.s_addr); - EXPECT_EQ(1, difference); - } else if (post_ip.family() == AF_INET6) { - in6_addr post_ip6 = post_ip.ipv6_address(); - in6_addr pre_ip6 = pre_ip.ipv6_address(); - uint32* post_as_ints = reinterpret_cast(&post_ip6.s6_addr); - uint32* pre_as_ints = reinterpret_cast(&pre_ip6.s6_addr); - EXPECT_EQ(post_as_ints[3], pre_as_ints[3] + 1); - } - } - - void BasicTest(const SocketAddress& initial_addr) { - AsyncSocket* socket = ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_DGRAM); - socket->Bind(initial_addr); - SocketAddress server_addr = socket->GetLocalAddress(); - // Make sure VSS didn't switch families on us. - EXPECT_EQ(server_addr.family(), initial_addr.family()); - - TestClient* client1 = new TestClient(new AsyncUDPSocket(socket)); - AsyncSocket* socket2 = - ss_->CreateAsyncSocket(initial_addr.family(), SOCK_DGRAM); - TestClient* client2 = new TestClient(new AsyncUDPSocket(socket2)); - - SocketAddress client2_addr; - EXPECT_EQ(3, client2->SendTo("foo", 3, server_addr)); - EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &client2_addr)); - - SocketAddress client1_addr; - EXPECT_EQ(6, client1->SendTo("bizbaz", 6, client2_addr)); - EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &client1_addr)); - EXPECT_EQ(client1_addr, server_addr); - - SocketAddress empty = EmptySocketAddressWithFamily(initial_addr.family()); - for (int i = 0; i < 10; i++) { - client2 = new TestClient(AsyncUDPSocket::Create(ss_, empty)); - - SocketAddress next_client2_addr; - EXPECT_EQ(3, client2->SendTo("foo", 3, server_addr)); - EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &next_client2_addr)); - CheckAddressIncrementalization(next_client2_addr, client2_addr); - // EXPECT_EQ(next_client2_addr.port(), client2_addr.port() + 1); - - SocketAddress server_addr2; - EXPECT_EQ(6, client1->SendTo("bizbaz", 6, next_client2_addr)); - EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &server_addr2)); - EXPECT_EQ(server_addr2, server_addr); - - client2_addr = next_client2_addr; - } - } - - // initial_addr should be made from either INADDR_ANY or in6addr_any. - void ConnectTest(const SocketAddress& initial_addr) { - testing::StreamSink sink; - SocketAddress accept_addr; - const SocketAddress kEmptyAddr = - EmptySocketAddressWithFamily(initial_addr.family()); - - // Create client - AsyncSocket* client = ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_STREAM); - sink.Monitor(client); - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED); - EXPECT_TRUE(client->GetLocalAddress().IsNil()); - - // Create server - AsyncSocket* server = ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_STREAM); - sink.Monitor(server); - EXPECT_NE(0, server->Listen(5)); // Bind required - EXPECT_EQ(0, server->Bind(initial_addr)); - EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family()); - EXPECT_EQ(0, server->Listen(5)); - EXPECT_EQ(server->GetState(), AsyncSocket::CS_CONNECTING); - - // No pending server connections - EXPECT_FALSE(sink.Check(server, testing::SSE_READ)); - EXPECT_TRUE(NULL == server->Accept(&accept_addr)); - EXPECT_EQ(AF_UNSPEC, accept_addr.family()); - - // Attempt connect to listening socket - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - EXPECT_NE(client->GetLocalAddress(), kEmptyAddr); // Implicit Bind - EXPECT_NE(AF_UNSPEC, client->GetLocalAddress().family()); // Implicit Bind - EXPECT_NE(client->GetLocalAddress(), server->GetLocalAddress()); - - // Client is connecting - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CONNECTING); - EXPECT_FALSE(sink.Check(client, testing::SSE_OPEN)); - EXPECT_FALSE(sink.Check(client, testing::SSE_CLOSE)); - - ss_->ProcessMessagesUntilIdle(); - - // Client still connecting - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CONNECTING); - EXPECT_FALSE(sink.Check(client, testing::SSE_OPEN)); - EXPECT_FALSE(sink.Check(client, testing::SSE_CLOSE)); - - // Server has pending connection - EXPECT_TRUE(sink.Check(server, testing::SSE_READ)); - Socket* accepted = server->Accept(&accept_addr); - EXPECT_TRUE(NULL != accepted); - EXPECT_NE(accept_addr, kEmptyAddr); - EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr); - - EXPECT_EQ(accepted->GetState(), AsyncSocket::CS_CONNECTED); - EXPECT_EQ(accepted->GetLocalAddress(), server->GetLocalAddress()); - EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress()); - - ss_->ProcessMessagesUntilIdle(); - - // Client has connected - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CONNECTED); - EXPECT_TRUE(sink.Check(client, testing::SSE_OPEN)); - EXPECT_FALSE(sink.Check(client, testing::SSE_CLOSE)); - EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress()); - EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress()); - } - - void ConnectToNonListenerTest(const SocketAddress& initial_addr) { - testing::StreamSink sink; - SocketAddress accept_addr; - const SocketAddress nil_addr; - const SocketAddress empty_addr = - EmptySocketAddressWithFamily(initial_addr.family()); - - // Create client - AsyncSocket* client = ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_STREAM); - sink.Monitor(client); - - // Create server - AsyncSocket* server = ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_STREAM); - sink.Monitor(server); - EXPECT_EQ(0, server->Bind(initial_addr)); - EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family()); - // Attempt connect to non-listening socket - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - ss_->ProcessMessagesUntilIdle(); - - // No pending server connections - EXPECT_FALSE(sink.Check(server, testing::SSE_READ)); - EXPECT_TRUE(NULL == server->Accept(&accept_addr)); - EXPECT_EQ(accept_addr, nil_addr); - - // Connection failed - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED); - EXPECT_FALSE(sink.Check(client, testing::SSE_OPEN)); - EXPECT_TRUE(sink.Check(client, testing::SSE_ERROR)); - EXPECT_EQ(client->GetRemoteAddress(), nil_addr); - } - - void CloseDuringConnectTest(const SocketAddress& initial_addr) { - testing::StreamSink sink; - SocketAddress accept_addr; - const SocketAddress empty_addr = - EmptySocketAddressWithFamily(initial_addr.family()); - - // Create client and server - scoped_ptr client(ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_STREAM)); - sink.Monitor(client.get()); - scoped_ptr server(ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_STREAM)); - sink.Monitor(server.get()); - - // Initiate connect - EXPECT_EQ(0, server->Bind(initial_addr)); - EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family()); - - EXPECT_EQ(0, server->Listen(5)); - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - // Server close before socket enters accept queue - EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ)); - server->Close(); - - ss_->ProcessMessagesUntilIdle(); - - // Result: connection failed - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR)); - - server.reset(ss_->CreateAsyncSocket(initial_addr.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - - // Initiate connect - EXPECT_EQ(0, server->Bind(initial_addr)); - EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family()); - - EXPECT_EQ(0, server->Listen(5)); - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - ss_->ProcessMessagesUntilIdle(); - - // Server close while socket is in accept queue - EXPECT_TRUE(sink.Check(server.get(), testing::SSE_READ)); - server->Close(); - - ss_->ProcessMessagesUntilIdle(); - - // Result: connection failed - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED); - EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR)); - - // New server - server.reset(ss_->CreateAsyncSocket(initial_addr.family(), SOCK_STREAM)); - sink.Monitor(server.get()); - - // Initiate connect - EXPECT_EQ(0, server->Bind(initial_addr)); - EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family()); - - EXPECT_EQ(0, server->Listen(5)); - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - - ss_->ProcessMessagesUntilIdle(); - - // Server accepts connection - EXPECT_TRUE(sink.Check(server.get(), testing::SSE_READ)); - scoped_ptr accepted(server->Accept(&accept_addr)); - ASSERT_TRUE(NULL != accepted.get()); - sink.Monitor(accepted.get()); - - // Client closes before connection complets - EXPECT_EQ(accepted->GetState(), AsyncSocket::CS_CONNECTED); - - // Connected message has not been processed yet. - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CONNECTING); - client->Close(); - - ss_->ProcessMessagesUntilIdle(); - - // Result: accepted socket closes - EXPECT_EQ(accepted->GetState(), AsyncSocket::CS_CLOSED); - EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE)); - EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE)); - } - - void CloseTest(const SocketAddress& initial_addr) { - testing::StreamSink sink; - const SocketAddress kEmptyAddr; - - // Create clients - AsyncSocket* a = ss_->CreateAsyncSocket(initial_addr.family(), SOCK_STREAM); - sink.Monitor(a); - a->Bind(initial_addr); - EXPECT_EQ(a->GetLocalAddress().family(), initial_addr.family()); - - - scoped_ptr b(ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_STREAM)); - sink.Monitor(b.get()); - b->Bind(initial_addr); - EXPECT_EQ(b->GetLocalAddress().family(), initial_addr.family()); - - EXPECT_EQ(0, a->Connect(b->GetLocalAddress())); - EXPECT_EQ(0, b->Connect(a->GetLocalAddress())); - - ss_->ProcessMessagesUntilIdle(); - - EXPECT_TRUE(sink.Check(a, testing::SSE_OPEN)); - EXPECT_EQ(a->GetState(), AsyncSocket::CS_CONNECTED); - EXPECT_EQ(a->GetRemoteAddress(), b->GetLocalAddress()); - - EXPECT_TRUE(sink.Check(b.get(), testing::SSE_OPEN)); - EXPECT_EQ(b->GetState(), AsyncSocket::CS_CONNECTED); - EXPECT_EQ(b->GetRemoteAddress(), a->GetLocalAddress()); - - EXPECT_EQ(1, a->Send("a", 1)); - b->Close(); - EXPECT_EQ(1, a->Send("b", 1)); - - ss_->ProcessMessagesUntilIdle(); - - char buffer[10]; - EXPECT_FALSE(sink.Check(b.get(), testing::SSE_READ)); - EXPECT_EQ(-1, b->Recv(buffer, 10)); - - EXPECT_TRUE(sink.Check(a, testing::SSE_CLOSE)); - EXPECT_EQ(a->GetState(), AsyncSocket::CS_CLOSED); - EXPECT_EQ(a->GetRemoteAddress(), kEmptyAddr); - - // No signal for Closer - EXPECT_FALSE(sink.Check(b.get(), testing::SSE_CLOSE)); - EXPECT_EQ(b->GetState(), AsyncSocket::CS_CLOSED); - EXPECT_EQ(b->GetRemoteAddress(), kEmptyAddr); - } - - void TcpSendTest(const SocketAddress& initial_addr) { - testing::StreamSink sink; - const SocketAddress kEmptyAddr; - - // Connect two sockets - AsyncSocket* a = ss_->CreateAsyncSocket(initial_addr.family(), SOCK_STREAM); - sink.Monitor(a); - a->Bind(initial_addr); - EXPECT_EQ(a->GetLocalAddress().family(), initial_addr.family()); - - AsyncSocket* b = ss_->CreateAsyncSocket(initial_addr.family(), SOCK_STREAM); - sink.Monitor(b); - b->Bind(initial_addr); - EXPECT_EQ(b->GetLocalAddress().family(), initial_addr.family()); - - EXPECT_EQ(0, a->Connect(b->GetLocalAddress())); - EXPECT_EQ(0, b->Connect(a->GetLocalAddress())); - - ss_->ProcessMessagesUntilIdle(); - - const size_t kBufferSize = 2000; - ss_->set_send_buffer_capacity(kBufferSize); - ss_->set_recv_buffer_capacity(kBufferSize); - - const size_t kDataSize = 5000; - char send_buffer[kDataSize], recv_buffer[kDataSize]; - for (size_t i = 0; i < kDataSize; ++i) - send_buffer[i] = static_cast(i % 256); - memset(recv_buffer, 0, sizeof(recv_buffer)); - size_t send_pos = 0, recv_pos = 0; - - // Can't send more than send buffer in one write - int result = a->Send(send_buffer + send_pos, kDataSize - send_pos); - EXPECT_EQ(static_cast(kBufferSize), result); - send_pos += result; - - ss_->ProcessMessagesUntilIdle(); - EXPECT_FALSE(sink.Check(a, testing::SSE_WRITE)); - EXPECT_TRUE(sink.Check(b, testing::SSE_READ)); - - // Receive buffer is already filled, fill send buffer again - result = a->Send(send_buffer + send_pos, kDataSize - send_pos); - EXPECT_EQ(static_cast(kBufferSize), result); - send_pos += result; - - ss_->ProcessMessagesUntilIdle(); - EXPECT_FALSE(sink.Check(a, testing::SSE_WRITE)); - EXPECT_FALSE(sink.Check(b, testing::SSE_READ)); - - // No more room in send or receive buffer - result = a->Send(send_buffer + send_pos, kDataSize - send_pos); - EXPECT_EQ(-1, result); - EXPECT_TRUE(a->IsBlocking()); - - // Read a subset of the data - result = b->Recv(recv_buffer + recv_pos, 500); - EXPECT_EQ(500, result); - recv_pos += result; - - ss_->ProcessMessagesUntilIdle(); - EXPECT_TRUE(sink.Check(a, testing::SSE_WRITE)); - EXPECT_TRUE(sink.Check(b, testing::SSE_READ)); - - // Room for more on the sending side - result = a->Send(send_buffer + send_pos, kDataSize - send_pos); - EXPECT_EQ(500, result); - send_pos += result; - - // Empty the recv buffer - while (true) { - result = b->Recv(recv_buffer + recv_pos, kDataSize - recv_pos); - if (result < 0) { - EXPECT_EQ(-1, result); - EXPECT_TRUE(b->IsBlocking()); - break; - } - recv_pos += result; - } - - ss_->ProcessMessagesUntilIdle(); - EXPECT_TRUE(sink.Check(b, testing::SSE_READ)); - - // Continue to empty the recv buffer - while (true) { - result = b->Recv(recv_buffer + recv_pos, kDataSize - recv_pos); - if (result < 0) { - EXPECT_EQ(-1, result); - EXPECT_TRUE(b->IsBlocking()); - break; - } - recv_pos += result; - } - - // Send last of the data - result = a->Send(send_buffer + send_pos, kDataSize - send_pos); - EXPECT_EQ(500, result); - send_pos += result; - - ss_->ProcessMessagesUntilIdle(); - EXPECT_TRUE(sink.Check(b, testing::SSE_READ)); - - // Receive the last of the data - while (true) { - result = b->Recv(recv_buffer + recv_pos, kDataSize - recv_pos); - if (result < 0) { - EXPECT_EQ(-1, result); - EXPECT_TRUE(b->IsBlocking()); - break; - } - recv_pos += result; - } - - ss_->ProcessMessagesUntilIdle(); - EXPECT_FALSE(sink.Check(b, testing::SSE_READ)); - - // The received data matches the sent data - EXPECT_EQ(kDataSize, send_pos); - EXPECT_EQ(kDataSize, recv_pos); - EXPECT_EQ(0, memcmp(recv_buffer, send_buffer, kDataSize)); - } - - void TcpSendsPacketsInOrderTest(const SocketAddress& initial_addr) { - const SocketAddress kEmptyAddr; - - // Connect two sockets - AsyncSocket* a = ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_STREAM); - AsyncSocket* b = ss_->CreateAsyncSocket(initial_addr.family(), - SOCK_STREAM); - a->Bind(initial_addr); - EXPECT_EQ(a->GetLocalAddress().family(), initial_addr.family()); - - b->Bind(initial_addr); - EXPECT_EQ(b->GetLocalAddress().family(), initial_addr.family()); - - EXPECT_EQ(0, a->Connect(b->GetLocalAddress())); - EXPECT_EQ(0, b->Connect(a->GetLocalAddress())); - ss_->ProcessMessagesUntilIdle(); - - // First, deliver all packets in 0 ms. - char buffer[2] = { 0, 0 }; - const char cNumPackets = 10; - for (char i = 0; i < cNumPackets; ++i) { - buffer[0] = '0' + i; - EXPECT_EQ(1, a->Send(buffer, 1)); - } - - ss_->ProcessMessagesUntilIdle(); - - for (char i = 0; i < cNumPackets; ++i) { - EXPECT_EQ(1, b->Recv(buffer, sizeof(buffer))); - EXPECT_EQ(static_cast('0' + i), buffer[0]); - } - - // Next, deliver packets at random intervals - const uint32 mean = 50; - const uint32 stddev = 50; - - ss_->set_delay_mean(mean); - ss_->set_delay_stddev(stddev); - ss_->UpdateDelayDistribution(); - - for (char i = 0; i < cNumPackets; ++i) { - buffer[0] = 'A' + i; - EXPECT_EQ(1, a->Send(buffer, 1)); - } - - ss_->ProcessMessagesUntilIdle(); - - for (char i = 0; i < cNumPackets; ++i) { - EXPECT_EQ(1, b->Recv(buffer, sizeof(buffer))); - EXPECT_EQ(static_cast('A' + i), buffer[0]); - } - } - - void BandwidthTest(const SocketAddress& initial_addr) { - AsyncSocket* send_socket = - ss_->CreateAsyncSocket(initial_addr.family(), SOCK_DGRAM); - AsyncSocket* recv_socket = - ss_->CreateAsyncSocket(initial_addr.family(), SOCK_DGRAM); - ASSERT_EQ(0, send_socket->Bind(initial_addr)); - ASSERT_EQ(0, recv_socket->Bind(initial_addr)); - EXPECT_EQ(send_socket->GetLocalAddress().family(), initial_addr.family()); - EXPECT_EQ(recv_socket->GetLocalAddress().family(), initial_addr.family()); - ASSERT_EQ(0, send_socket->Connect(recv_socket->GetLocalAddress())); - - uint32 bandwidth = 64 * 1024; - ss_->set_bandwidth(bandwidth); - - Thread* pthMain = Thread::Current(); - Sender sender(pthMain, send_socket, 80 * 1024); - Receiver receiver(pthMain, recv_socket, bandwidth); - - pthMain->ProcessMessages(5000); - sender.done = true; - pthMain->ProcessMessages(5000); - - ASSERT_TRUE(receiver.count >= 5 * 3 * bandwidth / 4); - ASSERT_TRUE(receiver.count <= 6 * bandwidth); // queue could drain for 1s - - ss_->set_bandwidth(0); - } - - void DelayTest(const SocketAddress& initial_addr) { - time_t seed = ::time(NULL); - LOG(LS_VERBOSE) << "seed = " << seed; - srand(static_cast(seed)); - - const uint32 mean = 2000; - const uint32 stddev = 500; - - ss_->set_delay_mean(mean); - ss_->set_delay_stddev(stddev); - ss_->UpdateDelayDistribution(); - - AsyncSocket* send_socket = - ss_->CreateAsyncSocket(initial_addr.family(), SOCK_DGRAM); - AsyncSocket* recv_socket = - ss_->CreateAsyncSocket(initial_addr.family(), SOCK_DGRAM); - ASSERT_EQ(0, send_socket->Bind(initial_addr)); - ASSERT_EQ(0, recv_socket->Bind(initial_addr)); - EXPECT_EQ(send_socket->GetLocalAddress().family(), initial_addr.family()); - EXPECT_EQ(recv_socket->GetLocalAddress().family(), initial_addr.family()); - ASSERT_EQ(0, send_socket->Connect(recv_socket->GetLocalAddress())); - - Thread* pthMain = Thread::Current(); - // Avg packet size is 2K, so at 200KB/s for 10s, we should see about - // 1000 packets, which is necessary to get a good distribution. - Sender sender(pthMain, send_socket, 100 * 2 * 1024); - Receiver receiver(pthMain, recv_socket, 0); - - pthMain->ProcessMessages(10000); - sender.done = receiver.done = true; - ss_->ProcessMessagesUntilIdle(); - - const double sample_mean = receiver.sum / receiver.samples; - double num = - receiver.samples * receiver.sum_sq - receiver.sum * receiver.sum; - double den = receiver.samples * (receiver.samples - 1); - const double sample_stddev = sqrt(num / den); - LOG(LS_VERBOSE) << "mean=" << sample_mean << " stddev=" << sample_stddev; - - EXPECT_LE(500u, receiver.samples); - // We initially used a 0.1 fudge factor, but on the build machine, we - // have seen the value differ by as much as 0.13. - EXPECT_NEAR(mean, sample_mean, 0.15 * mean); - EXPECT_NEAR(stddev, sample_stddev, 0.15 * stddev); - - ss_->set_delay_mean(0); - ss_->set_delay_stddev(0); - ss_->UpdateDelayDistribution(); - } - - // Test cross-family communication between a client bound to client_addr and a - // server bound to server_addr. shouldSucceed indicates if communication is - // expected to work or not. - void CrossFamilyConnectionTest(const SocketAddress& client_addr, - const SocketAddress& server_addr, - bool shouldSucceed) { - testing::StreamSink sink; - SocketAddress accept_address; - const SocketAddress kEmptyAddr; - - // Client gets a IPv4 address - AsyncSocket* client = ss_->CreateAsyncSocket(client_addr.family(), - SOCK_STREAM); - sink.Monitor(client); - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED); - EXPECT_EQ(client->GetLocalAddress(), kEmptyAddr); - client->Bind(client_addr); - - // Server gets a non-mapped non-any IPv6 address. - // IPv4 sockets should not be able to connect to this. - AsyncSocket* server = ss_->CreateAsyncSocket(server_addr.family(), - SOCK_STREAM); - sink.Monitor(server); - server->Bind(server_addr); - server->Listen(5); - - if (shouldSucceed) { - EXPECT_EQ(0, client->Connect(server->GetLocalAddress())); - ss_->ProcessMessagesUntilIdle(); - EXPECT_TRUE(sink.Check(server, testing::SSE_READ)); - Socket* accepted = server->Accept(&accept_address); - EXPECT_TRUE(NULL != accepted); - EXPECT_NE(kEmptyAddr, accept_address); - ss_->ProcessMessagesUntilIdle(); - EXPECT_TRUE(sink.Check(client, testing::SSE_OPEN)); - EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress()); - } else { - // Check that the connection failed. - EXPECT_EQ(-1, client->Connect(server->GetLocalAddress())); - ss_->ProcessMessagesUntilIdle(); - - EXPECT_FALSE(sink.Check(server, testing::SSE_READ)); - EXPECT_TRUE(NULL == server->Accept(&accept_address)); - EXPECT_EQ(accept_address, kEmptyAddr); - EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED); - EXPECT_FALSE(sink.Check(client, testing::SSE_OPEN)); - EXPECT_EQ(client->GetRemoteAddress(), kEmptyAddr); - } - } - - // Test cross-family datagram sending between a client bound to client_addr - // and a server bound to server_addr. shouldSucceed indicates if sending is - // expected to succed or not. - void CrossFamilyDatagramTest(const SocketAddress& client_addr, - const SocketAddress& server_addr, - bool shouldSucceed) { - AsyncSocket* socket = ss_->CreateAsyncSocket(SOCK_DGRAM); - socket->Bind(server_addr); - SocketAddress bound_server_addr = socket->GetLocalAddress(); - TestClient* client1 = new TestClient(new AsyncUDPSocket(socket)); - - AsyncSocket* socket2 = ss_->CreateAsyncSocket(SOCK_DGRAM); - socket2->Bind(client_addr); - TestClient* client2 = new TestClient(new AsyncUDPSocket(socket2)); - SocketAddress client2_addr; - - if (shouldSucceed) { - EXPECT_EQ(3, client2->SendTo("foo", 3, bound_server_addr)); - EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &client2_addr)); - SocketAddress client1_addr; - EXPECT_EQ(6, client1->SendTo("bizbaz", 6, client2_addr)); - EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &client1_addr)); - EXPECT_EQ(client1_addr, bound_server_addr); - } else { - EXPECT_EQ(-1, client2->SendTo("foo", 3, bound_server_addr)); - EXPECT_FALSE(client1->CheckNextPacket("foo", 3, 0)); - } - } - - protected: - virtual void SetUp() { - Thread::Current()->set_socketserver(ss_); - } - virtual void TearDown() { - Thread::Current()->set_socketserver(NULL); - } - - VirtualSocketServer* ss_; - const SocketAddress kIPv4AnyAddress; - const SocketAddress kIPv6AnyAddress; -}; - -TEST_F(VirtualSocketServerTest, basic_v4) { - SocketAddress ipv4_test_addr(IPAddress(INADDR_ANY), 5000); - BasicTest(ipv4_test_addr); -} - -TEST_F(VirtualSocketServerTest, basic_v6) { - SocketAddress ipv6_test_addr(IPAddress(in6addr_any), 5000); - BasicTest(ipv6_test_addr); -} - -TEST_F(VirtualSocketServerTest, connect_v4) { - ConnectTest(kIPv4AnyAddress); -} - -TEST_F(VirtualSocketServerTest, connect_v6) { - ConnectTest(kIPv6AnyAddress); -} - -TEST_F(VirtualSocketServerTest, connect_to_non_listener_v4) { - ConnectToNonListenerTest(kIPv4AnyAddress); -} - -TEST_F(VirtualSocketServerTest, connect_to_non_listener_v6) { - ConnectToNonListenerTest(kIPv6AnyAddress); -} - -TEST_F(VirtualSocketServerTest, close_during_connect_v4) { - CloseDuringConnectTest(kIPv4AnyAddress); -} - -TEST_F(VirtualSocketServerTest, close_during_connect_v6) { - CloseDuringConnectTest(kIPv6AnyAddress); -} - -TEST_F(VirtualSocketServerTest, close_v4) { - CloseTest(kIPv4AnyAddress); -} - -TEST_F(VirtualSocketServerTest, close_v6) { - CloseTest(kIPv6AnyAddress); -} - -TEST_F(VirtualSocketServerTest, tcp_send_v4) { - TcpSendTest(kIPv4AnyAddress); -} - -TEST_F(VirtualSocketServerTest, tcp_send_v6) { - TcpSendTest(kIPv6AnyAddress); -} - -TEST_F(VirtualSocketServerTest, TcpSendsPacketsInOrder_v4) { - TcpSendsPacketsInOrderTest(kIPv4AnyAddress); -} - -TEST_F(VirtualSocketServerTest, TcpSendsPacketsInOrder_v6) { - TcpSendsPacketsInOrderTest(kIPv6AnyAddress); -} - -TEST_F(VirtualSocketServerTest, bandwidth_v4) { - SocketAddress ipv4_test_addr(IPAddress(INADDR_ANY), 1000); - BandwidthTest(ipv4_test_addr); -} - -TEST_F(VirtualSocketServerTest, bandwidth_v6) { - SocketAddress ipv6_test_addr(IPAddress(in6addr_any), 1000); - BandwidthTest(ipv6_test_addr); -} - -TEST_F(VirtualSocketServerTest, delay_v4) { - SocketAddress ipv4_test_addr(IPAddress(INADDR_ANY), 1000); - DelayTest(ipv4_test_addr); -} - -// See: https://code.google.com/p/webrtc/issues/detail?id=2409 -TEST_F(VirtualSocketServerTest, DISABLED_delay_v6) { - SocketAddress ipv6_test_addr(IPAddress(in6addr_any), 1000); - DelayTest(ipv6_test_addr); -} - -// Works, receiving socket sees 127.0.0.2. -TEST_F(VirtualSocketServerTest, CanConnectFromMappedIPv6ToIPv4Any) { - CrossFamilyConnectionTest(SocketAddress("::ffff:127.0.0.2", 0), - SocketAddress("0.0.0.0", 5000), - true); -} - -// Fails. -TEST_F(VirtualSocketServerTest, CantConnectFromUnMappedIPv6ToIPv4Any) { - CrossFamilyConnectionTest(SocketAddress("::2", 0), - SocketAddress("0.0.0.0", 5000), - false); -} - -// Fails. -TEST_F(VirtualSocketServerTest, CantConnectFromUnMappedIPv6ToMappedIPv6) { - CrossFamilyConnectionTest(SocketAddress("::2", 0), - SocketAddress("::ffff:127.0.0.1", 5000), - false); -} - -// Works. receiving socket sees ::ffff:127.0.0.2. -TEST_F(VirtualSocketServerTest, CanConnectFromIPv4ToIPv6Any) { - CrossFamilyConnectionTest(SocketAddress("127.0.0.2", 0), - SocketAddress("::", 5000), - true); -} - -// Fails. -TEST_F(VirtualSocketServerTest, CantConnectFromIPv4ToUnMappedIPv6) { - CrossFamilyConnectionTest(SocketAddress("127.0.0.2", 0), - SocketAddress("::1", 5000), - false); -} - -// Works. Receiving socket sees ::ffff:127.0.0.1. -TEST_F(VirtualSocketServerTest, CanConnectFromIPv4ToMappedIPv6) { - CrossFamilyConnectionTest(SocketAddress("127.0.0.1", 0), - SocketAddress("::ffff:127.0.0.2", 5000), - true); -} - -// Works, receiving socket sees a result from GetNextIP. -TEST_F(VirtualSocketServerTest, CanConnectFromUnboundIPv6ToIPv4Any) { - CrossFamilyConnectionTest(SocketAddress("::", 0), - SocketAddress("0.0.0.0", 5000), - true); -} - -// Works, receiving socket sees whatever GetNextIP gave the client. -TEST_F(VirtualSocketServerTest, CanConnectFromUnboundIPv4ToIPv6Any) { - CrossFamilyConnectionTest(SocketAddress("0.0.0.0", 0), - SocketAddress("::", 5000), - true); -} - -TEST_F(VirtualSocketServerTest, CanSendDatagramFromUnboundIPv4ToIPv6Any) { - CrossFamilyDatagramTest(SocketAddress("0.0.0.0", 0), - SocketAddress("::", 5000), - true); -} - -TEST_F(VirtualSocketServerTest, CanSendDatagramFromMappedIPv6ToIPv4Any) { - CrossFamilyDatagramTest(SocketAddress("::ffff:127.0.0.1", 0), - SocketAddress("0.0.0.0", 5000), - true); -} - -TEST_F(VirtualSocketServerTest, CantSendDatagramFromUnMappedIPv6ToIPv4Any) { - CrossFamilyDatagramTest(SocketAddress("::2", 0), - SocketAddress("0.0.0.0", 5000), - false); -} - -TEST_F(VirtualSocketServerTest, CantSendDatagramFromUnMappedIPv6ToMappedIPv6) { - CrossFamilyDatagramTest(SocketAddress("::2", 0), - SocketAddress("::ffff:127.0.0.1", 5000), - false); -} - -TEST_F(VirtualSocketServerTest, CanSendDatagramFromIPv4ToIPv6Any) { - CrossFamilyDatagramTest(SocketAddress("127.0.0.2", 0), - SocketAddress("::", 5000), - true); -} - -TEST_F(VirtualSocketServerTest, CantSendDatagramFromIPv4ToUnMappedIPv6) { - CrossFamilyDatagramTest(SocketAddress("127.0.0.2", 0), - SocketAddress("::1", 5000), - false); -} - -TEST_F(VirtualSocketServerTest, CanSendDatagramFromIPv4ToMappedIPv6) { - CrossFamilyDatagramTest(SocketAddress("127.0.0.1", 0), - SocketAddress("::ffff:127.0.0.2", 5000), - true); -} - -TEST_F(VirtualSocketServerTest, CanSendDatagramFromUnboundIPv6ToIPv4Any) { - CrossFamilyDatagramTest(SocketAddress("::", 0), - SocketAddress("0.0.0.0", 5000), - true); -} - -TEST_F(VirtualSocketServerTest, CreatesStandardDistribution) { - const uint32 kTestMean[] = { 10, 100, 333, 1000 }; - const double kTestDev[] = { 0.25, 0.1, 0.01 }; - // TODO: The current code only works for 1000 data points or more. - const uint32 kTestSamples[] = { /*10, 100,*/ 1000 }; - for (size_t midx = 0; midx < ARRAY_SIZE(kTestMean); ++midx) { - for (size_t didx = 0; didx < ARRAY_SIZE(kTestDev); ++didx) { - for (size_t sidx = 0; sidx < ARRAY_SIZE(kTestSamples); ++sidx) { - ASSERT_LT(0u, kTestSamples[sidx]); - const uint32 kStdDev = - static_cast(kTestDev[didx] * kTestMean[midx]); - VirtualSocketServer::Function* f = - VirtualSocketServer::CreateDistribution(kTestMean[midx], - kStdDev, - kTestSamples[sidx]); - ASSERT_TRUE(NULL != f); - ASSERT_EQ(kTestSamples[sidx], f->size()); - double sum = 0; - for (uint32 i = 0; i < f->size(); ++i) { - sum += (*f)[i].second; - } - const double mean = sum / f->size(); - double sum_sq_dev = 0; - for (uint32 i = 0; i < f->size(); ++i) { - double dev = (*f)[i].second - mean; - sum_sq_dev += dev * dev; - } - const double stddev = sqrt(sum_sq_dev / f->size()); - EXPECT_NEAR(kTestMean[midx], mean, 0.1 * kTestMean[midx]) - << "M=" << kTestMean[midx] - << " SD=" << kStdDev - << " N=" << kTestSamples[sidx]; - EXPECT_NEAR(kStdDev, stddev, 0.1 * kStdDev) - << "M=" << kTestMean[midx] - << " SD=" << kStdDev - << " N=" << kTestSamples[sidx]; - delete f; - } - } - } -} diff --git a/webrtc/base/virtualsocketserver.cc b/webrtc/base/virtualsocketserver.cc deleted file mode 100644 index f8e8ddeb8..000000000 --- a/webrtc/base/virtualsocketserver.cc +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/virtualsocketserver.h" - -#include -#include - -#include -#include -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/physicalsocketserver.h" -#include "webrtc/base/socketaddresspair.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/timeutils.h" - -namespace rtc { -#if defined(WEBRTC_WIN) -const in_addr kInitialNextIPv4 = { {0x01, 0, 0, 0} }; -#else -// This value is entirely arbitrary, hence the lack of concern about endianness. -const in_addr kInitialNextIPv4 = { 0x01000000 }; -#endif -// Starts at ::2 so as to not cause confusion with ::1. -const in6_addr kInitialNextIPv6 = { { { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 - } } }; - -const uint16 kFirstEphemeralPort = 49152; -const uint16 kLastEphemeralPort = 65535; -const uint16 kEphemeralPortCount = kLastEphemeralPort - kFirstEphemeralPort + 1; -const uint32 kDefaultNetworkCapacity = 64 * 1024; -const uint32 kDefaultTcpBufferSize = 32 * 1024; - -const uint32 UDP_HEADER_SIZE = 28; // IP + UDP headers -const uint32 TCP_HEADER_SIZE = 40; // IP + TCP headers -const uint32 TCP_MSS = 1400; // Maximum segment size - -// Note: The current algorithm doesn't work for sample sizes smaller than this. -const int NUM_SAMPLES = 1000; - -enum { - MSG_ID_PACKET, - MSG_ID_CONNECT, - MSG_ID_DISCONNECT, -}; - -// Packets are passed between sockets as messages. We copy the data just like -// the kernel does. -class Packet : public MessageData { - public: - Packet(const char* data, size_t size, const SocketAddress& from) - : size_(size), consumed_(0), from_(from) { - ASSERT(NULL != data); - data_ = new char[size_]; - memcpy(data_, data, size_); - } - - virtual ~Packet() { - delete[] data_; - } - - const char* data() const { return data_ + consumed_; } - size_t size() const { return size_ - consumed_; } - const SocketAddress& from() const { return from_; } - - // Remove the first size bytes from the data. - void Consume(size_t size) { - ASSERT(size + consumed_ < size_); - consumed_ += size; - } - - private: - char* data_; - size_t size_, consumed_; - SocketAddress from_; -}; - -struct MessageAddress : public MessageData { - explicit MessageAddress(const SocketAddress& a) : addr(a) { } - SocketAddress addr; -}; - -// Implements the socket interface using the virtual network. Packets are -// passed as messages using the message queue of the socket server. -class VirtualSocket : public AsyncSocket, public MessageHandler { - public: - VirtualSocket(VirtualSocketServer* server, int family, int type, bool async) - : server_(server), family_(family), type_(type), async_(async), - state_(CS_CLOSED), error_(0), listen_queue_(NULL), - write_enabled_(false), - network_size_(0), recv_buffer_size_(0), bound_(false), was_any_(false) { - ASSERT((type_ == SOCK_DGRAM) || (type_ == SOCK_STREAM)); - ASSERT(async_ || (type_ != SOCK_STREAM)); // We only support async streams - } - - virtual ~VirtualSocket() { - Close(); - - for (RecvBuffer::iterator it = recv_buffer_.begin(); - it != recv_buffer_.end(); ++it) { - delete *it; - } - } - - virtual SocketAddress GetLocalAddress() const { - return local_addr_; - } - - virtual SocketAddress GetRemoteAddress() const { - return remote_addr_; - } - - // Used by server sockets to set the local address without binding. - void SetLocalAddress(const SocketAddress& addr) { - local_addr_ = addr; - } - - virtual int Bind(const SocketAddress& addr) { - if (!local_addr_.IsNil()) { - error_ = EINVAL; - return -1; - } - local_addr_ = addr; - int result = server_->Bind(this, &local_addr_); - if (result != 0) { - local_addr_.Clear(); - error_ = EADDRINUSE; - } else { - bound_ = true; - was_any_ = addr.IsAnyIP(); - } - return result; - } - - virtual int Connect(const SocketAddress& addr) { - return InitiateConnect(addr, true); - } - - virtual int Close() { - if (!local_addr_.IsNil() && bound_) { - // Remove from the binding table. - server_->Unbind(local_addr_, this); - bound_ = false; - } - - if (SOCK_STREAM == type_) { - // Cancel pending sockets - if (listen_queue_) { - while (!listen_queue_->empty()) { - SocketAddress addr = listen_queue_->front(); - - // Disconnect listening socket. - server_->Disconnect(server_->LookupBinding(addr)); - listen_queue_->pop_front(); - } - delete listen_queue_; - listen_queue_ = NULL; - } - // Disconnect stream sockets - if (CS_CONNECTED == state_) { - // Disconnect remote socket, check if it is a child of a server socket. - VirtualSocket* socket = - server_->LookupConnection(local_addr_, remote_addr_); - if (!socket) { - // Not a server socket child, then see if it is bound. - // TODO: If this is indeed a server socket that has no - // children this will cause the server socket to be - // closed. This might lead to unexpected results, how to fix this? - socket = server_->LookupBinding(remote_addr_); - } - server_->Disconnect(socket); - - // Remove mapping for both directions. - server_->RemoveConnection(remote_addr_, local_addr_); - server_->RemoveConnection(local_addr_, remote_addr_); - } - // Cancel potential connects - MessageList msgs; - if (server_->msg_queue_) { - server_->msg_queue_->Clear(this, MSG_ID_CONNECT, &msgs); - } - for (MessageList::iterator it = msgs.begin(); it != msgs.end(); ++it) { - ASSERT(NULL != it->pdata); - MessageAddress* data = static_cast(it->pdata); - - // Lookup remote side. - VirtualSocket* socket = server_->LookupConnection(local_addr_, - data->addr); - if (socket) { - // Server socket, remote side is a socket retreived by - // accept. Accepted sockets are not bound so we will not - // find it by looking in the bindings table. - server_->Disconnect(socket); - server_->RemoveConnection(local_addr_, data->addr); - } else { - server_->Disconnect(server_->LookupBinding(data->addr)); - } - delete data; - } - // Clear incoming packets and disconnect messages - if (server_->msg_queue_) { - server_->msg_queue_->Clear(this); - } - } - - state_ = CS_CLOSED; - local_addr_.Clear(); - remote_addr_.Clear(); - return 0; - } - - virtual int Send(const void *pv, size_t cb) { - if (CS_CONNECTED != state_) { - error_ = ENOTCONN; - return -1; - } - if (SOCK_DGRAM == type_) { - return SendUdp(pv, cb, remote_addr_); - } else { - return SendTcp(pv, cb); - } - } - - virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr) { - if (SOCK_DGRAM == type_) { - return SendUdp(pv, cb, addr); - } else { - if (CS_CONNECTED != state_) { - error_ = ENOTCONN; - return -1; - } - return SendTcp(pv, cb); - } - } - - virtual int Recv(void *pv, size_t cb) { - SocketAddress addr; - return RecvFrom(pv, cb, &addr); - } - - virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr) { - // If we don't have a packet, then either error or wait for one to arrive. - if (recv_buffer_.empty()) { - if (async_) { - error_ = EAGAIN; - return -1; - } - while (recv_buffer_.empty()) { - Message msg; - server_->msg_queue_->Get(&msg); - server_->msg_queue_->Dispatch(&msg); - } - } - - // Return the packet at the front of the queue. - Packet* packet = recv_buffer_.front(); - size_t data_read = _min(cb, packet->size()); - memcpy(pv, packet->data(), data_read); - *paddr = packet->from(); - - if (data_read < packet->size()) { - packet->Consume(data_read); - } else { - recv_buffer_.pop_front(); - delete packet; - } - - if (SOCK_STREAM == type_) { - bool was_full = (recv_buffer_size_ == server_->recv_buffer_capacity_); - recv_buffer_size_ -= data_read; - if (was_full) { - VirtualSocket* sender = server_->LookupBinding(remote_addr_); - ASSERT(NULL != sender); - server_->SendTcp(sender); - } - } - - return static_cast(data_read); - } - - virtual int Listen(int backlog) { - ASSERT(SOCK_STREAM == type_); - ASSERT(CS_CLOSED == state_); - if (local_addr_.IsNil()) { - error_ = EINVAL; - return -1; - } - ASSERT(NULL == listen_queue_); - listen_queue_ = new ListenQueue; - state_ = CS_CONNECTING; - return 0; - } - - virtual VirtualSocket* Accept(SocketAddress *paddr) { - if (NULL == listen_queue_) { - error_ = EINVAL; - return NULL; - } - while (!listen_queue_->empty()) { - VirtualSocket* socket = new VirtualSocket(server_, AF_INET, type_, - async_); - - // Set the new local address to the same as this server socket. - socket->SetLocalAddress(local_addr_); - // Sockets made from a socket that 'was Any' need to inherit that. - socket->set_was_any(was_any_); - SocketAddress remote_addr(listen_queue_->front()); - int result = socket->InitiateConnect(remote_addr, false); - listen_queue_->pop_front(); - if (result != 0) { - delete socket; - continue; - } - socket->CompleteConnect(remote_addr, false); - if (paddr) { - *paddr = remote_addr; - } - return socket; - } - error_ = EWOULDBLOCK; - return NULL; - } - - virtual int GetError() const { - return error_; - } - - virtual void SetError(int error) { - error_ = error; - } - - virtual ConnState GetState() const { - return state_; - } - - virtual int GetOption(Option opt, int* value) { - OptionsMap::const_iterator it = options_map_.find(opt); - if (it == options_map_.end()) { - return -1; - } - *value = it->second; - return 0; // 0 is success to emulate getsockopt() - } - - virtual int SetOption(Option opt, int value) { - options_map_[opt] = value; - return 0; // 0 is success to emulate setsockopt() - } - - virtual int EstimateMTU(uint16* mtu) { - if (CS_CONNECTED != state_) - return ENOTCONN; - else - return 65536; - } - - void OnMessage(Message *pmsg) { - if (pmsg->message_id == MSG_ID_PACKET) { - //ASSERT(!local_addr_.IsAny()); - ASSERT(NULL != pmsg->pdata); - Packet* packet = static_cast(pmsg->pdata); - - recv_buffer_.push_back(packet); - - if (async_) { - SignalReadEvent(this); - } - } else if (pmsg->message_id == MSG_ID_CONNECT) { - ASSERT(NULL != pmsg->pdata); - MessageAddress* data = static_cast(pmsg->pdata); - if (listen_queue_ != NULL) { - listen_queue_->push_back(data->addr); - if (async_) { - SignalReadEvent(this); - } - } else if ((SOCK_STREAM == type_) && (CS_CONNECTING == state_)) { - CompleteConnect(data->addr, true); - } else { - LOG(LS_VERBOSE) << "Socket at " << local_addr_ << " is not listening"; - server_->Disconnect(server_->LookupBinding(data->addr)); - } - delete data; - } else if (pmsg->message_id == MSG_ID_DISCONNECT) { - ASSERT(SOCK_STREAM == type_); - if (CS_CLOSED != state_) { - int error = (CS_CONNECTING == state_) ? ECONNREFUSED : 0; - state_ = CS_CLOSED; - remote_addr_.Clear(); - if (async_) { - SignalCloseEvent(this, error); - } - } - } else { - ASSERT(false); - } - } - - bool was_any() { return was_any_; } - void set_was_any(bool was_any) { was_any_ = was_any; } - - private: - struct NetworkEntry { - size_t size; - uint32 done_time; - }; - - typedef std::deque ListenQueue; - typedef std::deque NetworkQueue; - typedef std::vector SendBuffer; - typedef std::list RecvBuffer; - typedef std::map OptionsMap; - - int InitiateConnect(const SocketAddress& addr, bool use_delay) { - if (!remote_addr_.IsNil()) { - error_ = (CS_CONNECTED == state_) ? EISCONN : EINPROGRESS; - return -1; - } - if (local_addr_.IsNil()) { - // If there's no local address set, grab a random one in the correct AF. - int result = 0; - if (addr.ipaddr().family() == AF_INET) { - result = Bind(SocketAddress("0.0.0.0", 0)); - } else if (addr.ipaddr().family() == AF_INET6) { - result = Bind(SocketAddress("::", 0)); - } - if (result != 0) { - return result; - } - } - if (type_ == SOCK_DGRAM) { - remote_addr_ = addr; - state_ = CS_CONNECTED; - } else { - int result = server_->Connect(this, addr, use_delay); - if (result != 0) { - error_ = EHOSTUNREACH; - return -1; - } - state_ = CS_CONNECTING; - } - return 0; - } - - void CompleteConnect(const SocketAddress& addr, bool notify) { - ASSERT(CS_CONNECTING == state_); - remote_addr_ = addr; - state_ = CS_CONNECTED; - server_->AddConnection(remote_addr_, local_addr_, this); - if (async_ && notify) { - SignalConnectEvent(this); - } - } - - int SendUdp(const void* pv, size_t cb, const SocketAddress& addr) { - // If we have not been assigned a local port, then get one. - if (local_addr_.IsNil()) { - local_addr_ = EmptySocketAddressWithFamily(addr.ipaddr().family()); - int result = server_->Bind(this, &local_addr_); - if (result != 0) { - local_addr_.Clear(); - error_ = EADDRINUSE; - return result; - } - } - - // Send the data in a message to the appropriate socket. - return server_->SendUdp(this, static_cast(pv), cb, addr); - } - - int SendTcp(const void* pv, size_t cb) { - size_t capacity = server_->send_buffer_capacity_ - send_buffer_.size(); - if (0 == capacity) { - write_enabled_ = true; - error_ = EWOULDBLOCK; - return -1; - } - size_t consumed = _min(cb, capacity); - const char* cpv = static_cast(pv); - send_buffer_.insert(send_buffer_.end(), cpv, cpv + consumed); - server_->SendTcp(this); - return static_cast(consumed); - } - - VirtualSocketServer* server_; - int family_; - int type_; - bool async_; - ConnState state_; - int error_; - SocketAddress local_addr_; - SocketAddress remote_addr_; - - // Pending sockets which can be Accepted - ListenQueue* listen_queue_; - - // Data which tcp has buffered for sending - SendBuffer send_buffer_; - bool write_enabled_; - - // Critical section to protect the recv_buffer and queue_ - CriticalSection crit_; - - // Network model that enforces bandwidth and capacity constraints - NetworkQueue network_; - size_t network_size_; - - // Data which has been received from the network - RecvBuffer recv_buffer_; - // The amount of data which is in flight or in recv_buffer_ - size_t recv_buffer_size_; - - // Is this socket bound? - bool bound_; - - // When we bind a socket to Any, VSS's Bind gives it another address. For - // dual-stack sockets, we want to distinguish between sockets that were - // explicitly given a particular address and sockets that had one picked - // for them by VSS. - bool was_any_; - - // Store the options that are set - OptionsMap options_map_; - - friend class VirtualSocketServer; -}; - -VirtualSocketServer::VirtualSocketServer(SocketServer* ss) - : server_(ss), server_owned_(false), msg_queue_(NULL), stop_on_idle_(false), - network_delay_(Time()), next_ipv4_(kInitialNextIPv4), - next_ipv6_(kInitialNextIPv6), next_port_(kFirstEphemeralPort), - bindings_(new AddressMap()), connections_(new ConnectionMap()), - bandwidth_(0), network_capacity_(kDefaultNetworkCapacity), - send_buffer_capacity_(kDefaultTcpBufferSize), - recv_buffer_capacity_(kDefaultTcpBufferSize), - delay_mean_(0), delay_stddev_(0), delay_samples_(NUM_SAMPLES), - delay_dist_(NULL), drop_prob_(0.0) { - if (!server_) { - server_ = new PhysicalSocketServer(); - server_owned_ = true; - } - UpdateDelayDistribution(); -} - -VirtualSocketServer::~VirtualSocketServer() { - delete bindings_; - delete connections_; - delete delay_dist_; - if (server_owned_) { - delete server_; - } -} - -IPAddress VirtualSocketServer::GetNextIP(int family) { - if (family == AF_INET) { - IPAddress next_ip(next_ipv4_); - next_ipv4_.s_addr = - HostToNetwork32(NetworkToHost32(next_ipv4_.s_addr) + 1); - return next_ip; - } else if (family == AF_INET6) { - IPAddress next_ip(next_ipv6_); - uint32* as_ints = reinterpret_cast(&next_ipv6_.s6_addr); - as_ints[3] += 1; - return next_ip; - } - return IPAddress(); -} - -uint16 VirtualSocketServer::GetNextPort() { - uint16 port = next_port_; - if (next_port_ < kLastEphemeralPort) { - ++next_port_; - } else { - next_port_ = kFirstEphemeralPort; - } - return port; -} - -Socket* VirtualSocketServer::CreateSocket(int type) { - return CreateSocket(AF_INET, type); -} - -Socket* VirtualSocketServer::CreateSocket(int family, int type) { - return CreateSocketInternal(family, type); -} - -AsyncSocket* VirtualSocketServer::CreateAsyncSocket(int type) { - return CreateAsyncSocket(AF_INET, type); -} - -AsyncSocket* VirtualSocketServer::CreateAsyncSocket(int family, int type) { - return CreateSocketInternal(family, type); -} - -VirtualSocket* VirtualSocketServer::CreateSocketInternal(int family, int type) { - return new VirtualSocket(this, family, type, true); -} - -void VirtualSocketServer::SetMessageQueue(MessageQueue* msg_queue) { - msg_queue_ = msg_queue; - if (msg_queue_) { - msg_queue_->SignalQueueDestroyed.connect(this, - &VirtualSocketServer::OnMessageQueueDestroyed); - } -} - -bool VirtualSocketServer::Wait(int cmsWait, bool process_io) { - ASSERT(msg_queue_ == Thread::Current()); - if (stop_on_idle_ && Thread::Current()->empty()) { - return false; - } - return socketserver()->Wait(cmsWait, process_io); -} - -void VirtualSocketServer::WakeUp() { - socketserver()->WakeUp(); -} - -bool VirtualSocketServer::ProcessMessagesUntilIdle() { - ASSERT(msg_queue_ == Thread::Current()); - stop_on_idle_ = true; - while (!msg_queue_->empty()) { - Message msg; - if (msg_queue_->Get(&msg, kForever)) { - msg_queue_->Dispatch(&msg); - } - } - stop_on_idle_ = false; - return !msg_queue_->IsQuitting(); -} - -int VirtualSocketServer::Bind(VirtualSocket* socket, - const SocketAddress& addr) { - ASSERT(NULL != socket); - // Address must be completely specified at this point - ASSERT(!IPIsUnspec(addr.ipaddr())); - ASSERT(addr.port() != 0); - - // Normalize the address (turns v6-mapped addresses into v4-addresses). - SocketAddress normalized(addr.ipaddr().Normalized(), addr.port()); - - AddressMap::value_type entry(normalized, socket); - return bindings_->insert(entry).second ? 0 : -1; -} - -int VirtualSocketServer::Bind(VirtualSocket* socket, SocketAddress* addr) { - ASSERT(NULL != socket); - - if (IPIsAny(addr->ipaddr())) { - addr->SetIP(GetNextIP(addr->ipaddr().family())); - } else if (!IPIsUnspec(addr->ipaddr())) { - addr->SetIP(addr->ipaddr().Normalized()); - } else { - ASSERT(false); - } - - if (addr->port() == 0) { - for (int i = 0; i < kEphemeralPortCount; ++i) { - addr->SetPort(GetNextPort()); - if (bindings_->find(*addr) == bindings_->end()) { - break; - } - } - } - - return Bind(socket, *addr); -} - -VirtualSocket* VirtualSocketServer::LookupBinding(const SocketAddress& addr) { - SocketAddress normalized(addr.ipaddr().Normalized(), - addr.port()); - AddressMap::iterator it = bindings_->find(normalized); - return (bindings_->end() != it) ? it->second : NULL; -} - -int VirtualSocketServer::Unbind(const SocketAddress& addr, - VirtualSocket* socket) { - SocketAddress normalized(addr.ipaddr().Normalized(), - addr.port()); - ASSERT((*bindings_)[normalized] == socket); - bindings_->erase(bindings_->find(normalized)); - return 0; -} - -void VirtualSocketServer::AddConnection(const SocketAddress& local, - const SocketAddress& remote, - VirtualSocket* remote_socket) { - // Add this socket pair to our routing table. This will allow - // multiple clients to connect to the same server address. - SocketAddress local_normalized(local.ipaddr().Normalized(), - local.port()); - SocketAddress remote_normalized(remote.ipaddr().Normalized(), - remote.port()); - SocketAddressPair address_pair(local_normalized, remote_normalized); - connections_->insert(std::pair(address_pair, remote_socket)); -} - -VirtualSocket* VirtualSocketServer::LookupConnection( - const SocketAddress& local, - const SocketAddress& remote) { - SocketAddress local_normalized(local.ipaddr().Normalized(), - local.port()); - SocketAddress remote_normalized(remote.ipaddr().Normalized(), - remote.port()); - SocketAddressPair address_pair(local_normalized, remote_normalized); - ConnectionMap::iterator it = connections_->find(address_pair); - return (connections_->end() != it) ? it->second : NULL; -} - -void VirtualSocketServer::RemoveConnection(const SocketAddress& local, - const SocketAddress& remote) { - SocketAddress local_normalized(local.ipaddr().Normalized(), - local.port()); - SocketAddress remote_normalized(remote.ipaddr().Normalized(), - remote.port()); - SocketAddressPair address_pair(local_normalized, remote_normalized); - connections_->erase(address_pair); -} - -static double Random() { - return static_cast(rand()) / RAND_MAX; -} - -int VirtualSocketServer::Connect(VirtualSocket* socket, - const SocketAddress& remote_addr, - bool use_delay) { - uint32 delay = use_delay ? GetRandomTransitDelay() : 0; - VirtualSocket* remote = LookupBinding(remote_addr); - if (!CanInteractWith(socket, remote)) { - LOG(LS_INFO) << "Address family mismatch between " - << socket->GetLocalAddress() << " and " << remote_addr; - return -1; - } - if (remote != NULL) { - SocketAddress addr = socket->GetLocalAddress(); - msg_queue_->PostDelayed(delay, remote, MSG_ID_CONNECT, - new MessageAddress(addr)); - } else { - LOG(LS_INFO) << "No one listening at " << remote_addr; - msg_queue_->PostDelayed(delay, socket, MSG_ID_DISCONNECT); - } - return 0; -} - -bool VirtualSocketServer::Disconnect(VirtualSocket* socket) { - if (socket) { - // Remove the mapping. - msg_queue_->Post(socket, MSG_ID_DISCONNECT); - return true; - } - return false; -} - -int VirtualSocketServer::SendUdp(VirtualSocket* socket, - const char* data, size_t data_size, - const SocketAddress& remote_addr) { - // See if we want to drop this packet. - if (Random() < drop_prob_) { - LOG(LS_VERBOSE) << "Dropping packet: bad luck"; - return static_cast(data_size); - } - - VirtualSocket* recipient = LookupBinding(remote_addr); - if (!recipient) { - // Make a fake recipient for address family checking. - scoped_ptr dummy_socket( - CreateSocketInternal(AF_INET, SOCK_DGRAM)); - dummy_socket->SetLocalAddress(remote_addr); - if (!CanInteractWith(socket, dummy_socket.get())) { - LOG(LS_VERBOSE) << "Incompatible address families: " - << socket->GetLocalAddress() << " and " << remote_addr; - return -1; - } - LOG(LS_VERBOSE) << "No one listening at " << remote_addr; - return static_cast(data_size); - } - - if (!CanInteractWith(socket, recipient)) { - LOG(LS_VERBOSE) << "Incompatible address families: " - << socket->GetLocalAddress() << " and " << remote_addr; - return -1; - } - - CritScope cs(&socket->crit_); - - uint32 cur_time = Time(); - PurgeNetworkPackets(socket, cur_time); - - // Determine whether we have enough bandwidth to accept this packet. To do - // this, we need to update the send queue. Once we know it's current size, - // we know whether we can fit this packet. - // - // NOTE: There are better algorithms for maintaining such a queue (such as - // "Derivative Random Drop"); however, this algorithm is a more accurate - // simulation of what a normal network would do. - - size_t packet_size = data_size + UDP_HEADER_SIZE; - if (socket->network_size_ + packet_size > network_capacity_) { - LOG(LS_VERBOSE) << "Dropping packet: network capacity exceeded"; - return static_cast(data_size); - } - - AddPacketToNetwork(socket, recipient, cur_time, data, data_size, - UDP_HEADER_SIZE, false); - - return static_cast(data_size); -} - -void VirtualSocketServer::SendTcp(VirtualSocket* socket) { - // TCP can't send more data than will fill up the receiver's buffer. - // We track the data that is in the buffer plus data in flight using the - // recipient's recv_buffer_size_. Anything beyond that must be stored in the - // sender's buffer. We will trigger the buffered data to be sent when data - // is read from the recv_buffer. - - // Lookup the local/remote pair in the connections table. - VirtualSocket* recipient = LookupConnection(socket->local_addr_, - socket->remote_addr_); - if (!recipient) { - LOG(LS_VERBOSE) << "Sending data to no one."; - return; - } - - CritScope cs(&socket->crit_); - - uint32 cur_time = Time(); - PurgeNetworkPackets(socket, cur_time); - - while (true) { - size_t available = recv_buffer_capacity_ - recipient->recv_buffer_size_; - size_t max_data_size = _min(available, TCP_MSS - TCP_HEADER_SIZE); - size_t data_size = _min(socket->send_buffer_.size(), max_data_size); - if (0 == data_size) - break; - - AddPacketToNetwork(socket, recipient, cur_time, &socket->send_buffer_[0], - data_size, TCP_HEADER_SIZE, true); - recipient->recv_buffer_size_ += data_size; - - size_t new_buffer_size = socket->send_buffer_.size() - data_size; - // Avoid undefined access beyond the last element of the vector. - // This only happens when new_buffer_size is 0. - if (data_size < socket->send_buffer_.size()) { - // memmove is required for potentially overlapping source/destination. - memmove(&socket->send_buffer_[0], &socket->send_buffer_[data_size], - new_buffer_size); - } - socket->send_buffer_.resize(new_buffer_size); - } - - if (socket->write_enabled_ - && (socket->send_buffer_.size() < send_buffer_capacity_)) { - socket->write_enabled_ = false; - socket->SignalWriteEvent(socket); - } -} - -void VirtualSocketServer::AddPacketToNetwork(VirtualSocket* sender, - VirtualSocket* recipient, - uint32 cur_time, - const char* data, - size_t data_size, - size_t header_size, - bool ordered) { - VirtualSocket::NetworkEntry entry; - entry.size = data_size + header_size; - - sender->network_size_ += entry.size; - uint32 send_delay = SendDelay(static_cast(sender->network_size_)); - entry.done_time = cur_time + send_delay; - sender->network_.push_back(entry); - - // Find the delay for crossing the many virtual hops of the network. - uint32 transit_delay = GetRandomTransitDelay(); - - // Post the packet as a message to be delivered (on our own thread) - Packet* p = new Packet(data, data_size, sender->local_addr_); - uint32 ts = TimeAfter(send_delay + transit_delay); - if (ordered) { - // Ensure that new packets arrive after previous ones - // TODO: consider ordering on a per-socket basis, since this - // introduces artifical delay. - ts = TimeMax(ts, network_delay_); - } - msg_queue_->PostAt(ts, recipient, MSG_ID_PACKET, p); - network_delay_ = TimeMax(ts, network_delay_); -} - -void VirtualSocketServer::PurgeNetworkPackets(VirtualSocket* socket, - uint32 cur_time) { - while (!socket->network_.empty() && - (socket->network_.front().done_time <= cur_time)) { - ASSERT(socket->network_size_ >= socket->network_.front().size); - socket->network_size_ -= socket->network_.front().size; - socket->network_.pop_front(); - } -} - -uint32 VirtualSocketServer::SendDelay(uint32 size) { - if (bandwidth_ == 0) - return 0; - else - return 1000 * size / bandwidth_; -} - -#if 0 -void PrintFunction(std::vector >* f) { - return; - double sum = 0; - for (uint32 i = 0; i < f->size(); ++i) { - std::cout << (*f)[i].first << '\t' << (*f)[i].second << std::endl; - sum += (*f)[i].second; - } - if (!f->empty()) { - const double mean = sum / f->size(); - double sum_sq_dev = 0; - for (uint32 i = 0; i < f->size(); ++i) { - double dev = (*f)[i].second - mean; - sum_sq_dev += dev * dev; - } - std::cout << "Mean = " << mean << " StdDev = " - << sqrt(sum_sq_dev / f->size()) << std::endl; - } -} -#endif // - -void VirtualSocketServer::UpdateDelayDistribution() { - Function* dist = CreateDistribution(delay_mean_, delay_stddev_, - delay_samples_); - // We take a lock just to make sure we don't leak memory. - { - CritScope cs(&delay_crit_); - delete delay_dist_; - delay_dist_ = dist; - } -} - -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 exp(-a) / (stddev * sqrt(2 * PI)); -} - -#if 0 // static unused gives a warning -static double Pareto(double x, double min, double k) { - if (x < min) - return 0; - else - return k * std::pow(min, k) / std::pow(x, k+1); -} -#endif - -VirtualSocketServer::Function* VirtualSocketServer::CreateDistribution( - uint32 mean, uint32 stddev, uint32 samples) { - Function* f = new Function(); - - if (0 == stddev) { - f->push_back(Point(mean, 1.0)); - } else { - double start = 0; - if (mean >= 4 * static_cast(stddev)) - start = mean - 4 * static_cast(stddev); - double end = mean + 4 * static_cast(stddev); - - for (uint32 i = 0; i < samples; i++) { - double x = start + (end - start) * i / (samples - 1); - double y = Normal(x, mean, stddev); - f->push_back(Point(x, y)); - } - } - return Resample(Invert(Accumulate(f)), 0, 1, samples); -} - -uint32 VirtualSocketServer::GetRandomTransitDelay() { - size_t index = rand() % delay_dist_->size(); - double delay = (*delay_dist_)[index].second; - //LOG_F(LS_INFO) << "random[" << index << "] = " << delay; - return static_cast(delay); -} - -struct FunctionDomainCmp { - bool operator()(const VirtualSocketServer::Point& p1, - const VirtualSocketServer::Point& p2) { - return p1.first < p2.first; - } - bool operator()(double v1, const VirtualSocketServer::Point& p2) { - return v1 < p2.first; - } - bool operator()(const VirtualSocketServer::Point& p1, double v2) { - return p1.first < v2; - } -}; - -VirtualSocketServer::Function* VirtualSocketServer::Accumulate(Function* f) { - ASSERT(f->size() >= 1); - double v = 0; - for (Function::size_type i = 0; i < f->size() - 1; ++i) { - double dx = (*f)[i + 1].first - (*f)[i].first; - double avgy = ((*f)[i + 1].second + (*f)[i].second) / 2; - (*f)[i].second = v; - v = v + dx * avgy; - } - (*f)[f->size()-1].second = v; - return f; -} - -VirtualSocketServer::Function* VirtualSocketServer::Invert(Function* f) { - for (Function::size_type i = 0; i < f->size(); ++i) - std::swap((*f)[i].first, (*f)[i].second); - - std::sort(f->begin(), f->end(), FunctionDomainCmp()); - return f; -} - -VirtualSocketServer::Function* VirtualSocketServer::Resample( - Function* f, double x1, double x2, uint32 samples) { - Function* g = new Function(); - - for (size_t i = 0; i < samples; i++) { - double x = x1 + (x2 - x1) * i / (samples - 1); - double y = Evaluate(f, x); - g->push_back(Point(x, y)); - } - - delete f; - return g; -} - -double VirtualSocketServer::Evaluate(Function* f, double x) { - Function::iterator iter = - std::lower_bound(f->begin(), f->end(), x, FunctionDomainCmp()); - if (iter == f->begin()) { - return (*f)[0].second; - } else if (iter == f->end()) { - ASSERT(f->size() >= 1); - return (*f)[f->size() - 1].second; - } else if (iter->first == x) { - return iter->second; - } else { - double x1 = (iter - 1)->first; - double y1 = (iter - 1)->second; - double x2 = iter->first; - double y2 = iter->second; - return y1 + (y2 - y1) * (x - x1) / (x2 - x1); - } -} - -bool VirtualSocketServer::CanInteractWith(VirtualSocket* local, - VirtualSocket* remote) { - if (!local || !remote) { - return false; - } - IPAddress local_ip = local->GetLocalAddress().ipaddr(); - IPAddress remote_ip = remote->GetLocalAddress().ipaddr(); - IPAddress local_normalized = local_ip.Normalized(); - IPAddress remote_normalized = remote_ip.Normalized(); - // Check if the addresses are the same family after Normalization (turns - // mapped IPv6 address into IPv4 addresses). - // This will stop unmapped V6 addresses from talking to mapped V6 addresses. - if (local_normalized.family() == remote_normalized.family()) { - return true; - } - - // If ip1 is IPv4 and ip2 is :: and ip2 is not IPV6_V6ONLY. - int remote_v6_only = 0; - remote->GetOption(Socket::OPT_IPV6_V6ONLY, &remote_v6_only); - if (local_ip.family() == AF_INET && !remote_v6_only && IPIsAny(remote_ip)) { - return true; - } - // Same check, backwards. - int local_v6_only = 0; - local->GetOption(Socket::OPT_IPV6_V6ONLY, &local_v6_only); - if (remote_ip.family() == AF_INET && !local_v6_only && IPIsAny(local_ip)) { - return true; - } - - // Check to see if either socket was explicitly bound to IPv6-any. - // These sockets can talk with anyone. - if (local_ip.family() == AF_INET6 && local->was_any()) { - return true; - } - if (remote_ip.family() == AF_INET6 && remote->was_any()) { - return true; - } - - return false; -} - -} // namespace rtc diff --git a/webrtc/base/virtualsocketserver.h b/webrtc/base/virtualsocketserver.h deleted file mode 100644 index 87e35364c..000000000 --- a/webrtc/base/virtualsocketserver.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_VIRTUALSOCKETSERVER_H_ -#define WEBRTC_BASE_VIRTUALSOCKETSERVER_H_ - -#include - -#include -#include - -#include "webrtc/base/messagequeue.h" -#include "webrtc/base/socketserver.h" - -namespace rtc { - -class VirtualSocket; -class SocketAddressPair; - -// Simulates a network in the same manner as a loopback interface. The -// interface can create as many addresses as you want. All of the sockets -// created by this network will be able to communicate with one another, unless -// they are bound to addresses from incompatible families. -class VirtualSocketServer : public SocketServer, public sigslot::has_slots<> { - public: - // TODO: Add "owned" parameter. - // If "owned" is set, the supplied socketserver will be deleted later. - explicit VirtualSocketServer(SocketServer* ss); - virtual ~VirtualSocketServer(); - - SocketServer* socketserver() { return server_; } - - // Limits the network bandwidth (maximum bytes per second). Zero means that - // all sends occur instantly. Defaults to 0. - uint32 bandwidth() const { return bandwidth_; } - void set_bandwidth(uint32 bandwidth) { bandwidth_ = bandwidth; } - - // Limits the amount of data which can be in flight on the network without - // packet loss (on a per sender basis). Defaults to 64 KB. - uint32 network_capacity() const { return network_capacity_; } - void set_network_capacity(uint32 capacity) { - network_capacity_ = capacity; - } - - // The amount of data which can be buffered by tcp on the sender's side - uint32 send_buffer_capacity() const { return send_buffer_capacity_; } - void set_send_buffer_capacity(uint32 capacity) { - send_buffer_capacity_ = capacity; - } - - // The amount of data which can be buffered by tcp on the receiver's side - uint32 recv_buffer_capacity() const { return recv_buffer_capacity_; } - void set_recv_buffer_capacity(uint32 capacity) { - recv_buffer_capacity_ = capacity; - } - - // Controls the (transit) delay for packets sent in the network. This does - // not inclue the time required to sit in the send queue. Both of these - // values are measured in milliseconds. Defaults to no delay. - uint32 delay_mean() const { return delay_mean_; } - uint32 delay_stddev() const { return delay_stddev_; } - uint32 delay_samples() const { return delay_samples_; } - void set_delay_mean(uint32 delay_mean) { delay_mean_ = delay_mean; } - void set_delay_stddev(uint32 delay_stddev) { - delay_stddev_ = delay_stddev; - } - void set_delay_samples(uint32 delay_samples) { - delay_samples_ = delay_samples; - } - - // If the (transit) delay parameters are modified, this method should be - // called to recompute the new distribution. - void UpdateDelayDistribution(); - - // Controls the (uniform) probability that any sent packet is dropped. This - // is separate from calculations to drop based on queue size. - double drop_probability() { return drop_prob_; } - void set_drop_probability(double drop_prob) { - assert((0 <= drop_prob) && (drop_prob <= 1)); - drop_prob_ = drop_prob; - } - - // SocketFactory: - virtual Socket* CreateSocket(int type); - virtual Socket* CreateSocket(int family, int type); - - virtual AsyncSocket* CreateAsyncSocket(int type); - virtual AsyncSocket* CreateAsyncSocket(int family, int type); - - // SocketServer: - virtual void SetMessageQueue(MessageQueue* queue); - virtual bool Wait(int cms, bool process_io); - virtual void WakeUp(); - - typedef std::pair Point; - typedef std::vector Function; - - static Function* CreateDistribution(uint32 mean, uint32 stddev, - uint32 samples); - - // Similar to Thread::ProcessMessages, but it only processes messages until - // there are no immediate messages or pending network traffic. Returns false - // if Thread::Stop() was called. - bool ProcessMessagesUntilIdle(); - - protected: - // Returns a new IP not used before in this network. - IPAddress GetNextIP(int family); - uint16 GetNextPort(); - - VirtualSocket* CreateSocketInternal(int family, int type); - - // Binds the given socket to addr, assigning and IP and Port if necessary - int Bind(VirtualSocket* socket, SocketAddress* addr); - - // Binds the given socket to the given (fully-defined) address. - int Bind(VirtualSocket* socket, const SocketAddress& addr); - - // Find the socket bound to the given address - VirtualSocket* LookupBinding(const SocketAddress& addr); - - int Unbind(const SocketAddress& addr, VirtualSocket* socket); - - // Adds a mapping between this socket pair and the socket. - void AddConnection(const SocketAddress& client, - const SocketAddress& server, - VirtualSocket* socket); - - // Find the socket pair corresponding to this server address. - VirtualSocket* LookupConnection(const SocketAddress& client, - const SocketAddress& server); - - void RemoveConnection(const SocketAddress& client, - const SocketAddress& server); - - // Connects the given socket to the socket at the given address - int Connect(VirtualSocket* socket, const SocketAddress& remote_addr, - bool use_delay); - - // Sends a disconnect message to the socket at the given address - bool Disconnect(VirtualSocket* socket); - - // Sends the given packet to the socket at the given address (if one exists). - int SendUdp(VirtualSocket* socket, const char* data, size_t data_size, - const SocketAddress& remote_addr); - - // Moves as much data as possible from the sender's buffer to the network - void SendTcp(VirtualSocket* socket); - - // Places a packet on the network. - void AddPacketToNetwork(VirtualSocket* socket, VirtualSocket* recipient, - uint32 cur_time, const char* data, size_t data_size, - size_t header_size, bool ordered); - - // Removes stale packets from the network - void PurgeNetworkPackets(VirtualSocket* socket, uint32 cur_time); - - // Computes the number of milliseconds required to send a packet of this size. - uint32 SendDelay(uint32 size); - - // Returns a random transit delay chosen from the appropriate distribution. - uint32 GetRandomTransitDelay(); - - // Basic operations on functions. Those that return a function also take - // ownership of the function given (and hence, may modify or delete it). - static Function* Accumulate(Function* f); - static Function* Invert(Function* f); - static Function* Resample(Function* f, double x1, double x2, uint32 samples); - static double Evaluate(Function* f, double x); - - // NULL out our message queue if it goes away. Necessary in the case where - // our lifetime is greater than that of the thread we are using, since we - // try to send Close messages for all connected sockets when we shutdown. - void OnMessageQueueDestroyed() { msg_queue_ = NULL; } - - // Determine if two sockets should be able to communicate. - // We don't (currently) specify an address family for sockets; instead, - // the currently bound address is used to infer the address family. - // Any socket that is not explicitly bound to an IPv4 address is assumed to be - // dual-stack capable. - // This function tests if two addresses can communicate, as well as the - // sockets to which they may be bound (the addresses may or may not yet be - // bound to the sockets). - // First the addresses are tested (after normalization): - // If both have the same family, then communication is OK. - // If only one is IPv4 then false, unless the other is bound to ::. - // This applies even if the IPv4 address is 0.0.0.0. - // The socket arguments are optional; the sockets are checked to see if they - // were explicitly bound to IPv6-any ('::'), and if so communication is - // permitted. - // NB: This scheme doesn't permit non-dualstack IPv6 sockets. - static bool CanInteractWith(VirtualSocket* local, VirtualSocket* remote); - - private: - friend class VirtualSocket; - - typedef std::map AddressMap; - typedef std::map ConnectionMap; - - SocketServer* server_; - bool server_owned_; - MessageQueue* msg_queue_; - bool stop_on_idle_; - uint32 network_delay_; - in_addr next_ipv4_; - in6_addr next_ipv6_; - uint16 next_port_; - AddressMap* bindings_; - ConnectionMap* connections_; - - uint32 bandwidth_; - uint32 network_capacity_; - uint32 send_buffer_capacity_; - uint32 recv_buffer_capacity_; - uint32 delay_mean_; - uint32 delay_stddev_; - uint32 delay_samples_; - Function* delay_dist_; - CriticalSection delay_crit_; - - double drop_prob_; - DISALLOW_EVIL_CONSTRUCTORS(VirtualSocketServer); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_VIRTUALSOCKETSERVER_H_ diff --git a/webrtc/base/win32.cc b/webrtc/base/win32.cc deleted file mode 100644 index 8f5661225..000000000 --- a/webrtc/base/win32.cc +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/win32.h" - -#include -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/byteorder.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -// Helper function declarations for inet_ntop/inet_pton. -static const char* inet_ntop_v4(const void* src, char* dst, socklen_t size); -static const char* inet_ntop_v6(const void* src, char* dst, socklen_t size); -static int inet_pton_v4(const char* src, void* dst); -static int inet_pton_v6(const char* src, void* dst); - -// Implementation of inet_ntop (create a printable representation of an -// ip address). XP doesn't have its own inet_ntop, and -// WSAAddressToString requires both IPv6 to be installed and for Winsock -// to be initialized. -const char* win32_inet_ntop(int af, const void *src, - char* dst, socklen_t size) { - if (!src || !dst) { - return NULL; - } - switch (af) { - case AF_INET: { - return inet_ntop_v4(src, dst, size); - } - case AF_INET6: { - return inet_ntop_v6(src, dst, size); - } - } - return NULL; -} - -// As above, but for inet_pton. Implements inet_pton for v4 and v6. -// Note that our inet_ntop will output normal 'dotted' v4 addresses only. -int win32_inet_pton(int af, const char* src, void* dst) { - if (!src || !dst) { - return 0; - } - if (af == AF_INET) { - return inet_pton_v4(src, dst); - } else if (af == AF_INET6) { - return inet_pton_v6(src, dst); - } - return -1; -} - -// Helper function for inet_ntop for IPv4 addresses. -// Outputs "dotted-quad" decimal notation. -const char* inet_ntop_v4(const void* src, char* dst, socklen_t size) { - if (size < INET_ADDRSTRLEN) { - return NULL; - } - const struct in_addr* as_in_addr = - reinterpret_cast(src); - rtc::sprintfn(dst, size, "%d.%d.%d.%d", - as_in_addr->S_un.S_un_b.s_b1, - as_in_addr->S_un.S_un_b.s_b2, - as_in_addr->S_un.S_un_b.s_b3, - as_in_addr->S_un.S_un_b.s_b4); - return dst; -} - -// Helper function for inet_ntop for IPv6 addresses. -const char* inet_ntop_v6(const void* src, char* dst, socklen_t size) { - if (size < INET6_ADDRSTRLEN) { - return NULL; - } - const uint16* as_shorts = - reinterpret_cast(src); - int runpos[8]; - int current = 1; - int max = 1; - int maxpos = -1; - int run_array_size = ARRAY_SIZE(runpos); - // Run over the address marking runs of 0s. - for (int i = 0; i < run_array_size; ++i) { - if (as_shorts[i] == 0) { - runpos[i] = current; - if (current > max) { - maxpos = i; - max = current; - } - ++current; - } else { - runpos[i] = -1; - current =1; - } - } - - if (max > 1) { - int tmpmax = maxpos; - // Run back through, setting -1 for all but the longest run. - for (int i = run_array_size - 1; i >= 0; i--) { - if (i > tmpmax) { - runpos[i] = -1; - } else if (runpos[i] == -1) { - // We're less than maxpos, we hit a -1, so the 'good' run is done. - // Setting tmpmax -1 means all remaining positions get set to -1. - tmpmax = -1; - } - } - } - - char* cursor = dst; - // Print IPv4 compatible and IPv4 mapped addresses using the IPv4 helper. - // These addresses have an initial run of either eight zero-bytes followed - // by 0xFFFF, or an initial run of ten zero-bytes. - if (runpos[0] == 1 && (maxpos == 5 || - (maxpos == 4 && as_shorts[5] == 0xFFFF))) { - *cursor++ = ':'; - *cursor++ = ':'; - if (maxpos == 4) { - cursor += rtc::sprintfn(cursor, INET6_ADDRSTRLEN - 2, "ffff:"); - } - const struct in_addr* as_v4 = - reinterpret_cast(&(as_shorts[6])); - inet_ntop_v4(as_v4, cursor, - static_cast(INET6_ADDRSTRLEN - (cursor - dst))); - } else { - for (int i = 0; i < run_array_size; ++i) { - if (runpos[i] == -1) { - cursor += rtc::sprintfn(cursor, - INET6_ADDRSTRLEN - (cursor - dst), - "%x", NetworkToHost16(as_shorts[i])); - if (i != 7 && runpos[i + 1] != 1) { - *cursor++ = ':'; - } - } else if (runpos[i] == 1) { - // Entered the run; print the colons and skip the run. - *cursor++ = ':'; - *cursor++ = ':'; - i += (max - 1); - } - } - } - return dst; -} - -// Helper function for inet_pton for IPv4 addresses. -// |src| points to a character string containing an IPv4 network address in -// dotted-decimal format, "ddd.ddd.ddd.ddd", where ddd is a decimal number -// of up to three digits in the range 0 to 255. -// The address is converted and copied to dst, -// which must be sizeof(struct in_addr) (4) bytes (32 bits) long. -int inet_pton_v4(const char* src, void* dst) { - const int kIpv4AddressSize = 4; - int found = 0; - const char* src_pos = src; - unsigned char result[kIpv4AddressSize] = {0}; - - while (*src_pos != '\0') { - // strtol won't treat whitespace characters in the begining as an error, - // so check to ensure this is started with digit before passing to strtol. - if (!isdigit(*src_pos)) { - return 0; - } - char* end_pos; - long value = strtol(src_pos, &end_pos, 10); - if (value < 0 || value > 255 || src_pos == end_pos) { - return 0; - } - ++found; - if (found > kIpv4AddressSize) { - return 0; - } - result[found - 1] = static_cast(value); - src_pos = end_pos; - if (*src_pos == '.') { - // There's more. - ++src_pos; - } else if (*src_pos != '\0') { - // If it's neither '.' nor '\0' then return fail. - return 0; - } - } - if (found != kIpv4AddressSize) { - return 0; - } - memcpy(dst, result, sizeof(result)); - return 1; -} - -// Helper function for inet_pton for IPv6 addresses. -int inet_pton_v6(const char* src, void* dst) { - // sscanf will pick any other invalid chars up, but it parses 0xnnnn as hex. - // Check for literal x in the input string. - const char* readcursor = src; - char c = *readcursor++; - while (c) { - if (c == 'x') { - return 0; - } - c = *readcursor++; - } - readcursor = src; - - struct in6_addr an_addr; - memset(&an_addr, 0, sizeof(an_addr)); - - uint16* addr_cursor = reinterpret_cast(&an_addr.s6_addr[0]); - uint16* addr_end = reinterpret_cast(&an_addr.s6_addr[16]); - bool seencompressed = false; - - // Addresses that start with "::" (i.e., a run of initial zeros) or - // "::ffff:" can potentially be IPv4 mapped or compatibility addresses. - // These have dotted-style IPv4 addresses on the end (e.g. "::192.168.7.1"). - if (*readcursor == ':' && *(readcursor+1) == ':' && - *(readcursor + 2) != 0) { - // Check for periods, which we'll take as a sign of v4 addresses. - const char* addrstart = readcursor + 2; - if (rtc::strchr(addrstart, ".")) { - const char* colon = rtc::strchr(addrstart, "::"); - if (colon) { - uint16 a_short; - int bytesread = 0; - if (sscanf(addrstart, "%hx%n", &a_short, &bytesread) != 1 || - a_short != 0xFFFF || bytesread != 4) { - // Colons + periods means has to be ::ffff:a.b.c.d. But it wasn't. - return 0; - } else { - an_addr.s6_addr[10] = 0xFF; - an_addr.s6_addr[11] = 0xFF; - addrstart = colon + 1; - } - } - struct in_addr v4; - if (inet_pton_v4(addrstart, &v4.s_addr)) { - memcpy(&an_addr.s6_addr[12], &v4, sizeof(v4)); - memcpy(dst, &an_addr, sizeof(an_addr)); - return 1; - } else { - // Invalid v4 address. - return 0; - } - } - } - - // For addresses without a trailing IPv4 component ('normal' IPv6 addresses). - while (*readcursor != 0 && addr_cursor < addr_end) { - if (*readcursor == ':') { - if (*(readcursor + 1) == ':') { - if (seencompressed) { - // Can only have one compressed run of zeroes ("::") per address. - return 0; - } - // Hit a compressed run. Count colons to figure out how much of the - // address is skipped. - readcursor += 2; - const char* coloncounter = readcursor; - int coloncount = 0; - if (*coloncounter == 0) { - // Special case - trailing ::. - addr_cursor = addr_end; - } else { - while (*coloncounter) { - if (*coloncounter == ':') { - ++coloncount; - } - ++coloncounter; - } - // (coloncount + 1) is the number of shorts left in the address. - addr_cursor = addr_end - (coloncount + 1); - seencompressed = true; - } - } else { - ++readcursor; - } - } else { - uint16 word; - int bytesread = 0; - if (sscanf(readcursor, "%hx%n", &word, &bytesread) != 1) { - return 0; - } else { - *addr_cursor = HostToNetwork16(word); - ++addr_cursor; - readcursor += bytesread; - if (*readcursor != ':' && *readcursor != '\0') { - return 0; - } - } - } - } - - if (*readcursor != '\0' || addr_cursor < addr_end) { - // Catches addresses too short or too long. - return 0; - } - memcpy(dst, &an_addr, sizeof(an_addr)); - return 1; -} - -// -// Unix time is in seconds relative to 1/1/1970. So we compute the windows -// FILETIME of that time/date, then we add/subtract in appropriate units to -// convert to/from unix time. -// The units of FILETIME are 100ns intervals, so by multiplying by or dividing -// by 10000000, we can convert to/from seconds. -// -// FileTime = UnixTime*10000000 + FileTime(1970) -// UnixTime = (FileTime-FileTime(1970))/10000000 -// - -void FileTimeToUnixTime(const FILETIME& ft, time_t* ut) { - ASSERT(NULL != ut); - - // FILETIME has an earlier date base than time_t (1/1/1970), so subtract off - // the difference. - SYSTEMTIME base_st; - memset(&base_st, 0, sizeof(base_st)); - base_st.wDay = 1; - base_st.wMonth = 1; - base_st.wYear = 1970; - - FILETIME base_ft; - SystemTimeToFileTime(&base_st, &base_ft); - - ULARGE_INTEGER base_ul, current_ul; - memcpy(&base_ul, &base_ft, sizeof(FILETIME)); - memcpy(¤t_ul, &ft, sizeof(FILETIME)); - - // Divide by big number to convert to seconds, then subtract out the 1970 - // base date value. - const ULONGLONG RATIO = 10000000; - *ut = static_cast((current_ul.QuadPart - base_ul.QuadPart) / RATIO); -} - -void UnixTimeToFileTime(const time_t& ut, FILETIME* ft) { - ASSERT(NULL != ft); - - // FILETIME has an earlier date base than time_t (1/1/1970), so add in - // the difference. - SYSTEMTIME base_st; - memset(&base_st, 0, sizeof(base_st)); - base_st.wDay = 1; - base_st.wMonth = 1; - base_st.wYear = 1970; - - FILETIME base_ft; - SystemTimeToFileTime(&base_st, &base_ft); - - ULARGE_INTEGER base_ul; - memcpy(&base_ul, &base_ft, sizeof(FILETIME)); - - // Multiply by big number to convert to 100ns units, then add in the 1970 - // base date value. - const ULONGLONG RATIO = 10000000; - ULARGE_INTEGER current_ul; - current_ul.QuadPart = base_ul.QuadPart + static_cast(ut) * RATIO; - memcpy(ft, ¤t_ul, sizeof(FILETIME)); -} - -bool Utf8ToWindowsFilename(const std::string& utf8, std::wstring* filename) { - // TODO: Integrate into fileutils.h - // TODO: Handle wide and non-wide cases via TCHAR? - // TODO: Skip \\?\ processing if the length is not > MAX_PATH? - // TODO: Write unittests - - // Convert to Utf16 - int wlen = ::MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), - static_cast(utf8.length() + 1), NULL, - 0); - if (0 == wlen) { - return false; - } - wchar_t* wfilename = STACK_ARRAY(wchar_t, wlen); - if (0 == ::MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), - static_cast(utf8.length() + 1), - wfilename, wlen)) { - return false; - } - // Replace forward slashes with backslashes - std::replace(wfilename, wfilename + wlen, L'/', L'\\'); - // Convert to complete filename - DWORD full_len = ::GetFullPathName(wfilename, 0, NULL, NULL); - if (0 == full_len) { - return false; - } - wchar_t* filepart = NULL; - wchar_t* full_filename = STACK_ARRAY(wchar_t, full_len + 6); - wchar_t* start = full_filename + 6; - if (0 == ::GetFullPathName(wfilename, full_len, start, &filepart)) { - return false; - } - // Add long-path prefix - const wchar_t kLongPathPrefix[] = L"\\\\?\\UNC"; - if ((start[0] != L'\\') || (start[1] != L'\\')) { - // Non-unc path: - // Becomes: \\?\ - start -= 4; - ASSERT(start >= full_filename); - memcpy(start, kLongPathPrefix, 4 * sizeof(wchar_t)); - } else if (start[2] != L'?') { - // Unc path: \\\ - // Becomes: \\?\UNC\\ - start -= 6; - ASSERT(start >= full_filename); - memcpy(start, kLongPathPrefix, 7 * sizeof(wchar_t)); - } else { - // Already in long-path form. - } - filename->assign(start); - return true; -} - -bool GetOsVersion(int* major, int* minor, int* build) { - OSVERSIONINFO info = {0}; - info.dwOSVersionInfoSize = sizeof(info); - if (GetVersionEx(&info)) { - if (major) *major = info.dwMajorVersion; - if (minor) *minor = info.dwMinorVersion; - if (build) *build = info.dwBuildNumber; - return true; - } - return false; -} - -bool GetCurrentProcessIntegrityLevel(int* level) { - bool ret = false; - HANDLE process = ::GetCurrentProcess(), token; - if (OpenProcessToken(process, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &token)) { - DWORD size; - if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &size) && - GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - - char* buf = STACK_ARRAY(char, size); - TOKEN_MANDATORY_LABEL* til = - reinterpret_cast(buf); - if (GetTokenInformation(token, TokenIntegrityLevel, til, size, &size)) { - - DWORD count = *GetSidSubAuthorityCount(til->Label.Sid); - *level = *GetSidSubAuthority(til->Label.Sid, count - 1); - ret = true; - } - } - CloseHandle(token); - } - return ret; -} -} // namespace rtc diff --git a/webrtc/base/win32.h b/webrtc/base/win32.h deleted file mode 100644 index bf5da254c..000000000 --- a/webrtc/base/win32.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WIN32_H_ -#define WEBRTC_BASE_WIN32_H_ - -#if defined(WEBRTC_WIN) - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -// Make sure we don't get min/max macros -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include -#include - -#ifndef SECURITY_MANDATORY_LABEL_AUTHORITY -// Add defines that we use if we are compiling against older sdks -#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L) -#define TokenIntegrityLevel static_cast(0x19) -typedef struct _TOKEN_MANDATORY_LABEL { - SID_AND_ATTRIBUTES Label; -} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL; -#endif // SECURITY_MANDATORY_LABEL_AUTHORITY - -#undef SetPort - -#include - -#include "webrtc/base/stringutils.h" -#include "webrtc/base/basictypes.h" - -namespace rtc { - -const char* win32_inet_ntop(int af, const void *src, char* dst, socklen_t size); -int win32_inet_pton(int af, const char* src, void *dst); - -/////////////////////////////////////////////////////////////////////////////// - -inline std::wstring ToUtf16(const char* utf8, size_t len) { - int len16 = ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast(len), - NULL, 0); - wchar_t* ws = STACK_ARRAY(wchar_t, len16); - ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast(len), ws, len16); - return std::wstring(ws, len16); -} - -inline std::wstring ToUtf16(const std::string& str) { - return ToUtf16(str.data(), str.length()); -} - -inline std::string ToUtf8(const wchar_t* wide, size_t len) { - int len8 = ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast(len), - NULL, 0, NULL, NULL); - char* ns = STACK_ARRAY(char, len8); - ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast(len), ns, len8, - NULL, NULL); - return std::string(ns, len8); -} - -inline std::string ToUtf8(const wchar_t* wide) { - return ToUtf8(wide, wcslen(wide)); -} - -inline std::string ToUtf8(const std::wstring& wstr) { - return ToUtf8(wstr.data(), wstr.length()); -} - -// Convert FILETIME to time_t -void FileTimeToUnixTime(const FILETIME& ft, time_t* ut); - -// Convert time_t to FILETIME -void UnixTimeToFileTime(const time_t& ut, FILETIME * ft); - -// Convert a Utf8 path representation to a non-length-limited Unicode pathname. -bool Utf8ToWindowsFilename(const std::string& utf8, std::wstring* filename); - -// Convert a FILETIME to a UInt64 -inline uint64 ToUInt64(const FILETIME& ft) { - ULARGE_INTEGER r = {ft.dwLowDateTime, ft.dwHighDateTime}; - return r.QuadPart; -} - -enum WindowsMajorVersions { - kWindows2000 = 5, - kWindowsVista = 6, -}; -bool GetOsVersion(int* major, int* minor, int* build); - -inline bool IsWindowsVistaOrLater() { - int major; - return (GetOsVersion(&major, NULL, NULL) && major >= kWindowsVista); -} - -inline bool IsWindowsXpOrLater() { - int major, minor; - return (GetOsVersion(&major, &minor, NULL) && - (major >= kWindowsVista || - (major == kWindows2000 && minor >= 1))); -} - -// Determine the current integrity level of the process. -bool GetCurrentProcessIntegrityLevel(int* level); - -inline bool IsCurrentProcessLowIntegrity() { - int level; - return (GetCurrentProcessIntegrityLevel(&level) && - level < SECURITY_MANDATORY_MEDIUM_RID); -} - -bool AdjustCurrentProcessPrivilege(const TCHAR* privilege, bool to_enable); - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_WIN -#endif // WEBRTC_BASE_WIN32_H_ diff --git a/webrtc/base/win32_unittest.cc b/webrtc/base/win32_unittest.cc deleted file mode 100644 index 0050c7726..000000000 --- a/webrtc/base/win32_unittest.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/nethelpers.h" -#include "webrtc/base/win32.h" -#include "webrtc/base/winping.h" - -#if !defined(WEBRTC_WIN) -#error Only for Windows -#endif - -namespace rtc { - -class Win32Test : public testing::Test { - public: - Win32Test() { - } -}; - -TEST_F(Win32Test, FileTimeToUInt64Test) { - FILETIME ft; - ft.dwHighDateTime = 0xBAADF00D; - ft.dwLowDateTime = 0xFEED3456; - - uint64 expected = 0xBAADF00DFEED3456; - EXPECT_EQ(expected, ToUInt64(ft)); -} - -TEST_F(Win32Test, WinPingTest) { - WinPing ping; - ASSERT_TRUE(ping.IsValid()); - - // Test valid ping cases. - WinPing::PingResult result = ping.Ping(IPAddress(INADDR_LOOPBACK), 20, 50, 1, - false); - ASSERT_EQ(WinPing::PING_SUCCESS, result); - if (HasIPv6Enabled()) { - WinPing::PingResult v6result = ping.Ping(IPAddress(in6addr_loopback), 20, - 50, 1, false); - ASSERT_EQ(WinPing::PING_SUCCESS, v6result); - } - - // Test invalid parameter cases. - ASSERT_EQ(WinPing::PING_INVALID_PARAMS, ping.Ping( - IPAddress(INADDR_LOOPBACK), 0, 50, 1, false)); - ASSERT_EQ(WinPing::PING_INVALID_PARAMS, ping.Ping( - IPAddress(INADDR_LOOPBACK), 20, 0, 1, false)); - ASSERT_EQ(WinPing::PING_INVALID_PARAMS, ping.Ping( - IPAddress(INADDR_LOOPBACK), 20, 50, 0, false)); -} - -} // namespace rtc diff --git a/webrtc/base/win32filesystem.cc b/webrtc/base/win32filesystem.cc deleted file mode 100644 index 73f8ef0cf..000000000 --- a/webrtc/base/win32filesystem.cc +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/win32filesystem.h" - -#include "webrtc/base/win32.h" -#include -#include -#include - -#include "webrtc/base/fileutils.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/stream.h" -#include "webrtc/base/stringutils.h" - -// In several places in this file, we test the integrity level of the process -// before calling GetLongPathName. We do this because calling GetLongPathName -// when running under protected mode IE (a low integrity process) can result in -// a virtualized path being returned, which is wrong if you only plan to read. -// TODO: Waiting to hear back from IE team on whether this is the -// best approach; IEIsProtectedModeProcess is another possible solution. - -namespace rtc { - -bool Win32Filesystem::CreateFolder(const Pathname &pathname) { - if (pathname.pathname().empty() || !pathname.filename().empty()) - return false; - - std::wstring path16; - if (!Utf8ToWindowsFilename(pathname.pathname(), &path16)) - return false; - - DWORD res = ::GetFileAttributes(path16.c_str()); - if (res != INVALID_FILE_ATTRIBUTES) { - // Something exists at this location, check if it is a directory - return ((res & FILE_ATTRIBUTE_DIRECTORY) != 0); - } else if ((GetLastError() != ERROR_FILE_NOT_FOUND) - && (GetLastError() != ERROR_PATH_NOT_FOUND)) { - // Unexpected error - return false; - } - - // Directory doesn't exist, look up one directory level - if (!pathname.parent_folder().empty()) { - Pathname parent(pathname); - parent.SetFolder(pathname.parent_folder()); - if (!CreateFolder(parent)) { - return false; - } - } - - return (::CreateDirectory(path16.c_str(), NULL) != 0); -} - -FileStream *Win32Filesystem::OpenFile(const Pathname &filename, - const std::string &mode) { - FileStream *fs = new FileStream(); - if (fs && !fs->Open(filename.pathname().c_str(), mode.c_str(), NULL)) { - delete fs; - fs = NULL; - } - return fs; -} - -bool Win32Filesystem::CreatePrivateFile(const Pathname &filename) { - // To make the file private to the current user, we first must construct a - // SECURITY_DESCRIPTOR specifying an ACL. This code is mostly based upon - // http://msdn.microsoft.com/en-us/library/ms707085%28VS.85%29.aspx - - // Get the current process token. - HANDLE process_token = INVALID_HANDLE_VALUE; - if (!::OpenProcessToken(::GetCurrentProcess(), - TOKEN_QUERY, - &process_token)) { - LOG_ERR(LS_ERROR) << "OpenProcessToken() failed"; - return false; - } - - // Get the size of its TOKEN_USER structure. Return value is not checked - // because we expect it to fail. - DWORD token_user_size = 0; - (void)::GetTokenInformation(process_token, - TokenUser, - NULL, - 0, - &token_user_size); - - // Get the TOKEN_USER structure. - scoped_ptr token_user_bytes(new char[token_user_size]); - PTOKEN_USER token_user = reinterpret_cast( - token_user_bytes.get()); - memset(token_user, 0, token_user_size); - BOOL success = ::GetTokenInformation(process_token, - TokenUser, - token_user, - token_user_size, - &token_user_size); - // We're now done with this. - ::CloseHandle(process_token); - if (!success) { - LOG_ERR(LS_ERROR) << "GetTokenInformation() failed"; - return false; - } - - if (!IsValidSid(token_user->User.Sid)) { - LOG_ERR(LS_ERROR) << "Current process has invalid user SID"; - return false; - } - - // Compute size needed for an ACL that allows access to just this user. - int acl_size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + - GetLengthSid(token_user->User.Sid); - - // Allocate it. - scoped_ptr acl_bytes(new char[acl_size]); - PACL acl = reinterpret_cast(acl_bytes.get()); - memset(acl, 0, acl_size); - if (!::InitializeAcl(acl, acl_size, ACL_REVISION)) { - LOG_ERR(LS_ERROR) << "InitializeAcl() failed"; - return false; - } - - // Allow access to only the current user. - if (!::AddAccessAllowedAce(acl, - ACL_REVISION, - GENERIC_READ | GENERIC_WRITE | STANDARD_RIGHTS_ALL, - token_user->User.Sid)) { - LOG_ERR(LS_ERROR) << "AddAccessAllowedAce() failed"; - return false; - } - - // Now make the security descriptor. - SECURITY_DESCRIPTOR security_descriptor; - if (!::InitializeSecurityDescriptor(&security_descriptor, - SECURITY_DESCRIPTOR_REVISION)) { - LOG_ERR(LS_ERROR) << "InitializeSecurityDescriptor() failed"; - return false; - } - - // Put the ACL in it. - if (!::SetSecurityDescriptorDacl(&security_descriptor, - TRUE, - acl, - FALSE)) { - LOG_ERR(LS_ERROR) << "SetSecurityDescriptorDacl() failed"; - return false; - } - - // Finally create the file. - SECURITY_ATTRIBUTES security_attributes; - security_attributes.nLength = sizeof(security_attributes); - security_attributes.lpSecurityDescriptor = &security_descriptor; - security_attributes.bInheritHandle = FALSE; - HANDLE handle = ::CreateFile( - ToUtf16(filename.pathname()).c_str(), - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - &security_attributes, - CREATE_NEW, - 0, - NULL); - if (INVALID_HANDLE_VALUE == handle) { - LOG_ERR(LS_ERROR) << "CreateFile() failed"; - return false; - } - if (!::CloseHandle(handle)) { - LOG_ERR(LS_ERROR) << "CloseFile() failed"; - // Continue. - } - return true; -} - -bool Win32Filesystem::DeleteFile(const Pathname &filename) { - LOG(LS_INFO) << "Deleting file " << filename.pathname(); - if (!IsFile(filename)) { - ASSERT(IsFile(filename)); - return false; - } - return ::DeleteFile(ToUtf16(filename.pathname()).c_str()) != 0; -} - -bool Win32Filesystem::DeleteEmptyFolder(const Pathname &folder) { - LOG(LS_INFO) << "Deleting folder " << folder.pathname(); - - std::string no_slash(folder.pathname(), 0, folder.pathname().length()-1); - return ::RemoveDirectory(ToUtf16(no_slash).c_str()) != 0; -} - -bool Win32Filesystem::GetTemporaryFolder(Pathname &pathname, bool create, - const std::string *append) { - wchar_t buffer[MAX_PATH + 1]; - if (!::GetTempPath(ARRAY_SIZE(buffer), buffer)) - return false; - if (!IsCurrentProcessLowIntegrity() && - !::GetLongPathName(buffer, buffer, ARRAY_SIZE(buffer))) - return false; - size_t len = strlen(buffer); - if ((len > 0) && (buffer[len-1] != '\\')) { - len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, L"\\"); - } - if (len >= ARRAY_SIZE(buffer) - 1) - return false; - pathname.clear(); - pathname.SetFolder(ToUtf8(buffer)); - if (append != NULL) { - ASSERT(!append->empty()); - pathname.AppendFolder(*append); - } - return !create || CreateFolder(pathname); -} - -std::string Win32Filesystem::TempFilename(const Pathname &dir, - const std::string &prefix) { - wchar_t filename[MAX_PATH]; - if (::GetTempFileName(ToUtf16(dir.pathname()).c_str(), - ToUtf16(prefix).c_str(), 0, filename) != 0) - return ToUtf8(filename); - ASSERT(false); - return ""; -} - -bool Win32Filesystem::MoveFile(const Pathname &old_path, - const Pathname &new_path) { - if (!IsFile(old_path)) { - ASSERT(IsFile(old_path)); - return false; - } - LOG(LS_INFO) << "Moving " << old_path.pathname() - << " to " << new_path.pathname(); - return ::MoveFile(ToUtf16(old_path.pathname()).c_str(), - ToUtf16(new_path.pathname()).c_str()) != 0; -} - -bool Win32Filesystem::MoveFolder(const Pathname &old_path, - const Pathname &new_path) { - if (!IsFolder(old_path)) { - ASSERT(IsFolder(old_path)); - return false; - } - LOG(LS_INFO) << "Moving " << old_path.pathname() - << " to " << new_path.pathname(); - if (::MoveFile(ToUtf16(old_path.pathname()).c_str(), - ToUtf16(new_path.pathname()).c_str()) == 0) { - if (::GetLastError() != ERROR_NOT_SAME_DEVICE) { - LOG_GLE(LS_ERROR) << "Failed to move file"; - return false; - } - if (!CopyFolder(old_path, new_path)) - return false; - if (!DeleteFolderAndContents(old_path)) - return false; - } - return true; -} - -bool Win32Filesystem::IsFolder(const Pathname &path) { - WIN32_FILE_ATTRIBUTE_DATA data = {0}; - if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), - GetFileExInfoStandard, &data)) - return false; - return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == - FILE_ATTRIBUTE_DIRECTORY; -} - -bool Win32Filesystem::IsFile(const Pathname &path) { - WIN32_FILE_ATTRIBUTE_DATA data = {0}; - if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), - GetFileExInfoStandard, &data)) - return false; - return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; -} - -bool Win32Filesystem::IsAbsent(const Pathname& path) { - WIN32_FILE_ATTRIBUTE_DATA data = {0}; - if (0 != ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), - GetFileExInfoStandard, &data)) - return false; - DWORD err = ::GetLastError(); - return (ERROR_FILE_NOT_FOUND == err || ERROR_PATH_NOT_FOUND == err); -} - -bool Win32Filesystem::CopyFile(const Pathname &old_path, - const Pathname &new_path) { - return ::CopyFile(ToUtf16(old_path.pathname()).c_str(), - ToUtf16(new_path.pathname()).c_str(), TRUE) != 0; -} - -bool Win32Filesystem::IsTemporaryPath(const Pathname& pathname) { - TCHAR buffer[MAX_PATH + 1]; - if (!::GetTempPath(ARRAY_SIZE(buffer), buffer)) - return false; - if (!IsCurrentProcessLowIntegrity() && - !::GetLongPathName(buffer, buffer, ARRAY_SIZE(buffer))) - return false; - return (::strnicmp(ToUtf16(pathname.pathname()).c_str(), - buffer, strlen(buffer)) == 0); -} - -bool Win32Filesystem::GetFileSize(const Pathname &pathname, size_t *size) { - WIN32_FILE_ATTRIBUTE_DATA data = {0}; - if (::GetFileAttributesEx(ToUtf16(pathname.pathname()).c_str(), - GetFileExInfoStandard, &data) == 0) - return false; - *size = data.nFileSizeLow; - return true; -} - -bool Win32Filesystem::GetFileTime(const Pathname& path, FileTimeType which, - time_t* time) { - WIN32_FILE_ATTRIBUTE_DATA data = {0}; - if (::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), - GetFileExInfoStandard, &data) == 0) - return false; - switch (which) { - case FTT_CREATED: - FileTimeToUnixTime(data.ftCreationTime, time); - break; - case FTT_MODIFIED: - FileTimeToUnixTime(data.ftLastWriteTime, time); - break; - case FTT_ACCESSED: - FileTimeToUnixTime(data.ftLastAccessTime, time); - break; - default: - return false; - } - return true; -} - -bool Win32Filesystem::GetAppPathname(Pathname* path) { - TCHAR buffer[MAX_PATH + 1]; - if (0 == ::GetModuleFileName(NULL, buffer, ARRAY_SIZE(buffer))) - return false; - path->SetPathname(ToUtf8(buffer)); - return true; -} - -bool Win32Filesystem::GetAppDataFolder(Pathname* path, bool per_user) { - ASSERT(!organization_name_.empty()); - ASSERT(!application_name_.empty()); - TCHAR buffer[MAX_PATH + 1]; - int csidl = per_user ? CSIDL_LOCAL_APPDATA : CSIDL_COMMON_APPDATA; - if (!::SHGetSpecialFolderPath(NULL, buffer, csidl, TRUE)) - return false; - if (!IsCurrentProcessLowIntegrity() && - !::GetLongPathName(buffer, buffer, ARRAY_SIZE(buffer))) - return false; - size_t len = strcatn(buffer, ARRAY_SIZE(buffer), __T("\\")); - len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, - ToUtf16(organization_name_).c_str()); - if ((len > 0) && (buffer[len-1] != __T('\\'))) { - len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, __T("\\")); - } - len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, - ToUtf16(application_name_).c_str()); - if ((len > 0) && (buffer[len-1] != __T('\\'))) { - len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, __T("\\")); - } - if (len >= ARRAY_SIZE(buffer) - 1) - return false; - path->clear(); - path->SetFolder(ToUtf8(buffer)); - return CreateFolder(*path); -} - -bool Win32Filesystem::GetAppTempFolder(Pathname* path) { - if (!GetAppPathname(path)) - return false; - std::string filename(path->filename()); - return GetTemporaryFolder(*path, true, &filename); -} - -bool Win32Filesystem::GetDiskFreeSpace(const Pathname& path, int64 *freebytes) { - if (!freebytes) { - return false; - } - char drive[4]; - std::wstring drive16; - const wchar_t* target_drive = NULL; - if (path.GetDrive(drive, sizeof(drive))) { - drive16 = ToUtf16(drive); - target_drive = drive16.c_str(); - } else if (path.folder().substr(0, 2) == "\\\\") { - // UNC path, fail. - // TODO: Handle UNC paths. - return false; - } else { - // The path is probably relative. GetDriveType and GetDiskFreeSpaceEx - // use the current drive if NULL is passed as the drive name. - // TODO: Add method to Pathname to determine if the path is relative. - // TODO: Add method to Pathname to convert a path to absolute. - } - UINT driveType = ::GetDriveType(target_drive); - if ( (driveType & DRIVE_REMOTE) || (driveType & DRIVE_UNKNOWN) ) { - LOG(LS_VERBOSE) << " remove or unknown drive " << drive; - return false; - } - - int64 totalNumberOfBytes; // receives the number of bytes on disk - int64 totalNumberOfFreeBytes; // receives the free bytes on disk - // make sure things won't change in 64 bit machine - // TODO replace with compile time assert - ASSERT(sizeof(ULARGE_INTEGER) == sizeof(uint64)); //NOLINT - if (::GetDiskFreeSpaceEx(target_drive, - (PULARGE_INTEGER)freebytes, - (PULARGE_INTEGER)&totalNumberOfBytes, - (PULARGE_INTEGER)&totalNumberOfFreeBytes)) { - return true; - } else { - LOG(LS_VERBOSE) << " GetDiskFreeSpaceEx returns error "; - return false; - } -} - -Pathname Win32Filesystem::GetCurrentDirectory() { - Pathname cwd; - int path_len = 0; - scoped_ptr path; - do { - int needed = ::GetCurrentDirectory(path_len, path.get()); - if (needed == 0) { - // Error. - LOG_GLE(LS_ERROR) << "::GetCurrentDirectory() failed"; - return cwd; // returns empty pathname - } - if (needed <= path_len) { - // It wrote successfully. - break; - } - // Else need to re-alloc for "needed". - path.reset(new wchar_t[needed]); - path_len = needed; - } while (true); - cwd.SetFolder(ToUtf8(path.get())); - return cwd; -} - -// TODO: Consider overriding DeleteFolderAndContents for speed and potentially -// better OS integration (recycle bin?) -/* - std::wstring temp_path16 = ToUtf16(temp_path.pathname()); - temp_path16.append(1, '*'); - temp_path16.append(1, '\0'); - - SHFILEOPSTRUCT file_op = { 0 }; - file_op.wFunc = FO_DELETE; - file_op.pFrom = temp_path16.c_str(); - file_op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT; - return (0 == SHFileOperation(&file_op)); -*/ - -} // namespace rtc diff --git a/webrtc/base/win32filesystem.h b/webrtc/base/win32filesystem.h deleted file mode 100644 index 3cd5373e3..000000000 --- a/webrtc/base/win32filesystem.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef _WEBRTC_BASE_WIN32FILESYSTEM_H__ -#define _WEBRTC_BASE_WIN32FILESYSTEM_H__ - -#include "fileutils.h" - -namespace rtc { - -class Win32Filesystem : public FilesystemInterface { - public: - // Opens a file. Returns an open StreamInterface if function succeeds. Otherwise, - // returns NULL. - virtual FileStream *OpenFile(const Pathname &filename, - const std::string &mode); - - // Atomically creates an empty file accessible only to the current user if one - // does not already exist at the given path, otherwise fails. - virtual bool CreatePrivateFile(const Pathname &filename); - - // This will attempt to delete the path located at filename. - // If the path points to a folder, it will fail with VERIFY - virtual bool DeleteFile(const Pathname &filename); - - // This will attempt to delete an empty folder. If the path does not point to - // a folder, it fails with VERIFY. If the folder is not empty, it fails normally - virtual bool DeleteEmptyFolder(const Pathname &folder); - - // Creates a directory. This will call itself recursively to create /foo/bar even if - // /foo does not exist. - // Returns TRUE if function succeeds - virtual bool CreateFolder(const Pathname &pathname); - - // This moves a file from old_path to new_path. If the new path is on a - // different volume than the old, it will attempt to copy and then delete - // the folder - // Returns true if the file is successfully moved - virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path); - - // Moves a folder from old_path to new_path. If the new path is on a different - // volume from the old, it will attempt to Copy and then Delete the folder - // Returns true if the folder is successfully moved - virtual bool MoveFolder(const Pathname &old_path, const Pathname &new_path); - - // This copies a file from old_path to _new_path - // Returns true if function succeeds - virtual bool CopyFile(const Pathname &old_path, const Pathname &new_path); - - // Returns true if a pathname is a directory - virtual bool IsFolder(const Pathname& pathname); - - // Returns true if a file exists at path - virtual bool IsFile(const Pathname &path); - - // Returns true if pathname refers to no filesystem object, every parent - // directory either exists, or is also absent. - virtual bool IsAbsent(const Pathname& pathname); - - // Returns true if pathname represents a temporary location on the system. - virtual bool IsTemporaryPath(const Pathname& pathname); - - // All of the following functions set pathname and return true if successful. - // Returned paths always include a trailing backslash. - // If create is true, the path will be recursively created. - // If append is non-NULL, it will be appended (and possibly created). - - virtual std::string TempFilename(const Pathname &dir, const std::string &prefix); - - virtual bool GetFileSize(const Pathname& path, size_t* size); - virtual bool GetFileTime(const Pathname& path, FileTimeType which, - time_t* time); - - // A folder appropriate for storing temporary files (Contents are - // automatically deleted when the program exists) - virtual bool GetTemporaryFolder(Pathname &path, bool create, - const std::string *append); - - // Returns the path to the running application. - virtual bool GetAppPathname(Pathname* path); - - virtual bool GetAppDataFolder(Pathname* path, bool per_user); - - // Get a temporary folder that is unique to the current user and application. - virtual bool GetAppTempFolder(Pathname* path); - - virtual bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes); - - virtual Pathname GetCurrentDirectory(); -}; - -} // namespace rtc - -#endif // WEBRTC_WINFILESYSTEM_H__ diff --git a/webrtc/base/win32regkey.cc b/webrtc/base/win32regkey.cc deleted file mode 100644 index 1ed0d4ea2..000000000 --- a/webrtc/base/win32regkey.cc +++ /dev/null @@ -1,1102 +0,0 @@ -/* - * Copyright 2003 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Registry configuration wrapers class implementation -// -// Change made by S. Ganesh - ganesh@google.com: -// Use SHQueryValueEx instead of RegQueryValueEx throughout. -// A call to the SHLWAPI function is essentially a call to the standard -// function but with post-processing: -// * to fix REG_SZ or REG_EXPAND_SZ data that is not properly null-terminated; -// * to expand REG_EXPAND_SZ data. - -#include "webrtc/base/win32regkey.h" - -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/scoped_ptr.h" - -namespace rtc { - -RegKey::RegKey() { - h_key_ = NULL; -} - -RegKey::~RegKey() { - Close(); -} - -HRESULT RegKey::Create(HKEY parent_key, const wchar_t* key_name) { - return Create(parent_key, - key_name, - REG_NONE, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - NULL); -} - -HRESULT RegKey::Open(HKEY parent_key, const wchar_t* key_name) { - return Open(parent_key, key_name, KEY_ALL_ACCESS); -} - -bool RegKey::HasValue(const TCHAR* value_name) const { - return (ERROR_SUCCESS == ::RegQueryValueEx(h_key_, value_name, NULL, - NULL, NULL, NULL)); -} - -HRESULT RegKey::SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD value) { - ASSERT(full_key_name != NULL); - - return SetValueStaticHelper(full_key_name, value_name, REG_DWORD, &value); -} - -HRESULT RegKey::SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD64 value) { - ASSERT(full_key_name != NULL); - - return SetValueStaticHelper(full_key_name, value_name, REG_QWORD, &value); -} - -HRESULT RegKey::SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - float value) { - ASSERT(full_key_name != NULL); - - return SetValueStaticHelper(full_key_name, value_name, - REG_BINARY, &value, sizeof(value)); -} - -HRESULT RegKey::SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - double value) { - ASSERT(full_key_name != NULL); - - return SetValueStaticHelper(full_key_name, value_name, - REG_BINARY, &value, sizeof(value)); -} - -HRESULT RegKey::SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - const TCHAR* value) { - ASSERT(full_key_name != NULL); - ASSERT(value != NULL); - - return SetValueStaticHelper(full_key_name, value_name, - REG_SZ, const_cast(value)); -} - -HRESULT RegKey::SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - const uint8* value, - DWORD byte_count) { - ASSERT(full_key_name != NULL); - - return SetValueStaticHelper(full_key_name, value_name, REG_BINARY, - const_cast(value), byte_count); -} - -HRESULT RegKey::SetValueMultiSZ(const wchar_t* full_key_name, - const wchar_t* value_name, - const uint8* value, - DWORD byte_count) { - ASSERT(full_key_name != NULL); - - return SetValueStaticHelper(full_key_name, value_name, REG_MULTI_SZ, - const_cast(value), byte_count); -} - -HRESULT RegKey::GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD* value) { - ASSERT(full_key_name != NULL); - ASSERT(value != NULL); - - return GetValueStaticHelper(full_key_name, value_name, REG_DWORD, value); -} - -HRESULT RegKey::GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD64* value) { - ASSERT(full_key_name != NULL); - ASSERT(value != NULL); - - return GetValueStaticHelper(full_key_name, value_name, REG_QWORD, value); -} - -HRESULT RegKey::GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - float* value) { - ASSERT(value != NULL); - ASSERT(full_key_name != NULL); - - DWORD byte_count = 0; - scoped_ptr buffer; - HRESULT hr = GetValueStaticHelper(full_key_name, value_name, - REG_BINARY, buffer.accept(), &byte_count); - if (SUCCEEDED(hr)) { - ASSERT(byte_count == sizeof(*value)); - if (byte_count == sizeof(*value)) { - *value = *reinterpret_cast(buffer.get()); - } - } - return hr; -} - -HRESULT RegKey::GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - double* value) { - ASSERT(value != NULL); - ASSERT(full_key_name != NULL); - - DWORD byte_count = 0; - scoped_ptr buffer; - HRESULT hr = GetValueStaticHelper(full_key_name, value_name, - REG_BINARY, buffer.accept(), &byte_count); - if (SUCCEEDED(hr)) { - ASSERT(byte_count == sizeof(*value)); - if (byte_count == sizeof(*value)) { - *value = *reinterpret_cast(buffer.get()); - } - } - return hr; -} - -HRESULT RegKey::GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - wchar_t** value) { - ASSERT(full_key_name != NULL); - ASSERT(value != NULL); - - return GetValueStaticHelper(full_key_name, value_name, REG_SZ, value); -} - -HRESULT RegKey::GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - std::wstring* value) { - ASSERT(full_key_name != NULL); - ASSERT(value != NULL); - - scoped_ptr buffer; - HRESULT hr = RegKey::GetValue(full_key_name, value_name, buffer.accept()); - if (SUCCEEDED(hr)) { - value->assign(buffer.get()); - } - return hr; -} - -HRESULT RegKey::GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - std::vector* value) { - ASSERT(full_key_name != NULL); - ASSERT(value != NULL); - - return GetValueStaticHelper(full_key_name, value_name, REG_MULTI_SZ, value); -} - -HRESULT RegKey::GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - uint8** value, - DWORD* byte_count) { - ASSERT(full_key_name != NULL); - ASSERT(value != NULL); - ASSERT(byte_count != NULL); - - return GetValueStaticHelper(full_key_name, value_name, - REG_BINARY, value, byte_count); -} - -HRESULT RegKey::DeleteSubKey(const wchar_t* key_name) { - ASSERT(key_name != NULL); - ASSERT(h_key_ != NULL); - - LONG res = ::RegDeleteKey(h_key_, key_name); - HRESULT hr = HRESULT_FROM_WIN32(res); - if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || - hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) { - hr = S_FALSE; - } - return hr; -} - -HRESULT RegKey::DeleteValue(const wchar_t* value_name) { - ASSERT(h_key_ != NULL); - - LONG res = ::RegDeleteValue(h_key_, value_name); - HRESULT hr = HRESULT_FROM_WIN32(res); - if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || - hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) { - hr = S_FALSE; - } - return hr; -} - -HRESULT RegKey::Close() { - HRESULT hr = S_OK; - if (h_key_ != NULL) { - LONG res = ::RegCloseKey(h_key_); - hr = HRESULT_FROM_WIN32(res); - h_key_ = NULL; - } - return hr; -} - -HRESULT RegKey::Create(HKEY parent_key, - const wchar_t* key_name, - wchar_t* lpszClass, - DWORD options, - REGSAM sam_desired, - LPSECURITY_ATTRIBUTES lpSecAttr, - LPDWORD lpdwDisposition) { - ASSERT(key_name != NULL); - ASSERT(parent_key != NULL); - - DWORD dw = 0; - HKEY h_key = NULL; - LONG res = ::RegCreateKeyEx(parent_key, key_name, 0, lpszClass, options, - sam_desired, lpSecAttr, &h_key, &dw); - HRESULT hr = HRESULT_FROM_WIN32(res); - - if (lpdwDisposition) { - *lpdwDisposition = dw; - } - - // we have to close the currently opened key - // before replacing it with the new one - if (hr == S_OK) { - hr = Close(); - ASSERT(hr == S_OK); - h_key_ = h_key; - } - return hr; -} - -HRESULT RegKey::Open(HKEY parent_key, - const wchar_t* key_name, - REGSAM sam_desired) { - ASSERT(key_name != NULL); - ASSERT(parent_key != NULL); - - HKEY h_key = NULL; - LONG res = ::RegOpenKeyEx(parent_key, key_name, 0, sam_desired, &h_key); - HRESULT hr = HRESULT_FROM_WIN32(res); - - // we have to close the currently opened key - // before replacing it with the new one - if (hr == S_OK) { - // close the currently opened key if any - hr = Close(); - ASSERT(hr == S_OK); - h_key_ = h_key; - } - return hr; -} - -// save the key and all of its subkeys and values to a file -HRESULT RegKey::Save(const wchar_t* full_key_name, const wchar_t* file_name) { - ASSERT(full_key_name != NULL); - ASSERT(file_name != NULL); - - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - if (!h_key) { - return E_FAIL; - } - - RegKey key; - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ); - if (FAILED(hr)) { - return hr; - } - - AdjustCurrentProcessPrivilege(SE_BACKUP_NAME, true); - LONG res = ::RegSaveKey(key.h_key_, file_name, NULL); - AdjustCurrentProcessPrivilege(SE_BACKUP_NAME, false); - - return HRESULT_FROM_WIN32(res); -} - -// restore the key and all of its subkeys and values which are saved into a file -HRESULT RegKey::Restore(const wchar_t* full_key_name, - const wchar_t* file_name) { - ASSERT(full_key_name != NULL); - ASSERT(file_name != NULL); - - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - if (!h_key) { - return E_FAIL; - } - - RegKey key; - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_WRITE); - if (FAILED(hr)) { - return hr; - } - - AdjustCurrentProcessPrivilege(SE_RESTORE_NAME, true); - LONG res = ::RegRestoreKey(key.h_key_, file_name, REG_FORCE_RESTORE); - AdjustCurrentProcessPrivilege(SE_RESTORE_NAME, false); - - return HRESULT_FROM_WIN32(res); -} - -// check if the current key has the specified subkey -bool RegKey::HasSubkey(const wchar_t* key_name) const { - ASSERT(key_name != NULL); - - RegKey key; - HRESULT hr = key.Open(h_key_, key_name, KEY_READ); - key.Close(); - return hr == S_OK; -} - -// static flush key -HRESULT RegKey::FlushKey(const wchar_t* full_key_name) { - ASSERT(full_key_name != NULL); - - HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); - // get the root HKEY - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - - if (h_key != NULL) { - LONG res = ::RegFlushKey(h_key); - hr = HRESULT_FROM_WIN32(res); - } - return hr; -} - -// static SET helper -HRESULT RegKey::SetValueStaticHelper(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD type, - LPVOID value, - DWORD byte_count) { - ASSERT(full_key_name != NULL); - - HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); - // get the root HKEY - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - - if (h_key != NULL) { - RegKey key; - hr = key.Create(h_key, key_name.c_str()); - if (hr == S_OK) { - switch (type) { - case REG_DWORD: - hr = key.SetValue(value_name, *(static_cast(value))); - break; - case REG_QWORD: - hr = key.SetValue(value_name, *(static_cast(value))); - break; - case REG_SZ: - hr = key.SetValue(value_name, static_cast(value)); - break; - case REG_BINARY: - hr = key.SetValue(value_name, static_cast(value), - byte_count); - break; - case REG_MULTI_SZ: - hr = key.SetValue(value_name, static_cast(value), - byte_count, type); - break; - default: - ASSERT(false); - hr = HRESULT_FROM_WIN32(ERROR_DATATYPE_MISMATCH); - break; - } - // close the key after writing - HRESULT temp_hr = key.Close(); - if (hr == S_OK) { - hr = temp_hr; - } - } - } - return hr; -} - -// static GET helper -HRESULT RegKey::GetValueStaticHelper(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD type, - LPVOID value, - DWORD* byte_count) { - ASSERT(full_key_name != NULL); - - HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); - // get the root HKEY - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - - if (h_key != NULL) { - RegKey key; - hr = key.Open(h_key, key_name.c_str(), KEY_READ); - if (hr == S_OK) { - switch (type) { - case REG_DWORD: - hr = key.GetValue(value_name, reinterpret_cast(value)); - break; - case REG_QWORD: - hr = key.GetValue(value_name, reinterpret_cast(value)); - break; - case REG_SZ: - hr = key.GetValue(value_name, reinterpret_cast(value)); - break; - case REG_MULTI_SZ: - hr = key.GetValue(value_name, reinterpret_cast< - std::vector*>(value)); - break; - case REG_BINARY: - hr = key.GetValue(value_name, reinterpret_cast(value), - byte_count); - break; - default: - ASSERT(false); - hr = HRESULT_FROM_WIN32(ERROR_DATATYPE_MISMATCH); - break; - } - // close the key after writing - HRESULT temp_hr = key.Close(); - if (hr == S_OK) { - hr = temp_hr; - } - } - } - return hr; -} - -// GET helper -HRESULT RegKey::GetValueHelper(const wchar_t* value_name, - DWORD* type, - uint8** value, - DWORD* byte_count) const { - ASSERT(byte_count != NULL); - ASSERT(value != NULL); - ASSERT(type != NULL); - - // init return buffer - *value = NULL; - - // get the size of the return data buffer - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, type, NULL, byte_count); - HRESULT hr = HRESULT_FROM_WIN32(res); - - if (hr == S_OK) { - // if the value length is 0, nothing to do - if (*byte_count != 0) { - // allocate the buffer - *value = new byte[*byte_count]; - ASSERT(*value != NULL); - - // make the call again to get the data - res = ::SHQueryValueEx(h_key_, value_name, NULL, - type, *value, byte_count); - hr = HRESULT_FROM_WIN32(res); - ASSERT(hr == S_OK); - } - } - return hr; -} - -// Int32 Get -HRESULT RegKey::GetValue(const wchar_t* value_name, DWORD* value) const { - ASSERT(value != NULL); - - DWORD type = 0; - DWORD byte_count = sizeof(DWORD); - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, &type, - value, &byte_count); - HRESULT hr = HRESULT_FROM_WIN32(res); - ASSERT((hr != S_OK) || (type == REG_DWORD)); - ASSERT((hr != S_OK) || (byte_count == sizeof(DWORD))); - return hr; -} - -// Int64 Get -HRESULT RegKey::GetValue(const wchar_t* value_name, DWORD64* value) const { - ASSERT(value != NULL); - - DWORD type = 0; - DWORD byte_count = sizeof(DWORD64); - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, &type, - value, &byte_count); - HRESULT hr = HRESULT_FROM_WIN32(res); - ASSERT((hr != S_OK) || (type == REG_QWORD)); - ASSERT((hr != S_OK) || (byte_count == sizeof(DWORD64))); - return hr; -} - -// String Get -HRESULT RegKey::GetValue(const wchar_t* value_name, wchar_t** value) const { - ASSERT(value != NULL); - - DWORD byte_count = 0; - DWORD type = 0; - - // first get the size of the string buffer - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, - &type, NULL, &byte_count); - HRESULT hr = HRESULT_FROM_WIN32(res); - - if (hr == S_OK) { - // allocate room for the string and a terminating \0 - *value = new wchar_t[(byte_count / sizeof(wchar_t)) + 1]; - - if ((*value) != NULL) { - if (byte_count != 0) { - // make the call again - res = ::SHQueryValueEx(h_key_, value_name, NULL, &type, - *value, &byte_count); - hr = HRESULT_FROM_WIN32(res); - } else { - (*value)[0] = L'\0'; - } - - ASSERT((hr != S_OK) || (type == REG_SZ) || - (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ)); - } else { - hr = E_OUTOFMEMORY; - } - } - - return hr; -} - -// get a string value -HRESULT RegKey::GetValue(const wchar_t* value_name, std::wstring* value) const { - ASSERT(value != NULL); - - DWORD byte_count = 0; - DWORD type = 0; - - // first get the size of the string buffer - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, - &type, NULL, &byte_count); - HRESULT hr = HRESULT_FROM_WIN32(res); - - if (hr == S_OK) { - if (byte_count != 0) { - // Allocate some memory and make the call again - value->resize(byte_count / sizeof(wchar_t) + 1); - res = ::SHQueryValueEx(h_key_, value_name, NULL, &type, - &value->at(0), &byte_count); - hr = HRESULT_FROM_WIN32(res); - value->resize(wcslen(value->data())); - } else { - value->clear(); - } - - ASSERT((hr != S_OK) || (type == REG_SZ) || - (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ)); - } - - return hr; -} - -// convert REG_MULTI_SZ bytes to string array -HRESULT RegKey::MultiSZBytesToStringArray(const uint8* buffer, - DWORD byte_count, - std::vector* value) { - ASSERT(buffer != NULL); - ASSERT(value != NULL); - - const wchar_t* data = reinterpret_cast(buffer); - DWORD data_len = byte_count / sizeof(wchar_t); - value->clear(); - if (data_len > 1) { - // must be terminated by two null characters - if (data[data_len - 1] != 0 || data[data_len - 2] != 0) { - return E_INVALIDARG; - } - - // put null-terminated strings into arrays - while (*data) { - std::wstring str(data); - value->push_back(str); - data += str.length() + 1; - } - } - return S_OK; -} - -// get a std::vector value from REG_MULTI_SZ type -HRESULT RegKey::GetValue(const wchar_t* value_name, - std::vector* value) const { - ASSERT(value != NULL); - - DWORD byte_count = 0; - DWORD type = 0; - uint8* buffer = 0; - - // first get the size of the buffer - HRESULT hr = GetValueHelper(value_name, &type, &buffer, &byte_count); - ASSERT((hr != S_OK) || (type == REG_MULTI_SZ)); - - if (SUCCEEDED(hr)) { - hr = MultiSZBytesToStringArray(buffer, byte_count, value); - } - - return hr; -} - -// Binary data Get -HRESULT RegKey::GetValue(const wchar_t* value_name, - uint8** value, - DWORD* byte_count) const { - ASSERT(byte_count != NULL); - ASSERT(value != NULL); - - DWORD type = 0; - HRESULT hr = GetValueHelper(value_name, &type, value, byte_count); - ASSERT((hr != S_OK) || (type == REG_MULTI_SZ) || (type == REG_BINARY)); - return hr; -} - -// Raw data get -HRESULT RegKey::GetValue(const wchar_t* value_name, - uint8** value, - DWORD* byte_count, - DWORD*type) const { - ASSERT(type != NULL); - ASSERT(byte_count != NULL); - ASSERT(value != NULL); - - return GetValueHelper(value_name, type, value, byte_count); -} - -// Int32 set -HRESULT RegKey::SetValue(const wchar_t* value_name, DWORD value) const { - ASSERT(h_key_ != NULL); - - LONG res = ::RegSetValueEx(h_key_, value_name, NULL, REG_DWORD, - reinterpret_cast(&value), - sizeof(DWORD)); - return HRESULT_FROM_WIN32(res); -} - -// Int64 set -HRESULT RegKey::SetValue(const wchar_t* value_name, DWORD64 value) const { - ASSERT(h_key_ != NULL); - - LONG res = ::RegSetValueEx(h_key_, value_name, NULL, REG_QWORD, - reinterpret_cast(&value), - sizeof(DWORD64)); - return HRESULT_FROM_WIN32(res); -} - -// String set -HRESULT RegKey::SetValue(const wchar_t* value_name, - const wchar_t* value) const { - ASSERT(value != NULL); - ASSERT(h_key_ != NULL); - - LONG res = ::RegSetValueEx(h_key_, value_name, NULL, REG_SZ, - reinterpret_cast(value), - (lstrlen(value) + 1) * sizeof(wchar_t)); - return HRESULT_FROM_WIN32(res); -} - -// Binary data set -HRESULT RegKey::SetValue(const wchar_t* value_name, - const uint8* value, - DWORD byte_count) const { - ASSERT(h_key_ != NULL); - - // special case - if 'value' is NULL make sure byte_count is zero - if (value == NULL) { - byte_count = 0; - } - - LONG res = ::RegSetValueEx(h_key_, value_name, NULL, - REG_BINARY, value, byte_count); - return HRESULT_FROM_WIN32(res); -} - -// Raw data set -HRESULT RegKey::SetValue(const wchar_t* value_name, - const uint8* value, - DWORD byte_count, - DWORD type) const { - ASSERT(value != NULL); - ASSERT(h_key_ != NULL); - - LONG res = ::RegSetValueEx(h_key_, value_name, NULL, type, value, byte_count); - return HRESULT_FROM_WIN32(res); -} - -bool RegKey::HasKey(const wchar_t* full_key_name) { - ASSERT(full_key_name != NULL); - - // get the root HKEY - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - - if (h_key != NULL) { - RegKey key; - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ); - key.Close(); - return S_OK == hr; - } - return false; -} - -// static version of HasValue -bool RegKey::HasValue(const wchar_t* full_key_name, const wchar_t* value_name) { - ASSERT(full_key_name != NULL); - - bool has_value = false; - // get the root HKEY - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - - if (h_key != NULL) { - RegKey key; - if (key.Open(h_key, key_name.c_str(), KEY_READ) == S_OK) { - has_value = key.HasValue(value_name); - key.Close(); - } - } - return has_value; -} - -HRESULT RegKey::GetValueType(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD* value_type) { - ASSERT(full_key_name != NULL); - ASSERT(value_type != NULL); - - *value_type = REG_NONE; - - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - - RegKey key; - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ); - if (SUCCEEDED(hr)) { - LONG res = ::SHQueryValueEx(key.h_key_, value_name, NULL, value_type, - NULL, NULL); - if (res != ERROR_SUCCESS) { - hr = HRESULT_FROM_WIN32(res); - } - } - - return hr; -} - -HRESULT RegKey::DeleteKey(const wchar_t* full_key_name) { - ASSERT(full_key_name != NULL); - - return DeleteKey(full_key_name, true); -} - -HRESULT RegKey::DeleteKey(const wchar_t* full_key_name, bool recursively) { - ASSERT(full_key_name != NULL); - - // need to open the parent key first - // get the root HKEY - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - - // get the parent key - std::wstring parent_key(GetParentKeyInfo(&key_name)); - - RegKey key; - HRESULT hr = key.Open(h_key, parent_key.c_str()); - - if (hr == S_OK) { - hr = recursively ? key.RecurseDeleteSubKey(key_name.c_str()) - : key.DeleteSubKey(key_name.c_str()); - } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || - hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) { - hr = S_FALSE; - } - - key.Close(); - return hr; -} - -HRESULT RegKey::DeleteValue(const wchar_t* full_key_name, - const wchar_t* value_name) { - ASSERT(full_key_name != NULL); - - HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); - // get the root HKEY - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - - if (h_key != NULL) { - RegKey key; - hr = key.Open(h_key, key_name.c_str()); - if (hr == S_OK) { - hr = key.DeleteValue(value_name); - key.Close(); - } - } - return hr; -} - -HRESULT RegKey::RecurseDeleteSubKey(const wchar_t* key_name) { - ASSERT(key_name != NULL); - - RegKey key; - HRESULT hr = key.Open(h_key_, key_name); - - if (hr == S_OK) { - // enumerate all subkeys of this key and recursivelly delete them - FILETIME time = {0}; - wchar_t key_name_buf[kMaxKeyNameChars] = {0}; - DWORD key_name_buf_size = kMaxKeyNameChars; - while (hr == S_OK && - ::RegEnumKeyEx(key.h_key_, 0, key_name_buf, &key_name_buf_size, - NULL, NULL, NULL, &time) == ERROR_SUCCESS) { - hr = key.RecurseDeleteSubKey(key_name_buf); - - // restore the buffer size - key_name_buf_size = kMaxKeyNameChars; - } - // close the top key - key.Close(); - } - - if (hr == S_OK) { - // the key has no more children keys - // delete the key and all of its values - hr = DeleteSubKey(key_name); - } - - return hr; -} - -HKEY RegKey::GetRootKeyInfo(std::wstring* full_key_name) { - ASSERT(full_key_name != NULL); - - HKEY h_key = NULL; - // get the root HKEY - size_t index = full_key_name->find(L'\\'); - std::wstring root_key; - - if (index == -1) { - root_key = *full_key_name; - *full_key_name = L""; - } else { - root_key = full_key_name->substr(0, index); - *full_key_name = full_key_name->substr(index + 1, - full_key_name->length() - index - 1); - } - - for (std::wstring::iterator iter = root_key.begin(); - iter != root_key.end(); ++iter) { - *iter = toupper(*iter); - } - - if (!root_key.compare(L"HKLM") || - !root_key.compare(L"HKEY_LOCAL_MACHINE")) { - h_key = HKEY_LOCAL_MACHINE; - } else if (!root_key.compare(L"HKCU") || - !root_key.compare(L"HKEY_CURRENT_USER")) { - h_key = HKEY_CURRENT_USER; - } else if (!root_key.compare(L"HKU") || - !root_key.compare(L"HKEY_USERS")) { - h_key = HKEY_USERS; - } else if (!root_key.compare(L"HKCR") || - !root_key.compare(L"HKEY_CLASSES_ROOT")) { - h_key = HKEY_CLASSES_ROOT; - } - - return h_key; -} - - -// Returns true if this key name is 'safe' for deletion -// (doesn't specify a key root) -bool RegKey::SafeKeyNameForDeletion(const wchar_t* key_name) { - ASSERT(key_name != NULL); - std::wstring key(key_name); - - HKEY root_key = GetRootKeyInfo(&key); - - if (!root_key) { - key = key_name; - } - if (key.empty()) { - return false; - } - bool found_subkey = false, backslash_found = false; - for (size_t i = 0 ; i < key.length() ; ++i) { - if (key[i] == L'\\') { - backslash_found = true; - } else if (backslash_found) { - found_subkey = true; - break; - } - } - return (root_key == HKEY_USERS) ? found_subkey : true; -} - -std::wstring RegKey::GetParentKeyInfo(std::wstring* key_name) { - ASSERT(key_name != NULL); - - // get the parent key - size_t index = key_name->rfind(L'\\'); - std::wstring parent_key; - if (index == -1) { - parent_key = L""; - } else { - parent_key = key_name->substr(0, index); - *key_name = key_name->substr(index + 1, key_name->length() - index - 1); - } - - return parent_key; -} - -// get the number of values for this key -uint32 RegKey::GetValueCount() { - DWORD num_values = 0; - - 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; -} - -// Enumerators for the value_names for this key - -// Called to get the value name for the given value name index -// Use GetValueCount() to get the total value_name count for this key -// Returns failure if no key at the specified index -HRESULT RegKey::GetValueNameAt(int index, std::wstring* value_name, - DWORD* type) { - ASSERT(value_name != NULL); - - LONG res = ERROR_SUCCESS; - wchar_t value_name_buf[kMaxValueNameChars] = {0}; - DWORD value_name_buf_size = kMaxValueNameChars; - res = ::RegEnumValue(h_key_, index, value_name_buf, &value_name_buf_size, - NULL, type, NULL, NULL); - - if (res == ERROR_SUCCESS) { - value_name->assign(value_name_buf); - } - - return HRESULT_FROM_WIN32(res); -} - -uint32 RegKey::GetSubkeyCount() { - // number of values for key - DWORD num_subkeys = 0; - - 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; -} - -HRESULT RegKey::GetSubkeyNameAt(int index, std::wstring* key_name) { - ASSERT(key_name != NULL); - - LONG res = ERROR_SUCCESS; - wchar_t key_name_buf[kMaxKeyNameChars] = {0}; - DWORD key_name_buf_size = kMaxKeyNameChars; - - res = ::RegEnumKeyEx(h_key_, index, key_name_buf, &key_name_buf_size, - NULL, NULL, NULL, NULL); - - if (res == ERROR_SUCCESS) { - key_name->assign(key_name_buf); - } - - return HRESULT_FROM_WIN32(res); -} - -// Is the key empty: having no sub-keys and values -bool RegKey::IsKeyEmpty(const wchar_t* full_key_name) { - ASSERT(full_key_name != NULL); - - bool is_empty = true; - - // Get the root HKEY - std::wstring key_name(full_key_name); - HKEY h_key = GetRootKeyInfo(&key_name); - - // Open the key to check - if (h_key != NULL) { - RegKey key; - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ); - if (SUCCEEDED(hr)) { - is_empty = key.GetSubkeyCount() == 0 && key.GetValueCount() == 0; - key.Close(); - } - } - - return is_empty; -} - -bool AdjustCurrentProcessPrivilege(const TCHAR* privilege, bool to_enable) { - ASSERT(privilege != NULL); - - bool ret = false; - HANDLE token; - if (::OpenProcessToken(::GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { - LUID luid; - memset(&luid, 0, sizeof(luid)); - if (::LookupPrivilegeValue(NULL, privilege, &luid)) { - TOKEN_PRIVILEGES privs; - privs.PrivilegeCount = 1; - privs.Privileges[0].Luid = luid; - privs.Privileges[0].Attributes = to_enable ? SE_PRIVILEGE_ENABLED : 0; - if (::AdjustTokenPrivileges(token, FALSE, &privs, 0, NULL, 0)) { - ret = true; - } else { - LOG_GLE(LS_ERROR) << "AdjustTokenPrivileges failed"; - } - } else { - LOG_GLE(LS_ERROR) << "LookupPrivilegeValue failed"; - } - CloseHandle(token); - } else { - LOG_GLE(LS_ERROR) << "OpenProcessToken(GetCurrentProcess) failed"; - } - - return ret; -} - -} // namespace rtc diff --git a/webrtc/base/win32regkey.h b/webrtc/base/win32regkey.h deleted file mode 100644 index b33d4dc2b..000000000 --- a/webrtc/base/win32regkey.h +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright 2003 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Registry configuration wrappers class -// -// Offers static functions for convenient -// fast access for individual values -// -// Also provides a wrapper class for efficient -// batch operations on values of a given registry key. -// - -#ifndef WEBRTC_BASE_WIN32REGKEY_H_ -#define WEBRTC_BASE_WIN32REGKEY_H_ - -#include -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/win32.h" - -namespace rtc { - -// maximum sizes registry key and value names -const int kMaxKeyNameChars = 255 + 1; -const int kMaxValueNameChars = 16383 + 1; - -class RegKey { - public: - // constructor - RegKey(); - - // destructor - ~RegKey(); - - // create a reg key - HRESULT Create(HKEY parent_key, const wchar_t* key_name); - - HRESULT Create(HKEY parent_key, - const wchar_t* key_name, - wchar_t* reg_class, - DWORD options, - REGSAM sam_desired, - LPSECURITY_ATTRIBUTES lp_sec_attr, - LPDWORD lp_disposition); - - // open an existing reg key - HRESULT Open(HKEY parent_key, const wchar_t* key_name); - - HRESULT Open(HKEY parent_key, const wchar_t* key_name, REGSAM sam_desired); - - // close this reg key - HRESULT Close(); - - // check if the key has a specified value - bool HasValue(const wchar_t* value_name) const; - - // get the number of values for this key - uint32 GetValueCount(); - - // Called to get the value name for the given value name index - // Use GetValueCount() to get the total value_name count for this key - // Returns failure if no key at the specified index - // If you modify the key while enumerating, the indexes will be out of order. - // Since the index order is not guaranteed, you need to reset your counting - // loop. - // 'type' refers to REG_DWORD, REG_QWORD, etc.. - // 'type' can be NULL if not interested in the value type - HRESULT GetValueNameAt(int index, std::wstring* value_name, DWORD* type); - - // check if the current key has the specified subkey - bool HasSubkey(const wchar_t* key_name) const; - - // get the number of subkeys for this key - uint32 GetSubkeyCount(); - - // Called to get the key name for the given key index - // Use GetSubkeyCount() to get the total count for this key - // Returns failure if no key at the specified index - // If you modify the key while enumerating, the indexes will be out of order. - // Since the index order is not guaranteed, you need to reset your counting - // loop. - HRESULT GetSubkeyNameAt(int index, std::wstring* key_name); - - // SETTERS - - // set an int32 value - use when reading multiple values from a key - HRESULT SetValue(const wchar_t* value_name, DWORD value) const; - - // set an int64 value - HRESULT SetValue(const wchar_t* value_name, DWORD64 value) const; - - // set a string value - HRESULT SetValue(const wchar_t* value_name, const wchar_t* value) const; - - // set binary data - HRESULT SetValue(const wchar_t* value_name, - const uint8* value, - DWORD byte_count) const; - - // set raw data, including type - HRESULT SetValue(const wchar_t* value_name, - const uint8* value, - DWORD byte_count, - DWORD type) const; - - // GETTERS - - // get an int32 value - HRESULT GetValue(const wchar_t* value_name, DWORD* value) const; - - // get an int64 value - HRESULT GetValue(const wchar_t* value_name, DWORD64* value) const; - - // get a string value - the caller must free the return buffer - HRESULT GetValue(const wchar_t* value_name, wchar_t** value) const; - - // get a string value - HRESULT GetValue(const wchar_t* value_name, std::wstring* value) const; - - // get a std::vector value from REG_MULTI_SZ type - HRESULT GetValue(const wchar_t* value_name, - std::vector* value) const; - - // get binary data - the caller must free the return buffer - HRESULT GetValue(const wchar_t* value_name, - uint8** value, - DWORD* byte_count) const; - - // get raw data, including type - the caller must free the return buffer - HRESULT GetValue(const wchar_t* value_name, - uint8** value, - DWORD* byte_count, - DWORD* type) const; - - // STATIC VERSIONS - - // flush - static HRESULT FlushKey(const wchar_t* full_key_name); - - // check if a key exists - static bool HasKey(const wchar_t* full_key_name); - - // check if the key has a specified value - static bool HasValue(const wchar_t* full_key_name, const wchar_t* value_name); - - // SETTERS - - // STATIC int32 set - static HRESULT SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD value); - - // STATIC int64 set - static HRESULT SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD64 value); - - // STATIC float set - static HRESULT SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - float value); - - // STATIC double set - static HRESULT SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - double value); - - // STATIC string set - static HRESULT SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - const wchar_t* value); - - // STATIC binary data set - static HRESULT SetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - const uint8* value, - DWORD byte_count); - - // STATIC multi-string set - static HRESULT SetValueMultiSZ(const wchar_t* full_key_name, - const TCHAR* value_name, - const uint8* value, - DWORD byte_count); - - // GETTERS - - // STATIC int32 get - static HRESULT GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD* value); - - // STATIC int64 get - // - // Note: if you are using time64 you should - // likely use GetLimitedTimeValue (util.h) instead of this method. - static HRESULT GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD64* value); - - // STATIC float get - static HRESULT GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - float* value); - - // STATIC double get - static HRESULT GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - double* value); - - // STATIC string get - // Note: the caller must free the return buffer for wchar_t* version - static HRESULT GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - wchar_t** value); - static HRESULT GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - std::wstring* value); - - // STATIC REG_MULTI_SZ get - static HRESULT GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - std::vector* value); - - // STATIC get binary data - the caller must free the return buffer - static HRESULT GetValue(const wchar_t* full_key_name, - const wchar_t* value_name, - uint8** value, - DWORD* byte_count); - - // Get type of a registry value - static HRESULT GetValueType(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD* value_type); - - // delete a subkey of the current key (with no subkeys) - HRESULT DeleteSubKey(const wchar_t* key_name); - - // recursively delete a sub key of the current key (and all its subkeys) - HRESULT RecurseDeleteSubKey(const wchar_t* key_name); - - // STATIC version of delete key - handles nested keys also - // delete a key and all its sub-keys recursively - // Returns S_FALSE if key didn't exist, S_OK if deletion was successful, - // and failure otherwise. - static HRESULT DeleteKey(const wchar_t* full_key_name); - - // STATIC version of delete key - // delete a key recursively or non-recursively - // Returns S_FALSE if key didn't exist, S_OK if deletion was successful, - // and failure otherwise. - static HRESULT DeleteKey(const wchar_t* full_key_name, bool recursive); - - // delete the specified value - HRESULT DeleteValue(const wchar_t* value_name); - - // STATIC version of delete value - // Returns S_FALSE if key didn't exist, S_OK if deletion was successful, - // and failure otherwise. - static HRESULT DeleteValue(const wchar_t* full_key_name, - const wchar_t* value_name); - - // Peek inside (use a RegKey as a smart wrapper around a registry handle) - HKEY key() { return h_key_; } - - // helper function to get the HKEY and the root key from a string - // modifies the argument in place and returns the key name - // e.g. HKLM\\Software\\Google\... returns HKLM, "Software\\Google\..." - // Necessary for the static versions that use the full name of the reg key - static HKEY GetRootKeyInfo(std::wstring* full_key_name); - - // Returns true if this key name is 'safe' for deletion (doesn't specify a key - // root) - static bool SafeKeyNameForDeletion(const wchar_t* key_name); - - // save the key and all of its subkeys and values to a file - static HRESULT Save(const wchar_t* full_key_name, const wchar_t* file_name); - - // restore the key and all of its subkeys and values which are saved into a - // file - static HRESULT Restore(const wchar_t* full_key_name, - const wchar_t* file_name); - - // Is the key empty: having no sub-keys and values - static bool IsKeyEmpty(const wchar_t* full_key_name); - - private: - - // helper function to get any value from the registry - // used when the size of the data is unknown - HRESULT GetValueHelper(const wchar_t* value_name, - DWORD* type, uint8** value, - DWORD* byte_count) const; - - // helper function to get the parent key name and the subkey from a string - // modifies the argument in place and returns the key name - // Necessary for the static versions that use the full name of the reg key - static std::wstring GetParentKeyInfo(std::wstring* key_name); - - // common SET Helper for the static case - static HRESULT SetValueStaticHelper(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD type, - LPVOID value, - DWORD byte_count = 0); - - // common GET Helper for the static case - static HRESULT GetValueStaticHelper(const wchar_t* full_key_name, - const wchar_t* value_name, - DWORD type, - LPVOID value, - DWORD* byte_count = NULL); - - // convert REG_MULTI_SZ bytes to string array - static HRESULT MultiSZBytesToStringArray(const uint8* buffer, - DWORD byte_count, - std::vector* value); - - // the HKEY for the current key - HKEY h_key_; - - // for unittest - friend void RegKeyHelperFunctionsTest(); - - DISALLOW_EVIL_CONSTRUCTORS(RegKey); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_WIN32REGKEY_H_ diff --git a/webrtc/base/win32regkey_unittest.cc b/webrtc/base/win32regkey_unittest.cc deleted file mode 100644 index 1e7738182..000000000 --- a/webrtc/base/win32regkey_unittest.cc +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright 2003 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Unittest for registry access API - -#include "webrtc/base/gunit.h" -#include "webrtc/base/common.h" -#include "webrtc/base/win32regkey.h" - -namespace rtc { - -#ifndef EXPECT_SUCCEEDED -#define EXPECT_SUCCEEDED(x) EXPECT_TRUE(SUCCEEDED(x)) -#endif - -#ifndef EXPECT_FAILED -#define EXPECT_FAILED(x) EXPECT_TRUE(FAILED(x)) -#endif - -#define kBaseKey L"Software\\Google\\__TEST" -#define kSubkeyName L"subkey_test" - -const wchar_t kRkey1[] = kBaseKey; -const wchar_t kRkey1SubkeyName[] = kSubkeyName; -const wchar_t kRkey1Subkey[] = kBaseKey L"\\" kSubkeyName; -const wchar_t kFullRkey1[] = L"HKCU\\" kBaseKey; -const wchar_t kFullRkey1Subkey[] = L"HKCU\\" kBaseKey L"\\" kSubkeyName; - -const wchar_t kValNameInt[] = L"Int32 Value"; -const DWORD kIntVal = 20; -const DWORD kIntVal2 = 30; - -const wchar_t kValNameInt64[] = L"Int64 Value"; -const DWORD64 kIntVal64 = 119600064000000000uI64; - -const wchar_t kValNameFloat[] = L"Float Value"; -const float kFloatVal = 12.3456789f; - -const wchar_t kValNameDouble[] = L"Double Value"; -const double kDoubleVal = 98.7654321; - -const wchar_t kValNameStr[] = L"Str Value"; -const wchar_t kStrVal[] = L"Some string data 1"; -const wchar_t kStrVal2[] = L"Some string data 2"; - -const wchar_t kValNameBinary[] = L"Binary Value"; -const char kBinaryVal[] = "Some binary data abcdefghi 1"; -const char kBinaryVal2[] = "Some binary data abcdefghi 2"; - -const wchar_t kValNameMultiStr[] = L"MultiStr Value"; -const wchar_t kMultiSZ[] = L"abc\0def\0P12345\0"; -const wchar_t kEmptyMultiSZ[] = L""; -const wchar_t kInvalidMultiSZ[] = {L'6', L'7', L'8'}; - -// friend function of RegKey -void RegKeyHelperFunctionsTest() { - // Try out some dud values - std::wstring temp_key = L""; - EXPECT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL); - EXPECT_STREQ(temp_key.c_str(), L""); - - temp_key = L"a"; - EXPECT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL); - EXPECT_STREQ(temp_key.c_str(), L""); - - // The basics - temp_key = L"HKLM\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - temp_key = L"HKEY_LOCAL_MACHINE\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - temp_key = L"HKCU\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - temp_key = L"HKEY_CURRENT_USER\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - temp_key = L"HKU\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - temp_key = L"HKEY_USERS\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - temp_key = L"HKCR\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - temp_key = L"HKEY_CLASSES_ROOT\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - // Make sure it is case insensitive - temp_key = L"hkcr\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - temp_key = L"hkey_CLASSES_ROOT\\a"; - EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - // - // Test RegKey::GetParentKeyInfo - // - - // dud cases - temp_key = L""; - EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L""); - EXPECT_STREQ(temp_key.c_str(), L""); - - temp_key = L"a"; - EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L""); - EXPECT_STREQ(temp_key.c_str(), L"a"); - - temp_key = L"a\\b"; - EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"a"); - EXPECT_STREQ(temp_key.c_str(), L"b"); - - temp_key = L"\\b"; - EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L""); - EXPECT_STREQ(temp_key.c_str(), L"b"); - - // Some regular cases - temp_key = L"HKEY_CLASSES_ROOT\\moon"; - EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), - L"HKEY_CLASSES_ROOT"); - EXPECT_STREQ(temp_key.c_str(), L"moon"); - - temp_key = L"HKEY_CLASSES_ROOT\\moon\\doggy"; - EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), - L"HKEY_CLASSES_ROOT\\moon"); - EXPECT_STREQ(temp_key.c_str(), L"doggy"); - - // - // Test MultiSZBytesToStringArray - // - - std::vector result; - EXPECT_SUCCEEDED(RegKey::MultiSZBytesToStringArray( - reinterpret_cast(kMultiSZ), sizeof(kMultiSZ), &result)); - EXPECT_EQ(result.size(), 3); - EXPECT_STREQ(result[0].c_str(), L"abc"); - EXPECT_STREQ(result[1].c_str(), L"def"); - EXPECT_STREQ(result[2].c_str(), L"P12345"); - - EXPECT_SUCCEEDED(RegKey::MultiSZBytesToStringArray( - reinterpret_cast(kEmptyMultiSZ), - sizeof(kEmptyMultiSZ), &result)); - EXPECT_EQ(result.size(), 0); - EXPECT_FALSE(SUCCEEDED(RegKey::MultiSZBytesToStringArray( - reinterpret_cast(kInvalidMultiSZ), - sizeof(kInvalidMultiSZ), &result))); -} - -TEST(RegKeyTest, RegKeyHelperFunctionsTest) { - RegKeyHelperFunctionsTest(); -} - -TEST(RegKeyTest, RegKeyNonStaticFunctionsTest) { - DWORD int_val = 0; - DWORD64 int64_val = 0; - wchar_t* str_val = NULL; - uint8* binary_val = NULL; - DWORD uint8_count = 0; - - // Just in case... - // make sure the no test key residue is left from previous aborted runs - RegKey::DeleteKey(kFullRkey1); - - // initial state - RegKey r_key; - EXPECT_TRUE(r_key.key() == NULL); - - // create a reg key - EXPECT_SUCCEEDED(r_key.Create(HKEY_CURRENT_USER, kRkey1)); - - // do the create twice - it should return the already created one - EXPECT_SUCCEEDED(r_key.Create(HKEY_CURRENT_USER, kRkey1)); - - // now do an open - should work just fine - EXPECT_SUCCEEDED(r_key.Open(HKEY_CURRENT_USER, kRkey1)); - - // get an in-existent value - EXPECT_EQ(r_key.GetValue(kValNameInt, &int_val), - HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); - - // set and get some values - - // set an INT 32 - EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal)); - - // check that the value exists - EXPECT_TRUE(r_key.HasValue(kValNameInt)); - - // read it back - EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt, &int_val)); - EXPECT_EQ(int_val, kIntVal); - - // set it again! - EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal2)); - - // read it again - EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt, &int_val)); - EXPECT_EQ(int_val, kIntVal2); - - // delete the value - EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameInt)); - - // check that the value is gone - EXPECT_FALSE(r_key.HasValue(kValNameInt)); - - // set an INT 64 - EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt64, kIntVal64)); - - // check that the value exists - EXPECT_TRUE(r_key.HasValue(kValNameInt64)); - - // read it back - EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt64, &int64_val)); - EXPECT_EQ(int64_val, kIntVal64); - - // delete the value - EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameInt64)); - - // check that the value is gone - EXPECT_FALSE(r_key.HasValue(kValNameInt64)); - - // set a string - EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal)); - - // check that the value exists - EXPECT_TRUE(r_key.HasValue(kValNameStr)); - - // read it back - EXPECT_SUCCEEDED(r_key.GetValue(kValNameStr, &str_val)); - EXPECT_TRUE(lstrcmp(str_val, kStrVal) == 0); - delete[] str_val; - - // set it again - EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal2)); - - // read it again - EXPECT_SUCCEEDED(r_key.GetValue(kValNameStr, &str_val)); - EXPECT_TRUE(lstrcmp(str_val, kStrVal2) == 0); - delete[] str_val; - - // delete the value - EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameStr)); - - // check that the value is gone - EXPECT_FALSE(r_key.HasValue(kValNameInt)); - - // set a binary value - EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary, - reinterpret_cast(kBinaryVal), sizeof(kBinaryVal) - 1)); - - // check that the value exists - EXPECT_TRUE(r_key.HasValue(kValNameBinary)); - - // read it back - EXPECT_SUCCEEDED(r_key.GetValue(kValNameBinary, &binary_val, &uint8_count)); - EXPECT_TRUE(memcmp(binary_val, kBinaryVal, sizeof(kBinaryVal) - 1) == 0); - delete[] binary_val; - - // set it again - EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary, - reinterpret_cast(kBinaryVal2), sizeof(kBinaryVal) - 1)); - - // read it again - EXPECT_SUCCEEDED(r_key.GetValue(kValNameBinary, &binary_val, &uint8_count)); - EXPECT_TRUE(memcmp(binary_val, kBinaryVal2, sizeof(kBinaryVal2) - 1) == 0); - delete[] binary_val; - - // delete the value - EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameBinary)); - - // check that the value is gone - EXPECT_FALSE(r_key.HasValue(kValNameBinary)); - - // set some values and check the total count - - // set an INT 32 - EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal)); - - // set an INT 64 - EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt64, kIntVal64)); - - // set a string - EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal)); - - // set a binary value - EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary, - reinterpret_cast(kBinaryVal), sizeof(kBinaryVal) - 1)); - - // get the value count - uint32 value_count = r_key.GetValueCount(); - EXPECT_EQ(value_count, 4); - - // check the value names - std::wstring value_name; - DWORD type = 0; - - EXPECT_SUCCEEDED(r_key.GetValueNameAt(0, &value_name, &type)); - EXPECT_STREQ(value_name.c_str(), kValNameInt); - EXPECT_EQ(type, REG_DWORD); - - EXPECT_SUCCEEDED(r_key.GetValueNameAt(1, &value_name, &type)); - EXPECT_STREQ(value_name.c_str(), kValNameInt64); - EXPECT_EQ(type, REG_QWORD); - - EXPECT_SUCCEEDED(r_key.GetValueNameAt(2, &value_name, &type)); - EXPECT_STREQ(value_name.c_str(), kValNameStr); - EXPECT_EQ(type, REG_SZ); - - EXPECT_SUCCEEDED(r_key.GetValueNameAt(3, &value_name, &type)); - EXPECT_STREQ(value_name.c_str(), kValNameBinary); - EXPECT_EQ(type, REG_BINARY); - - // check that there are no more values - EXPECT_FAILED(r_key.GetValueNameAt(4, &value_name, &type)); - - uint32 subkey_count = r_key.GetSubkeyCount(); - EXPECT_EQ(subkey_count, 0); - - // now create a subkey and make sure we can get the name - RegKey temp_key; - EXPECT_SUCCEEDED(temp_key.Create(HKEY_CURRENT_USER, kRkey1Subkey)); - - // check the subkey exists - EXPECT_TRUE(r_key.HasSubkey(kRkey1SubkeyName)); - - // check the name - EXPECT_EQ(r_key.GetSubkeyCount(), 1); - - std::wstring subkey_name; - EXPECT_SUCCEEDED(r_key.GetSubkeyNameAt(0, &subkey_name)); - EXPECT_STREQ(subkey_name.c_str(), kRkey1SubkeyName); - - // delete the key - EXPECT_SUCCEEDED(r_key.DeleteSubKey(kRkey1)); - - // close this key - EXPECT_SUCCEEDED(r_key.Close()); - - // whack the whole key - EXPECT_SUCCEEDED(RegKey::DeleteKey(kFullRkey1)); -} - -TEST(RegKeyTest, RegKeyStaticFunctionsTest) { - DWORD int_val = 0; - DWORD64 int64_val = 0; - float float_val = 0; - double double_val = 0; - wchar_t* str_val = NULL; - std::wstring wstr_val; - uint8* binary_val = NULL; - DWORD uint8_count = 0; - - // Just in case... - // make sure the no test key residue is left from previous aborted runs - RegKey::DeleteKey(kFullRkey1); - - // get an in-existent value from an un-existent key - EXPECT_EQ(RegKey::GetValue(kFullRkey1, kValNameInt, &int_val), - HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); - - // set int32 - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameInt, kIntVal)); - - // check that the value exists - EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameInt)); - - // get an in-existent value from an existent key - EXPECT_EQ(RegKey::GetValue(kFullRkey1, L"bogus", &int_val), - HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); - - // read it back - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameInt, &int_val)); - EXPECT_EQ(int_val, kIntVal); - - // delete the value - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameInt)); - - // check that the value is gone - EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameInt)); - - // set int64 - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameInt64, kIntVal64)); - - // check that the value exists - EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameInt64)); - - // read it back - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameInt64, &int64_val)); - EXPECT_EQ(int64_val, kIntVal64); - - // delete the value - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameInt64)); - - // check that the value is gone - EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameInt64)); - - // set float - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameFloat, kFloatVal)); - - // check that the value exists - EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameFloat)); - - // read it back - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameFloat, &float_val)); - EXPECT_EQ(float_val, kFloatVal); - - // delete the value - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameFloat)); - - // check that the value is gone - EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameFloat)); - EXPECT_FAILED(RegKey::GetValue(kFullRkey1, kValNameFloat, &float_val)); - - // set double - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameDouble, kDoubleVal)); - - // check that the value exists - EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameDouble)); - - // read it back - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameDouble, &double_val)); - EXPECT_EQ(double_val, kDoubleVal); - - // delete the value - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameDouble)); - - // check that the value is gone - EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameDouble)); - EXPECT_FAILED(RegKey::GetValue(kFullRkey1, kValNameDouble, &double_val)); - - // set string - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameStr, kStrVal)); - - // check that the value exists - EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameStr)); - - // read it back - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameStr, &str_val)); - EXPECT_TRUE(lstrcmp(str_val, kStrVal) == 0); - delete[] str_val; - - // read it back in std::wstring - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameStr, &wstr_val)); - EXPECT_STREQ(wstr_val.c_str(), kStrVal); - - // get an in-existent value from an existent key - EXPECT_EQ(RegKey::GetValue(kFullRkey1, L"bogus", &str_val), - HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); - - // delete the value - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameStr)); - - // check that the value is gone - EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameStr)); - - // set binary - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary, - reinterpret_cast(kBinaryVal), sizeof(kBinaryVal)-1)); - - // check that the value exists - EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary)); - - // read it back - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary, - &binary_val, &uint8_count)); - EXPECT_TRUE(memcmp(binary_val, kBinaryVal, sizeof(kBinaryVal)-1) == 0); - delete[] binary_val; - - // delete the value - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary)); - - // check that the value is gone - EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary)); - - // special case - set a binary value with length 0 - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary, - reinterpret_cast(kBinaryVal), 0)); - - // check that the value exists - EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary)); - - // read it back - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary, - &binary_val, &uint8_count)); - EXPECT_EQ(uint8_count, 0); - EXPECT_TRUE(binary_val == NULL); - delete[] binary_val; - - // delete the value - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary)); - - // check that the value is gone - EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary)); - - // special case - set a NULL binary value - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary, NULL, 100)); - - // check that the value exists - EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary)); - - // read it back - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary, - &binary_val, &uint8_count)); - EXPECT_EQ(uint8_count, 0); - EXPECT_TRUE(binary_val == NULL); - delete[] binary_val; - - // delete the value - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary)); - - // check that the value is gone - EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary)); - - // test read/write REG_MULTI_SZ value - std::vector result; - EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr, - reinterpret_cast(kMultiSZ), sizeof(kMultiSZ))); - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result)); - EXPECT_EQ(result.size(), 3); - EXPECT_STREQ(result[0].c_str(), L"abc"); - EXPECT_STREQ(result[1].c_str(), L"def"); - EXPECT_STREQ(result[2].c_str(), L"P12345"); - EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr, - reinterpret_cast(kEmptyMultiSZ), sizeof(kEmptyMultiSZ))); - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result)); - EXPECT_EQ(result.size(), 0); - // writing REG_MULTI_SZ value will automatically add ending null characters - EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr, - reinterpret_cast(kInvalidMultiSZ), sizeof(kInvalidMultiSZ))); - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result)); - EXPECT_EQ(result.size(), 1); - EXPECT_STREQ(result[0].c_str(), L"678"); - - // Run the following test only in dev machine - // This is because the build machine might not have admin privilege -#ifdef IS_PRIVATE_BUILD - // get a temp file name - wchar_t temp_path[MAX_PATH] = {0}; - EXPECT_LT(::GetTempPath(ARRAY_SIZE(temp_path), temp_path), - static_cast(ARRAY_SIZE(temp_path))); - wchar_t temp_file[MAX_PATH] = {0}; - EXPECT_NE(::GetTempFileName(temp_path, L"rkut_", - ::GetTickCount(), temp_file), 0); - - // test save - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1Subkey, kValNameInt, kIntVal)); - EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1Subkey, kValNameInt64, kIntVal64)); - EXPECT_SUCCEEDED(RegKey::Save(kFullRkey1Subkey, temp_file)); - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1Subkey, kValNameInt)); - EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1Subkey, kValNameInt64)); - - // test restore - EXPECT_SUCCEEDED(RegKey::Restore(kFullRkey1Subkey, temp_file)); - int_val = 0; - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1Subkey, kValNameInt, &int_val)); - EXPECT_EQ(int_val, kIntVal); - int64_val = 0; - EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1Subkey, - kValNameInt64, - &int64_val)); - EXPECT_EQ(int64_val, kIntVal64); - - // delete the temp file - EXPECT_EQ(TRUE, ::DeleteFile(temp_file)); -#endif - - // whack the whole key - EXPECT_SUCCEEDED(RegKey::DeleteKey(kFullRkey1)); -} - -} // namespace rtc diff --git a/webrtc/base/win32securityerrors.cc b/webrtc/base/win32securityerrors.cc deleted file mode 100644 index 71fe466a9..000000000 --- a/webrtc/base/win32securityerrors.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/win32.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// - -extern const ConstantLabel SECURITY_ERRORS[]; - -const ConstantLabel SECURITY_ERRORS[] = { - KLABEL(SEC_I_COMPLETE_AND_CONTINUE), - KLABEL(SEC_I_COMPLETE_NEEDED), - KLABEL(SEC_I_CONTEXT_EXPIRED), - KLABEL(SEC_I_CONTINUE_NEEDED), - KLABEL(SEC_I_INCOMPLETE_CREDENTIALS), - KLABEL(SEC_I_RENEGOTIATE), - KLABEL(SEC_E_CERT_EXPIRED), - KLABEL(SEC_E_INCOMPLETE_MESSAGE), - KLABEL(SEC_E_INSUFFICIENT_MEMORY), - KLABEL(SEC_E_INTERNAL_ERROR), - KLABEL(SEC_E_INVALID_HANDLE), - KLABEL(SEC_E_INVALID_TOKEN), - KLABEL(SEC_E_LOGON_DENIED), - KLABEL(SEC_E_NO_AUTHENTICATING_AUTHORITY), - KLABEL(SEC_E_NO_CREDENTIALS), - KLABEL(SEC_E_NOT_OWNER), - KLABEL(SEC_E_OK), - KLABEL(SEC_E_SECPKG_NOT_FOUND), - KLABEL(SEC_E_TARGET_UNKNOWN), - KLABEL(SEC_E_UNKNOWN_CREDENTIALS), - KLABEL(SEC_E_UNSUPPORTED_FUNCTION), - KLABEL(SEC_E_UNTRUSTED_ROOT), - KLABEL(SEC_E_WRONG_PRINCIPAL), - LASTLABEL -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/win32socketinit.cc b/webrtc/base/win32socketinit.cc deleted file mode 100644 index 02a6c26f4..000000000 --- a/webrtc/base/win32socketinit.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/win32socketinit.h" - -#include "webrtc/base/win32.h" - -namespace rtc { - -// Please don't remove this function. -void EnsureWinsockInit() { - // The default implementation uses a global initializer, so WSAStartup - // happens at module load time. Thus we don't need to do anything here. - // The hook is provided so that a client that statically links with - // libjingle can override it, to provide its own initialization. -} - -#if defined(WEBRTC_WIN) -class WinsockInitializer { - public: - WinsockInitializer() { - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(1, 0); - err_ = WSAStartup(wVersionRequested, &wsaData); - } - ~WinsockInitializer() { - if (!err_) - WSACleanup(); - } - int error() { - return err_; - } - private: - int err_; -}; -WinsockInitializer g_winsockinit; -#endif - -} // namespace rtc diff --git a/webrtc/base/win32socketinit.h b/webrtc/base/win32socketinit.h deleted file mode 100644 index 46d27cba0..000000000 --- a/webrtc/base/win32socketinit.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WIN32SOCKETINIT_H_ -#define WEBRTC_BASE_WIN32SOCKETINIT_H_ - -namespace rtc { - -void EnsureWinsockInit(); - -} // namespace rtc - -#endif // WEBRTC_BASE_WIN32SOCKETINIT_H_ diff --git a/webrtc/base/win32socketserver.cc b/webrtc/base/win32socketserver.cc deleted file mode 100644 index d0b736c58..000000000 --- a/webrtc/base/win32socketserver.cc +++ /dev/null @@ -1,850 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/win32socketserver.h" -#include "webrtc/base/byteorder.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/winping.h" -#include "webrtc/base/win32window.h" -#include // NOLINT - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// Win32Socket -/////////////////////////////////////////////////////////////////////////////// - -// TODO: Move this to a common place where PhysicalSocketServer can -// share it. -// Standard MTUs -static const uint16 PACKET_MAXIMUMS[] = { - 65535, // Theoretical maximum, Hyperchannel - 32000, // Nothing - 17914, // 16Mb IBM Token Ring - 8166, // IEEE 802.4 - // 4464 // IEEE 802.5 (4Mb max) - 4352, // FDDI - // 2048, // Wideband Network - 2002, // IEEE 802.5 (4Mb recommended) - // 1536, // Expermental Ethernet Networks - // 1500, // Ethernet, Point-to-Point (default) - 1492, // IEEE 802.3 - 1006, // SLIP, ARPANET - // 576, // X.25 Networks - // 544, // DEC IP Portal - // 512, // NETBIOS - 508, // IEEE 802/Source-Rt Bridge, ARCNET - 296, // Point-to-Point (low delay) - 68, // Official minimum - 0, // End of list marker -}; - -static const int IP_HEADER_SIZE = 20u; -static const int ICMP_HEADER_SIZE = 8u; -static const int ICMP_PING_TIMEOUT_MILLIS = 10000u; - -// TODO: Enable for production builds also? Use FormatMessage? -#ifdef _DEBUG -LPCSTR WSAErrorToString(int error, LPCSTR *description_result) { - LPCSTR string = "Unspecified"; - LPCSTR description = "Unspecified description"; - switch (error) { - case ERROR_SUCCESS: - string = "SUCCESS"; - description = "Operation succeeded"; - break; - case WSAEWOULDBLOCK: - string = "WSAEWOULDBLOCK"; - description = "Using a non-blocking socket, will notify later"; - break; - case WSAEACCES: - string = "WSAEACCES"; - description = "Access denied, or sharing violation"; - break; - case WSAEADDRNOTAVAIL: - string = "WSAEADDRNOTAVAIL"; - description = "Address is not valid in this context"; - break; - case WSAENETDOWN: - string = "WSAENETDOWN"; - description = "Network is down"; - break; - case WSAENETUNREACH: - string = "WSAENETUNREACH"; - description = "Network is up, but unreachable"; - break; - case WSAENETRESET: - string = "WSANETRESET"; - description = "Connection has been reset due to keep-alive activity"; - break; - case WSAECONNABORTED: - string = "WSAECONNABORTED"; - description = "Aborted by host"; - break; - case WSAECONNRESET: - string = "WSAECONNRESET"; - description = "Connection reset by host"; - break; - case WSAETIMEDOUT: - string = "WSAETIMEDOUT"; - description = "Timed out, host failed to respond"; - break; - case WSAECONNREFUSED: - string = "WSAECONNREFUSED"; - description = "Host actively refused connection"; - break; - case WSAEHOSTDOWN: - string = "WSAEHOSTDOWN"; - description = "Host is down"; - break; - case WSAEHOSTUNREACH: - string = "WSAEHOSTUNREACH"; - description = "Host is unreachable"; - break; - case WSAHOST_NOT_FOUND: - string = "WSAHOST_NOT_FOUND"; - description = "No such host is known"; - break; - } - if (description_result) { - *description_result = description; - } - return string; -} - -void ReportWSAError(LPCSTR context, int error, const SocketAddress& address) { - LPCSTR description_string; - LPCSTR error_string = WSAErrorToString(error, &description_string); - LOG(LS_INFO) << context << " = " << error - << " (" << error_string << ":" << description_string << ") [" - << address.ToString() << "]"; -} -#else -void ReportWSAError(LPCSTR context, int error, const SocketAddress& address) {} -#endif - -///////////////////////////////////////////////////////////////////////////// -// Win32Socket::EventSink -///////////////////////////////////////////////////////////////////////////// - -#define WM_SOCKETNOTIFY (WM_USER + 50) -#define WM_DNSNOTIFY (WM_USER + 51) - -struct Win32Socket::DnsLookup { - HANDLE handle; - uint16 port; - char buffer[MAXGETHOSTSTRUCT]; -}; - -class Win32Socket::EventSink : public Win32Window { - public: - explicit EventSink(Win32Socket * parent) : parent_(parent) { } - - void Dispose(); - - virtual bool OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, - LRESULT& result); - virtual void OnNcDestroy(); - - private: - bool OnSocketNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& result); - bool OnDnsNotify(WPARAM wParam, LPARAM lParam, LRESULT& result); - - Win32Socket * parent_; -}; - -void Win32Socket::EventSink::Dispose() { - parent_ = NULL; - if (::IsWindow(handle())) { - ::DestroyWindow(handle()); - } else { - delete this; - } -} - -bool Win32Socket::EventSink::OnMessage(UINT uMsg, WPARAM wParam, - LPARAM lParam, LRESULT& result) { - switch (uMsg) { - case WM_SOCKETNOTIFY: - case WM_TIMER: - return OnSocketNotify(uMsg, wParam, lParam, result); - case WM_DNSNOTIFY: - return OnDnsNotify(wParam, lParam, result); - } - return false; -} - -bool Win32Socket::EventSink::OnSocketNotify(UINT uMsg, WPARAM wParam, - LPARAM lParam, LRESULT& result) { - result = 0; - - int wsa_event = WSAGETSELECTEVENT(lParam); - int wsa_error = WSAGETSELECTERROR(lParam); - - // Treat connect timeouts as close notifications - if (uMsg == WM_TIMER) { - wsa_event = FD_CLOSE; - wsa_error = WSAETIMEDOUT; - } - - if (parent_) - parent_->OnSocketNotify(static_cast(wParam), wsa_event, wsa_error); - return true; -} - -bool Win32Socket::EventSink::OnDnsNotify(WPARAM wParam, LPARAM lParam, - LRESULT& result) { - result = 0; - - int error = WSAGETASYNCERROR(lParam); - if (parent_) - parent_->OnDnsNotify(reinterpret_cast(wParam), error); - return true; -} - -void Win32Socket::EventSink::OnNcDestroy() { - if (parent_) { - LOG(LS_ERROR) << "EventSink hwnd is being destroyed, but the event sink" - " hasn't yet been disposed."; - } else { - delete this; - } -} - -///////////////////////////////////////////////////////////////////////////// -// Win32Socket -///////////////////////////////////////////////////////////////////////////// - -Win32Socket::Win32Socket() - : socket_(INVALID_SOCKET), error_(0), state_(CS_CLOSED), connect_time_(0), - closing_(false), close_error_(0), sink_(NULL), dns_(NULL) { -} - -Win32Socket::~Win32Socket() { - Close(); -} - -bool Win32Socket::CreateT(int family, int type) { - Close(); - int proto = (SOCK_DGRAM == type) ? IPPROTO_UDP : IPPROTO_TCP; - socket_ = ::WSASocket(family, type, proto, NULL, NULL, 0); - if (socket_ == INVALID_SOCKET) { - UpdateLastError(); - return false; - } - if ((SOCK_DGRAM == type) && !SetAsync(FD_READ | FD_WRITE)) { - return false; - } - return true; -} - -int Win32Socket::Attach(SOCKET s) { - ASSERT(socket_ == INVALID_SOCKET); - if (socket_ != INVALID_SOCKET) - return SOCKET_ERROR; - - ASSERT(s != INVALID_SOCKET); - if (s == INVALID_SOCKET) - return SOCKET_ERROR; - - socket_ = s; - state_ = CS_CONNECTED; - - if (!SetAsync(FD_READ | FD_WRITE | FD_CLOSE)) - return SOCKET_ERROR; - - return 0; -} - -void Win32Socket::SetTimeout(int ms) { - if (sink_) - ::SetTimer(sink_->handle(), 1, ms, 0); -} - -SocketAddress Win32Socket::GetLocalAddress() const { - sockaddr_storage addr = {0}; - socklen_t addrlen = sizeof(addr); - int result = ::getsockname(socket_, reinterpret_cast(&addr), - &addrlen); - SocketAddress address; - if (result >= 0) { - SocketAddressFromSockAddrStorage(addr, &address); - } else { - LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket=" - << socket_; - } - return address; -} - -SocketAddress Win32Socket::GetRemoteAddress() const { - sockaddr_storage addr = {0}; - socklen_t addrlen = sizeof(addr); - int result = ::getpeername(socket_, reinterpret_cast(&addr), - &addrlen); - SocketAddress address; - if (result >= 0) { - SocketAddressFromSockAddrStorage(addr, &address); - } else { - LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket=" - << socket_; - } - return address; -} - -int Win32Socket::Bind(const SocketAddress& addr) { - ASSERT(socket_ != INVALID_SOCKET); - if (socket_ == INVALID_SOCKET) - return SOCKET_ERROR; - - sockaddr_storage saddr; - size_t len = addr.ToSockAddrStorage(&saddr); - int err = ::bind(socket_, - reinterpret_cast(&saddr), - static_cast(len)); - UpdateLastError(); - return err; -} - -int Win32Socket::Connect(const SocketAddress& addr) { - if (state_ != CS_CLOSED) { - SetError(EALREADY); - return SOCKET_ERROR; - } - - if (!addr.IsUnresolvedIP()) { - return DoConnect(addr); - } - - LOG_F(LS_INFO) << "async dns lookup (" << addr.hostname() << ")"; - DnsLookup * dns = new DnsLookup; - if (!sink_) { - // Explicitly create the sink ourselves here; we can't rely on SetAsync - // because we don't have a socket_ yet. - CreateSink(); - } - // TODO: Replace with IPv6 compatible lookup. - dns->handle = WSAAsyncGetHostByName(sink_->handle(), WM_DNSNOTIFY, - addr.hostname().c_str(), dns->buffer, - sizeof(dns->buffer)); - - if (!dns->handle) { - LOG_F(LS_ERROR) << "WSAAsyncGetHostByName error: " << WSAGetLastError(); - delete dns; - UpdateLastError(); - Close(); - return SOCKET_ERROR; - } - - dns->port = addr.port(); - dns_ = dns; - state_ = CS_CONNECTING; - return 0; -} - -int Win32Socket::DoConnect(const SocketAddress& addr) { - if ((socket_ == INVALID_SOCKET) && !CreateT(addr.family(), SOCK_STREAM)) { - return SOCKET_ERROR; - } - if (!SetAsync(FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE)) { - return SOCKET_ERROR; - } - - sockaddr_storage saddr = {0}; - size_t len = addr.ToSockAddrStorage(&saddr); - connect_time_ = Time(); - int result = connect(socket_, - reinterpret_cast(&saddr), - static_cast(len)); - if (result != SOCKET_ERROR) { - state_ = CS_CONNECTED; - } else { - int code = WSAGetLastError(); - if (code == WSAEWOULDBLOCK) { - state_ = CS_CONNECTING; - } else { - ReportWSAError("WSAAsync:connect", code, addr); - error_ = code; - Close(); - return SOCKET_ERROR; - } - } - addr_ = addr; - - return 0; -} - -int Win32Socket::GetError() const { - return error_; -} - -void Win32Socket::SetError(int error) { - error_ = error; -} - -Socket::ConnState Win32Socket::GetState() const { - return state_; -} - -int Win32Socket::GetOption(Option opt, int* value) { - int slevel; - int sopt; - if (TranslateOption(opt, &slevel, &sopt) == -1) - return -1; - - char* p = reinterpret_cast(value); - int optlen = sizeof(value); - return ::getsockopt(socket_, slevel, sopt, p, &optlen); -} - -int Win32Socket::SetOption(Option opt, int value) { - int slevel; - int sopt; - if (TranslateOption(opt, &slevel, &sopt) == -1) - return -1; - - const char* p = reinterpret_cast(&value); - return ::setsockopt(socket_, slevel, sopt, p, sizeof(value)); -} - -int Win32Socket::Send(const void* buffer, size_t length) { - int sent = ::send(socket_, - reinterpret_cast(buffer), - static_cast(length), - 0); - UpdateLastError(); - return sent; -} - -int Win32Socket::SendTo(const void* buffer, size_t length, - const SocketAddress& addr) { - sockaddr_storage saddr; - size_t addr_len = addr.ToSockAddrStorage(&saddr); - int sent = ::sendto(socket_, reinterpret_cast(buffer), - static_cast(length), 0, - reinterpret_cast(&saddr), - static_cast(addr_len)); - UpdateLastError(); - return sent; -} - -int Win32Socket::Recv(void* buffer, size_t length) { - int received = ::recv(socket_, static_cast(buffer), - static_cast(length), 0); - UpdateLastError(); - if (closing_ && received <= static_cast(length)) - PostClosed(); - return received; -} - -int Win32Socket::RecvFrom(void* buffer, size_t length, - SocketAddress* out_addr) { - sockaddr_storage saddr; - socklen_t addr_len = sizeof(saddr); - int received = ::recvfrom(socket_, static_cast(buffer), - static_cast(length), 0, - reinterpret_cast(&saddr), &addr_len); - UpdateLastError(); - if (received != SOCKET_ERROR) - SocketAddressFromSockAddrStorage(saddr, out_addr); - if (closing_ && received <= static_cast(length)) - PostClosed(); - return received; -} - -int Win32Socket::Listen(int backlog) { - int err = ::listen(socket_, backlog); - if (!SetAsync(FD_ACCEPT)) - return SOCKET_ERROR; - - UpdateLastError(); - if (err == 0) - state_ = CS_CONNECTING; - return err; -} - -Win32Socket* Win32Socket::Accept(SocketAddress* out_addr) { - sockaddr_storage saddr; - socklen_t addr_len = sizeof(saddr); - SOCKET s = ::accept(socket_, reinterpret_cast(&saddr), &addr_len); - UpdateLastError(); - if (s == INVALID_SOCKET) - return NULL; - if (out_addr) - SocketAddressFromSockAddrStorage(saddr, out_addr); - Win32Socket* socket = new Win32Socket; - if (0 == socket->Attach(s)) - return socket; - delete socket; - return NULL; -} - -int Win32Socket::Close() { - int err = 0; - if (socket_ != INVALID_SOCKET) { - err = ::closesocket(socket_); - socket_ = INVALID_SOCKET; - closing_ = false; - close_error_ = 0; - UpdateLastError(); - } - if (dns_) { - WSACancelAsyncRequest(dns_->handle); - delete dns_; - dns_ = NULL; - } - if (sink_) { - sink_->Dispose(); - sink_ = NULL; - } - addr_.Clear(); - state_ = CS_CLOSED; - return err; -} - -int Win32Socket::EstimateMTU(uint16* mtu) { - SocketAddress addr = GetRemoteAddress(); - if (addr.IsAny()) { - error_ = ENOTCONN; - return -1; - } - - WinPing ping; - if (!ping.IsValid()) { - error_ = EINVAL; // can't think of a better error ID - return -1; - } - - for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) { - int32 size = PACKET_MAXIMUMS[level] - IP_HEADER_SIZE - ICMP_HEADER_SIZE; - WinPing::PingResult result = ping.Ping(addr.ipaddr(), size, - ICMP_PING_TIMEOUT_MILLIS, 1, false); - if (result == WinPing::PING_FAIL) { - error_ = EINVAL; // can't think of a better error ID - return -1; - } - if (result != WinPing::PING_TOO_LARGE) { - *mtu = PACKET_MAXIMUMS[level]; - return 0; - } - } - - ASSERT(false); - return 0; -} - -void Win32Socket::CreateSink() { - ASSERT(NULL == sink_); - - // Create window - sink_ = new EventSink(this); - sink_->Create(NULL, L"EventSink", 0, 0, 0, 0, 10, 10); -} - -bool Win32Socket::SetAsync(int events) { - if (NULL == sink_) { - CreateSink(); - ASSERT(NULL != sink_); - } - - // start the async select - if (WSAAsyncSelect(socket_, sink_->handle(), WM_SOCKETNOTIFY, events) - == SOCKET_ERROR) { - UpdateLastError(); - Close(); - return false; - } - - return true; -} - -bool Win32Socket::HandleClosed(int close_error) { - // WM_CLOSE will be received before all data has been read, so we need to - // hold on to it until the read buffer has been drained. - char ch; - closing_ = true; - close_error_ = close_error; - return (::recv(socket_, &ch, 1, MSG_PEEK) <= 0); -} - -void Win32Socket::PostClosed() { - // If we see that the buffer is indeed drained, then send the close. - closing_ = false; - ::PostMessage(sink_->handle(), WM_SOCKETNOTIFY, - socket_, WSAMAKESELECTREPLY(FD_CLOSE, close_error_)); -} - -void Win32Socket::UpdateLastError() { - error_ = WSAGetLastError(); -} - -int Win32Socket::TranslateOption(Option opt, int* slevel, int* sopt) { - switch (opt) { - case OPT_DONTFRAGMENT: - *slevel = IPPROTO_IP; - *sopt = IP_DONTFRAGMENT; - break; - case OPT_RCVBUF: - *slevel = SOL_SOCKET; - *sopt = SO_RCVBUF; - break; - case OPT_SNDBUF: - *slevel = SOL_SOCKET; - *sopt = SO_SNDBUF; - break; - case OPT_NODELAY: - *slevel = IPPROTO_TCP; - *sopt = TCP_NODELAY; - break; - case OPT_DSCP: - LOG(LS_WARNING) << "Socket::OPT_DSCP not supported."; - return -1; - default: - ASSERT(false); - return -1; - } - return 0; -} - -void Win32Socket::OnSocketNotify(SOCKET socket, int event, int error) { - // Ignore events if we're already closed. - if (socket != socket_) - return; - - error_ = error; - switch (event) { - case FD_CONNECT: - if (error != ERROR_SUCCESS) { - ReportWSAError("WSAAsync:connect notify", error, addr_); -#ifdef _DEBUG - int32 duration = TimeSince(connect_time_); - LOG(LS_INFO) << "WSAAsync:connect error (" << duration - << " ms), faking close"; -#endif - state_ = CS_CLOSED; - // If you get an error connecting, close doesn't really do anything - // and it certainly doesn't send back any close notification, but - // we really only maintain a few states, so it is easiest to get - // back into a known state by pretending that a close happened, even - // though the connect event never did occur. - SignalCloseEvent(this, error); - } else { -#ifdef _DEBUG - int32 duration = TimeSince(connect_time_); - LOG(LS_INFO) << "WSAAsync:connect (" << duration << " ms)"; -#endif - state_ = CS_CONNECTED; - SignalConnectEvent(this); - } - break; - - case FD_ACCEPT: - case FD_READ: - if (error != ERROR_SUCCESS) { - ReportWSAError("WSAAsync:read notify", error, addr_); - } else { - SignalReadEvent(this); - } - break; - - case FD_WRITE: - if (error != ERROR_SUCCESS) { - ReportWSAError("WSAAsync:write notify", error, addr_); - } else { - SignalWriteEvent(this); - } - break; - - case FD_CLOSE: - if (HandleClosed(error)) { - ReportWSAError("WSAAsync:close notify", error, addr_); - state_ = CS_CLOSED; - SignalCloseEvent(this, error); - } - break; - } -} - -void Win32Socket::OnDnsNotify(HANDLE task, int error) { - if (!dns_ || dns_->handle != task) - return; - - uint32 ip = 0; - if (error == 0) { - hostent* pHost = reinterpret_cast(dns_->buffer); - uint32 net_ip = *reinterpret_cast(pHost->h_addr_list[0]); - ip = NetworkToHost32(net_ip); - } - - LOG_F(LS_INFO) << "(" << IPAddress(ip).ToSensitiveString() - << ", " << error << ")"; - - if (error == 0) { - SocketAddress address(ip, dns_->port); - error = DoConnect(address); - } else { - Close(); - } - - if (error) { - error_ = error; - SignalCloseEvent(this, error_); - } else { - delete dns_; - dns_ = NULL; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Win32SocketServer -// Provides cricket base services on top of a win32 gui thread -/////////////////////////////////////////////////////////////////////////////// - -static UINT s_wm_wakeup_id = 0; -const TCHAR Win32SocketServer::kWindowName[] = L"libjingle Message Window"; - -Win32SocketServer::Win32SocketServer(MessageQueue* message_queue) - : message_queue_(message_queue), - wnd_(this), - posted_(false), - hdlg_(NULL) { - if (s_wm_wakeup_id == 0) - s_wm_wakeup_id = RegisterWindowMessage(L"WM_WAKEUP"); - if (!wnd_.Create(NULL, kWindowName, 0, 0, 0, 0, 0, 0)) { - LOG_GLE(LS_ERROR) << "Failed to create message window."; - } -} - -Win32SocketServer::~Win32SocketServer() { - if (wnd_.handle() != NULL) { - KillTimer(wnd_.handle(), 1); - wnd_.Destroy(); - } -} - -Socket* Win32SocketServer::CreateSocket(int type) { - return CreateSocket(AF_INET, type); -} - -Socket* Win32SocketServer::CreateSocket(int family, int type) { - return CreateAsyncSocket(family, type); -} - -AsyncSocket* Win32SocketServer::CreateAsyncSocket(int type) { - return CreateAsyncSocket(AF_INET, type); -} - -AsyncSocket* Win32SocketServer::CreateAsyncSocket(int family, int type) { - Win32Socket* socket = new Win32Socket; - if (socket->CreateT(family, type)) { - return socket; - } - delete socket; - return NULL; -} - -void Win32SocketServer::SetMessageQueue(MessageQueue* queue) { - message_queue_ = queue; -} - -bool Win32SocketServer::Wait(int cms, bool process_io) { - BOOL b; - if (process_io) { - // Spin the Win32 message pump at least once, and as long as requested. - // This is the Thread::ProcessMessages case. - uint32 start = Time(); - do { - MSG msg; - SetTimer(wnd_.handle(), 0, cms, NULL); - // Get the next available message. If we have a modeless dialog, give - // give the message to IsDialogMessage, which will return true if it - // was a message for the dialog that it handled internally. - // Otherwise, dispatch as usual via Translate/DispatchMessage. - b = GetMessage(&msg, NULL, 0, 0); - if (b == -1) { - LOG_GLE(LS_ERROR) << "GetMessage failed."; - return false; - } else if(b) { - if (!hdlg_ || !IsDialogMessage(hdlg_, &msg)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - KillTimer(wnd_.handle(), 0); - } while (b && TimeSince(start) < cms); - } else if (cms != 0) { - // Sit and wait forever for a WakeUp. This is the Thread::Send case. - ASSERT(cms == -1); - MSG msg; - b = GetMessage(&msg, NULL, s_wm_wakeup_id, s_wm_wakeup_id); - { - CritScope scope(&cs_); - posted_ = false; - } - } else { - // No-op (cms == 0 && !process_io). This is the Pump case. - b = TRUE; - } - return (b != FALSE); -} - -void Win32SocketServer::WakeUp() { - if (wnd_.handle()) { - // Set the "message pending" flag, if not already set. - { - CritScope scope(&cs_); - if (posted_) - return; - posted_ = true; - } - - PostMessage(wnd_.handle(), s_wm_wakeup_id, 0, 0); - } -} - -void Win32SocketServer::Pump() { - // Clear the "message pending" flag. - { - CritScope scope(&cs_); - posted_ = false; - } - - // Dispatch all the messages that are currently in our queue. If new messages - // are posted during the dispatch, they will be handled in the next Pump. - // We use max(1, ...) to make sure we try to dispatch at least once, since - // this allow us to process "sent" messages, not included in the size() count. - Message msg; - for (size_t max_messages_to_process = _max(1, message_queue_->size()); - max_messages_to_process > 0 && message_queue_->Get(&msg, 0, false); - --max_messages_to_process) { - message_queue_->Dispatch(&msg); - } - - // Anything remaining? - int delay = message_queue_->GetDelay(); - if (delay == -1) { - KillTimer(wnd_.handle(), 1); - } else { - SetTimer(wnd_.handle(), 1, delay, NULL); - } -} - -bool Win32SocketServer::MessageWindow::OnMessage(UINT wm, WPARAM wp, - LPARAM lp, LRESULT& lr) { - bool handled = false; - if (wm == s_wm_wakeup_id || (wm == WM_TIMER && wp == 1)) { - ss_->Pump(); - lr = 0; - handled = true; - } - return handled; -} - -} // namespace rtc diff --git a/webrtc/base/win32socketserver.h b/webrtc/base/win32socketserver.h deleted file mode 100644 index a03f6c028..000000000 --- a/webrtc/base/win32socketserver.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WIN32SOCKETSERVER_H_ -#define WEBRTC_BASE_WIN32SOCKETSERVER_H_ - -#if defined(WEBRTC_WIN) -#include "webrtc/base/asyncsocket.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/messagequeue.h" -#include "webrtc/base/socketserver.h" -#include "webrtc/base/socketfactory.h" -#include "webrtc/base/socket.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/win32window.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// Win32Socket -/////////////////////////////////////////////////////////////////////////////// - -class Win32Socket : public AsyncSocket { - public: - Win32Socket(); - virtual ~Win32Socket(); - - bool CreateT(int family, int type); - - int Attach(SOCKET s); - void SetTimeout(int ms); - - // AsyncSocket Interface - virtual SocketAddress GetLocalAddress() const; - virtual SocketAddress GetRemoteAddress() const; - virtual int Bind(const SocketAddress& addr); - virtual int Connect(const SocketAddress& addr); - virtual int Send(const void *buffer, size_t length); - virtual int SendTo(const void *buffer, size_t length, const SocketAddress& addr); - virtual int Recv(void *buffer, size_t length); - virtual int RecvFrom(void *buffer, size_t length, SocketAddress *out_addr); - virtual int Listen(int backlog); - virtual Win32Socket *Accept(SocketAddress *out_addr); - virtual int Close(); - virtual int GetError() const; - virtual void SetError(int error); - virtual ConnState GetState() const; - virtual int EstimateMTU(uint16* mtu); - virtual int GetOption(Option opt, int* value); - virtual int SetOption(Option opt, int value); - - private: - void CreateSink(); - bool SetAsync(int events); - int DoConnect(const SocketAddress& addr); - bool HandleClosed(int close_error); - void PostClosed(); - void UpdateLastError(); - static int TranslateOption(Option opt, int* slevel, int* sopt); - - void OnSocketNotify(SOCKET socket, int event, int error); - void OnDnsNotify(HANDLE task, int error); - - SOCKET socket_; - int error_; - ConnState state_; - SocketAddress addr_; // address that we connected to (see DoConnect) - uint32 connect_time_; - bool closing_; - int close_error_; - - class EventSink; - friend class EventSink; - EventSink * sink_; - - struct DnsLookup; - DnsLookup * dns_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Win32SocketServer -/////////////////////////////////////////////////////////////////////////////// - -class Win32SocketServer : public SocketServer { - public: - explicit Win32SocketServer(MessageQueue* message_queue); - virtual ~Win32SocketServer(); - - void set_modeless_dialog(HWND hdlg) { - hdlg_ = hdlg; - } - - // SocketServer Interface - virtual Socket* CreateSocket(int type); - virtual Socket* CreateSocket(int family, int type); - - virtual AsyncSocket* CreateAsyncSocket(int type); - virtual AsyncSocket* CreateAsyncSocket(int family, int type); - - virtual void SetMessageQueue(MessageQueue* queue); - virtual bool Wait(int cms, bool process_io); - virtual void WakeUp(); - - void Pump(); - - HWND handle() { return wnd_.handle(); } - - private: - class MessageWindow : public Win32Window { - public: - explicit MessageWindow(Win32SocketServer* ss) : ss_(ss) {} - private: - virtual bool OnMessage(UINT msg, WPARAM wp, LPARAM lp, LRESULT& result); - Win32SocketServer* ss_; - }; - - static const TCHAR kWindowName[]; - MessageQueue *message_queue_; - MessageWindow wnd_; - CriticalSection cs_; - bool posted_; - HWND hdlg_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Win32Thread. Automatically pumps Windows messages. -/////////////////////////////////////////////////////////////////////////////// - -class Win32Thread : public Thread { - public: - Win32Thread() : ss_(this), id_(0) { - set_socketserver(&ss_); - } - virtual ~Win32Thread() { - Stop(); - set_socketserver(NULL); - } - virtual void Run() { - id_ = GetCurrentThreadId(); - Thread::Run(); - id_ = 0; - } - virtual void Quit() { - PostThreadMessage(id_, WM_QUIT, 0, 0); - } - private: - Win32SocketServer ss_; - DWORD id_; -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_WIN - -#endif // WEBRTC_BASE_WIN32SOCKETSERVER_H_ diff --git a/webrtc/base/win32socketserver_unittest.cc b/webrtc/base/win32socketserver_unittest.cc deleted file mode 100644 index 1d3ef2ea3..000000000 --- a/webrtc/base/win32socketserver_unittest.cc +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "webrtc/base/gunit.h" -#include "webrtc/base/socket_unittest.h" -#include "webrtc/base/thread.h" -#include "webrtc/base/win32socketserver.h" - -namespace rtc { - -// Test that Win32SocketServer::Wait works as expected. -TEST(Win32SocketServerTest, TestWait) { - Win32SocketServer server(NULL); - uint32 start = Time(); - server.Wait(1000, true); - EXPECT_GE(TimeSince(start), 1000); -} - -// Test that Win32Socket::Pump does not touch general Windows messages. -TEST(Win32SocketServerTest, TestPump) { - Win32SocketServer server(NULL); - SocketServerScope scope(&server); - EXPECT_EQ(TRUE, PostMessage(NULL, WM_USER, 999, 0)); - server.Pump(); - MSG msg; - EXPECT_EQ(TRUE, PeekMessage(&msg, NULL, WM_USER, 0, PM_REMOVE)); - EXPECT_EQ(WM_USER, msg.message); - EXPECT_EQ(999, msg.wParam); -} - -// Test that Win32Socket passes all the generic Socket tests. -class Win32SocketTest : public SocketTest { - protected: - Win32SocketTest() : server_(NULL), scope_(&server_) {} - Win32SocketServer server_; - SocketServerScope scope_; -}; - -TEST_F(Win32SocketTest, TestConnectIPv4) { - SocketTest::TestConnectIPv4(); -} - -TEST_F(Win32SocketTest, TestConnectIPv6) { - SocketTest::TestConnectIPv6(); -} - -TEST_F(Win32SocketTest, TestConnectWithDnsLookupIPv4) { - SocketTest::TestConnectWithDnsLookupIPv4(); -} - -TEST_F(Win32SocketTest, TestConnectWithDnsLookupIPv6) { - SocketTest::TestConnectWithDnsLookupIPv6(); -} - -TEST_F(Win32SocketTest, TestConnectFailIPv4) { - SocketTest::TestConnectFailIPv4(); -} - -TEST_F(Win32SocketTest, TestConnectFailIPv6) { - SocketTest::TestConnectFailIPv6(); -} - -TEST_F(Win32SocketTest, TestConnectWithDnsLookupFailIPv4) { - SocketTest::TestConnectWithDnsLookupFailIPv4(); -} - -TEST_F(Win32SocketTest, TestConnectWithDnsLookupFailIPv6) { - SocketTest::TestConnectWithDnsLookupFailIPv6(); -} - -TEST_F(Win32SocketTest, TestConnectWithClosedSocketIPv4) { - SocketTest::TestConnectWithClosedSocketIPv4(); -} - -TEST_F(Win32SocketTest, TestConnectWithClosedSocketIPv6) { - SocketTest::TestConnectWithClosedSocketIPv6(); -} - -TEST_F(Win32SocketTest, TestConnectWhileNotClosedIPv4) { - SocketTest::TestConnectWhileNotClosedIPv4(); -} - -TEST_F(Win32SocketTest, TestConnectWhileNotClosedIPv6) { - SocketTest::TestConnectWhileNotClosedIPv6(); -} - -TEST_F(Win32SocketTest, TestServerCloseDuringConnectIPv4) { - SocketTest::TestServerCloseDuringConnectIPv4(); -} - -TEST_F(Win32SocketTest, TestServerCloseDuringConnectIPv6) { - SocketTest::TestServerCloseDuringConnectIPv6(); -} - -TEST_F(Win32SocketTest, TestClientCloseDuringConnectIPv4) { - SocketTest::TestClientCloseDuringConnectIPv4(); -} - -TEST_F(Win32SocketTest, TestClientCloseDuringConnectIPv6) { - SocketTest::TestClientCloseDuringConnectIPv6(); -} - -TEST_F(Win32SocketTest, TestServerCloseIPv4) { - SocketTest::TestServerCloseIPv4(); -} - -TEST_F(Win32SocketTest, TestServerCloseIPv6) { - SocketTest::TestServerCloseIPv6(); -} - -TEST_F(Win32SocketTest, TestCloseInClosedCallbackIPv4) { - SocketTest::TestCloseInClosedCallbackIPv4(); -} - -TEST_F(Win32SocketTest, TestCloseInClosedCallbackIPv6) { - SocketTest::TestCloseInClosedCallbackIPv6(); -} - -TEST_F(Win32SocketTest, TestSocketServerWaitIPv4) { - SocketTest::TestSocketServerWaitIPv4(); -} - -TEST_F(Win32SocketTest, TestSocketServerWaitIPv6) { - SocketTest::TestSocketServerWaitIPv6(); -} - -TEST_F(Win32SocketTest, TestTcpIPv4) { - SocketTest::TestTcpIPv4(); -} - -TEST_F(Win32SocketTest, TestTcpIPv6) { - SocketTest::TestTcpIPv6(); -} - -TEST_F(Win32SocketTest, TestUdpIPv4) { - SocketTest::TestUdpIPv4(); -} - -TEST_F(Win32SocketTest, TestUdpIPv6) { - SocketTest::TestUdpIPv6(); -} - -TEST_F(Win32SocketTest, TestGetSetOptionsIPv4) { - SocketTest::TestGetSetOptionsIPv4(); -} - -TEST_F(Win32SocketTest, TestGetSetOptionsIPv6) { - SocketTest::TestGetSetOptionsIPv6(); -} - -} // namespace rtc diff --git a/webrtc/base/win32toolhelp.h b/webrtc/base/win32toolhelp.h deleted file mode 100644 index dfafdb317..000000000 --- a/webrtc/base/win32toolhelp.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef WEBRTC_BASE_WIN32TOOLHELP_H_ -#define WEBRTC_BASE_WIN32TOOLHELP_H_ - -#if !defined(WEBRTC_WIN) -#error WEBRTC_WIN Only -#endif - -#include "webrtc/base/win32.h" - -// Should be included first, but that causes redefinitions. -#include - -#include "webrtc/base/constructormagic.h" - -namespace rtc { - -// The toolhelp api used to enumerate processes and their modules -// on Windows is very repetetive and clunky to use. This little -// template wraps it to make it a little more programmer friendly. -// -// Traits: Traits type that adapts the enumerator to the corresponding -// win32 toolhelp api. Each traits class need to: -// - define the type of the enumerated data as a public symbol Type -// -// - implement bool First(HANDLE, T*) normally calls a -// Xxxx32First method in the toolhelp API. Ex Process32First(...) -// -// - implement bool Next(HANDLE, T*) normally calls a -// Xxxx32Next method in the toolhelp API. Ex Process32Next(...) -// -// - implement bool CloseHandle(HANDLE) -// -template -class ToolhelpEnumeratorBase { - public: - ToolhelpEnumeratorBase(HANDLE snapshot) - : snapshot_(snapshot), broken_(false), first_(true) { - - // Clear out the Traits::Type structure instance. - Zero(¤t_); - } - - virtual ~ToolhelpEnumeratorBase() { - Close(); - } - - // Moves forward to the next object using the First and Next - // pointers. If either First or Next ever indicates an failure - // all subsequent calls to this method will fail; the enumerator - // object is considered broken. - bool Next() { - if (!Valid()) { - return false; - } - - // Move the iteration forward. - current_.dwSize = sizeof(typename Traits::Type); - bool incr_ok = false; - if (first_) { - incr_ok = Traits::First(snapshot_, ¤t_); - first_ = false; - } else { - incr_ok = Traits::Next(snapshot_, ¤t_); - } - - if (!incr_ok) { - Zero(¤t_); - broken_ = true; - } - - return incr_ok; - } - - const typename Traits::Type& current() const { - return current_; - } - - void Close() { - if (snapshot_ != INVALID_HANDLE_VALUE) { - Traits::CloseHandle(snapshot_); - snapshot_ = INVALID_HANDLE_VALUE; - } - } - - private: - // Checks the state of the snapshot handle. - bool Valid() { - return snapshot_ != INVALID_HANDLE_VALUE && !broken_; - } - - static void Zero(typename Traits::Type* buff) { - ZeroMemory(buff, sizeof(typename Traits::Type)); - } - - HANDLE snapshot_; - typename Traits::Type current_; - bool broken_; - bool first_; -}; - -class ToolhelpTraits { - public: - static HANDLE CreateSnapshot(uint32 flags, uint32 process_id) { - return CreateToolhelp32Snapshot(flags, process_id); - } - - static bool CloseHandle(HANDLE handle) { - return ::CloseHandle(handle) == TRUE; - } -}; - -class ToolhelpProcessTraits : public ToolhelpTraits { - public: - typedef PROCESSENTRY32 Type; - - static bool First(HANDLE handle, Type* t) { - return ::Process32First(handle, t) == TRUE; - } - - static bool Next(HANDLE handle, Type* t) { - return ::Process32Next(handle, t) == TRUE; - } -}; - -class ProcessEnumerator : public ToolhelpEnumeratorBase { - public: - ProcessEnumerator() - : ToolhelpEnumeratorBase( - ToolhelpProcessTraits::CreateSnapshot(TH32CS_SNAPPROCESS, 0)) { - } - - private: - DISALLOW_EVIL_CONSTRUCTORS(ProcessEnumerator); -}; - -class ToolhelpModuleTraits : public ToolhelpTraits { - public: - typedef MODULEENTRY32 Type; - - static bool First(HANDLE handle, Type* t) { - return ::Module32First(handle, t) == TRUE; - } - - static bool Next(HANDLE handle, Type* t) { - return ::Module32Next(handle, t) == TRUE; - } -}; - -class ModuleEnumerator : public ToolhelpEnumeratorBase { - public: - explicit ModuleEnumerator(uint32 process_id) - : ToolhelpEnumeratorBase( - ToolhelpModuleTraits::CreateSnapshot(TH32CS_SNAPMODULE, - process_id)) { - } - - private: - DISALLOW_EVIL_CONSTRUCTORS(ModuleEnumerator); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_WIN32TOOLHELP_H_ diff --git a/webrtc/base/win32toolhelp_unittest.cc b/webrtc/base/win32toolhelp_unittest.cc deleted file mode 100644 index 280f2ec98..000000000 --- a/webrtc/base/win32toolhelp_unittest.cc +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/pathutils.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/win32toolhelp.h" - -namespace rtc { - -typedef struct { - // Required to match the toolhelp api struct 'design'. - DWORD dwSize; - int a; - uint32 b; -} TestData; - -class Win32ToolhelpTest : public testing::Test { - public: - Win32ToolhelpTest() { - } - - HANDLE AsHandle() { - return reinterpret_cast(this); - } - - static Win32ToolhelpTest* AsFixture(HANDLE handle) { - return reinterpret_cast(handle); - } - - static bool First(HANDLE handle, TestData* d) { - Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle); - // This method should be called only once for every test. - // If it is called more than once it return false which - // should break the test. - EXPECT_EQ(0, tst->first_called_); // Just to be safe. - if (tst->first_called_ > 0) { - return false; - } - - *d = kTestData[0]; - tst->index_ = 1; - ++(tst->first_called_); - return true; - } - - static bool Next(HANDLE handle, TestData* d) { - Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle); - ++(tst->next_called_); - - if (tst->index_ >= kTestDataSize) { - return FALSE; - } - - *d = kTestData[tst->index_]; - ++(tst->index_); - return true; - } - - static bool Fail(HANDLE handle, TestData* d) { - Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle); - ++(tst->fail_called_); - return false; - } - - static bool CloseHandle(HANDLE handle) { - Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle); - ++(tst->close_handle_called_); - return true; - } - - protected: - virtual void SetUp() { - fail_called_ = 0; - first_called_ = 0; - next_called_ = 0; - close_handle_called_ = 0; - index_ = 0; - } - - static bool AllZero(const TestData& data) { - return data.dwSize == 0 && data.a == 0 && data.b == 0; - } - - static bool Equals(const TestData& expected, const TestData& actual) { - return expected.dwSize == actual.dwSize - && expected.a == actual.a - && expected.b == actual.b; - } - - bool CheckCallCounters(int first, int next, int fail, int close) { - bool match = first_called_ == first && next_called_ == next - && fail_called_ == fail && close_handle_called_ == close; - - if (!match) { - LOG(LS_ERROR) << "Expected: (" - << first << ", " - << next << ", " - << fail << ", " - << close << ")"; - - LOG(LS_ERROR) << "Actual: (" - << first_called_ << ", " - << next_called_ << ", " - << fail_called_ << ", " - << close_handle_called_ << ")"; - } - return match; - } - - static const int kTestDataSize = 3; - static const TestData kTestData[]; - int index_; - int first_called_; - int fail_called_; - int next_called_; - int close_handle_called_; -}; - -const TestData Win32ToolhelpTest::kTestData[] = { - {1, 1, 1}, {2, 2, 2}, {3, 3, 3} -}; - - -class TestTraits { - public: - typedef TestData Type; - - static bool First(HANDLE handle, Type* t) { - return Win32ToolhelpTest::First(handle, t); - } - - static bool Next(HANDLE handle, Type* t) { - return Win32ToolhelpTest::Next(handle, t); - } - - static bool CloseHandle(HANDLE handle) { - return Win32ToolhelpTest::CloseHandle(handle); - } -}; - -class BadFirstTraits { - public: - typedef TestData Type; - - static bool First(HANDLE handle, Type* t) { - return Win32ToolhelpTest::Fail(handle, t); - } - - static bool Next(HANDLE handle, Type* t) { - // This should never be called. - ADD_FAILURE(); - return false; - } - - static bool CloseHandle(HANDLE handle) { - return Win32ToolhelpTest::CloseHandle(handle); - } -}; - -class BadNextTraits { - public: - typedef TestData Type; - - static bool First(HANDLE handle, Type* t) { - return Win32ToolhelpTest::First(handle, t); - } - - static bool Next(HANDLE handle, Type* t) { - return Win32ToolhelpTest::Fail(handle, t); - } - - static bool CloseHandle(HANDLE handle) { - return Win32ToolhelpTest::CloseHandle(handle); - } -}; - -// The toolhelp in normally inherited but most of -// these tests only excercise the methods from the -// traits therefore I use a typedef to make the -// test code easier to read. -typedef rtc::ToolhelpEnumeratorBase EnumeratorForTest; - -TEST_F(Win32ToolhelpTest, TestNextWithInvalidCtorHandle) { - EnumeratorForTest t(INVALID_HANDLE_VALUE); - - EXPECT_FALSE(t.Next()); - EXPECT_TRUE(CheckCallCounters(0, 0, 0, 0)); -} - -// Tests that Next() returns false if the first-pointer -// function fails. -TEST_F(Win32ToolhelpTest, TestNextFirstFails) { - typedef rtc::ToolhelpEnumeratorBase BadEnumerator; - rtc::scoped_ptr t(new BadEnumerator(AsHandle())); - - // If next ever fails it shall always fail. - EXPECT_FALSE(t->Next()); - EXPECT_FALSE(t->Next()); - EXPECT_FALSE(t->Next()); - t.reset(); - EXPECT_TRUE(CheckCallCounters(0, 0, 1, 1)); -} - -// Tests that Next() returns false if the next-pointer -// function fails. -TEST_F(Win32ToolhelpTest, TestNextNextFails) { - typedef rtc::ToolhelpEnumeratorBase BadEnumerator; - rtc::scoped_ptr t(new BadEnumerator(AsHandle())); - - // If next ever fails it shall always fail. No more calls - // shall be dispatched to Next(...). - EXPECT_TRUE(t->Next()); - EXPECT_FALSE(t->Next()); - EXPECT_FALSE(t->Next()); - t.reset(); - EXPECT_TRUE(CheckCallCounters(1, 0, 1, 1)); -} - - -// Tests that current returns an object is all zero's -// if Next() hasn't been called. -TEST_F(Win32ToolhelpTest, TestCurrentNextNotCalled) { - rtc::scoped_ptr t(new EnumeratorForTest(AsHandle())); - EXPECT_TRUE(AllZero(t->current())); - t.reset(); - EXPECT_TRUE(CheckCallCounters(0, 0, 0, 1)); -} - -// Tests the simple everything works path through the code. -TEST_F(Win32ToolhelpTest, TestCurrentNextCalled) { - rtc::scoped_ptr t(new EnumeratorForTest(AsHandle())); - - EXPECT_TRUE(t->Next()); - EXPECT_TRUE(Equals(t->current(), kTestData[0])); - EXPECT_TRUE(t->Next()); - EXPECT_TRUE(Equals(t->current(), kTestData[1])); - EXPECT_TRUE(t->Next()); - EXPECT_TRUE(Equals(t->current(), kTestData[2])); - EXPECT_FALSE(t->Next()); - t.reset(); - EXPECT_TRUE(CheckCallCounters(1, 3, 0, 1)); -} - -TEST_F(Win32ToolhelpTest, TestCurrentProcess) { - WCHAR buf[MAX_PATH]; - GetModuleFileName(NULL, buf, ARRAY_SIZE(buf)); - std::wstring name = ToUtf16(Pathname(ToUtf8(buf)).filename()); - - rtc::ProcessEnumerator processes; - bool found = false; - while (processes.Next()) { - if (!name.compare(processes.current().szExeFile)) { - found = true; - break; - } - } - EXPECT_TRUE(found); - - rtc::ModuleEnumerator modules(processes.current().th32ProcessID); - found = false; - while (modules.Next()) { - if (!name.compare(modules.current().szModule)) { - found = true; - break; - } - } - EXPECT_TRUE(found); -} - -} // namespace rtc diff --git a/webrtc/base/win32window.cc b/webrtc/base/win32window.cc deleted file mode 100644 index 4d4101405..000000000 --- a/webrtc/base/win32window.cc +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/win32window.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// Win32Window -/////////////////////////////////////////////////////////////////////////////// - -static const wchar_t kWindowBaseClassName[] = L"WindowBaseClass"; -HINSTANCE Win32Window::instance_ = NULL; -ATOM Win32Window::window_class_ = 0; - -Win32Window::Win32Window() : wnd_(NULL) { -} - -Win32Window::~Win32Window() { - ASSERT(NULL == wnd_); -} - -bool Win32Window::Create(HWND parent, const wchar_t* title, DWORD style, - DWORD exstyle, int x, int y, int cx, int cy) { - if (wnd_) { - // Window already exists. - return false; - } - - if (!window_class_) { - if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - reinterpret_cast(&Win32Window::WndProc), - &instance_)) { - LOG_GLE(LS_ERROR) << "GetModuleHandleEx failed"; - return false; - } - - // Class not registered, register it. - WNDCLASSEX wcex; - memset(&wcex, 0, sizeof(wcex)); - wcex.cbSize = sizeof(wcex); - wcex.hInstance = instance_; - wcex.lpfnWndProc = &Win32Window::WndProc; - wcex.lpszClassName = kWindowBaseClassName; - window_class_ = ::RegisterClassEx(&wcex); - if (!window_class_) { - LOG_GLE(LS_ERROR) << "RegisterClassEx failed"; - return false; - } - } - wnd_ = ::CreateWindowEx(exstyle, kWindowBaseClassName, title, style, - x, y, cx, cy, parent, NULL, instance_, this); - return (NULL != wnd_); -} - -void Win32Window::Destroy() { - VERIFY(::DestroyWindow(wnd_) != FALSE); -} - -void Win32Window::Shutdown() { - if (window_class_) { - ::UnregisterClass(MAKEINTATOM(window_class_), instance_); - window_class_ = 0; - } -} - -bool Win32Window::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, - LRESULT& result) { - switch (uMsg) { - case WM_CLOSE: - if (!OnClose()) { - result = 0; - return true; - } - break; - } - return false; -} - -LRESULT Win32Window::WndProc(HWND hwnd, UINT uMsg, - WPARAM wParam, LPARAM lParam) { - Win32Window* that = reinterpret_cast( - ::GetWindowLongPtr(hwnd, GWLP_USERDATA)); - if (!that && (WM_CREATE == uMsg)) { - CREATESTRUCT* cs = reinterpret_cast(lParam); - that = static_cast(cs->lpCreateParams); - that->wnd_ = hwnd; - ::SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast(that)); - } - if (that) { - LRESULT result; - bool handled = that->OnMessage(uMsg, wParam, lParam, result); - if (WM_DESTROY == uMsg) { - for (HWND child = ::GetWindow(hwnd, GW_CHILD); child; - child = ::GetWindow(child, GW_HWNDNEXT)) { - LOG(LS_INFO) << "Child window: " << static_cast(child); - } - } - if (WM_NCDESTROY == uMsg) { - ::SetWindowLongPtr(hwnd, GWLP_USERDATA, NULL); - that->wnd_ = NULL; - that->OnNcDestroy(); - } - if (handled) { - return result; - } - } - return ::DefWindowProc(hwnd, uMsg, wParam, lParam); -} - -} // namespace rtc diff --git a/webrtc/base/win32window.h b/webrtc/base/win32window.h deleted file mode 100644 index c0ba6b23d..000000000 --- a/webrtc/base/win32window.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WIN32WINDOW_H_ -#define WEBRTC_BASE_WIN32WINDOW_H_ - -#if defined(WEBRTC_WIN) - -#include "webrtc/base/win32.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// Win32Window -/////////////////////////////////////////////////////////////////////////////// - -class Win32Window { - public: - Win32Window(); - virtual ~Win32Window(); - - HWND handle() const { return wnd_; } - - bool Create(HWND parent, const wchar_t* title, DWORD style, DWORD exstyle, - int x, int y, int cx, int cy); - void Destroy(); - - // Call this when your DLL unloads. - static void Shutdown(); - - protected: - virtual bool OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, - LRESULT& result); - - virtual bool OnClose() { return true; } - virtual void OnNcDestroy() { } - - private: - static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, - LPARAM lParam); - - HWND wnd_; - static HINSTANCE instance_; - static ATOM window_class_; -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_WIN - -#endif // WEBRTC_BASE_WIN32WINDOW_H_ diff --git a/webrtc/base/win32window_unittest.cc b/webrtc/base/win32window_unittest.cc deleted file mode 100644 index 5dba67eb5..000000000 --- a/webrtc/base/win32window_unittest.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/common.h" -#include "webrtc/base/win32window.h" -#include "webrtc/base/logging.h" - -static LRESULT kDummyResult = 0x1234ABCD; - -class TestWindow : public rtc::Win32Window { - public: - TestWindow() : destroyed_(false) { memset(&msg_, 0, sizeof(msg_)); } - const MSG& msg() const { return msg_; } - bool destroyed() const { return destroyed_; } - - virtual bool OnMessage(UINT uMsg, WPARAM wParam, - LPARAM lParam, LRESULT& result) { - msg_.message = uMsg; - msg_.wParam = wParam; - msg_.lParam = lParam; - result = kDummyResult; - return true; - } - virtual void OnNcDestroy() { - destroyed_ = true; - } - - private: - MSG msg_; - bool destroyed_; -}; - -TEST(Win32WindowTest, Basics) { - TestWindow wnd; - EXPECT_TRUE(wnd.handle() == NULL); - EXPECT_FALSE(wnd.destroyed()); - EXPECT_TRUE(wnd.Create(0, L"Test", 0, 0, 0, 0, 100, 100)); - EXPECT_TRUE(wnd.handle() != NULL); - EXPECT_EQ(kDummyResult, ::SendMessage(wnd.handle(), WM_USER, 1, 2)); - EXPECT_EQ(WM_USER, wnd.msg().message); - EXPECT_EQ(1, wnd.msg().wParam); - EXPECT_EQ(2, wnd.msg().lParam); - wnd.Destroy(); - EXPECT_TRUE(wnd.handle() == NULL); - EXPECT_TRUE(wnd.destroyed()); -} - -TEST(Win32WindowTest, MultipleWindows) { - TestWindow wnd1, wnd2; - EXPECT_TRUE(wnd1.Create(0, L"Test", 0, 0, 0, 0, 100, 100)); - EXPECT_TRUE(wnd2.Create(0, L"Test", 0, 0, 0, 0, 100, 100)); - EXPECT_TRUE(wnd1.handle() != NULL); - EXPECT_TRUE(wnd2.handle() != NULL); - wnd1.Destroy(); - wnd2.Destroy(); - EXPECT_TRUE(wnd2.handle() == NULL); - EXPECT_TRUE(wnd1.handle() == NULL); -} diff --git a/webrtc/base/win32windowpicker.cc b/webrtc/base/win32windowpicker.cc deleted file mode 100644 index b4550ae4a..000000000 --- a/webrtc/base/win32windowpicker.cc +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "webrtc/base/win32windowpicker.h" - -#include -#include - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -namespace { - -// Window class names that we want to filter out. -const char kProgramManagerClass[] = "Progman"; -const char kButtonClass[] = "Button"; - -} // namespace - -BOOL CALLBACK Win32WindowPicker::EnumProc(HWND hwnd, LPARAM l_param) { - WindowDescriptionList* descriptions = - reinterpret_cast(l_param); - - // Skip windows that are invisible, minimized, have no title, or are owned, - // unless they have the app window style set. Except for minimized windows, - // this is what Alt-Tab does. - // TODO: Figure out how to grab a thumbnail of a minimized window and - // include them in the list. - int len = GetWindowTextLength(hwnd); - HWND owner = GetWindow(hwnd, GW_OWNER); - LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); - if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) || - (owner && !(exstyle & WS_EX_APPWINDOW))) { - // TODO: Investigate if windows without title still could be - // interesting to share. We could use the name of the process as title: - // - // GetWindowThreadProcessId() - // OpenProcess() - // QueryFullProcessImageName() - return TRUE; - } - - // Skip the Program Manager window and the Start button. - TCHAR class_name_w[500]; - ::GetClassName(hwnd, class_name_w, 500); - std::string class_name = ToUtf8(class_name_w); - if (class_name == kProgramManagerClass || class_name == kButtonClass) { - // We don't want the Program Manager window nor the Start button. - return TRUE; - } - - TCHAR window_title[500]; - GetWindowText(hwnd, window_title, ARRAY_SIZE(window_title)); - std::string title = ToUtf8(window_title); - - WindowId id(hwnd); - WindowDescription desc(id, title); - descriptions->push_back(desc); - return TRUE; -} - -BOOL CALLBACK Win32WindowPicker::MonitorEnumProc(HMONITOR h_monitor, - HDC hdc_monitor, - LPRECT lprc_monitor, - LPARAM l_param) { - DesktopDescriptionList* desktop_desc = - reinterpret_cast(l_param); - - DesktopId id(h_monitor, static_cast(desktop_desc->size())); - // TODO: Figure out an appropriate desktop title. - DesktopDescription desc(id, ""); - - // Determine whether it's the primary monitor. - MONITORINFO monitor_info = {0}; - monitor_info.cbSize = sizeof(monitor_info); - bool primary = (GetMonitorInfo(h_monitor, &monitor_info) && - (monitor_info.dwFlags & MONITORINFOF_PRIMARY) != 0); - desc.set_primary(primary); - - desktop_desc->push_back(desc); - return TRUE; -} - -Win32WindowPicker::Win32WindowPicker() { -} - -bool Win32WindowPicker::Init() { - return true; -} -// TODO: Consider changing enumeration to clear() descriptions -// before append(). -bool Win32WindowPicker::GetWindowList(WindowDescriptionList* descriptions) { - LPARAM desc = reinterpret_cast(descriptions); - return EnumWindows(Win32WindowPicker::EnumProc, desc) != FALSE; -} - -bool Win32WindowPicker::GetDesktopList(DesktopDescriptionList* descriptions) { - // Create a fresh WindowDescriptionList so that we can use desktop_desc.size() - // in MonitorEnumProc to compute the desktop index. - DesktopDescriptionList desktop_desc; - HDC hdc = GetDC(NULL); - bool success = false; - if (EnumDisplayMonitors(hdc, NULL, Win32WindowPicker::MonitorEnumProc, - reinterpret_cast(&desktop_desc)) != FALSE) { - // Append the desktop descriptions to the end of the returned descriptions. - descriptions->insert(descriptions->end(), desktop_desc.begin(), - desktop_desc.end()); - success = true; - } - ReleaseDC(NULL, hdc); - return success; -} - -bool Win32WindowPicker::GetDesktopDimensions(const DesktopId& id, - int* width, - int* height) { - MONITORINFOEX monitor_info; - monitor_info.cbSize = sizeof(MONITORINFOEX); - if (!GetMonitorInfo(id.id(), &monitor_info)) { - return false; - } - *width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left; - *height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top; - return true; -} - -bool Win32WindowPicker::IsVisible(const WindowId& id) { - return (::IsWindow(id.id()) != FALSE && ::IsWindowVisible(id.id()) != FALSE); -} - -bool Win32WindowPicker::MoveToFront(const WindowId& id) { - return SetForegroundWindow(id.id()) != FALSE; -} - -} // namespace rtc diff --git a/webrtc/base/win32windowpicker.h b/webrtc/base/win32windowpicker.h deleted file mode 100644 index 9c84bfd98..000000000 --- a/webrtc/base/win32windowpicker.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef WEBRTC_BASE_WIN32WINDOWPICKER_H_ -#define WEBRTC_BASE_WIN32WINDOWPICKER_H_ - -#include "webrtc/base/win32.h" -#include "webrtc/base/windowpicker.h" - -namespace rtc { - -class Win32WindowPicker : public WindowPicker { - public: - Win32WindowPicker(); - virtual bool Init(); - virtual bool IsVisible(const WindowId& id); - virtual bool MoveToFront(const WindowId& id); - virtual bool GetWindowList(WindowDescriptionList* descriptions); - virtual bool GetDesktopList(DesktopDescriptionList* descriptions); - virtual bool GetDesktopDimensions(const DesktopId& id, int* width, - int* height); - - protected: - static BOOL CALLBACK EnumProc(HWND hwnd, LPARAM l_param); - static BOOL CALLBACK MonitorEnumProc(HMONITOR h_monitor, - HDC hdc_monitor, - LPRECT lprc_monitor, - LPARAM l_param); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_WIN32WINDOWPICKER_H_ diff --git a/webrtc/base/win32windowpicker_unittest.cc b/webrtc/base/win32windowpicker_unittest.cc deleted file mode 100644 index 71e8af6bf..000000000 --- a/webrtc/base/win32windowpicker_unittest.cc +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "webrtc/base/gunit.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/win32window.h" -#include "webrtc/base/win32windowpicker.h" -#include "webrtc/base/windowpicker.h" - -#if !defined(WEBRTC_WIN) -#error Only for Windows -#endif - -namespace rtc { - -static const TCHAR* kVisibleWindowTitle = L"Visible Window"; -static const TCHAR* kInvisibleWindowTitle = L"Invisible Window"; - -class Win32WindowPickerForTest : public Win32WindowPicker { - public: - Win32WindowPickerForTest() { - EXPECT_TRUE(visible_window_.Create(NULL, kVisibleWindowTitle, WS_VISIBLE, - 0, 0, 0, 0, 0)); - EXPECT_TRUE(invisible_window_.Create(NULL, kInvisibleWindowTitle, 0, - 0, 0, 0, 0, 0)); - } - - ~Win32WindowPickerForTest() { - visible_window_.Destroy(); - invisible_window_.Destroy(); - } - - virtual bool GetWindowList(WindowDescriptionList* descriptions) { - if (!Win32WindowPicker::EnumProc(visible_window_.handle(), - reinterpret_cast(descriptions))) { - return false; - } - if (!Win32WindowPicker::EnumProc(invisible_window_.handle(), - reinterpret_cast(descriptions))) { - return false; - } - return true; - } - - Win32Window* visible_window() { - return &visible_window_; - } - - Win32Window* invisible_window() { - return &invisible_window_; - } - - private: - Win32Window visible_window_; - Win32Window invisible_window_; -}; - -TEST(Win32WindowPickerTest, TestGetWindowList) { - Win32WindowPickerForTest window_picker; - WindowDescriptionList descriptions; - EXPECT_TRUE(window_picker.GetWindowList(&descriptions)); - EXPECT_EQ(1, descriptions.size()); - WindowDescription desc = descriptions.front(); - EXPECT_EQ(window_picker.visible_window()->handle(), desc.id().id()); - TCHAR window_title[500]; - GetWindowText(window_picker.visible_window()->handle(), window_title, - ARRAY_SIZE(window_title)); - EXPECT_EQ(0, wcscmp(window_title, kVisibleWindowTitle)); -} - -TEST(Win32WindowPickerTest, TestIsVisible) { - Win32WindowPickerForTest window_picker; - HWND visible_id = window_picker.visible_window()->handle(); - HWND invisible_id = window_picker.invisible_window()->handle(); - EXPECT_TRUE(window_picker.IsVisible(WindowId(visible_id))); - EXPECT_FALSE(window_picker.IsVisible(WindowId(invisible_id))); -} - -TEST(Win32WindowPickerTest, TestMoveToFront) { - Win32WindowPickerForTest window_picker; - HWND visible_id = window_picker.visible_window()->handle(); - HWND invisible_id = window_picker.invisible_window()->handle(); - - // There are a number of condition where SetForegroundWindow might - // fail depending on the state of the calling process. To be on the - // safe side we doesn't expect MoveToFront to return true, just test - // that we don't crash. - window_picker.MoveToFront(WindowId(visible_id)); - window_picker.MoveToFront(WindowId(invisible_id)); -} - -} // namespace rtc diff --git a/webrtc/base/window.h b/webrtc/base/window.h deleted file mode 100644 index d96102652..000000000 --- a/webrtc/base/window.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WINDOW_H_ -#define WEBRTC_BASE_WINDOW_H_ - -#include "webrtc/base/stringencode.h" - -// Define platform specific window types. -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) -typedef unsigned long Window; // Avoid include . -#elif defined(WEBRTC_WIN) -// We commonly include win32.h in webrtc/base so just include it here. -#include "webrtc/base/win32.h" // Include HWND, HMONITOR. -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -typedef unsigned int CGWindowID; -typedef unsigned int CGDirectDisplayID; -#endif - -namespace rtc { - -class WindowId { - public: - // Define WindowT for each platform. -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - typedef Window WindowT; -#elif defined(WEBRTC_WIN) - typedef HWND WindowT; -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - typedef CGWindowID WindowT; -#else - typedef unsigned int WindowT; -#endif - - static WindowId Cast(uint64 id) { -#if defined(WEBRTC_WIN) - return WindowId(reinterpret_cast(id)); -#else - return WindowId(static_cast(id)); -#endif - } - - static uint64 Format(const WindowT& id) { -#if defined(WEBRTC_WIN) - return static_cast(reinterpret_cast(id)); -#else - return static_cast(id); -#endif - } - - WindowId() : id_(0) {} - WindowId(const WindowT& id) : id_(id) {} // NOLINT - const WindowT& id() const { return id_; } - bool IsValid() const { return id_ != 0; } - bool Equals(const WindowId& other) const { - return id_ == other.id(); - } - - private: - WindowT id_; -}; - -class DesktopId { - public: - // Define DesktopT for each platform. -#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) - typedef Window DesktopT; -#elif defined(WEBRTC_WIN) - typedef HMONITOR DesktopT; -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - typedef CGDirectDisplayID DesktopT; -#else - typedef unsigned int DesktopT; -#endif - - static DesktopId Cast(int id, int index) { -#if defined(WEBRTC_WIN) - return DesktopId(reinterpret_cast(id), index); -#else - return DesktopId(static_cast(id), index); -#endif - } - - DesktopId() : id_(0), index_(-1) {} - DesktopId(const DesktopT& id, int index) // NOLINT - : id_(id), index_(index) { - } - const DesktopT& id() const { return id_; } - int index() const { return index_; } - bool IsValid() const { return index_ != -1; } - bool Equals(const DesktopId& other) const { - return id_ == other.id() && index_ == other.index(); - } - - private: - // Id is the platform specific desktop identifier. - DesktopT id_; - // Index is the desktop index as enumerated by each platform. - // Desktop capturer typically takes the index instead of id. - int index_; -}; - -// Window event types. -enum WindowEvent { - WE_RESIZE = 0, - WE_CLOSE = 1, - WE_MINIMIZE = 2, - WE_RESTORE = 3, -}; - -inline std::string ToString(const WindowId& window) { - return ToString(window.id()); -} - -} // namespace rtc - -#endif // WEBRTC_BASE_WINDOW_H_ diff --git a/webrtc/base/windowpicker.h b/webrtc/base/windowpicker.h deleted file mode 100644 index 3ae7b0e49..000000000 --- a/webrtc/base/windowpicker.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WINDOWPICKER_H_ -#define WEBRTC_BASE_WINDOWPICKER_H_ - -#include -#include - -#include "webrtc/base/window.h" - -namespace rtc { - -class WindowDescription { - public: - WindowDescription() : id_() {} - WindowDescription(const WindowId& id, const std::string& title) - : id_(id), title_(title) { - } - const WindowId& id() const { return id_; } - void set_id(const WindowId& id) { id_ = id; } - const std::string& title() const { return title_; } - void set_title(const std::string& title) { title_ = title; } - - private: - WindowId id_; - std::string title_; -}; - -class DesktopDescription { - public: - DesktopDescription() : id_() {} - DesktopDescription(const DesktopId& id, const std::string& title) - : id_(id), title_(title), primary_(false) { - } - const DesktopId& id() const { return id_; } - void set_id(const DesktopId& id) { id_ = id; } - const std::string& title() const { return title_; } - void set_title(const std::string& title) { title_ = title; } - // Indicates whether it is the primary desktop in the system. - bool primary() const { return primary_; } - void set_primary(bool primary) { primary_ = primary; } - - private: - DesktopId id_; - std::string title_; - bool primary_; -}; - -typedef std::vector WindowDescriptionList; -typedef std::vector DesktopDescriptionList; - -class WindowPicker { - public: - virtual ~WindowPicker() {} - virtual bool Init() = 0; - - // TODO: Move this two methods to window.h when we no longer need to load - // CoreGraphics dynamically. - virtual bool IsVisible(const WindowId& id) = 0; - virtual bool MoveToFront(const WindowId& id) = 0; - - // Gets a list of window description and appends to descriptions. - // Returns true if successful. - virtual bool GetWindowList(WindowDescriptionList* descriptions) = 0; - // Gets a list of desktop descriptions and appends to descriptions. - // Returns true if successful. - virtual bool GetDesktopList(DesktopDescriptionList* descriptions) = 0; - // Gets the width and height of a desktop. - // Returns true if successful. - virtual bool GetDesktopDimensions(const DesktopId& id, int* width, - int* height) = 0; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_WINDOWPICKER_H_ diff --git a/webrtc/base/windowpicker_unittest.cc b/webrtc/base/windowpicker_unittest.cc deleted file mode 100644 index edd01bc0b..000000000 --- a/webrtc/base/windowpicker_unittest.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "webrtc/base/gunit.h" -#include "webrtc/base/testutils.h" -#include "webrtc/base/window.h" -#include "webrtc/base/windowpicker.h" -#include "webrtc/base/windowpickerfactory.h" - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -# define DISABLE_ON_MAC(name) DISABLED_ ## name -#else -# define DISABLE_ON_MAC(name) name -#endif - -TEST(WindowPickerTest, GetWindowList) { - MAYBE_SKIP_SCREENCAST_TEST(); - if (!rtc::WindowPickerFactory::IsSupported()) { - LOG(LS_INFO) << "skipping test: window capturing is not supported with " - << "current configuration."; - } - rtc::scoped_ptr picker( - rtc::WindowPickerFactory::CreateWindowPicker()); - EXPECT_TRUE(picker->Init()); - rtc::WindowDescriptionList descriptions; - EXPECT_TRUE(picker->GetWindowList(&descriptions)); -} - -// TODO(hughv) Investigate why this fails on pulse but not locally after -// upgrading to XCode 4.5. The failure is GetDesktopList returning FALSE. -TEST(WindowPickerTest, DISABLE_ON_MAC(GetDesktopList)) { - MAYBE_SKIP_SCREENCAST_TEST(); - if (!rtc::WindowPickerFactory::IsSupported()) { - LOG(LS_INFO) << "skipping test: window capturing is not supported with " - << "current configuration."; - } - rtc::scoped_ptr picker( - rtc::WindowPickerFactory::CreateWindowPicker()); - EXPECT_TRUE(picker->Init()); - rtc::DesktopDescriptionList descriptions; - EXPECT_TRUE(picker->GetDesktopList(&descriptions)); - if (descriptions.size() > 0) { - int width = 0; - int height = 0; - EXPECT_TRUE(picker->GetDesktopDimensions(descriptions[0].id(), &width, - &height)); - EXPECT_GT(width, 0); - EXPECT_GT(height, 0); - - // Test |IsPrimaryDesktop|. Only one desktop should be a primary. - bool found_primary = false; - for (rtc::DesktopDescriptionList::iterator it = descriptions.begin(); - it != descriptions.end(); ++it) { - if (it->primary()) { - EXPECT_FALSE(found_primary); - found_primary = true; - } - } - EXPECT_TRUE(found_primary); - } -} diff --git a/webrtc/base/windowpickerfactory.h b/webrtc/base/windowpickerfactory.h deleted file mode 100644 index 00a4cc469..000000000 --- a/webrtc/base/windowpickerfactory.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WINDOWPICKERFACTORY_H_ -#define WEBRTC_BASE_WINDOWPICKERFACTORY_H_ - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32windowpicker.h" -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include "webrtc/base/macutils.h" -#include "webrtc/base/macwindowpicker.h" -#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) -#include "webrtc/base/linuxwindowpicker.h" -#endif - -#include "webrtc/base/windowpicker.h" - -namespace rtc { - -class WindowPickerFactory { - public: - virtual ~WindowPickerFactory() {} - - // Instance method for dependency injection. - virtual WindowPicker* Create() { - return CreateWindowPicker(); - } - - static WindowPicker* CreateWindowPicker() { -#if defined(WEBRTC_WIN) - return new Win32WindowPicker(); -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - return new MacWindowPicker(); -#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) && defined(HAVE_X11) - return new LinuxWindowPicker(); -#else - return NULL; -#endif - } - - static bool IsSupported() { -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - return GetOSVersionName() >= kMacOSLeopard; -#else - return true; -#endif - } -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_WINDOWPICKERFACTORY_H_ diff --git a/webrtc/base/winfirewall.cc b/webrtc/base/winfirewall.cc deleted file mode 100644 index 97e6d1518..000000000 --- a/webrtc/base/winfirewall.cc +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/winfirewall.h" - -#include "webrtc/base/win32.h" - -#include -#include - -#define RELEASE(lpUnk) do { \ - if ((lpUnk) != NULL) { \ - (lpUnk)->Release(); \ - (lpUnk) = NULL; \ - } \ -} while (0) - -namespace rtc { - -////////////////////////////////////////////////////////////////////// -// WinFirewall -////////////////////////////////////////////////////////////////////// - -WinFirewall::WinFirewall() : mgr_(NULL), policy_(NULL), profile_(NULL) { -} - -WinFirewall::~WinFirewall() { - Shutdown(); -} - -bool WinFirewall::Initialize(HRESULT* result) { - if (mgr_) { - if (result) { - *result = S_OK; - } - return true; - } - - HRESULT hr = CoCreateInstance(__uuidof(NetFwMgr), - 0, CLSCTX_INPROC_SERVER, - __uuidof(INetFwMgr), - reinterpret_cast(&mgr_)); - if (SUCCEEDED(hr) && (mgr_ != NULL)) - hr = mgr_->get_LocalPolicy(&policy_); - if (SUCCEEDED(hr) && (policy_ != NULL)) - hr = policy_->get_CurrentProfile(&profile_); - - if (result) - *result = hr; - return SUCCEEDED(hr) && (profile_ != NULL); -} - -void WinFirewall::Shutdown() { - RELEASE(profile_); - RELEASE(policy_); - RELEASE(mgr_); -} - -bool WinFirewall::Enabled() const { - if (!profile_) - return false; - - VARIANT_BOOL fwEnabled = VARIANT_FALSE; - profile_->get_FirewallEnabled(&fwEnabled); - return (fwEnabled != VARIANT_FALSE); -} - -bool WinFirewall::QueryAuthorized(const char* filename, bool* authorized) - const { - return QueryAuthorizedW(ToUtf16(filename).c_str(), authorized); -} - -bool WinFirewall::QueryAuthorizedW(const wchar_t* filename, bool* authorized) - const { - *authorized = false; - bool success = false; - - if (!profile_) - return false; - - _bstr_t bfilename = filename; - - INetFwAuthorizedApplications* apps = NULL; - HRESULT hr = profile_->get_AuthorizedApplications(&apps); - if (SUCCEEDED(hr) && (apps != NULL)) { - INetFwAuthorizedApplication* app = NULL; - hr = apps->Item(bfilename, &app); - if (SUCCEEDED(hr) && (app != NULL)) { - VARIANT_BOOL fwEnabled = VARIANT_FALSE; - hr = app->get_Enabled(&fwEnabled); - app->Release(); - - if (SUCCEEDED(hr)) { - success = true; - *authorized = (fwEnabled != VARIANT_FALSE); - } - } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { - // No entry in list of authorized apps - success = true; - } else { - // Unexpected error - } - apps->Release(); - } - - return success; -} - -bool WinFirewall::AddApplication(const char* filename, - const char* friendly_name, - bool authorized, - HRESULT* result) { - return AddApplicationW(ToUtf16(filename).c_str(), - ToUtf16(friendly_name).c_str(), authorized, result); -} - -bool WinFirewall::AddApplicationW(const wchar_t* filename, - const wchar_t* friendly_name, - bool authorized, - HRESULT* result) { - INetFwAuthorizedApplications* apps = NULL; - HRESULT hr = profile_->get_AuthorizedApplications(&apps); - if (SUCCEEDED(hr) && (apps != NULL)) { - INetFwAuthorizedApplication* app = NULL; - hr = CoCreateInstance(__uuidof(NetFwAuthorizedApplication), - 0, CLSCTX_INPROC_SERVER, - __uuidof(INetFwAuthorizedApplication), - reinterpret_cast(&app)); - if (SUCCEEDED(hr) && (app != NULL)) { - _bstr_t bstr = filename; - hr = app->put_ProcessImageFileName(bstr); - bstr = friendly_name; - if (SUCCEEDED(hr)) - hr = app->put_Name(bstr); - if (SUCCEEDED(hr)) - hr = app->put_Enabled(authorized ? VARIANT_TRUE : VARIANT_FALSE); - if (SUCCEEDED(hr)) - hr = apps->Add(app); - app->Release(); - } - apps->Release(); - } - if (result) - *result = hr; - return SUCCEEDED(hr); -} - -} // namespace rtc diff --git a/webrtc/base/winfirewall.h b/webrtc/base/winfirewall.h deleted file mode 100644 index a74631baf..000000000 --- a/webrtc/base/winfirewall.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WINFIREWALL_H_ -#define WEBRTC_BASE_WINFIREWALL_H_ - -#ifndef _HRESULT_DEFINED -#define _HRESULT_DEFINED -typedef long HRESULT; // Can't forward declare typedef, but don't need all win -#endif // !_HRESULT_DEFINED - -struct INetFwMgr; -struct INetFwPolicy; -struct INetFwProfile; - -namespace rtc { - -////////////////////////////////////////////////////////////////////// -// WinFirewall -////////////////////////////////////////////////////////////////////// - -class WinFirewall { - public: - WinFirewall(); - ~WinFirewall(); - - bool Initialize(HRESULT* result); - void Shutdown(); - - bool Enabled() const; - bool QueryAuthorized(const char* filename, bool* authorized) const; - bool QueryAuthorizedW(const wchar_t* filename, bool* authorized) const; - - bool AddApplication(const char* filename, const char* friendly_name, - bool authorized, HRESULT* result); - bool AddApplicationW(const wchar_t* filename, const wchar_t* friendly_name, - bool authorized, HRESULT* result); - - private: - INetFwMgr* mgr_; - INetFwPolicy* policy_; - INetFwProfile* profile_; -}; - -////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_WINFIREWALL_H_ diff --git a/webrtc/base/winfirewall_unittest.cc b/webrtc/base/winfirewall_unittest.cc deleted file mode 100644 index e5c3d6ac1..000000000 --- a/webrtc/base/winfirewall_unittest.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2010 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/gunit.h" -#include "webrtc/base/winfirewall.h" - -#include - -namespace rtc { - -TEST(WinFirewallTest, ReadStatus) { - ::CoInitialize(NULL); - WinFirewall fw; - HRESULT hr; - bool authorized; - - EXPECT_FALSE(fw.QueryAuthorized("bogus.exe", &authorized)); - EXPECT_TRUE(fw.Initialize(&hr)); - EXPECT_EQ(S_OK, hr); - - EXPECT_TRUE(fw.QueryAuthorized("bogus.exe", &authorized)); - - // Unless we mock out INetFwMgr we can't really have an expectation either way - // about whether we're authorized. It will depend on the settings of the - // machine running the test. Same goes for AddApplication. - - fw.Shutdown(); - EXPECT_FALSE(fw.QueryAuthorized("bogus.exe", &authorized)); - - ::CoUninitialize(); -} - -} // namespace rtc diff --git a/webrtc/base/winping.cc b/webrtc/base/winping.cc deleted file mode 100644 index cbb0847bb..000000000 --- a/webrtc/base/winping.cc +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/winping.h" - -#include -#include - -#include "webrtc/base/byteorder.h" -#include "webrtc/base/common.h" -#include "webrtc/base/ipaddress.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/nethelpers.h" -#include "webrtc/base/socketaddress.h" - -namespace rtc { - -////////////////////////////////////////////////////////////////////// -// Found in IPExport.h -////////////////////////////////////////////////////////////////////// - -typedef struct icmp_echo_reply { - ULONG Address; // Replying address - ULONG Status; // Reply IP_STATUS - ULONG RoundTripTime; // RTT in milliseconds - USHORT DataSize; // Reply data size in bytes - USHORT Reserved; // Reserved for system use - PVOID Data; // Pointer to the reply data - struct ip_option_information Options; // Reply options -} ICMP_ECHO_REPLY, * PICMP_ECHO_REPLY; - -typedef struct icmpv6_echo_reply_lh { - sockaddr_in6 Address; - ULONG Status; - unsigned int RoundTripTime; -} ICMPV6_ECHO_REPLY, *PICMPV6_ECHO_REPLY; - -// -// IP_STATUS codes returned from IP APIs -// - -#define IP_STATUS_BASE 11000 - -#define IP_SUCCESS 0 -#define IP_BUF_TOO_SMALL (IP_STATUS_BASE + 1) -#define IP_DEST_NET_UNREACHABLE (IP_STATUS_BASE + 2) -#define IP_DEST_HOST_UNREACHABLE (IP_STATUS_BASE + 3) -#define IP_DEST_PROT_UNREACHABLE (IP_STATUS_BASE + 4) -#define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5) -#define IP_NO_RESOURCES (IP_STATUS_BASE + 6) -#define IP_BAD_OPTION (IP_STATUS_BASE + 7) -#define IP_HW_ERROR (IP_STATUS_BASE + 8) -#define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9) -#define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10) -#define IP_BAD_REQ (IP_STATUS_BASE + 11) -#define IP_BAD_ROUTE (IP_STATUS_BASE + 12) -#define IP_TTL_EXPIRED_TRANSIT (IP_STATUS_BASE + 13) -#define IP_TTL_EXPIRED_REASSEM (IP_STATUS_BASE + 14) -#define IP_PARAM_PROBLEM (IP_STATUS_BASE + 15) -#define IP_SOURCE_QUENCH (IP_STATUS_BASE + 16) -#define IP_OPTION_TOO_BIG (IP_STATUS_BASE + 17) -#define IP_BAD_DESTINATION (IP_STATUS_BASE + 18) - -#define IP_ADDR_DELETED (IP_STATUS_BASE + 19) -#define IP_SPEC_MTU_CHANGE (IP_STATUS_BASE + 20) -#define IP_MTU_CHANGE (IP_STATUS_BASE + 21) -#define IP_UNLOAD (IP_STATUS_BASE + 22) -#define IP_ADDR_ADDED (IP_STATUS_BASE + 23) -#define IP_MEDIA_CONNECT (IP_STATUS_BASE + 24) -#define IP_MEDIA_DISCONNECT (IP_STATUS_BASE + 25) -#define IP_BIND_ADAPTER (IP_STATUS_BASE + 26) -#define IP_UNBIND_ADAPTER (IP_STATUS_BASE + 27) -#define IP_DEVICE_DOES_NOT_EXIST (IP_STATUS_BASE + 28) -#define IP_DUPLICATE_ADDRESS (IP_STATUS_BASE + 29) -#define IP_INTERFACE_METRIC_CHANGE (IP_STATUS_BASE + 30) -#define IP_RECONFIG_SECFLTR (IP_STATUS_BASE + 31) -#define IP_NEGOTIATING_IPSEC (IP_STATUS_BASE + 32) -#define IP_INTERFACE_WOL_CAPABILITY_CHANGE (IP_STATUS_BASE + 33) -#define IP_DUPLICATE_IPADD (IP_STATUS_BASE + 34) - -#define IP_GENERAL_FAILURE (IP_STATUS_BASE + 50) -#define MAX_IP_STATUS IP_GENERAL_FAILURE -#define IP_PENDING (IP_STATUS_BASE + 255) - -// -// Values used in the IP header Flags field. -// -#define IP_FLAG_DF 0x2 // Don't fragment this packet. - -// -// Supported IP Option Types. -// -// These types define the options which may be used in the OptionsData field -// of the ip_option_information structure. See RFC 791 for a complete -// description of each. -// -#define IP_OPT_EOL 0 // End of list option -#define IP_OPT_NOP 1 // No operation -#define IP_OPT_SECURITY 0x82 // Security option -#define IP_OPT_LSRR 0x83 // Loose source route -#define IP_OPT_SSRR 0x89 // Strict source route -#define IP_OPT_RR 0x7 // Record route -#define IP_OPT_TS 0x44 // Timestamp -#define IP_OPT_SID 0x88 // Stream ID (obsolete) -#define IP_OPT_ROUTER_ALERT 0x94 // Router Alert Option - -#define MAX_OPT_SIZE 40 // Maximum length of IP options in bytes - -////////////////////////////////////////////////////////////////////// -// Global Constants and Types -////////////////////////////////////////////////////////////////////// - -const char * const ICMP_DLL_NAME = "Iphlpapi.dll"; -const char * const ICMP_CREATE_FUNC = "IcmpCreateFile"; -const char * const ICMP_CLOSE_FUNC = "IcmpCloseHandle"; -const char * const ICMP_SEND_FUNC = "IcmpSendEcho"; -const char * const ICMP6_CREATE_FUNC = "Icmp6CreateFile"; -const char * const ICMP6_CLOSE_FUNC = "Icmp6CloseHandle"; -const char * const ICMP6_SEND_FUNC = "Icmp6SendEcho2"; - -inline uint32 ReplySize(uint32 data_size, int family) { - if (family == AF_INET) { - // A ping error message is 8 bytes long, so make sure we allow for at least - // 8 bytes of reply data. - return sizeof(ICMP_ECHO_REPLY) + rtc::_max(8, data_size); - } else if (family == AF_INET6) { - // Per MSDN, Send6IcmpEcho2 needs at least one ICMPV6_ECHO_REPLY, - // 8 bytes for ICMP header, _and_ an IO_BLOCK_STATUS (2 pointers), - // in addition to the data size. - return sizeof(ICMPV6_ECHO_REPLY) + data_size + 8 + (2 * sizeof(DWORD*)); - } else { - return 0; - } -} - -////////////////////////////////////////////////////////////////////// -// WinPing -////////////////////////////////////////////////////////////////////// - -WinPing::WinPing() - : dll_(0), hping_(INVALID_HANDLE_VALUE), create_(0), close_(0), send_(0), - create6_(0), send6_(0), data_(0), dlen_(0), reply_(0), - rlen_(0), valid_(false) { - - dll_ = LoadLibraryA(ICMP_DLL_NAME); - if (!dll_) { - LOG(LERROR) << "LoadLibrary: " << GetLastError(); - return; - } - - create_ = (PIcmpCreateFile) GetProcAddress(dll_, ICMP_CREATE_FUNC); - close_ = (PIcmpCloseHandle) GetProcAddress(dll_, ICMP_CLOSE_FUNC); - send_ = (PIcmpSendEcho) GetProcAddress(dll_, ICMP_SEND_FUNC); - if (!create_ || !close_ || !send_) { - LOG(LERROR) << "GetProcAddress(ICMP_*): " << GetLastError(); - return; - } - hping_ = create_(); - if (hping_ == INVALID_HANDLE_VALUE) { - LOG(LERROR) << "IcmpCreateFile: " << GetLastError(); - return; - } - - if (HasIPv6Enabled()) { - create6_ = (PIcmp6CreateFile) GetProcAddress(dll_, ICMP6_CREATE_FUNC); - send6_ = (PIcmp6SendEcho2) GetProcAddress(dll_, ICMP6_SEND_FUNC); - if (!create6_ || !send6_) { - LOG(LERROR) << "GetProcAddress(ICMP6_*): " << GetLastError(); - return; - } - hping6_ = create6_(); - if (hping6_ == INVALID_HANDLE_VALUE) { - LOG(LERROR) << "Icmp6CreateFile: " << GetLastError(); - } - } - - dlen_ = 0; - rlen_ = ReplySize(dlen_, AF_INET); - data_ = new char[dlen_]; - reply_ = new char[rlen_]; - - valid_ = true; -} - -WinPing::~WinPing() { - if ((hping_ != INVALID_HANDLE_VALUE) && close_) { - if (!close_(hping_)) - LOG(WARNING) << "IcmpCloseHandle: " << GetLastError(); - } - if ((hping6_ != INVALID_HANDLE_VALUE) && close_) { - if (!close_(hping6_)) { - LOG(WARNING) << "Icmp6CloseHandle: " << GetLastError(); - } - } - - if (dll_) - FreeLibrary(dll_); - - delete[] data_; - delete[] reply_; -} - -WinPing::PingResult WinPing::Ping( - IPAddress ip, uint32 data_size, uint32 timeout, uint8 ttl, - bool allow_fragments) { - - if (data_size == 0 || timeout == 0 || ttl == 0) { - LOG(LERROR) << "IcmpSendEcho: data_size/timeout/ttl is 0."; - return PING_INVALID_PARAMS; - } - - assert(IsValid()); - - IP_OPTION_INFORMATION ipopt; - memset(&ipopt, 0, sizeof(ipopt)); - if (!allow_fragments) - ipopt.Flags |= IP_FLAG_DF; - ipopt.Ttl = ttl; - - uint32 reply_size = ReplySize(data_size, ip.family()); - - if (data_size > dlen_) { - delete [] data_; - dlen_ = data_size; - data_ = new char[dlen_]; - memset(data_, 'z', dlen_); - } - - if (reply_size > rlen_) { - delete [] reply_; - rlen_ = reply_size; - reply_ = new char[rlen_]; - } - DWORD result = 0; - if (ip.family() == AF_INET) { - result = send_(hping_, ip.ipv4_address().S_un.S_addr, - data_, uint16(data_size), &ipopt, - reply_, reply_size, timeout); - } else if (ip.family() == AF_INET6) { - sockaddr_in6 src = {0}; - sockaddr_in6 dst = {0}; - src.sin6_family = AF_INET6; - dst.sin6_family = AF_INET6; - dst.sin6_addr = ip.ipv6_address(); - result = send6_(hping6_, NULL, NULL, NULL, - &src, &dst, - data_, int16(data_size), &ipopt, - reply_, reply_size, timeout); - } - if (result == 0) { - DWORD error = GetLastError(); - if (error == IP_PACKET_TOO_BIG) - return PING_TOO_LARGE; - if (error == IP_REQ_TIMED_OUT) - return PING_TIMEOUT; - LOG(LERROR) << "IcmpSendEcho(" << ip.ToSensitiveString() - << ", " << data_size << "): " << error; - return PING_FAIL; - } - - return PING_SUCCESS; -} - -////////////////////////////////////////////////////////////////////// -// Microsoft Documenation -////////////////////////////////////////////////////////////////////// -// -// Routine Name: -// -// IcmpCreateFile -// -// Routine Description: -// -// Opens a handle on which ICMP Echo Requests can be issued. -// -// Arguments: -// -// None. -// -// Return Value: -// -// An open file handle or INVALID_HANDLE_VALUE. Extended error information -// is available by calling GetLastError(). -// -////////////////////////////////////////////////////////////////////// -// -// Routine Name: -// -// IcmpCloseHandle -// -// Routine Description: -// -// Closes a handle opened by ICMPOpenFile. -// -// Arguments: -// -// IcmpHandle - The handle to close. -// -// Return Value: -// -// TRUE if the handle was closed successfully, otherwise FALSE. Extended -// error information is available by calling GetLastError(). -// -////////////////////////////////////////////////////////////////////// -// -// Routine Name: -// -// IcmpSendEcho -// -// Routine Description: -// -// Sends an ICMP Echo request and returns any replies. The -// call returns when the timeout has expired or the reply buffer -// is filled. -// -// Arguments: -// -// IcmpHandle - An open handle returned by ICMPCreateFile. -// -// DestinationAddress - The destination of the echo request. -// -// RequestData - A buffer containing the data to send in the -// request. -// -// RequestSize - The number of bytes in the request data buffer. -// -// RequestOptions - Pointer to the IP header options for the request. -// May be NULL. -// -// ReplyBuffer - A buffer to hold any replies to the request. -// On return, the buffer will contain an array of -// ICMP_ECHO_REPLY structures followed by the -// options and data for the replies. The buffer -// should be large enough to hold at least one -// ICMP_ECHO_REPLY structure plus -// MAX(RequestSize, 8) bytes of data since an ICMP -// error message contains 8 bytes of data. -// -// ReplySize - The size in bytes of the reply buffer. -// -// Timeout - The time in milliseconds to wait for replies. -// -// Return Value: -// -// Returns the number of ICMP_ECHO_REPLY structures stored in ReplyBuffer. -// The status of each reply is contained in the structure. If the return -// value is zero, extended error information is available via -// GetLastError(). -// -////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/winping.h b/webrtc/base/winping.h deleted file mode 100644 index 75f82b7b4..000000000 --- a/webrtc/base/winping.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WINPING_H__ -#define WEBRTC_BASE_WINPING_H__ - -#if defined(WEBRTC_WIN) - -#include "webrtc/base/win32.h" -#include "webrtc/base/basictypes.h" -#include "webrtc/base/IPAddress.h" - -namespace rtc { - -// This class wraps a Win32 API for doing ICMP pinging. This API, unlike the -// the normal socket APIs (as implemented on Win9x), will return an error if -// an ICMP packet with the dont-fragment bit set is too large. This means this -// class can be used to detect the MTU to a given address. - -typedef struct ip_option_information { - UCHAR Ttl; // Time To Live - UCHAR Tos; // Type Of Service - UCHAR Flags; // IP header flags - UCHAR OptionsSize; // Size in bytes of options data - PUCHAR OptionsData; // Pointer to options data -} IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION; - -typedef HANDLE (WINAPI *PIcmpCreateFile)(); - -typedef BOOL (WINAPI *PIcmpCloseHandle)(HANDLE icmp_handle); - -typedef HANDLE (WINAPI *PIcmp6CreateFile)(); - -typedef BOOL (WINAPI *PIcmp6CloseHandle)(HANDLE icmp_handle); - -typedef DWORD (WINAPI *PIcmpSendEcho)( - HANDLE IcmpHandle, - ULONG DestinationAddress, - LPVOID RequestData, - WORD RequestSize, - PIP_OPTION_INFORMATION RequestOptions, - LPVOID ReplyBuffer, - DWORD ReplySize, - DWORD Timeout); - -typedef DWORD (WINAPI *PIcmp6SendEcho2)( - HANDLE IcmpHandle, - HANDLE Event, - FARPROC ApcRoutine, - PVOID ApcContext, - struct sockaddr_in6 *SourceAddress, - struct sockaddr_in6 *DestinationAddress, - LPVOID RequestData, - WORD RequestSize, - PIP_OPTION_INFORMATION RequestOptions, - LPVOID ReplyBuffer, - DWORD ReplySize, - DWORD Timeout -); - -class WinPing { -public: - WinPing(); - ~WinPing(); - - // Determines whether the class was initialized correctly. - bool IsValid() { return valid_; } - - // Attempts to send a ping with the given parameters. - enum PingResult { PING_FAIL, PING_INVALID_PARAMS, - PING_TOO_LARGE, PING_TIMEOUT, PING_SUCCESS }; - PingResult Ping( - IPAddress ip, uint32 data_size, uint32 timeout_millis, uint8 ttl, - bool allow_fragments); - -private: - HMODULE dll_; - HANDLE hping_; - HANDLE hping6_; - PIcmpCreateFile create_; - PIcmpCloseHandle close_; - PIcmpSendEcho send_; - PIcmp6CreateFile create6_; - PIcmp6SendEcho2 send6_; - char* data_; - uint32 dlen_; - char* reply_; - uint32 rlen_; - bool valid_; -}; - -} // namespace rtc - -#endif // WEBRTC_WIN - -#endif // WEBRTC_BASE_WINPING_H__ diff --git a/webrtc/base/worker.cc b/webrtc/base/worker.cc deleted file mode 100644 index 1b48b9b1d..000000000 --- a/webrtc/base/worker.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/worker.h" - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -enum { - MSG_HAVEWORK = 0, -}; - -Worker::Worker() : worker_thread_(NULL) {} - -Worker::~Worker() { - // We need to already be stopped before being destroyed. We cannot call - // StopWork() from here because the subclass's data has already been - // destructed, so OnStop() cannot be called. - ASSERT(!worker_thread_); -} - -bool Worker::StartWork() { - rtc::Thread *me = rtc::Thread::Current(); - if (worker_thread_) { - if (worker_thread_ == me) { - // Already working on this thread, so nothing to do. - return true; - } else { - LOG(LS_ERROR) << "Automatically switching threads is not supported"; - ASSERT(false); - return false; - } - } - worker_thread_ = me; - OnStart(); - return true; -} - -bool Worker::StopWork() { - if (!worker_thread_) { - // Already not working, so nothing to do. - return true; - } else if (worker_thread_ != rtc::Thread::Current()) { - LOG(LS_ERROR) << "Stopping from a different thread is not supported"; - ASSERT(false); - return false; - } - OnStop(); - worker_thread_->Clear(this, MSG_HAVEWORK); - worker_thread_ = NULL; - return true; -} - -void Worker::HaveWork() { - ASSERT(worker_thread_ != NULL); - worker_thread_->Post(this, MSG_HAVEWORK); -} - -void Worker::OnMessage(rtc::Message *msg) { - ASSERT(msg->message_id == MSG_HAVEWORK); - ASSERT(worker_thread_ == rtc::Thread::Current()); - OnHaveWork(); -} - -} // namespace rtc diff --git a/webrtc/base/worker.h b/webrtc/base/worker.h deleted file mode 100644 index 694a78057..000000000 --- a/webrtc/base/worker.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_WORKER_H_ -#define WEBRTC_BASE_WORKER_H_ - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/messagehandler.h" - -namespace rtc { - -class Thread; - -// A worker is an object that performs some specific long-lived task in an -// event-driven manner. -// The only method that should be considered thread-safe is HaveWork(), which -// allows you to signal the availability of work from any thread. All other -// methods are thread-hostile. Specifically: -// StartWork()/StopWork() should not be called concurrently with themselves or -// each other, and it is an error to call them while the worker is running on -// a different thread. -// The destructor may not be called if the worker is currently running -// (regardless of the thread), but you can call StopWork() in a subclass's -// destructor. -class Worker : private MessageHandler { - public: - Worker(); - - // Destroys this Worker, but it must have already been stopped via StopWork(). - virtual ~Worker(); - - // Attaches the worker to the current thread and begins processing work if not - // already doing so. - bool StartWork(); - // Stops processing work if currently doing so and detaches from the current - // thread. - bool StopWork(); - - protected: - // Signal that work is available to be done. May only be called within the - // lifetime of a OnStart()/OnStop() pair. - void HaveWork(); - - // These must be implemented by a subclass. - // Called on the worker thread to start working. - virtual void OnStart() = 0; - // Called on the worker thread when work has been signalled via HaveWork(). - virtual void OnHaveWork() = 0; - // Called on the worker thread to stop working. Upon return, any pending - // OnHaveWork() calls are cancelled. - virtual void OnStop() = 0; - - private: - // Inherited from MessageHandler. - virtual void OnMessage(Message *msg); - - // The thread that is currently doing the work. - Thread *worker_thread_; - - DISALLOW_COPY_AND_ASSIGN(Worker); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_WORKER_H_ diff --git a/webrtc/build/common.gypi b/webrtc/build/common.gypi index 233b1b8c0..a07711401 100644 --- a/webrtc/build/common.gypi +++ b/webrtc/build/common.gypi @@ -89,9 +89,6 @@ 'build_libyuv%': 1, 'build_libvpx%': 1, - # Disable by default - 'have_dbus_glib%': 0, - # Enable to use the Mozilla internal settings. 'build_with_mozilla%': 0, @@ -147,6 +144,9 @@ }, 'target_defaults': { 'include_dirs': [ + # Allow includes to be prefixed with webrtc/ in case it is not an + # immediate subdirectory of <(DEPTH). + '../..', # To include the top-level directory when building in Chrome, so we can # use full paths (e.g. headers inside testing/ or third_party/). '<(DEPTH)', @@ -161,14 +161,6 @@ 'WEBRTC_MOZILLA_BUILD', ], }], - ['have_dbus_glib==1', { - 'defines': [ - 'HAVE_DBUS_GLIB', - ], - 'cflags': [ - '= 1600 -#include -#else -typedef unsigned __int64 uint64; -typedef __int64 int64; -#endif -#ifndef INT64_C -#define INT64_C(x) x ## I64 -#endif -#ifndef UINT64_C -#define UINT64_C(x) x ## UI64 -#endif -#define INT64_F "I64" -#else // COMPILER_MSVC -#ifndef INT64_C -#define INT64_C(x) x ## LL -#endif -#ifndef UINT64_C -#define UINT64_C(x) x ## ULL -#endif -#ifndef INT64_F -#define INT64_F "ll" -#endif -#endif // COMPILER_MSVC -#endif // INT_TYPES_DEFINED - -// Detect compiler is for x86 or x64. -#if defined(__x86_64__) || defined(_M_X64) || \ - defined(__i386__) || defined(_M_IX86) -#define CPU_X86 1 -#endif -// Detect compiler is for arm. -#if defined(__arm__) || defined(_M_ARM) -#define CPU_ARM 1 -#endif -#if defined(CPU_X86) && defined(CPU_ARM) -#error CPU_X86 and CPU_ARM both defined. -#endif -#if !defined(ARCH_CPU_BIG_ENDIAN) && !defined(ARCH_CPU_LITTLE_ENDIAN) -// x86, arm or GCC provided __BYTE_ORDER__ macros -#if CPU_X86 || CPU_ARM || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define ARCH_CPU_LITTLE_ENDIAN -#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define ARCH_CPU_BIG_ENDIAN -#else -#error ARCH_CPU_BIG_ENDIAN or ARCH_CPU_LITTLE_ENDIAN should be defined. -#endif -#endif -#if defined(ARCH_CPU_BIG_ENDIAN) && defined(ARCH_CPU_LITTLE_ENDIAN) -#error ARCH_CPU_BIG_ENDIAN and ARCH_CPU_LITTLE_ENDIAN both defined. -#endif - -#if defined(WEBRTC_WIN) -typedef int socklen_t; -#endif - -namespace rtc { -template inline T _min(T a, T b) { return (a > b) ? b : a; } -template inline T _max(T a, T b) { return (a < b) ? b : a; } - -// For wait functions that take a number of milliseconds, kForever indicates -// unlimited time. -const int kForever = -1; -} - -#if defined(WEBRTC_WIN) -#if _MSC_VER < 1700 - #define alignof(t) __alignof(t) -#endif -#else // !WEBRTC_WIN -#define alignof(t) __alignof__(t) -#endif // !WEBRTC_WIN -#define IS_ALIGNED(p, a) (0==(reinterpret_cast(p) & ((a)-1))) -#define ALIGNP(p, t) \ - (reinterpret_cast(((reinterpret_cast(p) + \ - ((t)-1)) & ~((t)-1)))) - -// LIBJINGLE_DEFINE_STATIC_LOCAL() is a libjingle's copy -// of CR_DEFINE_STATIC_LOCAL(). -#define LIBJINGLE_DEFINE_STATIC_LOCAL(type, name, arguments) \ - CR_DEFINE_STATIC_LOCAL(type, name, arguments) - -#endif // OVERRIDES_WEBRTC_BASE_BASICTYPES_H__ diff --git a/webrtc/overrides/webrtc/base/constructormagic.h b/webrtc/overrides/webrtc/base/constructormagic.h deleted file mode 100644 index bb89f91f1..000000000 --- a/webrtc/overrides/webrtc/base/constructormagic.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// This file overrides the inclusion of webrtc/base/constructormagic.h -// We do this because constructor magic defines DISALLOW_EVIL_CONSTRUCTORS, -// but we want to use the version from Chromium. - -#ifndef OVERRIDES_WEBRTC_BASE_CONSTRUCTORMAGIC_H__ -#define OVERRIDES_WEBRTC_BASE_CONSTRUCTORMAGIC_H__ - -#include "base/basictypes.h" - -#endif // OVERRIDES_WEBRTC_BASE_CONSTRUCTORMAGIC_H__ diff --git a/webrtc/overrides/webrtc/base/logging.cc b/webrtc/overrides/webrtc/base/logging.cc deleted file mode 100644 index 2e43c5016..000000000 --- a/webrtc/overrides/webrtc/base/logging.cc +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "third_party/webrtc/overrides/webrtc/base/logging.h" - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include -#endif // OS_MACOSX - -#include - -#include "base/atomicops.h" -#include "base/strings/string_util.h" -#include "base/threading/platform_thread.h" -#include "third_party/webrtc/base/ipaddress.h" -#include "third_party/webrtc/base/stream.h" -#include "third_party/webrtc/base/stringencode.h" -#include "third_party/webrtc/base/stringutils.h" -#include "third_party/webrtc/base/timeutils.h" - -// From this file we can't use VLOG since it expands into usage of the __FILE__ -// macro (for correct filtering). The actual logging call from DIAGNOSTIC_LOG in -// ~DiagnosticLogMessage. Note that the second parameter to the LAZY_STREAM -// macro is true since the filter check has already been done for -// DIAGNOSTIC_LOG. -#define LOG_LAZY_STREAM_DIRECT(file_name, line_number, sev) \ - LAZY_STREAM(logging::LogMessage(file_name, line_number, \ - -sev).stream(), true) - -namespace rtc { - -void (*g_logging_delegate_function)(const std::string&) = NULL; -void (*g_extra_logging_init_function)( - void (*logging_delegate_function)(const std::string&)) = NULL; -#ifndef NDEBUG -COMPILE_ASSERT(sizeof(base::subtle::Atomic32) == sizeof(base::PlatformThreadId), - atomic32_not_same_size_as_platformthreadid); -base::subtle::Atomic32 g_init_logging_delegate_thread_id = 0; -#endif - -///////////////////////////////////////////////////////////////////////////// -// Constant Labels -///////////////////////////////////////////////////////////////////////////// - -const char* FindLabel(int value, const ConstantLabel entries[]) { - for (int i = 0; entries[i].label; ++i) { - if (value == entries[i].value) return entries[i].label; - } - return 0; -} - -std::string ErrorName(int err, const ConstantLabel* err_table) { - if (err == 0) - return "No error"; - - if (err_table != 0) { - if (const char * value = FindLabel(err, err_table)) - return value; - } - - char buffer[16]; - base::snprintf(buffer, sizeof(buffer), "0x%08x", err); - return buffer; -} - -///////////////////////////////////////////////////////////////////////////// -// Log helper functions -///////////////////////////////////////////////////////////////////////////// - -// Generates extra information for LOG_E. -static std::string GenerateExtra(LogErrorContext err_ctx, - int err, - const char* module) { - if (err_ctx != ERRCTX_NONE) { - std::ostringstream tmp; - tmp << ": "; - tmp << "[0x" << std::setfill('0') << std::hex << std::setw(8) << err << "]"; - switch (err_ctx) { - case ERRCTX_ERRNO: - tmp << " " << strerror(err); - break; -#if defined(WEBRTC_WIN) - case ERRCTX_HRESULT: { - char msgbuf[256]; - DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM; - HMODULE hmod = GetModuleHandleA(module); - if (hmod) - flags |= FORMAT_MESSAGE_FROM_HMODULE; - if (DWORD len = FormatMessageA( - flags, hmod, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - msgbuf, sizeof(msgbuf) / sizeof(msgbuf[0]), NULL)) { - while ((len > 0) && - isspace(static_cast(msgbuf[len-1]))) { - msgbuf[--len] = 0; - } - tmp << " " << msgbuf; - } - break; - } -#endif // OS_WIN -#if defined(WEBRTC_IOS) - case ERRCTX_OSSTATUS: - tmp << " " << "Unknown LibJingle error: " << err; - break; -#elif defined(WEBRTC_MAC) - case ERRCTX_OSSTATUS: { - tmp << " " << nonnull(GetMacOSStatusErrorString(err), "Unknown error"); - if (const char* desc = GetMacOSStatusCommentString(err)) { - tmp << ": " << desc; - } - break; - } -#endif // OS_MACOSX - default: - break; - } - return tmp.str(); - } - return ""; -} - -DiagnosticLogMessage::DiagnosticLogMessage(const char* file, - int line, - LoggingSeverity severity, - bool log_to_chrome, - LogErrorContext err_ctx, - int err) - : file_name_(file), - line_(line), - severity_(severity), - log_to_chrome_(log_to_chrome) { - extra_ = GenerateExtra(err_ctx, err, NULL); -} - -DiagnosticLogMessage::DiagnosticLogMessage(const char* file, - int line, - LoggingSeverity severity, - bool log_to_chrome, - LogErrorContext err_ctx, - int err, - const char* module) - : file_name_(file), - line_(line), - severity_(severity), - log_to_chrome_(log_to_chrome) { - extra_ = GenerateExtra(err_ctx, err, module); -} - -DiagnosticLogMessage::~DiagnosticLogMessage() { - print_stream_ << extra_; - const std::string& str = print_stream_.str(); - if (log_to_chrome_) - LOG_LAZY_STREAM_DIRECT(file_name_, line_, severity_) << str; - if (g_logging_delegate_function && severity_ <= LS_INFO) { - g_logging_delegate_function(str); - } -} - -// Note: this function is a copy from the overriden libjingle implementation. -void LogMultiline(LoggingSeverity level, const char* label, bool input, - const void* data, size_t len, bool hex_mode, - LogMultilineState* state) { - if (!LOG_CHECK_LEVEL_V(level)) - return; - - const char * direction = (input ? " << " : " >> "); - - // NULL data means to flush our count of unprintable characters. - if (!data) { - if (state && state->unprintable_count_[input]) { - LOG_V(level) << label << direction << "## " - << state->unprintable_count_[input] - << " consecutive unprintable ##"; - state->unprintable_count_[input] = 0; - } - return; - } - - // The ctype classification functions want unsigned chars. - const unsigned char* udata = static_cast(data); - - if (hex_mode) { - const size_t LINE_SIZE = 24; - char hex_line[LINE_SIZE * 9 / 4 + 2], asc_line[LINE_SIZE + 1]; - while (len > 0) { - memset(asc_line, ' ', sizeof(asc_line)); - memset(hex_line, ' ', sizeof(hex_line)); - size_t line_len = _min(len, LINE_SIZE); - for (size_t i = 0; i < line_len; ++i) { - unsigned char ch = udata[i]; - asc_line[i] = isprint(ch) ? ch : '.'; - hex_line[i*2 + i/4] = hex_encode(ch >> 4); - hex_line[i*2 + i/4 + 1] = hex_encode(ch & 0xf); - } - asc_line[sizeof(asc_line)-1] = 0; - hex_line[sizeof(hex_line)-1] = 0; - LOG_V(level) << label << direction - << asc_line << " " << hex_line << " "; - udata += line_len; - len -= line_len; - } - return; - } - - size_t consecutive_unprintable = state ? state->unprintable_count_[input] : 0; - - const unsigned char* end = udata + len; - while (udata < end) { - const unsigned char* line = udata; - const unsigned char* end_of_line = strchrn(udata, - end - udata, - '\n'); - if (!end_of_line) { - udata = end_of_line = end; - } else { - udata = end_of_line + 1; - } - - bool is_printable = true; - - // If we are in unprintable mode, we need to see a line of at least - // kMinPrintableLine characters before we'll switch back. - const ptrdiff_t kMinPrintableLine = 4; - if (consecutive_unprintable && ((end_of_line - line) < kMinPrintableLine)) { - is_printable = false; - } else { - // Determine if the line contains only whitespace and printable - // characters. - bool is_entirely_whitespace = true; - for (const unsigned char* pos = line; pos < end_of_line; ++pos) { - if (isspace(*pos)) - continue; - is_entirely_whitespace = false; - if (!isprint(*pos)) { - is_printable = false; - break; - } - } - // Treat an empty line following unprintable data as unprintable. - if (consecutive_unprintable && is_entirely_whitespace) { - is_printable = false; - } - } - if (!is_printable) { - consecutive_unprintable += (udata - line); - continue; - } - // Print out the current line, but prefix with a count of prior unprintable - // characters. - if (consecutive_unprintable) { - LOG_V(level) << label << direction << "## " << consecutive_unprintable - << " consecutive unprintable ##"; - consecutive_unprintable = 0; - } - // Strip off trailing whitespace. - while ((end_of_line > line) && isspace(*(end_of_line-1))) { - --end_of_line; - } - // Filter out any private data - std::string substr(reinterpret_cast(line), end_of_line - line); - std::string::size_type pos_private = substr.find("Email"); - if (pos_private == std::string::npos) { - pos_private = substr.find("Passwd"); - } - if (pos_private == std::string::npos) { - LOG_V(level) << label << direction << substr; - } else { - LOG_V(level) << label << direction << "## omitted for privacy ##"; - } - } - - if (state) { - state->unprintable_count_[input] = consecutive_unprintable; - } -} - -void InitDiagnosticLoggingDelegateFunction( - void (*delegate)(const std::string&)) { -#ifndef NDEBUG - // Ensure that this function is always called from the same thread. - base::subtle::NoBarrier_CompareAndSwap(&g_init_logging_delegate_thread_id, 0, - static_cast(base::PlatformThread::CurrentId())); - DCHECK_EQ(g_init_logging_delegate_thread_id, - base::PlatformThread::CurrentId()); -#endif - CHECK(delegate); - // This function may be called with the same argument several times if the - // page is reloaded or there are several PeerConnections on one page with - // logging enabled. This is OK, we simply don't have to do anything. - if (delegate == g_logging_delegate_function) - return; - CHECK(!g_logging_delegate_function); -#ifdef NDEBUG - IPAddress::set_strip_sensitive(true); -#endif - g_logging_delegate_function = delegate; - - if (g_extra_logging_init_function) - g_extra_logging_init_function(delegate); -} - -void SetExtraLoggingInit( - void (*function)(void (*delegate)(const std::string&))) { - CHECK(function); - CHECK(!g_extra_logging_init_function); - g_extra_logging_init_function = function; -} - -} // namespace rtc diff --git a/webrtc/overrides/webrtc/base/logging.h b/webrtc/overrides/webrtc/base/logging.h deleted file mode 100644 index d8dfca2ce..000000000 --- a/webrtc/overrides/webrtc/base/logging.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// This file overrides the logging macros in libjingle (webrtc/base/logging.h). -// Instead of using libjingle's logging implementation, the libjingle macros are -// mapped to the corresponding base/logging.h macro (chromium's VLOG). -// If this file is included outside of libjingle (e.g. in wrapper code) it -// should be included after base/logging.h (if any) or compiler error or -// unexpected behavior may occur (macros that have the same name in libjingle as -// in chromium will use the libjingle definition if this file is included -// first). - -// Setting the LoggingSeverity (and lower) that should be written to file should -// be done via command line by specifying the flags: -// --vmodule or --v please see base/logging.h for details on how to use them. -// Specifying what file to write to is done using InitLogging also in -// base/logging.h. - -// The macros and classes declared in here are not described as they are -// NOT TO BE USED outside of libjingle. - -#ifndef THIRD_PARTY_LIBJINGLE_OVERRIDES_WEBRTC_BASE_LOGGING_H_ -#define THIRD_PARTY_LIBJINGLE_OVERRIDES_WEBRTC_BASE_LOGGING_H_ - -#include -#include - -#include "base/logging.h" -#include "third_party/webrtc/base/scoped_ref_ptr.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// ConstantLabel can be used to easily generate string names from constant -// values. This can be useful for logging descriptive names of error messages. -// Usage: -// const ConstantLabel LIBRARY_ERRORS[] = { -// KLABEL(SOME_ERROR), -// KLABEL(SOME_OTHER_ERROR), -// ... -// LASTLABEL -// } -// -// int err = LibraryFunc(); -// LOG(LS_ERROR) << "LibraryFunc returned: " -// << ErrorName(err, LIBRARY_ERRORS); - -struct ConstantLabel { - int value; - const char* label; -}; -#define KLABEL(x) { x, #x } -#define LASTLABEL { 0, 0 } - -const char* FindLabel(int value, const ConstantLabel entries[]); -std::string ErrorName(int err, const ConstantLabel* err_table); - -////////////////////////////////////////////////////////////////////// -// Note that the non-standard LoggingSeverity aliases exist because they are -// still in broad use. The meanings of the levels are: -// LS_SENSITIVE: Information which should only be logged with the consent -// of the user, due to privacy concerns. -// LS_VERBOSE: This level is for data which we do not want to appear in the -// normal debug log, but should appear in diagnostic logs. -// LS_INFO: Chatty level used in debugging for all sorts of things, the default -// in debug builds. -// LS_WARNING: Something that may warrant investigation. -// LS_ERROR: Something that should not have occurred. -// Note that LoggingSeverity is mapped over to chromiums verbosity levels where -// anything lower than or equal to the current verbosity level is written to -// file which is the opposite of logging severity in libjingle where higher -// severity numbers than or equal to the current severity level are written to -// file. Also, note that the values are explicitly defined here for convenience -// since the command line flag must be set using numerical values. -enum LoggingSeverity { LS_ERROR = 1, - LS_WARNING = 2, - LS_INFO = 3, - LS_VERBOSE = 4, - LS_SENSITIVE = 5, - INFO = LS_INFO, - WARNING = LS_WARNING, - LERROR = LS_ERROR }; - -// LogErrorContext assists in interpreting the meaning of an error value. -enum LogErrorContext { - ERRCTX_NONE, - ERRCTX_ERRNO, // System-local errno - ERRCTX_HRESULT, // Windows HRESULT - ERRCTX_OSSTATUS, // MacOS OSStatus - - // Abbreviations for LOG_E macro - ERRCTX_EN = ERRCTX_ERRNO, // LOG_E(sev, EN, x) - ERRCTX_HR = ERRCTX_HRESULT, // LOG_E(sev, HR, x) - ERRCTX_OS = ERRCTX_OSSTATUS, // LOG_E(sev, OS, x) -}; - -// Class that writes a log message to the logging delegate ("WebRTC logging -// stream" in Chrome) and to Chrome's logging stream. -class DiagnosticLogMessage { - public: - DiagnosticLogMessage(const char* file, int line, LoggingSeverity severity, - bool log_to_chrome, LogErrorContext err_ctx, int err); - DiagnosticLogMessage(const char* file, int line, LoggingSeverity severity, - bool log_to_chrome, LogErrorContext err_ctx, int err, - const char* module); - ~DiagnosticLogMessage(); - - void CreateTimestamp(); - - std::ostream& stream() { return print_stream_; } - - private: - const char* file_name_; - const int line_; - const LoggingSeverity severity_; - const bool log_to_chrome_; - - std::string extra_; - - std::ostringstream print_stream_; -}; - -// This class is used to explicitly ignore values in the conditional -// logging macros. This avoids compiler warnings like "value computed -// is not used" and "statement has no effect". -class LogMessageVoidify { - public: - LogMessageVoidify() { } - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(std::ostream&) { } -}; - -////////////////////////////////////////////////////////////////////// -// Logging Helpers -////////////////////////////////////////////////////////////////////// - -class LogMultilineState { - public: - size_t unprintable_count_[2]; - LogMultilineState() { - unprintable_count_[0] = unprintable_count_[1] = 0; - } -}; - -// When possible, pass optional state variable to track various data across -// multiple calls to LogMultiline. Otherwise, pass NULL. -void LogMultiline(LoggingSeverity level, const char* label, bool input, - const void* data, size_t len, bool hex_mode, - LogMultilineState* state); - -// TODO(grunell): Change name to InitDiagnosticLoggingDelegate or -// InitDiagnosticLogging. Change also in init_webrtc.h/cc. -// TODO(grunell): typedef the delegate function. -void InitDiagnosticLoggingDelegateFunction( - void (*delegate)(const std::string&)); - -void SetExtraLoggingInit( - void (*function)(void (*delegate)(const std::string&))); -} // namespace rtc - -////////////////////////////////////////////////////////////////////// -// Libjingle macros which are mapped over to their VLOG equivalent in -// base/logging.h -////////////////////////////////////////////////////////////////////// - -#if defined(LOGGING_INSIDE_WEBRTC) - -#define DIAGNOSTIC_LOG(sev, ctx, err, ...) \ - rtc::DiagnosticLogMessage( \ - __FILE__, __LINE__, sev, VLOG_IS_ON(sev), \ - rtc::ERRCTX_ ## ctx, err, ##__VA_ARGS__).stream() - -#define LOG_CHECK_LEVEL(sev) VLOG_IS_ON(rtc::sev) -#define LOG_CHECK_LEVEL_V(sev) VLOG_IS_ON(sev) - -#define LOG_V(sev) DIAGNOSTIC_LOG(sev, NONE, 0) -#undef LOG -#define LOG(sev) DIAGNOSTIC_LOG(rtc::sev, NONE, 0) - -// The _F version prefixes the message with the current function name. -#if defined(__GNUC__) && defined(_DEBUG) -#define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": " -#else -#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": " -#endif - -#define LOG_E(sev, ctx, err, ...) \ - DIAGNOSTIC_LOG(rtc::sev, ctx, err, ##__VA_ARGS__) - -#undef LOG_ERRNO_EX -#define LOG_ERRNO_EX(sev, err) LOG_E(sev, ERRNO, err) -#undef LOG_ERRNO -#define LOG_ERRNO(sev) LOG_ERRNO_EX(sev, errno) - -#if defined(WEBRTC_WIN) -#define LOG_GLE_EX(sev, err) LOG_E(sev, HRESULT, err) -#define LOG_GLE(sev) LOG_GLE_EX(sev, GetLastError()) -#define LOG_GLEM(sev, mod) LOG_E(sev, HRESULT, GetLastError(), mod) -#define LOG_ERR_EX(sev, err) LOG_GLE_EX(sev, err) -#define LOG_ERR(sev) LOG_GLE(sev) -#define LAST_SYSTEM_ERROR (::GetLastError()) -#else -#define LOG_ERR_EX(sev, err) LOG_ERRNO_EX(sev, err) -#define LOG_ERR(sev) LOG_ERRNO(sev) -#define LAST_SYSTEM_ERROR (errno) -#endif // OS_WIN - -#undef PLOG -#define PLOG(sev, err) LOG_ERR_EX(sev, err) - -#endif // LOGGING_INSIDE_WEBRTC - -#endif // THIRD_PARTY_LIBJINGLE_OVERRIDES_WEBRTC_BASE_LOGGING_H_ diff --git a/webrtc/overrides/webrtc/base/win32socketinit.cc b/webrtc/overrides/webrtc/base/win32socketinit.cc deleted file mode 100644 index 929ce8d36..000000000 --- a/webrtc/overrides/webrtc/base/win32socketinit.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2006 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Redirect Libjingle's winsock initialization activity into Chromium's -// singleton object that managest precisely that for the browser. - -#include "webrtc/base/win32socketinit.h" - -#include "net/base/winsock_init.h" - -#if !defined(WEBRTC_WIN) -#error "Only compile this on Windows" -#endif - -namespace rtc { - -void EnsureWinsockInit() { - net::EnsureWinsockInit(); -} - -} // namespace rtc diff --git a/webrtc/system_wrappers/source/system_wrappers.gyp b/webrtc/system_wrappers/source/system_wrappers.gyp index 60b41dbd6..dd25de674 100644 --- a/webrtc/system_wrappers/source/system_wrappers.gyp +++ b/webrtc/system_wrappers/source/system_wrappers.gyp @@ -16,9 +16,6 @@ 'spreadsortlib', '../interface', ], - 'dependencies': [ - '../../base/base.gyp:webrtc_base', - ], 'direct_dependent_settings': { 'include_dirs': [ '../interface', diff --git a/webrtc/webrtc.gyp b/webrtc/webrtc.gyp index f376c0643..e78dba6fa 100644 --- a/webrtc/webrtc.gyp +++ b/webrtc/webrtc.gyp @@ -19,7 +19,6 @@ ], 'variables': { 'webrtc_all_dependencies': [ - 'base/base.gyp:*', 'common_audio/common_audio.gyp:*', 'common_video/common_video.gyp:*', 'modules/modules.gyp:*', @@ -40,7 +39,6 @@ 'conditions': [ ['include_tests==1', { 'dependencies': [ - 'base/base_tests.gyp:*', 'common_video/common_video_unittests.gyp:*', 'system_wrappers/source/system_wrappers_tests.gyp:*', 'test/metrics.gyp:*',