blob: 440c2bab52f00c6f95778c47610118b0a208c86d [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
Nick Gordonf14ec352017-07-24 16:09:58 -050022#include "lsa.hpp"
23#include "nlsr.hpp"
24#include "name-prefix-list.hpp"
25#include "adjacent.hpp"
26#include "logger.hpp"
27
akmhoque53353462014-04-22 08:43:45 -050028#include <string>
29#include <iostream>
30#include <sstream>
31#include <algorithm>
32#include <cmath>
33#include <limits>
akmhoque31d1d4b2014-05-05 22:08:14 -050034#include <boost/tokenizer.hpp>
35#include <boost/algorithm/string.hpp>
akmhoque53353462014-04-22 08:43:45 -050036
akmhoque53353462014-04-22 08:43:45 -050037namespace nlsr {
38
akmhoque674b0b12014-05-20 14:33:28 -050039INIT_LOGGER("Lsa");
40
alvy49b1c0c2014-12-19 13:57:46 -060041const std::string NameLsa::TYPE_STRING = "name";
42const std::string AdjLsa::TYPE_STRING = "adjacency";
43const std::string CoordinateLsa::TYPE_STRING = "coordinate";
44
akmhoque31d1d4b2014-05-05 22:08:14 -050045const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -050046NameLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -050047{
akmhoque31d1d4b2014-05-05 22:08:14 -050048 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -060049 key.append(NameLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -050050 return key;
51}
52
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060053NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -050054 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -050055 NamePrefixList& npl)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060056 : Lsa(NameLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -050057{
58 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -050059 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -050060 m_expirationTimePoint = lt;
Nick Gordonf14ec352017-07-24 16:09:58 -050061 for (const auto& name : npl.getNames()) {
62 addName(name);
akmhoque53353462014-04-22 08:43:45 -050063 }
64}
65
Nick Gordone98480b2017-05-24 11:23:03 -050066std::string
akmhoque53353462014-04-22 08:43:45 -050067NameLsa::getData()
68{
Nick Gordonadad2492017-05-25 10:53:07 -050069 std::ostringstream os;
70 os << m_origRouter << "|" << NameLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
71 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_npl.getSize();
Nick Gordonf14ec352017-07-24 16:09:58 -050072 for (const auto& name : m_npl.getNames()) {
Nick Gordonadad2492017-05-25 10:53:07 -050073 os << "|" << name;
akmhoque53353462014-04-22 08:43:45 -050074 }
Nick Gordonadad2492017-05-25 10:53:07 -050075 os << "|";
76 return os.str();
akmhoque53353462014-04-22 08:43:45 -050077}
78
79bool
akmhoque31d1d4b2014-05-05 22:08:14 -050080NameLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -050081{
82 uint32_t numName = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -050083 boost::char_separator<char> sep("|");
84 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
85 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
86 tokens.begin();
87 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -050088 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -050089 return false;
90 }
akmhoque31d1d4b2014-05-05 22:08:14 -050091 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060092 if (*tok_iter++ != NameLsa::TYPE_STRING) {
93 return false;
94 }
95
akmhoque31d1d4b2014-05-05 22:08:14 -050096 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -050097 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -050098 numName = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -050099 }
Nick Gordonadad2492017-05-25 10:53:07 -0500100 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600101 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500102 return false;
103 }
akmhoque157b0a42014-05-13 00:26:37 -0500104 for (uint32_t i = 0; i < numName; i++) {
akmhoque778f81b2014-06-27 10:07:56 -0500105 ndn::Name name(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500106 addName(name);
107 }
108 return true;
109}
110
Nick Gordon56d1fae2017-05-26 16:39:25 -0500111bool
112NameLsa::isEqualContent(const NameLsa& other) const
113{
114 return m_npl == other.getNpl();
115}
116
akmhoque53353462014-04-22 08:43:45 -0500117void
118NameLsa::writeLog()
119{
akmhoque674b0b12014-05-20 14:33:28 -0500120 _LOG_DEBUG("Name Lsa: ");
121 _LOG_DEBUG(" Origination Router: " << m_origRouter);
122 _LOG_DEBUG(" Ls Type: " << m_lsType);
123 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500124 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500125 _LOG_DEBUG(" Names: ");
126 int i = 1;
Nick Gordonf14ec352017-07-24 16:09:58 -0500127 std::list<ndn::Name> nl = m_npl.getNames();
akmhoque674b0b12014-05-20 14:33:28 -0500128 for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++)
129 {
130 _LOG_DEBUG(" Name " << i << ": " << (*it));
131 }
akmhoque2f423352014-06-03 11:49:35 -0500132 _LOG_DEBUG("name_lsa_end");
akmhoque53353462014-04-22 08:43:45 -0500133}
134
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600135CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500136 const ndn::time::system_clock::TimePoint& lt,
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600137 double r, std::vector<double> theta)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600138 : Lsa(CoordinateLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -0500139{
140 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500141 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500142 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500143 m_corRad = r;
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600144 m_angles = theta;
akmhoque53353462014-04-22 08:43:45 -0500145}
146
akmhoque31d1d4b2014-05-05 22:08:14 -0500147const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -0500148CoordinateLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500149{
akmhoque31d1d4b2014-05-05 22:08:14 -0500150 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -0600151 key.append(CoordinateLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -0500152 return key;
153}
154
155bool
akmhoquefdbddb12014-05-02 18:35:19 -0500156CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500157{
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600158 if (clsa.getCorTheta().size() != m_angles.size()) {
159 return false;
160 }
161
162 std::vector<double> m_angles2 = clsa.getCorTheta();
163 for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
164 if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
165 return false;
166 }
167 }
168
akmhoque53353462014-04-22 08:43:45 -0500169 return (std::abs(m_corRad - clsa.getCorRadius()) <
akmhoque53353462014-04-22 08:43:45 -0500170 std::numeric_limits<double>::epsilon());
171}
172
Nick Gordone98480b2017-05-24 11:23:03 -0500173std::string
akmhoqueb6450b12014-04-24 00:01:03 -0500174CoordinateLsa::getData()
akmhoque53353462014-04-22 08:43:45 -0500175{
Nick Gordonadad2492017-05-25 10:53:07 -0500176 std::ostringstream os;
177 os << m_origRouter << "|" << CoordinateLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
178 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_corRad << "|"
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600179 << m_angles.size() << "|";
180
181 for (const auto& angle: m_angles) {
182 os << angle << "|";
183 }
184
Nick Gordonadad2492017-05-25 10:53:07 -0500185 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500186}
187
188bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500189CoordinateLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500190{
akmhoque31d1d4b2014-05-05 22:08:14 -0500191 boost::char_separator<char> sep("|");
192 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
193 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
194 tokens.begin();
195 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500196 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500197 return false;
198 }
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600199
akmhoque31d1d4b2014-05-05 22:08:14 -0500200 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600201 if (*tok_iter++ != CoordinateLsa::TYPE_STRING) {
202 return false;
203 }
204
akmhoque31d1d4b2014-05-05 22:08:14 -0500205 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500206 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500207 m_corRad = boost::lexical_cast<double>(*tok_iter++);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600208 int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
209
210 for (int i = 0; i < numAngles; i++) {
211 m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
212 }
akmhoque53353462014-04-22 08:43:45 -0500213 }
Nick Gordonadad2492017-05-25 10:53:07 -0500214 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600215 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500216 return false;
217 }
218 return true;
219}
220
akmhoque674b0b12014-05-20 14:33:28 -0500221void
222CoordinateLsa::writeLog()
223{
224 _LOG_DEBUG("Cor Lsa: ");
225 _LOG_DEBUG(" Origination Router: " << m_origRouter);
226 _LOG_DEBUG(" Ls Type: " << m_lsType);
227 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500228 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500229 _LOG_DEBUG(" Hyperbolic Radius: " << m_corRad);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600230 int i = 0;
231 for(auto const& value: m_angles) {
232 _LOG_DEBUG(" Hyperbolic Theta " << i++ << ": "<< value);
233 }
akmhoque674b0b12014-05-20 14:33:28 -0500234}
235
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600236AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500237 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -0500238 uint32_t nl , AdjacencyList& adl)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600239 : Lsa(AdjLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -0500240{
241 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500242 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500243 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500244 m_noLink = nl;
akmhoquec8a10f72014-04-25 18:42:55 -0500245 std::list<Adjacent> al = adl.getAdjList();
akmhoque157b0a42014-05-13 00:26:37 -0500246 for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500247 if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
akmhoque53353462014-04-22 08:43:45 -0500248 addAdjacent((*it));
249 }
250 }
251}
252
akmhoque31d1d4b2014-05-05 22:08:14 -0500253const ndn::Name
254AdjLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500255{
akmhoque31d1d4b2014-05-05 22:08:14 -0500256 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -0600257 key.append(AdjLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -0500258 return key;
259}
260
261bool
akmhoquefdbddb12014-05-02 18:35:19 -0500262AdjLsa::isEqualContent(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500263{
akmhoquefdbddb12014-05-02 18:35:19 -0500264 return m_adl == alsa.getAdl();
akmhoque53353462014-04-22 08:43:45 -0500265}
266
Nick Gordone98480b2017-05-24 11:23:03 -0500267std::string
akmhoque53353462014-04-22 08:43:45 -0500268AdjLsa::getData()
269{
Nick Gordonadad2492017-05-25 10:53:07 -0500270 std::ostringstream os;
271 os << m_origRouter << "|" << AdjLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
272 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_adl.getSize();
273 for (const auto& adjacent : m_adl.getAdjList()) {
Nick Gordone9733ed2017-04-26 10:48:39 -0500274 os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
Nick Gordonadad2492017-05-25 10:53:07 -0500275 << "|" << adjacent.getLinkCost();
akmhoque53353462014-04-22 08:43:45 -0500276 }
Nick Gordonadad2492017-05-25 10:53:07 -0500277 os << "|";
278 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500279}
280
281bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500282AdjLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500283{
284 uint32_t numLink = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500285 boost::char_separator<char> sep("|");
286 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
287 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
288 tokens.begin();
289 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500290 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500291 return false;
292 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500293 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600294 if (*tok_iter++ != AdjLsa::TYPE_STRING) {
295 return false;
296 }
297
akmhoque31d1d4b2014-05-05 22:08:14 -0500298 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500299 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500300 numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500301 }
Nick Gordonadad2492017-05-25 10:53:07 -0500302 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600303 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500304 return false;
305 }
akmhoque157b0a42014-05-13 00:26:37 -0500306 for (uint32_t i = 0; i < numLink; i++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500307 try {
akmhoque778f81b2014-06-27 10:07:56 -0500308 ndn::Name adjName(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500309 std::string connectingFaceUri(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500310 double linkCost = boost::lexical_cast<double>(*tok_iter++);
Nick Gordone9733ed2017-04-26 10:48:39 -0500311 Adjacent adjacent(adjName, ndn::util::FaceUri(connectingFaceUri), linkCost,
312 Adjacent::STATUS_INACTIVE, 0, 0);
akmhoque53353462014-04-22 08:43:45 -0500313 addAdjacent(adjacent);
314 }
Nick Gordonadad2492017-05-25 10:53:07 -0500315 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600316 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500317 return false;
318 }
319 }
320 return true;
321}
322
akmhoque53353462014-04-22 08:43:45 -0500323void
324AdjLsa::addNptEntries(Nlsr& pnlsr)
325{
Nick G97e34942016-07-11 14:46:27 -0500326 // Only add NPT entries if this is an adj LSA from another router.
akmhoque157b0a42014-05-13 00:26:37 -0500327 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
Nick G97e34942016-07-11 14:46:27 -0500328 // Pass the originating router as both the name to register and
329 // where it came from.
akmhoque31d1d4b2014-05-05 22:08:14 -0500330 pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500331 }
332}
333
334
335void
336AdjLsa::removeNptEntries(Nlsr& pnlsr)
337{
akmhoque157b0a42014-05-13 00:26:37 -0500338 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500339 pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500340 }
341}
342
akmhoque674b0b12014-05-20 14:33:28 -0500343void
344AdjLsa::writeLog()
345{
alvydce3f182015-04-09 11:23:30 -0500346 _LOG_DEBUG(*this);
akmhoque53353462014-04-22 08:43:45 -0500347}
348
alvydce3f182015-04-09 11:23:30 -0500349std::ostream&
350operator<<(std::ostream& os, const AdjLsa& adjLsa)
351{
352 os << "Adj Lsa:\n"
353 << " Origination Router: " << adjLsa.getOrigRouter() << "\n"
354 << " Ls Type: " << adjLsa.getLsType() << "\n"
355 << " Ls Seq No: " << adjLsa.getLsSeqNo() << "\n"
356 << " Ls Lifetime: " << adjLsa.getExpirationTimePoint() << "\n"
357 << " Adjacents: \n";
358
359 int adjacencyIndex = 1;
360
361 for (const Adjacent& adjacency : adjLsa) {
362 os << " Adjacent " << adjacencyIndex++ << ":\n"
363 << " Adjacent Name: " << adjacency.getName() << "\n"
Nick Gordone9733ed2017-04-26 10:48:39 -0500364 << " Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
alvydce3f182015-04-09 11:23:30 -0500365 << " Link Cost: " << adjacency.getLinkCost() << "\n";
366 }
367 os << "adj_lsa_end";
368
369 return os;
370}
371
372} // namespace nlsr