Example #1
0
void 
do_old_routing_table_updates(void)
{
	if ( nlsr->debugging )
		printf("do_old_routing_table_updates called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"do_old_routing_table_updates called\n");
	
	int i, rt_element;
	int mapping_no;	

	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = ⅇ
    	
    	hashtb_start(nlsr->routing_table, e);
	rt_element=hashtb_n(nlsr->routing_table);

	for(i=0;i<rt_element;i++)
	{
		rte=e->data;
		mapping_no=get_mapping_no(rte->dest_router);
		if ( mapping_no == NO_MAPPING_NUM)
		{		
			delete_orig_router_from_npt(rte->dest_router);
			/*
			char *router=(char *)malloc(strlen(rte->dest_router)+1);
			memset(router,0,strlen(rte->dest_router)+1);
			memcpy(router,rte->dest_router,strlen(rte->dest_router)+1);
			nlsr->event = ccn_schedule_event(nlsr->sched, 1, &delete_empty_rte, (void *)router , 0);
			*/
			destroy_routing_table_entry_comp(rte);
			hashtb_delete(e);
			i++;
		}
		else
		{
			hashtb_next(e);
		}		
	}

	hashtb_end(e);	
}
Example #2
0
/**
 *  Remove internal representation of a content object
 */
PUBLIC void
r_store_forget_content(struct ccnr_handle *h, struct content_entry **pentry)
{
    unsigned i;
    struct content_entry *entry = *pentry;
    
    if (entry == NULL)
        return;
    *pentry = NULL;
    if ((entry->flags & CCN_CONTENT_ENTRY_STALE) != 0)
        h->n_stale--;
    if (CCNSHOULDLOG(h, LM_4, CCNL_FINER))
        ccnr_debug_content(h, __LINE__, "remove", NULL, entry);
    /* Remove the cookie reference */
    i = entry->cookie & (h->cookie_limit - 1);
    if (h->content_by_cookie[i] == entry)
        h->content_by_cookie[i] = NULL;
    entry->cookie = 0;
    /* Remove the accession reference */
    if (entry->accession != CCNR_NULL_ACCESSION) {
        struct hashtb_enumerator ee;
        struct hashtb_enumerator *e = &ee;
        hashtb_start(h->content_by_accession_tab, e);
        if (hashtb_seek(e, &entry->accession, sizeof(entry->accession), 0) ==
            HT_NEW_ENTRY) {
            ccnr_msg(h, "orphaned content %llu",
                     (unsigned long long)(entry->accession));
            hashtb_delete(e);
            hashtb_end(e);
            return;
        }
        hashtb_delete(e);
        hashtb_end(e);
        entry->accession = CCNR_NULL_ACCESSION;
    }
    /* Clean up allocated subfields */
    ccn_charbuf_destroy(&entry->flatname);
    if (entry->cob != NULL) {
        h->cob_count--;
        ccn_charbuf_destroy(&entry->cob);
    }
    free(entry);
}
Example #3
0
static void add_ccn_ping_entry(struct ccn_ping_client *client,
        struct ccn_charbuf *name, long int number)
{
    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;
    struct ccn_ping_entry *entry;
    int res;

    hashtb_start(client->ccn_ping_table, e);

    res = hashtb_seek(e, name->buf + 1, name->length - 2, 0);
    assert(res == HT_NEW_ENTRY);

    entry = e->data;
    entry->number = number;
    gettimeofday(&entry->send_time, NULL);

    hashtb_end(e);
}
Example #4
0
static struct ccn_ping_entry *get_ccn_ping_entry(struct ccn_ping_client *client,
        const unsigned char *interest_msg, const struct ccn_parsed_interest *pi)
{
    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;
    struct ccn_ping_entry *entry;
    int res;

    hashtb_start(client->ccn_ping_table, e);

    res = hashtb_seek(e, interest_msg + pi->offset[CCN_PI_B_Component0],
            pi->offset[CCN_PI_E_LastPrefixComponent] - pi->offset[CCN_PI_B_Component0], 0);

    assert(res == HT_OLD_ENTRY);

    entry = e->data;
    hashtb_end(e);

    return entry;
}
Example #5
0
void
destroy_rev_map(void)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->rev_map, e);
	map_element=hashtb_n(nlsr->rev_map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		free(me->router);
		hashtb_next(e);		
	}

	hashtb_end(e);
}
Example #6
0
void
destroy_routing_table(void)
{
	int i, rt_element;
	struct hashtb_enumerator ee;
	struct hashtb_enumerator *e = &ee;

	struct routing_table_entry *rte;
	hashtb_start(nlsr->routing_table, e);
	rt_element=hashtb_n(nlsr->routing_table);
	for(i=0;i<rt_element;i++)
	{
		rte=e->data;
		free(rte->dest_router);
		hashtb_destroy(&rte->face_list);	
		hashtb_next(e);		
	}	
	hashtb_end(e);
	hashtb_destroy(&nlsr->routing_table);

}
Example #7
0
NdnlpPkt LMD_read(LMD self, SockAddr srcaddr) {
	struct hashtb_enumerator htee; struct hashtb_enumerator* hte = &htee;
	int htres; LMDRec rec = NULL;
	struct ccn_charbuf* hashkey = SockAddr_hashkey(srcaddr);

	hashtb_start(self->demux, hte);
	htres = hashtb_seek(hte, hashkey->buf, hashkey->length, 0);
	if (htres == HT_OLD_ENTRY) {
		rec = *((LMDRec*)hte->data);
	} else if (htres == HT_NEW_ENTRY) {
		hashtb_delete(hte);
	}
	hashtb_end(hte);

	if (rec == NULL) return NULL;
	NdnlpPkt pkt = LMDRec_read(rec, srcaddr);
	if (pkt == NULL) {
		LMD_demux(self);
		pkt = LMDRec_read(rec, srcaddr);
	}
	return pkt;
}
Example #8
0
void
assign_mapping_number(void)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->map, e);
	map_element=hashtb_n(nlsr->map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		me->mapping=i;
		add_rev_map_entry(i,me->router);
		hashtb_next(e);		
	}

	hashtb_end(e);
}
Example #9
0
void
print_all_path_from_source(long int *parent,long int source)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->map, e);
	map_element=hashtb_n(nlsr->map);

	if ( source != NO_MAPPING_NUM)
	{
		for(i=0;i<map_element;i++)
		{
			me=e->data;
			if(me->mapping != source)
			{
				
				if ( nlsr->debugging )
				{
					print_path(parent,(long int)me->mapping);
					printf("\n");
				}
				if ( nlsr->detailed_logging )
				{
					print_path(parent,(long int)me->mapping);
					writeLogg(__FILE__,__FUNCTION__,__LINE__,"\n");
				}
				
			}
			hashtb_next(e);		
		}
	}
	hashtb_end(e);

}
Example #10
0
DataPkt SentPkts_getRetransmit(SentPkts self, DateTime sendBefore) {
	SentPktRec rec = self->rhead;
	if (rec == NULL || rec->sendTime >= sendBefore) return NULL;

	SentPkts_rDetach(self, rec);
	DataPkt pkt = rec->pkt;
	if (--rec->retryCount <= 0) {
		struct hashtb_enumerator htee; struct hashtb_enumerator* hte = &htee;
		SeqNum sequence = DataPkt_getSequence(pkt);
		hashtb_start(self->index, hte);
		hashtb_seek(hte, &sequence, sizeof(SeqNum), 0);
		hashtb_delete(hte);
		hashtb_end(hte);

		SentPkts_sDetach(self, rec);
		SentPktRec_dtor(rec, true);
	} else {
		rec->sendTime = DateTime_now();
		SentPkts_rInsert(self, rec);
		pkt = NdnlpPkt_clone(pkt);
	}
	return pkt;
}
Example #11
0
void 
update_nlsa_id_for_name_in_npl(struct name_prefix *np, long int nlsa_id)
{
	struct name_prefix_list_entry *npe;
	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res;

   	hashtb_start(nlsr->npl, e);
    	res = hashtb_seek(e, np->name, np->length, 0);

	if(res == HT_OLD_ENTRY)
	{   
		npe=e->data;
		npe->name_lsa_id=nlsa_id;
	}
	else
	{
		hashtb_delete(e);	
	}
    	
	hashtb_end(e);
}
Example #12
0
int 
does_face_exist_for_router(char *dest_router, int face_id)
{
	if (nlsr->debugging)
	{
		printf("does_face_exist_for_router called\n");
		printf("Dest Router: %s and Face id: %d \n",dest_router, face_id);
	}

	int ret=0;

	int res;
	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->routing_table, e);
	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);

	if( res == HT_OLD_ENTRY )
	{
		rte=e->data;
		unsigned *v;
		v = hashtb_lookup(rte->face_list, &face_id, sizeof(face_id));
		if (v != NULL)
			ret = 1;
	}
	else
	{
		hashtb_delete(e);
	} 
	
	hashtb_end(e);

	return ret;
}
Example #13
0
void
print_rev_map(void)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->map, e);
	map_element=hashtb_n(nlsr->map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		if ( nlsr->debugging )
			printf("Mapping Number: %d Router: %s  \n",me->mapping,me->router);
		if ( nlsr->detailed_logging )
			writeLogg(__FILE__,__FUNCTION__,__LINE__,"Mapping Number: %d Router: %s  \n",me->mapping,me->router);
		hashtb_next(e);		
	}

	hashtb_end(e);
}
Example #14
0
int 
get_mapping_no(char *router)
{
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res;
	int ret;

	int n = hashtb_n(nlsr->map);

	if ( n < 1)
	{
		return NO_MAPPING_NUM;
	}

   	hashtb_start(nlsr->map, e);
    	res = hashtb_seek(e, router, strlen(router), 0);

	if( res == HT_OLD_ENTRY )
	{
		me=e->data;
		ret=me->mapping;
	}
	else if(res == HT_NEW_ENTRY)
	{
		hashtb_delete(e);
		ret=NO_MAPPING_NUM;
	}

	hashtb_end(e);	

	return ret;

}
Example #15
0
int get_default_keys(struct ccn* h, struct ccn_signing_params* p, struct ccn_keystore** keystore, struct ccn_pkey** public_key,
		unsigned char** public_key_digest, size_t* public_key_digest_length, struct ccn_pkey** private_key) {
	// These structures are supposed to be internal to the libs but
	// there doesn't appear to be an API to deal with the keystores -
	// We could use ccn_keystore_init but seem to have to know just
	// as many implementation details. See ccnsendchunks.c
	struct hashtb_enumerator ee;
	struct hashtb_enumerator *e = &ee;
	int res = 0;
	hashtb_start(h->keystores, e);
		if (hashtb_seek(e, p->pubid, sizeof(p->pubid), 0) != HT_OLD_ENTRY) {
			fprintf(stderr,"No default keystore?\n");
			res = -1;
		} else {
			struct ccn_keystore **pk = e->data;
			(*keystore) = *pk;
			(*public_key) = (struct ccn_pkey*) ccn_keystore_public_key(*keystore);
			(*private_key) = (struct ccn_pkey*) ccn_keystore_private_key(*keystore);
			(*public_key_digest) = (unsigned char*) ccn_keystore_public_key_digest(*keystore);
			(*public_key_digest_length) = ccn_keystore_public_key_digest_length(*keystore);
		}
	hashtb_end(e);
	return(res);
}
Example #16
0
void 
add_name_to_npl(struct name_prefix *np)
{
	struct name_prefix_list_entry *npe;
	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res;

   	hashtb_start(nlsr->npl, e);
    	res = hashtb_seek(e, np->name, np->length, 0);

	if(res == HT_NEW_ENTRY)
	{   
		npe=e->data;
		npe->np=(struct name_prefix *)calloc(1,sizeof(struct name_prefix ));
		npe->np->length=np->length;
		npe->np->name=(char *)calloc(np->length,sizeof(char));
		memcpy(npe->np->name,np->name,np->length);
		npe->name_lsa_id=0;
	}
    	
	hashtb_end(e);

}
Example #17
0
void
destroy_npl(void)
{
	int i, npl_element;
	struct name_prefix_list_entry *npe;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->npl, e);
	npl_element=hashtb_n(nlsr->npl);

	for(i=0;i<npl_element;i++)
	{
		npe=e->data;
		destroy_npl_entry_component(npe);
		hashtb_next(e);		
	}

	hashtb_end(e);

	if ( nlsr->npl)
		hashtb_destroy(&nlsr->npl);
}
Example #18
0
enum ccn_upcall_res
andana_client_encap_interest(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    int res;
    enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR;

    struct andana_client *client = selfp->data;
    struct ccn_proxy *proxy = client->proxy;

    size_t orig_name_ncomps;
    struct ccn_charbuf *orig_name = NULL;
    struct ccn_indexbuf *orig_name_comps = NULL;
    struct ccn_charbuf *new_name = NULL;
    struct ccn_indexbuf *new_name_comps = NULL;


    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;

    switch (kind) {
    case CCN_UPCALL_INTEREST:
        DEBUG_PRINT("Received Interest\n");
        break;
    case CCN_UPCALL_FINAL:
        DEBUG_PRINT("Encap: callback final\n");
        return(CCN_UPCALL_RESULT_OK);
    default:
        return(CCN_UPCALL_RESULT_ERR);
    }

    /* Extract Name from Interest */

    orig_name_ncomps = ccn_util_extract_name(info->interest_ccnb,
                                             info->interest_comps,
                                             &orig_name,
                                             &orig_name_comps);


    /*
     * Need to check this Interest doesn't match what we send out.
     * Otherwise, we'll just keep encapsulating the same thing over and over.
     */

    int num_matching_comps =
        ccn_util_name_match(client->proxy->prefix,
                            client->proxy->prefix_comps,
                            orig_name,
                            orig_name_comps);

    if (num_matching_comps == client->proxy->prefix_ncomps) {
        DEBUG_PRINT("Interest matches %d of %d components, ignoring interest\n", num_matching_comps, (int)client->proxy->prefix_ncomps);
#ifdef PROXYDEBUG
	ccn_util_println_pc_fmt(orig_name->buf, orig_name->length);
	DEBUG_PRINT("Name has %lu comps\n", orig_name_comps->n-1);
	ccn_util_println_pc_fmt(client->proxy->prefix->buf, client->proxy->prefix->length);
	DEBUG_PRINT("Name has %lu comps\n", client->proxy->prefix_comps->n-1);
#endif
        goto MatchBail;
    } else {
        DEBUG_PRINT("Interest matches %d of %d components\n", num_matching_comps, (int)client->proxy->prefix_ncomps);
    }


    /* Create a new name encapsulated & encrypted name */

    //	new_name_comps = ccn_indexbuf_create();
    ccn_name_append(orig_name, info->interest_ccnb, info->pi->offset[CCN_PI_E]);
    ccn_indexbuf_destroy(&orig_name_comps);

    struct ccn_buf_decoder decoder;
    struct ccn_buf_decoder *d = &decoder;
    ccn_buf_decoder_start(d, orig_name->buf, orig_name->length);

    orig_name_comps = ccn_indexbuf_create();
    res = ccn_parse_Name(d, orig_name_comps);

    if (res <= 0) {
        DEBUG_PRINT("%d %s error parsing encapsulated name\n",
                    __LINE__, __func__);
        goto MatchBail;
    }

    res = andana_path_encrypt_encap(client->path,
                                    orig_name,
                                    orig_name_comps,
                                    &new_name,
                                    &new_name_comps);

    if (res <= 0) {
        DEBUG_PRINT("%d %s error encapsulating and encrypting name\n",
                    __LINE__, __func__);
        goto EncryptBail;
    }

    /* Remember the new name so we know how to decrypt & decapsulate it later */

    hashtb_start(client->name_to_path, e);
    res = hashtb_seek(e, new_name->buf, new_name->length, 0);

    if (res == HT_NEW_ENTRY) {

    } else if (res == HT_OLD_ENTRY) {
        DEBUG_PRINT("Interest recording found old entry\n");
        upcall_res = CCN_UPCALL_RESULT_OK;
        goto LookupBail;
    } else {
        DEBUG_PRINT("Error in Interest insertion\n");
        goto LookupBail;
    }

    /* Send out new Interest */

#ifdef PROXYDEBUG
    struct ccn_charbuf *c = ccn_charbuf_create();
    ccn_uri_append(c, new_name->buf, new_name->length, 1);
    DEBUG_PRINT("name = %s\n", ccn_charbuf_as_string(c));
    ccn_charbuf_destroy(&c);
#endif
    res = ccn_express_interest(proxy->handle, new_name, proxy->content_handler, NULL);

    if(res != 0) {
        DEBUG_PRINT("express interest res = %d\n",res);
    } else {
        struct andana_path **path_ptr = e->data;
        *path_ptr = andana_path_copy(client->path);

        upcall_res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
    }



LookupBail:
    hashtb_end(e);

EncryptBail:

    ccn_charbuf_destroy(&new_name);
    ccn_indexbuf_destroy(&new_name_comps);

MatchBail:
    ccn_charbuf_destroy(&orig_name);
    ccn_indexbuf_destroy(&orig_name_comps);

    return(upcall_res);
}
Example #19
0
enum ccn_upcall_res
andana_server_decap_interest(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR;
    struct andana_server *server = selfp->data;

    struct ccn_proxy *proxy = server->proxy;

    struct ccn_charbuf *new_interest = NULL;
    struct ccn_charbuf *new_name = NULL;

    struct ccn_charbuf *orig_name = NULL;
    struct ccn_indexbuf *orig_name_indexbuf = NULL;
    int orig_name_ncomps;

    char is_session = 0;

    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;

    int res;


    DEBUG_PRINT("IN %d %s\n", __LINE__, __func__);

    switch (kind) {
    case CCN_UPCALL_INTEREST:
        DEBUG_PRINT("%d %s received interest\n", __LINE__, __func__);
        break;
    case CCN_UPCALL_INTEREST_TIMED_OUT:
        DEBUG_PRINT("%d %s received interest time out\n", __LINE__, __func__);
        /* Fall through */
    default:
        DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);
        return(CCN_UPCALL_RESULT_OK);
    }


    /* Extract Name from Interest */

    orig_name_ncomps = ccn_util_extract_name(info->interest_ccnb,
                                             info->interest_comps,
                                             &orig_name,
                                             &orig_name_indexbuf);

