1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef TOOLS_ANDROID_FORWARDER2_SOCKET_H_ 6 #define TOOLS_ANDROID_FORWARDER2_SOCKET_H_ 7 8 #include <fcntl.h> 9 #include <netinet/in.h> 10 #include <sys/socket.h> 11 #include <sys/un.h> 12 13 #include <string> 14 #include <vector> 15 16 #include "base/basictypes.h" 17 18 namespace forwarder2 { 19 20 // Wrapper class around unix socket api. Can be used to create, bind or 21 // connect to both Unix domain sockets and TCP sockets. 22 // TODO(pliard): Split this class into TCPSocket and UnixDomainSocket. 23 class Socket { 24 public: 25 Socket(); 26 ~Socket(); 27 28 bool BindUnix(const std::string& path); 29 bool BindTcp(const std::string& host, int port); 30 bool ConnectUnix(const std::string& path); 31 bool ConnectTcp(const std::string& host, int port); 32 33 // Just a wrapper around unix socket shutdown(), see man 2 shutdown. 34 void Shutdown(); 35 36 // Just a wrapper around unix socket close(), see man 2 close. 37 void Close(); IsClosed()38 bool IsClosed() const { return socket_ < 0; } 39 40 bool Accept(Socket* new_socket); 41 42 // Returns the port allocated to this socket or zero on error. 43 int GetPort(); 44 45 bool IsFdInSet(const fd_set& fds) const; 46 bool AddFdToSet(fd_set* fds) const; 47 48 // Just a wrapper around unix read() function. 49 // Reads up to buffer_size, but may read less then buffer_size. 50 // Returns the number of bytes read. 51 int Read(void* buffer, size_t buffer_size); 52 53 // Non-blocking version of Read() above. This must be called after a 54 // successful call to select(). The socket must also be in non-blocking mode 55 // before calling this method. 56 int NonBlockingRead(void* buffer, size_t buffer_size); 57 58 // Wrapper around send(). 59 int Write(const void* buffer, size_t count); 60 61 // Same as NonBlockingRead() but for writing. 62 int NonBlockingWrite(const void* buffer, size_t count); 63 64 // Calls Read() multiple times until num_bytes is written to the provided 65 // buffer. No bounds checking is performed. 66 // Returns number of bytes read, which can be different from num_bytes in case 67 // of errror. 68 int ReadNumBytes(void* buffer, size_t num_bytes); 69 70 // Calls Write() multiple times until num_bytes is written. No bounds checking 71 // is performed. Returns number of bytes written, which can be different from 72 // num_bytes in case of errror. 73 int WriteNumBytes(const void* buffer, size_t num_bytes); 74 75 // Calls WriteNumBytes for the given std::string. Note that the null 76 // terminator is not written to the socket. 77 int WriteString(const std::string& buffer); 78 has_error()79 bool has_error() const { return socket_error_; } 80 81 // |event_fd| must be a valid pipe file descriptor created from the 82 // PipeNotifier and must live (not be closed) at least as long as this socket 83 // is alive. 84 void AddEventFd(int event_fd); 85 86 // Returns whether Accept() or Connect() was interrupted because the socket 87 // received an external event fired through the provided fd. 88 bool DidReceiveEventOnFd(int fd) const; 89 90 bool DidReceiveEvent() const; 91 92 static int GetHighestFileDescriptor(const Socket& s1, const Socket& s2); 93 94 static pid_t GetUnixDomainSocketProcessOwner(const std::string& path); 95 96 private: 97 enum EventType { 98 READ, 99 WRITE 100 }; 101 102 union SockAddr { 103 // IPv4 sockaddr 104 sockaddr_in addr4; 105 // IPv6 sockaddr 106 sockaddr_in6 addr6; 107 // Unix Domain sockaddr 108 sockaddr_un addr_un; 109 }; 110 111 struct Event { 112 int fd; 113 bool was_fired; 114 }; 115 116 bool SetNonBlocking(); 117 118 // If |host| is empty, use localhost. 119 bool InitTcpSocket(const std::string& host, int port); 120 bool InitUnixSocket(const std::string& path); 121 bool BindAndListen(); 122 bool Connect(); 123 124 bool Resolve(const std::string& host); 125 bool InitSocketInternal(); 126 void SetSocketError(); 127 128 // Waits until either the Socket or the |exit_notifier_fd_| has received an 129 // event. 130 bool WaitForEvent(EventType type, int timeout_secs); 131 132 int socket_; 133 int port_; 134 bool socket_error_; 135 136 // Family of the socket (PF_INET, PF_INET6 or PF_UNIX). 137 int family_; 138 139 SockAddr addr_; 140 141 // Points to one of the members of the above union depending on the family. 142 sockaddr* addr_ptr_; 143 // Length of one of the members of the above union depending on the family. 144 socklen_t addr_len_; 145 146 // Used to listen for external events (e.g. process received a SIGTERM) while 147 // blocking on I/O operations. 148 std::vector<Event> events_; 149 150 DISALLOW_COPY_AND_ASSIGN(Socket); 151 }; 152 153 } // namespace forwarder 154 155 #endif // TOOLS_ANDROID_FORWARDER2_SOCKET_H_ 156