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