blob: 0a152b1677ced06240b0225a429f11ce16bc0e88 [file] [log] [blame]
Alexander Afanasyeva9034b02014-01-26 18:32:02 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Chengyu Fan4381fb62015-01-14 11:37:04 -07003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Steve DiBenedettoef04f272014-06-04 14:28:31 -060024 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080025
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080026#include "tcp-factory.hpp"
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080027#include "core/logger.hpp"
Steve DiBenedettoca53ac62014-03-27 19:58:40 -060028#include "core/network-interface.hpp"
Chengyu Fan4381fb62015-01-14 11:37:04 -070029#include "core/global-io.hpp"
30#include <ndn-cxx/util/dns.hpp>
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080031
32NFD_LOG_INIT("TcpFactory");
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080033
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080034namespace nfd {
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080035
Alexander Afanasyev70aaf8a2014-12-13 00:44:22 -080036static const boost::asio::ip::address_v4 ALL_V4_ENDPOINT(
37 boost::asio::ip::address_v4::from_string("0.0.0.0"));
38
39static const boost::asio::ip::address_v6 ALL_V6_ENDPOINT(
40 boost::asio::ip::address_v6::from_string("::"));
41
Alexander Afanasyevd6655302014-02-28 08:41:28 -080042TcpFactory::TcpFactory(const std::string& defaultPort/* = "6363"*/)
43 : m_defaultPort(defaultPort)
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080044{
Steve DiBenedettoca53ac62014-03-27 19:58:40 -060045}
46
47void
48TcpFactory::prohibitEndpoint(const tcp::Endpoint& endpoint)
49{
50 using namespace boost::asio::ip;
51
Steve DiBenedettoca53ac62014-03-27 19:58:40 -060052 const address& address = endpoint.address();
53
54 if (address.is_v4() && address == ALL_V4_ENDPOINT)
55 {
56 prohibitAllIpv4Endpoints(endpoint.port());
57 }
58 else if (endpoint.address().is_v6() && address == ALL_V6_ENDPOINT)
59 {
60 prohibitAllIpv6Endpoints(endpoint.port());
61 }
62
Alexander Afanasyev70aaf8a2014-12-13 00:44:22 -080063 NFD_LOG_TRACE("prohibiting TCP " << endpoint);
Steve DiBenedettoca53ac62014-03-27 19:58:40 -060064
65 m_prohibitedEndpoints.insert(endpoint);
66}
67
68void
69TcpFactory::prohibitAllIpv4Endpoints(const uint16_t port)
70{
71 using namespace boost::asio::ip;
72
Davide Pesaventob499a602014-11-18 22:36:56 +010073 for (const NetworkInterfaceInfo& nic : listNetworkInterfaces()) {
74 for (const address_v4& addr : nic.ipv4Addresses) {
Alexander Afanasyev70aaf8a2014-12-13 00:44:22 -080075 if (addr != ALL_V4_ENDPOINT) {
76 prohibitEndpoint(tcp::Endpoint(addr, port));
77 }
Steve DiBenedettoca53ac62014-03-27 19:58:40 -060078 }
Davide Pesaventob499a602014-11-18 22:36:56 +010079 }
Steve DiBenedettoca53ac62014-03-27 19:58:40 -060080}
81
82void
83TcpFactory::prohibitAllIpv6Endpoints(const uint16_t port)
84{
85 using namespace boost::asio::ip;
86
Davide Pesaventob499a602014-11-18 22:36:56 +010087 for (const NetworkInterfaceInfo& nic : listNetworkInterfaces()) {
88 for (const address_v6& addr : nic.ipv6Addresses) {
Alexander Afanasyev70aaf8a2014-12-13 00:44:22 -080089 if (addr != ALL_V6_ENDPOINT) {
90 prohibitEndpoint(tcp::Endpoint(addr, port));
91 }
Steve DiBenedettoca53ac62014-03-27 19:58:40 -060092 }
Davide Pesaventob499a602014-11-18 22:36:56 +010093 }
Alexander Afanasyevd6655302014-02-28 08:41:28 -080094}
95
96shared_ptr<TcpChannel>
97TcpFactory::createChannel(const tcp::Endpoint& endpoint)
98{
99 shared_ptr<TcpChannel> channel = findChannel(endpoint);
Davide Pesaventob499a602014-11-18 22:36:56 +0100100 if (static_cast<bool>(channel))
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800101 return channel;
102
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700103 channel = make_shared<TcpChannel>(endpoint);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800104 m_channels[endpoint] = channel;
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600105 prohibitEndpoint(endpoint);
106
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800107 NFD_LOG_DEBUG("Channel [" << endpoint << "] created");
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800108 return channel;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800109}
110
111shared_ptr<TcpChannel>
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800112TcpFactory::createChannel(const std::string& localHost, const std::string& localPort)
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800113{
Chengyu Fan4381fb62015-01-14 11:37:04 -0700114 tcp::Endpoint endpoint(ndn::dns::syncResolve(localHost, getGlobalIoService()),
115 boost::lexical_cast<uint16_t>(localPort));
116 return createChannel(endpoint);
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800117}
118
119shared_ptr<TcpChannel>
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800120TcpFactory::findChannel(const tcp::Endpoint& localEndpoint)
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800121{
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800122 ChannelMap::iterator i = m_channels.find(localEndpoint);
123 if (i != m_channels.end())
124 return i->second;
125 else
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800126 return shared_ptr<TcpChannel>();
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800127}
128
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800129void
130TcpFactory::createFace(const FaceUri& uri,
131 const FaceCreatedCallback& onCreated,
132 const FaceConnectFailedCallback& onConnectFailed)
133{
Chengyu Fan4381fb62015-01-14 11:37:04 -0700134 BOOST_ASSERT(uri.isCanonical());
135 boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(uri.getHost());
136 tcp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(uri.getPort()));
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800137
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600138 if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end())
139 {
140 onConnectFailed("Requested endpoint is prohibited "
141 "(reserved by this NFD or disallowed by face management protocol)");
142 return;
143 }
144
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800145 // very simple logic for now
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800146 for (ChannelMap::iterator channel = m_channels.begin();
147 channel != m_channels.end();
148 ++channel)
149 {
150 if ((channel->first.address().is_v4() && endpoint.address().is_v4()) ||
151 (channel->first.address().is_v6() && endpoint.address().is_v6()))
152 {
153 channel->second->connect(endpoint, onCreated, onConnectFailed);
154 return;
155 }
156 }
157 onConnectFailed("No channels available to connect to "
158 + boost::lexical_cast<std::string>(endpoint));
159}
160
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600161std::list<shared_ptr<const Channel> >
162TcpFactory::getChannels() const
163{
164 std::list<shared_ptr<const Channel> > channels;
165 for (ChannelMap::const_iterator i = m_channels.begin(); i != m_channels.end(); ++i)
166 {
167 channels.push_back(i->second);
168 }
169
170 return channels;
171}
172
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800173} // namespace nfd