aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gns_tld_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gns_tld_api.c')
-rw-r--r--src/gns/gns_tld_api.c120
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 */
184static void 197static void
185identity_zone_cb (void *cls, 198identity_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 &ltr->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 *
333GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr) 384GNUNET_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;