• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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