31 namespace ip = boost::asio::ip;
39 static std::string id(
"tcp");
58 if (!context.
isDryRun && !m_channels.empty()) {
59 NFD_LOG_WARN(
"Cannot disable TCP channels after initialization");
64 bool wantListen =
true;
68 IpAddressPredicate local;
69 bool isLocalConfigured =
false;
71 for (
const auto& pair : *configSection) {
72 const std::string& key = pair.first;
74 if (key ==
"listen") {
77 else if (key ==
"port") {
78 port = ConfigFile::parseNumber<uint16_t>(pair,
"face_system.tcp");
80 else if (key ==
"enable_v4") {
83 else if (key ==
"enable_v6") {
86 else if (key ==
"local") {
87 isLocalConfigured =
true;
88 for (
const auto& localPair : pair.second) {
89 const std::string& localKey = localPair.first;
90 if (localKey ==
"whitelist") {
91 local.parseWhitelist(localPair.second);
93 else if (localKey ==
"blacklist") {
94 local.parseBlacklist(localPair.second);
97 NDN_THROW(ConfigFile::Error(
"Unrecognized option face_system.tcp.local." + localKey));
102 NDN_THROW(ConfigFile::Error(
"Unrecognized option face_system.tcp." + key));
105 if (!isLocalConfigured) {
106 local.assign({{
"subnet",
"127.0.0.0/8"}, {
"subnet",
"::1/128"}}, {});
109 if (!enableV4 && !enableV6) {
111 "IPv4 and IPv6 TCP channels have been disabled. Remove face_system.tcp section to disable "
112 "TCP channels or enable at least one channel type."));
124 if (wantListen && !v4Channel->isListening()) {
125 v4Channel->listen(this->
addFace,
nullptr);
130 NFD_LOG_WARN(
"Cannot close tcp4 channel after its creation");
136 if (wantListen && !v6Channel->isListening()) {
137 v6Channel->listen(this->
addFace,
nullptr);
142 NFD_LOG_WARN(
"Cannot close tcp6 channel after its creation");
149 TcpFactory::doCreateFace(
const CreateFaceRequest& req,
154 NFD_LOG_TRACE(
"Cannot create unicast TCP face with LocalUri");
155 onFailure(406,
"Unicast TCP faces cannot be created with a LocalUri");
160 NFD_LOG_TRACE(
"createFace does not support FACE_PERSISTENCY_ON_DEMAND");
161 onFailure(406,
"Outgoing TCP faces do not support on-demand persistency");
165 tcp::Endpoint endpoint(ip::address::from_string(req.remoteUri.getHost()),
166 boost::lexical_cast<uint16_t>(req.remoteUri.getPort()));
169 BOOST_ASSERT(!endpoint.address().is_multicast());
171 if (req.params.wantLocalFields && !endpoint.address().is_loopback()) {
172 NFD_LOG_TRACE(
"createFace cannot create non-local face with local fields enabled");
173 onFailure(406,
"Local fields can only be enabled on faces with local scope");
177 if (req.params.mtu) {
178 NFD_LOG_TRACE(
"createFace cannot create a TCP face with an overridden MTU");
179 onFailure(406,
"TCP faces do not support MTU overrides");
184 for (
const auto& i : m_channels) {
185 if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
186 (i.first.address().is_v6() && endpoint.address().is_v6())) {
187 i.second->connect(endpoint, req.params, onCreated, onFailure);
192 NFD_LOG_TRACE(
"No channels available to connect to " << endpoint);
193 onFailure(504,
"No channels available to connect");
196 shared_ptr<TcpChannel>
199 auto it = m_channels.find(endpoint);
200 if (it != m_channels.end())
203 auto channel = make_shared<TcpChannel>(endpoint, m_wantCongestionMarking,
204 bind(&TcpFactory::determineFaceScopeFromAddresses,
this, _1, _2));
205 m_channels[endpoint] = channel;
209 std::vector<shared_ptr<const Channel>>
210 TcpFactory::doGetChannels()
const
216 TcpFactory::determineFaceScopeFromAddresses(
const boost::asio::ip::address& localAddress,
217 const boost::asio::ip::address& remoteAddress)
const
219 if (m_local(localAddress) && m_local(remoteAddress)) {