SocketAddress.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/IPv4Address.h>
  9. #include <AK/IPv6Address.h>
  10. #include <arpa/inet.h>
  11. #include <netinet/in.h>
  12. #include <string.h>
  13. #include <sys/socket.h>
  14. #include <sys/un.h>
  15. namespace Core {
  16. class SocketAddress {
  17. public:
  18. enum class Type {
  19. Invalid,
  20. IPv4,
  21. IPv6,
  22. Local
  23. };
  24. SocketAddress() = default;
  25. SocketAddress(IPv4Address const& address)
  26. : m_type(Type::IPv4)
  27. , m_ip_address { address }
  28. {
  29. }
  30. SocketAddress(IPv6Address const& address)
  31. : m_type(Type::IPv6)
  32. , m_ip_address { address }
  33. {
  34. }
  35. SocketAddress(IPv4Address const& address, u16 port)
  36. : m_type(Type::IPv4)
  37. , m_ip_address { address }
  38. , m_port(port)
  39. {
  40. }
  41. SocketAddress(IPv6Address const& address, u16 port)
  42. : m_type(Type::IPv6)
  43. , m_ip_address { address }
  44. , m_port(port)
  45. {
  46. }
  47. static SocketAddress local(ByteString const& address)
  48. {
  49. SocketAddress addr;
  50. addr.m_type = Type::Local;
  51. addr.m_local_address = address;
  52. return addr;
  53. }
  54. Type type() const { return m_type; }
  55. bool is_valid() const { return m_type != Type::Invalid; }
  56. IPv4Address ipv4_address() const { return m_ip_address.get<IPv4Address>(); }
  57. IPv6Address ipv6_address() const { return m_ip_address.get<IPv6Address>(); }
  58. u16 port() const { return m_port; }
  59. ByteString to_byte_string() const
  60. {
  61. switch (m_type) {
  62. case Type::IPv4:
  63. return ByteString::formatted("{}:{}", m_ip_address.get<IPv4Address>(), m_port);
  64. case Type::IPv6:
  65. return ByteString::formatted("[{}]:{}", m_ip_address.get<IPv6Address>(), m_port);
  66. case Type::Local:
  67. return m_local_address;
  68. default:
  69. return "[SocketAddress]";
  70. }
  71. }
  72. Optional<sockaddr_un> to_sockaddr_un() const
  73. {
  74. VERIFY(type() == Type::Local);
  75. sockaddr_un address;
  76. address.sun_family = AF_LOCAL;
  77. bool fits = m_local_address.copy_characters_to_buffer(address.sun_path, sizeof(address.sun_path));
  78. if (!fits)
  79. return {};
  80. return address;
  81. }
  82. sockaddr_in6 to_sockaddr_in6() const
  83. {
  84. VERIFY(type() == Type::IPv6);
  85. sockaddr_in6 address {};
  86. memset(&address, 0, sizeof(address));
  87. address.sin6_family = AF_INET6;
  88. address.sin6_port = htons(port());
  89. auto ipv6_addr = ipv6_address();
  90. memcpy(&address.sin6_addr, &ipv6_addr.to_in6_addr_t(), sizeof(address.sin6_addr));
  91. return address;
  92. }
  93. sockaddr_in to_sockaddr_in() const
  94. {
  95. VERIFY(type() == Type::IPv4);
  96. sockaddr_in address {};
  97. address.sin_family = AF_INET;
  98. address.sin_port = htons(port());
  99. address.sin_addr.s_addr = ipv4_address().to_in_addr_t();
  100. return address;
  101. }
  102. bool operator==(SocketAddress const& other) const = default;
  103. bool operator!=(SocketAddress const& other) const = default;
  104. private:
  105. Type m_type { Type::Invalid };
  106. Variant<IPv4Address, IPv6Address> m_ip_address = IPv4Address();
  107. u16 m_port { 0 };
  108. ByteString m_local_address;
  109. };
  110. }
  111. template<>
  112. struct AK::Formatter<Core::SocketAddress> : Formatter<ByteString> {
  113. ErrorOr<void> format(FormatBuilder& builder, Core::SocketAddress const& value)
  114. {
  115. return Formatter<ByteString>::format(builder, value.to_byte_string());
  116. }
  117. };
  118. template<>
  119. struct AK::Traits<Core::SocketAddress> : public DefaultTraits<Core::SocketAddress> {
  120. static unsigned hash(Core::SocketAddress const& socket_address)
  121. {
  122. return pair_int_hash(Traits<IPv4Address>::hash(socket_address.ipv4_address()), Traits<u16>::hash(socket_address.port()));
  123. }
  124. };