blob: 52a99484cae80a1c560f6304978b2122009883bc [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 <string>
23#include <iostream>
24#include <sstream>
25#include <algorithm>
26#include <cmath>
27#include <limits>
akmhoque31d1d4b2014-05-05 22:08:14 -050028#include <boost/tokenizer.hpp>
29#include <boost/algorithm/string.hpp>
akmhoque53353462014-04-22 08:43:45 -050030
31#include "nlsr.hpp"
32#include "lsa.hpp"
akmhoquec8a10f72014-04-25 18:42:55 -050033#include "name-prefix-list.hpp"
akmhoque53353462014-04-22 08:43:45 -050034#include "adjacent.hpp"
akmhoque674b0b12014-05-20 14:33:28 -050035#include "logger.hpp"
akmhoque53353462014-04-22 08:43:45 -050036
37
38namespace nlsr {
39
akmhoque674b0b12014-05-20 14:33:28 -050040INIT_LOGGER("Lsa");
41
akmhoque53353462014-04-22 08:43:45 -050042using namespace std;
43
alvy49b1c0c2014-12-19 13:57:46 -060044const std::string NameLsa::TYPE_STRING = "name";
45const std::string AdjLsa::TYPE_STRING = "adjacency";
46const std::string CoordinateLsa::TYPE_STRING = "coordinate";
47
akmhoque31d1d4b2014-05-05 22:08:14 -050048const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -050049NameLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -050050{
akmhoque31d1d4b2014-05-05 22:08:14 -050051 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -060052 key.append(NameLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -050053 return key;
54}
55
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060056NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -050057 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -050058 NamePrefixList& npl)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060059 : Lsa(NameLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -050060{
61 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -050062 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -050063 m_expirationTimePoint = lt;
akmhoque31d1d4b2014-05-05 22:08:14 -050064 std::list<ndn::Name>& nl = npl.getNameList();
akmhoque157b0a42014-05-13 00:26:37 -050065 for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++) {
akmhoque53353462014-04-22 08:43:45 -050066 addName((*it));
67 }
68}
69
70string
71NameLsa::getData()
72{
Nick Gordonadad2492017-05-25 10:53:07 -050073 std::ostringstream os;
74 os << m_origRouter << "|" << NameLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
75 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_npl.getSize();
76 for (const auto& name : m_npl.getNameList()) {
77 os << "|" << name;
akmhoque53353462014-04-22 08:43:45 -050078 }
Nick Gordonadad2492017-05-25 10:53:07 -050079 os << "|";
80 return os.str();
akmhoque53353462014-04-22 08:43:45 -050081}
82
83bool
akmhoque31d1d4b2014-05-05 22:08:14 -050084NameLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -050085{
86 uint32_t numName = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -050087 boost::char_separator<char> sep("|");
88 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
89 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
90 tokens.begin();
91 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -050092 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -050093 return false;
94 }
akmhoque31d1d4b2014-05-05 22:08:14 -050095 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060096 if (*tok_iter++ != NameLsa::TYPE_STRING) {
97 return false;
98 }
99
akmhoque31d1d4b2014-05-05 22:08:14 -0500100 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500101 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500102 numName = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500103 }
Nick Gordonadad2492017-05-25 10:53:07 -0500104 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600105 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500106 return false;
107 }
akmhoque157b0a42014-05-13 00:26:37 -0500108 for (uint32_t i = 0; i < numName; i++) {
akmhoque778f81b2014-06-27 10:07:56 -0500109 ndn::Name name(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500110 addName(name);
111 }
112 return true;
113}
114
115void
116NameLsa::writeLog()
117{
akmhoque674b0b12014-05-20 14:33:28 -0500118 _LOG_DEBUG("Name Lsa: ");
119 _LOG_DEBUG(" Origination Router: " << m_origRouter);
120 _LOG_DEBUG(" Ls Type: " << m_lsType);
121 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500122 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500123 _LOG_DEBUG(" Names: ");
124 int i = 1;
125 std::list<ndn::Name> nl = m_npl.getNameList();
126 for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++)
127 {
128 _LOG_DEBUG(" Name " << i << ": " << (*it));
129 }
akmhoque2f423352014-06-03 11:49:35 -0500130 _LOG_DEBUG("name_lsa_end");
akmhoque53353462014-04-22 08:43:45 -0500131}
132
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600133CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500134 const ndn::time::system_clock::TimePoint& lt,
135 double r, double theta)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600136 : Lsa(CoordinateLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -0500137{
138 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500139 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500140 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500141 m_corRad = r;
142 m_corTheta = theta;
143}
144
akmhoque31d1d4b2014-05-05 22:08:14 -0500145const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -0500146CoordinateLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500147{
akmhoque31d1d4b2014-05-05 22:08:14 -0500148 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -0600149 key.append(CoordinateLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -0500150 return key;
151}
152
153bool
akmhoquefdbddb12014-05-02 18:35:19 -0500154CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500155{
156 return (std::abs(m_corRad - clsa.getCorRadius()) <
157 std::numeric_limits<double>::epsilon()) &&
158 (std::abs(m_corTheta - clsa.getCorTheta()) <
159 std::numeric_limits<double>::epsilon());
160}
161
162string
akmhoqueb6450b12014-04-24 00:01:03 -0500163CoordinateLsa::getData()
akmhoque53353462014-04-22 08:43:45 -0500164{
Nick Gordonadad2492017-05-25 10:53:07 -0500165 std::ostringstream os;
166 os << m_origRouter << "|" << CoordinateLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
167 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_corRad << "|"
168 << m_corTheta << "|";
169 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500170}
171
172bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500173CoordinateLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500174{
akmhoque31d1d4b2014-05-05 22:08:14 -0500175 boost::char_separator<char> sep("|");
176 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
177 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
178 tokens.begin();
179 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500180 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500181 return false;
182 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500183 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600184 if (*tok_iter++ != CoordinateLsa::TYPE_STRING) {
185 return false;
186 }
187
akmhoque31d1d4b2014-05-05 22:08:14 -0500188 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500189 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500190 m_corRad = boost::lexical_cast<double>(*tok_iter++);
191 m_corTheta = boost::lexical_cast<double>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500192 }
Nick Gordonadad2492017-05-25 10:53:07 -0500193 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600194 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500195 return false;
196 }
197 return true;
198}
199
akmhoque674b0b12014-05-20 14:33:28 -0500200void
201CoordinateLsa::writeLog()
202{
203 _LOG_DEBUG("Cor Lsa: ");
204 _LOG_DEBUG(" Origination Router: " << m_origRouter);
205 _LOG_DEBUG(" Ls Type: " << m_lsType);
206 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500207 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500208 _LOG_DEBUG(" Hyperbolic Radius: " << m_corRad);
Vince Lehman9a709032014-09-13 16:28:07 -0500209 _LOG_DEBUG(" Hyperbolic Theta: " << m_corTheta);
akmhoque674b0b12014-05-20 14:33:28 -0500210}
211
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600212AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500213 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -0500214 uint32_t nl , AdjacencyList& adl)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600215 : Lsa(AdjLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -0500216{
217 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500218 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500219 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500220 m_noLink = nl;
akmhoquec8a10f72014-04-25 18:42:55 -0500221 std::list<Adjacent> al = adl.getAdjList();
akmhoque157b0a42014-05-13 00:26:37 -0500222 for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500223 if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
akmhoque53353462014-04-22 08:43:45 -0500224 addAdjacent((*it));
225 }
226 }
227}
228
akmhoque31d1d4b2014-05-05 22:08:14 -0500229const ndn::Name
230AdjLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500231{
akmhoque31d1d4b2014-05-05 22:08:14 -0500232 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -0600233 key.append(AdjLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -0500234 return key;
235}
236
237bool
akmhoquefdbddb12014-05-02 18:35:19 -0500238AdjLsa::isEqualContent(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500239{
akmhoquefdbddb12014-05-02 18:35:19 -0500240 return m_adl == alsa.getAdl();
akmhoque53353462014-04-22 08:43:45 -0500241}
242
akmhoque53353462014-04-22 08:43:45 -0500243string
244AdjLsa::getData()
245{
Nick Gordonadad2492017-05-25 10:53:07 -0500246 std::ostringstream os;
247 os << m_origRouter << "|" << AdjLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
248 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_adl.getSize();
249 for (const auto& adjacent : m_adl.getAdjList()) {
250 os << "|" << adjacent.getName() << "|" << adjacent.getConnectingFaceUri()
251 << "|" << adjacent.getLinkCost();
akmhoque53353462014-04-22 08:43:45 -0500252 }
Nick Gordonadad2492017-05-25 10:53:07 -0500253 os << "|";
254 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500255}
256
257bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500258AdjLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500259{
260 uint32_t numLink = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500261 boost::char_separator<char> sep("|");
262 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
263 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
264 tokens.begin();
265 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500266 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500267 return false;
268 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500269 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600270 if (*tok_iter++ != AdjLsa::TYPE_STRING) {
271 return false;
272 }
273
akmhoque31d1d4b2014-05-05 22:08:14 -0500274 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500275 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500276 numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500277 }
Nick Gordonadad2492017-05-25 10:53:07 -0500278 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600279 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500280 return false;
281 }
akmhoque157b0a42014-05-13 00:26:37 -0500282 for (uint32_t i = 0; i < numLink; i++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500283 try {
akmhoque778f81b2014-06-27 10:07:56 -0500284 ndn::Name adjName(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500285 std::string connectingFaceUri(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500286 double linkCost = boost::lexical_cast<double>(*tok_iter++);
Vince Lehmancb76ade2014-08-28 21:24:41 -0500287 Adjacent adjacent(adjName, connectingFaceUri, linkCost, Adjacent::STATUS_INACTIVE, 0, 0);
akmhoque53353462014-04-22 08:43:45 -0500288 addAdjacent(adjacent);
289 }
Nick Gordonadad2492017-05-25 10:53:07 -0500290 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600291 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500292 return false;
293 }
294 }
295 return true;
296}
297
akmhoque53353462014-04-22 08:43:45 -0500298void
299AdjLsa::addNptEntries(Nlsr& pnlsr)
300{
Nick G97e34942016-07-11 14:46:27 -0500301 // Only add NPT entries if this is an adj LSA from another router.
akmhoque157b0a42014-05-13 00:26:37 -0500302 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
Nick G97e34942016-07-11 14:46:27 -0500303 // Pass the originating router as both the name to register and
304 // where it came from.
akmhoque31d1d4b2014-05-05 22:08:14 -0500305 pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500306 }
307}
308
309
310void
311AdjLsa::removeNptEntries(Nlsr& pnlsr)
312{
akmhoque157b0a42014-05-13 00:26:37 -0500313 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500314 pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500315 }
316}
317
akmhoque674b0b12014-05-20 14:33:28 -0500318void
319AdjLsa::writeLog()
320{
alvydce3f182015-04-09 11:23:30 -0500321 _LOG_DEBUG(*this);
akmhoque53353462014-04-22 08:43:45 -0500322}
323
alvydce3f182015-04-09 11:23:30 -0500324std::ostream&
325operator<<(std::ostream& os, const AdjLsa& adjLsa)
326{
327 os << "Adj Lsa:\n"
328 << " Origination Router: " << adjLsa.getOrigRouter() << "\n"
329 << " Ls Type: " << adjLsa.getLsType() << "\n"
330 << " Ls Seq No: " << adjLsa.getLsSeqNo() << "\n"
331 << " Ls Lifetime: " << adjLsa.getExpirationTimePoint() << "\n"
332 << " Adjacents: \n";
333
334 int adjacencyIndex = 1;
335
336 for (const Adjacent& adjacency : adjLsa) {
337 os << " Adjacent " << adjacencyIndex++ << ":\n"
338 << " Adjacent Name: " << adjacency.getName() << "\n"
339 << " Connecting FaceUri: " << adjacency.getConnectingFaceUri() << "\n"
340 << " Link Cost: " << adjacency.getLinkCost() << "\n";
341 }
342 os << "adj_lsa_end";
343
344 return os;
345}
346
347} // namespace nlsr