15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <poll.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/socket.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/un.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstring> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <queue> 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/condition_variable.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/unix_domain_socket_posix.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::queue; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSocketFilename[] = "unix_domain_socket_for_testing"; 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kFallbackSocketName[] = "unix_domain_socket_for_testing_2"; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidSocketPath[] = "/invalid/path"; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMsg[] = "hello"; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum EventType { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_ACCEPT, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_AUTH_DENIED, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_AUTH_GRANTED, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_CLOSE, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_LISTEN, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_READ, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)string MakeSocketPath(const string& socket_file_name) { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath temp_dir; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::GetTempDir(&temp_dir); 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return temp_dir.Append(socket_file_name).value(); 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)string MakeSocketPath() { 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return MakeSocketPath(kSocketFilename); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EventManager : public base::RefCounted<EventManager> { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventManager() : condition_(&mutex_) {} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasPendingEvent() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock(mutex_); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !events_.empty(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Notify(EventType event) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock(mutex_); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.push(event); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) condition_.Broadcast(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventType WaitForEvent() { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock(mutex_); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (events_.empty()) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) condition_.Wait(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventType event = events_.front(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.pop(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return event; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<EventManager>; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~EventManager() {} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queue<EventType> events_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock mutex_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ConditionVariable condition_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestListenSocketDelegate : public StreamListenSocket::Delegate { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit TestListenSocketDelegate( 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<EventManager>& event_manager) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : event_manager_(event_manager) {} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DidAccept(StreamListenSocket* server, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamListenSocket* connection) OVERRIDE { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << __PRETTY_FUNCTION__; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_ = connection; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notify(EVENT_ACCEPT); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DidRead(StreamListenSocket* connection, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len) OVERRIDE { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock(mutex_); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(len); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_.assign(data, len - 1); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notify(EVENT_READ); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DidClose(StreamListenSocket* sock) OVERRIDE { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notify(EVENT_CLOSE); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnListenCompleted() { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notify(EVENT_LISTEN); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string ReceivedData() { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock(mutex_); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data_; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Notify(EventType event) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_manager_->Notify(event); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<EventManager> event_manager_; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<StreamListenSocket> connection_; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock mutex_; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string data_; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UserCanConnectCallback( 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool allow_user, const scoped_refptr<EventManager>& event_manager, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uid_t, gid_t) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_manager->Notify( 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allow_user ? EVENT_AUTH_GRANTED : EVENT_AUTH_DENIED); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return allow_user; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UnixDomainSocketTestHelper : public testing::Test { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateAndListen() { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = UnixDomainSocket::CreateAndListen( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_path_.value(), socket_delegate_.get(), MakeAuthCallback()); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_delegate_->OnListenCompleted(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnixDomainSocketTestHelper(const string& path, bool allow_user) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : file_path_(path), 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allow_user_(allow_user) {} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_manager_ = new EventManager(); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_delegate_.reset(new TestListenSocketDelegate(event_manager_)); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSocketFile(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSocketFile(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = NULL; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_delegate_.reset(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_manager_ = NULL; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnixDomainSocket::AuthCallback MakeAuthCallback() { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Bind(&UserCanConnectCallback, allow_user_, event_manager_); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteSocketFile() { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(file_path_.empty()); 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(file_path_, false /* not recursive */); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SocketDescriptor CreateClientSocket() { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SocketDescriptor sock = socket(PF_UNIX, SOCK_STREAM, 0); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sock < 0) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "socket() error"; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StreamListenSocket::kInvalidSocket; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockaddr_un addr; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&addr, 0, sizeof(addr)); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.sun_family = AF_UNIX; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socklen_t addr_len; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strncpy(addr.sun_path, file_path_.value().c_str(), sizeof(addr.sun_path)); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr_len = sizeof(sockaddr_un); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connect(sock, reinterpret_cast<sockaddr*>(&addr), addr_len) != 0) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "connect() error"; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StreamListenSocket::kInvalidSocket; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sock; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Thread> CreateAndRunServerThread() { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread::Options options; 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) options.message_loop_type = base::MessageLoop::TYPE_IO; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Thread> thread(new base::Thread("socketio_test")); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread->StartWithOptions(options); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread->message_loop()->PostTask( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&UnixDomainSocketTestHelper::CreateAndListen, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return thread.Pass(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath file_path_; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool allow_user_; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<EventManager> event_manager_; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TestListenSocketDelegate> socket_delegate_; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<UnixDomainSocket> socket_; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UnixDomainSocketTest : public UnixDomainSocketTestHelper { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnixDomainSocketTest() 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : UnixDomainSocketTestHelper(MakeSocketPath(), true /* allow user */) {} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UnixDomainSocketTestWithInvalidPath : public UnixDomainSocketTestHelper { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnixDomainSocketTestWithInvalidPath() 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : UnixDomainSocketTestHelper(kInvalidSocketPath, true) {} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UnixDomainSocketTestWithForbiddenUser 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public UnixDomainSocketTestHelper { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnixDomainSocketTestWithForbiddenUser() 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : UnixDomainSocketTestHelper(MakeSocketPath(), false /* forbid user */) {} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(UnixDomainSocketTest, CreateAndListen) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateAndListen(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(socket_.get() == NULL); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(UnixDomainSocketTestWithInvalidPath, CreateAndListenWithInvalidPath) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateAndListen(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(socket_.get() == NULL); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SOCKET_ABSTRACT_NAMESPACE_SUPPORTED 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test with an invalid path to make sure that the socket is not backed by a 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// file. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(UnixDomainSocketTestWithInvalidPath, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateAndListenWithAbstractNamespace) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = UnixDomainSocket::CreateAndListenWithAbstractNamespace( 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_path_.value(), "", socket_delegate_.get(), MakeAuthCallback()); 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_FALSE(socket_.get() == NULL); 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(UnixDomainSocketTest, TestFallbackName) { 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<UnixDomainSocket> existing_socket = 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UnixDomainSocket::CreateAndListenWithAbstractNamespace( 269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_path_.value(), "", socket_delegate_.get(), MakeAuthCallback()); 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_FALSE(existing_socket.get() == NULL); 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // First, try to bind socket with the same name with no fallback name. 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) socket_ = 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UnixDomainSocket::CreateAndListenWithAbstractNamespace( 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_path_.value(), "", socket_delegate_.get(), MakeAuthCallback()); 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(socket_.get() == NULL); 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Now with a fallback name. 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) socket_ = UnixDomainSocket::CreateAndListenWithAbstractNamespace( 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_path_.value(), 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MakeSocketPath(kFallbackSocketName), 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) socket_delegate_.get(), 281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MakeAuthCallback()); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(socket_.get() == NULL); 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) existing_socket = NULL; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(UnixDomainSocketTest, TestWithClient) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_ptr<base::Thread> server_thread = CreateAndRunServerThread(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventType event = event_manager_->WaitForEvent(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EVENT_LISTEN, event); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the client socket. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SocketDescriptor sock = CreateClientSocket(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(StreamListenSocket::kInvalidSocket, sock); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event = event_manager_->WaitForEvent(); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EVENT_AUTH_GRANTED, event); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event = event_manager_->WaitForEvent(); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EVENT_ACCEPT, event); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send a message from the client to the server. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssize_t ret = HANDLE_EINTR(send(sock, kMsg, sizeof(kMsg), 0)); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(-1, ret); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(sizeof(kMsg), static_cast<size_t>(ret)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event = event_manager_->WaitForEvent(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EVENT_READ, event); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(kMsg, socket_delegate_->ReceivedData()); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the client socket. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = HANDLE_EINTR(close(sock)); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event = event_manager_->WaitForEvent(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EVENT_CLOSE, event); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(UnixDomainSocketTestWithForbiddenUser, TestWithForbiddenUser) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_ptr<base::Thread> server_thread = CreateAndRunServerThread(); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventType event = event_manager_->WaitForEvent(); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EVENT_LISTEN, event); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SocketDescriptor sock = CreateClientSocket(); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(StreamListenSocket::kInvalidSocket, sock); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event = event_manager_->WaitForEvent(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EVENT_AUTH_DENIED, event); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait until the file descriptor is closed by the server. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pollfd poll_fd; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) poll_fd.fd = sock; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) poll_fd.events = POLLIN; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) poll(&poll_fd, 1, -1 /* rely on GTest for timeout handling */); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send() must fail. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssize_t ret = HANDLE_EINTR(send(sock, kMsg, sizeof(kMsg), 0)); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(-1, ret); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EPIPE, errno); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(event_manager_->HasPendingEvent()); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 339