MongoDB C++ Driver  legacy-1.1.2
sock.h
1 // @file sock.h
2 
3 /* Copyright 2009 10gen Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include "mongo/config.h"
21 
22 #include <stdio.h>
23 
24 #ifndef _WIN32
25 
26 #include <sys/socket.h>
27 #include <sys/types.h>
28 #include <sys/un.h>
29 #include <errno.h>
30 
31 #ifdef __openbsd__
32 #include <sys/uio.h>
33 #endif
34 
35 #endif // not _WIN32
36 
37 #include <boost/scoped_ptr.hpp>
38 #include <string>
39 #include <utility>
40 #include <vector>
41 
42 #include "mongo/base/disallow_copying.h"
43 #include "mongo/logger/log_severity.h"
44 #include "mongo/platform/compiler.h"
45 #include "mongo/platform/cstdint.h"
46 #include "mongo/util/assert_util.h"
47 
48 namespace mongo {
49 
50 #ifdef MONGO_SSL
51 class SSLManagerInterface;
52 class SSLConnection;
53 #endif
54 
55 extern const int portSendFlags;
56 extern const int portRecvFlags;
57 
58 const int SOCK_FAMILY_UNKNOWN_ERROR = 13078;
59 
60 void disableNagle(int sock);
61 
62 void shutdownNetworking();
63 
64 #if defined(_WIN32)
65 
66 typedef short sa_family_t;
67 typedef int socklen_t;
68 
69 // This won't actually be used on windows
70 struct sockaddr_un {
71  short sun_family;
72  char sun_path[108]; // length from unix header
73 };
74 
75 #else // _WIN32
76 
77 inline void closesocket(int s) {
78  close(s);
79 }
80 const int INVALID_SOCKET = -1;
81 typedef int SOCKET;
82 
83 #endif // _WIN32
84 
85 // If an ip address is passed in, just return that. If a hostname is passed
86 // in, look up its ip and return that. Returns "" on failure.
87 std::string hostbyname(const char* hostname);
88 
89 void enableIPv6(bool state = true);
90 bool IPv6Enabled();
91 void setSockTimeouts(int sock, double secs);
92 
96 struct MONGO_CLIENT_API SockAddr {
97  SockAddr();
98  explicit SockAddr(int sourcePort); /* listener side */
99  SockAddr(
100  const char* ip,
101  int port); /* EndPoint (remote) side, or if you want to specify which interface locally */
102 
103  template <typename T>
104  T& as() {
105  return *(T*)(&sa);
106  }
107  template <typename T>
108  const T& as() const {
109  return *(const T*)(&sa);
110  }
111 
112  std::string toString(bool includePort = true) const;
113 
114  bool isValid() const {
115  return _isValid;
116  }
117 
121  sa_family_t getType() const;
122 
123  unsigned getPort() const;
124 
125  std::string getAddr() const;
126 
127  bool isLocalHost() const;
128 
129  bool operator==(const SockAddr& r) const;
130 
131  bool operator!=(const SockAddr& r) const;
132 
133  bool operator<(const SockAddr& r) const;
134 
135  const sockaddr* raw() const {
136  return (sockaddr*)&sa;
137  }
138  sockaddr* raw() {
139  return (sockaddr*)&sa;
140  }
141 
142  socklen_t addressSize;
143 
144 private:
145  struct sockaddr_storage sa;
146  bool _isValid;
147 };
148 
149 extern SockAddr unknownAddress; // ( "0.0.0.0", 0 )
150 
152 std::string getHostName();
153 
157 class MONGO_CLIENT_API SocketException : public DBException {
158 public:
159  const enum Type {
160  CLOSED,
161  RECV_ERROR,
162  SEND_ERROR,
163  RECV_TIMEOUT,
164  SEND_TIMEOUT,
165  FAILED_STATE,
166  CONNECT_ERROR
167  } _type;
168 
169  SocketException(Type t,
170  const std::string& server,
171  int code = 9001,
172  const std::string& extra = "")
173  : DBException(std::string("socket exception [") + _getStringType(t) + "] for " + server,
174  code),
175  _type(t),
176  _server(server),
177  _extra(extra) {}
178 
179  virtual ~SocketException() throw() {}
180 
181  bool shouldPrint() const {
182  return _type != CLOSED;
183  }
184  virtual std::string toString() const;
185  virtual const std::string* server() const {
186  return &_server;
187  }
188 
189 private:
190  // TODO: Allow exceptions better control over their messages
191  static std::string _getStringType(Type t) {
192  switch (t) {
193  case CLOSED:
194  return "CLOSED";
195  case RECV_ERROR:
196  return "RECV_ERROR";
197  case SEND_ERROR:
198  return "SEND_ERROR";
199  case RECV_TIMEOUT:
200  return "RECV_TIMEOUT";
201  case SEND_TIMEOUT:
202  return "SEND_TIMEOUT";
203  case FAILED_STATE:
204  return "FAILED_STATE";
205  case CONNECT_ERROR:
206  return "CONNECT_ERROR";
207  default:
208  return "UNKNOWN"; // should never happen
209  }
210  }
211 
212  std::string _server;
213  std::string _extra;
214 };
215 
216 
221 class MONGO_CLIENT_API Socket {
222  MONGO_DISALLOW_COPYING(Socket);
223 
224 public:
225  static const int errorPollIntervalSecs;
226 
227  Socket(int sock, const SockAddr& farEnd);
228 
235  Socket(double so_timeout = 0, logger::LogSeverity logLevel = logger::LogSeverity::Log());
236 
237  ~Socket();
238 
247  bool connect(SockAddr& farEnd);
248 
249  void close();
250  void send(const char* data, int len, const char* context);
251  void send(const std::vector<std::pair<char*, int> >& data, const char* context);
252 
253  // recv len or throw SocketException
254  void recv(char* data, int len);
255  int unsafe_recv(char* buf, int max);
256 
257  logger::LogSeverity getLogLevel() const {
258  return _logLevel;
259  }
260  void setLogLevel(logger::LogSeverity ll) {
261  _logLevel = ll;
262  }
263 
264  SockAddr remoteAddr() const {
265  return _remote;
266  }
267  std::string remoteString() const {
268  return _remote.toString();
269  }
270  unsigned remotePort() const {
271  return _remote.getPort();
272  }
273 
274  SockAddr localAddr() const {
275  return _local;
276  }
277 
278  void clearCounters() {
279  _bytesIn = 0;
280  _bytesOut = 0;
281  }
282  long long getBytesIn() const {
283  return _bytesIn;
284  }
285  long long getBytesOut() const {
286  return _bytesOut;
287  }
288  int rawFD() const {
289  return _fd;
290  }
291 
292  void setTimeout(double secs);
293  bool isStillConnected();
294 
295  void setHandshakeReceived() {
296  _awaitingHandshake = false;
297  }
298 
299  bool isAwaitingHandshake() {
300  return _awaitingHandshake;
301  }
302 
303 #ifdef MONGO_SSL
304 
308  bool secure(SSLManagerInterface* ssl, const std::string& remoteHost);
309 
310  void secureAccepted(SSLManagerInterface* ssl);
311 #endif
312 
324  std::string doSSLHandshake(const char* firstBytes = NULL, int len = 0);
325 
329  uint64_t getSockCreationMicroSec() const {
330  return _fdCreationMicroSec;
331  }
332 
333  void handleRecvError(int ret, int len);
334  MONGO_COMPILER_NORETURN void handleSendError(int ret, const char* context);
335 
336 private:
337  void _init();
338 
340  void _send(const std::vector<std::pair<char*, int> >& data, const char* context);
341 
343  int _send(const char* data, int len, const char* context);
344 
346  int _recv(char* buf, int max);
347 
348  int _fd;
349  uint64_t _fdCreationMicroSec;
350  SockAddr _local;
351  SockAddr _remote;
352  double _timeout;
353 
354  long long _bytesIn;
355  long long _bytesOut;
356  time_t _lastValidityCheckAtSecs;
357 
358 #ifdef MONGO_SSL
359  boost::scoped_ptr<SSLConnection> _sslConnection;
360  SSLManagerInterface* _sslManager;
361 #endif
362  logger::LogSeverity _logLevel; // passed to log() when logging errors
363 
365  bool _awaitingHandshake;
366 };
367 
368 
369 } // namespace mongo
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
thrown by Socket and SockAddr
Definition: sock.h:157
wrapped around os representation of network address
Definition: sock.h:96
uint64_t getSockCreationMicroSec() const
Definition: sock.h:329
std::string getHostName()
this is not cache and does a syscall
thin wrapped around file descriptor and system calls todo: ssl
Definition: sock.h:221
Most mongo exceptions inherit from this; this is commonly caught in most threads. ...
Definition: assert_util.h:87
Representation of the severity / priority of a log message.
Definition: log_severity.h:33