/** * The DNS request handler. Called for every incoming DNS request. * * @param cls closure, unused * @param rh request handle to user for reply * @param request_length number of bytes in @a request * @param request UDP payload of the DNS request */ static void handle_dns_request (void *cls, struct GNUNET_DNS_RequestHandle *rh, size_t request_length, const char *request) { struct GNUNET_DNSPARSER_Packet *p; struct InterceptLookupHandle *ilh; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hijacked a DNS request. Processing.\n"); if (NULL == (p = GNUNET_DNSPARSER_parse (request, request_length))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Received malformed DNS packet, leaving it untouched.\n"); GNUNET_DNS_request_forward (rh); GNUNET_DNSPARSER_free_packet (p); return; } /* Check TLD and decide if we or legacy dns is responsible */ if (1 != p->num_queries) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not exactly one query in DNS packet. Forwarding untouched.\n"); GNUNET_DNS_request_forward (rh); GNUNET_DNSPARSER_free_packet(p); return; } /* Check for GNS TLDs. */ if ( (GNUNET_YES == is_gnu_tld (p->queries[0].name)) || (GNUNET_YES == is_zkey_tld (p->queries[0].name)) || (0 == strcmp (p->queries[0].name, GNUNET_GNS_TLD)) ) { /* Start resolution in GNS */ ilh = GNUNET_new (struct InterceptLookupHandle); GNUNET_CONTAINER_DLL_insert (ilh_head, ilh_tail, ilh); ilh->packet = p; ilh->request_handle = rh; ilh->lookup = GNS_resolver_lookup (&zone, p->queries[0].type, p->queries[0].name, NULL /* FIXME: enable shorten for DNS intercepts? */, GNUNET_NO, &reply_to_dns, ilh); return; }
/** * Handle a shorten message from the api * * @param cls the closure * @param client the client * @param message the message */ static void handle_shorten(void *cls, struct GNUNET_SERVER_Client * client, const struct GNUNET_MessageHeader * message) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "SHORTEN"); size_t msg_size = 0; struct ClientShortenHandle *csh; char name[MAX_DNS_NAME_LENGTH]; char* nameptr = name; struct GNUNET_CRYPTO_ShortHashCode zone; struct GNUNET_CRYPTO_RsaPrivateKey *key; if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientShortenMessage)) { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } struct GNUNET_GNS_ClientShortenMessage *sh_msg = (struct GNUNET_GNS_ClientShortenMessage *) message; msg_size = ntohs(message->size); if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } csh = GNUNET_malloc(sizeof(struct ClientShortenHandle)); csh->client = client; csh->unique_id = sh_msg->id; csh->zone_key = NULL; GNUNET_STRINGS_utf8_tolower((char*)&sh_msg[1], &nameptr); if (strlen (name) < strlen(GNUNET_GNS_TLD)) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "SHORTEN: %s is too short", name); csh->name = NULL; send_shorten_response(csh, name); return; } if (strlen (name) > MAX_DNS_NAME_LENGTH) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "SHORTEN: %s is too long", name); csh->name = NULL; send_shorten_response(csh, name); return; } if (!is_gnunet_tld(name) && !is_zkey_tld(name)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s is not our domain. Returning\n", name); csh->name = NULL; send_shorten_response(csh, name); return; } GNUNET_SERVER_notification_context_add (nc, client); if (1 == ntohl(sh_msg->use_default_zone)) zone = zone_hash; //Default zone else zone = sh_msg->zone; /* Start shortening */ if (GNUNET_YES == auto_import_pkey) { if (1 == ntohl(sh_msg->use_default_zone)) key = zone_key; else { key = lookup_private_key(&sh_msg->zone); csh->zone_key = key; } gns_resolver_shorten_name(zone, zone, name, key, &send_shorten_response, csh); } else gns_resolver_shorten_name(zone, zone, name, NULL, &send_shorten_response, csh); }