aboutsummaryrefslogtreecommitdiff
path: root/src/gns
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-16 18:12:10 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-16 18:12:10 +0000
commite92f0d41aa9063c24fae339f93ea76240909883d (patch)
tree9a0d9aef2eb310ad8efc692b95b98c796092e8c6 /src/gns
parent7028ad967e99bfdef4938a26442b8466730f666b (diff)
downloadgnunet-e92f0d41aa9063c24fae339f93ea76240909883d.tar.gz
gnunet-e92f0d41aa9063c24fae339f93ea76240909883d.zip
-more NS delegation
Diffstat (limited to 'src/gns')
-rw-r--r--src/gns/gnunet-service-gns_resolver.c164
-rw-r--r--src/gns/gnunet-service-gns_resolver.h11
2 files changed, 170 insertions, 5 deletions
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c
index bbdf90194..514bb1785 100644
--- a/src/gns/gnunet-service-gns_resolver.c
+++ b/src/gns/gnunet-service-gns_resolver.c
@@ -1292,6 +1292,156 @@ handle_record_vpn (void* cls, struct ResolverHandle *rh,
1292 1292
1293 1293
1294/** 1294/**
1295 * Sends a UDP dns query to a nameserver specified in the rh
1296 *
1297 * @param rh the request handle
1298 */
1299static void
1300send_dns_packet (struct ResolverHandle *rh);
1301
1302
1303static void
1304read_dns_response (void *cls,
1305 const struct GNUNET_SCHEDULER_TaskContext *tc)
1306{
1307 struct ResolverHandle *rh = cls;
1308 struct RecordLookupHandle *rlh = rh->proc_cls;
1309 char buf[UINT16_MAX];
1310 ssize_t r;
1311 struct sockaddr_in addr;
1312 socklen_t addrlen;
1313 struct GNUNET_DNSPARSER_Packet *packet;
1314 struct GNUNET_NAMESTORE_RecordData rd;
1315 int found_delegation = GNUNET_NO;
1316 char* delegation_name = NULL;
1317 int i;
1318
1319 rh->dns_read_task = GNUNET_SCHEDULER_NO_TASK;
1320 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
1321 {
1322 /* timeout or shutdown */
1323 rh->proc (rh->proc_cls, rh, 0, NULL);
1324 GNUNET_NETWORK_socket_close (rh->dns_sock);
1325 free_resolver_handle (rh);
1326 return;
1327 }
1328
1329 addrlen = sizeof (addr);
1330 r = GNUNET_NETWORK_socket_recvfrom (rh->dns_sock,
1331 buf, sizeof (buf),
1332 (struct sockaddr*) &addr,
1333 &addrlen);
1334
1335 if (-1 == r)
1336 {
1337 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recvfrom");
1338 rh->proc (rh->proc_cls, rh, 0, NULL);
1339 GNUNET_NETWORK_socket_close (rh->dns_sock);
1340 free_resolver_handle (rh);
1341 return;
1342 }
1343
1344 packet = GNUNET_DNSPARSER_parse (buf, r);
1345
1346 if (NULL == packet)
1347 {
1348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1349 "Failed to parse DNS reply!\n");
1350 rh->proc (rh->proc_cls, rh, 0, NULL);
1351 GNUNET_NETWORK_socket_close (rh->dns_sock);
1352 free_resolver_handle (rh);
1353 return;
1354 }
1355
1356 for (i = 0; i < packet->num_answers; i++)
1357 {
1358 if ((packet->answers[i].type == rlh->record_type) &&
1359 (0 == strcmp (packet->answers[i].name, rh->dns_name)))
1360 {
1361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1362 "Found record!\n");
1363 rd.data = packet->answers[i].data.raw.data;
1364 rd.data_size = packet->answers[i].data.raw.data_len;
1365 rd.record_type = packet->answers[i].type;
1366 rd.flags = 0;
1367 rd.expiration = packet->answers[i].expiration_time;
1368 rh->proc (rh->proc_cls, rh, 1, &rd);
1369 GNUNET_NETWORK_socket_close (rh->dns_sock);
1370 GNUNET_DNSPARSER_free_packet (packet);
1371 free_resolver_handle (rh);
1372 return;
1373 }
1374 }
1375
1376 for (i = 0; i < packet->num_authority_records; i++)
1377 {
1378 if (packet->authority_records[i].type == GNUNET_GNS_RECORD_TYPE_NS)
1379 {
1380 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1381 "Found NS delegation!\n");
1382 found_delegation = GNUNET_YES;
1383 delegation_name = packet->authority_records[i].data.hostname;
1384 break;
1385 }
1386 }
1387
1388 for (i = 0; i < packet->num_additional_records; i++)
1389 {
1390 if (found_delegation == GNUNET_NO)
1391 break;
1392
1393 if ((packet->additional_records[i].type == GNUNET_GNS_RECORD_TYPE_A) &&
1394 (0 == strcmp (packet->additional_records[i].name, delegation_name)))
1395 {
1396 GNUNET_assert (sizeof (struct in_addr) ==
1397 packet->authority_records[i].data.raw.data_len);
1398
1399 rh->dns_addr.sin_addr =
1400 *((struct in_addr*)packet->authority_records[i].data.raw.data);
1401 send_dns_packet (rh);
1402 GNUNET_DNSPARSER_free_packet (packet);
1403 return;
1404 }
1405 }
1406
1407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1408 "Failed to parse DNS reply!\n");
1409 rh->proc (rh->proc_cls, rh, 0, NULL);
1410 GNUNET_NETWORK_socket_close (rh->dns_sock);
1411 free_resolver_handle (rh);
1412 GNUNET_DNSPARSER_free_packet (packet);
1413 return;
1414}
1415
1416/**
1417 * Sends a UDP dns query to a nameserver specified in the rh
1418 *
1419 * @param rh the request handle
1420 */
1421static void
1422send_dns_packet (struct ResolverHandle *rh)
1423{
1424 struct GNUNET_NETWORK_FDSet *rset = GNUNET_NETWORK_fdset_create ();
1425 GNUNET_NETWORK_fdset_set (rset, rh->dns_sock);
1426
1427 GNUNET_NETWORK_socket_sendto (rh->dns_sock,
1428 rh->dns_raw_packet,
1429 rh->dns_raw_packet_size,
1430 (struct sockaddr*)&rh->dns_addr,
1431 sizeof (struct sockaddr_in));
1432
1433 rh->dns_read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1434 rh->timeout, //FIXME less?
1435 rset,
1436 NULL,
1437 &read_dns_response,
1438 rh);
1439
1440 GNUNET_NETWORK_fdset_destroy (rset);
1441
1442}
1443
1444/**
1295 * The final phase of resoution. 1445 * The final phase of resoution.
1296 * We found a NS RR and want to resolve via DNS 1446 * We found a NS RR and want to resolve via DNS
1297 * 1447 *
@@ -1313,7 +1463,6 @@ resolve_record_dns (struct ResolverHandle *rh,
1313 struct sockaddr *sa; 1463 struct sockaddr *sa;
1314 int i; 1464 int i;
1315 struct RecordLookupHandle *rlh = rh->proc_cls; 1465 struct RecordLookupHandle *rlh = rh->proc_cls;
1316 size_t packet_size;
1317 1466
1318 /* We cancel here as to not include the ns lookup in the timeout */ 1467 /* We cancel here as to not include the ns lookup in the timeout */
1319 if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK) 1468 if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK)
@@ -1335,7 +1484,7 @@ resolve_record_dns (struct ResolverHandle *rh,
1335 { 1484 {
1336 /* Synthesize dns name */ 1485 /* Synthesize dns name */
1337 if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_NS) 1486 if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_NS)
1338 sprintf (dns_name, "%s.%s", rh->name, (char*)rd[i].data); 1487 sprintf (rh->dns_name, "%s.%s", rh->name, (char*)rd[i].data);
1339 /* The glue */ 1488 /* The glue */
1340 if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_A) 1489 if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_A)
1341 dnsip = *((struct in_addr*)rd[i].data); 1490 dnsip = *((struct in_addr*)rd[i].data);
@@ -1345,7 +1494,6 @@ resolve_record_dns (struct ResolverHandle *rh,
1345 "GNS_PHASE_REC_DNS-%llu: Looking up %s from %s\n", 1494 "GNS_PHASE_REC_DNS-%llu: Looking up %s from %s\n",
1346 dns_name, 1495 dns_name,
1347 inet_ntoa (dnsip)); 1496 inet_ntoa (dnsip));
1348 rh->dns_ip = dnsip;
1349 rh->dns_sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_DGRAM, 0); 1497 rh->dns_sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_DGRAM, 0);
1350 if (rh->dns_sock == NULL) 1498 if (rh->dns_sock == NULL)
1351 { 1499 {
@@ -1394,7 +1542,7 @@ resolve_record_dns (struct ResolverHandle *rh,
1394 if (GNUNET_OK != GNUNET_DNSPARSER_pack (&packet, 1542 if (GNUNET_OK != GNUNET_DNSPARSER_pack (&packet,
1395 UINT16_MAX, 1543 UINT16_MAX,
1396 &rh->dns_raw_packet, 1544 &rh->dns_raw_packet,
1397 &packet_size)) 1545 &rh->dns_raw_packet_size))
1398 { 1546 {
1399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1547 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1400 "GNS_PHASE_REC_DNS-%llu: Creating raw dns packet!\n", 1548 "GNS_PHASE_REC_DNS-%llu: Creating raw dns packet!\n",
@@ -1404,6 +1552,14 @@ resolve_record_dns (struct ResolverHandle *rh,
1404 return; 1552 return;
1405 } 1553 }
1406 1554
1555 rh->dns_addr.sin_family = AF_INET;
1556 rh->dns_addr.sin_port = htons (53); //domain
1557 rh->dns_addr.sin_addr = dnsip;
1558#if HAVE_SOCKADDR_IN_SIN_LEN
1559 rh->dns_addr.sin_len = (u_char) sizeof (struct sockaddr_in);
1560#endif
1561
1562 send_dns_packet (rh);
1407 1563
1408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1564 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1409 "GNS_PHASE_REC_DNS-%llu: NOT IMPLEMENTED!\n", 1565 "GNS_PHASE_REC_DNS-%llu: NOT IMPLEMENTED!\n",
diff --git a/src/gns/gnunet-service-gns_resolver.h b/src/gns/gnunet-service-gns_resolver.h
index a0ac2cb0b..d7ad17d5f 100644
--- a/src/gns/gnunet-service-gns_resolver.h
+++ b/src/gns/gnunet-service-gns_resolver.h
@@ -139,12 +139,21 @@ struct ResolverHandle
139 /* a socket for a dns request */ 139 /* a socket for a dns request */
140 struct GNUNET_NETWORK_Handle *dns_sock; 140 struct GNUNET_NETWORK_Handle *dns_sock;
141 141
142 /* a synthesized dns name */
143 char dns_name[MAX_DNS_NAME_LENGTH];
144
142 /* the address of the DNS server FIXME not needed? */ 145 /* the address of the DNS server FIXME not needed? */
143 struct in_addr dns_ip; 146 struct sockaddr_in dns_addr;
147
148 /* select task for DNS */
149 GNUNET_SCHEDULER_TaskIdentifier dns_read_task;
144 150
145 /* pointer to raw dns query payload FIXME needs to be freed/NULL */ 151 /* pointer to raw dns query payload FIXME needs to be freed/NULL */
146 char *dns_raw_packet; 152 char *dns_raw_packet;
147 153
154 /* size of the raw dns query */
155 size_t dns_raw_packet_size;
156
148 /* timeout task for the lookup */ 157 /* timeout task for the lookup */
149 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 158 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
150 159