diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-01-11 22:22:32 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-01-11 22:22:40 +0100 |
commit | 18406d4913d43024b66eca3a2ee434984fd5d342 (patch) | |
tree | 10fb0b0d6cb4af5da750c994b639cf151af70883 | |
parent | 963cdcfe33adfb00c18bbcbf2f93ff363d27fa01 (diff) | |
download | gnunet-18406d4913d43024b66eca3a2ee434984fd5d342.tar.gz gnunet-18406d4913d43024b66eca3a2ee434984fd5d342.zip |
do longest prefix match on egos as well
-rw-r--r-- | src/gns/gns_tld_api.c | 120 |
1 files changed, 86 insertions, 34 deletions
diff --git a/src/gns/gns_tld_api.c b/src/gns/gns_tld_api.c index 55ee30bd9..d9856ea90 100644 --- a/src/gns/gns_tld_api.c +++ b/src/gns/gns_tld_api.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -71,7 +71,18 @@ struct GNUNET_GNS_LookupWithTldRequest | |||
71 | /** | 71 | /** |
72 | * Lookup an ego with the identity service. | 72 | * Lookup an ego with the identity service. |
73 | */ | 73 | */ |
74 | struct GNUNET_IDENTITY_EgoLookup *id_op; | 74 | struct GNUNET_IDENTITY_Handle *id_co; |
75 | |||
76 | /** | ||
77 | * Name of the longest matching ego found so far. | ||
78 | * Must be freed on termination. | ||
79 | */ | ||
80 | char *longest_match; | ||
81 | |||
82 | /** | ||
83 | * Ego corresponding to @e longest_match. | ||
84 | */ | ||
85 | struct GNUNET_IDENTITY_Ego *longest_match_ego; | ||
75 | 86 | ||
76 | /** | 87 | /** |
77 | * Desired result record type. | 88 | * Desired result record type. |
@@ -179,31 +190,82 @@ lookup_with_public_key (struct GNUNET_GNS_LookupWithTldRequest *ltr, | |||
179 | * when the ego is determined by a name. | 190 | * when the ego is determined by a name. |
180 | * | 191 | * |
181 | * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *` | 192 | * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *` |
182 | * @param ego ego handle, NULL if not found | 193 | * @param ego ego handle, NULL at the end of the iteration |
194 | * @param ctx context we could store data to associate with @e ego | ||
195 | * @param name name of the ego | ||
183 | */ | 196 | */ |
184 | static void | 197 | static void |
185 | identity_zone_cb (void *cls, | 198 | identity_zone_cb (void *cls, |
186 | const struct GNUNET_IDENTITY_Ego *ego) | 199 | struct GNUNET_IDENTITY_Ego *ego, |
200 | void **ctx, | ||
201 | const char *name) | ||
187 | { | 202 | { |
188 | struct GNUNET_GNS_LookupWithTldRequest *ltr = cls; | 203 | struct GNUNET_GNS_LookupWithTldRequest *ltr = cls; |
189 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; | 204 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; |
190 | 205 | ||
191 | ltr->id_op = NULL; | ||
192 | if (NULL == ego) | 206 | if (NULL == ego) |
193 | { | 207 | { |
194 | ltr->lookup_proc (ltr->lookup_proc_cls, | 208 | if (NULL != ltr->longest_match) |
195 | GNUNET_NO, | 209 | { |
196 | 0, | 210 | /* Final case: TLD matches one of our egos */ |
197 | NULL); | 211 | // FIXME: eat all of the match (not just TLD!) |
198 | GNUNET_GNS_lookup_with_tld_cancel (ltr); | 212 | if (0 == strcmp (ltr->name, |
213 | ltr->longest_match)) | ||
214 | { | ||
215 | /* name matches ego name perfectly, only "@" remains */ | ||
216 | strcpy (ltr->name, | ||
217 | GNUNET_GNS_EMPTY_LABEL_AT); | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | GNUNET_assert (strlen (ltr->longest_match) < strlen (ltr->name)); | ||
222 | ltr->name[strlen(ltr->name) - strlen (ltr->longest_match) - 1] = '\0'; | ||
223 | } | ||
224 | |||
225 | /* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go to the DHT */ | ||
226 | GNUNET_free (ltr->longest_match); | ||
227 | ltr->longest_match = NULL; | ||
228 | if (NULL == strchr (ltr->name, | ||
229 | (unsigned char) '.')) | ||
230 | ltr->options = GNUNET_GNS_LO_NO_DHT; | ||
231 | else | ||
232 | ltr->options = GNUNET_GNS_LO_LOCAL_MASTER; | ||
233 | |||
234 | GNUNET_IDENTITY_ego_get_public_key (ltr->longest_match_ego, | ||
235 | &pkey); | ||
236 | GNUNET_IDENTITY_disconnect (ltr->id_co); | ||
237 | ltr->id_co = NULL; | ||
238 | lookup_with_public_key (ltr, | ||
239 | &pkey); | ||
240 | } | ||
241 | else | ||
242 | { | ||
243 | /* no matching ego found */ | ||
244 | GNUNET_IDENTITY_disconnect (ltr->id_co); | ||
245 | ltr->id_co = NULL; | ||
246 | ltr->lookup_proc (ltr->lookup_proc_cls, | ||
247 | GNUNET_NO, | ||
248 | 0, | ||
249 | NULL); | ||
250 | GNUNET_GNS_lookup_with_tld_cancel (ltr); | ||
251 | } | ||
199 | return; | 252 | return; |
200 | } | 253 | } |
201 | else | 254 | else if (NULL != name) |
202 | { | 255 | { |
203 | GNUNET_IDENTITY_ego_get_public_key (ego, | 256 | if ( (strlen (name) <= strlen (ltr->name)) && |
204 | &pkey); | 257 | (0 == strcmp (name, |
205 | lookup_with_public_key (ltr, | 258 | <r->name[strlen(ltr->name) - strlen (name)])) && |
206 | &pkey); | 259 | ( (strlen (name) == strlen (ltr->name)) || |
260 | ('.' == ltr->name[strlen(ltr->name) - strlen (name) - 1]) ) && | ||
261 | ( (NULL == ltr->longest_match) || | ||
262 | (strlen (name) > strlen (ltr->longest_match)) ) ) | ||
263 | { | ||
264 | /* found better match, update! */ | ||
265 | GNUNET_free_non_null (ltr->longest_match); | ||
266 | ltr->longest_match = GNUNET_strdup (name); | ||
267 | ltr->longest_match_ego = ego; | ||
268 | } | ||
207 | } | 269 | } |
208 | } | 270 | } |
209 | 271 | ||
@@ -299,21 +361,10 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, | |||
299 | GNUNET_free (dot_tld); | 361 | GNUNET_free (dot_tld); |
300 | } | 362 | } |
301 | 363 | ||
302 | /* Final case: TLD matches one of our egos */ | 364 | ltr->id_co = GNUNET_IDENTITY_connect (ltr->gns_handle->cfg, |
303 | eat_tld (ltr->name, | 365 | &identity_zone_cb, |
304 | tld); | 366 | ltr); |
305 | 367 | if (NULL == ltr->id_co) | |
306 | /* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go to the DHT */ | ||
307 | if (NULL == strchr (ltr->name, | ||
308 | (unsigned char) '.')) | ||
309 | ltr->options = GNUNET_GNS_LO_NO_DHT; | ||
310 | else | ||
311 | ltr->options = GNUNET_GNS_LO_LOCAL_MASTER; | ||
312 | ltr->id_op = GNUNET_IDENTITY_ego_lookup (ltr->gns_handle->cfg, | ||
313 | tld, | ||
314 | &identity_zone_cb, | ||
315 | ltr); | ||
316 | if (NULL == ltr->id_op) | ||
317 | { | 368 | { |
318 | GNUNET_free (ltr->name); | 369 | GNUNET_free (ltr->name); |
319 | GNUNET_free (ltr); | 370 | GNUNET_free (ltr); |
@@ -333,17 +384,18 @@ void * | |||
333 | GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr) | 384 | GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr) |
334 | { | 385 | { |
335 | void *ret = ltr->lookup_proc_cls; | 386 | void *ret = ltr->lookup_proc_cls; |
336 | 387 | ||
337 | if (NULL != ltr->id_op) | 388 | if (NULL != ltr->id_co) |
338 | { | 389 | { |
339 | GNUNET_IDENTITY_ego_lookup_cancel (ltr->id_op); | 390 | GNUNET_IDENTITY_disconnect (ltr->id_co); |
340 | ltr->id_op = NULL; | 391 | ltr->id_co = NULL; |
341 | } | 392 | } |
342 | if (NULL != ltr->lr) | 393 | if (NULL != ltr->lr) |
343 | { | 394 | { |
344 | GNUNET_GNS_lookup_cancel (ltr->lr); | 395 | GNUNET_GNS_lookup_cancel (ltr->lr); |
345 | ltr->lr = NULL; | 396 | ltr->lr = NULL; |
346 | } | 397 | } |
398 | GNUNET_free_non_null (ltr->longest_match); | ||
347 | GNUNET_free (ltr->name); | 399 | GNUNET_free (ltr->name); |
348 | GNUNET_free (ltr); | 400 | GNUNET_free (ltr); |
349 | return ret; | 401 | return ret; |