00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #pragma once
00019
00020 #include "../../pch.h"
00021
00022 #include <stdio.h>
00023 #include <sstream>
00024 #include "../goodies.h"
00025 #include "../../db/cmdline.h"
00026 #include "../mongoutils/str.h"
00027
00028 #ifndef _WIN32
00029
00030 #include <sys/socket.h>
00031 #include <sys/types.h>
00032 #include <sys/socket.h>
00033 #include <sys/un.h>
00034 #include <errno.h>
00035
00036 #ifdef __openbsd__
00037 # include <sys/uio.h>
00038 #endif
00039
00040 #endif // _WIN32
00041
00042 #ifdef MONGO_SSL
00043 #include <openssl/ssl.h>
00044 #endif
00045
00046 namespace mongo {
00047
00048 const int SOCK_FAMILY_UNKNOWN_ERROR=13078;
00049
00050 void disableNagle(int sock);
00051
00052 #if defined(_WIN32)
00053
00054 typedef short sa_family_t;
00055 typedef int socklen_t;
00056
00057
00058 struct sockaddr_un {
00059 short sun_family;
00060 char sun_path[108];
00061 };
00062
00063 #else // _WIN32
00064
00065 inline void closesocket(int s) { close(s); }
00066 const int INVALID_SOCKET = -1;
00067 typedef int SOCKET;
00068
00069 #endif // _WIN32
00070
00071 inline string makeUnixSockPath(int port) {
00072 return mongoutils::str::stream() << cmdLine.socket << "/mongodb-" << port << ".sock";
00073 }
00074
00075
00076
00077 string hostbyname(const char *hostname);
00078
00079 void enableIPv6(bool state=true);
00080 bool IPv6Enabled();
00081 void setSockTimeouts(int sock, double secs);
00082
00086 struct SockAddr {
00087 SockAddr() {
00088 addressSize = sizeof(sa);
00089 memset(&sa, 0, sizeof(sa));
00090 sa.ss_family = AF_UNSPEC;
00091 }
00092 SockAddr(int sourcePort);
00093 SockAddr(const char *ip, int port);
00094
00095 template <typename T> T& as() { return *(T*)(&sa); }
00096 template <typename T> const T& as() const { return *(const T*)(&sa); }
00097
00098 string toString(bool includePort=true) const;
00099
00103 sa_family_t getType() const;
00104
00105 unsigned getPort() const;
00106
00107 string getAddr() const;
00108
00109 bool isLocalHost() const;
00110
00111 bool operator==(const SockAddr& r) const;
00112
00113 bool operator!=(const SockAddr& r) const;
00114
00115 bool operator<(const SockAddr& r) const;
00116
00117 const sockaddr* raw() const {return (sockaddr*)&sa;}
00118 sockaddr* raw() {return (sockaddr*)&sa;}
00119
00120 socklen_t addressSize;
00121 private:
00122 struct sockaddr_storage sa;
00123 };
00124
00125 extern SockAddr unknownAddress;
00126
00128 string getHostName();
00129
00132 string getHostNameCached();
00133
00137 class SocketException : public DBException {
00138 public:
00139 const enum Type { CLOSED , RECV_ERROR , SEND_ERROR, RECV_TIMEOUT, SEND_TIMEOUT, FAILED_STATE, CONNECT_ERROR } _type;
00140
00141 SocketException( Type t , string server , int code = 9001 , string extra="" )
00142 : DBException( "socket exception" , code ) , _type(t) , _server(server), _extra(extra){ }
00143 virtual ~SocketException() throw() {}
00144
00145 bool shouldPrint() const { return _type != CLOSED; }
00146 virtual string toString() const;
00147
00148 private:
00149 string _server;
00150 string _extra;
00151 };
00152
00153 #ifdef MONGO_SSL
00154 class SSLManager : boost::noncopyable {
00155 public:
00156 SSLManager( bool client );
00157
00158 void setupPEM( const string& keyFile , const string& password );
00159 void setupPubPriv( const string& privateKeyFile , const string& publicKeyFile );
00160
00165 SSL * secure( int fd );
00166
00167 static int password_cb( char *buf,int num, int rwflag,void *userdata );
00168
00169 private:
00170 bool _client;
00171 SSL_CTX* _context;
00172 string _password;
00173 };
00174 #endif
00175
00180 class Socket {
00181 public:
00182 Socket(int sock, const SockAddr& farEnd);
00183
00190 Socket(double so_timeout = 0, int logLevel = 0 );
00191
00192 bool connect(SockAddr& farEnd);
00193 void close();
00194
00195 void send( const char * data , int len, const char *context );
00196 void send( const vector< pair< char *, int > > &data, const char *context );
00197
00198
00199 void recv( char * data , int len );
00200 int unsafe_recv( char *buf, int max );
00201
00202 int getLogLevel() const { return _logLevel; }
00203 void setLogLevel( int ll ) { _logLevel = ll; }
00204
00205 SockAddr remoteAddr() const { return _remote; }
00206 string remoteString() const { return _remote.toString(); }
00207 unsigned remotePort() const { return _remote.getPort(); }
00208
00209 void clearCounters() { _bytesIn = 0; _bytesOut = 0; }
00210 long long getBytesIn() const { return _bytesIn; }
00211 long long getBytesOut() const { return _bytesOut; }
00212
00213 void setTimeout( double secs );
00214
00215 #ifdef MONGO_SSL
00216
00217 void secure( SSLManager * ssl );
00218
00219 void secureAccepted( SSLManager * ssl );
00220 #endif
00221
00225 void postFork();
00226
00227 private:
00228 void _init();
00230 int _send( const char * data , int len );
00231
00233 void _send( const vector< pair< char *, int > > &data, const char *context );
00234
00236 int _recv( char * buf , int max );
00237
00238 int _fd;
00239 SockAddr _remote;
00240 double _timeout;
00241
00242 long long _bytesIn;
00243 long long _bytesOut;
00244
00245 #ifdef MONGO_SSL
00246 shared_ptr<SSL> _ssl;
00247 SSLManager * _sslAccepted;
00248 #endif
00249
00250 protected:
00251 int _logLevel;
00252
00253 };
00254
00255
00256 }