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