diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-02-03 18:44:40 +0100 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-02-03 18:44:40 +0100 |
commit | afd2cb5db220ce528b6222340b31b8a1a365c8e4 (patch) | |
tree | b5267e30561ac9469ba08e2996967c1373dfef36 | |
parent | 3d72be07448fd435640c6d0fdc2859601319d07e (diff) | |
download | gnunet-afd2cb5db220ce528b6222340b31b8a1a365c8e4.tar.gz gnunet-afd2cb5db220ce528b6222340b31b8a1a365c8e4.zip |
GNS: Introduce REDIRECT records. Fixes #7172
-rw-r--r-- | src/gns/gnunet-service-gns_resolver.c | 127 | ||||
-rw-r--r-- | src/gns/plugin_gnsrecord_gns.c | 8 |
2 files changed, 112 insertions, 23 deletions
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index f232fb272..461257609 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c | |||
@@ -1235,16 +1235,16 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh) | |||
1235 | 1235 | ||
1236 | 1236 | ||
1237 | /** | 1237 | /** |
1238 | * We encountered a CNAME record during our resolution. | 1238 | * We encountered a REDIRECT record during our resolution. |
1239 | * Merge it into our chain. | 1239 | * Merge it into our chain. |
1240 | * | 1240 | * |
1241 | * @param rh resolution we are performing | 1241 | * @param rh resolution we are performing |
1242 | * @param cname value of the cname record we got for the current | 1242 | * @param rname value of the redirect record we got for the current |
1243 | * authority chain tail | 1243 | * authority chain tail |
1244 | */ | 1244 | */ |
1245 | static void | 1245 | static void |
1246 | handle_gns_cname_result (struct GNS_ResolverHandle *rh, | 1246 | handle_gns_redirect_result (struct GNS_ResolverHandle *rh, |
1247 | const char *cname) | 1247 | const char *rname) |
1248 | { | 1248 | { |
1249 | size_t nlen; | 1249 | size_t nlen; |
1250 | char *res; | 1250 | char *res; |
@@ -1253,14 +1253,14 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1253 | int af; | 1253 | int af; |
1254 | struct GNUNET_IDENTITY_PublicKey zone; | 1254 | struct GNUNET_IDENTITY_PublicKey zone; |
1255 | 1255 | ||
1256 | nlen = strlen (cname); | 1256 | nlen = strlen (rname); |
1257 | tld = GNS_get_tld (cname); | 1257 | tld = GNS_get_tld (rname); |
1258 | if (0 == strcmp ("+", tld)) | 1258 | if (0 == strcmp ("+", tld)) |
1259 | { | 1259 | { |
1260 | /* CNAME resolution continues relative to current domain */ | 1260 | /* REDIRECT resolution continues relative to current domain */ |
1261 | if (0 == rh->name_resolution_pos) | 1261 | if (0 == rh->name_resolution_pos) |
1262 | { | 1262 | { |
1263 | res = GNUNET_strndup (cname, nlen - 2); | 1263 | res = GNUNET_strndup (rname, nlen - 2); |
1264 | rh->name_resolution_pos = nlen - 2; | 1264 | rh->name_resolution_pos = nlen - 2; |
1265 | } | 1265 | } |
1266 | else | 1266 | else |
@@ -1270,7 +1270,7 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1270 | (int) rh->name_resolution_pos, | 1270 | (int) rh->name_resolution_pos, |
1271 | rh->name, | 1271 | rh->name, |
1272 | (int) (nlen - 2), | 1272 | (int) (nlen - 2), |
1273 | cname); | 1273 | rname); |
1274 | rh->name_resolution_pos = strlen (res); | 1274 | rh->name_resolution_pos = strlen (res); |
1275 | } | 1275 | } |
1276 | GNUNET_free (rh->name); | 1276 | GNUNET_free (rh->name); |
@@ -1291,13 +1291,13 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1291 | } | 1291 | } |
1292 | if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone)) | 1292 | if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone)) |
1293 | { | 1293 | { |
1294 | /* CNAME resolution continues relative to current domain */ | 1294 | /* REDIRECT resolution continues relative to current domain */ |
1295 | if (0 == rh->name_resolution_pos) | 1295 | if (0 == rh->name_resolution_pos) |
1296 | { | 1296 | { |
1297 | GNUNET_asprintf (&res, | 1297 | GNUNET_asprintf (&res, |
1298 | "%.*s", | 1298 | "%.*s", |
1299 | (int) (strlen (cname) - (strlen (tld) + 1)), | 1299 | (int) (strlen (rname) - (strlen (tld) + 1)), |
1300 | cname); | 1300 | rname); |
1301 | } | 1301 | } |
1302 | else | 1302 | else |
1303 | { | 1303 | { |
@@ -1305,8 +1305,8 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1305 | "%.*s.%.*s", | 1305 | "%.*s.%.*s", |
1306 | (int) rh->name_resolution_pos, | 1306 | (int) rh->name_resolution_pos, |
1307 | rh->name, | 1307 | rh->name, |
1308 | (int) (strlen (cname) - (strlen (tld) + 1)), | 1308 | (int) (strlen (rname) - (strlen (tld) + 1)), |
1309 | cname); | 1309 | rname); |
1310 | } | 1310 | } |
1311 | rh->name_resolution_pos = strlen (res); | 1311 | rh->name_resolution_pos = strlen (res); |
1312 | GNUNET_free (rh->name); | 1312 | GNUNET_free (rh->name); |
@@ -1326,18 +1326,64 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1326 | } | 1326 | } |
1327 | 1327 | ||
1328 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1328 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1329 | "Got CNAME `%s' from GNS for `%s'\n", | 1329 | "Got REDIRECT `%s' from GNS for `%s'\n", |
1330 | cname, | 1330 | rname, |
1331 | rh->name); | 1331 | rh->name); |
1332 | if (NULL != rh->std_resolve) | 1332 | if (NULL != rh->std_resolve) |
1333 | { | 1333 | { |
1334 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1334 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1335 | "Multiple CNAME results from GNS resolving `%s'! Not really allowed...\n", | 1335 | "Multiple REDIRECT results from GNS resolving `%s'! Not really allowed...\n", |
1336 | rh->name); | 1336 | rh->name); |
1337 | GNUNET_RESOLVER_request_cancel (rh->std_resolve); | 1337 | GNUNET_RESOLVER_request_cancel (rh->std_resolve); |
1338 | } | 1338 | } |
1339 | /* name is absolute, go to DNS */ | 1339 | /* name is absolute, go to DNS */ |
1340 | GNUNET_free (rh->name); | 1340 | GNUNET_free (rh->name); |
1341 | rh->name = GNUNET_strdup (rname); | ||
1342 | rh->name_resolution_pos = strlen (rh->name); | ||
1343 | switch (rh->record_type) | ||
1344 | { | ||
1345 | case GNUNET_DNSPARSER_TYPE_A: | ||
1346 | af = AF_INET; | ||
1347 | break; | ||
1348 | |||
1349 | case GNUNET_DNSPARSER_TYPE_AAAA: | ||
1350 | af = AF_INET6; | ||
1351 | break; | ||
1352 | |||
1353 | default: | ||
1354 | af = AF_UNSPEC; | ||
1355 | break; | ||
1356 | } | ||
1357 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1358 | "Doing standard DNS lookup for `%s'\n", | ||
1359 | rh->name); | ||
1360 | |||
1361 | rh->std_resolve = GNUNET_RESOLVER_ip_get (rh->name, | ||
1362 | af, | ||
1363 | DNS_LOOKUP_TIMEOUT, | ||
1364 | &handle_dns_result, | ||
1365 | rh); | ||
1366 | } | ||
1367 | |||
1368 | |||
1369 | |||
1370 | /** | ||
1371 | * We encountered a CNAME record during our resolution. | ||
1372 | * Merge it into our chain. | ||
1373 | * | ||
1374 | * @param rh resolution we are performing | ||
1375 | * @param cname value of the cname record we got for the current | ||
1376 | * authority chain tail | ||
1377 | */ | ||
1378 | static void | ||
1379 | handle_gns_cname_result (struct GNS_ResolverHandle *rh, | ||
1380 | const char *cname) | ||
1381 | { | ||
1382 | struct AuthorityChain *ac; | ||
1383 | int af; | ||
1384 | struct GNUNET_IDENTITY_PublicKey zone; | ||
1385 | |||
1386 | GNUNET_free (rh->name); | ||
1341 | rh->name = GNUNET_strdup (cname); | 1387 | rh->name = GNUNET_strdup (cname); |
1342 | rh->name_resolution_pos = strlen (rh->name); | 1388 | rh->name_resolution_pos = strlen (rh->name); |
1343 | switch (rh->record_type) | 1389 | switch (rh->record_type) |
@@ -1653,6 +1699,20 @@ handle_gns2dns_ip (void *cls, | |||
1653 | ac->authority_info.dns_authority.found = GNUNET_YES; | 1699 | ac->authority_info.dns_authority.found = GNUNET_YES; |
1654 | } | 1700 | } |
1655 | 1701 | ||
1702 | /** | ||
1703 | * We found a REDIRECT record, perform recursive resolution on it. | ||
1704 | * | ||
1705 | * @param rh resolution handle | ||
1706 | * @param rd record with CNAME to resolve recursively | ||
1707 | */ | ||
1708 | static void | ||
1709 | recursive_redirect_resolution (struct GNS_ResolverHandle *rh, | ||
1710 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1711 | { | ||
1712 | handle_gns_redirect_result (rh, | ||
1713 | rd->data); | ||
1714 | } | ||
1715 | |||
1656 | 1716 | ||
1657 | /** | 1717 | /** |
1658 | * We found a CNAME record, perform recursive resolution on it. | 1718 | * We found a CNAME record, perform recursive resolution on it. |
@@ -2006,6 +2066,16 @@ handle_gns_resolution_result (void *cls, | |||
2006 | GNUNET_free (cname); | 2066 | GNUNET_free (cname); |
2007 | return; | 2067 | return; |
2008 | } | 2068 | } |
2069 | if ((rd_count > 0) && | ||
2070 | (GNUNET_GNSRECORD_TYPE_REDIRECT == rd[0].record_type) && | ||
2071 | (GNUNET_GNSRECORD_TYPE_REDIRECT != rh->record_type)) | ||
2072 | { | ||
2073 | handle_gns_cname_result (rh, | ||
2074 | rd[0].data); | ||
2075 | return; | ||
2076 | } | ||
2077 | |||
2078 | |||
2009 | /* If A/AAAA was requested, but we got a VPN | 2079 | /* If A/AAAA was requested, but we got a VPN |
2010 | record, we convert it to A/AAAA using GNUnet VPN */ | 2080 | record, we convert it to A/AAAA using GNUnet VPN */ |
2011 | if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) || | 2081 | if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) || |
@@ -2117,6 +2187,23 @@ handle_gns_resolution_result (void *cls, | |||
2117 | so we can free it afterwards. */ | 2187 | so we can free it afterwards. */ |
2118 | switch (rd[i].record_type) | 2188 | switch (rd[i].record_type) |
2119 | { | 2189 | { |
2190 | case GNUNET_GNSRECORD_TYPE_REDIRECT: | ||
2191 | { | ||
2192 | char *rname; | ||
2193 | rname = GNUNET_strndup (rd[i].data, rd[i].data_size); | ||
2194 | rname = translate_dot_plus (rh, rname); | ||
2195 | GNUNET_break (NULL != rname); | ||
2196 | scratch_start = scratch_off; | ||
2197 | memcpy (&scratch[scratch_start], rname, strlen (rname) + 1); | ||
2198 | scratch_off += strlen (rname) + 1; | ||
2199 | GNUNET_assert (rd_off < rd_count); | ||
2200 | rd_new[rd_off].data = &scratch[scratch_start]; | ||
2201 | rd_new[rd_off].data_size = scratch_off - scratch_start; | ||
2202 | rd_off++; | ||
2203 | GNUNET_free (rname); | ||
2204 | } | ||
2205 | break; | ||
2206 | |||
2120 | case GNUNET_DNSPARSER_TYPE_CNAME: | 2207 | case GNUNET_DNSPARSER_TYPE_CNAME: |
2121 | { | 2208 | { |
2122 | char *cname; | 2209 | char *cname; |
@@ -2380,6 +2467,12 @@ handle_gns_resolution_result (void *cls, | |||
2380 | 2467 | ||
2381 | switch (rd[0].record_type) | 2468 | switch (rd[0].record_type) |
2382 | { | 2469 | { |
2470 | case GNUNET_GNSRECORD_TYPE_REDIRECT: | ||
2471 | GNUNET_break_op (1 == rd_count); /* REDIRECT should be unique */ | ||
2472 | recursive_redirect_resolution (rh, | ||
2473 | &rd[0]); | ||
2474 | return; | ||
2475 | |||
2383 | case GNUNET_DNSPARSER_TYPE_CNAME: | 2476 | case GNUNET_DNSPARSER_TYPE_CNAME: |
2384 | GNUNET_break_op (1 == rd_count); /* CNAME should be unique */ | 2477 | GNUNET_break_op (1 == rd_count); /* CNAME should be unique */ |
2385 | recursive_cname_resolution (rh, | 2478 | recursive_cname_resolution (rh, |
diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c index f270e4473..e74ec96ad 100644 --- a/src/gns/plugin_gnsrecord_gns.c +++ b/src/gns/plugin_gnsrecord_gns.c | |||
@@ -64,8 +64,7 @@ gns_value_to_string (void *cls, | |||
64 | return GNUNET_IDENTITY_public_key_to_string (&pk); | 64 | return GNUNET_IDENTITY_public_key_to_string (&pk); |
65 | 65 | ||
66 | case GNUNET_GNSRECORD_TYPE_NICK: | 66 | case GNUNET_GNSRECORD_TYPE_NICK: |
67 | return GNUNET_strndup (data, data_size); | 67 | case GNUNET_GNSRECORD_TYPE_REDIRECT: |
68 | |||
69 | case GNUNET_GNSRECORD_TYPE_LEHO: | 68 | case GNUNET_GNSRECORD_TYPE_LEHO: |
70 | return GNUNET_strndup (data, data_size); | 69 | return GNUNET_strndup (data, data_size); |
71 | 70 | ||
@@ -190,10 +189,7 @@ gns_string_to_value (void *cls, | |||
190 | return GNUNET_OK; | 189 | return GNUNET_OK; |
191 | 190 | ||
192 | case GNUNET_GNSRECORD_TYPE_NICK: | 191 | case GNUNET_GNSRECORD_TYPE_NICK: |
193 | *data = GNUNET_strdup (s); | 192 | case GNUNET_GNSRECORD_TYPE_REDIRECT: |
194 | *data_size = strlen (s); | ||
195 | return GNUNET_OK; | ||
196 | |||
197 | case GNUNET_GNSRECORD_TYPE_LEHO: | 193 | case GNUNET_GNSRECORD_TYPE_LEHO: |
198 | *data = GNUNET_strdup (s); | 194 | *data = GNUNET_strdup (s); |
199 | *data_size = strlen (s); | 195 | *data_size = strlen (s); |