face: more robust handling of multicast face creation errors
Refs: #5030, #5297
Change-Id: I3ca985498d9d3756cbff94873063f3734bcea288
diff --git a/daemon/face/ethernet-channel.cpp b/daemon/face/ethernet-channel.cpp
index c07d6f8..655f313 100644
--- a/daemon/face/ethernet-channel.cpp
+++ b/daemon/face/ethernet-channel.cpp
@@ -101,8 +101,9 @@
EthernetChannel::asyncRead(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed)
{
- m_socket.async_wait(boost::asio::posix::stream_descriptor::wait_read,
- [=] (const auto& e) { this->handleRead(e, onFaceCreated, onReceiveFailed); });
+ m_socket.async_wait(boost::asio::posix::stream_descriptor::wait_read, [=] (const auto& e) {
+ handleRead(e, onFaceCreated, onReceiveFailed);
+ });
}
void
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index f7fb63f..9ffd16e 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -26,7 +26,6 @@
#include "ethernet-factory.hpp"
#include "generic-link-service.hpp"
#include "multicast-ethernet-transport.hpp"
-#include "pcap-helper.hpp"
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm/copy.hpp>
@@ -170,13 +169,13 @@
const FaceCreationFailedCallback& onFailure)
{
if (!req.localUri || req.localUri->getScheme() != "dev") {
- NFD_LOG_TRACE("Cannot create unicast Ethernet face without dev:// LocalUri");
+ NFD_LOG_TRACE("createFace: dev:// LocalUri required");
onFailure(406, "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
- NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
+ NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing Ethernet faces do not support on-demand persistency");
return;
}
@@ -185,14 +184,14 @@
std::string localEndpoint(req.localUri->getHost());
if (remoteEndpoint.isMulticast()) {
- NFD_LOG_TRACE("createFace does not support multicast faces");
+ NFD_LOG_TRACE("createFace: unsupported multicast endpoint");
onFailure(406, "Cannot create multicast Ethernet faces");
return;
}
if (req.params.wantLocalFields) {
// Ethernet faces are never local
- NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
+ NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
@@ -258,7 +257,9 @@
connectFaceClosedSignal(*face, [this, key] { m_mcastFaces.erase(key); });
auto channelIt = m_channels.find(netif.getName());
- face->setChannel(channelIt != m_channels.end() ? channelIt->second : nullptr);
+ if (channelIt != m_channels.end()) {
+ face->setChannel(channelIt->second);
+ }
return face;
}
@@ -332,15 +333,11 @@
NFD_LOG_DEBUG("Creating multicast face on " << netif.getName());
shared_ptr<Face> face;
try {
- face = this->createMulticastFace(netif, m_mcastConfig.group);
+ face = createMulticastFace(netif, m_mcastConfig.group);
}
- catch (const EthernetTransport::Error& e) {
+ catch (const std::runtime_error& e) {
NFD_LOG_WARN("Cannot create multicast face on " << netif.getName() << ": " << e.what());
- return nullptr;
- }
- catch (const PcapHelper::Error& e) {
- NFD_LOG_WARN("Cannot create multicast face on " << netif.getName() << ": " << e.what());
- return nullptr;
+ return nullptr; // not a fatal error
}
if (face->getId() == INVALID_FACEID) {
diff --git a/daemon/face/ethernet-factory.hpp b/daemon/face/ethernet-factory.hpp
index 607c965..d8d49c9 100644
--- a/daemon/face/ethernet-factory.hpp
+++ b/daemon/face/ethernet-factory.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, Regents of the University of California,
+ * Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,10 +28,12 @@
#include "protocol-factory.hpp"
#include "ethernet-channel.hpp"
+#include "network-predicate.hpp"
namespace nfd::face {
-/** \brief Protocol factory for Ethernet.
+/**
+ * \brief Protocol factory for Ethernet.
*/
class EthernetFactory final : public ProtocolFactory
{
@@ -48,7 +50,7 @@
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
*
- * \return always a valid pointer to a EthernetChannel object, an exception
+ * \return Always a valid pointer to a EthernetChannel object, an exception
* is thrown if it cannot be created.
* \throw PcapHelper::Error channel creation failed
*/
@@ -65,7 +67,7 @@
* \param localEndpoint local network interface
* \param group multicast group address
*
- * \throw EthernetTransport::Error transport creation fails
+ * \throw std::runtime_error %Face creation failed
*/
shared_ptr<Face>
createMulticastFace(const ndn::net::NetworkInterface& localEndpoint,
@@ -84,14 +86,16 @@
std::vector<shared_ptr<const Channel>>
doGetChannels() const final;
- /** \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
- * \return new or existing channel, or nullptr if no channel should be created
+ /**
+ * \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
+ * \return New or existing channel, or nullptr if no channel should be created.
*/
shared_ptr<EthernetChannel>
applyUnicastConfigToNetif(const shared_ptr<const ndn::net::NetworkInterface>& netif);
- /** \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
- * \return new or existing face, or nullptr if no face should be created
+ /**
+ * \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
+ * \return New or existing face, or nullptr if no face should be created.
*/
shared_ptr<Face>
applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif);
@@ -100,7 +104,8 @@
applyConfig(const FaceSystem::ConfigContext& context);
private:
- std::map<std::string, shared_ptr<EthernetChannel>> m_channels; ///< ifname => channel
+ // ifname => channel
+ std::map<std::string, shared_ptr<EthernetChannel>> m_channels;
struct UnicastConfig
{
diff --git a/daemon/face/face-system.cpp b/daemon/face/face-system.cpp
index 7ab9879..bcc8a5e 100644
--- a/daemon/face/face-system.cpp
+++ b/daemon/face/face-system.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, Regents of the University of California,
+ * Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,9 +24,8 @@
*/
#include "face-system.hpp"
-#include "protocol-factory.hpp"
#include "netdev-bound.hpp"
-#include "common/global.hpp"
+#include "protocol-factory.hpp"
#include "fw/face-table.hpp"
namespace nfd::face {
@@ -71,14 +70,14 @@
}
ProtocolFactory*
-FaceSystem::getFactoryById(const std::string& id)
+FaceSystem::getFactoryById(const std::string& id) const
{
auto found = m_factories.find(id);
return found == m_factories.end() ? nullptr : found->second.get();
}
ProtocolFactory*
-FaceSystem::getFactoryByScheme(const std::string& scheme)
+FaceSystem::getFactoryByScheme(const std::string& scheme) const
{
auto found = m_factoryByScheme.find(scheme);
return found == m_factoryByScheme.end() ? nullptr : found->second;
diff --git a/daemon/face/face-system.hpp b/daemon/face/face-system.hpp
index d7d534b..36148df 100644
--- a/daemon/face/face-system.hpp
+++ b/daemon/face/face-system.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, Regents of the University of California,
+ * Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,7 +26,6 @@
#ifndef NFD_DAEMON_FACE_FACE_SYSTEM_HPP
#define NFD_DAEMON_FACE_FACE_SYSTEM_HPP
-#include "network-predicate.hpp"
#include "common/config-file.hpp"
#include <ndn-cxx/net/network-address.hpp>
@@ -62,15 +61,17 @@
[[nodiscard]] std::set<const ProtocolFactory*>
listProtocolFactories() const;
- /** \return ProtocolFactory for the specified registered factory id or nullptr if not found.
+ /**
+ * \return ProtocolFactory for the specified registered factory id or nullptr if not found.
*/
ProtocolFactory*
- getFactoryById(const std::string& id);
+ getFactoryById(const std::string& id) const;
- /** \return ProtocolFactory for the specified FaceUri scheme or nullptr if not found.
+ /**
+ * \return ProtocolFactory for the specified FaceUri scheme or nullptr if not found.
*/
ProtocolFactory*
- getFactoryByScheme(const std::string& scheme);
+ getFactoryByScheme(const std::string& scheme) const;
bool
hasFactoryForScheme(const std::string& scheme) const;
diff --git a/daemon/face/netdev-bound.hpp b/daemon/face/netdev-bound.hpp
index 9c9aec3..68cbdc6 100644
--- a/daemon/face/netdev-bound.hpp
+++ b/daemon/face/netdev-bound.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, Regents of the University of California,
+ * Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,6 +26,7 @@
#ifndef NFD_DAEMON_FACE_NETDEV_BOUND_HPP
#define NFD_DAEMON_FACE_NETDEV_BOUND_HPP
+#include "network-predicate.hpp"
#include "protocol-factory.hpp"
namespace nfd::face {
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index 072525d..5edbd57 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -152,13 +152,13 @@
const FaceCreationFailedCallback& onFailure)
{
if (req.localUri) {
- NFD_LOG_TRACE("Cannot create unicast TCP face with LocalUri");
+ NFD_LOG_TRACE("createFace: unsupported LocalUri");
onFailure(406, "Unicast TCP faces cannot be created with a LocalUri");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
- NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
+ NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing TCP faces do not support on-demand persistency");
return;
}
@@ -170,13 +170,13 @@
BOOST_ASSERT(!endpoint.address().is_multicast());
if (req.params.wantLocalFields && !endpoint.address().is_loopback()) {
- NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
+ NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
if (req.params.mtu) {
- NFD_LOG_TRACE("createFace cannot create a TCP face with an overridden MTU");
+ NFD_LOG_TRACE("createFace: cannot create TCP face with overridden MTU");
onFailure(406, "TCP faces do not support MTU overrides");
return;
}
diff --git a/daemon/face/tcp-factory.hpp b/daemon/face/tcp-factory.hpp
index 23969f8..e94f33a 100644
--- a/daemon/face/tcp-factory.hpp
+++ b/daemon/face/tcp-factory.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, Regents of the University of California,
+ * Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,11 +27,13 @@
#define NFD_DAEMON_FACE_TCP_FACTORY_HPP
#include "protocol-factory.hpp"
+#include "network-predicate.hpp"
#include "tcp-channel.hpp"
namespace nfd::face {
-/** \brief Protocol factory for TCP over IPv4 and IPv6.
+/**
+ * \brief Protocol factory for TCP over IPv4 and IPv6.
*/
class TcpFactory final : public ProtocolFactory
{
@@ -44,12 +46,12 @@
/**
* \brief Create TCP-based channel using tcp::Endpoint.
*
- * tcp::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
+ * tcp::Endpoint is an alias for boost::asio::ip::tcp::endpoint.
*
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
*
- * \return always a valid pointer to a TcpChannel object, an exception
+ * \return Always a valid pointer to a TcpChannel object, an exception
* is thrown if it cannot be created.
*/
shared_ptr<TcpChannel>
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 5573306..a7515f4 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -97,10 +97,9 @@
UdpChannel::waitForNewPeer(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed)
{
- m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_remoteEndpoint,
- [=] (auto&&... args) {
- this->handleNewPeer(std::forward<decltype(args)>(args)..., onFaceCreated, onReceiveFailed);
- });
+ m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_remoteEndpoint, [=] (auto&&... args) {
+ handleNewPeer(std::forward<decltype(args)>(args)..., onFaceCreated, onReceiveFailed);
+ });
}
void
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 2c22c4c..be3f87e 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -28,6 +28,7 @@
#include "multicast-udp-transport.hpp"
#include "common/global.hpp"
+#include <boost/container/static_vector.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
@@ -196,7 +197,7 @@
providedSchemes.insert("udp4");
}
else if (providedSchemes.count("udp4") > 0) {
- NFD_LOG_WARN("Cannot close udp4 channel after its creation");
+ NFD_LOG_WARN("Cannot close UDP channel after its creation");
}
if (enableV6) {
@@ -209,7 +210,7 @@
providedSchemes.insert("udp6");
}
else if (providedSchemes.count("udp6") > 0) {
- NFD_LOG_WARN("Cannot close udp6 channel after its creation");
+ NFD_LOG_WARN("Cannot close UDP channel after its creation");
}
if (m_mcastConfig.isEnabled != mcastConfig.isEnabled) {
@@ -250,13 +251,13 @@
const FaceCreationFailedCallback& onFailure)
{
if (req.localUri) {
- NFD_LOG_TRACE("Cannot create unicast UDP face with LocalUri");
+ NFD_LOG_TRACE("createFace: unsupported LocalUri");
onFailure(406, "Unicast UDP faces cannot be created with a LocalUri");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
- NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
+ NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing UDP faces do not support on-demand persistency");
return;
}
@@ -265,14 +266,14 @@
boost::lexical_cast<uint16_t>(req.remoteUri.getPort()));
if (endpoint.address().is_multicast()) {
- NFD_LOG_TRACE("createFace does not support multicast faces");
+ NFD_LOG_TRACE("createFace: unsupported multicast endpoint");
onFailure(406, "Cannot create multicast UDP faces");
return;
}
if (req.params.wantLocalFields) {
// UDP faces are never local
- NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
+ NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
@@ -377,7 +378,9 @@
[isV4 = localEp.address().is_v4()] (const auto& it) {
return it.first.address().is_v4() == isV4;
});
- face->setChannel(channelIt != m_channels.end() ? channelIt->second : nullptr);
+ if (channelIt != m_channels.end()) {
+ face->setChannel(channelIt->second);
+ }
return face;
}
@@ -423,7 +426,7 @@
return {};
}
- std::vector<ip::address> addrs;
+ boost::container::static_vector<ip::address, 2> addrs;
for (auto af : {net::AddressFamily::V4, net::AddressFamily::V6}) {
auto addr = pickAddress(*netif, af);
if (addr)
@@ -442,8 +445,14 @@
std::vector<shared_ptr<Face>> faces;
for (const auto& addr : addrs) {
- auto face = this->createMulticastFace(*netif, addr,
- addr.is_v4() ? m_mcastConfig.group : m_mcastConfig.groupV6);
+ shared_ptr<Face> face;
+ try {
+ face = createMulticastFace(*netif, addr, addr.is_v4() ? m_mcastConfig.group : m_mcastConfig.groupV6);
+ }
+ catch (const std::runtime_error& e) {
+ NFD_LOG_WARN("Cannot create multicast face on " << addr << ": " << e.what());
+ continue; // not a fatal error
+ }
if (face->getId() == INVALID_FACEID) {
// new face: register with forwarding
this->addFace(face);
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index 9144a7a..ca697e7 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, Regents of the University of California,
+ * Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,11 +27,13 @@
#define NFD_DAEMON_FACE_UDP_FACTORY_HPP
#include "protocol-factory.hpp"
+#include "network-predicate.hpp"
#include "udp-channel.hpp"
namespace nfd::face {
-/** \brief Protocol factory for UDP over IPv4 and IPv6.
+/**
+ * \brief Protocol factory for UDP over IPv4 and IPv6.
*/
class UdpFactory final : public ProtocolFactory
{
@@ -51,7 +53,7 @@
/**
* \brief Create UDP-based channel using udp::Endpoint.
*
- * udp::Endpoint is really an alias for boost::asio::ip::udp::endpoint.
+ * udp::Endpoint is an alias for boost::asio::ip::udp::endpoint.
*
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
@@ -59,7 +61,7 @@
* If a multicast face is already active on the same local endpoint,
* the creation fails and an exception is thrown.
*
- * \return always a valid pointer to a UdpChannel object, an exception
+ * \return Always a valid pointer to a UdpChannel object, an exception
* is thrown if it cannot be created.
* \throw UdpFactory::Error
*/
@@ -70,7 +72,7 @@
/**
* \brief Create a multicast UDP face.
*
- * udp::Endpoint is really an alias for boost::asio::ip::udp::endpoint.
+ * udp::Endpoint is an alias for boost::asio::ip::udp::endpoint.
*
* The face will join the specified multicast group.
*
@@ -85,9 +87,9 @@
* \param localAddress the local IP address to which the face will be bound
* \param multicastEndpoint the multicast endpoint (multicast group and port number)
*
- * \return always a valid shared pointer to the created face;
+ * \return Always a valid shared pointer to the created face;
* an exception is thrown if the face cannot be created.
- * \throw UdpFactory::Error
+ * \throw std::runtime_error %Face creation failed
*/
shared_ptr<Face>
createMulticastFace(const ndn::net::NetworkInterface& netif,
@@ -107,13 +109,15 @@
std::vector<shared_ptr<const Channel>>
doGetChannels() const final;
- /** \brief Create UDP multicast faces on \p netif if needed by \p m_mcastConfig.
- * \return list of faces (just created or already existing) on \p netif
+ /**
+ * \brief Create UDP multicast faces on \p netif if needed by \p m_mcastConfig.
+ * \return List of faces (just created or already existing) on \p netif.
*/
std::vector<shared_ptr<Face>>
applyMcastConfigToNetif(const shared_ptr<const ndn::net::NetworkInterface>& netif);
- /** \brief Create and destroy UDP multicast faces according to \p m_mcastConfig.
+ /**
+ * \brief Create and destroy UDP multicast faces according to \p m_mcastConfig.
*/
void
applyMcastConfig(const FaceSystem::ConfigContext& context);
diff --git a/daemon/face/unix-stream-factory.hpp b/daemon/face/unix-stream-factory.hpp
index 8b044d4..76bbfc9 100644
--- a/daemon/face/unix-stream-factory.hpp
+++ b/daemon/face/unix-stream-factory.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, Regents of the University of California,
+ * Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,8 @@
namespace nfd::face {
-/** \brief Protocol factory for stream-oriented Unix sockets.
+/**
+ * \brief Protocol factory for stream-oriented Unix sockets.
*/
class UnixStreamFactory final : public ProtocolFactory
{
@@ -48,7 +49,7 @@
* will be created. The second call will just retrieve the existing
* channel.
*
- * \returns always a valid pointer to a UnixStreamChannel object,
+ * \returns Always a valid pointer to a UnixStreamChannel object,
* an exception will be thrown if the channel cannot be created.
*/
shared_ptr<UnixStreamChannel>
diff --git a/daemon/face/websocket-factory.hpp b/daemon/face/websocket-factory.hpp
index 7804a62..73631e3 100644
--- a/daemon/face/websocket-factory.hpp
+++ b/daemon/face/websocket-factory.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, Regents of the University of California,
+ * Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,8 @@
namespace nfd::face {
-/** \brief Protocol factory for WebSocket.
+/**
+ * \brief Protocol factory for WebSocket.
*/
class WebSocketFactory final : public ProtocolFactory
{
@@ -44,13 +45,13 @@
/**
* \brief Create WebSocket-based channel using websocket::Endpoint.
*
- * websocket::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
+ * websocket::Endpoint is an alias for boost::asio::ip::tcp::endpoint.
*
* If this method called twice with the same endpoint, only one channel
* will be created. The second call will just retrieve the existing
* channel.
*
- * \returns always a valid pointer to a WebSocketChannel object, an exception
+ * \returns Always a valid pointer to a WebSocketChannel object, an exception
* is thrown if it cannot be created.
*/
shared_ptr<WebSocketChannel>