blob: 6629d89a27008b10dc97715abed4fcc57860712f [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/*
Junxiao Shi6593a432023-08-21 10:50:28 +00003 * Copyright (c) 2014-2023, 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 */
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080020
21#ifndef NLSR_ROUTE_NEXTHOP_HPP
22#define NLSR_ROUTE_NEXTHOP_HPP
akmhoque53353462014-04-22 08:43:45 -050023
Vince Lehman20fe4a92014-09-09 15:57:59 -050024#include "test-access-control.hpp"
25
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070026#include <ndn-cxx/encoding/block.hpp>
27#include <ndn-cxx/encoding/encoding-buffer.hpp>
28#include <ndn-cxx/encoding/tlv.hpp>
Junxiao Shi6593a432023-08-21 10:50:28 +000029#include <ndn-cxx/net/face-uri.hpp>
30
31#include <boost/operators.hpp>
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070032
akmhoque102aea42014-08-04 10:22:12 -050033#include <cmath>
Davide Pesaventod90338d2021-01-07 17:50:05 -050034#include <ostream>
akmhoque53353462014-04-22 08:43:45 -050035
36namespace nlsr {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080037
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070038/*! \brief Data abstraction for Nexthop
39 *
40 * NextHop := NEXTHOP-TYPE TLV-LENGTH
41 * Uri
42 * Cost
43 *
44 * \sa https://redmine.named-data.net/projects/nlsr/wiki/Routing_Table_Dataset
45 */
Junxiao Shi6593a432023-08-21 10:50:28 +000046class NextHop : private boost::totally_ordered<NextHop>
akmhoque53353462014-04-22 08:43:45 -050047{
48public:
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070049 using Error = ndn::tlv::Error;
50
Junxiao Shi6593a432023-08-21 10:50:28 +000051 NextHop() = default;
akmhoque53353462014-04-22 08:43:45 -050052
Junxiao Shi6593a432023-08-21 10:50:28 +000053 NextHop(const ndn::FaceUri& cfu, double rc)
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070054 : m_connectingFaceUri(cfu)
55 , m_routeCost(rc)
akmhoque53353462014-04-22 08:43:45 -050056 {
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070057 }
58
Junxiao Shi6593a432023-08-21 10:50:28 +000059 explicit
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070060 NextHop(const ndn::Block& block)
61 {
62 wireDecode(block);
akmhoque53353462014-04-22 08:43:45 -050063 }
64
Junxiao Shi6593a432023-08-21 10:50:28 +000065 const ndn::FaceUri&
akmhoque157b0a42014-05-13 00:26:37 -050066 getConnectingFaceUri() const
akmhoque53353462014-04-22 08:43:45 -050067 {
akmhoque157b0a42014-05-13 00:26:37 -050068 return m_connectingFaceUri;
akmhoque53353462014-04-22 08:43:45 -050069 }
70
71 void
Junxiao Shi6593a432023-08-21 10:50:28 +000072 setConnectingFaceUri(const ndn::FaceUri& cfu)
akmhoque53353462014-04-22 08:43:45 -050073 {
akmhoque157b0a42014-05-13 00:26:37 -050074 m_connectingFaceUri = cfu;
akmhoque53353462014-04-22 08:43:45 -050075 }
76
akmhoque102aea42014-08-04 10:22:12 -050077 uint64_t
Vince Lehman145064a2014-08-23 11:44:16 -050078 getRouteCostAsAdjustedInteger() const
79 {
Vince Lehman20fe4a92014-09-09 15:57:59 -050080 if (m_isHyperbolic) {
81 // Round the cost to better preserve decimal cost differences
82 // e.g. Without rounding: 12.3456 > 12.3454 -> 12345 = 12345
83 // With rounding: 12.3456 > 12.3454 -> 12346 > 12345
84 return static_cast<uint64_t>(round(m_routeCost*HYPERBOLIC_COST_ADJUSTMENT_FACTOR));
85 }
86 else {
87 return static_cast<uint64_t>(m_routeCost);
88 }
Vince Lehman145064a2014-08-23 11:44:16 -050089 }
90
91 double
akmhoque53353462014-04-22 08:43:45 -050092 getRouteCost() const
93 {
Vince Lehman145064a2014-08-23 11:44:16 -050094 return m_routeCost;
akmhoque53353462014-04-22 08:43:45 -050095 }
96
97 void
Vince Lehmanef21d8e2015-04-01 15:59:39 -050098 setRouteCost(const double rc)
akmhoque53353462014-04-22 08:43:45 -050099 {
100 m_routeCost = rc;
101 }
102
Vince Lehman20fe4a92014-09-09 15:57:59 -0500103 void
104 setHyperbolic(bool b)
105 {
106 m_isHyperbolic = b;
107 }
108
109 bool
110 isHyperbolic() const
111 {
112 return m_isHyperbolic;
113 }
114
Ashlesh Gawande0421bc62020-05-08 20:42:19 -0700115 template<ndn::encoding::Tag TAG>
116 size_t
117 wireEncode(ndn::EncodingImpl<TAG>& block) const;
118
119 const ndn::Block&
120 wireEncode() const;
121
122 void
123 wireDecode(const ndn::Block& wire);
124
Junxiao Shi6593a432023-08-21 10:50:28 +0000125private: // non-member operators
126 // NOTE: the following "hidden friend" operators are available via
127 // argument-dependent lookup only and must be defined inline.
128 // boost::totally_ordered provides !=, <=, >=, and > operators.
129
130 friend bool
131 operator==(const NextHop& lhs, const NextHop& rhs)
132 {
133 return lhs.getRouteCostAsAdjustedInteger() == rhs.getRouteCostAsAdjustedInteger() &&
134 lhs.getConnectingFaceUri() == rhs.getConnectingFaceUri();
135 }
136
137 friend bool
138 operator<(const NextHop& lhs, const NextHop& rhs)
139 {
140 return std::forward_as_tuple(lhs.getRouteCostAsAdjustedInteger(), lhs.getConnectingFaceUri()) <
141 std::forward_as_tuple(rhs.getRouteCostAsAdjustedInteger(), rhs.getConnectingFaceUri());
142 }
143
akmhoque53353462014-04-22 08:43:45 -0500144private:
Junxiao Shi6593a432023-08-21 10:50:28 +0000145 ndn::FaceUri m_connectingFaceUri;
146 double m_routeCost = 0.0;
147 bool m_isHyperbolic = false;
Vince Lehman20fe4a92014-09-09 15:57:59 -0500148
Ashlesh Gawande0421bc62020-05-08 20:42:19 -0700149 mutable ndn::Block m_wire;
150
Vince Lehman20fe4a92014-09-09 15:57:59 -0500151PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Nick G97e34942016-07-11 14:46:27 -0500152 /*! \brief Used to adjust floating point route costs to integers
153 Since NFD uses integer route costs in the FIB, hyperbolic paths with similar route costs
154 will be rounded to integers and installed with identical nexthop costs.
155
156 e.g. costs 12.34 and 12.35 will be equal in NFD's FIB
157
158 This multiplier is used to differentiate similar route costs in the FIB.
159
160 e.g costs 12.34 and 12.35 will be installed into NFD's FIB as 12340 and 12350
Vince Lehman20fe4a92014-09-09 15:57:59 -0500161 */
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400162 static constexpr uint64_t HYPERBOLIC_COST_ADJUSTMENT_FACTOR = 1000;
akmhoque53353462014-04-22 08:43:45 -0500163};
164
Ashlesh Gawande0421bc62020-05-08 20:42:19 -0700165NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NextHop);
166
Vince Lehman9a709032014-09-13 16:28:07 -0500167std::ostream&
168operator<<(std::ostream& os, const NextHop& hop);
169
Nick Gordonfad8e252016-08-11 14:21:38 -0500170} // namespace nlsr
akmhoque53353462014-04-22 08:43:45 -0500171
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800172#endif // NLSR_ROUTE_NEXTHOP_HPP