Ejemplo n.º 1
0
int 
get_number_of_next_hop(char *dest_router)
{
	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = ⅇ 	
    	int res,ret;

   	hashtb_start(nlsr->routing_table, e);
    	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);

	if( res == HT_OLD_ENTRY )
	{
		rte=e->data;
		ret=hashtb_n(rte->face_list);
		//nhl=rte->face_list;
	}
	else if(res == HT_NEW_ENTRY)
	{
		hashtb_delete(e);
		ret=NO_NEXT_HOP;
	}

	hashtb_end(e);	

	return ret;
}
Ejemplo n.º 2
0
void LMD_demux(LMD self) {
	struct hashtb_enumerator htee; struct hashtb_enumerator* hte = &htee;
	int htres; LMDRec rec;
	SockAddr addr = SockAddr_ctor(); struct ccn_charbuf* hashkey;
	void* buf = malloc(self->mtu); size_t len;

	hashtb_start(self->demux, hte);
	while ((len = NBS_read(self->nbs, buf, self->mtu, addr)) > 0) {
	        	
		hashkey = SockAddr_hashkey(addr);
		htres = hashtb_seek(hte, hashkey->buf, hashkey->length, 0);
		rec = NULL;
		if (htres == HT_OLD_ENTRY) {
			rec = *((LMDRec*)hte->data);
		} else {
			rec = self->fallback;
			if (htres == HT_NEW_ENTRY) hashtb_delete(hte);
		}
		if (rec != NULL) {
			LMDRec_deliver(rec, buf, len, addr);
			buf = malloc(self->mtu);
		}
	}
	free(buf);
	hashtb_end(hte);
	SockAddr_dtor(addr);
}
Ejemplo n.º 3
0
// TODO deferred cleaning
void hash_store_clean(struct hash_store* self) {
  struct hashtb_enumerator ee; struct hashtb_enumerator* e = ⅇ
  hashtb_start(self->btree->resident, e);
  int overquota = 0;
  if (self->btree->nodepool >= 16) overquota = hashtb_n(self->btree->resident) - self->btree->nodepool;
  for (struct ndn_btree_node* node = e->data; node != NULL; node = e->data) {
    if (overquota > 0 && node->activity == 0 && node->iodata == NULL && node->clean == node->buf->length) {
      --overquota;
      hashtb_delete(e);
      continue;
    }
    //node->activity /= 2;
    node->activity = 0;
    if (node->clean != node->buf->length || (node->iodata != NULL && node->activity == 0)) {
      int res = ndn_btree_chknode(node);
      if (res < 0) continue;
      if (node->clean != node->buf->length) {
        res = self->btree->io->btwrite(self->btree->io, node);
        if (res < 0) continue;
        node->clean = node->buf->length;
      }
      if (node->iodata != NULL && node->activity == 0) {
        res = ndn_btree_close_node(self->btree, node);
      }
    }
    hashtb_next(e);
  }
  hashtb_end(e);
}
Ejemplo n.º 4
0
int  
does_name_exist_in_npl(struct name_prefix *np)
{
	int ret=0;
	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)
	{   
		hashtb_delete(e);
		ret=0;
	}
	else
	{
		ret=1;
    	}
	hashtb_end(e);

	return ret;

}
Ejemplo n.º 5
0
char * 
get_router_from_rev_map(long int mapping_number)
{

	struct map_entry *me;

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

   	hashtb_start(nlsr->rev_map, e);
    	res = hashtb_seek(e, &mapping_number, sizeof(mapping_number), 0);

	if(res == HT_OLD_ENTRY)
	{
		me=e->data;
		hashtb_end(e);
		return me->router;
	}
	else if(res == HT_NEW_ENTRY)
	{
		hashtb_delete(e);
		hashtb_end(e);
	}
	
	return NULL;
}
Ejemplo n.º 6
0
long int  
get_lsa_id_from_npl(struct name_prefix *np)
{
	int ret=0;

	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)
	{   
		hashtb_delete(e);
		ret=0;
	}
	else
	{
		npe=e->data;
		ret=npe->name_lsa_id;
    	}
	hashtb_end(e);

	return ret;

}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
void 
update_routing_table(char * dest_router,int next_hop_face, int route_cost)
{
	if ( nlsr->debugging )
	{
		printf("update_routing_table called \n");
		printf("Dest Router: %s Next Hop face: %d Route Cost: %d \n",dest_router,next_hop_face,route_cost);
	}

	int res,res1;
	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;

		struct hashtb_enumerator eef;
    		struct hashtb_enumerator *ef = &eef;
    	
    		hashtb_start(rte->face_list, ef);
		res1 = hashtb_seek(ef, &next_hop_face, sizeof(next_hop_face), 0);	
		if( res1 == HT_NEW_ENTRY)
		{
			struct face_list_entry *fle;
			fle=ef->data;
			fle->next_hop_face=next_hop_face;
			fle->route_cost=route_cost;						
		}
		else if ( res1 == HT_OLD_ENTRY )
		{
			struct face_list_entry *fle;
			fle=ef->data;
			fle->route_cost=route_cost;
		}
		hashtb_end(ef);
	}
	else if ( res == HT_NEW_ENTRY )
	{
		hashtb_delete(e);
	}
	
	hashtb_end(e);
	
}
Ejemplo n.º 9
0
void SentPkts_remove(SentPkts self, SeqNum sequence) {
	struct hashtb_enumerator htee; struct hashtb_enumerator* hte = &htee;
	int htres; SentPktRec rec;
	
	hashtb_start(self->index, hte);
	htres = hashtb_seek(hte, &sequence, sizeof(SeqNum), 0);
	if (htres == HT_OLD_ENTRY) {
		rec = *((SentPktRec*)hte->data);
		SentPkts_rDetach(self, rec);
		SentPkts_sDetach(self, rec);
		SentPktRec_dtor(rec, false);
	}
	hashtb_delete(hte);
	hashtb_end(hte);
}
Ejemplo n.º 10
0
void LMD_dtor(LMD self) {
	struct hashtb_enumerator htee; struct hashtb_enumerator* hte = &htee;
	LMDRec rec;
	for (hashtb_start(self->demux, hte); hte->data != NULL; ) {
		rec = *((LMDRec*)hte->data);
		LMDRec_dtor(rec);
		hashtb_delete(hte);
	}
	hashtb_end(hte);

	NBS_dtor(self->nbs);
	if (self->localAddr != NULL) SockAddr_dtor(self->localAddr);
	hashtb_destroy(&(self->demux));
	free(self);
}
Ejemplo n.º 11
0
bool LMD_registered(LMD self, SockAddr srcaddr) {
	struct hashtb_enumerator htee; struct hashtb_enumerator* hte = &htee;
	int htres; bool found = false;
	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) {
		found = true;
	} else {
		hashtb_delete(hte);
	}
	hashtb_end(hte);

	return found;
}
Ejemplo n.º 12
0
static void remove_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;
    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);
    hashtb_delete(e);

    hashtb_end(e);
}
Ejemplo n.º 13
0
int 
get_next_hop(char *dest_router,int *faces, int *route_costs)
{
	struct routing_table_entry *rte;

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

   	hashtb_start(nlsr->routing_table, e);
    	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);

	if( res == HT_OLD_ENTRY )
	{
		rte=e->data;
		ret=hashtb_n(rte->face_list);
		//nhl=rte->face_list;
		int j,face_list_element;
		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);
		for(j=0;j<face_list_element;j++)
		{
			fle=ef->data;
			//printf(" 	Face: %d Route_Cost: %d \n",fle->next_hop_face,fle->route_cost);
			faces[j]=fle->next_hop_face;
			route_costs[j]=fle->route_cost;
			hashtb_next(ef);	
		}
		hashtb_end(ef);
		
	}
	else if(res == HT_NEW_ENTRY)
	{
		hashtb_delete(e);
		ret=NO_NEXT_HOP;
	}

	hashtb_end(e);	

	return ret;
}
Ejemplo n.º 14
0
void LMD_unreg(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);
	}
	hashtb_delete(hte);
	hashtb_end(hte);

	if (rec != NULL) {
		if (self->fallback == rec) self->fallback = NULL;
		LMDRec_dtor(rec);
	}
}
Ejemplo n.º 15
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 = &ee;
    	
    	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);	
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
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);
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
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;

}
Ejemplo n.º 21
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);
}
Ejemplo n.º 22
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);
}
Ejemplo n.º 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);
}