00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #pragma once
00019
00020 #include "sock.h"
00021 #include "../db/cmdline.h"
00022 #include "mongoutils/str.h"
00023
00024 namespace mongo {
00025
00026 using namespace mongoutils;
00027
00030 struct HostAndPort {
00031 HostAndPort() : _port(-1) { }
00032
00036 HostAndPort(string s);
00037
00039 HostAndPort(string h, int p ) : _host(h), _port(p) { }
00040
00041 HostAndPort(const SockAddr& sock )
00042 : _host( sock.getAddr() ) , _port( sock.getPort() ) {
00043 }
00044
00045 static HostAndPort me() {
00046 return HostAndPort("localhost", cmdLine.port);
00047 }
00048
00049
00050 static HostAndPort Me();
00051
00052 bool operator<(const HostAndPort& r) const {
00053 if( _host < r._host )
00054 return true;
00055 if( _host == r._host )
00056 return port() < r.port();
00057 return false;
00058 }
00059
00060 bool operator==(const HostAndPort& r) const {
00061 return _host == r._host && port() == r.port();
00062 }
00063
00064 bool operator!=(const HostAndPort& r) const {
00065 return _host != r._host || port() != r.port();
00066 }
00067
00068
00069 bool isSelf() const;
00070
00071 bool isLocalHost() const;
00072
00073
00074 string toString() const;
00075
00076 operator string() const { return toString(); }
00077
00078 string host() const { return _host; }
00079
00080 int port() const { return _port >= 0 ? _port : CmdLine::DefaultDBPort; }
00081 bool hasPort() const { return _port >= 0; }
00082 void setPort( int port ) { _port = port; }
00083
00084 private:
00085
00086 string _host;
00087 int _port;
00088 };
00089
00093 inline bool sameHostname(const string& a, const string& b) {
00094 size_t prefixLen = str::shareCommonPrefix(a.c_str(), b.c_str());
00095
00096 if (prefixLen == a.size()) {
00097 if ( b[prefixLen] == '.' || b[prefixLen] == '\0')
00098 return true;
00099 }
00100 else if(prefixLen == b.size()) {
00101 if ( a[prefixLen] == '.')
00102 return true;
00103 }
00104
00105 return false;
00106 }
00107
00108 inline HostAndPort HostAndPort::Me() {
00109 const char* ips = cmdLine.bind_ip.c_str();
00110 while(*ips) {
00111 string ip;
00112 const char * comma = strchr(ips, ',');
00113 if (comma) {
00114 ip = string(ips, comma - ips);
00115 ips = comma + 1;
00116 }
00117 else {
00118 ip = string(ips);
00119 ips = "";
00120 }
00121 HostAndPort h = HostAndPort(ip, cmdLine.port);
00122 if (!h.isLocalHost()) {
00123 return h;
00124 }
00125 }
00126
00127 string h = getHostName();
00128 assert( !h.empty() );
00129 assert( h != "localhost" );
00130 return HostAndPort(h, cmdLine.port);
00131 }
00132
00133 inline string HostAndPort::toString() const {
00134 stringstream ss;
00135 ss << _host;
00136 if ( _port != -1 ) {
00137 ss << ':';
00138 #if defined(_DEBUG)
00139 if( _port >= 44000 && _port < 44100 ) {
00140 log() << "warning: special debug port 44xxx used" << endl;
00141 ss << _port+1;
00142 }
00143 else
00144 ss << _port;
00145 #else
00146 ss << _port;
00147 #endif
00148 }
00149 return ss.str();
00150 }
00151
00152 inline bool HostAndPort::isLocalHost() const {
00153 return _host == "localhost" || startsWith(_host.c_str(), "127.") || _host == "::1";
00154 }
00155
00156 inline HostAndPort::HostAndPort(string s) {
00157 const char *p = s.c_str();
00158 uassert(13110, "HostAndPort: bad config string", *p);
00159 const char *colon = strrchr(p, ':');
00160 if( colon ) {
00161 int port = atoi(colon+1);
00162 uassert(13095, "HostAndPort: bad port #", port > 0);
00163 _host = string(p,colon-p);
00164 _port = port;
00165 }
00166 else {
00167
00168 _host = p;
00169 _port = -1;
00170 }
00171 }
00172
00173 }