#ifdef PROXYDEBUG
    ccn_util_print_pc_fmt(orig_name->buf, orig_name->length);
    DEBUG_PRINT("\n");

    DEBUG_PRINT("Name has %lu comps\n", orig_name_indexbuf->n-1);
#endif

    /*Decapsulate & decrypt Interest. */


    const unsigned char *const_encrypted = NULL;
    unsigned char *encrypted = NULL;
    size_t encrypted_size;

    if (orig_name_ncomps >= 2) {
        const unsigned char *session_check = NULL;
        size_t session_check_size;

        res = ccn_name_comp_get(orig_name->buf,
				orig_name_indexbuf,
				(unsigned int)server->SESSION_FLAG,
				&session_check,
				&session_check_size);

        if (res < 0) {
            DEBUG_PRINT("%d %s Error extracting session check component %lu\n", __LINE__, __func__, server->SESSION_FLAG);
            goto SessionFail;
        } else {
            DEBUG_PRINT("%d %s Extracted component %lu\n", __LINE__, __func__,server->SESSION_FLAG);
        }

        if (session_check_size == strlen("SESSION") &&
            memcmp(session_check, "SESSION", session_check_size) == 0) {

            DEBUG_PRINT("%d %s Session identified\n", __LINE__, __func__);
            is_session = 1;

        } else {
            DEBUG_PRINT("%d %s Not a session\n", __LINE__, __func__);
        }
    }



    /* Decrypt the name (contains a new name and an Interest template) */

    struct ccn_pkey *symkey = NULL;
    struct ccn_charbuf *decrypted = NULL;
    struct ccn_indexbuf *decrypted_comps = ccn_indexbuf_create();

    if (is_session) {

        res = ccn_name_comp_get(orig_name->buf,
				orig_name_indexbuf,
				(unsigned int)server->SESSION_ENC,
				&const_encrypted,
				&encrypted_size);

        if (res < 0) {
            DEBUG_PRINT("%d %s Error extracting encrypted session component %lu\n", __LINE__, __func__, server->SESSION_ENC);
            goto SessionParseFail;
        } else {
            DEBUG_PRINT("%d %s Extracted encrypted session component  %lu\n", __LINE__, __func__, server->SESSION_ENC);
        }

        encrypted = calloc(encrypted_size, sizeof(unsigned char));
        memcpy(encrypted, const_encrypted, encrypted_size);

        ccn_crypto_name_sym_decrypt(server->node_key,
                                    encrypted,
                                    encrypted_size,
                                    &symkey,
                                    &decrypted,
                                    &decrypted_comps);
    } else {

        ccn_name_comp_get(orig_name->buf, orig_name_indexbuf, (unsigned int)server->ENC, &const_encrypted, &encrypted_size);
        encrypted = calloc(encrypted_size, sizeof(unsigned char));
        memcpy(encrypted, const_encrypted, encrypted_size);

        ccn_crypto_name_asym_decrypt(server->privkey,
                                     encrypted,
                                     &symkey,
                                     &decrypted,
                                     &decrypted_comps);
    }

    size_t ncomps = decrypted_comps->n-1;
    const unsigned char *tmpl = NULL;
    size_t tmpl_size;

    res = ccn_name_comp_get(decrypted->buf, decrypted_comps, (unsigned int)ncomps - 1, &tmpl, &tmpl_size);

    if (res < 0) {
        DEBUG_PRINT("ABORT %d %s unable to retrieve component %d\n",
                    __LINE__, __func__, (int)ncomps);
        goto CompExtractFail;
    }

    /* Pull timestamp component (comp 0) */
    const unsigned char *ts_data = NULL;
    size_t ts_size;
    res = ccn_name_comp_get(decrypted->buf, decrypted_comps, 0, &ts_data, &ts_size);

    if (res < 0) {
        goto CompExtractFail;
    }

    struct timeval timestamp;
    ccn_util_extract_timestamp(ts_data, ts_size, &timestamp);

    struct timeval window = {.tv_sec = 1, .tv_usec = 600000};

    if (ccn_util_timestamp_window(&timestamp, &window) == 0) {
        /* Timestamp too far away, this may be a replay attack */
        DEBUG_PRINT("%d %s Timestamp too distant\n", __LINE__, __func__);
        goto TimestampFail;
    }

    new_name = ccn_charbuf_create();
    ccn_name_init(new_name);


    res = ccn_name_append_components(new_name,
                                     decrypted->buf,
                                     decrypted_comps->buf[1],
                                     decrypted_comps->buf[ncomps-1]);

    if (res < 0) {
        DEBUG_PRINT("ABORT %d %s unable to append components\n",
                    __LINE__, __func__);
        goto AppendCompFail;
    }


    /*Construct new Interest*/

    if (tmpl_size == 0) {
        /* Detected default template */
        DEBUG_PRINT("%d %s Using default Interest template\n", __LINE__, __func__);
        new_interest = NULL;
    } else {
        DEBUG_PRINT("%d %s Copying Interest template\n", __LINE__, __func__);
        new_interest = ccn_charbuf_create();
        ccn_charbuf_append(new_interest, tmpl, tmpl_size);
    }

    /*Map new name to that of the original Interest and the requested symkey */

    hashtb_start(server->cname_to_pair, e);
    res = hashtb_seek(e, new_name->buf, new_name->length, 0);

    if (res == HT_NEW_ENTRY) {
        struct andana_server_pair *p = andana_server_pair_init(orig_name, symkey);
        struct andana_server_pair **loc = e->data;
        *loc = p;
    } else if (res == HT_OLD_ENTRY) {
        DEBUG_PRINT("Interest recording found old entry\n");
        goto LookupFail;
    } else {
        DEBUG_PRINT("Error in Interest insertion\n");
        goto LookupFail;
    }





    DEBUG_PRINT("%d %s starting to write new interest\n", __LINE__, __func__);

    res = ccn_express_interest(proxy->handle, new_name, proxy->content_handler, new_interest);

    DEBUG_PRINT("%d %s done to writing new interest\n", __LINE__, __func__);

    if(res != 0) {
        DEBUG_PRINT("ABORT %d %s express interest res = %d\n", __LINE__, __func__, res);
        goto SendFail;
    }

    upcall_res = CCN_UPCALL_RESULT_OK;


