MongoDB  2.6.0
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 <stdio.h>
21 
22 #ifndef _WIN32
23 
24 #include <sys/socket.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <errno.h>
29 
30 #ifdef __openbsd__
31 # include <sys/uio.h>
32 #endif
33 
34 #endif // not _WIN32
35 
36 #include <boost/scoped_ptr.hpp>
37 #include <string>
38 #include <utility>
39 #include <vector>
40 
41 #include "mongo/base/disallow_copying.h"
42 #include "mongo/logger/log_severity.h"
43 #include "mongo/platform/compiler.h"
44 #include "mongo/platform/cstdint.h"
45 #include "mongo/util/assert_util.h"
46 
47 namespace mongo {
48 
49 #ifdef MONGO_SSL
50  class SSLManagerInterface;
51  class SSLConnection;
52 #endif
53 
54  extern const int portSendFlags;
55  extern const int portRecvFlags;
56 
57  const int SOCK_FAMILY_UNKNOWN_ERROR=13078;
58 
59  void disableNagle(int sock);
60 
61 #if defined(_WIN32)
62 
63  typedef short sa_family_t;
64  typedef int socklen_t;
65 
66  // This won't actually be used on windows
67  struct sockaddr_un {
68  short sun_family;
69  char sun_path[108]; // length from unix header
70  };
71 
72 #else // _WIN32
73 
74  inline void closesocket(int s) { close(s); }
75  const int INVALID_SOCKET = -1;
76  typedef int SOCKET;
77 
78 #endif // _WIN32
79 
80  std::string makeUnixSockPath(int port);
81 
82  // If an ip address is passed in, just return that. If a hostname is passed
83  // in, look up its ip and return that. Returns "" on failure.
84  std::string hostbyname(const char *hostname);
85 
86  void enableIPv6(bool state=true);
87  bool IPv6Enabled();
88  void setSockTimeouts(int sock, double secs);
89 
93  struct SockAddr {
94  SockAddr() {
95  addressSize = sizeof(sa);
96  memset(&sa, 0, sizeof(sa));
97  sa.ss_family = AF_UNSPEC;
98  }
99  explicit SockAddr(int sourcePort); /* listener side */
100  SockAddr(const char *ip, int port); /* EndPoint (remote) side, or if you want to specify which interface locally */
101 
102  template <typename T> T& as() { return *(T*)(&sa); }
103  template <typename T> const T& as() const { return *(const T*)(&sa); }
104 
105  std::string toString(bool includePort=true) const;
106 
110  sa_family_t getType() const;
111 
112  unsigned getPort() const;
113 
114  std::string getAddr() const;
115 
116  bool isLocalHost() const;
117 
118  bool operator==(const SockAddr& r) const;
119 
120  bool operator!=(const SockAddr& r) const;
121 
122  bool operator<(const SockAddr& r) const;
123 
124  const sockaddr* raw() const {return (sockaddr*)&sa;}
125  sockaddr* raw() {return (sockaddr*)&sa;}
126 
127  socklen_t addressSize;
128  private:
129  struct sockaddr_storage sa;
130  };
131 
132  extern SockAddr unknownAddress; // ( "0.0.0.0", 0 )
133 
135  std::string getHostName();
136 
139  std::string getHostNameCached();
140 
141  std::string prettyHostName();
142 
146  class SocketException : public DBException {
147  public:
148  const enum Type { CLOSED , RECV_ERROR , SEND_ERROR, RECV_TIMEOUT, SEND_TIMEOUT, FAILED_STATE, CONNECT_ERROR } _type;
149 
150  SocketException( Type t , const std::string& server , int code = 9001 , const std::string& extra="" )
151  : DBException( std::string("socket exception [") + _getStringType( t ) + "] for " + server, code ),
152  _type(t),
153  _server(server),
154  _extra(extra)
155  {}
156 
157  virtual ~SocketException() throw() {}
158 
159  bool shouldPrint() const { return _type != CLOSED; }
160  virtual std::string toString() const;
161  virtual const std::string* server() const { return &_server; }
162  private:
163 
164  // TODO: Allow exceptions better control over their messages
165  static std::string _getStringType( Type t ){
166  switch (t) {
167  case CLOSED: return "CLOSED";
168  case RECV_ERROR: return "RECV_ERROR";
169  case SEND_ERROR: return "SEND_ERROR";
170  case RECV_TIMEOUT: return "RECV_TIMEOUT";
171  case SEND_TIMEOUT: return "SEND_TIMEOUT";
172  case FAILED_STATE: return "FAILED_STATE";
173  case CONNECT_ERROR: return "CONNECT_ERROR";
174  default: return "UNKNOWN"; // should never happen
175  }
176  }
177 
178  std::string _server;
179  std::string _extra;
180  };
181 
182 
187  class Socket {
188  MONGO_DISALLOW_COPYING(Socket);
189  public:
190 
191  static const int errorPollIntervalSecs;
192 
193  Socket(int sock, const SockAddr& farEnd);
194 
201  Socket(double so_timeout = 0, logger::LogSeverity logLevel = logger::LogSeverity::Log() );
202 
203  ~Socket();
204 
205  bool connect(SockAddr& farEnd);
206  void close();
207  void send( const char * data , int len, const char *context );
208  void send( const std::vector< std::pair< char *, int > > &data, const char *context );
209 
210  // recv len or throw SocketException
211  void recv( char * data , int len );
212  int unsafe_recv( char *buf, int max );
213 
214  logger::LogSeverity getLogLevel() const { return _logLevel; }
215  void setLogLevel( logger::LogSeverity ll ) { _logLevel = ll; }
216 
217  SockAddr remoteAddr() const { return _remote; }
218  std::string remoteString() const { return _remote.toString(); }
219  unsigned remotePort() const { return _remote.getPort(); }
220 
221  SockAddr localAddr() const { return _local; }
222 
223  void clearCounters() { _bytesIn = 0; _bytesOut = 0; }
224  long long getBytesIn() const { return _bytesIn; }
225  long long getBytesOut() const { return _bytesOut; }
226  int rawFD() const { return _fd; }
227 
228  void setTimeout( double secs );
229  bool isStillConnected();
230 
231  void setHandshakeReceived() {
232  _awaitingHandshake = false;
233  }
234 
235  bool isAwaitingHandshake() {
236  return _awaitingHandshake;
237  }
238 
239 #ifdef MONGO_SSL
240 
244  bool secure( SSLManagerInterface* ssl, const std::string& remoteHost);
245 
246  void secureAccepted( SSLManagerInterface* ssl );
247 #endif
248 
260  std::string doSSLHandshake(const char* firstBytes = NULL, int len = 0);
261 
265  uint64_t getSockCreationMicroSec() const {
266  return _fdCreationMicroSec;
267  }
268 
269  void handleRecvError(int ret, int len);
270  MONGO_COMPILER_NORETURN void handleSendError(int ret, const char* context);
271 
272  private:
273  void _init();
274 
276  void _send( const std::vector< std::pair< char *, int > > &data, const char *context );
277 
279  int _send( const char * data , int len , const char * context );
280 
282  int _recv( char * buf , int max );
283 
284  int _fd;
285  uint64_t _fdCreationMicroSec;
286  SockAddr _local;
287  SockAddr _remote;
288  double _timeout;
289 
290  long long _bytesIn;
291  long long _bytesOut;
292  time_t _lastValidityCheckAtSecs;
293 
294 #ifdef MONGO_SSL
295  boost::scoped_ptr<SSLConnection> _sslConnection;
296  SSLManagerInterface* _sslManager;
297 #endif
298  logger::LogSeverity _logLevel; // passed to log() when logging errors
299 
301  bool _awaitingHandshake;
302 
303  };
304 
305 
306 } // namespace mongo
Most mongo exceptions inherit from this; this is commonly caught in most threads. ...
Definition: assert_util.h:97
thin wrapped around file descriptor and system calls todo: ssl
Definition: sock.h:187
sa_family_t getType() const
Definition: sock.cpp:224
wrapped around os representation of network address
Definition: sock.h:93
std::string doSSLHandshake(const char *firstBytes=NULL, int len=0)
This function calls SSL_accept() if SSL-encrypted sockets are desired.
thrown by Socket and SockAddr
Definition: sock.h:146
string getHostNameCached()
we store our host name once
Definition: sock.cpp:348
string getHostName()
this is not cache and does a syscall
Definition: sock.cpp:337
uint64_t getSockCreationMicroSec() const
Definition: sock.h:265