address.cpp 4.9 KB

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