Mercurial > hg > freeDiameter
annotate libfdproto/rt_data.c @ 1562:6219359a36a9 default tip
Merge latest changes from proposed branch
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Mon, 21 Jun 2021 19:08:18 +0800 |
parents | 1af09cc156d6 |
children |
rev | line source |
---|---|
84 | 1 /********************************************************************************************************* |
2 * Software License Agreement (BSD License) * | |
740
4a9f08d6b6ba
Updated my mail address
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
738
diff
changeset
|
3 * Author: Sebastien Decugis <sdecugis@freediameter.net> * |
84 | 4 * * |
1127
1af09cc156d6
Updated copyright information
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
5 * Copyright (c) 2013, WIDE Project and NICT * |
84 | 6 * All rights reserved. * |
7 * * | |
8 * Redistribution and use of this software in source and binary forms, with or without modification, are * | |
9 * permitted provided that the following conditions are met: * | |
10 * * | |
11 * * Redistributions of source code must retain the above * | |
12 * copyright notice, this list of conditions and the * | |
13 * following disclaimer. * | |
14 * * | |
15 * * Redistributions in binary form must reproduce the above * | |
16 * copyright notice, this list of conditions and the * | |
17 * following disclaimer in the documentation and/or other * | |
18 * materials provided with the distribution. * | |
19 * * | |
20 * * Neither the name of the WIDE Project or NICT nor the * | |
21 * names of its contributors may be used to endorse or * | |
22 * promote products derived from this software without * | |
23 * specific prior written permission of WIDE Project and * | |
24 * NICT. * | |
25 * * | |
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * | |
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * | |
28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * | |
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * | |
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * | |
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * | |
32 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * | |
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * | |
34 *********************************************************************************************************/ | |
35 | |
36 /* Routing module helpers. | |
37 * | |
38 * This file provides support for the rt_data structure manipulation. | |
39 */ | |
40 | |
658
f198d16fa7f4
Initial commit for 1.1.0:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
563
diff
changeset
|
41 #include "fdproto-internal.h" |
84 | 42 |
43 /* Structure that contains the routing data for a message */ | |
44 struct rt_data { | |
1019
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
45 int extracted; /* if 0, candidates is ordered by diamid, otherwise the order is unspecified. This also counts the number of times the message was (re-)sent, as a side effect */ |
84 | 46 struct fd_list candidates; /* All the candidates. Items are struct rtd_candidate. */ |
47 struct fd_list errors; /* All errors received from other peers for this message */ | |
48 }; | |
49 | |
50 /* Items of the errors list */ | |
51 struct rtd_error { | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
52 struct fd_list chain; /* link in the list, ordered by nexthop (fd_os_cmp) */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
53 DiamId_t nexthop;/* the peer the message was sent to */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
54 size_t nexthoplen; /* cached string length */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
55 DiamId_t erh; /* the origin of the error */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
56 size_t erhlen; /* cached string length */ |
84 | 57 uint32_t code; /* the error code */ |
58 }; | |
59 | |
60 /* Create a new structure to store routing data */ | |
61 int fd_rtd_init(struct rt_data ** rtd) | |
62 { | |
63 struct rt_data *new; | |
64 TRACE_ENTRY("%p", rtd); | |
65 CHECK_PARAMS(rtd); | |
66 | |
67 /* Alloc the structure */ | |
68 CHECK_MALLOC( new = malloc(sizeof(struct rt_data)) ); | |
69 memset(new, 0, sizeof(struct rt_data) ); | |
70 fd_list_init(&new->candidates, new); | |
71 fd_list_init(&new->errors, new); | |
72 | |
73 *rtd = new; | |
74 return 0; | |
75 } | |
76 | |
77 /* Destroy the routing data */ | |
78 void fd_rtd_free(struct rt_data ** rtd) | |
79 { | |
80 struct rt_data *old; | |
81 | |
82 TRACE_ENTRY("%p", rtd); | |
83 CHECK_PARAMS_DO(rtd, return ); | |
84 | |
85 old = *rtd; | |
86 *rtd = NULL; | |
87 | |
88 while (!FD_IS_LIST_EMPTY(&old->candidates)) { | |
89 struct rtd_candidate * c = (struct rtd_candidate *) old->candidates.next; | |
90 | |
91 fd_list_unlink(&c->chain); | |
92 free(c->diamid); | |
168
6db078b955e3
Completed rt_default extension
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
166
diff
changeset
|
93 free(c->realm); |
84 | 94 free(c); |
95 } | |
96 | |
97 while (!FD_IS_LIST_EMPTY(&old->errors)) { | |
98 struct rtd_error * c = (struct rtd_error *) old->errors.next; | |
99 | |
100 fd_list_unlink(&c->chain); | |
101 free(c->nexthop); | |
102 free(c->erh); | |
103 free(c); | |
104 } | |
105 | |
106 free(old); | |
107 | |
108 return; | |
109 } | |
110 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
111 /* Add a peer to the candidates list. The source is our local peer list, so no need to care for the case here. */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
112 int fd_rtd_candidate_add(struct rt_data * rtd, DiamId_t peerid, size_t peeridlen, DiamId_t realm, size_t realmlen) |
84 | 113 { |
114 struct fd_list * prev; | |
115 struct rtd_candidate * new; | |
116 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
117 TRACE_ENTRY("%p %p %zd %p %zd", rtd, peerid, peeridlen, realm, realmlen); |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
118 CHECK_PARAMS(rtd && peerid && peeridlen); |
84 | 119 |
120 /* Since the peers are ordered when they are added (fd_g_activ_peers) we search for the position from the end -- this should be efficient */ | |
121 for (prev = rtd->candidates.prev; prev != &rtd->candidates; prev = prev->prev) { | |
122 struct rtd_candidate * cp = (struct rtd_candidate *) prev; | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
123 int cmp = fd_os_cmp(peerid, peeridlen, cp->diamid, cp->diamidlen); |
84 | 124 if (cmp > 0) |
125 break; | |
126 if (cmp == 0) | |
127 /* The candidate is already in the list */ | |
128 return 0; | |
129 } | |
130 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
131 /* Create the new entry */ |
84 | 132 CHECK_MALLOC( new = malloc(sizeof(struct rtd_candidate)) ); |
133 memset(new, 0, sizeof(struct rtd_candidate) ); | |
717
571b3abaa5df
Support for Diameter Redirects through rt_redirect.fdx extension (EXPERIMENTAL)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
706
diff
changeset
|
134 fd_list_init(&new->chain, new); |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
135 CHECK_MALLOC( new->diamid = os0dup(peerid, peeridlen) ) |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
136 new->diamidlen = peeridlen; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
137 if (realm) { |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
138 CHECK_MALLOC( new->realm = os0dup(realm, realmlen) ) |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
139 new->realmlen = realmlen; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
140 } |
84 | 141 |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
142 /* insert in the list at the correct position */ |
84 | 143 fd_list_insert_after(prev, &new->chain); |
144 | |
145 return 0; | |
146 } | |
147 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
148 /* Remove a peer from the candidates (if it is found). Case insensitive search since the names are received from other peers */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
149 void fd_rtd_candidate_del(struct rt_data * rtd, uint8_t * id, size_t idsz) |
84 | 150 { |
151 struct fd_list * li; | |
152 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
153 TRACE_ENTRY("%p %p %zd", rtd, id, idsz); |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
154 CHECK_PARAMS_DO( rtd && id && idsz, return ); |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
155 |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
156 if (!fd_os_is_valid_DiameterIdentity(id, idsz)) |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
157 /* it cannot be in the list */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
158 return; |
84 | 159 |
160 for (li = rtd->candidates.next; li != &rtd->candidates; li = li->next) { | |
161 struct rtd_candidate * c = (struct rtd_candidate *) li; | |
738
d666051658bd
Fix broken 'almostcasecmp' logic
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
717
diff
changeset
|
162 int cont; |
d666051658bd
Fix broken 'almostcasecmp' logic
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
717
diff
changeset
|
163 int cmp = fd_os_almostcasesrch(id, idsz, c->diamid, c->diamidlen, &cont); |
84 | 164 |
165 if (!cmp) { | |
166 /* Found it! Remove it */ | |
167 fd_list_unlink(&c->chain); | |
168 free(c->diamid); | |
168
6db078b955e3
Completed rt_default extension
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
166
diff
changeset
|
169 free(c->realm); |
84 | 170 free(c); |
171 break; | |
172 } | |
173 | |
738
d666051658bd
Fix broken 'almostcasecmp' logic
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
717
diff
changeset
|
174 if (cont) |
84 | 175 continue; |
176 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
177 /* The list is guaranteed to be ordered only if not extracted */ |
84 | 178 if (! rtd->extracted) |
179 break; | |
180 } | |
181 | |
182 return; | |
183 } | |
184 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
185 /* If a peer returned a protocol error for this message, save it so that we don't try to send it there again. |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
186 Case insensitive search since the names are received from other peers*/ |
1019
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
187 int fd_rtd_error_add(struct rt_data * rtd, DiamId_t sentto, size_t senttolen, uint8_t * origin, size_t originsz, uint32_t rcode, struct fd_list ** candidates, int * sendingattemtps) |
84 | 188 { |
189 struct fd_list * li; | |
190 int match = 0; | |
191 | |
1019
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
192 TRACE_ENTRY("%p %p %zd %p %zd %u %p %p", rtd, sentto, senttolen, origin, originsz, rcode, candidates, sendingattemtps); |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
193 CHECK_PARAMS( rtd && sentto && senttolen ); /* origin may be NULL */ |
84 | 194 |
195 /* First add the new error entry */ | |
196 for (li = rtd->errors.next; li != &rtd->errors; li = li->next) { | |
197 struct rtd_error * e = (struct rtd_error *) li; | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
198 int cmp = fd_os_cmp(sentto, senttolen, e->nexthop, e->nexthoplen); |
84 | 199 if (cmp > 0) |
200 continue; | |
201 if (!cmp) | |
202 match = 1; | |
203 break; | |
204 } | |
205 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
206 /* If we already had this entry, we should not have sent the message again to this peer... anyway, let's close our eyes. */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
207 /* in the normal case, we save the error */ |
84 | 208 if (!match) { |
209 /* Add a new entry in the error list */ | |
210 struct rtd_error * new; | |
211 CHECK_MALLOC( new = malloc(sizeof(struct rtd_error)) ); | |
212 memset(new, 0, sizeof(struct rtd_error)); | |
213 fd_list_init(&new->chain, NULL); | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
214 |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
215 CHECK_MALLOC(new->nexthop = os0dup(sentto, senttolen)); |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
216 new->nexthoplen = senttolen; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
217 |
84 | 218 if (origin) { |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
219 if (!originsz) { |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
220 originsz=strlen((char *)origin); |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
221 } else { |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
222 if (!fd_os_is_valid_DiameterIdentity(origin, originsz)){ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
223 TRACE_DEBUG(FULL, "Received error %d from peer with invalid Origin-Host AVP, not saved", rcode); |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
224 origin = NULL; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
225 goto after_origin; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
226 } |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
227 } |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
228 CHECK_MALLOC( new->erh = (DiamId_t)os0dup(origin, originsz) ); |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
229 new->erhlen = originsz; |
84 | 230 } |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
231 after_origin: |
84 | 232 new->code = rcode; |
233 fd_list_insert_before(li, &new->chain); | |
234 } | |
235 | |
236 /* Finally, remove this (these) peers from the candidate list */ | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
237 fd_rtd_candidate_del(rtd, (os0_t)sentto, senttolen); |
84 | 238 if (origin) |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
239 fd_rtd_candidate_del(rtd, origin, originsz); |
84 | 240 |
1019
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
241 if (candidates) |
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
242 *candidates = &rtd->candidates; |
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
243 |
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
244 if (sendingattemtps) |
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
245 *sendingattemtps = rtd->extracted; |
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
246 |
84 | 247 /* Done! */ |
248 return 0; | |
249 } | |
250 | |
1097
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
251 /* Only retrieve the number of times this message has been processed by the routing-out mechanism (i.e. number of times it was failed over) */ |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
252 int fd_rtd_get_nb_attempts(struct rt_data * rtd, int * sendingattemtps) |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
253 { |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
254 TRACE_ENTRY("%p %p", rtd, sendingattemtps); |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
255 CHECK_PARAMS( rtd && sendingattemtps ); |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
256 |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
257 *sendingattemtps = rtd->extracted; |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
258 |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
259 /* Done! */ |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
260 return 0; |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
261 } |
4d2dcb54d9a6
New function fd_rtd_get_nb_attempts
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1019
diff
changeset
|
262 |
166
6d166f75e25a
Fix routing list scores initialization
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
124
diff
changeset
|
263 /* Extract the list of valid candidates, and initialize their scores */ |
124
cc42d8607114
Completed cleanups of queues when the daemon is stopping
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
84
diff
changeset
|
264 void fd_rtd_candidate_extract(struct rt_data * rtd, struct fd_list ** candidates, int ini_score) |
84 | 265 { |
166
6d166f75e25a
Fix routing list scores initialization
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
124
diff
changeset
|
266 struct fd_list * li; |
6d166f75e25a
Fix routing list scores initialization
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
124
diff
changeset
|
267 |
84 | 268 TRACE_ENTRY("%p %p", rtd, candidates); |
269 CHECK_PARAMS_DO( candidates, return ); | |
270 CHECK_PARAMS_DO( rtd, { *candidates = NULL; return; } ); | |
271 | |
272 *candidates = &rtd->candidates; | |
273 | |
166
6d166f75e25a
Fix routing list scores initialization
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
124
diff
changeset
|
274 /* Reset all scores to INITIAL score */ |
6d166f75e25a
Fix routing list scores initialization
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
124
diff
changeset
|
275 for (li = rtd->candidates.next; li != &rtd->candidates; li = li->next) { |
6d166f75e25a
Fix routing list scores initialization
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
124
diff
changeset
|
276 struct rtd_candidate * c = (struct rtd_candidate *) li; |
6d166f75e25a
Fix routing list scores initialization
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
124
diff
changeset
|
277 c->score = ini_score; |
84 | 278 } |
279 | |
1019
6fcd30ce3ce7
Retrieve additional information when adding a routing error
Sebastien Decugis <sdecugis@freediameter.net>
parents:
740
diff
changeset
|
280 rtd->extracted += 1; |
84 | 281 return; |
282 } | |
283 | |
563
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
284 /* Reorder the list of peers. If several peer have the same highest score, they are randomized. */ |
84 | 285 int fd_rtd_candidate_reorder(struct fd_list * candidates) |
286 { | |
287 struct fd_list unordered = FD_LIST_INITIALIZER(unordered), *li; | |
563
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
288 struct fd_list highest = FD_LIST_INITIALIZER(highest); |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
289 int hs = -1; |
84 | 290 |
291 TRACE_ENTRY("%p", candidates); | |
292 CHECK_PARAMS( candidates ); | |
293 | |
294 /* First, move all items from candidates to the undordered list */ | |
295 fd_list_move_end(&unordered, candidates); | |
296 | |
297 /* Now extract each element from unordered and add it back to list ordered by score */ | |
298 while (!FD_IS_LIST_EMPTY(&unordered)) { | |
299 struct rtd_candidate * c = (struct rtd_candidate *) unordered.next; | |
300 | |
301 fd_list_unlink(&c->chain); | |
302 | |
563
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
303 /* If this candidate has a higher score than the previous ones */ |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
304 if (c->score > hs) { |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
305 /* Then we move the previous high score items at end of the list */ |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
306 fd_list_move_end(candidates, &highest); |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
307 |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
662
diff
changeset
|
308 /* And the new high score is set */ |
563
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
309 hs = c->score; |
84 | 310 } |
311 | |
563
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
312 /* If this candidate equals the higher score, add it into highest list at a random place */ |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
313 if (c->score == hs) { |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
314 if (rand() & 1) { |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
315 fd_list_insert_after(&highest, &c->chain); |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
316 } else { |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
317 fd_list_insert_before(&highest, &c->chain); |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
318 } |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
319 /* Otherwise, insert at normal place in the list */ |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
320 } else { |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
321 /* Find the position in ordered candidates list */ |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
322 for (li = candidates->next; li != candidates; li = li->next) { |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
323 struct rtd_candidate * cnext = (struct rtd_candidate *) li; |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
324 if (cnext->score >= c->score) |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
325 break; |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
326 } |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
327 |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
328 /* Add the element there */ |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
329 fd_list_insert_before(li, &c->chain); |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
330 } |
84 | 331 } |
332 | |
563
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
333 /* Now simply move back all the "highest" candidates at the end of the list */ |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
334 fd_list_move_end(candidates, &highest); |
dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
403
diff
changeset
|
335 |
84 | 336 return 0; |
337 } | |
338 |