Skip to content

Commit b2203bb

Browse files
authored
server: support dual-stack server socket (#450)
According to RFC 3493 the socket option IPV6_V6ONLY should be off by default, see https://tools.ietf.org/html/rfc3493#page-22 (chapter 5.3). However this does not seem to be the case on all systems. For instance on any Windows OS, the option is on by default. Therefore clear this option in order to allow an server socket which can support IPv6 and IPv4 at the same time.
1 parent d45250f commit b2203bb

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

httplib.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,6 +1469,11 @@ socket_t create_socket(const char *host, int port, Fn fn,
14691469
int yes = 1;
14701470
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&yes),
14711471
sizeof(yes));
1472+
1473+
int no = 0;
1474+
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char *>(&no),
1475+
sizeof(no));
1476+
14721477
#ifdef SO_REUSEPORT
14731478
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<char *>(&yes),
14741479
sizeof(yes));

test/test.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,39 @@ TEST(RedirectToDifferentPort, Redirect) {
724724
}
725725
#endif
726726

727+
TEST(Server, BindDualStack) {
728+
Server svr;
729+
730+
svr.Get("/1", [&](const Request & /*req*/, Response &res) {
731+
res.set_content("Hello World!", "text/plain");
732+
});
733+
734+
auto thread = std::thread([&]() { svr.listen("::", PORT); });
735+
736+
// Give GET time to get a few messages.
737+
std::this_thread::sleep_for(std::chrono::seconds(1));
738+
739+
{
740+
Client cli("127.0.0.1", PORT);
741+
742+
auto res = cli.Get("/1");
743+
ASSERT_TRUE(res != nullptr);
744+
EXPECT_EQ(200, res->status);
745+
EXPECT_EQ(res->body, "Hello World!");
746+
}
747+
{
748+
Client cli("::1", PORT);
749+
750+
auto res = cli.Get("/1");
751+
ASSERT_TRUE(res != nullptr);
752+
EXPECT_EQ(200, res->status);
753+
EXPECT_EQ(res->body, "Hello World!");
754+
}
755+
svr.stop();
756+
thread.join();
757+
ASSERT_FALSE(svr.is_running());
758+
}
759+
727760
TEST(Server, BindAndListenSeparately) {
728761
Server svr;
729762
int port = svr.bind_to_any_port("0.0.0.0");

0 commit comments

Comments
 (0)