blob: 45cd33eba400fddeae6e5dfce31f64217252bedf [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/algorithm/string.hpp>
akmhoque53353462014-04-22 08:43:45 -050035
akmhoque53353462014-04-22 08:43:45 -050036namespace nlsr {
37
akmhoque674b0b12014-05-20 14:33:28 -050038INIT_LOGGER("Lsa");
39
Nick Gordonfaf49f42017-10-23 12:36:28 -050040std::string
41Lsa::getData() const
42{
43 std::ostringstream os;
44 os << m_origRouter << "|" << getType() << "|" << m_lsSeqNo << "|"
45 << ndn::time::toIsoString(m_expirationTimePoint) << "|";
46 return os.str();
47}
48
akmhoque31d1d4b2014-05-05 22:08:14 -050049const ndn::Name
Nick Gordon22cc1a82017-10-23 13:06:53 -050050Lsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -050051{
Nick Gordon22cc1a82017-10-23 13:06:53 -050052 return ndn::Name(m_origRouter).append(std::to_string(getType()));
akmhoque53353462014-04-22 08:43:45 -050053}
54
Nick Gordon0fa4c772017-10-23 13:33:03 -050055bool
56Lsa::deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator)
57{
58 m_origRouter = ndn::Name(*iterator++);
59 if (m_origRouter.size() <= 0)
60 return false;
61 if (*iterator++ != std::to_string(getType()))
62 return false;
63 m_lsSeqNo = boost::lexical_cast<uint32_t>(*iterator++);
64 m_expirationTimePoint = ndn::time::fromIsoString(*iterator++);
65 return true;
66}
67
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060068NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -050069 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -050070 NamePrefixList& npl)
akmhoque53353462014-04-22 08:43:45 -050071{
72 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -050073 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -050074 m_expirationTimePoint = lt;
Nick Gordonf14ec352017-07-24 16:09:58 -050075 for (const auto& name : npl.getNames()) {
76 addName(name);
akmhoque53353462014-04-22 08:43:45 -050077 }
78}
79
Nick Gordone98480b2017-05-24 11:23:03 -050080std::string
Nick Gordonfaf49f42017-10-23 12:36:28 -050081NameLsa::serialize() const
akmhoque53353462014-04-22 08:43:45 -050082{
Nick Gordonadad2492017-05-25 10:53:07 -050083 std::ostringstream os;
Nick Gordonfaf49f42017-10-23 12:36:28 -050084 os << getData() << m_npl.size();
Nick Gordonf14ec352017-07-24 16:09:58 -050085 for (const auto& name : m_npl.getNames()) {
Nick Gordonadad2492017-05-25 10:53:07 -050086 os << "|" << name;
akmhoque53353462014-04-22 08:43:45 -050087 }
Nick Gordonadad2492017-05-25 10:53:07 -050088 os << "|";
89 return os.str();
akmhoque53353462014-04-22 08:43:45 -050090}
91
92bool
Nick Gordon0fa4c772017-10-23 13:33:03 -050093NameLsa::deserialize(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -050094{
95 uint32_t numName = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -050096 boost::char_separator<char> sep("|");
97 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
98 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
99 tokens.begin();
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600100
Nick Gordon0fa4c772017-10-23 13:33:03 -0500101 try {
102 if (!deserializeCommon(tok_iter))
103 return false;
akmhoque31d1d4b2014-05-05 22:08:14 -0500104 numName = boost::lexical_cast<uint32_t>(*tok_iter++);
Nick Gordon0fa4c772017-10-23 13:33:03 -0500105 for (uint32_t i = 0; i < numName; i++) {
106 ndn::Name name(*tok_iter++);
107 addName(name);
108 }
akmhoque53353462014-04-22 08:43:45 -0500109 }
Nick Gordonadad2492017-05-25 10:53:07 -0500110 catch (const std::exception& e) {
dmcoomes5bcb39e2017-10-31 15:07:55 -0500111 NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
akmhoque53353462014-04-22 08:43:45 -0500112 return false;
113 }
akmhoque53353462014-04-22 08:43:45 -0500114 return true;
115}
116
Nick Gordon56d1fae2017-05-26 16:39:25 -0500117bool
118NameLsa::isEqualContent(const NameLsa& other) const
119{
120 return m_npl == other.getNpl();
121}
122
akmhoque53353462014-04-22 08:43:45 -0500123void
124NameLsa::writeLog()
125{
dmcoomes5bcb39e2017-10-31 15:07:55 -0500126 NLSR_LOG_DEBUG("Name Lsa: ");
127 NLSR_LOG_DEBUG(" Origination Router: " << m_origRouter);
128 NLSR_LOG_DEBUG(" Ls Type: " << getType());
129 NLSR_LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
130 NLSR_LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
131 NLSR_LOG_DEBUG(" Names: ");
akmhoque674b0b12014-05-20 14:33:28 -0500132 int i = 1;
Nick Gordonf14ec352017-07-24 16:09:58 -0500133 std::list<ndn::Name> nl = m_npl.getNames();
akmhoque674b0b12014-05-20 14:33:28 -0500134 for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++)
135 {
dmcoomes5bcb39e2017-10-31 15:07:55 -0500136 NLSR_LOG_DEBUG(" Name " << i << ": " << (*it));
akmhoque674b0b12014-05-20 14:33:28 -0500137 }
dmcoomes5bcb39e2017-10-31 15:07:55 -0500138 NLSR_LOG_DEBUG("name_lsa_end");
akmhoque53353462014-04-22 08:43:45 -0500139}
140
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600141CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500142 const ndn::time::system_clock::TimePoint& lt,
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600143 double r, std::vector<double> theta)
akmhoque53353462014-04-22 08:43:45 -0500144{
145 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500146 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500147 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500148 m_corRad = r;
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600149 m_angles = theta;
akmhoque53353462014-04-22 08:43:45 -0500150}
151
akmhoque53353462014-04-22 08:43:45 -0500152bool
akmhoquefdbddb12014-05-02 18:35:19 -0500153CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500154{
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600155 if (clsa.getCorTheta().size() != m_angles.size()) {
156 return false;
157 }
158
159 std::vector<double> m_angles2 = clsa.getCorTheta();
160 for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
161 if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
162 return false;
163 }
164 }
165
akmhoque53353462014-04-22 08:43:45 -0500166 return (std::abs(m_corRad - clsa.getCorRadius()) <
akmhoque53353462014-04-22 08:43:45 -0500167 std::numeric_limits<double>::epsilon());
168}
169
Nick Gordone98480b2017-05-24 11:23:03 -0500170std::string
Nick Gordonfaf49f42017-10-23 12:36:28 -0500171CoordinateLsa::serialize() const
akmhoque53353462014-04-22 08:43:45 -0500172{
Nick Gordonadad2492017-05-25 10:53:07 -0500173 std::ostringstream os;
Nick Gordonfaf49f42017-10-23 12:36:28 -0500174 os << getData() << m_corRad << "|" << m_angles.size() << "|";
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600175 for (const auto& angle: m_angles) {
176 os << angle << "|";
177 }
Nick Gordonadad2492017-05-25 10:53:07 -0500178 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500179}
180
181bool
Nick Gordon0fa4c772017-10-23 13:33:03 -0500182CoordinateLsa::deserialize(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500183{
akmhoque31d1d4b2014-05-05 22:08:14 -0500184 boost::char_separator<char> sep("|");
185 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
186 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
187 tokens.begin();
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600188
akmhoque31d1d4b2014-05-05 22:08:14 -0500189 try {
Nick Gordon0fa4c772017-10-23 13:33:03 -0500190 if (!deserializeCommon(tok_iter))
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600191 return false;
Nick Gordon0fa4c772017-10-23 13:33:03 -0500192 m_corRad = boost::lexical_cast<double>(*tok_iter++);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600193 int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
Nick Gordon0fa4c772017-10-23 13:33:03 -0500194 for (int i = 0; i < numAngles; i++) {
195 m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
196 }
akmhoque53353462014-04-22 08:43:45 -0500197 }
Nick Gordonadad2492017-05-25 10:53:07 -0500198 catch (const std::exception& e) {
dmcoomes5bcb39e2017-10-31 15:07:55 -0500199 NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
akmhoque53353462014-04-22 08:43:45 -0500200 return false;
201 }
202 return true;
203}
204
akmhoque674b0b12014-05-20 14:33:28 -0500205void
206CoordinateLsa::writeLog()
207{
dmcoomes5bcb39e2017-10-31 15:07:55 -0500208 NLSR_LOG_DEBUG("Cor Lsa: ");
209 NLSR_LOG_DEBUG(" Origination Router: " << m_origRouter);
210 NLSR_LOG_DEBUG(" Ls Type: " << getType());
211 NLSR_LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
212 NLSR_LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
213 NLSR_LOG_DEBUG(" Hyperbolic Radius: " << m_corRad);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600214 int i = 0;
215 for(auto const& value: m_angles) {
dmcoomes5bcb39e2017-10-31 15:07:55 -0500216 NLSR_LOG_DEBUG(" Hyperbolic Theta " << i++ << ": "<< value);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600217 }
akmhoque674b0b12014-05-20 14:33:28 -0500218}
219
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600220AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500221 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -0500222 uint32_t nl , AdjacencyList& adl)
akmhoque53353462014-04-22 08:43:45 -0500223{
224 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500225 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500226 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500227 m_noLink = nl;
akmhoquec8a10f72014-04-25 18:42:55 -0500228 std::list<Adjacent> al = adl.getAdjList();
akmhoque157b0a42014-05-13 00:26:37 -0500229 for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500230 if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
akmhoque53353462014-04-22 08:43:45 -0500231 addAdjacent((*it));
232 }
233 }
234}
235
akmhoque53353462014-04-22 08:43:45 -0500236bool
akmhoquefdbddb12014-05-02 18:35:19 -0500237AdjLsa::isEqualContent(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500238{
akmhoquefdbddb12014-05-02 18:35:19 -0500239 return m_adl == alsa.getAdl();
akmhoque53353462014-04-22 08:43:45 -0500240}
241
Nick Gordone98480b2017-05-24 11:23:03 -0500242std::string
Nick Gordonfaf49f42017-10-23 12:36:28 -0500243AdjLsa::serialize() const
akmhoque53353462014-04-22 08:43:45 -0500244{
Nick Gordonadad2492017-05-25 10:53:07 -0500245 std::ostringstream os;
Nick Gordonfaf49f42017-10-23 12:36:28 -0500246 os << getData() << m_adl.size();
Nick Gordonadad2492017-05-25 10:53:07 -0500247 for (const auto& adjacent : m_adl.getAdjList()) {
Nick Gordone9733ed2017-04-26 10:48:39 -0500248 os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
Nick Gordonadad2492017-05-25 10:53:07 -0500249 << "|" << adjacent.getLinkCost();
akmhoque53353462014-04-22 08:43:45 -0500250 }
Nick Gordonadad2492017-05-25 10:53:07 -0500251 os << "|";
252 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500253}
254
255bool
Nick Gordon0fa4c772017-10-23 13:33:03 -0500256AdjLsa::deserialize(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500257{
258 uint32_t numLink = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500259 boost::char_separator<char> sep("|");
260 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
261 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
262 tokens.begin();
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600263
Nick Gordon0fa4c772017-10-23 13:33:03 -0500264 try {
265 if (!deserializeCommon(tok_iter))
266 return false;
267 numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
268 for (uint32_t i = 0; i < numLink; i++) {
akmhoque778f81b2014-06-27 10:07:56 -0500269 ndn::Name adjName(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500270 std::string connectingFaceUri(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500271 double linkCost = boost::lexical_cast<double>(*tok_iter++);
Nick Gordone9733ed2017-04-26 10:48:39 -0500272 Adjacent adjacent(adjName, ndn::util::FaceUri(connectingFaceUri), linkCost,
273 Adjacent::STATUS_INACTIVE, 0, 0);
akmhoque53353462014-04-22 08:43:45 -0500274 addAdjacent(adjacent);
275 }
Nick Gordon0fa4c772017-10-23 13:33:03 -0500276 }
277 catch (const std::exception& e) {
dmcoomes5bcb39e2017-10-31 15:07:55 -0500278 NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
Nick Gordon0fa4c772017-10-23 13:33:03 -0500279 return false;
akmhoque53353462014-04-22 08:43:45 -0500280 }
281 return true;
282}
283
akmhoque53353462014-04-22 08:43:45 -0500284void
285AdjLsa::addNptEntries(Nlsr& pnlsr)
286{
Nick G97e34942016-07-11 14:46:27 -0500287 // Only add NPT entries if this is an adj LSA from another router.
akmhoque157b0a42014-05-13 00:26:37 -0500288 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
Nick G97e34942016-07-11 14:46:27 -0500289 // Pass the originating router as both the name to register and
290 // where it came from.
akmhoque31d1d4b2014-05-05 22:08:14 -0500291 pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500292 }
293}
294
295
296void
297AdjLsa::removeNptEntries(Nlsr& pnlsr)
298{
akmhoque157b0a42014-05-13 00:26:37 -0500299 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500300 pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500301 }
302}
303
akmhoque674b0b12014-05-20 14:33:28 -0500304void
305AdjLsa::writeLog()
306{
dmcoomes5bcb39e2017-10-31 15:07:55 -0500307 NLSR_LOG_DEBUG(*this);
akmhoque53353462014-04-22 08:43:45 -0500308}
309
alvydce3f182015-04-09 11:23:30 -0500310std::ostream&
311operator<<(std::ostream& os, const AdjLsa& adjLsa)
312{
313 os << "Adj Lsa:\n"
314 << " Origination Router: " << adjLsa.getOrigRouter() << "\n"
Nick Gordon727d4832017-10-13 18:04:25 -0500315 << " Ls Type: " << adjLsa.getType() << "\n"
alvydce3f182015-04-09 11:23:30 -0500316 << " Ls Seq No: " << adjLsa.getLsSeqNo() << "\n"
317 << " Ls Lifetime: " << adjLsa.getExpirationTimePoint() << "\n"
318 << " Adjacents: \n";
319
320 int adjacencyIndex = 1;
321
322 for (const Adjacent& adjacency : adjLsa) {
323 os << " Adjacent " << adjacencyIndex++ << ":\n"
324 << " Adjacent Name: " << adjacency.getName() << "\n"
Nick Gordone9733ed2017-04-26 10:48:39 -0500325 << " Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
alvydce3f182015-04-09 11:23:30 -0500326 << " Link Cost: " << adjacency.getLinkCost() << "\n";
327 }
328 os << "adj_lsa_end";
329
330 return os;
331}
332
Nick Gordon727d4832017-10-13 18:04:25 -0500333std::ostream&
334operator<<(std::ostream& os, const Lsa::Type& type)
335{
336 os << std::to_string(type);
337 return os;
338}
339
340std::istream&
341operator>>(std::istream& is, Lsa::Type& type)
342{
343 std::string typeString;
344 is >> typeString;
345 if (typeString == "ADJACENCY") {
346 type = Lsa::Type::ADJACENCY;
347 }
348 else if (typeString == "COORDINATE") {
349 type = Lsa::Type::COORDINATE;
350 }
351 else if (typeString == "NAME") {
352 type = Lsa::Type::NAME;
353 }
354 else {
355 type = Lsa::Type::BASE;
356 }
357 return is;
358}
359
alvydce3f182015-04-09 11:23:30 -0500360} // namespace nlsr
Nick Gordon727d4832017-10-13 18:04:25 -0500361
362namespace std {
363std::string
364to_string(const nlsr::Lsa::Type& type)
365{
366 switch (type) {
367 case nlsr::Lsa::Type::ADJACENCY:
368 return "ADJACENCY";
369 case nlsr::Lsa::Type::COORDINATE:
370 return "COORDINATE";
371 case nlsr::Lsa::Type::NAME:
372 return "NAME";
Nick Gordon9212bd42017-10-23 10:59:38 -0500373 case nlsr::Lsa::Type::MOCK:
374 return "MOCK";
Nick Gordon727d4832017-10-13 18:04:25 -0500375 default:
376 return "BASE";
377 }
378}
379
380} // namespace std