blob: fae92d568dd9c73e07a7bd5491d5b8cf92ac0200 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Ashlesh Gawande0421bc62020-05-08 20:42:19 -07002/*
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -08003 * Copyright (c) 2014-2020, The University of Memphis,
Nick Gordonf8b5bcd2016-08-11 15:06:50 -05004 * Regents of the University of California
akmhoque3d06e792014-05-27 16:23:20 -05005 *
6 * This file is part of NLSR (Named-data Link State Routing).
7 * See AUTHORS.md for complete list of NLSR authors and contributors.
8 *
9 * NLSR is free software: you can redistribute it and/or modify it under the terms
10 * of the GNU General Public License as published by the Free Software Foundation,
11 * either version 3 of the License, or (at your option) any later version.
12 *
13 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070019 */
Nick Gordond0a7df32017-05-30 16:44:34 -050020
21#include "adjacent.hpp"
22#include "logger.hpp"
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070023#include "tlv-nlsr.hpp"
akmhoquec8a10f72014-04-25 18:42:55 -050024
akmhoque53353462014-04-22 08:43:45 -050025namespace nlsr {
26
dmcoomescf8d0ed2017-02-21 11:39:01 -060027INIT_LOGGER(Adjacent);
akmhoque674b0b12014-05-20 14:33:28 -050028
dulalsaurabd0816a32019-07-26 13:11:24 +000029const double Adjacent::DEFAULT_LINK_COST = 10.0;
30const double Adjacent::NON_ADJACENT_COST = -12345;
akmhoque157b0a42014-05-13 00:26:37 -050031
32Adjacent::Adjacent()
33 : m_name()
Nick Gordone9733ed2017-04-26 10:48:39 -050034 , m_faceUri()
akmhoque157b0a42014-05-13 00:26:37 -050035 , m_linkCost(DEFAULT_LINK_COST)
Vince Lehmancb76ade2014-08-28 21:24:41 -050036 , m_status(STATUS_INACTIVE)
akmhoque157b0a42014-05-13 00:26:37 -050037 , m_interestTimedOutNo(0)
akmhoquec04e7272014-07-02 11:00:14 -050038 , m_faceId(0)
akmhoque157b0a42014-05-13 00:26:37 -050039{
40}
41
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080042Adjacent::Adjacent(const ndn::Block& block)
43{
44 wireDecode(block);
45}
46
akmhoque157b0a42014-05-13 00:26:37 -050047Adjacent::Adjacent(const ndn::Name& an)
48 : m_name(an)
Nick Gordone9733ed2017-04-26 10:48:39 -050049 , m_faceUri()
akmhoque157b0a42014-05-13 00:26:37 -050050 , m_linkCost(DEFAULT_LINK_COST)
Vince Lehmancb76ade2014-08-28 21:24:41 -050051 , m_status(STATUS_INACTIVE)
akmhoque157b0a42014-05-13 00:26:37 -050052 , m_interestTimedOutNo(0)
akmhoquec04e7272014-07-02 11:00:14 -050053 , m_faceId(0)
akmhoque157b0a42014-05-13 00:26:37 -050054 {
55 }
56
Ashlesh Gawande41878572019-09-29 00:16:02 -050057Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Vince Lehmancb76ade2014-08-28 21:24:41 -050058 Status s, uint32_t iton, uint64_t faceId)
akmhoquec04e7272014-07-02 11:00:14 -050059 : m_name(an)
Nick Gordone9733ed2017-04-26 10:48:39 -050060 , m_faceUri(faceUri)
akmhoquec04e7272014-07-02 11:00:14 -050061 , m_status(s)
62 , m_interestTimedOutNo(iton)
63 , m_faceId(faceId)
64 {
dulalsaurabd0816a32019-07-26 13:11:24 +000065 this->setLinkCost(lc);
akmhoquec04e7272014-07-02 11:00:14 -050066 }
akmhoque53353462014-04-22 08:43:45 -050067
dulalsaurabd0816a32019-07-26 13:11:24 +000068void
69Adjacent::setLinkCost(double lc)
70{
71 // NON_ADJACENT_COST is a negative value and is used for nodes that aren't direct neighbors.
72 // But for direct/active neighbors, the cost cannot be negative.
73 if (lc < 0 && lc != NON_ADJACENT_COST)
74 {
75 NLSR_LOG_ERROR(" Neighbor's link-cost cannot be negative");
76 BOOST_THROW_EXCEPTION(ndn::tlv::Error("Neighbor's link-cost cannot be negative"));
77 }
78
79 m_linkCost = lc;
80}
81
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080082NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
83
84template<ndn::encoding::Tag TAG>
85size_t
86Adjacent::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
87{
88 size_t totalLength = 0;
89
90 totalLength += prependDoubleBlock(encoder, ndn::tlv::nlsr::Cost, m_linkCost);
91
92 totalLength += prependStringBlock(encoder, ndn::tlv::nlsr::Uri, m_faceUri.toString());
93
94 totalLength += m_name.wireEncode(encoder);
95
96 totalLength += encoder.prependVarNumber(totalLength);
97 totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::Adjacency);
98
99 return totalLength;
100}
101
102const ndn::Block&
103Adjacent::wireEncode() const
104{
105 if (m_wire.hasWire()) {
106 return m_wire;
107 }
108
109 ndn::EncodingEstimator estimator;
110 size_t estimatedSize = wireEncode(estimator);
111
112 ndn::EncodingBuffer buffer(estimatedSize, 0);
113 wireEncode(buffer);
114
115 m_wire = buffer.block();
116
117 return m_wire;
118}
119
120void
121Adjacent::wireDecode(const ndn::Block& wire)
122{
123 m_name.clear();
124 m_faceUri = ndn::FaceUri();
125 m_linkCost = 0;
126
127 m_wire = wire;
128
129 if (m_wire.type() != ndn::tlv::nlsr::Adjacency) {
130 BOOST_THROW_EXCEPTION(Error("Expected Adjacency Block, but Block is of a different type: #" +
131 ndn::to_string(m_wire.type())));
132 }
133
134 m_wire.parse();
135
136 ndn::Block::element_const_iterator val = m_wire.elements_begin();
137
138 if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
139 m_name.wireDecode(*val);
140 ++val;
141 }
142 else {
143 BOOST_THROW_EXCEPTION(Error("Missing required Name field"));
144 }
145
146 if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Uri) {
147 m_faceUri = ndn::FaceUri(readString(*val));
148 ++val;
149 }
150 else {
151 BOOST_THROW_EXCEPTION(Error("Missing required Uri field"));
152 }
153
154 if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Cost) {
155 m_linkCost = ndn::encoding::readDouble(*val);
156 ++val;
157 }
158 else {
159 BOOST_THROW_EXCEPTION(Error("Missing required Cost field"));
160 }
161}
162
akmhoque53353462014-04-22 08:43:45 -0500163bool
akmhoquefdbddb12014-05-02 18:35:19 -0500164Adjacent::operator==(const Adjacent& adjacent) const
akmhoque53353462014-04-22 08:43:45 -0500165{
akmhoquefdbddb12014-05-02 18:35:19 -0500166 return (m_name == adjacent.getName()) &&
Nick Gordone9733ed2017-04-26 10:48:39 -0500167 (m_faceUri == adjacent.getFaceUri()) &&
akmhoquefdbddb12014-05-02 18:35:19 -0500168 (std::abs(m_linkCost - adjacent.getLinkCost()) <
Nick Gordone9733ed2017-04-26 10:48:39 -0500169 std::numeric_limits<double>::epsilon());
akmhoque53353462014-04-22 08:43:45 -0500170}
171
Nick Gordon2a1ac612017-10-06 15:36:49 -0500172bool
173Adjacent::operator<(const Adjacent& adjacent) const
174{
Ashlesh Gawandee8d8bd52018-08-09 17:18:51 -0500175 auto linkCost = adjacent.getLinkCost();
176 return std::tie(m_name, m_linkCost) <
177 std::tie(adjacent.getName(), linkCost);
Nick Gordon2a1ac612017-10-06 15:36:49 -0500178}
179
180std::ostream&
181operator<<(std::ostream& os, const Adjacent& adjacent)
182{
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800183 os << "Adjacent: " << adjacent.m_name
184 << "\n\t\tConnecting FaceUri: " << adjacent.m_faceUri
185 << "\n\t\tLink cost: " << adjacent.m_linkCost
186 << "\n\t\tStatus: " << adjacent.m_status
187 << "\n\t\tInterest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
Nick Gordon2a1ac612017-10-06 15:36:49 -0500188 return os;
189}
190
Nick Gordonfad8e252016-08-11 14:21:38 -0500191} // namespace nlsr