William A. Kennington III | be3fb71 | 2023-12-17 19:14:56 -0800 | [diff] [blame] | 1 | #include <stdplus/net/addr/sock.hpp> |
| 2 | |
William A. Kennington III | 87a1697 | 2023-12-17 22:19:44 -0800 | [diff] [blame] | 3 | #include <format> |
| 4 | #include <string> |
William A. Kennington III | c03c91f | 2023-12-17 22:18:53 -0800 | [diff] [blame] | 5 | #include <string_view> |
| 6 | |
William A. Kennington III | be3fb71 | 2023-12-17 19:14:56 -0800 | [diff] [blame] | 7 | #include <gtest/gtest.h> |
| 8 | |
William A. Kennington III | c03c91f | 2023-12-17 22:18:53 -0800 | [diff] [blame] | 9 | using std::literals::string_view_literals::operator""sv; |
| 10 | |
William A. Kennington III | be3fb71 | 2023-12-17 19:14:56 -0800 | [diff] [blame] | 11 | namespace stdplus |
| 12 | { |
| 13 | |
| 14 | TEST(Sock4Addr, Basic) |
| 15 | { |
| 16 | constexpr Sock4Addr addr1{.addr = In4Addr{255}, .port = 3959}; |
| 17 | Sock4Addr addr2{.addr = In4Addr{255}, .port = 2000}; |
| 18 | Sock4Addr addr3{.addr = In4Addr{0}, .port = 3959}; |
| 19 | |
| 20 | EXPECT_EQ(addr1, addr1); |
| 21 | EXPECT_NE(addr1, addr2); |
| 22 | EXPECT_NE(addr3, addr1); |
| 23 | |
| 24 | auto addr = addr1.sockaddr(); |
| 25 | EXPECT_EQ(AF_INET, addr.sin_family); |
| 26 | EXPECT_EQ(In4Addr{255}, addr.sin_addr); |
| 27 | EXPECT_EQ(3959, stdplus::ntoh(addr.sin_port)); |
| 28 | EXPECT_EQ(sizeof(sockaddr_in), addr1.sockaddrLen()); |
| 29 | } |
| 30 | |
William A. Kennington III | c47ff77 | 2024-01-04 12:56:45 -0800 | [diff] [blame] | 31 | TEST(Sock4Addr, FromBuf) |
| 32 | { |
| 33 | SockAddrBuf buf = {}; |
| 34 | auto& sin = reinterpret_cast<sockaddr_in&>(buf); |
| 35 | sin.sin_addr.s_addr = stdplus::hton(std::uint32_t{0xff000000}); |
| 36 | sin.sin_port = stdplus::hton(std::uint16_t{33}); |
| 37 | EXPECT_THROW(Sock4Addr::fromBuf(buf), std::invalid_argument); |
| 38 | buf.fam = AF_INET; |
| 39 | EXPECT_THROW(Sock4Addr::fromBuf(buf), std::invalid_argument); |
| 40 | buf.fam = AF_INET6; |
| 41 | buf.len = sizeof(sockaddr_in); |
| 42 | EXPECT_THROW(Sock4Addr::fromBuf(buf), std::invalid_argument); |
| 43 | buf.fam = AF_INET; |
| 44 | EXPECT_EQ(Sock4Addr::fromBuf(buf), Sock4Addr(In4Addr{255, 0, 0, 0}, 33)); |
| 45 | } |
| 46 | |
William A. Kennington III | 87a1697 | 2023-12-17 22:19:44 -0800 | [diff] [blame] | 47 | TEST(Sock4Addr, FromStr) |
| 48 | { |
| 49 | constexpr FromStr<Sock4Addr> fs; |
| 50 | EXPECT_THROW(fs("10"sv), std::invalid_argument); |
| 51 | EXPECT_THROW(fs(":3959"sv), std::invalid_argument); |
| 52 | EXPECT_THROW(fs("0.0.0.0"sv), std::invalid_argument); |
| 53 | EXPECT_THROW(fs("0.0.0.0:"sv), std::invalid_argument); |
| 54 | EXPECT_THROW(fs(":::80"sv), std::invalid_argument); |
| 55 | EXPECT_EQ((Sock4Addr{In4Addr{}, 30}), fs("0.0.0.0:30"sv)); |
| 56 | } |
| 57 | |
| 58 | TEST(Sock4Addr, ToStr) |
| 59 | { |
| 60 | ToStrHandle<ToStr<Sock4Addr>> tsh; |
| 61 | EXPECT_EQ("0.0.0.0:3959", tsh(Sock4Addr({}, 3959))); |
| 62 | EXPECT_EQ("255.0.255.255:28", |
| 63 | tsh(Sock4Addr(In4Addr{255, 0, 255, 255}, 28))); |
| 64 | EXPECT_EQ("a 1.2.3.4:32 b", |
| 65 | std::format("a {} b", Sock4Addr(In4Addr{1, 2, 3, 4}, 32))); |
| 66 | } |
| 67 | |
William A. Kennington III | be3fb71 | 2023-12-17 19:14:56 -0800 | [diff] [blame] | 68 | TEST(Sock6Addr, Basic) |
| 69 | { |
| 70 | constexpr Sock6Addr addr1{.addr = In6Addr{255}, .port = 3959, .scope = 0}; |
| 71 | Sock6Addr addr2{.addr = In6Addr{255}, .port = 2000, .scope = 0}; |
| 72 | Sock6Addr addr3{.addr = In6Addr{0}, .port = 3959, .scope = 0}; |
| 73 | Sock6Addr addr4{.addr = In6Addr{255}, .port = 3959, .scope = 1}; |
| 74 | |
| 75 | EXPECT_EQ(addr1, addr1); |
| 76 | EXPECT_NE(addr1, addr2); |
| 77 | EXPECT_NE(addr3, addr1); |
| 78 | EXPECT_NE(addr4, addr1); |
| 79 | |
| 80 | auto addr = addr1.sockaddr(); |
| 81 | EXPECT_EQ(AF_INET6, addr.sin6_family); |
| 82 | EXPECT_EQ(In6Addr{255}, addr.sin6_addr); |
| 83 | EXPECT_EQ(3959, stdplus::ntoh(addr.sin6_port)); |
| 84 | EXPECT_EQ(sizeof(sockaddr_in6), addr1.sockaddrLen()); |
| 85 | } |
| 86 | |
William A. Kennington III | c47ff77 | 2024-01-04 12:56:45 -0800 | [diff] [blame] | 87 | TEST(Sock6Addr, FromBuf) |
| 88 | { |
| 89 | SockAddrBuf buf = {}; |
| 90 | auto& sin6 = reinterpret_cast<sockaddr_in6&>(buf); |
| 91 | sin6.sin6_addr.s6_addr[0] = 0xff; |
| 92 | sin6.sin6_port = stdplus::hton(std::uint16_t{33}); |
| 93 | EXPECT_THROW(Sock6Addr::fromBuf(buf), std::invalid_argument); |
| 94 | buf.fam = AF_INET6; |
| 95 | EXPECT_THROW(Sock6Addr::fromBuf(buf), std::invalid_argument); |
| 96 | buf.fam = AF_INET; |
| 97 | buf.len = sizeof(sockaddr_in6); |
| 98 | EXPECT_THROW(Sock6Addr::fromBuf(buf), std::invalid_argument); |
| 99 | buf.fam = AF_INET6; |
| 100 | EXPECT_EQ(Sock6Addr::fromBuf(buf), Sock6Addr(In6Addr{0xff}, 33, 0)); |
| 101 | } |
| 102 | |
William A. Kennington III | 87a1697 | 2023-12-17 22:19:44 -0800 | [diff] [blame] | 103 | TEST(Sock6Addr, FromStr) |
| 104 | { |
| 105 | constexpr FromStr<Sock6Addr> fs; |
| 106 | EXPECT_THROW(fs("10"sv), std::invalid_argument); |
| 107 | EXPECT_THROW(fs(":10"sv), std::invalid_argument); |
| 108 | EXPECT_THROW(fs("ff::"sv), std::invalid_argument); |
| 109 | EXPECT_THROW(fs("[ff::]"sv), std::invalid_argument); |
| 110 | EXPECT_THROW(fs("[::]:"sv), std::invalid_argument); |
| 111 | EXPECT_THROW(fs("0.0.0.0:0"sv), std::invalid_argument); |
| 112 | EXPECT_EQ((Sock6Addr{In6Addr{}, 80, 0}), fs("[::]:80"sv)); |
| 113 | } |
| 114 | |
| 115 | TEST(Sock6Addr, ToStr) |
| 116 | { |
| 117 | ToStrHandle<ToStr<Sock6Addr>> tsh; |
| 118 | EXPECT_EQ("[::]:0", tsh(Sock6Addr({}, 0, 0))); |
| 119 | EXPECT_EQ("[ff00::]:128", tsh(Sock6Addr(In6Addr{0xff}, 128, 0))); |
| 120 | EXPECT_EQ("a [102:304::]:32 b", |
| 121 | std::format("a {} b", Sock6Addr(In6Addr{1, 2, 3, 4}, 32, 0))); |
| 122 | } |
| 123 | |
William A. Kennington III | c03c91f | 2023-12-17 22:18:53 -0800 | [diff] [blame] | 124 | TEST(SockUAddr, Basic) |
| 125 | { |
| 126 | // Non-abstract Requires null-terminator |
| 127 | EXPECT_THROW(SockUAddr(std::string(SockUAddr::maxLen, 'a')), |
| 128 | std::invalid_argument); |
| 129 | EXPECT_NO_THROW(SockUAddr(std::string(SockUAddr::maxLen - 1, 'a'))); |
| 130 | |
| 131 | // Abstract can use the full space |
| 132 | EXPECT_THROW(SockUAddr(std::string(SockUAddr::maxLen + 1, '\0')), |
| 133 | std::invalid_argument); |
| 134 | EXPECT_NO_THROW(SockUAddr(std::string(SockUAddr::maxLen, '\0'))); |
| 135 | |
| 136 | EXPECT_THROW(SockUAddr("hi\0o"sv), std::invalid_argument); |
| 137 | |
| 138 | constexpr SockUAddr addr1{"@hi"sv}; |
| 139 | constexpr SockUAddr addr2{"\0hi"sv}; |
| 140 | constexpr SockUAddr addr3{"/nope"sv}; |
| 141 | constexpr SockUAddr addr4{""sv}; |
| 142 | |
| 143 | EXPECT_EQ(addr1, addr1); |
| 144 | EXPECT_EQ(addr1, addr2); |
| 145 | EXPECT_NE(addr3, addr1); |
| 146 | EXPECT_NE(addr4, addr1); |
| 147 | EXPECT_NE(addr4, addr3); |
| 148 | |
| 149 | EXPECT_EQ(addr1.path(), "@hi"sv); |
| 150 | EXPECT_EQ(addr2.path(), "@hi"sv); |
| 151 | EXPECT_EQ(addr3.path(), "/nope"sv); |
| 152 | EXPECT_EQ(addr4.path(), ""sv); |
| 153 | |
| 154 | auto addr = addr1.sockaddr(); |
| 155 | EXPECT_EQ(AF_UNIX, addr.sun_family); |
| 156 | EXPECT_EQ("\0hi"sv, std::string_view(addr.sun_path, 3)); |
| 157 | auto buf = addr2.buf(); |
| 158 | auto ptr = reinterpret_cast<std::uint8_t*>(&buf); |
| 159 | EXPECT_TRUE( |
| 160 | std::equal(ptr, ptr + buf.len, reinterpret_cast<std::uint8_t*>(&addr))); |
| 161 | addr = addr3; |
| 162 | EXPECT_EQ("/nope\0"sv, std::string_view(addr.sun_path, 6)); |
| 163 | EXPECT_EQ(addr1.sockaddrLen(), sizeof(addr.sun_family) + 3); |
| 164 | EXPECT_EQ(addr2.sockaddrLen(), sizeof(addr.sun_family) + 3); |
| 165 | EXPECT_EQ(addr3.sockaddrLen(), sizeof(addr.sun_family) + 6); |
| 166 | EXPECT_EQ(addr4.sockaddrLen(), sizeof(addr.sun_family)); |
| 167 | } |
| 168 | |
William A. Kennington III | c47ff77 | 2024-01-04 12:56:45 -0800 | [diff] [blame] | 169 | TEST(SockUAddr, FromBuf) |
| 170 | { |
| 171 | SockAddrBuf buf = {}; |
| 172 | auto& sun = reinterpret_cast<sockaddr_un&>(buf); |
| 173 | auto path = "/my-path"sv; |
| 174 | std::copy(path.begin(), path.end(), sun.sun_path); |
| 175 | EXPECT_THROW(SockUAddr::fromBuf(buf), std::invalid_argument); |
| 176 | buf.fam = AF_UNIX; |
| 177 | EXPECT_THROW(SockUAddr::fromBuf(buf), std::invalid_argument); |
| 178 | buf.fam = AF_INET6; |
| 179 | buf.len = sizeof(buf.fam) + path.size() + 1; |
| 180 | EXPECT_THROW(SockUAddr::fromBuf(buf), std::invalid_argument); |
| 181 | buf.fam = AF_UNIX; |
| 182 | EXPECT_EQ(SockUAddr::fromBuf(buf), SockUAddr(path)); |
| 183 | |
| 184 | path = "\0abs-path"sv; |
| 185 | std::copy(path.begin(), path.end(), sun.sun_path); |
| 186 | buf.len = sizeof(buf.fam) + path.size(); |
| 187 | EXPECT_EQ(SockUAddr::fromBuf(buf), SockUAddr(path)); |
| 188 | |
| 189 | buf.len = sizeof(buf.fam); |
| 190 | EXPECT_EQ(SockUAddr::fromBuf(buf), SockUAddr("")); |
| 191 | } |
| 192 | |
William A. Kennington III | 87a1697 | 2023-12-17 22:19:44 -0800 | [diff] [blame] | 193 | TEST(SockUAddr, FromStr) |
| 194 | { |
| 195 | constexpr FromStr<SockUAddr> fs; |
| 196 | std::string as(sizeof(sockaddr_un), 'a'); |
| 197 | EXPECT_THROW(fs(std::string_view(as)), std::invalid_argument); |
| 198 | EXPECT_THROW(fs("a\0"sv), std::invalid_argument); |
| 199 | EXPECT_EQ((SockUAddr{"/nope"sv}), fs("unix:/nope"sv)); |
| 200 | EXPECT_EQ((SockUAddr{"@hi"sv}), fs("@hi"sv)); |
| 201 | } |
| 202 | |
| 203 | TEST(SockUAddr, ToStr) |
| 204 | { |
| 205 | ToStrHandle<ToStr<SockUAddr>> tsh; |
| 206 | EXPECT_EQ("unix:/nope", tsh(SockUAddr("/nope"sv))); |
| 207 | EXPECT_EQ("unix:@hi", tsh(SockUAddr("\0hi"sv))); |
| 208 | EXPECT_EQ("a unix:a b", std::format("a {} b", SockUAddr("a"sv))); |
| 209 | } |
| 210 | |
William A. Kennington III | 766d485 | 2023-12-18 16:54:47 -0800 | [diff] [blame] | 211 | TEST(SockInAddr, Basic) |
| 212 | { |
| 213 | constexpr SockInAddr addr1(In4Addr{255}, 3959); |
| 214 | constexpr SockInAddr addr2(In6Addr{255}, 3959); |
| 215 | EXPECT_NE(addr1, addr2); |
| 216 | EXPECT_EQ(addr1, addr1); |
| 217 | auto buf = addr1.buf(); |
| 218 | EXPECT_EQ(buf.len, sizeof(sockaddr_in)); |
| 219 | EXPECT_EQ(addr1.sockaddrLen(), sizeof(sockaddr_in)); |
| 220 | EXPECT_EQ(addr2.sockaddrLen(), sizeof(sockaddr_in6)); |
| 221 | } |
| 222 | |
William A. Kennington III | c47ff77 | 2024-01-04 12:56:45 -0800 | [diff] [blame] | 223 | TEST(SockInAddr, FromBuf) |
| 224 | { |
| 225 | SockAddrBuf buf = {}; |
| 226 | EXPECT_THROW(SockInAddr::fromBuf(buf), std::invalid_argument); |
| 227 | buf.fam = AF_UNIX; |
| 228 | buf.len = sizeof(sockaddr_un); |
| 229 | EXPECT_THROW(SockInAddr::fromBuf(buf), std::invalid_argument); |
| 230 | buf.fam = AF_INET6; |
| 231 | buf.len = sizeof(sockaddr_in); |
| 232 | EXPECT_THROW(SockInAddr::fromBuf(buf), std::invalid_argument); |
| 233 | buf.fam = AF_INET; |
| 234 | EXPECT_EQ(SockInAddr::fromBuf(buf), SockInAddr(In4Addr{}, 0)); |
| 235 | buf.fam = AF_INET6; |
| 236 | buf.len = sizeof(sockaddr_in6); |
| 237 | EXPECT_EQ(SockInAddr::fromBuf(buf), SockInAddr(In6Addr{}, 0)); |
| 238 | } |
| 239 | |
William A. Kennington III | 766d485 | 2023-12-18 16:54:47 -0800 | [diff] [blame] | 240 | TEST(SockInAddr, FromStr) |
| 241 | { |
| 242 | constexpr FromStr<SockInAddr> fs; |
| 243 | EXPECT_THROW(fs("abcd"sv), std::invalid_argument); |
| 244 | EXPECT_THROW(fs("/nope"sv), std::invalid_argument); |
| 245 | EXPECT_EQ((Sock4Addr{In4Addr{}, 30}), fs("0.0.0.0:30"sv)); |
| 246 | EXPECT_EQ((Sock6Addr{In6Addr{}, 80, 0}), fs("[::]:80"sv)); |
| 247 | EXPECT_THROW(fs("unix:/nope"sv), std::invalid_argument); |
| 248 | } |
| 249 | |
| 250 | TEST(SockInAddr, ToStr) |
| 251 | { |
| 252 | ToStrHandle<ToStr<SockInAddr>> tsh; |
| 253 | EXPECT_EQ("0.0.0.0:3949", tsh(Sock4Addr(In4Addr{}, 3949))); |
| 254 | EXPECT_EQ("a [::]:356 b", |
| 255 | std::format("a {} b", Sock6Addr(In6Addr{}, 356, 0))); |
| 256 | } |
| 257 | |
William A. Kennington III | be3fb71 | 2023-12-17 19:14:56 -0800 | [diff] [blame] | 258 | TEST(SockAnyAddr, Basic) |
| 259 | { |
William A. Kennington III | 766d485 | 2023-12-18 16:54:47 -0800 | [diff] [blame] | 260 | constexpr SockAnyAddr addr1(In4Addr{255}, 3959); |
| 261 | constexpr SockAnyAddr addr2("/hi"sv); |
William A. Kennington III | c03c91f | 2023-12-17 22:18:53 -0800 | [diff] [blame] | 262 | EXPECT_NE(addr1, addr2); |
William A. Kennington III | be3fb71 | 2023-12-17 19:14:56 -0800 | [diff] [blame] | 263 | EXPECT_EQ(addr1, addr1); |
| 264 | auto buf = addr1.buf(); |
| 265 | EXPECT_EQ(buf.len, sizeof(sockaddr_in)); |
| 266 | EXPECT_EQ(addr1.sockaddrLen(), sizeof(sockaddr_in)); |
William A. Kennington III | c03c91f | 2023-12-17 22:18:53 -0800 | [diff] [blame] | 267 | EXPECT_EQ(addr2.sockaddrLen(), sizeof(sa_family_t) + 4); |
William A. Kennington III | be3fb71 | 2023-12-17 19:14:56 -0800 | [diff] [blame] | 268 | } |
| 269 | |
William A. Kennington III | c47ff77 | 2024-01-04 12:56:45 -0800 | [diff] [blame] | 270 | TEST(SockAnyAddr, FromBuf) |
| 271 | { |
| 272 | SockAddrBuf buf = {}; |
| 273 | EXPECT_THROW(SockAnyAddr::fromBuf(buf), std::invalid_argument); |
| 274 | buf.fam = AF_UNIX; |
| 275 | EXPECT_THROW(SockInAddr::fromBuf(buf), std::invalid_argument); |
| 276 | buf.len = sizeof(sockaddr_un{}.sun_family); |
| 277 | EXPECT_EQ(SockAnyAddr::fromBuf(buf), SockAnyAddr("")); |
| 278 | buf.fam = AF_INET6; |
| 279 | buf.len = sizeof(sockaddr_in); |
| 280 | EXPECT_THROW(SockAnyAddr::fromBuf(buf), std::invalid_argument); |
| 281 | buf.fam = AF_INET; |
| 282 | EXPECT_EQ(SockAnyAddr::fromBuf(buf), SockAnyAddr(In4Addr{}, 0)); |
| 283 | buf.fam = AF_INET6; |
| 284 | buf.len = sizeof(sockaddr_in6); |
| 285 | EXPECT_EQ(SockAnyAddr::fromBuf(buf), SockAnyAddr(In6Addr{}, 0)); |
| 286 | } |
| 287 | |
William A. Kennington III | 87a1697 | 2023-12-17 22:19:44 -0800 | [diff] [blame] | 288 | TEST(SockAnyAddr, FromStr) |
| 289 | { |
| 290 | constexpr FromStr<SockAnyAddr> fs; |
| 291 | EXPECT_THROW(fs("abcd"sv), std::invalid_argument); |
| 292 | EXPECT_THROW(fs("/nope"sv), std::invalid_argument); |
| 293 | EXPECT_EQ((Sock4Addr{In4Addr{}, 30}), fs("0.0.0.0:30"sv)); |
| 294 | EXPECT_EQ((Sock6Addr{In6Addr{}, 80, 0}), fs("[::]:80"sv)); |
| 295 | EXPECT_EQ((SockUAddr{"/nope"sv}), fs("unix:/nope"sv)); |
| 296 | } |
| 297 | |
| 298 | TEST(SockAnyAddr, ToStr) |
| 299 | { |
| 300 | ToStrHandle<ToStr<SockAnyAddr>> tsh; |
| 301 | EXPECT_EQ("unix:/nope", tsh(SockUAddr("/nope"sv))); |
| 302 | EXPECT_EQ("0.0.0.0:3949", tsh(Sock4Addr(In4Addr{}, 3949))); |
| 303 | EXPECT_EQ("a [::]:356 b", |
| 304 | std::format("a {} b", Sock6Addr(In6Addr{}, 356, 0))); |
| 305 | } |
| 306 | |
William A. Kennington III | be3fb71 | 2023-12-17 19:14:56 -0800 | [diff] [blame] | 307 | } // namespace stdplus |