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(); 38 bool IsClosed() const { return socket_ < 0; } 39 40 int fd() const { return socket_; } 41 42 bool Accept(Socket* new_socket); 43 44 // Returns the port allocated to this socket or zero on error. 45 int GetPort(); 46 47 // Just a wrapper around unix read() function. 48 // Reads up to buffer_size, but may read less then buffer_size. 49 // Returns the number of bytes read. 50 int Read(void* buffer, size_t buffer_size); 51 52 // Non-blocking version of Read() above. This must be called after a 53 // successful call to select(). The socket must also be in non-blocking mode 54 // before calling this method. 55 int NonBlockingRead(void* buffer, size_t buffer_size); 56 57 // Wrapper around send(). 58 int Write(const void* buffer, size_t count); 59 60 // Same as NonBlockingRead() but for writing. 61 int NonBlockingWrite(const void* buffer, size_t count); 62 63 // Calls Read() multiple times until num_bytes is written to the provided 64 // buffer. No bounds checking is performed. 65 // Returns number of bytes read, which can be different from num_bytes in case 66 // of errror. 67 int ReadNumBytes(void* buffer, size_t num_bytes); 68 69 // Calls Write() multiple times until num_bytes is written. No bounds checking 70 // is performed. Returns number of bytes written, which can be different from 71 // num_bytes in case of errror. 72 int WriteNumBytes(const void* buffer, size_t num_bytes); 73 74 // Calls WriteNumBytes for the given std::string. Note that the null 75 // terminator is not written to the socket. 76 int WriteString(const std::string& buffer); 77 78 bool has_error() const { return socket_error_; } 79 80 // |event_fd| must be a valid pipe file descriptor created from the 81 // PipeNotifier and must live (not be closed) at least as long as this socket 82 // is alive. 83 void AddEventFd(int event_fd); 84 85 // Returns whether Accept() or Connect() was interrupted because the socket 86 // received an external event fired through the provided fd. 87 bool DidReceiveEventOnFd(int fd) const; 88 89 bool DidReceiveEvent() const; 90 91 static pid_t GetUnixDomainSocketProcessOwner(const std::string& path); 92 93 private: 94 enum EventType { 95 READ, 96 WRITE 97 }; 98 99 union SockAddr { 100 // IPv4 sockaddr 101 sockaddr_in addr4; 102 // IPv6 sockaddr 103 sockaddr_in6 addr6; 104 // Unix Domain sockaddr 105 sockaddr_un addr_un; 106 }; 107 108 struct Event { 109 int fd; 110 bool was_fired; 111 }; 112 113 bool SetNonBlocking(); 114 115 // If |host| is empty, use localhost. 116 bool InitTcpSocket(const std::string& host, int port); 117 bool InitUnixSocket(const std::string& path); 118 bool BindAndListen(); 119 bool Connect(); 120 121 bool Resolve(const std::string& host); 122 bool InitSocketInternal(); 123 void SetSocketError(); 124 125 // Waits until either the Socket or the |exit_notifier_fd_| has received an 126 // event. 127 bool WaitForEvent(EventType type, int timeout_secs); 128 129 int socket_; 130 int port_; 131 bool socket_error_; 132 133 // Family of the socket (PF_INET, PF_INET6 or PF_UNIX). 134 int family_; 135 136 SockAddr addr_; 137 138 // Points to one of the members of the above union depending on the family. 139 sockaddr* addr_ptr_; 140 // Length of one of the members of the above union depending on the family. 141 socklen_t addr_len_; 142 143 // Used to listen for external events (e.g. process received a SIGTERM) while 144 // blocking on I/O operations. 145 std::vector<Event> events_; 146 147 DISALLOW_COPY_AND_ASSIGN(Socket); 148 }; 149 150 } // namespace forwarder 151 152 #endif // TOOLS_ANDROID_FORWARDER2_SOCKET_H_ 153