SendFail:
LookupFail:

    if (upcall_res == CCN_UPCALL_RESULT_ERR) {
        hashtb_delete(e);
    }

    hashtb_end(e);

    if (new_interest != NULL) {
        ccn_charbuf_destroy(&new_interest);
    }

TimestampFail:
AppendCompFail:
    ccn_charbuf_destroy(&new_name);

CompExtractFail:
    ccn_charbuf_destroy(&decrypted);
    free(encrypted);
    ccn_crypto_symkey_destroy(&symkey);

SessionParseFail:
    ccn_indexbuf_destroy(&decrypted_comps);

SessionFail:
    ccn_charbuf_destroy(&orig_name);
    ccn_indexbuf_destroy(&orig_name_indexbuf);

    DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);

    return(upcall_res);
}

/**
 * Encapsulate and encrypt returning content objects. Encryption
 * uses the ephemeral symmetric key provided by the user in the original
 * interest (stored in a pair).
 *
 * This node will naturally sign the outgoing content object, thus providing
 * verifiability.
 */

enum ccn_upcall_res
andana_server_encap_content(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR;
    struct andana_server *server = selfp->data;
    struct ccn_proxy *proxy = server->proxy;

    struct ccn_charbuf *new_name = NULL;
    struct andana_server_pair **pair_ptr = NULL;
    struct ccn_charbuf *new_content = NULL;
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;

    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;

    int res;

    DEBUG_PRINT("IN %d %s\n",__LINE__, __func__);

    switch (kind) {
    case CCN_UPCALL_CONTENT:           /**< incoming verified content */
        DEBUG_PRINT("%d %s Incoming verified content\n",__LINE__, __func__);
        break;
    case CCN_UPCALL_CONTENT_UNVERIFIED:/**< content that has not been verified */
        DEBUG_PRINT("%d %s Incoming unverified content\n", __LINE__, __func__);
        break;
    case CCN_UPCALL_CONTENT_BAD:        /**< verification failed */
        DEBUG_PRINT("%d %s Incoming bad content (verification failure)\n", __LINE__, __func__);
        break;

    case CCN_UPCALL_INTEREST_TIMED_OUT:/**< interest timed out */
    {
        DEBUG_PRINT("OUT %d %s Interest timed out\n", __LINE__, __func__);

        const unsigned char *name = info->interest_ccnb + info->pi->offset[CCN_PI_B_Name];
        const size_t length =  info->pi->offset[CCN_PI_E_Name] - info->pi->offset[CCN_PI_B_Name];

        hashtb_start(server->cname_to_pair, e);
        hashtb_seek(e, name, length, 0);
        hashtb_delete(e);
        hashtb_end(e);

        return(CCN_UPCALL_RESULT_OK);
    }
    case CCN_UPCALL_FINAL:/**< handler is about to be deregistered */
        DEBUG_PRINT("OUT %d %s final upcall\n", __LINE__, __func__);
        return(CCN_UPCALL_RESULT_OK);

    case CCN_UPCALL_INTEREST:          /**< incoming interest */
    case CCN_UPCALL_CONSUMED_INTEREST: /**< incoming interest, someone has answered */
    default:
        DEBUG_PRINT("OUT %d %s upcall other kind = %d\n", __LINE__, __func__, kind);
        return(CCN_UPCALL_RESULT_ERR);
    }



    DEBUG_PRINT("%d %s Received content object\n", __LINE__, __func__);

    if (info->content_ccnb == NULL) {
        DEBUG_PRINT("OUT %d %s in content upcall, but no content, check kind: %d\n", __LINE__, __func__, kind);
        return(CCN_UPCALL_RESULT_OK);
    }

    /*Find name in Content Object*/

    new_name = ccn_charbuf_create();
    ccn_name_init(new_name);
    ccn_name_append_components(new_name, info->content_ccnb,
                               info->content_comps->buf[0], info->content_comps->buf[info->matched_comps]);

#ifdef PROXYDEBUG
    DEBUG_PRINT("name matches %d comps\n", info->matched_comps);
    ccn_util_print_pc_fmt(info->content_ccnb + info->pco->offset[CCN_PCO_B_Name],
                          info->pco->offset[CCN_PCO_E_Name] - info->pco->offset[CCN_PCO_B_Name]);
    DEBUG_PRINT("\n");
#endif

    pair_ptr = hashtb_lookup(server->cname_to_pair, new_name->buf, new_name->length);

    if(pair_ptr == NULL) {
        /* No match for name*/
#ifdef PROXYDEBUG
        DEBUG_PRINT("Unsolicited content object with name: ");
        ccn_util_print_pc_fmt(new_name->buf, new_name->length);
        DEBUG_PRINT("\n");
#endif
        goto LookupFail;
    }

    struct ccn_charbuf *orig_name = (*pair_ptr)->name;
    struct ccn_pkey *symkey = (*pair_ptr)->symkey;






    /*Created signed info for new content object*/
    unsigned char *encrypted_content = NULL;
    size_t encrypted_length;

    struct ccn_charbuf *content = ccn_charbuf_create();
    ccn_charbuf_append(content, info->content_ccnb, info->pco->offset[CCN_PCO_E]);

    ccn_crypto_content_encrypt(symkey, content->buf, content->length, &encrypted_content, &encrypted_length);

    new_content = ccn_charbuf_create();
    sp.type = CCN_CONTENT_DATA;

    res = ccn_sign_content(proxy->handle,
                           new_content,
                           orig_name,
                           &sp,
                           encrypted_content,
                           encrypted_length);


    if (ccn_util_validate_content_object(new_content->buf, new_content->length) != 0) {
        DEBUG_PRINT("ABORT %d %s Failed to validated signed content\n", __LINE__, __func__);
        abort();
        goto SignFail;
    } else {
        DEBUG_PRINT("OK %d %s signed content is valid\n", __LINE__, __func__);
    }


    if (res != 0) {
        DEBUG_PRINT("ABORT %d %s Failed to encode ContentObject (res == %d)\n", __LINE__, __func__, res);
        goto SignFail;
    }

    DEBUG_PRINT("%d %s starting content write\n", __LINE__, __func__);

    res = ccn_put(proxy->handle, new_content->buf, new_content->length);

    DEBUG_PRINT("%d %s done content write line\n", __LINE__, __func__);

    if (res < 0) {
        DEBUG_PRINT("ABORT %d %s ccn_put failed (res == %d)\n", __LINE__, __func__, res);
        goto SendFail;
    }

    DEBUG_PRINT("%d %s Reply sent\n", __LINE__, __func__);
    upcall_res = CCN_UPCALL_RESULT_OK;


SendFail:
    hashtb_start(server->cname_to_pair, e);
    hashtb_seek(e, new_name->buf, new_name->length, 0);
    hashtb_delete(e);
    hashtb_end(e);



SignFail:
    ccn_charbuf_destroy(&new_content);
    free(encrypted_content);
    ccn_charbuf_destroy(&content);

LookupFail:
    ccn_charbuf_destroy(&new_name);

    DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);

    return(upcall_res);
}


