blob: c633549e16bb61e1f83aacf67b59a4aa8a9bf71d [file] [log] [blame]
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Ashlesh Gawande0421bc62020-05-08 20:42:19 -07002/*
Davide Pesaventod90338d2021-01-07 17:50:05 -05003 * Copyright (c) 2014-2021, The University of Memphis,
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -08004 * Regents of the University of California,
5 * Arizona Board of Regents.
6 *
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/>.
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070020 */
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080021
22#include "lsa.hpp"
23#include "nlsr.hpp"
24#include "name-prefix-list.hpp"
25#include "adjacent.hpp"
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070026#include "tlv-nlsr.hpp"
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080027
28namespace nlsr {
29
Ashlesh Gawande57a87172020-05-09 19:47:06 -070030Lsa::Lsa(const ndn::Name& originRouter, uint64_t seqNo,
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080031 ndn::time::system_clock::TimePoint expirationTimePoint)
32 : m_originRouter(originRouter)
33 , m_seqNo(seqNo)
34 , m_expirationTimePoint(expirationTimePoint)
35{
36}
37
Ashlesh Gawande5d93aa52020-06-13 18:57:45 -070038Lsa::Lsa(const Lsa& lsa)
39 : m_originRouter(lsa.getOriginRouter())
40 , m_seqNo(lsa.getSeqNo())
41 , m_expirationTimePoint(lsa.getExpirationTimePoint())
42{
43}
44
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080045template<ndn::encoding::Tag TAG>
46size_t
47Lsa::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
48{
49 size_t totalLength = 0;
50
51 totalLength += prependStringBlock(encoder,
52 ndn::tlv::nlsr::ExpirationTime,
53 ndn::time::toString(m_expirationTimePoint));
54
55 totalLength += prependNonNegativeIntegerBlock(encoder, ndn::tlv::nlsr::SequenceNumber,
56 m_seqNo);
57
58 totalLength += m_originRouter.wireEncode(encoder);
59
60 totalLength += encoder.prependVarNumber(totalLength);
61 totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::Lsa);
62
63 return totalLength;
64}
65
66NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
67
68void
69Lsa::wireDecode(const ndn::Block& wire)
70{
71 m_originRouter.clear();
72 m_seqNo = 0;
73
Ashlesh Gawande57a87172020-05-09 19:47:06 -070074 ndn::Block baseWire = wire;
75 baseWire.parse();
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080076
Ashlesh Gawande57a87172020-05-09 19:47:06 -070077 auto val = baseWire.elements_begin();
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080078
Ashlesh Gawande57a87172020-05-09 19:47:06 -070079 if (val != baseWire.elements_end() && val->type() == ndn::tlv::Name) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080080 m_originRouter.wireDecode(*val);
81 }
82 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -050083 NDN_THROW(Error("OriginRouter: Missing required Name field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080084 }
85
86 ++val;
87
Ashlesh Gawande57a87172020-05-09 19:47:06 -070088 if (val != baseWire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080089 m_seqNo = ndn::readNonNegativeInteger(*val);
90 ++val;
91 }
92 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -050093 NDN_THROW(Error("Missing required SequenceNumber field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080094 }
95
Ashlesh Gawande57a87172020-05-09 19:47:06 -070096 if (val != baseWire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationTime) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080097 m_expirationTimePoint = ndn::time::fromString(readString(*val));
98 }
99 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500100 NDN_THROW(Error("Missing required ExpirationTime field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800101 }
102}
103
104std::ostream&
105operator<<(std::ostream& os, const Lsa::Type& type)
106{
107 switch (type) {
108 case nlsr::Lsa::Type::ADJACENCY:
109 os << "ADJACENCY";
110 break;
111
112 case nlsr::Lsa::Type::COORDINATE:
113 os << "COORDINATE";
114 break;
115
116 case nlsr::Lsa::Type::NAME:
117 os << "NAME";
118 break;
119
120 default:
121 os << "BASE";
122 break;
123 }
124 return os;
125}
126
127std::istream&
128operator>>(std::istream& is, Lsa::Type& type)
129{
130 std::string typeString;
131 is >> typeString;
132 if (typeString == "ADJACENCY") {
133 type = Lsa::Type::ADJACENCY;
134 }
135 else if (typeString == "COORDINATE") {
136 type = Lsa::Type::COORDINATE;
137 }
138 else if (typeString == "NAME") {
139 type = Lsa::Type::NAME;
140 }
141 else {
142 type = Lsa::Type::BASE;
143 }
144 return is;
145}
146
147std::string
Ashlesh Gawande5d93aa52020-06-13 18:57:45 -0700148Lsa::getString() const
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800149{
150 std::ostringstream os;
Ashlesh Gawande5d93aa52020-06-13 18:57:45 -0700151 auto duration = m_expirationTimePoint - ndn::time::system_clock::now();
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800152 os << " " << getType() << " LSA:\n"
Ashlesh Gawande5d93aa52020-06-13 18:57:45 -0700153 << " Origin Router : " << m_originRouter << "\n"
154 << " Sequence Number : " << m_seqNo << "\n"
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800155 << " Expires in : " << ndn::time::duration_cast<ndn::time::milliseconds>(duration)
156 << "\n";
157 return os.str();
158}
159
160} // namespace nlsr