|
1 /* |
|
2 * Copyright 2007 Baylor University |
|
3 * |
|
4 * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 * you may not use this file except in compliance with the License. |
|
6 * You may obtain a copy of the License at |
|
7 * |
|
8 * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 * |
|
10 * Unless required by applicable law or agreed to in writing, software |
|
11 * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 * See the License for the specific language governing permissions and |
|
14 * limitations under the License. |
|
15 */ |
|
16 |
|
17 #ifndef _PROPHET_DECIDER_H_ |
|
18 #define _PROPHET_DECIDER_H_ |
|
19 |
|
20 #include "Bundle.h" |
|
21 #include "Link.h" |
|
22 #include "Stats.h" |
|
23 #include "FwdStrategy.h" |
|
24 #include "BundleCore.h" |
|
25 |
|
26 namespace prophet |
|
27 { |
|
28 |
|
29 /** |
|
30 * Base class for FwdStrategy deciders, used by router to decide whether |
|
31 * to forward a Bundle based on the forwarding strategy |
|
32 */ |
|
33 class Decider |
|
34 { |
|
35 public: |
|
36 /** |
|
37 * Destructor |
|
38 */ |
|
39 virtual ~Decider() {} |
|
40 |
|
41 /** |
|
42 * Factory method for creating decider instance |
|
43 */ |
|
44 static inline Decider* decider(FwdStrategy::fwd_strategy_t fs, |
|
45 const Link* nexthop, |
|
46 BundleCore* core, |
|
47 const Table* local_nodes, |
|
48 const Table* remote_nodes, |
|
49 const Stats* stats = NULL, |
|
50 u_int max_forward = 0, |
|
51 bool is_relay = true); |
|
52 |
|
53 /** |
|
54 * The decision function: return true if the strategy says to forward |
|
55 * the Bundle; else false |
|
56 */ |
|
57 virtual bool operator() (const Bundle*) const = 0; |
|
58 |
|
59 ///@{ Accessors |
|
60 FwdStrategy::fwd_strategy_t fwd_strategy() const { return fwd_strategy_; } |
|
61 const Link* nexthop() const { return next_hop_; } |
|
62 const BundleCore* core() const { return core_; } |
|
63 const Table* local_nodes() const { return local_; } |
|
64 const Table* remote_nodes() const { return remote_; } |
|
65 const Stats* stats() const { return stats_; } |
|
66 bool is_relay() const { return is_relay_; } |
|
67 ///@} |
|
68 |
|
69 protected: |
|
70 /** |
|
71 * Constructor |
|
72 */ |
|
73 Decider(FwdStrategy::fwd_strategy_t fs, |
|
74 const Link* nexthop, |
|
75 BundleCore* core, |
|
76 const Table* local, const Table* remote, |
|
77 const Stats* stats, bool is_relay) |
|
78 : fwd_strategy_(fs), |
|
79 next_hop_(nexthop), |
|
80 core_(core), local_(local), remote_(remote), |
|
81 stats_(stats), is_relay_(is_relay) {} |
|
82 |
|
83 FwdStrategy::fwd_strategy_t fwd_strategy_; ///< which strategy is in use |
|
84 const Link* next_hop_; ///< next hop Link |
|
85 BundleCore* const core_; ///< facade interface to Bundle host |
|
86 const Table* local_; ///< local routing table |
|
87 const Table* remote_; ///< peer's routing table |
|
88 const Stats* stats_; ///< forwarding statistics per Bundle |
|
89 bool is_relay_; ///< whether peer acts as a relay (forwards Bundles) |
|
90 |
|
91 }; // class Decider |
|
92 |
|
93 /** |
|
94 * Forward the bundle only if P(B,D) > P(A,D). That is, predictability |
|
95 * for route via peer is greater than route's predictability locally |
|
96 */ |
|
97 class FwdDeciderGRTR : public Decider |
|
98 { |
|
99 public: |
|
100 /** |
|
101 * Destructor |
|
102 */ |
|
103 virtual ~FwdDeciderGRTR() {} |
|
104 |
|
105 /** |
|
106 * Virtual from Decider |
|
107 */ |
|
108 bool operator() (const Bundle*) const; |
|
109 |
|
110 protected: |
|
111 friend class Decider; // for factory method |
|
112 |
|
113 /** |
|
114 * Constructor. Protected to force entry via factory method. |
|
115 */ |
|
116 FwdDeciderGRTR(FwdStrategy::fwd_strategy_t fs, |
|
117 const Link* nexthop, BundleCore* core, |
|
118 const Table* local, const Table* remote, |
|
119 const Stats* stats = NULL, |
|
120 bool relay = true); |
|
121 }; // class FwdDeciderGRTR |
|
122 |
|
123 /** |
|
124 * Forward the bundle only if P(B,D) > P(A,D) (same as GRTR) and if the |
|
125 * bundle has been forwarded (NF) less than max times (NF_Max). |
|
126 */ |
|
127 class FwdDeciderGTMX : public FwdDeciderGRTR |
|
128 { |
|
129 public: |
|
130 /** |
|
131 * Destructor |
|
132 */ |
|
133 virtual ~FwdDeciderGTMX() {} |
|
134 |
|
135 /** |
|
136 * Virtual from Decider |
|
137 */ |
|
138 bool operator() (const Bundle*) const; |
|
139 |
|
140 ///@{ Accessors |
|
141 u_int max_forward() const { return max_fwd_; } |
|
142 ///@} |
|
143 protected: |
|
144 friend class Decider; // for factory method |
|
145 |
|
146 /** |
|
147 * Constructor. Protected to force entry via factory method. |
|
148 */ |
|
149 FwdDeciderGTMX(FwdStrategy::fwd_strategy_t fs, |
|
150 const Link* nexthop, BundleCore* core, |
|
151 const Table* local, const Table* remote, |
|
152 u_int max_fwd, bool relay); |
|
153 |
|
154 u_int max_fwd_; ///< local configuration setting for NF_max |
|
155 }; // class FwdDeciderGTMX |
|
156 |
|
157 /** |
|
158 * Forward the bundle only if P(B,D) > P(A,D) (same as GRTR) and if |
|
159 * P(B,D) > P_max where P_max is the largest delivery predictability |
|
160 * reported by a node to which the bundle has been sent so far. |
|
161 */ |
|
162 class FwdDeciderGRTRPLUS : public FwdDeciderGRTR |
|
163 { |
|
164 public: |
|
165 /** |
|
166 * Destructor |
|
167 */ |
|
168 virtual ~FwdDeciderGRTRPLUS() {} |
|
169 |
|
170 /** |
|
171 * Virtual from Decider |
|
172 */ |
|
173 bool operator() (const Bundle*) const; |
|
174 |
|
175 protected: |
|
176 friend class Decider; // for factory method |
|
177 |
|
178 /** |
|
179 * Constructor. Protected to force entry via factory method. |
|
180 */ |
|
181 FwdDeciderGRTRPLUS(FwdStrategy::fwd_strategy_t fs, |
|
182 const Link* nexthop, BundleCore* core, |
|
183 const Table* local, const Table* remote, |
|
184 const Stats* stats, bool relay); |
|
185 |
|
186 }; // class FwdDeciderGRTRPLUS |
|
187 |
|
188 /** |
|
189 * Forward the bundle only if |
|
190 * P(B,D) > P(A,D) && P(B,D) > P_max && NF < NF_max |
|
191 * which is a combination of GTMX and GRTR_PLUS |
|
192 */ |
|
193 class FwdDeciderGTMXPLUS : public FwdDeciderGRTRPLUS |
|
194 { |
|
195 public: |
|
196 /** |
|
197 * Destructor |
|
198 */ |
|
199 virtual ~FwdDeciderGTMXPLUS() {} |
|
200 |
|
201 /** |
|
202 * Virtual from Decider |
|
203 */ |
|
204 bool operator() (const Bundle*) const; |
|
205 |
|
206 ///@{ Accessors |
|
207 u_int max_forward() const { return max_fwd_; } |
|
208 ///@} |
|
209 protected: |
|
210 friend class Decider; // for factory method |
|
211 |
|
212 /** |
|
213 * Constructor. Protected to force entry via factory method. |
|
214 */ |
|
215 FwdDeciderGTMXPLUS(FwdStrategy::fwd_strategy_t fs, |
|
216 const Link* nexthop, BundleCore* core, |
|
217 const Table* local, const Table* remote, |
|
218 const Stats* stats, |
|
219 u_int max_forward, bool relay); |
|
220 |
|
221 u_int max_fwd_; ///< local configuration setting for NF_max |
|
222 }; // class FwdDeciderGTMXPLUS |
|
223 |
|
224 Decider* |
|
225 Decider::decider(FwdStrategy::fwd_strategy_t fs, |
|
226 const Link* nexthop, |
|
227 BundleCore* core, |
|
228 const Table* local_nodes, |
|
229 const Table* remote_nodes, |
|
230 const Stats* stats, |
|
231 u_int max_forward, |
|
232 bool is_relay) |
|
233 { |
|
234 Decider* d = NULL; |
|
235 |
|
236 // weed out the oddball |
|
237 if (nexthop == NULL || nexthop->nexthop()[0] == '\0') return NULL; |
|
238 if (local_nodes == NULL) return NULL; |
|
239 if (remote_nodes == NULL) return NULL; |
|
240 |
|
241 // pick the decider based on strategy |
|
242 switch (fs) |
|
243 { |
|
244 case FwdStrategy::GRTR: |
|
245 case FwdStrategy::GRTR_SORT: |
|
246 case FwdStrategy::GRTR_MAX: |
|
247 { |
|
248 d = new FwdDeciderGRTR(fs,nexthop,core,local_nodes, |
|
249 remote_nodes,NULL,is_relay); |
|
250 break; |
|
251 } |
|
252 case FwdStrategy::GTMX: |
|
253 { |
|
254 if (max_forward == 0) return NULL; |
|
255 d = new FwdDeciderGTMX(fs,nexthop,core,local_nodes, |
|
256 remote_nodes,max_forward, |
|
257 is_relay); |
|
258 break; |
|
259 } |
|
260 case FwdStrategy::GRTR_PLUS: |
|
261 { |
|
262 if (stats == NULL) return NULL; |
|
263 d = new FwdDeciderGRTRPLUS(fs,nexthop,core,local_nodes, |
|
264 remote_nodes,stats,is_relay); |
|
265 break; |
|
266 } |
|
267 case FwdStrategy::GTMX_PLUS: |
|
268 { |
|
269 if (stats == NULL || max_forward == 0) return NULL; |
|
270 d = new FwdDeciderGTMXPLUS(fs,nexthop,core,local_nodes, |
|
271 remote_nodes,stats,max_forward, |
|
272 is_relay); |
|
273 break; |
|
274 } |
|
275 case FwdStrategy::INVALID_FS: |
|
276 default: |
|
277 break; |
|
278 } |
|
279 return d; |
|
280 } |
|
281 |
|
282 }; // namespace prophet |
|
283 |
|
284 #endif // _PROPHET_DECIDER_H_ |