face: support IPv6-only WebSocket channels
Change-Id: Ib9ba27d04611c13882e50995d701fc1b707cea5f
Refs: #4710
diff --git a/daemon/face/websocket-channel.cpp b/daemon/face/websocket-channel.cpp
index ca149b3..c4c392b 100644
--- a/daemon/face/websocket-channel.cpp
+++ b/daemon/face/websocket-channel.cpp
@@ -46,6 +46,12 @@
// Setup WebSocket server
m_server.init_asio(&getGlobalIoService());
+ m_server.set_tcp_pre_bind_handler([isV6 = m_localEndpoint.address().is_v6()] (const auto& acceptor) {
+ if (isV6) {
+ acceptor->set_option(boost::asio::ip::v6_only(true));
+ }
+ return websocketpp::lib::error_code{};
+ });
m_server.set_open_handler(bind(&WebSocketChannel::handleOpen, this, _1));
m_server.set_close_handler(bind(&WebSocketChannel::handleClose, this, _1));
m_server.set_message_handler(bind(&WebSocketChannel::handleMessage, this, _1, _2));
diff --git a/daemon/face/websocket-factory.cpp b/daemon/face/websocket-factory.cpp
index 11921cc..6b493de 100644
--- a/daemon/face/websocket-factory.cpp
+++ b/daemon/face/websocket-factory.cpp
@@ -91,28 +91,30 @@
"to disable WebSocket channels or enable at least one channel type."));
}
- if (!enableV4 && enableV6) {
- // websocketpp's IPv6 socket always accepts IPv4 connections.
- BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel."));
+ if (context.isDryRun) {
+ return;
}
- if (!context.isDryRun) {
- if (!wantListen) {
- if (!m_channels.empty()) {
- NFD_LOG_WARN("Cannot close WebSocket channel after initialization");
- }
- return;
+ if (!wantListen) {
+ if (!m_channels.empty()) {
+ NFD_LOG_WARN("Cannot disable WebSocket channels after initialization");
}
+ return;
+ }
- BOOST_ASSERT(enableV4);
- websocket::Endpoint endpoint(enableV6 ? ip::tcp::v6() : ip::tcp::v4(), port);
+ if (enableV4) {
+ websocket::Endpoint endpoint(ip::tcp::v4(), port);
+ auto v4Channel = this->createChannel(endpoint);
+ if (!v4Channel->isListening()) {
+ v4Channel->listen(this->addFace);
+ }
+ }
- auto channel = this->createChannel(endpoint);
- if (!channel->isListening()) {
- channel->listen(this->addFace);
- if (m_channels.size() > 1) {
- NFD_LOG_WARN("Adding WebSocket channel for new endpoint; cannot close existing channels");
- }
+ if (enableV6) {
+ websocket::Endpoint endpoint(ip::tcp::v6(), port);
+ auto v6Channel = this->createChannel(endpoint);
+ if (!v6Channel->isListening()) {
+ v6Channel->listen(this->addFace);
}
}
}
diff --git a/daemon/face/websocketpp.hpp b/daemon/face/websocketpp.hpp
index 35581fe..022682b 100644
--- a/daemon/face/websocketpp.hpp
+++ b/daemon/face/websocketpp.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -34,8 +34,8 @@
#pragma GCC system_header
#pragma clang system_header
-#include <websocketpp/config/asio_no_tls_client.hpp>
-#include <websocketpp/client.hpp>
+#include "websocketpp/config/asio_no_tls_client.hpp"
+#include "websocketpp/client.hpp"
#include "websocketpp/config/asio_no_tls.hpp"
#include "websocketpp/server.hpp"