From fe14caa055450c56088cfde9e5f008a104175319 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Sat, 16 Jun 2012 16:04:05 +0000 Subject: -NS delegation WIP --- src/gns/gnunet-service-gns_resolver.c | 167 +++++++++++++++++++++++++++++++++- src/gns/gnunet-service-gns_resolver.h | 14 ++- 2 files changed, 178 insertions(+), 3 deletions(-) diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index 6e20c3f9c..bbdf90194 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c @@ -1291,6 +1291,129 @@ handle_record_vpn (void* cls, struct ResolverHandle *rh, } +/** + * The final phase of resoution. + * We found a NS RR and want to resolve via DNS + * + * @param rh the pending lookup handle + * @param rd_count length of record data + * @param rd record data containing VPN RR + */ +static void +resolve_record_dns (struct ResolverHandle *rh, + int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct GNUNET_DNSPARSER_Query query; + struct GNUNET_DNSPARSER_Packet packet; + struct GNUNET_DNSPARSER_Flags flags; + char dns_name[MAX_DNS_NAME_LENGTH]; + struct in_addr dnsip; + struct sockaddr_in addr; + struct sockaddr *sa; + int i; + struct RecordLookupHandle *rlh = rh->proc_cls; + size_t packet_size; + + /* We cancel here as to not include the ns lookup in the timeout */ + if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel(rh->timeout_task); + rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + /* Start shortening */ + if ((rh->priv_key != NULL) && is_canonical (rh->name)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC_DNS-%llu: Trying to shorten authority chain\n", + rh->id); + start_shorten (rh->authority_chain_tail, + rh->priv_key); + } + + for (i = 0; i < rd_count; i++) + { + /* Synthesize dns name */ + if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_NS) + sprintf (dns_name, "%s.%s", rh->name, (char*)rd[i].data); + /* The glue */ + if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_A) + dnsip = *((struct in_addr*)rd[i].data); + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC_DNS-%llu: Looking up %s from %s\n", + dns_name, + inet_ntoa (dnsip)); + rh->dns_ip = dnsip; + rh->dns_sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_DGRAM, 0); + if (rh->dns_sock == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC_DNS-%llu: Error creating udp socket for dns!\n", + rh->id); + rh->proc(rh->proc_cls, rh, 0, NULL); + return; + } + + memset (&addr, 0, sizeof (struct sockaddr_in)); + sa = (struct sockaddr *) &addr; + sa->sa_family = AF_INET; + if (GNUNET_OK != GNUNET_NETWORK_socket_bind (rh->dns_sock, + sa, + sizeof (struct sockaddr_in))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC_DNS-%llu: Error binding udp socket for dns!\n", + rh->id); + GNUNET_NETWORK_socket_close (rh->dns_sock); + rh->proc(rh->proc_cls, rh, 0, NULL); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC_DNS-%llu: NOT IMPLEMENTED!\n", + rh->id); + GNUNET_NETWORK_socket_close (rh->dns_sock); + rh->proc(rh->proc_cls, rh, 0, NULL); + /*TODO create dnsparser query, serialize, sendto, handle reply*/ + query.name = dns_name; + query.type = rlh->record_type; + query.class = GNUNET_DNSPARSER_CLASS_INTERNET; + memset (&flags, 0, sizeof (flags)); + flags.recursion_desired = 1; + flags.checking_disabled = 1; + packet.queries = &query; + packet.answers = NULL; + packet.authority_records = NULL; + packet.num_queries = 1; + packet.num_answers = 0; + packet.num_authority_records = 0; + packet.num_additional_records = 0; + packet.flags = flags; + packet.id = rh->id; + if (GNUNET_OK != GNUNET_DNSPARSER_pack (&packet, + UINT16_MAX, + &rh->dns_raw_packet, + &packet_size)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC_DNS-%llu: Creating raw dns packet!\n", + rh->id); + GNUNET_NETWORK_socket_close (rh->dns_sock); + rh->proc(rh->proc_cls, rh, 0, NULL); + return; + } + + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC_DNS-%llu: NOT IMPLEMENTED!\n", + rh->id); + GNUNET_free (rh->dns_raw_packet); + GNUNET_NETWORK_socket_close (rh->dns_sock); + rh->proc(rh->proc_cls, rh, 0, NULL); +} + + /** * The final phase of resoution. * We found a VPN RR and want to request an IPv4/6 address @@ -2141,7 +2264,7 @@ handle_delegation_ns(void* cls, struct ResolverHandle *rh, if (strcmp(rh->name, "") == 0) { - if ((rlh->record_type == GNUNET_GNS_RECORD_PKEY)) + if (rlh->record_type == GNUNET_GNS_RECORD_PKEY) { GNUNET_assert(rd_count == 1); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, @@ -2158,6 +2281,15 @@ handle_delegation_ns(void* cls, struct ResolverHandle *rh, if (rh->status & RSL_DELEGATE_VPN) { + if (rlh->record_type == GNUNET_GNS_RECORD_VPN) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Resolved queried VPNRR in NS.\n", + rh->id); + finish_lookup(rh, rlh, rd_count, rd); + free_resolver_handle(rh); + return; + } GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: VPN delegation starting.\n", rh->id); @@ -2165,6 +2297,24 @@ handle_delegation_ns(void* cls, struct ResolverHandle *rh, rh->proc = &handle_record_vpn; resolve_record_vpn (rh, rd_count, rd); } + else if (rh->status & RSL_DELEGATE_NS) + { + if (rlh->record_type == GNUNET_GNS_RECORD_TYPE_NS) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Resolved queried NSRR in NS.\n", + rh->id); + finish_lookup(rh, rlh, rd_count, rd); + free_resolver_handle(rh); + return; + } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: VPN delegation starting.\n", + rh->id); + GNUNET_assert (NULL != rd); + rh->proc = &handle_record_ns; + resolve_record_dns (rh, rd_count, rd); + } else { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, @@ -2342,9 +2492,22 @@ process_delegation_result_ns(void* cls, "GNS_PHASE_DELEGATE_NS-%llu: VPNRR found.\n", rh->id); rh->status |= RSL_DELEGATE_VPN; - rh->proc(rh->proc_cls, rh, rd_count, rd); + rh->proc (rh->proc_cls, rh, rd_count, rd); return; } + + /** + * Redirect via NS + * FIXME make optional + */ + if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_NS) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: NS found.\n", + rh->id); + rh->status |= RSL_DELEGATE_NS; + rh->proc (rh->proc_cls, rh, rd_count, rd); + } if (rd[i].record_type != GNUNET_GNS_RECORD_PKEY) continue; diff --git a/src/gns/gnunet-service-gns_resolver.h b/src/gns/gnunet-service-gns_resolver.h index 8387e1166..a0ac2cb0b 100644 --- a/src/gns/gnunet-service-gns_resolver.h +++ b/src/gns/gnunet-service-gns_resolver.h @@ -88,13 +88,16 @@ typedef void (*ResolutionResultProcessor) (void *cls, * RSL_RECORD_EXISTS: the name to lookup exists * RSL_RECORD_EXPIRED: the name in the record expired * RSL_TIMED_OUT: resolution timed out + * RSL_DELEGATE_VPN: Found VPN delegation + * RSL_DELEGATE_NS: Found NS delegation */ enum ResolutionStatus { RSL_RECORD_EXISTS = 1, RSL_RECORD_EXPIRED = 2, RSL_TIMED_OUT = 4, - RSL_DELEGATE_VPN = 8 + RSL_DELEGATE_VPN = 8, + RSL_DELEGATE_NS = 16 }; /** @@ -133,6 +136,15 @@ struct ResolverHandle /* a handle to a vpn request */ struct GNUNET_VPN_RedirectionRequest *vpn_handle; + /* a socket for a dns request */ + struct GNUNET_NETWORK_Handle *dns_sock; + + /* the address of the DNS server FIXME not needed? */ + struct in_addr dns_ip; + + /* pointer to raw dns query payload FIXME needs to be freed/NULL */ + char *dns_raw_packet; + /* timeout task for the lookup */ GNUNET_SCHEDULER_TaskIdentifier timeout_task; -- cgit v1.2.3