MongoDB C++ Driver  legacy-1.0.3
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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) { close(s); }
78  const int INVALID_SOCKET = -1;
79  typedef int SOCKET;
80 
81 #endif // _WIN32
82 
83  // If an ip address is passed in, just return that. If a hostname is passed
84  // in, look up its ip and return that. Returns "" on failure.
85  std::string hostbyname(const char *hostname);
86 
87  void enableIPv6(bool state=true);
88  bool IPv6Enabled();
89  void setSockTimeouts(int sock, double secs);
90 
94  struct MONGO_CLIENT_API SockAddr {
95  SockAddr();
96  explicit SockAddr(int sourcePort); /* listener side */
97  SockAddr(const char *ip, int port); /* EndPoint (remote) side, or if you want to specify which interface locally */
98 
99  template <typename T> T& as() { return *(T*)(&sa); }
100  template <typename T> const T& as() const { return *(const T*)(&sa); }
101 
102  std::string toString(bool includePort=true) const;
103 
104  bool isValid() const { return _isValid; }
105 
109  sa_family_t getType() const;
110 
111  unsigned getPort() const;
112 
113  std::string getAddr() const;
114 
115  bool isLocalHost() const;
116 
117  bool operator==(const SockAddr& r) const;
118 
119  bool operator!=(const SockAddr& r) const;
120 
121  bool operator<(const SockAddr& r) const;
122 
123  const sockaddr* raw() const {return (sockaddr*)&sa;}
124  sockaddr* raw() {return (sockaddr*)&sa;}
125 
126  socklen_t addressSize;
127  private:
128  struct sockaddr_storage sa;
129  bool _isValid;
130  };
131 
132  extern SockAddr unknownAddress; // ( "0.0.0.0", 0 )
133 
135  std::string getHostName();
136 
140  class MONGO_CLIENT_API SocketException : public DBException {
141  public:
142  const enum Type { CLOSED , RECV_ERROR , SEND_ERROR, RECV_TIMEOUT, SEND_TIMEOUT, FAILED_STATE, CONNECT_ERROR } _type;
143 
144  SocketException( Type t , const std::string& server , int code = 9001 , const std::string& extra="" )
145  : DBException( std::string("socket exception [") + _getStringType( t ) + "] for " + server, code ),
146  _type(t),
147  _server(server),
148  _extra(extra)
149  {}
150 
151  virtual ~SocketException() throw() {}
152 
153  bool shouldPrint() const { return _type != CLOSED; }
154  virtual std::string toString() const;
155  virtual const std::string* server() const { return &_server; }
156  private:
157 
158  // TODO: Allow exceptions better control over their messages
159  static std::string _getStringType( Type t ){
160  switch (t) {
161  case CLOSED: return "CLOSED";
162  case RECV_ERROR: return "RECV_ERROR";
163  case SEND_ERROR: return "SEND_ERROR";
164  case RECV_TIMEOUT: return "RECV_TIMEOUT";
165  case SEND_TIMEOUT: return "SEND_TIMEOUT";
166  case FAILED_STATE: return "FAILED_STATE";
167  case CONNECT_ERROR: return "CONNECT_ERROR";
168  default: return "UNKNOWN"; // should never happen
169  }
170  }
171 
172  std::string _server;
173  std::string _extra;
174  };
175 
176 
181  class MONGO_CLIENT_API Socket {
182  MONGO_DISALLOW_COPYING(Socket);
183  public:
184 
185  static const int errorPollIntervalSecs;
186 
187  Socket(int sock, const SockAddr& farEnd);
188 
195  Socket(double so_timeout = 0, logger::LogSeverity logLevel = logger::LogSeverity::Log() );
196 
197  ~Socket();
198 
207  bool connect(SockAddr& farEnd);
208 
209  void close();
210  void send( const char * data , int len, const char *context );
211  void send( const std::vector< std::pair< char *, int > > &data, const char *context );
212 
213  // recv len or throw SocketException
214  void recv( char * data , int len );
215  int unsafe_recv( char *buf, int max );
216 
217  logger::LogSeverity getLogLevel() const { return _logLevel; }
218  void setLogLevel( logger::LogSeverity ll ) { _logLevel = ll; }
219 
220  SockAddr remoteAddr() const { return _remote; }
221  std::string remoteString() const { return _remote.toString(); }
222  unsigned remotePort() const { return _remote.getPort(); }
223 
224  SockAddr localAddr() const { return _local; }
225 
226  void clearCounters() { _bytesIn = 0; _bytesOut = 0; }
227  long long getBytesIn() const { return _bytesIn; }
228  long long getBytesOut() const { return _bytesOut; }
229  int rawFD() const { return _fd; }
230 
231  void setTimeout( double secs );
232  bool isStillConnected();
233 
234  void setHandshakeReceived() {
235  _awaitingHandshake = false;
236  }
237 
238  bool isAwaitingHandshake() {
239  return _awaitingHandshake;
240  }
241 
242 #ifdef MONGO_SSL
243 
247  bool secure( SSLManagerInterface* ssl, const std::string& remoteHost);
248 
249  void secureAccepted( SSLManagerInterface* ssl );
250 #endif
251 
263  std::string doSSLHandshake(const char* firstBytes = NULL, int len = 0);
264 
268  uint64_t getSockCreationMicroSec() const {
269  return _fdCreationMicroSec;
270  }
271 
272  void handleRecvError(int ret, int len);
273  MONGO_COMPILER_NORETURN void handleSendError(int ret, const char* context);
274 
275  private:
276  void _init();
277 
279  void _send( const std::vector< std::pair< char *, int > > &data, const char *context );
280 
282  int _send( const char * data , int len , const char * context );
283 
285  int _recv( char * buf , int max );
286 
287  int _fd;
288  uint64_t _fdCreationMicroSec;
289  SockAddr _local;
290  SockAddr _remote;
291  double _timeout;
292 
293  long long _bytesIn;
294  long long _bytesOut;
295  time_t _lastValidityCheckAtSecs;
296 
297 #ifdef MONGO_SSL
298  boost::scoped_ptr<SSLConnection> _sslConnection;
299  SSLManagerInterface* _sslManager;
300 #endif
301  logger::LogSeverity _logLevel; // passed to log() when logging errors
302 
304  bool _awaitingHandshake;
305 
306  };
307 
308 
309 } // namespace mongo
the main MongoDB namespace
Definition: bulk_operation_builder.h:24
thrown by Socket and SockAddr
Definition: sock.h:140
wrapped around os representation of network address
Definition: sock.h:94
uint64_t getSockCreationMicroSec() const
Definition: sock.h:268
std::string getHostName()
this is not cache and does a syscall
thin wrapped around file descriptor and system calls todo: ssl
Definition: sock.h:181
Most mongo exceptions inherit from this; this is commonly caught in most threads. ...
Definition: assert_util.h:81