blob: 1413b39a7f71042ad538ab4f5b3fba12bb047c8a [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Nick Gordonfeae5572017-01-13 12:06:26 -06003 * Copyright (c) 2014-2017, The University of Memphis,
Vince Lehmanc2e51f62015-01-20 15:03:11 -06004 * Regents of the University of California,
5 * Arizona Board of Regents.
akmhoque3d06e792014-05-27 16:23:20 -05006 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
akmhoque3d06e792014-05-27 16:23:20 -050020 **/
Vince Lehmanc2e51f62015-01-20 15:03:11 -060021
akmhoque53353462014-04-22 08:43:45 -050022#include "sync-logic-handler.hpp"
Vince Lehman904c2412014-09-23 19:36:11 -050023
Vince Lehman0a7da612014-10-29 14:39:29 -050024#include "common.hpp"
Vince Lehman904c2412014-09-23 19:36:11 -050025#include "conf-parameter.hpp"
akmhoque674b0b12014-05-20 14:33:28 -050026#include "logger.hpp"
Vince Lehman904c2412014-09-23 19:36:11 -050027#include "lsa.hpp"
28#include "lsdb.hpp"
Vince Lehman904c2412014-09-23 19:36:11 -050029#include "utility/name-helper.hpp"
30
akmhoque53353462014-04-22 08:43:45 -050031namespace nlsr {
32
akmhoque674b0b12014-05-20 14:33:28 -050033INIT_LOGGER("SyncLogicHandler");
34
akmhoquefdbddb12014-05-02 18:35:19 -050035using namespace ndn;
36using namespace std;
37
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050038const std::string NLSR_COMPONENT = "NLSR";
39const std::string LSA_COMPONENT = "LSA";
Vince Lehman904c2412014-09-23 19:36:11 -050040
Alexander Afanasyev7c8882f2014-10-28 12:12:15 -070041template<class T>
42class NullDeleter
43{
44public:
45 void
46 operator()(T*)
47 {
48 }
49};
50
Vince Lehman0bcf9a32014-12-10 11:24:45 -060051SyncLogicHandler::SyncLogicHandler(ndn::Face& face,
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050052 Lsdb& lsdb, ConfParameter& conf)
53 : m_syncFace(face)
Vince Lehman0bcf9a32014-12-10 11:24:45 -060054 , m_lsdb(lsdb)
55 , m_confParam(conf)
Vince Lehman0bcf9a32014-12-10 11:24:45 -060056{
Vince Lehman0bcf9a32014-12-10 11:24:45 -060057}
58
akmhoque53353462014-04-22 08:43:45 -050059void
Vince Lehman9d097802015-03-16 17:55:59 -050060SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix)
akmhoque53353462014-04-22 08:43:45 -050061{
Vince Lehman9d097802015-03-16 17:55:59 -050062 if (m_syncSocket != nullptr) {
63 _LOG_WARN("Trying to create Sync socket, but Sync socket already exists");
64 return;
65 }
66
67 m_syncPrefix = syncPrefix;
68
69 // Build LSA sync update prefix
70 buildUpdatePrefix();
71
akmhoque674b0b12014-05-20 14:33:28 -050072 _LOG_DEBUG("Creating Sync socket. Sync Prefix: " << m_syncPrefix);
Vince Lehman904c2412014-09-23 19:36:11 -050073
74 // The face's lifetime is managed in main.cpp; SyncSocket should not manage the memory
75 // of the object
dmcoomes9f936662017-03-02 10:33:09 -060076 std::shared_ptr<ndn::Face> facePtr(&m_syncFace, NullDeleter<ndn::Face>());
Vince Lehman904c2412014-09-23 19:36:11 -050077
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050078
79 m_syncSocket = std::make_shared<chronosync::Socket>(m_syncPrefix, m_nameLsaUserPrefix, *facePtr,
Ashlesh Gawande415676b2016-12-22 00:26:23 -060080 bind(&SyncLogicHandler::onNsyncUpdate, this, _1));
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050081
82 if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
83 m_syncSocket->addSyncNode(m_adjLsaUserPrefix);
84 }
85 else {
86 m_syncSocket->addSyncNode(m_coorLsaUserPrefix);
87 }
akmhoque53353462014-04-22 08:43:45 -050088}
89
90void
Ashlesh Gawande415676b2016-12-22 00:26:23 -060091SyncLogicHandler::onNsyncUpdate(const vector<chronosync::MissingDataInfo>& v)
akmhoque53353462014-04-22 08:43:45 -050092{
Vince Lehman904c2412014-09-23 19:36:11 -050093 _LOG_DEBUG("Received Nsync update event");
94
95 for (size_t i = 0; i < v.size(); i++){
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050096 ndn::Name updateName = v[i].session.getPrefix(-1);
Vince Lehman904c2412014-09-23 19:36:11 -050097
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050098 _LOG_DEBUG("Update Name: " << updateName << " Seq no: " << v[i].high);
Vince Lehman904c2412014-09-23 19:36:11 -050099
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500100 int32_t nlsrPosition = util::getNameComponentPosition(updateName, nlsr::NLSR_COMPONENT);
101 int32_t lsaPosition = util::getNameComponentPosition(updateName, nlsr::LSA_COMPONENT);
102
103 if (nlsrPosition < 0 || lsaPosition < 0) {
104 _LOG_WARN("Received malformed sync update");
105 return;
106 }
107
108 ndn::Name networkName = updateName.getSubName(1, nlsrPosition-1);
109 ndn::Name routerName = updateName.getSubName(lsaPosition + 1).getPrefix(-1);
110
111 ndn::Name originRouter = networkName;
112 originRouter.append(routerName);
113
114 processUpdateFromSync(originRouter, updateName, v[i].high);
akmhoque53353462014-04-22 08:43:45 -0500115 }
116}
117
118void
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500119SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
120 const ndn::Name& updateName, const uint64_t& seqNo)
akmhoque53353462014-04-22 08:43:45 -0500121{
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500122 _LOG_DEBUG("Origin Router of update: " << originRouter);
akmhoque53353462014-04-22 08:43:45 -0500123
Vince Lehman904c2412014-09-23 19:36:11 -0500124 // A router should not try to fetch its own LSA
125 if (originRouter != m_confParam.getRouterPrefix()) {
126
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500127 std::string lsaType = updateName.get(updateName.size()-1).toUri();
Vince Lehman904c2412014-09-23 19:36:11 -0500128
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500129 _LOG_DEBUG("Received sync update with higher " << lsaType
130 << " sequence number than entry in LSDB");
Vince Lehman904c2412014-09-23 19:36:11 -0500131
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500132 if (isLsaNew(originRouter, lsaType, seqNo)) {
133 if (lsaType == AdjLsa::TYPE_STRING && seqNo != 0 &&
134 m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
135 _LOG_ERROR("Got an update for adjacency LSA when hyperbolic routing"
136 << " is enabled. Not going to fetch.");
137 return;
akmhoque31d1d4b2014-05-05 22:08:14 -0500138 }
Vince Lehman904c2412014-09-23 19:36:11 -0500139
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500140 if (lsaType == CoordinateLsa::TYPE_STRING && seqNo != 0 &&
141 m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
142 _LOG_ERROR("Got an update for coordinate LSA when link-state"
143 << " is enabled. Not going to fetch.");
144 return;
akmhoque31d1d4b2014-05-05 22:08:14 -0500145 }
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500146 expressInterestForLsa(updateName, seqNo);
147 }
akmhoque53353462014-04-22 08:43:45 -0500148 }
149}
150
Vince Lehman904c2412014-09-23 19:36:11 -0500151bool
152SyncLogicHandler::isLsaNew(const ndn::Name& originRouter, const std::string& lsaType,
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500153 const uint64_t& seqNo)
akmhoque53353462014-04-22 08:43:45 -0500154{
Vince Lehman904c2412014-09-23 19:36:11 -0500155 ndn::Name lsaKey = originRouter;
156 lsaKey.append(lsaType);
157
alvy49b1c0c2014-12-19 13:57:46 -0600158 if (lsaType == NameLsa::TYPE_STRING)
Vince Lehman904c2412014-09-23 19:36:11 -0500159 {
160 return m_lsdb.isNameLsaNew(lsaKey, seqNo);
161 }
alvy49b1c0c2014-12-19 13:57:46 -0600162 else if (lsaType == AdjLsa::TYPE_STRING)
Vince Lehman904c2412014-09-23 19:36:11 -0500163 {
164 return m_lsdb.isAdjLsaNew(lsaKey, seqNo);
165 }
alvy49b1c0c2014-12-19 13:57:46 -0600166 else if (lsaType == CoordinateLsa::TYPE_STRING)
Vince Lehman904c2412014-09-23 19:36:11 -0500167 {
168 return m_lsdb.isCoordinateLsaNew(lsaKey, seqNo);
169 }
170
171 return false;
akmhoque53353462014-04-22 08:43:45 -0500172}
173
akmhoque53353462014-04-22 08:43:45 -0500174void
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500175SyncLogicHandler::expressInterestForLsa(const ndn::Name& updateName,
176 const uint64_t& seqNo)
akmhoque53353462014-04-22 08:43:45 -0500177{
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500178 ndn::Name interest(updateName);
Vince Lehman904c2412014-09-23 19:36:11 -0500179 interest.appendNumber(seqNo);
180
181 m_lsdb.expressInterest(interest, 0);
182}
183
184void
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500185SyncLogicHandler::publishRoutingUpdate(const ndn::Name& type, const uint64_t& seqNo)
Vince Lehman904c2412014-09-23 19:36:11 -0500186{
Vince Lehman9d097802015-03-16 17:55:59 -0500187 if (m_syncSocket == nullptr) {
188 _LOG_FATAL("Cannot publish routing update; SyncSocket does not exist");
189
dmcoomes9f936662017-03-02 10:33:09 -0600190 BOOST_THROW_EXCEPTION(SyncLogicHandler::Error("Cannot publish routing update; SyncSocket does not exist"));
Vince Lehman9d097802015-03-16 17:55:59 -0500191 }
192
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500193 if (type == NameLsa::TYPE_STRING) {
194 publishSyncUpdate(m_nameLsaUserPrefix, seqNo);
195 }
196 else if (type == AdjLsa::TYPE_STRING) {
197 publishSyncUpdate(m_adjLsaUserPrefix, seqNo);
198 }
199 else {
200 publishSyncUpdate(m_coorLsaUserPrefix, seqNo);
201 }
Vince Lehman904c2412014-09-23 19:36:11 -0500202}
203
204void
Vince Lehmanc11cc202015-01-20 11:41:33 -0600205SyncLogicHandler::buildUpdatePrefix()
206{
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500207 ndn::Name updatePrefix = m_confParam.getLsaPrefix();
208 updatePrefix.append(m_confParam.getSiteName());
209 updatePrefix.append(m_confParam.getRouterName());
210
211 m_nameLsaUserPrefix = updatePrefix;
212 m_nameLsaUserPrefix.append(NameLsa::TYPE_STRING);
213
214 m_adjLsaUserPrefix = updatePrefix;
215 m_adjLsaUserPrefix.append(AdjLsa::TYPE_STRING);
216
217 m_coorLsaUserPrefix = updatePrefix;
218 m_coorLsaUserPrefix.append(CoordinateLsa::TYPE_STRING);
Vince Lehmanc11cc202015-01-20 11:41:33 -0600219}
220
221void
Vince Lehman904c2412014-09-23 19:36:11 -0500222SyncLogicHandler::publishSyncUpdate(const ndn::Name& updatePrefix, uint64_t seqNo)
223{
224 _LOG_DEBUG("Publishing Sync Update. Prefix: " << updatePrefix << " Seq No: " << seqNo);
225
akmhoque53353462014-04-22 08:43:45 -0500226 ndn::Name updateName(updatePrefix);
227 string data("NoData");
Vince Lehman904c2412014-09-23 19:36:11 -0500228
Ashlesh Gawande415676b2016-12-22 00:26:23 -0600229 m_syncSocket->publishData(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(),
230 ndn::time::milliseconds(1000), seqNo, updateName);
akmhoque53353462014-04-22 08:43:45 -0500231}
232
Nick Gordonfad8e252016-08-11 14:21:38 -0500233} // namespace nlsr