blob: 7ecad7a76cd0a7ad9fdfb7b9a3e7465d570a49e6 [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
akmhoque53353462014-04-22 08:43:45 -050041using namespace std;
42
alvy49b1c0c2014-12-19 13:57:46 -060043const std::string NameLsa::TYPE_STRING = "name";
44const std::string AdjLsa::TYPE_STRING = "adjacency";
45const std::string CoordinateLsa::TYPE_STRING = "coordinate";
46
akmhoque31d1d4b2014-05-05 22:08:14 -050047const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -050048NameLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -050049{
akmhoque31d1d4b2014-05-05 22:08:14 -050050 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -060051 key.append(NameLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -050052 return key;
53}
54
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060055NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -050056 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -050057 NamePrefixList& npl)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060058 : Lsa(NameLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -050059{
60 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -050061 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -050062 m_expirationTimePoint = lt;
Nick Gordonf14ec352017-07-24 16:09:58 -050063 for (const auto& name : npl.getNames()) {
64 addName(name);
akmhoque53353462014-04-22 08:43:45 -050065 }
66}
67
68string
69NameLsa::getData()
70{
Nick Gordonadad2492017-05-25 10:53:07 -050071 std::ostringstream os;
72 os << m_origRouter << "|" << NameLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
73 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_npl.getSize();
Nick Gordonf14ec352017-07-24 16:09:58 -050074 for (const auto& name : m_npl.getNames()) {
Nick Gordonadad2492017-05-25 10:53:07 -050075 os << "|" << name;
akmhoque53353462014-04-22 08:43:45 -050076 }
Nick Gordonadad2492017-05-25 10:53:07 -050077 os << "|";
78 return os.str();
akmhoque53353462014-04-22 08:43:45 -050079}
80
81bool
akmhoque31d1d4b2014-05-05 22:08:14 -050082NameLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -050083{
84 uint32_t numName = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -050085 boost::char_separator<char> sep("|");
86 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
87 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
88 tokens.begin();
89 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -050090 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -050091 return false;
92 }
akmhoque31d1d4b2014-05-05 22:08:14 -050093 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060094 if (*tok_iter++ != NameLsa::TYPE_STRING) {
95 return false;
96 }
97
akmhoque31d1d4b2014-05-05 22:08:14 -050098 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -050099 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500100 numName = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500101 }
Nick Gordonadad2492017-05-25 10:53:07 -0500102 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600103 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500104 return false;
105 }
akmhoque157b0a42014-05-13 00:26:37 -0500106 for (uint32_t i = 0; i < numName; i++) {
akmhoque778f81b2014-06-27 10:07:56 -0500107 ndn::Name name(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500108 addName(name);
109 }
110 return true;
111}
112
Nick Gordon56d1fae2017-05-26 16:39:25 -0500113bool
114NameLsa::isEqualContent(const NameLsa& other) const
115{
116 return m_npl == other.getNpl();
117}
118
akmhoque53353462014-04-22 08:43:45 -0500119void
120NameLsa::writeLog()
121{
akmhoque674b0b12014-05-20 14:33:28 -0500122 _LOG_DEBUG("Name Lsa: ");
123 _LOG_DEBUG(" Origination Router: " << m_origRouter);
124 _LOG_DEBUG(" Ls Type: " << m_lsType);
125 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500126 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500127 _LOG_DEBUG(" Names: ");
128 int i = 1;
Nick Gordonf14ec352017-07-24 16:09:58 -0500129 std::list<ndn::Name> nl = m_npl.getNames();
akmhoque674b0b12014-05-20 14:33:28 -0500130 for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++)
131 {
132 _LOG_DEBUG(" Name " << i << ": " << (*it));
133 }
akmhoque2f423352014-06-03 11:49:35 -0500134 _LOG_DEBUG("name_lsa_end");
akmhoque53353462014-04-22 08:43:45 -0500135}
136
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600137CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500138 const ndn::time::system_clock::TimePoint& lt,
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600139 double r, std::vector<double> theta)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600140 : Lsa(CoordinateLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -0500141{
142 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500143 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500144 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500145 m_corRad = r;
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600146 m_angles = theta;
akmhoque53353462014-04-22 08:43:45 -0500147}
148
akmhoque31d1d4b2014-05-05 22:08:14 -0500149const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -0500150CoordinateLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500151{
akmhoque31d1d4b2014-05-05 22:08:14 -0500152 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -0600153 key.append(CoordinateLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -0500154 return key;
155}
156
157bool
akmhoquefdbddb12014-05-02 18:35:19 -0500158CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500159{
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600160 if (clsa.getCorTheta().size() != m_angles.size()) {
161 return false;
162 }
163
164 std::vector<double> m_angles2 = clsa.getCorTheta();
165 for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
166 if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
167 return false;
168 }
169 }
170
akmhoque53353462014-04-22 08:43:45 -0500171 return (std::abs(m_corRad - clsa.getCorRadius()) <
akmhoque53353462014-04-22 08:43:45 -0500172 std::numeric_limits<double>::epsilon());
173}
174
175string
akmhoqueb6450b12014-04-24 00:01:03 -0500176CoordinateLsa::getData()
akmhoque53353462014-04-22 08:43:45 -0500177{
Nick Gordonadad2492017-05-25 10:53:07 -0500178 std::ostringstream os;
179 os << m_origRouter << "|" << CoordinateLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
180 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_corRad << "|"
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600181 << m_angles.size() << "|";
182
183 for (const auto& angle: m_angles) {
184 os << angle << "|";
185 }
186
Nick Gordonadad2492017-05-25 10:53:07 -0500187 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500188}
189
190bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500191CoordinateLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500192{
akmhoque31d1d4b2014-05-05 22:08:14 -0500193 boost::char_separator<char> sep("|");
194 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
195 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
196 tokens.begin();
197 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500198 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500199 return false;
200 }
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600201
akmhoque31d1d4b2014-05-05 22:08:14 -0500202 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600203 if (*tok_iter++ != CoordinateLsa::TYPE_STRING) {
204 return false;
205 }
206
akmhoque31d1d4b2014-05-05 22:08:14 -0500207 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500208 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500209 m_corRad = boost::lexical_cast<double>(*tok_iter++);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600210 int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
211
212 for (int i = 0; i < numAngles; i++) {
213 m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
214 }
akmhoque53353462014-04-22 08:43:45 -0500215 }
Nick Gordonadad2492017-05-25 10:53:07 -0500216 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600217 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500218 return false;
219 }
220 return true;
221}
222
akmhoque674b0b12014-05-20 14:33:28 -0500223void
224CoordinateLsa::writeLog()
225{
226 _LOG_DEBUG("Cor Lsa: ");
227 _LOG_DEBUG(" Origination Router: " << m_origRouter);
228 _LOG_DEBUG(" Ls Type: " << m_lsType);
229 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500230 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500231 _LOG_DEBUG(" Hyperbolic Radius: " << m_corRad);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600232 int i = 0;
233 for(auto const& value: m_angles) {
234 _LOG_DEBUG(" Hyperbolic Theta " << i++ << ": "<< value);
235 }
akmhoque674b0b12014-05-20 14:33:28 -0500236}
237
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600238AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500239 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -0500240 uint32_t nl , AdjacencyList& adl)
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600241 : Lsa(AdjLsa::TYPE_STRING)
akmhoque53353462014-04-22 08:43:45 -0500242{
243 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500244 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500245 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500246 m_noLink = nl;
akmhoquec8a10f72014-04-25 18:42:55 -0500247 std::list<Adjacent> al = adl.getAdjList();
akmhoque157b0a42014-05-13 00:26:37 -0500248 for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500249 if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
akmhoque53353462014-04-22 08:43:45 -0500250 addAdjacent((*it));
251 }
252 }
253}
254
akmhoque31d1d4b2014-05-05 22:08:14 -0500255const ndn::Name
256AdjLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500257{
akmhoque31d1d4b2014-05-05 22:08:14 -0500258 ndn::Name key = m_origRouter;
alvy49b1c0c2014-12-19 13:57:46 -0600259 key.append(AdjLsa::TYPE_STRING);
akmhoque53353462014-04-22 08:43:45 -0500260 return key;
261}
262
263bool
akmhoquefdbddb12014-05-02 18:35:19 -0500264AdjLsa::isEqualContent(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500265{
akmhoquefdbddb12014-05-02 18:35:19 -0500266 return m_adl == alsa.getAdl();
akmhoque53353462014-04-22 08:43:45 -0500267}
268
akmhoque53353462014-04-22 08:43:45 -0500269string
270AdjLsa::getData()
271{
Nick Gordonadad2492017-05-25 10:53:07 -0500272 std::ostringstream os;
273 os << m_origRouter << "|" << AdjLsa::TYPE_STRING << "|" << m_lsSeqNo << "|"
274 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_adl.getSize();
275 for (const auto& adjacent : m_adl.getAdjList()) {
Nick Gordone9733ed2017-04-26 10:48:39 -0500276 os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
Nick Gordonadad2492017-05-25 10:53:07 -0500277 << "|" << adjacent.getLinkCost();
akmhoque53353462014-04-22 08:43:45 -0500278 }
Nick Gordonadad2492017-05-25 10:53:07 -0500279 os << "|";
280 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500281}
282
283bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500284AdjLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500285{
286 uint32_t numLink = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500287 boost::char_separator<char> sep("|");
288 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
289 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
290 tokens.begin();
291 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500292 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500293 return false;
294 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500295 try {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600296 if (*tok_iter++ != AdjLsa::TYPE_STRING) {
297 return false;
298 }
299
akmhoque31d1d4b2014-05-05 22:08:14 -0500300 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500301 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500302 numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500303 }
Nick Gordonadad2492017-05-25 10:53:07 -0500304 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600305 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500306 return false;
307 }
akmhoque157b0a42014-05-13 00:26:37 -0500308 for (uint32_t i = 0; i < numLink; i++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500309 try {
akmhoque778f81b2014-06-27 10:07:56 -0500310 ndn::Name adjName(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500311 std::string connectingFaceUri(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500312 double linkCost = boost::lexical_cast<double>(*tok_iter++);
Nick Gordone9733ed2017-04-26 10:48:39 -0500313 Adjacent adjacent(adjName, ndn::util::FaceUri(connectingFaceUri), linkCost,
314 Adjacent::STATUS_INACTIVE, 0, 0);
akmhoque53353462014-04-22 08:43:45 -0500315 addAdjacent(adjacent);
316 }
Nick Gordonadad2492017-05-25 10:53:07 -0500317 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600318 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500319 return false;
320 }
321 }
322 return true;
323}
324
akmhoque53353462014-04-22 08:43:45 -0500325void
326AdjLsa::addNptEntries(Nlsr& pnlsr)
327{
Nick G97e34942016-07-11 14:46:27 -0500328 // Only add NPT entries if this is an adj LSA from another router.
akmhoque157b0a42014-05-13 00:26:37 -0500329 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
Nick G97e34942016-07-11 14:46:27 -0500330 // Pass the originating router as both the name to register and
331 // where it came from.
akmhoque31d1d4b2014-05-05 22:08:14 -0500332 pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500333 }
334}
335
336
337void
338AdjLsa::removeNptEntries(Nlsr& pnlsr)
339{
akmhoque157b0a42014-05-13 00:26:37 -0500340 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500341 pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500342 }
343}
344
akmhoque674b0b12014-05-20 14:33:28 -0500345void
346AdjLsa::writeLog()
347{
alvydce3f182015-04-09 11:23:30 -0500348 _LOG_DEBUG(*this);
akmhoque53353462014-04-22 08:43:45 -0500349}
350
alvydce3f182015-04-09 11:23:30 -0500351std::ostream&
352operator<<(std::ostream& os, const AdjLsa& adjLsa)
353{
354 os << "Adj Lsa:\n"
355 << " Origination Router: " << adjLsa.getOrigRouter() << "\n"
356 << " Ls Type: " << adjLsa.getLsType() << "\n"
357 << " Ls Seq No: " << adjLsa.getLsSeqNo() << "\n"
358 << " Ls Lifetime: " << adjLsa.getExpirationTimePoint() << "\n"
359 << " Adjacents: \n";
360
361 int adjacencyIndex = 1;
362
363 for (const Adjacent& adjacency : adjLsa) {
364 os << " Adjacent " << adjacencyIndex++ << ":\n"
365 << " Adjacent Name: " << adjacency.getName() << "\n"
Nick Gordone9733ed2017-04-26 10:48:39 -0500366 << " Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
alvydce3f182015-04-09 11:23:30 -0500367 << " Link Cost: " << adjacency.getLinkCost() << "\n";
368 }
369 os << "adj_lsa_end";
370
371 return os;
372}
373
374} // namespace nlsr