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
18namespace 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.
23class 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