address.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include <util/stream/str.h>
  2. #include "address.h"
  3. #if defined(_unix_)
  4. #include <sys/un.h>
  5. #endif
  6. #ifndef UNIX_PATH_MAX
  7. inline constexpr size_t UNIX_PATH_LIMIT = 108;
  8. #else
  9. inline constexpr size_t UNIX_PATH_LIMIT = UNIX_PATH_MAX;
  10. #endif
  11. using namespace NAddr;
  12. template <bool printPort>
  13. static inline void PrintAddr(IOutputStream& out, const IRemoteAddr& addr) {
  14. const sockaddr* a = addr.Addr();
  15. char buf[INET6_ADDRSTRLEN + 10];
  16. switch (a->sa_family) {
  17. case AF_INET: {
  18. const TIpAddress sa(*(const sockaddr_in*)a);
  19. out << IpToString(sa.Host(), buf, sizeof(buf));
  20. if (printPort) {
  21. out << ":" << sa.Port();
  22. }
  23. break;
  24. }
  25. case AF_INET6: {
  26. const sockaddr_in6* sa = (const sockaddr_in6*)a;
  27. if (!inet_ntop(AF_INET6, (void*)&sa->sin6_addr.s6_addr, buf, sizeof(buf))) {
  28. ythrow TSystemError() << "inet_ntop() failed";
  29. }
  30. if (printPort) {
  31. out << "[" << buf << "]"
  32. << ":" << InetToHost(sa->sin6_port);
  33. } else {
  34. out << buf;
  35. }
  36. break;
  37. }
  38. #if defined(AF_UNIX)
  39. case AF_UNIX: {
  40. const sockaddr_un* sa = (const sockaddr_un*)a;
  41. out << TStringBuf(sa->sun_path);
  42. break;
  43. }
  44. #endif
  45. default: {
  46. size_t len = addr.Len();
  47. const char* b = (const char*)a;
  48. const char* e = b + len;
  49. bool allZeros = true;
  50. for (size_t i = 0; i < len; ++i) {
  51. if (b[i] != 0) {
  52. allZeros = false;
  53. break;
  54. }
  55. }
  56. if (allZeros) {
  57. out << "(raw all zeros)";
  58. } else {
  59. out << "(raw " << (int)a->sa_family << " ";
  60. while (b != e) {
  61. //just print raw bytes
  62. out << (int)*b++;
  63. if (b != e) {
  64. out << " ";
  65. }
  66. }
  67. out << ")";
  68. }
  69. break;
  70. }
  71. }
  72. }
  73. template <>
  74. void Out<IRemoteAddr>(IOutputStream& out, const IRemoteAddr& addr) {
  75. PrintAddr<true>(out, addr);
  76. }
  77. template <>
  78. void Out<NAddr::TAddrInfo>(IOutputStream& out, const NAddr::TAddrInfo& addr) {
  79. PrintAddr<true>(out, addr);
  80. }
  81. template <>
  82. void Out<NAddr::TIPv4Addr>(IOutputStream& out, const NAddr::TIPv4Addr& addr) {
  83. PrintAddr<true>(out, addr);
  84. }
  85. template <>
  86. void Out<NAddr::TIPv6Addr>(IOutputStream& out, const NAddr::TIPv6Addr& addr) {
  87. PrintAddr<true>(out, addr);
  88. }
  89. template <>
  90. void Out<NAddr::TOpaqueAddr>(IOutputStream& out, const NAddr::TOpaqueAddr& addr) {
  91. PrintAddr<true>(out, addr);
  92. }
  93. void NAddr::PrintHost(IOutputStream& out, const IRemoteAddr& addr) {
  94. PrintAddr<false>(out, addr);
  95. }
  96. TString NAddr::PrintHost(const IRemoteAddr& addr) {
  97. TStringStream ss;
  98. PrintAddr<false>(ss, addr);
  99. return ss.Str();
  100. }
  101. TString NAddr::PrintHostAndPort(const IRemoteAddr& addr) {
  102. TStringStream ss;
  103. PrintAddr<true>(ss, addr);
  104. return ss.Str();
  105. }
  106. IRemoteAddrPtr NAddr::GetSockAddr(SOCKET s) {
  107. auto addr = MakeHolder<TOpaqueAddr>();
  108. if (getsockname(s, addr->MutableAddr(), addr->LenPtr()) < 0) {
  109. ythrow TSystemError() << "getsockname() failed";
  110. }
  111. return addr;
  112. }
  113. IRemoteAddrPtr NAddr::GetPeerAddr(SOCKET s) {
  114. auto addr = MakeHolder<TOpaqueAddr>();
  115. if (getpeername(s, addr->MutableAddr(), addr->LenPtr()) < 0) {
  116. ythrow TSystemError() << "getpeername() failed";
  117. }
  118. return addr;
  119. }
  120. static const in_addr& InAddr(const IRemoteAddr& addr) {
  121. return ((const sockaddr_in*)addr.Addr())->sin_addr;
  122. }
  123. static const in6_addr& In6Addr(const IRemoteAddr& addr) {
  124. return ((const sockaddr_in6*)addr.Addr())->sin6_addr;
  125. }
  126. bool NAddr::IsLoopback(const IRemoteAddr& addr) {
  127. if (addr.Addr()->sa_family == AF_INET) {
  128. return ((ntohl(InAddr(addr).s_addr) >> 24) & 0xff) == 127;
  129. }
  130. if (addr.Addr()->sa_family == AF_INET6) {
  131. return 0 == memcmp(&In6Addr(addr), &in6addr_loopback, sizeof(in6_addr));
  132. }
  133. return false;
  134. }
  135. bool NAddr::IsSame(const IRemoteAddr& lhs, const IRemoteAddr& rhs) {
  136. if (lhs.Addr()->sa_family != rhs.Addr()->sa_family) {
  137. return false;
  138. }
  139. if (lhs.Addr()->sa_family == AF_INET) {
  140. return InAddr(lhs).s_addr == InAddr(rhs).s_addr;
  141. }
  142. if (lhs.Addr()->sa_family == AF_INET6) {
  143. return 0 == memcmp(&In6Addr(lhs), &In6Addr(rhs), sizeof(in6_addr));
  144. }
  145. ythrow yexception() << "unsupported addr family: " << lhs.Addr()->sa_family;
  146. }
  147. socklen_t NAddr::SockAddrLength(const sockaddr* addr) {
  148. switch (addr->sa_family) {
  149. case AF_INET:
  150. return sizeof(sockaddr_in);
  151. case AF_INET6:
  152. return sizeof(sockaddr_in6);
  153. #if defined(AF_LOCAL)
  154. case AF_LOCAL:
  155. return sizeof(sockaddr_un);
  156. #endif
  157. }
  158. ythrow yexception() << "unsupported address family: " << addr->sa_family;
  159. }
  160. TUnixSocketAddr::TUnixSocketAddr(TStringBuf path) {
  161. Y_ENSURE(path.Size() <= UNIX_PATH_LIMIT - 1,
  162. "Unix path \"" << path << "\" is longer than " << UNIX_PATH_LIMIT);
  163. SockAddr_.Set(path);
  164. }
  165. const sockaddr* TUnixSocketAddr::Addr() const {
  166. return SockAddr_.SockAddr();
  167. }
  168. socklen_t TUnixSocketAddr::Len() const {
  169. return SockAddr_.Len();
  170. }