endpoint.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // Copyright (c) 2011 Baidu.com, Inc. All Rights Reserved
  2. //
  3. // Wrappers of IP and port.
  4. //
  5. // Author: Ge,Jun (gejun@baidu.com)
  6. // Date: Mon. Nov 7 14:47:36 CST 2011
  7. #ifndef BRPC_BASE_ENDPOINT_H
  8. #define BRPC_BASE_ENDPOINT_H
  9. #include <netinet/in.h> // in_addr
  10. #include <iostream> // std::ostream
  11. #include "base/containers/hash_tables.h" // hashing functions
  12. namespace base {
  13. // Type of an IP address
  14. typedef struct in_addr ip_t;
  15. static const ip_t IP_ANY = { INADDR_ANY };
  16. static const ip_t IP_NONE = { INADDR_NONE };
  17. // Convert |ip| to an integral
  18. inline in_addr_t ip2int(ip_t ip) { return ip.s_addr; }
  19. // Convert integral |ip_value| to an IP
  20. inline ip_t int2ip(in_addr_t ip_value) {
  21. const ip_t ip = { ip_value };
  22. return ip;
  23. }
  24. // Convert string `ip_str' to ip_t *ip.
  25. // `ip_str' is in IPv4 dotted-quad format: `127.0.0.1', `10.23.249.73' ...
  26. // Returns 0 on success, -1 otherwise.
  27. int str2ip(const char* ip_str, ip_t* ip);
  28. struct IPStr {
  29. const char* c_str() const { return _buf; }
  30. char _buf[INET_ADDRSTRLEN];
  31. };
  32. // Convert IP to c-style string. Notice that you can serialize ip_t to
  33. // std::ostream directly. Use this function when you don't have streaming log.
  34. // Example: printf("ip=%s\n", ip2str(some_ip).c_str());
  35. IPStr ip2str(ip_t ip);
  36. // Convert `hostname' to ip_t *ip. If `hostname' is NULL, use hostname
  37. // of this machine.
  38. // `hostname' is typically in this form: `tc-cm-et21.tc' `db-cos-dev.db01' ...
  39. // Returns 0 on success, -1 otherwise.
  40. int hostname2ip(const char* hostname, ip_t* ip);
  41. // Convert `ip' to `hostname'.
  42. // Returns 0 on success, -1 otherwise and errno is set.
  43. int ip2hostname(ip_t ip, char* hostname, size_t hostname_len);
  44. int ip2hostname(ip_t ip, std::string* hostname);
  45. // Hostname of this machine, "" on error.
  46. // NOTE: This function caches result on first call.
  47. const char* my_hostname();
  48. // IP of this machine, IP_ANY on error.
  49. // NOTE: This function caches result on first call.
  50. ip_t my_ip();
  51. // String form.
  52. const char* my_ip_cstr();
  53. // ipv4 + port
  54. struct EndPoint {
  55. EndPoint() : ip(IP_ANY), port(0) {}
  56. EndPoint(ip_t ip2, int port2) : ip(ip2), port(port2) {}
  57. explicit EndPoint(const sockaddr_in& in)
  58. : ip(in.sin_addr), port(ntohs(in.sin_port)) {}
  59. ip_t ip;
  60. int port;
  61. };
  62. struct EndPointStr {
  63. const char* c_str() const { return _buf; }
  64. char _buf[INET_ADDRSTRLEN + 16];
  65. };
  66. // Convert EndPoint to c-style string. Notice that you can serialize
  67. // EndPoint to std::ostream directly. Use this function when you don't
  68. // have streaming log.
  69. // Example: printf("point=%s\n", endpoint2str(point).c_str());
  70. EndPointStr endpoint2str(const EndPoint&);
  71. // Convert string `ip_and_port_str' to a EndPoint *point.
  72. // Returns 0 on success, -1 otherwise.
  73. int str2endpoint(const char* ip_and_port_str, EndPoint* point);
  74. int str2endpoint(const char* ip_str, int port, EndPoint* point);
  75. // Convert `hostname_and_port_str' to a EndPoint *point.
  76. // Returns 0 on success, -1 otherwise.
  77. int hostname2endpoint(const char* ip_and_port_str, EndPoint* point);
  78. int hostname2endpoint(const char* name_str, int port, EndPoint* point);
  79. // Convert `endpoint' to `hostname'.
  80. // Returns 0 on success, -1 otherwise and errno is set.
  81. int endpoint2hostname(const EndPoint& point, char* hostname, size_t hostname_len);
  82. int endpoint2hostname(const EndPoint& point, std::string* host);
  83. // Create a TCP socket and connect it to `server'. Write port of this side
  84. // into `self_port' if it's not NULL.
  85. // Returns the socket descriptor, -1 otherwise and errno is set.
  86. int tcp_connect(EndPoint server, int* self_port);
  87. // Create and listen to a TCP socket bound with `ip_and_port'. If `reuse_addr'
  88. // is true, ports in TIME_WAIT will be bound as well.
  89. // Returns the socket descriptor, -1 otherwise and errno is set.
  90. int tcp_listen(EndPoint ip_and_port, bool reuse_addr);
  91. // Get the local end of a socket connection
  92. int get_local_side(int fd, EndPoint *out);
  93. // Get the other end of a socket connection
  94. int get_remote_side(int fd, EndPoint *out);
  95. } // namespace base
  96. // Since ip_t is defined from in_addr which is globally defined, due to ADL
  97. // we have to put overloaded operators globally as well.
  98. inline bool operator<(base::ip_t lhs, base::ip_t rhs) {
  99. return base::ip2int(lhs) < base::ip2int(rhs);
  100. }
  101. inline bool operator>(base::ip_t lhs, base::ip_t rhs) {
  102. return rhs < lhs;
  103. }
  104. inline bool operator>=(base::ip_t lhs, base::ip_t rhs) {
  105. return !(lhs < rhs);
  106. }
  107. inline bool operator<=(base::ip_t lhs, base::ip_t rhs) {
  108. return !(rhs < lhs);
  109. }
  110. inline bool operator==(base::ip_t lhs, base::ip_t rhs) {
  111. return base::ip2int(lhs) == base::ip2int(rhs);
  112. }
  113. inline bool operator!=(base::ip_t lhs, base::ip_t rhs) {
  114. return !(lhs == rhs);
  115. }
  116. inline std::ostream& operator<<(std::ostream& os, const base::IPStr& ip_str) {
  117. return os << ip_str.c_str();
  118. }
  119. inline std::ostream& operator<<(std::ostream& os, base::ip_t ip) {
  120. return os << base::ip2str(ip);
  121. }
  122. namespace base {
  123. // Overload operators for EndPoint in the same namespace due to ADL.
  124. inline bool operator<(EndPoint p1, EndPoint p2) {
  125. return (p1.ip != p2.ip) ? (p1.ip < p2.ip) : (p1.port < p2.port);
  126. }
  127. inline bool operator>(EndPoint p1, EndPoint p2) {
  128. return p2 < p1;
  129. }
  130. inline bool operator<=(EndPoint p1, EndPoint p2) {
  131. return !(p2 < p1);
  132. }
  133. inline bool operator>=(EndPoint p1, EndPoint p2) {
  134. return !(p1 < p2);
  135. }
  136. inline bool operator==(EndPoint p1, EndPoint p2) {
  137. return p1.ip == p2.ip && p1.port == p2.port;
  138. }
  139. inline bool operator!=(EndPoint p1, EndPoint p2) {
  140. return !(p1 == p2);
  141. }
  142. inline std::ostream& operator<<(std::ostream& os, const EndPoint& ep) {
  143. return os << ep.ip << ':' << ep.port;
  144. }
  145. inline std::ostream& operator<<(std::ostream& os, const EndPointStr& ep_str) {
  146. return os << ep_str.c_str();
  147. }
  148. } // namespace base
  149. namespace BASE_HASH_NAMESPACE {
  150. // Implement methods for hashing a pair of integers, so they can be used as
  151. // keys in STL containers.
  152. #if defined(COMPILER_MSVC)
  153. inline std::size_t hash_value(const base::EndPoint& ep) {
  154. return base::HashPair(base::ip2int(ep.ip), ep.port);
  155. }
  156. #elif defined(COMPILER_GCC)
  157. template <>
  158. struct hash<base::EndPoint> {
  159. std::size_t operator()(const base::EndPoint& ep) const {
  160. return base::HashPair(base::ip2int(ep.ip), ep.port);
  161. }
  162. };
  163. #else
  164. #error define hash<EndPoint> for your compiler
  165. #endif // COMPILER
  166. }
  167. #endif // BRPC_BASE_ENDPOINT_H