blob: 78e5837ff5ea34c0146c7e70d487d34c498c9e0e [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
Nick Gordon56d1fae2017-05-26 16:39:25 -0500115bool
116NameLsa::isEqualContent(const NameLsa& other) const
117{
118 return m_npl == other.getNpl();
119}
120
akmhoque53353462014-04-22 08:43:45 -0500121void
122NameLsa::writeLog()
123{
akmhoque674b0b12014-05-20 14:33:28 -0500124 _LOG_DEBUG("Name Lsa: ");
125 _LOG_DEBUG(" Origination Router: " << m_origRouter);
126 _LOG_DEBUG(" Ls Type: " << m_lsType);
127 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500128 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500129 _LOG_DEBUG(" Names: ");
130 int i = 1;
131 std::list<ndn::Name> nl = m_npl.getNameList();
132 for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++)
133 {
134 _LOG_DEBUG(" Name " << i << ": " << (*it));
135 }
akmhoque2f423352014-06-03 11:49:35 -0500136 _LOG_DEBUG("name_lsa_end");
akmhoque53353462014-04-22 08:43:45 -0500137}
138
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600139CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500140 const ndn::time::system_clock::TimePoint& lt,
141 double r, double theta)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600142 : Lsa(CoordinateLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -0500143{
144 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500145 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500146 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500147 m_corRad = r;
148 m_corTheta = theta;
149}
150
akmhoque31d1d4b2014-05-05 22:08:14 -0500151const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -0500152CoordinateLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500153{
akmhoque31d1d4b2014-05-05 22:08:14 -0500154 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -0600155 key.append(CoordinateLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -0500156 return key;
157}
158
159bool
akmhoquefdbddb12014-05-02 18:35:19 -0500160CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500161{
162 return (std::abs(m_corRad - clsa.getCorRadius()) <
163 std::numeric_limits<double>::epsilon()) &&
164 (std::abs(m_corTheta - clsa.getCorTheta()) <
165 std::numeric_limits<double>::epsilon());
166}
167
168string
akmhoqueb6450b12014-04-24 00:01:03 -0500169CoordinateLsa::getData()
akmhoque53353462014-04-22 08:43:45 -0500170{
Nick Gordonadad2492017-05-25 10:53:07 -0500171 std::ostringstream os;
172 os << m_origRouter << "|" << CoordinateLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
173 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_corRad << "|"
174 << m_corTheta << "|";
175 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500176}
177
178bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500179CoordinateLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500180{
akmhoque31d1d4b2014-05-05 22:08:14 -0500181 boost::char_separator<char> sep("|");
182 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
183 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
184 tokens.begin();
185 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500186 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500187 return false;
188 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500189 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600190 if (*tok_iter++ != CoordinateLsa::TYPE_STRING) {
191 return false;
192 }
193
akmhoque31d1d4b2014-05-05 22:08:14 -0500194 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500195 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500196 m_corRad = boost::lexical_cast<double>(*tok_iter++);
197 m_corTheta = boost::lexical_cast<double>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500198 }
Nick Gordonadad2492017-05-25 10:53:07 -0500199 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600200 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500201 return false;
202 }
203 return true;
204}
205
akmhoque674b0b12014-05-20 14:33:28 -0500206void
207CoordinateLsa::writeLog()
208{
209 _LOG_DEBUG("Cor Lsa: ");
210 _LOG_DEBUG(" Origination Router: " << m_origRouter);
211 _LOG_DEBUG(" Ls Type: " << m_lsType);
212 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500213 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500214 _LOG_DEBUG(" Hyperbolic Radius: " << m_corRad);
Vince Lehman9a709032014-09-13 16:28:07 -0500215 _LOG_DEBUG(" Hyperbolic Theta: " << m_corTheta);
akmhoque674b0b12014-05-20 14:33:28 -0500216}
217
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600218AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500219 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -0500220 uint32_t nl , AdjacencyList& adl)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600221 : Lsa(AdjLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -0500222{
223 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500224 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500225 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500226 m_noLink = nl;
akmhoquec8a10f72014-04-25 18:42:55 -0500227 std::list<Adjacent> al = adl.getAdjList();
akmhoque157b0a42014-05-13 00:26:37 -0500228 for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500229 if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
akmhoque53353462014-04-22 08:43:45 -0500230 addAdjacent((*it));
231 }
232 }
233}
234
akmhoque31d1d4b2014-05-05 22:08:14 -0500235const ndn::Name
236AdjLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500237{
akmhoque31d1d4b2014-05-05 22:08:14 -0500238 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -0600239 key.append(AdjLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -0500240 return key;
241}
242
243bool
akmhoquefdbddb12014-05-02 18:35:19 -0500244AdjLsa::isEqualContent(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500245{
akmhoquefdbddb12014-05-02 18:35:19 -0500246 return m_adl == alsa.getAdl();
akmhoque53353462014-04-22 08:43:45 -0500247}
248
akmhoque53353462014-04-22 08:43:45 -0500249string
250AdjLsa::getData()
251{
Nick Gordonadad2492017-05-25 10:53:07 -0500252 std::ostringstream os;
253 os << m_origRouter << "|" << AdjLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
254 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_adl.getSize();
255 for (const auto& adjacent : m_adl.getAdjList()) {
Nick Gordone9733ed2017-04-26 10:48:39 -0500256 os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
Nick Gordonadad2492017-05-25 10:53:07 -0500257 << "|" << adjacent.getLinkCost();
akmhoque53353462014-04-22 08:43:45 -0500258 }
Nick Gordonadad2492017-05-25 10:53:07 -0500259 os << "|";
260 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500261}
262
263bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500264AdjLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500265{
266 uint32_t numLink = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500267 boost::char_separator<char> sep("|");
268 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
269 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
270 tokens.begin();
271 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500272 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500273 return false;
274 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500275 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600276 if (*tok_iter++ != AdjLsa::TYPE_STRING) {
277 return false;
278 }
279
akmhoque31d1d4b2014-05-05 22:08:14 -0500280 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500281 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500282 numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500283 }
Nick Gordonadad2492017-05-25 10:53:07 -0500284 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600285 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500286 return false;
287 }
akmhoque157b0a42014-05-13 00:26:37 -0500288 for (uint32_t i = 0; i < numLink; i++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500289 try {
akmhoque778f81b2014-06-27 10:07:56 -0500290 ndn::Name adjName(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500291 std::string connectingFaceUri(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500292 double linkCost = boost::lexical_cast<double>(*tok_iter++);
Nick Gordone9733ed2017-04-26 10:48:39 -0500293 Adjacent adjacent(adjName, ndn::util::FaceUri(connectingFaceUri), linkCost,
294 Adjacent::STATUS_INACTIVE, 0, 0);
akmhoque53353462014-04-22 08:43:45 -0500295 addAdjacent(adjacent);
296 }
Nick Gordonadad2492017-05-25 10:53:07 -0500297 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600298 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500299 return false;
300 }
301 }
302 return true;
303}
304
akmhoque53353462014-04-22 08:43:45 -0500305void
306AdjLsa::addNptEntries(Nlsr& pnlsr)
307{
Nick G97e34942016-07-11 14:46:27 -0500308 // Only add NPT entries if this is an adj LSA from another router.
akmhoque157b0a42014-05-13 00:26:37 -0500309 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
Nick G97e34942016-07-11 14:46:27 -0500310 // Pass the originating router as both the name to register and
311 // where it came from.
akmhoque31d1d4b2014-05-05 22:08:14 -0500312 pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500313 }
314}
315
316
317void
318AdjLsa::removeNptEntries(Nlsr& pnlsr)
319{
akmhoque157b0a42014-05-13 00:26:37 -0500320 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500321 pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500322 }
323}
324
akmhoque674b0b12014-05-20 14:33:28 -0500325void
326AdjLsa::writeLog()
327{
alvydce3f182015-04-09 11:23:30 -0500328 _LOG_DEBUG(*this);
akmhoque53353462014-04-22 08:43:45 -0500329}
330
alvydce3f182015-04-09 11:23:30 -0500331std::ostream&
332operator<<(std::ostream& os, const AdjLsa& adjLsa)
333{
334 os << "Adj Lsa:\n"
335 << " Origination Router: " << adjLsa.getOrigRouter() << "\n"
336 << " Ls Type: " << adjLsa.getLsType() << "\n"
337 << " Ls Seq No: " << adjLsa.getLsSeqNo() << "\n"
338 << " Ls Lifetime: " << adjLsa.getExpirationTimePoint() << "\n"
339 << " Adjacents: \n";
340
341 int adjacencyIndex = 1;
342
343 for (const Adjacent& adjacency : adjLsa) {
344 os << " Adjacent " << adjacencyIndex++ << ":\n"
345 << " Adjacent Name: " << adjacency.getName() << "\n"
Nick Gordone9733ed2017-04-26 10:48:39 -0500346 << " Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
alvydce3f182015-04-09 11:23:30 -0500347 << " Link Cost: " << adjacency.getLinkCost() << "\n";
348 }
349 os << "adj_lsa_end";
350
351 return os;
352}
353
354} // namespace nlsr