blob: 8d5a3dc1fad9fc50ca89ee69d521f766fcd5538f [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/*
Junxiao Shi153fbc12024-01-09 23:37:23 +00003 * Copyright (c) 2014-2024, 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"
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070023#include "tlv-nlsr.hpp"
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080024
25namespace nlsr {
26
Ashlesh Gawande57a87172020-05-09 19:47:06 -070027Lsa::Lsa(const ndn::Name& originRouter, uint64_t seqNo,
Davide Pesavento658fd852023-05-10 22:15:03 -040028 ndn::time::system_clock::time_point expirationTimePoint)
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080029 : m_originRouter(originRouter)
30 , m_seqNo(seqNo)
31 , m_expirationTimePoint(expirationTimePoint)
32{
33}
34
Ashlesh Gawande5d93aa52020-06-13 18:57:45 -070035Lsa::Lsa(const Lsa& lsa)
36 : m_originRouter(lsa.getOriginRouter())
37 , m_seqNo(lsa.getSeqNo())
38 , m_expirationTimePoint(lsa.getExpirationTimePoint())
39{
40}
41
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080042template<ndn::encoding::Tag TAG>
43size_t
44Lsa::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
45{
46 size_t totalLength = 0;
47
48 totalLength += prependStringBlock(encoder,
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040049 nlsr::tlv::ExpirationTime,
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080050 ndn::time::toString(m_expirationTimePoint));
51
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040052 totalLength += prependNonNegativeIntegerBlock(encoder, nlsr::tlv::SequenceNumber, m_seqNo);
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080053
54 totalLength += m_originRouter.wireEncode(encoder);
55
56 totalLength += encoder.prependVarNumber(totalLength);
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040057 totalLength += encoder.prependVarNumber(nlsr::tlv::Lsa);
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080058
59 return totalLength;
60}
61
62NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
63
64void
65Lsa::wireDecode(const ndn::Block& wire)
66{
67 m_originRouter.clear();
68 m_seqNo = 0;
69
Ashlesh Gawande57a87172020-05-09 19:47:06 -070070 ndn::Block baseWire = wire;
71 baseWire.parse();
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080072
Ashlesh Gawande57a87172020-05-09 19:47:06 -070073 auto val = baseWire.elements_begin();
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080074
Ashlesh Gawande57a87172020-05-09 19:47:06 -070075 if (val != baseWire.elements_end() && val->type() == ndn::tlv::Name) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080076 m_originRouter.wireDecode(*val);
77 }
78 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -050079 NDN_THROW(Error("OriginRouter: Missing required Name field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080080 }
81
82 ++val;
83
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040084 if (val != baseWire.elements_end() && val->type() == nlsr::tlv::SequenceNumber) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080085 m_seqNo = ndn::readNonNegativeInteger(*val);
86 ++val;
87 }
88 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -050089 NDN_THROW(Error("Missing required SequenceNumber field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080090 }
91
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040092 if (val != baseWire.elements_end() && val->type() == nlsr::tlv::ExpirationTime) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080093 m_expirationTimePoint = ndn::time::fromString(readString(*val));
94 }
95 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -050096 NDN_THROW(Error("Missing required ExpirationTime field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080097 }
98}
99
100std::ostream&
Junxiao Shi153fbc12024-01-09 23:37:23 +0000101operator<<(std::ostream& os, const Lsa& lsa)
102{
103 auto duration = lsa.m_expirationTimePoint - ndn::time::system_clock::now();
104 os << " " << lsa.getType() << " LSA:\n"
105 << " Origin Router : " << lsa.m_originRouter << "\n"
106 << " Sequence Number : " << lsa.m_seqNo << "\n"
107 << " Expires in : " << ndn::time::duration_cast<ndn::time::milliseconds>(duration)
108 << "\n";
109 lsa.print(os);
110 return os;
111}
112
113std::ostream&
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800114operator<<(std::ostream& os, const Lsa::Type& type)
115{
116 switch (type) {
Davide Pesaventoe28d8752022-03-19 03:55:25 -0400117 case Lsa::Type::ADJACENCY:
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800118 os << "ADJACENCY";
119 break;
Davide Pesaventoe28d8752022-03-19 03:55:25 -0400120 case Lsa::Type::COORDINATE:
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800121 os << "COORDINATE";
122 break;
Davide Pesaventoe28d8752022-03-19 03:55:25 -0400123 case Lsa::Type::NAME:
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800124 os << "NAME";
125 break;
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800126 default:
127 os << "BASE";
128 break;
129 }
130 return os;
131}
132
133std::istream&
134operator>>(std::istream& is, Lsa::Type& type)
135{
136 std::string typeString;
137 is >> typeString;
138 if (typeString == "ADJACENCY") {
139 type = Lsa::Type::ADJACENCY;
140 }
141 else if (typeString == "COORDINATE") {
142 type = Lsa::Type::COORDINATE;
143 }
144 else if (typeString == "NAME") {
145 type = Lsa::Type::NAME;
146 }
147 else {
148 type = Lsa::Type::BASE;
149 }
150 return is;
151}
152
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800153} // namespace nlsr