/src/mongo/util/net/hostandport.h

https://github.com/tadmarshall/mongo · C Header · 188 lines · 129 code · 33 blank · 26 comment · 29 complexity · a180ff3535b590c2056a56fabde10526 MD5 · raw file

  1. // hostandport.h
  2. /* Copyright 2009 10gen Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include "mongo/bson/util/builder.h"
  18. #include "mongo/db/cmdline.h"
  19. #include "mongo/util/mongoutils/str.h"
  20. #include "mongo/util/net/sock.h"
  21. namespace mongo {
  22. using namespace mongoutils;
  23. /** helper for manipulating host:port connection endpoints.
  24. */
  25. struct HostAndPort {
  26. HostAndPort() : _port(-1) { }
  27. /** From a string hostname[:portnumber]
  28. Throws user assertion if bad config string or bad port #.
  29. */
  30. HostAndPort(const std::string& s);
  31. /** @param p port number. -1 is ok to use default. */
  32. HostAndPort(const std::string& h, int p /*= -1*/) : _host(h), _port(p) {
  33. verify( !str::startsWith(h, '#') );
  34. }
  35. HostAndPort(const SockAddr& sock ) : _host( sock.getAddr() ) , _port( sock.getPort() ) { }
  36. static HostAndPort me();
  37. bool operator<(const HostAndPort& r) const {
  38. string h = host();
  39. string rh = r.host();
  40. if( h < rh )
  41. return true;
  42. if( h == rh )
  43. return port() < r.port();
  44. return false;
  45. }
  46. bool operator==(const HostAndPort& r) const {
  47. return host() == r.host() && port() == r.port();
  48. }
  49. bool operator!=(const HostAndPort& r) const { return !(*this == r); }
  50. /* returns true if the host/port combo identifies this process instance. */
  51. bool isSelf() const; // defined in isself.cpp
  52. bool isLocalHost() const;
  53. /**
  54. * @param includePort host:port if true, host otherwise
  55. */
  56. string toString( bool includePort=true ) const;
  57. operator string() const { return toString(); }
  58. void append( StringBuilder& ss ) const;
  59. bool empty() const {
  60. return _host.empty() && _port < 0;
  61. }
  62. string host() const {
  63. return _host;
  64. }
  65. int port() const {
  66. if (hasPort())
  67. return _port;
  68. return CmdLine::DefaultDBPort;
  69. }
  70. bool hasPort() const {
  71. return _port >= 0;
  72. }
  73. void setPort( int port ) {
  74. _port = port;
  75. }
  76. private:
  77. void init(const char *);
  78. string _host;
  79. int _port; // -1 indicates unspecified
  80. };
  81. inline HostAndPort HostAndPort::me() {
  82. const char* ips = cmdLine.bind_ip.c_str();
  83. while(*ips) {
  84. string ip;
  85. const char * comma = strchr(ips, ',');
  86. if (comma) {
  87. ip = string(ips, comma - ips);
  88. ips = comma + 1;
  89. }
  90. else {
  91. ip = string(ips);
  92. ips = "";
  93. }
  94. HostAndPort h = HostAndPort(ip, cmdLine.port);
  95. if (!h.isLocalHost()) {
  96. return h;
  97. }
  98. }
  99. string h = getHostName();
  100. verify( !h.empty() );
  101. verify( h != "localhost" );
  102. return HostAndPort(h, cmdLine.port);
  103. }
  104. inline string HostAndPort::toString( bool includePort ) const {
  105. if ( ! includePort )
  106. return host();
  107. StringBuilder ss;
  108. append( ss );
  109. return ss.str();
  110. }
  111. inline void HostAndPort::append( StringBuilder& ss ) const {
  112. ss << host();
  113. int p = port();
  114. if ( p != -1 ) {
  115. ss << ':';
  116. #if defined(_DEBUG)
  117. if( p >= 44000 && p < 44100 ) {
  118. log() << "warning: special debug port 44xxx used" << endl;
  119. ss << p+1;
  120. }
  121. else
  122. ss << p;
  123. #else
  124. ss << p;
  125. #endif
  126. }
  127. }
  128. inline bool HostAndPort::isLocalHost() const {
  129. string _host = host();
  130. return ( _host == "localhost"
  131. || startsWith(_host.c_str(), "127.")
  132. || _host == "::1"
  133. || _host == "anonymous unix socket"
  134. || _host.c_str()[0] == '/' // unix socket
  135. );
  136. }
  137. inline void HostAndPort::init(const char *p) {
  138. massert(13110, "HostAndPort: host is empty", *p);
  139. const char *colon = strrchr(p, ':');
  140. if( colon ) {
  141. int port = atoi(colon+1);
  142. massert(13095, "HostAndPort: bad port #", port > 0);
  143. _host = string(p,colon-p);
  144. _port = port;
  145. }
  146. else {
  147. // no port specified.
  148. _host = p;
  149. _port = -1;
  150. }
  151. }
  152. inline HostAndPort::HostAndPort(const std::string& s) {
  153. init(s.c_str());
  154. }
  155. }