/** * Create a flat file with a large number of key pairs for testing. */ static void create_keys (const char *fn) { FILE *f; struct GNUNET_CRYPTO_RsaPrivateKey *pk; struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *enc; if (NULL == (f = fopen (fn, "w+"))) { fprintf (stderr, _("Failed to open `%s': %s\n"), fn, STRERROR (errno)); return; } fprintf (stderr, _("Generating %u keys, please wait"), make_keys); while (0 < make_keys--) { fprintf (stderr, "."); if (NULL == (pk = rsa_key_create ())) { GNUNET_break (0); break; } enc = GNUNET_CRYPTO_rsa_encode_key (pk); if (GNUNET_TESTING_HOSTKEYFILESIZE != htons (enc->len)) { /* sometimes we get a different key length because 'd' or 'u' start with leading bits; skip those... */ GNUNET_CRYPTO_rsa_key_free (pk); GNUNET_free (enc); make_keys++; continue; } if (htons (enc->len) != fwrite (enc, 1, htons (enc->len), f)) { fprintf (stderr, _("\nFailed to write to `%s': %s\n"), fn, STRERROR (errno)); GNUNET_CRYPTO_rsa_key_free (pk); GNUNET_free (enc); break; } GNUNET_CRYPTO_rsa_key_free (pk); GNUNET_free (enc); } if (0 == make_keys) fprintf (stderr, _("Finished!\n")); fclose (f); }
/** * Explicitly remove some content from the database. The * "cont"inuation will be called with status "GNUNET_OK" if content * was removed, "GNUNET_NO" if no matching entry was found and * "GNUNET_SYSERR" on all other types of errors. * This API is used by the authority of a zone. * * @param h handle to the namestore * @param pkey private key of the zone * @param name name that is being mapped (at most 255 characters long) * @param rd record data, remove specific record, NULL to remove the name and all records * @param cont continuation to call when done * @param cont_cls closure for cont * @return handle to abort the request */ struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_RsaPrivateKey *pkey, const char *name, const struct GNUNET_NAMESTORE_RecordData *rd, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls) { struct GNUNET_NAMESTORE_QueueEntry *qe; struct PendingMessage *pe; char *pkey_tmp; char *rd_tmp; char *name_tmp; size_t rd_ser_len = 0; size_t msg_size = 0; size_t name_len = 0; size_t key_len = 0; uint32_t rid = 0; uint16_t rd_count = 1; GNUNET_assert (NULL != h); rid = get_op_id(h); qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); qe->nsh = h; qe->cont = cont; qe->cont_cls = cont_cls; qe->op_id = rid; GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe); /* set msg_size*/ struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * pkey_enc = GNUNET_CRYPTO_rsa_encode_key (pkey); GNUNET_assert (pkey_enc != NULL); key_len = ntohs (pkey_enc->len); if (NULL == rd) rd_count = 0; else rd_count = 1; rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); char rd_ser[rd_ser_len]; GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser); name_len = strlen (name) + 1; struct RecordRemoveMessage * msg; msg_size = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len; /* create msg here */ pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); pe->size = msg_size; pe->is_init = GNUNET_NO; msg = (struct RecordRemoveMessage *) &pe[1]; pkey_tmp = (char *) &msg[1]; name_tmp = &pkey_tmp[key_len]; rd_tmp = &name_tmp[name_len]; msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE); msg->gns_header.header.size = htons (msg_size); msg->gns_header.r_id = htonl (rid); msg->name_len = htons (name_len); msg->rd_len = htons (rd_ser_len); msg->rd_count = htons (rd_count); msg->pkey_len = htons (key_len); memcpy (pkey_tmp, pkey_enc, key_len); memcpy (name_tmp, name, name_len); memcpy (rd_tmp, rd_ser, rd_ser_len); GNUNET_free (pkey_enc); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_REMOVE", name, msg_size); GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); do_transmit(h); return qe; }
/** * Perform an asynchronous Lookup operation on the GNS. * * @param handle handle to the GNS service * @param name the name to look up * @param zone the zone to start the resolution in * @param type the record type to look up * @param only_cached GNUNET_YES to only check locally not DHT for performance * @param shorten_key the private key of the shorten zone (can be NULL) * @param proc processor to call on result * @param proc_cls closure for processor * @return handle to the get request */ struct GNUNET_GNS_LookupRequest* GNUNET_GNS_lookup_zone (struct GNUNET_GNS_Handle *handle, const char *name, struct GNUNET_CRYPTO_ShortHashCode *zone, enum GNUNET_GNS_RecordType type, int only_cached, struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key, GNUNET_GNS_LookupResultProcessor proc, void *proc_cls) { /* IPC to shorten gns names, return shorten_handle */ struct GNUNET_GNS_ClientLookupMessage *lookup_msg; struct GNUNET_GNS_LookupRequest *lr; size_t msize; struct PendingMessage *pending; struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pkey_enc; size_t key_len; char* pkey_tmp; if (NULL == name) { GNUNET_break (0); return NULL; } if (NULL != shorten_key) { pkey_enc = GNUNET_CRYPTO_rsa_encode_key (shorten_key); GNUNET_assert (pkey_enc != NULL); key_len = ntohs (pkey_enc->len); } else { pkey_enc = NULL; key_len = 0; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to lookup `%s' in GNS\n", name); msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) + key_len + strlen (name) + 1; if (msize > UINT16_MAX) { GNUNET_break (0); GNUNET_free (pkey_enc); return NULL; } lr = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupRequest) + sizeof (struct PendingMessage) + msize); lr->gns_handle = handle; lr->lookup_proc = proc; lr->proc_cls = proc_cls; lr->r_id = handle->r_id_gen++; pending = (struct PendingMessage *)&lr[1]; pending->size = msize; pending->r_id = lr->r_id; GNUNET_CONTAINER_DLL_insert_tail (handle->lookup_head, handle->lookup_tail, lr); lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1]; lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP); lookup_msg->header.size = htons (msize); lookup_msg->id = htonl (lr->r_id); lookup_msg->only_cached = htonl (only_cached); if (NULL != zone) { lookup_msg->use_default_zone = htonl (GNUNET_NO); memcpy (&lookup_msg->zone, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode)); } else { lookup_msg->use_default_zone = htonl (GNUNET_YES); memset (&lookup_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode)); } lookup_msg->type = htonl (type); pkey_tmp = (char *) &lookup_msg[1]; if (pkey_enc != NULL) { lookup_msg->have_key = htonl (GNUNET_YES); memcpy (pkey_tmp, pkey_enc, key_len); } else lookup_msg->have_key = htonl (GNUNET_NO); GNUNET_free_non_null (pkey_enc); memcpy (&pkey_tmp[key_len], name, strlen (name) + 1); GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail, pending); process_pending_messages (handle); return lr; }