diff options
-rw-r--r-- | src/gns/gnunet-service-gns_resolver.c | 164 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_resolver.h | 11 |
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 | */ | ||
1299 | static void | ||
1300 | send_dns_packet (struct ResolverHandle *rh); | ||
1301 | |||
1302 | |||
1303 | static void | ||
1304 | read_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 | */ | ||
1421 | static void | ||
1422 | send_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 | ||