/**
 * Clean up and destroy anonymous server object. Expect
 * to be called once at program close.
 *
 * @param pointer to anonymous server to be destroyed
 * @returns 0 (always)
 */

int
andana_server_destroy(struct andana_server **server)
{
    struct andana_server *s = *server;

    free(s->proxy->int_handler);
    free(s->proxy->content_handler);
    ccn_proxy_destroy(&(s->proxy));
    ccn_crypto_pubkey_destroy(&(s->privkey));
    hashtb_destroy(&(s->cname_to_pair));
    free(s);

    return(0);
}
Example #20
0
void 
print_routing_table(void)
{
	if ( nlsr->debugging )
		printf("print_routing_table called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"print_routing_table called\n");
	int i,j, rt_element,face_list_element;
	
	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->routing_table, e);
	rt_element=hashtb_n(nlsr->routing_table);

	for(i=0;i<rt_element;i++)
	{
		if ( nlsr->debugging )
			printf("----------Routing Table Entry %d------------------\n",i+1);
		if ( nlsr->detailed_logging )
			writeLogg(__FILE__,__FUNCTION__,__LINE__,"----------Routing Table Entry %d------------------\n",i+1);
		
		rte=e->data;

		if ( nlsr->debugging )
			printf(" Destination Router: %s \n",rte->dest_router);
		if ( nlsr->detailed_logging )
			writeLogg(__FILE__,__FUNCTION__,__LINE__," Destination Router: %s \n",rte->dest_router);

		
		//rte->next_hop_face == NO_NEXT_HOP ? printf(" Next Hop Face: NO_NEXT_HOP \n") : printf(" Next Hop Face: %d \n", rte->next_hop_face);

		struct face_list_entry *fle;

		struct hashtb_enumerator eef;
    		struct hashtb_enumerator *ef = &eef;
    	
    		hashtb_start(rte->face_list, ef);
		face_list_element=hashtb_n(rte->face_list);
		if ( face_list_element <= 0 )
		{
			if ( nlsr->debugging )
				printf(" 	Face: No Face \n");
			if ( nlsr->detailed_logging )
				writeLogg(__FILE__,__FUNCTION__,__LINE__," 	Face: No Face \n");
		}
		else
		{
			for(j=0;j<face_list_element;j++)
			{
				fle=ef->data;
				if ( nlsr->debugging )
					printf(" 	Face: %d Route_Cost: %f \n",fle->next_hop_face,fle->route_cost);
				if ( nlsr->detailed_logging )
					writeLogg(__FILE__,__FUNCTION__,__LINE__," 	Face: %d Route_Cost: %d \n",fle->next_hop_face,fle->route_cost);
				hashtb_next(ef);	
			}
		}
		hashtb_end(ef);

		hashtb_next(e);		
	}

	hashtb_end(e);

	if ( nlsr->debugging )
		printf("\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"\n");
}
Example #21
0
int
route_calculate(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags)
{

	if(flags == CCN_SCHEDULE_CANCEL)
	{
 	 	return -1;
	}

	nlsr_lock();

	if ( nlsr->debugging )
		printf("route_calculate called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"route_calculate called\n");

	if( ! nlsr->is_build_adj_lsa_sheduled )
	{
		/* Calculate Route here */
		print_routing_table();
		print_npt();		

		//struct hashtb_param param_me = {0};
		nlsr->map = hashtb_create(sizeof(struct map_entry), NULL);
		nlsr->rev_map = hashtb_create(sizeof(struct map_entry), NULL);
		make_map();
		assign_mapping_number();		
		print_map();
		print_rev_map();

		do_old_routing_table_updates();
		clear_old_routing_table();	
		print_routing_table();
		print_npt();

		int i;
		int **adj_matrix;
		int map_element=hashtb_n(nlsr->map);
		adj_matrix=malloc(map_element * sizeof(int *));
		for(i = 0; i < map_element; i++)
		{
			adj_matrix[i] = malloc(map_element * sizeof(int));
		}
		make_adj_matrix(adj_matrix,map_element);
		if ( nlsr->debugging )
			print_adj_matrix(adj_matrix,map_element);

		long int source=get_mapping_no(nlsr->router_name);
		int num_link=get_no_link_from_adj_matrix(adj_matrix, map_element ,source);

		if ( nlsr->is_hyperbolic_calc == 1)
		{
			long int *links=(long int *)malloc(num_link*sizeof(long int));
			long int *link_costs=(long int *)malloc(num_link*sizeof(long int));
			get_links_from_adj_matrix(adj_matrix, map_element , links, link_costs, source);

			struct hashtb_enumerator ee;
			struct hashtb_enumerator *e = &ee;
			for (hashtb_start(nlsr->rev_map, e); e->key != NULL; hashtb_next(e)) 
			{
				struct map_entry *me=e->data;
				if ( me->mapping != source )
				{
					long int *faces=(long int *)calloc(num_link,sizeof(long int));
					double *nbr_dist=(double *)calloc(num_link,sizeof(double));
					double *nbr_to_dest=(double *)calloc(num_link,sizeof(double));
					for ( i=0 ; i < num_link; i++)
					{
						int face=get_next_hop_face_from_adl(get_router_from_rev_map(links[i]));
						double dist_to_nbr=get_hyperbolic_distance(source,links[i]);
						double dist_to_dest_from_nbr=get_hyperbolic_distance(links[i],me->mapping);
						faces[i]=face;
						nbr_dist[i]=dist_to_nbr;
						nbr_to_dest[i]=	dist_to_dest_from_nbr;	

						
					}
					sort_hyperbolic_route(nbr_to_dest,nbr_dist, faces,0,num_link);
					if (nlsr->max_faces_per_prefix == 0 )
					{
						for ( i=0 ; i < num_link; i++)
						{
							update_routing_table_with_new_hyperbolic_route(me->mapping,faces[i],nbr_to_dest[i]);
						}				
					}
					else if ( nlsr->max_faces_per_prefix > 0 )
					{
						if ( num_link <= nlsr->max_faces_per_prefix )
						{
							for ( i=0 ; i < num_link; i++)
							{
								update_routing_table_with_new_hyperbolic_route(me->mapping,faces[i],nbr_to_dest[i]);
							}
						}
						else if (num_link > nlsr->max_faces_per_prefix)
						{
							for ( i=0 ; i < nlsr->max_faces_per_prefix; i++)
							{
								update_routing_table_with_new_hyperbolic_route(me->mapping,faces[i],nbr_to_dest[i]);
							}
						}

					}
					free(faces);
					free(nbr_dist);
					free(nbr_to_dest);
				}
			}
			hashtb_end(e);

			
			free(links);
			free(link_costs);
		}
		else if (nlsr->is_hyperbolic_calc == 0 )
		{

			long int *parent=(long int *)malloc(map_element * sizeof(long int));
			long int *dist=(long int *)malloc(map_element * sizeof(long int));
			
		
			if ( (num_link == 0) || (nlsr->max_faces_per_prefix == 1 ) )
			{	
				calculate_path(adj_matrix,parent,dist, map_element, source);		
				print_all_path_from_source(parent,source);
				print_all_next_hop(parent,source);		
				update_routing_table_with_new_route(parent, dist,source);
			}
			else if ( (num_link != 0) && (nlsr->max_faces_per_prefix == 0 || nlsr->max_faces_per_prefix > 1 ) )
			{
				long int *links=(long int *)malloc(num_link*sizeof(long int));
				long int *link_costs=(long int *)malloc(num_link*sizeof(long int));
				get_links_from_adj_matrix(adj_matrix, map_element , links, link_costs, source);
				for ( i=0 ; i < num_link; i++)
				{
					adjust_adj_matrix(adj_matrix, map_element,source,links[i],link_costs[i]);
					calculate_path(adj_matrix,parent,dist, map_element, source);		
					print_all_path_from_source(parent,source);
					print_all_next_hop(parent,source);		
					update_routing_table_with_new_route(parent, dist,source);
				}

				free(links);
				free(link_costs);
			}
			free(parent);
			free(dist);
		}
		
		print_routing_table();
		print_npt();

		update_npt_with_new_route();

		print_routing_table();
		print_npt();


		for(i = 0; i < map_element; i++)
		{
			free(adj_matrix[i]);
		}
		
		free(adj_matrix);
		destroy_map();
		destroy_rev_map();
		//hashtb_destroy(&nlsr->map);
		//hashtb_destroy(&nlsr->rev_map);
		
	}
	nlsr->is_route_calculation_scheduled=0;

	nlsr_unlock();

	return 0;
}
Example #22
0
int
andana_client_decap_content(struct ccn_closure *selfp,
                            enum ccn_upcall_kind kind,
                            struct ccn_upcall_info *info)
{
    int res;
    struct andana_client *client = selfp->data;

    struct andana_path **path_ptr;

    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;


    DEBUG_PRINT("Client Content handle called\n");


    switch (kind) {
    case CCN_UPCALL_CONTENT:           /**< incoming verified content */
        DEBUG_PRINT("Incoming verified content\n");
        break;
    case CCN_UPCALL_CONTENT_UNVERIFIED:/**< content that has not been verified */
        DEBUG_PRINT("Incoming unverified content\n");
        break;
    case CCN_UPCALL_CONTENT_BAD:        /**< verification failed */
        DEBUG_PRINT("Incoming bad content (verification failure)\n");
        break;

    case CCN_UPCALL_INTEREST_TIMED_OUT:/**< interest timed out */
    {
        const unsigned char *name = info->interest_ccnb + info->pi->offset[CCN_PI_B_Name];
        const size_t length =  info->pi->offset[CCN_PI_E_Name] - info->pi->offset[CCN_PI_B_Name];
        DEBUG_PRINT("Interest timed out\n");
        hashtb_start(client->name_to_path, e);
        hashtb_seek(e, name, length, 0);
        hashtb_delete(e);
        hashtb_end(e);

        return(CCN_UPCALL_RESULT_ERR);
    }
    case CCN_UPCALL_INTEREST:          /**< incoming interest */
    case CCN_UPCALL_CONSUMED_INTEREST: /**< incoming interest, someone has answered */
    case CCN_UPCALL_FINAL:             /**< handler is about to be deregistered */
    default:
        DEBUG_PRINT("upcall other kind = %d\n", kind);
        return(CCN_UPCALL_RESULT_ERR);
    }


    const unsigned char *content_name = info->content_ccnb + info->pco->offset[CCN_PCO_B_Name];
    const size_t name_length = info->pco->offset[CCN_PCO_E_Name] - info->pco->offset[CCN_PCO_B_Name];
    hashtb_start(client->name_to_path, e);
    res = hashtb_seek(e, content_name, name_length, 0);

    if (res == HT_NEW_ENTRY) {
        DEBUG_PRINT("ABORT %d %s Received unsolicited content?\n", __LINE__, __func__);
        abort();
    } else if (res == HT_OLD_ENTRY) {
        path_ptr = e->data;
        DEBUG_PRINT("Interest recording found old entry\n");
    } else {
        DEBUG_PRINT("Error in Interest insertion\n");
    }
    //	hashtb_end(e);

    /* Inner content object (that we just extracted) should exactly
     * match the original requesting Interest. Decrypted and send it out
     */

    unsigned char *decrypted_content = NULL;
    size_t decrypted_length;

    unsigned char *content_ccnb = calloc(info->pco->offset[CCN_PCO_E], sizeof(unsigned char));
    memcpy(content_ccnb, info->content_ccnb, info->pco->offset[CCN_PCO_E]);

    res = andana_path_decrypt_decap(*path_ptr,
                                    content_ccnb,
                                    info->pco->offset[CCN_PCO_E],
                                    info->pco,
                                    &decrypted_content,
                                    &decrypted_length);

    if (res < 0) {
        hashtb_delete(e);
        hashtb_end(e);
        free(content_ccnb);
        free(decrypted_content);
        return(CCN_UPCALL_RESULT_ERR);
    }


    //	ccn_util_validate_content_object(decrypted_content, decrypted_length);

    res = ccn_put(client->proxy->handle, decrypted_content, decrypted_length);

    if (res < 0) {
        DEBUG_PRINT("Error sending parsed content object\n");
        abort();
    }

    //    andana_path_destroy(path_ptr);
    hashtb_delete(e);
    hashtb_end(e);
    free(content_ccnb);
    free(decrypted_content);
    //	andana_path_destroy(path_ptr);
    return(CCN_UPCALL_RESULT_OK);
}
Example #23
0
static int
r_store_index_cleaner(struct ccn_schedule *sched,
    void *clienth,
    struct ccn_scheduled_event *ev,
    int flags)
{
    struct ccnr_handle *h = clienth;
    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;
    struct ccn_btree_node *node = NULL;
    int k;
    int res;
    int overquota;
    
    (void)(sched);
    (void)(ev);
    if ((flags & CCN_SCHEDULE_CANCEL) != 0 ||
         h->btree == NULL || h->btree->io == NULL) {
        h->index_cleaner = NULL;
        ccn_indexbuf_destroy(&h->toclean);
        return(0);
    }
    /* First, work on cleaning the things we already know need cleaning */
    if (h->toclean != NULL) {
        for (k = 0; k < CCN_BT_CLEAN_BATCH && h->toclean->n > 0; k++) {
            node = ccn_btree_rnode(h->btree, h->toclean->buf[--h->toclean->n]);
            if (node != NULL && node->iodata != NULL) {
                res = ccn_btree_chknode(node); /* paranoia */
                if (res < 0 || CCNSHOULDLOG(h, sdfsdffd, CCNL_FINER))
                    ccnr_msg(h, "write index node %u (err %d)",
                             (unsigned)node->nodeid, node->corrupt);
                if (res >= 0) {
                    if (node->clean != node->buf->length)
                        res = h->btree->io->btwrite(h->btree->io, node);
                    if (res < 0)
                        ccnr_msg(h, "failed to write index node %u",
                                 (unsigned)node->nodeid);
                    else
                        node->clean = node->buf->length;
                }
                if (res >= 0 && node->iodata != NULL && node->activity == 0) {
                    if (CCNSHOULDLOG(h, sdfsdffd, CCNL_FINER))
                        ccnr_msg(h, "close index node %u",
                                 (unsigned)node->nodeid);
                    res = ccn_btree_close_node(h->btree, node);
                }
            }
        }
        if (h->toclean->n > 0)
            return(nrand48(h->seed) % (2U * CCN_BT_CLEAN_TICK_MICROS) + 500);
    }
    /* Sweep though and find the nodes that still need cleaning */
    overquota = 0;
    if (h->btree->nodepool >= 16)
        overquota = hashtb_n(h->btree->resident) - h->btree->nodepool;
    hashtb_start(h->btree->resident, e);
    for (node = e->data; node != NULL; node = e->data) {
        if (overquota > 0 &&
              node->activity == 0 &&
              node->iodata == NULL &&
              node->clean == node->buf->length) {
            overquota -= 1;
            if (CCNSHOULDLOG(h, sdfsdffd, CCNL_FINEST))
                ccnr_msg(h, "prune index node %u",
                         (unsigned)node->nodeid);
            hashtb_delete(e);
            continue;
        }
        node->activity /= 2; /* Age the node's activity */
        if (node->clean != node->buf->length ||
            (node->iodata != NULL && node->activity == 0)) {
            if (h->toclean == NULL) {
                h->toclean = ccn_indexbuf_create();
                if (h->toclean == NULL)
                    break;
            }
            ccn_indexbuf_append_element(h->toclean, node->nodeid);
        }
        hashtb_next(e);
    }
    hashtb_end(e);
    /* If nothing to do, shut down cleaner */
    if ((h->toclean == NULL || h->toclean->n == 0) && overquota <= 0 &&
        h->btree->io->openfds <= CCN_BT_OPEN_NODES_IDLE) {
        h->btree->cleanreq = 0;
        h->index_cleaner = NULL;
        ccn_indexbuf_destroy(&h->toclean);
        if (CCNSHOULDLOG(h, sdfsdffd, CCNL_FINE))
            ccnr_msg(h, "index btree nodes all clean");
        
        return(0);
    }
    return(nrand48(h->seed) % (2U * CCN_BT_CLEAN_TICK_MICROS) + 500);
}