/Users/deen/code/yugabyte-db/src/yb/util/net/socket.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // |
18 | | // The following only applies to changes made to this file as part of YugaByte development. |
19 | | // |
20 | | // Portions Copyright (c) YugaByte, Inc. |
21 | | // |
22 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
23 | | // in compliance with the License. You may obtain a copy of the License at |
24 | | // |
25 | | // http://www.apache.org/licenses/LICENSE-2.0 |
26 | | // |
27 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
28 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
29 | | // or implied. See the License for the specific language governing permissions and limitations |
30 | | // under the License. |
31 | | // |
32 | | #ifndef YB_UTIL_NET_SOCKET_H |
33 | | #define YB_UTIL_NET_SOCKET_H |
34 | | |
35 | | #include <sys/uio.h> |
36 | | #include <string> |
37 | | |
38 | | #include <boost/container/small_vector.hpp> |
39 | | |
40 | | #include "yb/gutil/macros.h" |
41 | | |
42 | | #include "yb/util/net/sockaddr.h" |
43 | | #include "yb/util/status_fwd.h" |
44 | | |
45 | | namespace yb { |
46 | | |
47 | | class MonoDelta; |
48 | | class MonoTime; |
49 | | |
50 | | // Vector of io buffers. Could be used with receive, already received data etc. |
51 | | typedef boost::container::small_vector<::iovec, 4> IoVecs; |
52 | | |
53 | | size_t IoVecsFullSize(const IoVecs& io_vecs); |
54 | | // begin and end are positions in concatenated io_vecs. |
55 | | void IoVecsToBuffer(const IoVecs& io_vecs, size_t begin, size_t end, std::vector<char>* result); |
56 | | void IoVecsToBuffer(const IoVecs& io_vecs, size_t begin, size_t end, char* result); |
57 | 328M | inline const char* IoVecBegin(const iovec& inp) { return static_cast<const char*>(inp.iov_base); } |
58 | 1.93M | inline const char* IoVecEnd(const iovec& inp) { return IoVecBegin(inp) + inp.iov_len; } |
59 | | |
60 | 1.45M | inline void IoVecRemovePrefix(size_t len, iovec* iov) { |
61 | 1.45M | iov->iov_len -= len; |
62 | 1.45M | iov->iov_base = static_cast<char*>(iov->iov_base) + len; |
63 | 1.45M | } |
64 | | |
65 | | class Socket { |
66 | | public: |
67 | | static const int FLAG_NONBLOCKING = 0x1; |
68 | | static const int FLAG_IPV6 = 0x02; |
69 | | |
70 | | // Create a new invalid Socket object. |
71 | | Socket(); |
72 | | |
73 | 10.0M | Socket(Socket&& rhs) noexcept : fd_(rhs.fd_) { rhs.Release(); } |
74 | | |
75 | | // Start managing a socket. |
76 | | explicit Socket(int fd); |
77 | | |
78 | | // Close the socket. Errors will be ignored. |
79 | | ~Socket(); |
80 | | |
81 | | // Close the Socket, checking for errors. |
82 | | CHECKED_STATUS Close(); |
83 | | |
84 | | // call shutdown() on the socket |
85 | | CHECKED_STATUS Shutdown(bool shut_read, bool shut_write); |
86 | | |
87 | | // Start managing a socket. |
88 | | void Reset(int fd); |
89 | | |
90 | | // Stop managing the socket and return it. |
91 | | int Release(); |
92 | | |
93 | | // Get the raw file descriptor, or -1 if there is no file descriptor being |
94 | | // managed. |
95 | | int GetFd() const; |
96 | | |
97 | | CHECKED_STATUS Init(int flags); // See FLAG_NONBLOCKING |
98 | | |
99 | | // Set or clear TCP_NODELAY |
100 | | CHECKED_STATUS SetNoDelay(bool enabled); |
101 | | |
102 | | // Set or clear O_NONBLOCK |
103 | | CHECKED_STATUS SetNonBlocking(bool enabled); |
104 | | CHECKED_STATUS IsNonBlocking(bool* is_nonblock) const; |
105 | | |
106 | | // Set SO_SENDTIMEO to the specified value. Should only be used for blocking sockets. |
107 | | CHECKED_STATUS SetSendTimeout(const MonoDelta& timeout); |
108 | | |
109 | | // Set SO_RCVTIMEO to the specified value. Should only be used for blocking sockets. |
110 | | CHECKED_STATUS SetRecvTimeout(const MonoDelta& timeout); |
111 | | |
112 | | // Sets SO_REUSEADDR to 'flag'. Should be used prior to Bind(). |
113 | | CHECKED_STATUS SetReuseAddr(bool flag); |
114 | | |
115 | | // Convenience method to invoke the common sequence: |
116 | | // 1) SetReuseAddr(true) |
117 | | // 2) Bind() |
118 | | // 3) Listen() |
119 | | CHECKED_STATUS BindAndListen(const Endpoint& endpoint, int listen_queue_size); |
120 | | |
121 | | // Start listening for new connections, with the given backlog size. |
122 | | // Requires that the socket has already been bound using Bind(). |
123 | | CHECKED_STATUS Listen(int listen_queue_size); |
124 | | |
125 | | // Call getsockname to get the address of this socket. |
126 | | CHECKED_STATUS GetSocketAddress(Endpoint* out) const; |
127 | | |
128 | | // Call getpeername to get the address of the connected peer. |
129 | | CHECKED_STATUS GetPeerAddress(Endpoint* out) const; |
130 | | |
131 | | // Call bind() to bind the socket to a given address. |
132 | | // If bind() fails and indicates that the requested port is already in use, |
133 | | // and if explain_addr_in_use is set to true, generates an informative log message by calling |
134 | | // 'lsof' if available. |
135 | | CHECKED_STATUS Bind(const Endpoint& bind_addr, bool explain_addr_in_use = true); |
136 | | |
137 | | // Call accept(2) to get a new connection. |
138 | | CHECKED_STATUS Accept(Socket *new_conn, Endpoint* remote, int flags); |
139 | | |
140 | | // start connecting this socket to a remote address. |
141 | | CHECKED_STATUS Connect(const Endpoint& remote); |
142 | | |
143 | | // get the error status using getsockopt(2) |
144 | | CHECKED_STATUS GetSockError() const; |
145 | | |
146 | | Result<size_t> Write(const uint8_t *buf, ssize_t amt); |
147 | | |
148 | | Result<size_t> Writev(const struct ::iovec *iov, int iov_len); |
149 | | |
150 | | // Blocking Write call, returns IOError unless full buffer is sent. |
151 | | // Underlying Socket expected to be in blocking mode. Fails if any Write() sends 0 bytes. |
152 | | // Returns OK if buflen bytes were sent, otherwise IOError. |
153 | | // Upon return, num_written will contain the number of bytes actually written. |
154 | | // See also writen() from Stevens (2004) or Kerrisk (2010) |
155 | | CHECKED_STATUS BlockingWrite(const uint8_t *buf, size_t buflen, const MonoTime& deadline); |
156 | | |
157 | | Result<size_t> Recv(uint8_t* buf, ssize_t amt); |
158 | | |
159 | | // Receives into multiple buffers, returns number of bytes received. |
160 | | Result<size_t> Recvv(IoVecs* vecs); |
161 | | |
162 | | // Blocking Recv call, returns IOError unless requested amt bytes are read. |
163 | | // Underlying Socket expected to be in blocking mode. Fails if any Recv() reads 0 bytes. |
164 | | // Returns OK if amt bytes were read, otherwise IOError. |
165 | | // Upon return, nread will contain the number of bytes actually read. |
166 | | // See also readn() from Stevens (2004) or Kerrisk (2010) |
167 | | Result<size_t> BlockingRecv(uint8_t *buf, size_t amt, const MonoTime& deadline); |
168 | | |
169 | | // Implements the SOL_SOCKET/SO_RCVBUF socket option. |
170 | | Result<int32_t> GetReceiveBufferSize(); |
171 | | CHECKED_STATUS SetReceiveBufferSize(int32_t size); |
172 | | |
173 | | private: |
174 | | // Called internally from SetSend/RecvTimeout(). |
175 | | CHECKED_STATUS SetTimeout(int opt, std::string optname, const MonoDelta& timeout); |
176 | | |
177 | | // Called internally during socket setup. |
178 | | CHECKED_STATUS SetCloseOnExec(); |
179 | | |
180 | | // Bind the socket to a local address before making an outbound connection, |
181 | | // based on the value of FLAGS_local_ip_for_outbound_sockets. |
182 | | CHECKED_STATUS BindForOutgoingConnection(); |
183 | | |
184 | | int fd_; |
185 | | |
186 | | DISALLOW_COPY_AND_ASSIGN(Socket); |
187 | | }; |
188 | | |
189 | | } // namespace yb |
190 | | |
191 | | #endif // YB_UTIL_NET_SOCKET_H |