28 #include <boost/lexical_cast.hpp>
32 namespace ip = boost::asio::ip;
40 static std::string id(
"tcp");
59 if (!context.
isDryRun && !m_channels.empty()) {
60 NFD_LOG_WARN(
"Cannot disable TCP channels after initialization");
65 bool wantListen =
true;
69 IpAddressPredicate local;
70 bool isLocalConfigured =
false;
72 for (
const auto& pair : *configSection) {
73 const std::string& key = pair.first;
75 if (key ==
"listen") {
78 else if (key ==
"port") {
79 port = ConfigFile::parseNumber<uint16_t>(pair,
"face_system.tcp");
81 else if (key ==
"enable_v4") {
84 else if (key ==
"enable_v6") {
87 else if (key ==
"local") {
88 isLocalConfigured =
true;
89 for (
const auto& localPair : pair.second) {
90 const std::string& localKey = localPair.first;
91 if (localKey ==
"whitelist") {
92 local.parseWhitelist(localPair.second);
94 else if (localKey ==
"blacklist") {
95 local.parseBlacklist(localPair.second);
98 NDN_THROW(ConfigFile::Error(
"Unrecognized option face_system.tcp.local." + localKey));
103 NDN_THROW(ConfigFile::Error(
"Unrecognized option face_system.tcp." + key));
106 if (!isLocalConfigured) {
107 local.assign({{
"subnet",
"127.0.0.0/8"}, {
"subnet",
"::1/128"}}, {});
110 if (!enableV4 && !enableV6) {
111 NDN_THROW(ConfigFile::Error(
112 "IPv4 and IPv6 TCP channels have been disabled. Remove face_system.tcp section to disable "
113 "TCP channels or enable at least one channel type."));
125 if (wantListen && !v4Channel->isListening()) {
126 v4Channel->listen(this->
addFace,
nullptr);
131 NFD_LOG_WARN(
"Cannot close tcp4 channel after its creation");
137 if (wantListen && !v6Channel->isListening()) {
138 v6Channel->listen(this->
addFace,
nullptr);
143 NFD_LOG_WARN(
"Cannot close tcp6 channel after its creation");
146 m_local = std::move(local);
150 TcpFactory::doCreateFace(
const CreateFaceRequest& req,
156 onFailure(406,
"Unicast TCP faces cannot be created with a LocalUri");
160 if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
162 onFailure(406,
"Outgoing TCP faces do not support on-demand persistency");
166 tcp::Endpoint endpoint(ip::make_address(req.remoteUri.getHost()),
167 boost::lexical_cast<uint16_t>(req.remoteUri.getPort()));
170 BOOST_ASSERT(!endpoint.address().is_multicast());
172 if (req.params.wantLocalFields && !endpoint.address().is_loopback()) {
173 NFD_LOG_TRACE(
"createFace: cannot create non-local face with local fields enabled");
174 onFailure(406,
"Local fields can only be enabled on faces with local scope");
178 if (req.params.mtu) {
179 NFD_LOG_TRACE(
"createFace: cannot create TCP face with overridden MTU");
180 onFailure(406,
"TCP faces do not support MTU overrides");
185 for (
const auto& i : m_channels) {
186 if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
187 (i.first.address().is_v6() && endpoint.address().is_v6())) {
188 i.second->connect(endpoint, req.params, onCreated, onFailure);
193 NFD_LOG_TRACE(
"No channels available to connect to " << endpoint);
194 onFailure(504,
"No channels available to connect");
197 shared_ptr<TcpChannel>
200 auto it = m_channels.find(endpoint);
201 if (it != m_channels.end())
204 auto channel = make_shared<TcpChannel>(endpoint, m_wantCongestionMarking, [
this] (
auto&&... args) {
205 return determineFaceScopeFromAddresses(std::forward<decltype(args)>(args)...);
207 m_channels[endpoint] = channel;
211 std::vector<shared_ptr<const Channel>>
212 TcpFactory::doGetChannels()
const
218 TcpFactory::determineFaceScopeFromAddresses(
const ip::address& localAddress,
219 const ip::address& remoteAddress)
const
221 if (m_local(localAddress) && m_local(remoteAddress)) {
222 return ndn::nfd::FACE_SCOPE_LOCAL;
224 return ndn::nfd::FACE_SCOPE_NON_LOCAL;
static bool parseYesNo(const ConfigSection &node, const std::string &key, const std::string §ionName)
Parse a config option that can be either "yes" or "no".
Context for processing a config section in ProtocolFactory.
GeneralConfig generalConfig
static std::vector< shared_ptr< const Channel > > getChannelsFromMap(const ChannelMap &channelMap)
std::set< std::string > providedSchemes
FaceUri schemes provided by this protocol factory.
FaceCreatedCallback addFace
callback when a new face is created
Protocol factory for TCP over IPv4 and IPv6.
shared_ptr< TcpChannel > createChannel(const tcp::Endpoint &localEndpoint)
Create TCP-based channel using tcp::Endpoint.
static const std::string & getId() noexcept
#define NFD_LOG_INIT(name)
std::function< void(uint32_t status, const std::string &reason)> FaceCreationFailedCallback
Prototype for the callback that is invoked when a face fails to be created.
std::function< void(const shared_ptr< Face > &)> FaceCreatedCallback
Prototype for the callback that is invoked when a face is created (in response to an incoming connect...
boost::asio::ip::tcp::endpoint Endpoint
boost::optional< const ConfigSection & > OptionalConfigSection
An optional configuration file section.
#define NFD_REGISTER_PROTOCOL_FACTORY(PF)
Registers a protocol factory.
bool wantCongestionMarking