예제 #1
0
int main()
{
    struct ccn *ccn = NULL;
    struct ccn_charbuf *name = NULL;
    int res;
    struct ccn_closure *incoming = NULL;

    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1)
    {
        perror("Could not connect to ccnd");
        exit(1);
    }

    incoming = calloc(1, sizeof(*incoming));
    incoming->p = &incoming_content;
    name = ccn_charbuf_create();

    res = ccn_name_from_uri(name, "ccnx:/FOX/test");

    //ccn_express_persistent_interest(ccn, name, incoming, NULL, 1);
    ccn_express_interest(ccn, name, incoming, NULL);



    printf("Interests send\n", res);

    res = ccn_run(ccn, 10000);

    return 0;
}
예제 #2
0
static int do_ping(struct ccn_schedule *sched, void *clienth,
        struct ccn_scheduled_event *ev, int flags)
{
    struct ccn_ping_client *client = clienth;
    if (client->total >= 0 && client->sent >= client->total)
        return 0;

    struct ccn_charbuf *name = ccn_charbuf_create();
    long int rnum;
    char rnumstr[20];
    int res;

    ccn_charbuf_append(name, client->prefix->buf, client->prefix->length);
    if (client->number < 0)
        rnum = random();
    else {
        rnum = client->number;
        client->number ++;
    }
    memset(&rnumstr, 0, 20);
    sprintf(rnumstr, "%ld", rnum);
    ccn_name_append_str(name, rnumstr);

    res = ccn_express_interest(client->h, name, client->closure, NULL);
    add_ccn_ping_entry(client, name, rnum);
    client->sent ++;
    sta.sent ++;

    ccn_charbuf_destroy(&name);

    if (res >= 0)
        return client->interval * 1000000;
    else
        return 0;
}
예제 #3
0
/**
 * Post an interests to the CCN network, and maintains the state information
 *
 * This will create the name used to express the interest on the network. It takes
 * the given segment and includes it in the name. It will then manage the state information
 * we keep in the context to allow us to deliver segments in order, as oppose to how
 * they may be presented to us from the network.
 *
 * \param me		context holding the array of interest states and other ccn information
 * \param seg		the segment to express interest in
 * \return status value from the express call made to CCN
 */
static gint
request_segment (Gstccnxsrc * me, uintmax_t seg)
{
  struct ccn_charbuf *nm = NULL;
  gint rc = 0;

  if (NULL == me)
    return -1;

  // nm = sequenced_name(me->p_name, seg);
  nm = ccn_charbuf_create ();
  rc |= ccn_charbuf_append_charbuf (nm, me->p_name);
  rc |= ccn_name_append_numeric (nm, CCN_MARKER_SEQNUM, seg);

  GST_INFO ("reqseg - name for interest...");
  // hDump(nm->buf, nm->length);
  rc |= ccn_express_interest (me->ccn, nm, me->ccn_closure, me->p_template);
  ccn_charbuf_destroy (&nm);
  if (rc < 0) {
    return rc;
  }

  GST_DEBUG ("interest sent for segment %d\n", seg);
  return rc;
}
예제 #4
0
static void
NeedSegment(struct ccn_fetch_stream *fs, seg_t seg) {
	// requests that a specific segment interest be registered
	// but ONLY if it the request not already in flight
	// AND the segment is not already in a buffer
	struct ccn_fetch_buffer *fb = FindBufferForSeg(fs, seg);
	if (fb != NULL)
		// no point in requesting what we have
		return;
	if (fs->finalSeg >= 0 && seg > fs->finalSeg)
		// no point in requesting off the end, either
		return;
	if (fs->timeoutSeg > 0 && seg >= fs->timeoutSeg)
		// don't request a timed-out segment
		return;
	if (fs->zeroLenSeg > 0 && seg >= fs->zeroLenSeg)
		// don't request a zero-length segment
		return;
	struct localClosure *req = AddSegRequest(fs, seg);
	if (req != NULL) {
		FILE *debug = fs->parent->debug;
		ccn_fetch_flags flags = fs->parent->debugFlags;
		struct ccn_charbuf *temp = sequenced_name(fs->name, seg);
		struct ccn *h = fs->parent->h;
		struct ccn_closure *action = calloc(1, sizeof(*action));
		action->data = req;
		action->p = &CallMe;
		int res = ccn_express_interest(h, temp, action, fs->interest);
		ccn_charbuf_destroy(&temp);
		if (res >= 0) {
			// the ccn connection accepted our request
			fs->reqBusy++;
			fs->segsRequested++;
			if (debug != NULL && (flags & ccn_fetch_flags_NoteNeed)) {
				fprintf(debug,
						"-- ccn_fetch NeedSegment %s, seg %jd",
						fs->id, seg);
				if (fs->finalSeg >= 0)
					fprintf(debug, ", final %jd", fs->finalSeg);
				fprintf(debug, "\n");
				fflush(debug);
			}
			return;
		}
		// the request was not placed, so get rid of the evidence
		// CallMe won't get a chance to free it
		if (debug != NULL && (flags & ccn_fetch_flags_NoteNeed)) {
			fprintf(debug,
					"** ccn_fetch NeedSegment failed, %s, seg %jd\n",
					fs->id, seg);
			fflush(debug);
		}
		RemSegRequest(fs, req);
		free(req);
		free(action);
        
	}
}
예제 #5
0
void
ccn_ssh_connect(char *remote_name_str)
{
    dropbear_log(LOG_WARNING,"Enter ccn_ssh_connect");
    int result;
    struct ccn_charbuf *remote_name;
/*
    struct ccn_pkey *server_pkey;
    void *encrypted_local_name;
    size_t encrypted_local_name_length;
*/

    struct ccn_charbuf *connect_template;


    remote_name = ccn_charbuf_create();
    result = ccn_name_from_uri(remote_name,remote_name_str);
    if( result < 0 )
        dropbear_exit("Could not parse server uri");

    ccn_name_append_str(remote_name,"ssh");
    ccn_name_append_str(remote_name,"client");

    /*
    server_pkey = ssh_ccn_retrieve_public_key(
            cli_opts.ssh_ccn,
            cli_opts.remote_name_str,
            cli_opts.ccn_cached_keystore);
    if( server_pkey == NULL )
        dropbear_exit("Could not get server public key");

    result = ccn_pubkey_encrypt(server_pkey,
            cli_opts.ccnxdomain,
            strlen(cli_opts.ccnxdomain),
            &encrypted_local_name,
            &encrypted_local_name_length);

    ccn_name_append(remote_name,encrypted_local_name);
    */
    ccn_name_append(remote_name,cli_opts.ccnxdomain,strlen(cli_opts.ccnxdomain));

    dropbear_log(LOG_WARNING,"Connecting to remote:");
    print_ccnb_charbuf(remote_name);

    connect_template = make_connect_template();

    result = ccn_express_interest(cli_opts.ssh_ccn,
            remote_name,
            &newServerAction,
            connect_template);
    if( result < 0 )
        dropbear_exit("Failed to express interest to server");
}
예제 #6
0
void NdnMediaProcess::initPipe(struct ccn_closure *selfp, struct ccn_upcall_info *info, UserDataBuf *userBuf) {
	fprintf(stderr, "initializing pipe\n");
	// get seq
	const unsigned char *ccnb = info->content_ccnb;
	size_t ccnb_size = info->pco->offset[CCN_PCO_E];
	struct ccn_indexbuf *comps = info->content_comps;

	long seq;
	const unsigned char *seqptr = NULL;
	char *endptr = NULL;
	size_t seq_size = 0;
	int k = comps->n - 2;

	if (userBuf->seq < 0) {
		seq = ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb,
				comps->buf[k], comps->buf[k + 1],
				&seqptr, &seq_size);
		if (seq >= 0) {
			seq = strtol((const char *)seqptr, &endptr, 10);
			if (endptr != ((const char *)seqptr) + seq_size)
				seq = -1;
		}
		if (seq >= 0) {
			userBuf->seq = seq;
		}
		else {
			return;
		}
	}	
	
	fprintf(stderr, "fetched content with seq %d\n", seq);
	// send hint-ahead interests
	for (int i = 0; i < hint_ahead; i ++) {
		userBuf->seq++;
		struct ccn_charbuf *pathbuf = ccn_charbuf_create();
		ccn_name_init(pathbuf);
		ccn_name_append_components(pathbuf, ccnb, comps->buf[0], comps->buf[k]);
		struct ccn_charbuf *temp = ccn_charbuf_create();
		ccn_charbuf_putf(temp, "%ld", userBuf->seq);
		ccn_name_append(pathbuf, temp->buf, temp->length);
		
		// no need to trylock as we already have the lock
		// this should use  pipe callback, selfp is normal callback
		int res = ccn_express_interest(info->h, pathbuf, userBuf->data_buf.pipe_callback, NULL);
		if (res < 0) {
			fprintf(stderr, "Sending interest failed at normal processor\n");
			std::exit(1);
		}
		ccn_charbuf_destroy(&pathbuf);
		ccn_charbuf_destroy(&temp);
	}
}
예제 #7
0
파일: CcnClient.c 프로젝트: ltr120/NDNFD
void CcnH_regForwardingEntry(struct ccn* ccnh, CCNDID ccndid, struct ccn_forwarding_entry* fe, void* closureData, ccn_handler closureHandler) {
	struct ccn_charbuf* reqname = CcnH_signForwardingEntry(ccnh, ccndid, fe);

	struct ccn_closure* action = NULL;
	if (closureHandler != NULL) {
		action = (struct ccn_closure*)calloc(1, sizeof(*action));
		action->data = closureData;
		action->p = closureHandler;
	}

	ccn_express_interest(ccnh, reqname, action, CcnH_localScopeTempl());
	ccn_charbuf_destroy(&reqname);
}
예제 #8
0
int NdnMediaProcess::checkInterest()
{
    int res = 0;
    QHash<QString,UserDataBuf *>::iterator it; 
	ruMutex->lock();
    for ( it = qhRemoteUser.begin(); it != qhRemoteUser.end(); ++it ) {
        if (!it.value()->interested) {
            /* Use a template to express our order preference for the first packet. */
            struct ccn_charbuf *templ = ccn_charbuf_create();
            struct ccn_charbuf *path = ccn_charbuf_create();
            ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
            ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
            ccn_charbuf_append_closer(templ);
            ccn_charbuf_append_tt(templ, CCN_DTAG_ChildSelector, CCN_DTAG);
            ccn_charbuf_append_tt(templ, 1, CCN_UDATA);
            ccn_charbuf_append(templ, "1", 1);	/* low bit 1: rightmost */
            ccn_charbuf_append_closer(templ); /*<ChildSelector>*/
            ccn_charbuf_append_closer(templ);
			ccn_name_from_uri(path, it.key().toLocal8Bit().constData());
			ccn_name_append_str(path, "audio");
            if (res >= 0) {
                if (it.value()->data_buf.callback->p == NULL) {fprintf(stderr, "data_buf.callback is NULL!\n"); exit(1); }
				/*
				int c = 0;
				while (pthread_mutex_trylock(&ccn_mutex) != 0) {
					c++;
					if (c > 10000000) {
						fprintf(stderr, "cannot obtain lock! %s:%d\n", __FILE__, __LINE__);
						std::exit(1);
					}
				}
				*/
				pthread_mutex_lock(&ccn_mutex);
                res = ccn_express_interest(ndnState.ccn, path, it.value()->data_buf.callback, templ);
				pthread_mutex_unlock(&ccn_mutex);
                it.value()->interested = 1;
				fprintf(stderr, "short interest sent\n");
            }
            if (res < 0) {
				fprintf(stderr, "sending the first interest failed\n");
				exit(1);
			}
            ccn_charbuf_destroy(&path);
            ccn_charbuf_destroy(&templ);
        }
    }
	ruMutex->unlock();
    return res;
}
예제 #9
0
파일: ccnping.c 프로젝트: remap/ndn-status
int
main(int argc, char *argv[])
{
	int res;
	struct ccn *ccn = NULL;
	struct ccn_charbuf *name = NULL;
	struct ccn_closure *incoming;

	if (argc != 2)
		usage(argv[0]);

	name = ccn_charbuf_create();

	res = ccn_name_from_uri(name, argv[1]);
	if (res < 0) {
		fprintf(stderr, "invalid ccn URI: %s\n", argv[1]);
		usage(argv[0]);
	}
	ccn = ccn_create();

	res = ccn_connect(ccn, NULL);
	if (res < 0) {
		fprintf(stderr, "can't connect to ccn: %d\n", res);
		ccn_perror(ccn, "ccn_connect");
		exit(1);
	}

	incoming = calloc(1, sizeof(*incoming));
	incoming->p = incoming_handler;
	g_working = true;
	gettimeofday(&g_start, NULL);
	res = ccn_express_interest(ccn, name, incoming, NULL);

	while (g_working && res >= 0)
		res = ccn_run(ccn, 100);

	free(incoming);

	if (res < 0) {
		ccn_perror(ccn, "ccn_run");
		exit(1);
	}

	ccn_charbuf_destroy(&name);
	ccn_destroy(&ccn);

	return 0;
}
예제 #10
0
/* send optional leave notification before actually leaves
 */
void GroupManager::sendLeaveInterest() {
	ccn_charbuf *interest_path = ccn_charbuf_create();
	if (interest_path == NULL ) {
		return;
	}
	ccn_name_from_uri(interest_path, (const char*)BROADCAST_PREFIX);
	ccn_name_append_str(interest_path, confName.toLocal8Bit().constData());
	ccn_name_append_str(interest_path, "leave");
	ccn_name_append_str(interest_path, userName.toLocal8Bit().constData());
	static ccn_charbuf *templ = NULL;
	mutex_trylock();
    ccn_express_interest(ccn, interest_path, leave_closure, NULL);
	mutex_unlock();
    ccn_charbuf_destroy(&interest_path);
	templ = NULL;
}
예제 #11
0
/*
 * Construct and send a new interest that uses the exclusion list.
 * Return -1 if not sent because of packet size, 0 for success.
 */
static int
express_my_interest(struct ccn *h,
                    struct ccn_closure *selfp,
                    struct ccn_charbuf *name)
{
    int ans;
    struct ccn_charbuf *templ = NULL;
    int i;
    struct ccn_traversal *data = get_my_data(selfp);

    templ = ccn_charbuf_create();
    ccnb_element_begin(templ, CCN_DTAG_Interest);
    ccnb_element_begin(templ, CCN_DTAG_Name);
    ccnb_element_end(templ); /* </Name> */
    if (data->n_excl != 0) {
        ccnb_element_begin(templ, CCN_DTAG_Exclude);
        if ((data->flags & EXCLUDE_LOW) != 0)
            append_Any_filter(templ);
        for (i = 0; i < data->n_excl; i++) {
            struct ccn_charbuf *comp = data->excl[i];
            if (comp->length < 4) abort();
            ccn_charbuf_append(templ, comp->buf + 1, comp->length - 2);
        }
        if ((data->flags & EXCLUDE_HIGH) != 0)
            append_Any_filter(templ);
        ccnb_element_end(templ); /* </Exclude> */
    }
    answer_passive(templ, (data->flags & ALLOW_STALE) != 0);
    if ((data->flags & LOCAL_SCOPE) != 0)
        local_scope(templ);
    ccnb_element_end(templ); /* </Interest> */
    if (templ->length + name->length > data->warn + 2) {
        fprintf(stderr, "*** Interest packet is %d bytes\n", (int)templ->length);
        data->warn = data->warn * 8 / 5;
    }
    if (templ->length + name->length > 1450 && data->n_excl > 3)
        ans = -1;
    else {
        ccn_express_interest(h, name, selfp, templ);
        ans = 0;
    }
    ccn_charbuf_destroy(&templ);
    return(ans);
}
예제 #12
0
파일: ccn_bulkdata.c 프로젝트: Emat12/ccnx
static void
express_bulkdata_interest(struct ccn *h, struct pending *p)
{
    int res;
    struct bulkdata *b = NULL;
    int prefix_comps = -1;
    int addl_comps = -1;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *templ = NULL;
    struct ccn_charbuf *seq = NULL;
    
    b = p->parent;
    if (b == NULL)
        return;
    name = ccn_charbuf_create();
    templ = ccn_charbuf_create();
    seq = ccn_charbuf_create();

    ccn_charbuf_append(name, b->name_prefix->buf, b->name_prefix->length);
    
    seq->length = 0;
    (*b->seqfunc)(p->x, b->seqfunc_param, seq);
    ccn_name_append(name, seq->buf, seq->length);
    prefix_comps = -1;
    addl_comps = 1;
    
    ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);

    ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
    ccn_charbuf_append_closer(templ); /* </Name> */

    // XXX - may want to set Min/MaxSuffixComponents
    
    ccn_charbuf_append_closer(templ); /* </Interest> */
    res = ccn_express_interest(h, name, &p->closure, templ);
    assert(res >= 0); // XXX - handle this better
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&templ);
    ccn_charbuf_destroy(&seq);
}
예제 #13
0
파일: ccnslurp.c 프로젝트: Emat12/ccnx
/*
 * Construct and send a new interest that uses the exclusion list.
 * Return -1 if not sent because of packet size, 0 for success.
 */
static int
express_my_interest(struct ccn *h,
                    struct ccn_closure *selfp,
                    struct ccn_charbuf *name)
{
    int ans;
    struct ccn_charbuf *templ = NULL;
    int i;
    struct upcalldata *data = get_my_data(selfp);

    templ = ccn_charbuf_create();
    ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
    ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
    ccn_charbuf_append_closer(templ); /* </Name> */
    ccn_charbuf_append_tt(templ, CCN_DTAG_Exclude, CCN_DTAG);
    if ((data->flags & EXCLUDE_LOW) != 0)
        append_bf_all(templ);
    for (i = 0; i < data->n_excl; i++) {
        struct ccn_charbuf *comp = data->excl[i];
        if (comp->length < 4) abort();
        ccn_charbuf_append(templ, comp->buf + 1, comp->length - 2);
    }
    if ((data->flags & EXCLUDE_HIGH) != 0)
        append_bf_all(templ);
    ccn_charbuf_append_closer(templ); /* </Exclude> */
    answer_passive(templ);
    ccn_charbuf_append_closer(templ); /* </Interest> */
    if (templ->length + name->length > data->warn + 2) {
        fprintf(stderr, "*** Interest packet is %d bytes\n", (int)templ->length);
        data->warn = data->warn * 8 / 5;
    }
    if (templ->length + name->length > 1450 && data->n_excl > 3)
        ans = -1;
    else {
        ccn_express_interest(h, name, selfp, templ);
        ans = 0;
    }
    ccn_charbuf_destroy(&templ);
    return(ans);
}
예제 #14
0
void NdnMediaProcess::tick() {
	// send new interest for every speaker
	ruMutex->lock();
	QHash<QString, UserDataBuf *>::const_iterator it = qhRemoteUser.constBegin(); 	
	while (it != qhRemoteUser.constEnd()) {
		QString userName = it.key();
		UserDataBuf *udb = it.value();
		if (udb != NULL && udb->seq >= 0) {
			udb->seq++;
			struct ccn_charbuf *pathbuf = ccn_charbuf_create();
			ccn_name_from_uri(pathbuf, userName.toLocal8Bit().constData());
			ccn_name_append_str(pathbuf, "audio");
			struct ccn_charbuf *temp = ccn_charbuf_create();
			ccn_charbuf_putf(temp, "%ld", udb->seq);
			ccn_name_append(pathbuf, temp->buf, temp->length);
			/*
			int c = 0;
			while (pthread_mutex_trylock(&ccn_mutex) != 0) {
				c++;
				if (c > 10000000) {
					fprintf(stderr, "cannot obtain lock! %s:%d\n", __FILE__, __LINE__);
					std::exit(1);
				}
			}
			*/
			pthread_mutex_lock(&ccn_mutex);
			int res = ccn_express_interest(ndnState.ccn, pathbuf, udb->data_buf.pipe_callback, NULL);
			pthread_mutex_unlock(&ccn_mutex);
			if (res < 0) {
				fprintf(stderr, "Sending interest failed at normal processor\n");
				exit(1);
			}
			ccn_charbuf_destroy(&pathbuf);
			ccn_charbuf_destroy(&temp);
		}
		it++;	
	}
	ruMutex->unlock();
}
예제 #15
0
/************************************************
* Text
************************************************/
int NdnMediaProcess::fetchNdnText()
{
    int res = 0;
    QHash<QString,UserDataBuf *>::iterator it; 
	ruMutex->lock();
    for ( it = qhRemoteUser.begin(); it != qhRemoteUser.end(); ++it ) {
        if (!it.value()->texted) {
            struct ccn_charbuf *templ = ccn_charbuf_create();
            struct ccn_charbuf *path = ccn_charbuf_create();
            ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
            ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
            ccn_charbuf_append_closer(templ);
            ccn_charbuf_append_tt(templ, CCN_DTAG_ChildSelector, CCN_DTAG);
            ccn_charbuf_append_tt(templ, 1, CCN_UDATA);
            ccn_charbuf_append(templ, "1", 1);	/* low bit 1: rightmost */
            ccn_charbuf_append_closer(templ); /*<ChildSelector>*/
            ccn_charbuf_append_closer(templ);
			ccn_name_from_uri(path, it.key().toLocal8Bit().constData());
			ccn_name_append_str(path, "text");
            if (res >= 0) {
                if (it.value()->data_buf.text_callback->p == NULL) {fprintf(stderr, "data_buf.text_callback is NULL!\n"); exit(1); }
				pthread_mutex_lock(&ccn_mutex);
                res = ccn_express_interest(ndnState.ccn, path, it.value()->data_buf.text_callback, templ);
				pthread_mutex_unlock(&ccn_mutex);
                it.value()->texted = 1;
				fprintf(stderr, "short interest sent\n");
            }
            if (res < 0) {
				fprintf(stderr, "sending the first interest failed\n");
				exit(1);
			}
            ccn_charbuf_destroy(&path);
            ccn_charbuf_destroy(&templ);
        }
    }
	ruMutex->unlock();
    return res;
}
예제 #16
0
enum ccn_upcall_res
incoming_content(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *templ = NULL;
    struct ccn_charbuf *temp = NULL;
    const unsigned char *ccnb = NULL;
    size_t ccnb_size = 0;
    const unsigned char *data = NULL;
    size_t data_size = 0;
    size_t written;
    const unsigned char *ib = NULL; /* info->interest_ccnb */
    struct ccn_indexbuf *ic = NULL;
    int res;
    struct mydata *md = selfp->data;
    
    if (kind == CCN_UPCALL_FINAL) {
        if (md != NULL) {
            selfp->data = NULL;
            free(md);
            md = NULL;
        }
        return(CCN_UPCALL_RESULT_OK);
    }
    if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
        return(CCN_UPCALL_RESULT_REEXPRESS);
    if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED)
        return(CCN_UPCALL_RESULT_ERR);
    if (md == NULL)
        selfp->data = md = calloc(1, sizeof(*md));
    ccnb = info->content_ccnb;
    ccnb_size = info->pco->offset[CCN_PCO_E];
    ib = info->interest_ccnb;
    ic = info->interest_comps;
    /* XXX - must verify sig, and make sure it is LEAF content */
    res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size);
    if (res < 0) abort();
    if (data_size > CHUNK_SIZE) {
        /* For us this is spam. Give up now. */
        fprintf(stderr, "*** Segment %d found with a data size of %d."
                        " This program only works with segments of 1024 bytes."
                        " Try ccncatchunks2 instead.\n",
                        (int)selfp->intdata, (int)data_size);
        exit(1);
    }
    
    /* OK, we will accept this block. */
    
    written = fwrite(data, data_size, 1, stdout);
    if (written != 1)
        exit(1);
    
    /* A short block signals EOF for us. */
    if (data_size < CHUNK_SIZE)
        exit(0);
    
    /* Ask for the next one */
    name = ccn_charbuf_create();
    ccn_name_init(name);
    if (ic->n < 2) abort();
    res = ccn_name_append_components(name, ib, ic->buf[0], ic->buf[ic->n - 2]);
    if (res < 0) abort();
    temp = ccn_charbuf_create();
    ccn_charbuf_putf(temp, "%d", ++(selfp->intdata));
    ccn_name_append(name, temp->buf, temp->length);
    ccn_charbuf_destroy(&temp);
    templ = make_template(md, info);
    
    res = ccn_express_interest(info->h, name, selfp, templ);
    if (res < 0) abort();
    
    ccn_charbuf_destroy(&templ);
    ccn_charbuf_destroy(&name);
    
    return(CCN_UPCALL_RESULT_OK);
}
예제 #17
0
파일: ccnsimplecat.c 프로젝트: Emat12/ccnx
/**
 * Process options and then loop through command line CCNx URIs retrieving
 * the data and writing it to stdout.
 */
int
main(int argc, char **argv)
{
    struct ccn *ccn = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *templ = NULL;
    struct ccn_closure *incoming = NULL;
    const char *arg = NULL;
    int i;
    int res;
    int opt;
    struct mydata *mydata;
    int allow_stale = 0;
    int *done;
    int exit_status = 0;
    
    done = calloc(1, sizeof(*done));
    
    while ((opt = getopt(argc, argv, "ha")) != -1) {
        switch (opt) {
            case 'a':
                allow_stale = 1;
                break;
            case 'h':
            default:
                usage(argv[0]);
        }
    }
    arg = argv[optind];
    if (arg == NULL)
        usage(argv[0]);
    name = ccn_charbuf_create();
    /* Check the args first */
    for (i = optind; argv[i] != NULL; i++) {
        name->length = 0;
        res = ccn_name_from_uri(name, argv[i]);
        if (res < 0) {
            fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], argv[i]);
            exit(1);
        }
    }
    for (i = optind; (arg = argv[i]) != NULL; i++) {
        *done = 0;
        name->length = 0;
        res = ccn_name_from_uri(name, arg);
        ccn = ccn_create();
        if (ccn_connect(ccn, NULL) == -1) {
            perror("Could not connect to ccnd");
            exit(1);
        }
        ccn_resolve_version(ccn, name, CCN_V_HIGHEST, 50);
        ccn_name_append_numeric(name, CCN_MARKER_SEQNUM, 0);
        incoming = calloc(1, sizeof(*incoming));
        incoming->p = &incoming_content;
        mydata = calloc(1, sizeof(*mydata));
        mydata->allow_stale = allow_stale;
        mydata->done = done;
        incoming->data = mydata;
        templ = make_template(mydata, NULL);
        ccn_express_interest(ccn, name, incoming, templ);
        ccn_charbuf_destroy(&templ);
        /* Run a little while to see if there is anything there */
        res = ccn_run(ccn, 200);
        if ((!*done) && incoming->intdata == 0) {
            fprintf(stderr, "%s: not found: %s\n", argv[0], arg);
            res = -1;
        }
        /* We got something; run until end of data or somebody kills us */
        while (res >= 0 && !*done) {
            fflush(stdout);
            res = ccn_run(ccn, 333);
        }
        if (res < 0)
            exit_status = 1;
        ccn_destroy(&ccn);
        fflush(stdout);
        free(incoming);
        incoming = NULL;
    }
    ccn_charbuf_destroy(&name);
    free(done);
    exit(exit_status);
}
예제 #18
0
파일: ccnls.c 프로젝트: Emat12/ccnx
int
main(int argc, char **argv)
{
    struct ccn *ccn = NULL;
    struct ccn_charbuf *c = NULL;
    struct ccn_charbuf *templ = NULL;
    struct upcalldata *data = NULL;
    int i;
    int n;
    int res;
    long counter = 0;
    struct ccn_closure *cl = NULL;
    int timeout_ms = 500;
    const char *env_timeout = getenv("CCN_LINGER");
    const char *env_verify = getenv("CCN_VERIFY");
    const char *env_scope = getenv("CCN_SCOPE");

    if (argv[1] == NULL || argv[2] != NULL)
        usage(argv[0]);

    if (env_timeout != NULL && (i = atoi(env_timeout)) > 0)
        timeout_ms = i * 1000;

    c = ccn_charbuf_create();
    res = ccn_name_from_uri(c, argv[1]);
    if (res < 0)
        usage(argv[0]);
        
    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }
    
    data = calloc(1, sizeof(*data));
    data->magic = 856372;
    data->warn = 1492;
    data->counter = &counter;
    data->option = 0;
    if (env_verify && *env_verify)
        data->option |= MUST_VERIFY;
    data->scope = -1;
    if (env_scope != NULL && (i = atoi(env_scope)) >= 0)
      data->scope = i;
    cl = calloc(1, sizeof(*cl));
    cl->p = &incoming_content;
    cl->data = data;
    if (data->scope > -1) {
        templ = ccn_charbuf_create();
        ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
        ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
        ccn_charbuf_append_closer(templ); /* </Name> */
        ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", data->scope);
        ccn_charbuf_append_closer(templ); /* </Interest> */
    }
    ccn_express_interest(ccn, c, cl, templ);
    ccn_charbuf_destroy(&templ);
    cl = NULL;
    data = NULL;
    for (i = 0;; i++) {
        n = counter;
        ccn_run(ccn, timeout_ms); /* stop if we run dry for 1/2 sec */
        fflush(stdout);
        if (counter == n)
            break;
    }
    ccn_destroy(&ccn);
    ccn_charbuf_destroy(&c);
    exit(0);
}
예제 #19
0
int
main(int argc, char **argv)
{
    struct ccn *ccn = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *templ = NULL;
    struct ccn_closure *incoming = NULL;
    const char *arg = NULL;
    int res;
    int opt;
    struct mydata *mydata;
    int allow_stale = 0;
    
    while ((opt = getopt(argc, argv, "ha")) != -1) {
        switch (opt) {
            case 'a':
                allow_stale = 1;
                break;
            case 'h':
            default:
                usage(argv[0]);
        }
    }
    arg = argv[optind];
    if (arg == NULL)
        usage(argv[0]);
    name = ccn_charbuf_create();
    res = ccn_name_from_uri(name, arg);
    if (res < 0) {
        fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], arg);
        exit(1);
    }
    if (argv[optind + 1] != NULL)
        fprintf(stderr, "%s warning: extra arguments ignored\n", argv[0]);
    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }
    ccn_name_append(name, "0", 1);
    incoming = calloc(1, sizeof(*incoming));
    incoming->p = &incoming_content;
    mydata = calloc(1, sizeof(*mydata));
    mydata->allow_stale = allow_stale;
    incoming->data = mydata;
    templ = make_template(mydata, NULL);
    ccn_express_interest(ccn, name, incoming, templ);
    ccn_charbuf_destroy(&templ);
    ccn_charbuf_destroy(&name);
    /* Run a little while to see if there is anything there */
    res = ccn_run(ccn, 200);
    if (incoming->intdata == 0) {
        fprintf(stderr, "%s: not found: %s\n", argv[0], arg);
        exit(1);
    }
    /* We got something, run until end of data or somebody kills us */
    while (res >= 0) {
        fflush(stdout);
        res = ccn_run(ccn, 200);
    }
    ccn_destroy(&ccn);
    exit(res < 0);
}
예제 #20
0
static void
ask_set(struct mydata *md, char ** urlList, int flying){
	if(DEBUG)
		printf("In function askset \n ");
	
	struct ccn_charbuf * name = NULL;
	struct ccn_charbuf * templ = NULL;
	int i = 0;
	int res = -1;
	struct ccn_closure * cl = NULL;
	
/* TODO: Zipf Distribution	
	//Test the Zipf distribution
	printf("Zipf starts \n");
	for(i = 1; i < 100000; i++){
		printf("%d \n", zipf(5, 100, i));
	}
	printf("Zipfs ends\n");
*/

	int r = 0;
		
	for(r = 0; r < 1; r++){
		for(i = 0; i < flying; i++){

			cl = &(md->ooo[i].closure);
			name = ccn_charbuf_create();
		
			printf("url = %s \n", urlList[i]);
			printf("===\n");
			res = ccn_name_from_uri(name, urlList[i]);
			if(res < 0){
				printf("ccn_name_from_uri failed \n");
				abort();
			}


			ccn_name_append(name, "0", 1);
			templ = make_template(md);
			
			
			if(DEBUG){
				//Print out the interest's name
				printf("Sending Interest : ");

				int myres = 0;
				struct ccn_indexbuf* ndx = ccn_indexbuf_create();
				unsigned char* mycomp = NULL;
				size_t mysize = 0;

				ndx->n = 0;
				myres = ccn_name_split(name, ndx);
				if(myres < 0){
					fprintf(stderr, "ccn_name_split @ ccntraffic. failed");
				}

				int it = 0;
				for(it = 0; it < ndx->n-1; it++){
					mysize = 0;
					myres = ccn_name_comp_get(name->buf, ndx, it, &mycomp, &mysize);
					printf("%s/", mycomp);
					mycomp = NULL;
				}
				
				

				printf("\n");
			}
			

			res = ccn_express_interest(md->h, name, cl, templ);
			if(res < 0) abort();
		
			ccn_charbuf_destroy(&name);
		}
	}

	printf("Sent!\n");
}
예제 #21
0
enum ccn_upcall_res
incoming_content(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *templ = NULL;
    struct ccn_charbuf *temp = NULL;
    const unsigned char *ccnb = NULL;
    size_t ccnb_size = 0;
    const unsigned char *data = NULL;
    size_t data_size = 0;
    // TANG: no need to write data to stdout
    //size_t written;
    const unsigned char *ib = NULL; /* info->interest_ccnb */
    struct ccn_indexbuf *ic = NULL;
    int res;
    struct mydata *md = selfp->data;
    
    if (kind == CCN_UPCALL_FINAL) {
        if (md != NULL) {
            selfp->data = NULL;
            free(md);
            md = NULL;
        }
        return(CCN_UPCALL_RESULT_OK);
    }
    if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
        return(CCN_UPCALL_RESULT_REEXPRESS);
    if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED)
        return(CCN_UPCALL_RESULT_ERR);
    if (md == NULL)
        selfp->data = md = calloc(1, sizeof(*md));
    ccnb = info->content_ccnb;
    ccnb_size = info->pco->offset[CCN_PCO_E];
    ib = info->interest_ccnb;
    ic = info->interest_comps;
    /* XXX - must verify sig, and make sure it is LEAF content */
    res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size);
    if (res < 0) abort();
    if (data_size > CHUNK_SIZE) {
        /* For us this is spam. Give up now. */
        fprintf(stderr, "*** Segment %d found with a data size of %d."
                        " This program only works with segments of 1024 bytes."
                        " Try ccncatchunks2 instead.\n",
                        (int)selfp->intdata, (int)data_size);
        exit(1);
    }
    
    /* OK, we will accept this block. */
    //sleep(1);
    // TANG: No need to write data to stdout, skip 3 lines
    //written = fwrite(data, data_size, 1, stdout);
    //if (written != 1)
    //    exit(1);
    
    /* A short block signals EOF for us. */
    // TANG: to support data_size smaller than 1024, skip 2 lines
    //if (data_size < CHUNK_SIZE)
    //    exit(0);
    
    /* Ask for the next one */
    name = ccn_charbuf_create();
    ccn_name_init(name);
    if (ic->n < 2) abort();
    res = ccn_name_append_components(name, ib, ic->buf[0], ic->buf[ic->n - 2]);
    if (res < 0) abort();
    temp = ccn_charbuf_create();
	//printf("intdata = %d \n ", selfp->intdata);
    ccn_charbuf_putf(temp, "%d", ++(selfp->intdata));
    ccn_name_append(name, temp->buf, temp->length);
    ccn_charbuf_destroy(&temp);
	
	if(DEBUG){
		//Print out the interest's name
		printf("Interest name = ");
		
		int myres = 0;
		struct ccn_indexbuf* ndx = ccn_indexbuf_create();
		unsigned char* mycomp = NULL;
		size_t mysize = 0;
		
		ndx->n = 0;
		myres = ccn_name_split(name, ndx);
		if(myres < 0){
			fprintf(stderr, "ccn_name_split @ ccntraffic. failed");
		}
		
		int it = 0;
		for(it = 0; it < ndx->n-1; it++){
			mysize = 0;
			myres = ccn_name_comp_get(name->buf, ndx, it, &mycomp, &mysize);
			printf("%s/", mycomp);
			mycomp = NULL;
		}
		
		printf("\n");
	}
	
    templ = make_template(md);

    res = ccn_express_interest(info->h, name, selfp, templ);
    if (res < 0) abort();
    
    ccn_charbuf_destroy(&templ);
    ccn_charbuf_destroy(&name);
    
    return(CCN_UPCALL_RESULT_OK);
}
예제 #22
0
파일: ccnsendchunks.c 프로젝트: futtre/ccnx
int
main(int argc, char **argv)
{
    const char *progname = argv[0];
    struct ccn *ccn = NULL;
    struct ccn_charbuf *root = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *temp = NULL;
    struct ccn_charbuf *templ = NULL;
    struct ccn_charbuf *signed_info = NULL;
    struct ccn_charbuf *keylocator = NULL;
    struct ccn_charbuf *finalblockid = NULL;
    struct ccn_keystore *keystore = NULL;
    long expire = -1;
    long blocksize = 1024;
    int i;
    int status = 0;
    int res;
    ssize_t read_res;
    unsigned char *buf = NULL;
    struct mydata mydata = { 0 };
    struct ccn_closure in_content = {.p=&incoming_content, .data=&mydata};
    struct ccn_closure in_interest = {.p=&incoming_interest, .data=&mydata};
    while ((res = getopt(argc, argv, "hx:b:")) != -1) {
        switch (res) {
            case 'x':
                expire = atol(optarg);
                if (expire <= 0)
                    usage(progname);
                break;
	    case 'b':
	        blocksize = atol(optarg);
                break;
            default:
            case 'h':
                usage(progname);
                break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argv[0] == NULL)
        usage(progname);
    name = ccn_charbuf_create();
    res = ccn_name_from_uri(name, argv[0]);
    if (res < 0) {
        fprintf(stderr, "%s: bad ccn URI: %s\n", progname, argv[0]);
        exit(1);
    }
    if (argv[1] != NULL)
        fprintf(stderr, "%s warning: extra arguments ignored\n", progname);

    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }
    
    buf = calloc(1, blocksize);
    root = name;
    name = ccn_charbuf_create();
    temp = ccn_charbuf_create();
    templ = ccn_charbuf_create();
    signed_info = ccn_charbuf_create();
    keystore = ccn_keystore_create();
    temp->length = 0;
    ccn_charbuf_putf(temp, "%s/.ccnx/.ccnx_keystore", getenv("HOME"));
    res = ccn_keystore_init(keystore,
                            ccn_charbuf_as_string(temp),
                            "Th1s1sn0t8g00dp8ssw0rd.");
    if (res != 0) {
        printf("Failed to initialize keystore\n");
        exit(1);
    }
    
    name->length = 0;
    ccn_charbuf_append(name, root->buf, root->length);
    
    /* Set up a handler for interests */
    ccn_set_interest_filter(ccn, name, &in_interest);
    
    /* Initiate check to see whether there is already something there. */
    temp->length = 0;
    ccn_charbuf_putf(temp, "%d", 0);
    ccn_name_append(name, temp->buf, temp->length);
    templ->length = 0;
    ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
    ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
    ccn_charbuf_append_closer(templ); /* </Name> */
    ccn_charbuf_append_tt(templ, CCN_DTAG_MaxSuffixComponents, CCN_DTAG);
    ccn_charbuf_append_tt(templ, 1, CCN_UDATA);
    ccn_charbuf_append(templ, "1", 1);
    ccn_charbuf_append_closer(templ); /* </MaxSuffixComponents> */
    // XXX - use pubid
    ccn_charbuf_append_closer(templ); /* </Interest> */
    res = ccn_express_interest(ccn, name, &in_content, templ);
    if (res < 0) abort();
    
    /* Construct a key locator contining the key itself */
    keylocator = ccn_charbuf_create();
    ccn_charbuf_append_tt(keylocator, CCN_DTAG_KeyLocator, CCN_DTAG);
    ccn_charbuf_append_tt(keylocator, CCN_DTAG_Key, CCN_DTAG);
    res = ccn_append_pubkey_blob(keylocator, ccn_keystore_public_key(keystore));
    if (res < 0)
        ccn_charbuf_destroy(&keylocator);
    else {
        ccn_charbuf_append_closer(keylocator); /* </Key> */
        ccn_charbuf_append_closer(keylocator); /* </KeyLocator> */
    }
    
    for (i = 0;; i++) {
        read_res = read_full(0, buf, blocksize);
        if (read_res < 0) {
            perror("read");
            read_res = 0;
            status = 1;
        }
        signed_info->length = 0;
        if (read_res < blocksize) {
            temp->length = 0;
            ccn_charbuf_putf(temp, "%d", i);
            ccn_name_append(name, temp->buf, temp->length);
            finalblockid = ccn_charbuf_create();
            ccn_charbuf_append_tt(finalblockid, temp->length, CCN_BLOB);
            ccn_charbuf_append(finalblockid, temp->buf, temp->length);
        }
        res = ccn_signed_info_create(signed_info,
                                     /*pubkeyid*/ccn_keystore_public_key_digest(keystore),
                                     /*publisher_key_id_size*/ccn_keystore_public_key_digest_length(keystore),
                                     /*datetime*/NULL,
                                     /*type*/CCN_CONTENT_DATA,
                                     /*freshness*/ expire,
                                     finalblockid,
                                     keylocator);
        /* Put the keylocator in the first block only. */
        ccn_charbuf_destroy(&keylocator);
        if (res < 0) {
            fprintf(stderr, "Failed to create signed_info (res == %d)\n", res);
            exit(1);
        }
        name->length = 0;
        ccn_charbuf_append(name, root->buf, root->length);
        temp->length = 0;
        ccn_charbuf_putf(temp, "%d", i);
        ccn_name_append(name, temp->buf, temp->length);
        temp->length = 0;
        ccn_charbuf_append(temp, buf, read_res);
        temp->length = 0;
        res = ccn_encode_ContentObject(temp,
                                       name,
                                       signed_info,
                                       buf,
                                       read_res,
                                       NULL,
                                       ccn_keystore_private_key(keystore));
        if (res != 0) {
            fprintf(stderr, "Failed to encode ContentObject (res == %d)\n", res);
            exit(1);
        }
        if (i == 0) {
            /* Finish check for old content */
            if (mydata.content_received == 0)
                ccn_run(ccn, 100);
            if (mydata.content_received > 0) {
                fprintf(stderr, "%s: name is in use: %s\n", progname, argv[0]);
                exit(1);
            }
            mydata.outstanding++; /* the first one is free... */
        }
        res = ccn_put(ccn, temp->buf, temp->length);
        if (res < 0) {
            fprintf(stderr, "ccn_put failed (res == %d)\n", res);
            exit(1);
        }
        if (read_res < blocksize)
            break;
        if (mydata.outstanding > 0)
            mydata.outstanding--;
        else
            res = 10;
        res = ccn_run(ccn, res * 100);
        if (res < 0) {
            status = 1;
            break;
        }
    }
    
    free(buf);
    buf = NULL;
    ccn_charbuf_destroy(&root);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&finalblockid);
    ccn_keystore_destroy(&keystore);
    ccn_destroy(&ccn);
    exit(status);
}
예제 #23
0
파일: ccnls.c 프로젝트: Emat12/ccnx
enum ccn_upcall_res
incoming_content(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    struct ccn_charbuf *c = NULL;
    struct ccn_charbuf *comp = NULL;
    struct ccn_charbuf *uri = NULL;
    struct ccn_charbuf *templ = NULL;
    const unsigned char *ccnb = NULL;
    size_t ccnb_size = 0;
    struct ccn_indexbuf *comps = NULL;
    int matched_comps = 0;
    int res;
    int i;
    struct upcalldata *data = selfp->data;
    
    if (data->magic != 856372) abort();
    if (kind == CCN_UPCALL_FINAL)
        return(CCN_UPCALL_RESULT_OK);
    if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
        return(CCN_UPCALL_RESULT_REEXPRESS);
    if (kind == CCN_UPCALL_CONTENT_UNVERIFIED) {
        if ((data->option & MUST_VERIFY) != 0)
        return(CCN_UPCALL_RESULT_VERIFY);
        }
    else if (kind != CCN_UPCALL_CONTENT) abort();
    
    ccnb = info->content_ccnb;
    ccnb_size = info->pco->offset[CCN_PCO_E];
    comps = info->content_comps;
    matched_comps = info->pi->prefix_comps;
    c = ccn_charbuf_create();
    uri = ccn_charbuf_create();
    templ = ccn_charbuf_create();
    /* note that comps->n is 1 greater than the number of explicit components */
    if (matched_comps > comps->n) {
        ccn_uri_append(c, ccnb, ccnb_size, 1);
        fprintf(stderr, "How did this happen?  %s\n", ccn_charbuf_as_string(uri));
        exit(1);
    }
    data->counter[0]++;
    /* Recover the same prefix as before */
    ccn_name_init(c);
    res = ccn_name_append_components(c, info->interest_ccnb,
                                     info->interest_comps->buf[0],
                                     info->interest_comps->buf[matched_comps]);
    if (res < 0) abort();
    
    comp = ccn_charbuf_create();
    ccn_name_init(comp);
    if (matched_comps + 1 == comps->n) {
        /* Reconstruct the implicit ContentObject digest component */
        ccn_digest_ContentObject(ccnb, info->pco);
        ccn_name_append(comp, info->pco->digest, info->pco->digest_bytes);
    }
    else if (matched_comps < comps->n) {
        ccn_name_append_components(comp, ccnb,
                                   comps->buf[matched_comps],
                                   comps->buf[matched_comps + 1]);
    }
    res = ccn_uri_append(uri, comp->buf, comp->length, 0);
    if (res < 0 || uri->length < 1)
        fprintf(stderr, "*** Error: ccnls line %d res=%d\n", __LINE__, res);
    else {
        if (uri->length == 1)
            ccn_charbuf_append(uri, ".", 1);
        printf("%s%s\n", ccn_charbuf_as_string(uri) + 1,
               kind == CCN_UPCALL_CONTENT ? " [verified]" : " [unverified]");
    }
    ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
    ccn_charbuf_append(templ, c->buf, c->length); /* Name */
    if (matched_comps == comps->n) {
        /* The interest supplied the digest component */
        ccn_charbuf_destroy(&comp);
        /*
         * We can't rely on the Exclude filter to keep from seeing this, so 
         * say that we need at least one more name component.
         */
        ccn_charbuf_append_tt(templ, CCN_DTAG_MinSuffixComponents, CCN_DTAG);
        ccn_charbuf_append_tt(templ, 1, CCN_UDATA);
        ccn_charbuf_append(templ, "1", 1);
        ccn_charbuf_append_closer(templ); /* </MinSuffixComponents> */
    }
    else {
        data->excl = realloc(data->excl, (data->n_excl + 1) * sizeof(data->excl[0]));
        data->excl[data->n_excl++] = comp;
        comp = NULL;
    }
    qsort(data->excl, data->n_excl, sizeof(data->excl[0]), &namecompare);
    ccn_charbuf_append_tt(templ, CCN_DTAG_Exclude, CCN_DTAG);
    for (i = 0; i < data->n_excl; i++) {
        comp = data->excl[i];
        if (comp->length < 4) abort();
        ccn_charbuf_append(templ, comp->buf + 1, comp->length - 2);
    }
    comp = NULL;
    ccn_charbuf_append_closer(templ); /* </Exclude> */
    ccnb_tagged_putf(templ, CCN_DTAG_AnswerOriginKind, "%d", CCN_AOK_CS);
    if (data->scope > -1)
       ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", data->scope);
    ccn_charbuf_append_closer(templ); /* </Interest> */
    if (templ->length > data->warn) {
        fprintf(stderr, "*** Interest packet is %d bytes\n", (int)templ->length);
        data->warn = data->warn * 8 / 5;
    }
    ccn_express_interest(info->h, c, selfp, templ);
    ccn_charbuf_destroy(&templ);
    ccn_charbuf_destroy(&c);
    ccn_charbuf_destroy(&uri);
    return(CCN_UPCALL_RESULT_OK);
}
예제 #24
0
파일: ccnslurp.c 프로젝트: GabrielLiz/ccnx
/*
 * This upcall gets called for each piece of incoming content that
 * matches one of our interests.  We need to issue a new interest that
 * excludes another component at the current level, and perhaps also
 * and interest to start exploring the next level.  Thus if the matched
 * interest is
 *   /a/b/c exclude {d,e,f,i,j,k}
 * and we get
 *   /a/b/c/g/h
 * we would issue a new interest
 *   /a/b/c exclude {d,e,f,g,i,j,k}
 * to continue exploring the current level, plus a simple interest
 *   /a/b/c/g
 * to start exploring the next level as well.
 *
 * This does end up fetching each piece of content multiple times, once for
 * each level in the name. The repeated requests will be answered from the local
 * content store, though, and so should not generate extra network traffic.
 * There is a lot of unanswerable interest generated, though.  
 *
 * To prevent the interests from becoming too huge, we may need to split them.
 * Thus if the first new interest above were deemed too large, we could instead
 * issue the two interests
 *   /a/b/c exclude {d,e,f,g,*}
 *   /a/b/c exclude {*,g,i,j,k}
 * where * stands for a Bloom filter that excludes anything.  Note the
 * repetiton of g to ensure that these two interests cover disjoint portions
 * of the hierarchy. We need to keep track of the endpoint conditions
 * as well as the excluded set in our upcall data.
 * When a split happens, we need a new closure to track it, as we do when
 * we start exploring a new level.
 */
static enum ccn_upcall_res
incoming_content(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    struct ccn_charbuf *c = NULL;
    struct ccn_charbuf *comp = NULL;
    struct ccn_charbuf *uri = NULL;
    const unsigned char *ccnb = NULL;
    size_t ccnb_size = 0;
    struct ccn_indexbuf *comps = NULL;
    int matched_comps = 0;
    int res;
    int i;
    struct upcalldata *data = get_my_data(selfp);
    
    if (kind == CCN_UPCALL_FINAL) {
        for (i = 0; i < data->n_excl; i++)
            ccn_charbuf_destroy(&(data->excl[i]));
        if (data->excl != NULL)
            free(data->excl);
        free(data);
        free(selfp);
        return(0);
    }
    if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
        return(0);
    if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED && kind != CCN_UPCALL_CONTENT_BAD)
        abort();

    ccnb = info->content_ccnb;
    ccnb_size = info->pco->offset[CCN_PCO_E];
    comps = info->content_comps;
    matched_comps = info->pi->prefix_comps;
    c = ccn_charbuf_create();
    uri = ccn_charbuf_create();
        
    if (matched_comps + 1 > comps->n) {
        ccn_uri_append(c, ccnb, ccnb_size, 1);
        fprintf(stderr, "How did this happen?  %s\n", ccn_charbuf_as_string(uri));
        exit(1);
    }
    
    if (kind == CCN_UPCALL_CONTENT_BAD) {
        ccn_uri_append(uri, ccnb, ccnb_size, 1);
        fprintf(stderr, "*** VERIFICATION FAILURE *** %s\n", ccn_charbuf_as_string(uri));
        uri->length = 0;
    }
    
    data->counter[0]++; /* Tell main that something new came in */

    /* Recover the same prefix as before */
    ccn_name_init(c);
    ccn_name_append_components(c, ccnb, comps->buf[0], comps->buf[matched_comps]);
    
    comp = ccn_charbuf_create();
    ccn_name_init(comp);
    if (matched_comps + 1 == comps->n) {
        /* Reconstruct the implicit ContentObject digest component */
        ccn_digest_ContentObject(ccnb, info->pco);
        ccn_name_append(comp, info->pco->digest, info->pco->digest_bytes);
    }
    else {
        ccn_name_append_components(comp, ccnb,
                                   comps->buf[matched_comps],
                                   comps->buf[matched_comps + 1]);
    }
    data->excl = realloc(data->excl, (data->n_excl + 1) * sizeof(data->excl[0]));
    data->excl[data->n_excl++] = comp;
    comp = NULL;
    qsort(data->excl, data->n_excl, sizeof(data->excl[0]), &namecompare);
    res = express_my_interest(info->h, selfp, c);
    if (res == -1) {
        struct ccn_closure *high = split_my_excludes(selfp);
        if (high == NULL) abort();
        express_my_interest(info->h, selfp, c);
        express_my_interest(info->h, high, c);
    }
    /* Explore the next level, if there is one. */
    if (matched_comps + 2 < comps->n) {
        struct upcalldata *newdat = NULL;
        struct ccn_closure *cl;
        newdat = calloc(1, sizeof(*newdat));
        newdat->magic = 856372;
        newdat->warn = 1492;
        newdat->counter = data->counter;
        newdat->flags = 0;
        newdat->n_excl = 0;
        newdat->excl = NULL;
        cl = calloc(1, sizeof(*cl));
        cl->p = &incoming_content;
        cl->data = newdat;
        ccn_name_init(c);
        ccn_name_append_components(c, ccnb,
                                   comps->buf[0],
                                   comps->buf[matched_comps + 1]);
        ccn_express_interest(info->h, c, cl, passive_templ);
    }
    else {
        res = ccn_uri_append(uri, info->content_ccnb, info->pco->offset[CCN_PCO_E], 1);
        if (res < 0)
            fprintf(stderr, "*** Error: ccnslurp line %d res=%d\n", __LINE__, res);
        else
            printf("%s\n", ccn_charbuf_as_string(uri));
    }
    ccn_charbuf_destroy(&c);
    ccn_charbuf_destroy(&uri);
    return(0);
}
예제 #25
0
파일: ccnrm.c 프로젝트: GabrielLiz/ccnx
int
main(int argc, char **argv)
{
    struct ccn *ccn = NULL;
    struct ccn_charbuf *c = NULL;
    struct ccn_charbuf *templ = NULL;
    int i;
    int res;
    int opt;
    FILE* closethis = NULL;
    
    while ((opt = getopt(argc, argv, "ho:")) != -1) {
        switch (opt) {
            case 'o':
                if (strcmp(optarg, "-") == 0)
                    mydata.output = stdout;
                else
                    mydata.output = closethis = fopen(optarg, "wb");
                if (mydata.output == NULL) {
                    perror(optarg);
                    exit(1);
                }
                break;
            case 'h': /* FALLTHRU */
            default: usage(argv[0]);
        }
    }
    
    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }
    c = ccn_charbuf_create();
    /* set scope to only address ccnd, expire anything we get */
    templ = local_scope_rm_template();
    for (i = optind; argv[i] != NULL; i++) {
        c->length = 0;
        res = ccn_name_from_uri(c, argv[i]);
        if (res < 0) {
            fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], argv[i]);
            exit(1);
        }
        ccn_express_interest(ccn, c, &incoming_content_action, templ);
    }
    if (i == optind)
        usage(argv[0]);
    ccn_charbuf_destroy(&templ);
    ccn_charbuf_destroy(&c);
    for (i = 0;; i++) {
        res = mydata.nseen;
        ccn_run(ccn, 100); /* stop if we run dry for 1/10 sec */
        if (res == mydata.nseen)
            break;
    }
    if (closethis != NULL)
        fclose(closethis);
    ccn_destroy(&ccn);
    fprintf(stderr, "marked stale: %d\n", mydata.nseen);
    exit(0);
}
예제 #26
0
void GroupManager::expressEnumInterest(struct ccn_charbuf *interest, QList<QString> &toExclude) {

	if (toExclude.size() == 0) {
		mutex_trylock();	
		int res = ccn_express_interest(ccn, interest, join_closure, NULL);
		mutex_unlock();
		if (res < 0) {
			critical("express interest failed!");
		}
		ccn_charbuf_destroy(&interest);
		return;
	}

	struct ccn_charbuf **excl = NULL;
	if (toExclude.size() > 0) {
		excl = new ccn_charbuf *[toExclude.size()];
		for (int i = 0; i < toExclude.size(); i ++) {
			QString compName = toExclude.at(i);
			struct ccn_charbuf *comp = ccn_charbuf_create();
			ccn_name_init(comp);
			ccn_name_append_str(comp, compName.toStdString().c_str());
			excl[i] = comp;
			comp = NULL;
		}
		qsort(excl, toExclude.size(), sizeof(excl[0]), &namecompare);
	}

	int begin = 0;
	bool excludeLow = false;
	bool excludeHigh = true;
	while (begin < toExclude.size()) {
		if (begin != 0) {
			excludeLow = true;
		}
		struct ccn_charbuf *templ = ccn_charbuf_create();
		ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG); // <Interest>
		ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG); // <Name>
		ccn_charbuf_append_closer(templ); // </Name> 
		ccn_charbuf_append_tt(templ, CCN_DTAG_Exclude, CCN_DTAG); // <Exclude>
		if (excludeLow) {
			append_bf_all(templ);
		}
		for (; begin < toExclude.size(); begin++) {
			struct ccn_charbuf *comp = excl[begin];
			if (comp->length < 4) abort();
			// we are being conservative here
			if (interest->length + templ->length + comp->length > 1350) {
				break;
			}
			ccn_charbuf_append(templ, comp->buf + 1, comp->length - 2);
		}
		if (begin == toExclude.size()) {
			excludeHigh = false;
		}
		if (excludeHigh) {
			append_bf_all(templ);
		}
		ccn_charbuf_append_closer(templ); // </Exclude>

		ccn_charbuf_append_closer(templ); // </Interest> 
		mutex_trylock();	
		int res = ccn_express_interest(ccn, interest, join_closure, templ);
		mutex_unlock();
		if (res < 0) {
			critical("express interest failed!");
		}
		ccn_charbuf_destroy(&templ);
	}
	ccn_charbuf_destroy(&interest);
	for (int i = 0; i < toExclude.size(); i++) {
		ccn_charbuf_destroy(&excl[i]);
	}
	if (excl != NULL) {
		delete []excl;
	}
}
예제 #27
0
파일: ccnsimplecat.c 프로젝트: Emat12/ccnx
/**
 * Handle the incoming content messages. Extracts the data, and
 * requests the next block in sequence if the received block was
 * not the final one.
 */
enum ccn_upcall_res
incoming_content(struct ccn_closure *selfp,
                 enum ccn_upcall_kind kind,
                 struct ccn_upcall_info *info)
{
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *templ = NULL;
    const unsigned char *ccnb = NULL;
    size_t ccnb_size = 0;
    const unsigned char *data = NULL;
    size_t data_size = 0;
    size_t written;
    const unsigned char *ib = NULL; /* info->interest_ccnb */
    struct ccn_indexbuf *ic = NULL;
    int res;
    struct mydata *md = selfp->data;
    
    if (kind == CCN_UPCALL_FINAL) {
        if (md != NULL) {
            selfp->data = NULL;
            free(md);
            md = NULL;
        }
        return(CCN_UPCALL_RESULT_OK);
    }
    if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
        return(CCN_UPCALL_RESULT_REEXPRESS);
    if (kind == CCN_UPCALL_CONTENT_UNVERIFIED)
        return(CCN_UPCALL_RESULT_VERIFY);
    if (kind != CCN_UPCALL_CONTENT)
        return(CCN_UPCALL_RESULT_ERR);
    if (md == NULL)
        selfp->data = md = calloc(1, sizeof(*md));
    ccnb = info->content_ccnb;
    ccnb_size = info->pco->offset[CCN_PCO_E];
    ib = info->interest_ccnb;
    ic = info->interest_comps;
    res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size);
    if (res < 0) abort();
    if (info->pco->type != CCN_CONTENT_DATA) {
        /* For us this is spam. For now, give up. */
        fprintf(stderr, "*** spammed at block %d\n", (int)selfp->intdata);
        exit(1);
    }
    
    /* OK, we will accept this block. */
    if (data_size == 0)
        *(md->done) = 1;
    else {
        written = fwrite(data, data_size, 1, stdout);
        if (written != 1)
            exit(1);
    }
    // XXX The test below should get refactored into the library
    if (info->pco->offset[CCN_PCO_B_FinalBlockID] !=
        info->pco->offset[CCN_PCO_E_FinalBlockID]) {
        const unsigned char *finalid = NULL;
        size_t finalid_size = 0;
        const unsigned char *nameid = NULL;
        size_t nameid_size = 0;
        struct ccn_indexbuf *cc = info->content_comps;
        ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb,
                            info->pco->offset[CCN_PCO_B_FinalBlockID],
                            info->pco->offset[CCN_PCO_E_FinalBlockID],
                            &finalid,
                            &finalid_size);
        if (cc->n < 2) abort();
        ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb,
                            cc->buf[cc->n - 2],
                            cc->buf[cc->n - 1],
                            &nameid,
                            &nameid_size);
        if (finalid_size == nameid_size &&
              0 == memcmp(finalid, nameid, nameid_size))
            *(md->done) = 1;
    }
    
    if (*(md->done)) {
        ccn_set_run_timeout(info->h, 0);
        return(CCN_UPCALL_RESULT_OK);
    }
    
    /* Ask for the next fragment */
    name = ccn_charbuf_create();
    ccn_name_init(name);
    if (ic->n < 2) abort();
    res = ccn_name_append_components(name, ib, ic->buf[0], ic->buf[ic->n - 2]);
    if (res < 0) abort();
    ccn_name_append_numeric(name, CCN_MARKER_SEQNUM, ++(selfp->intdata));
    templ = make_template(md, info);
    
    res = ccn_express_interest(info->h, name, selfp, templ);
    if (res < 0) abort();
    
    ccn_charbuf_destroy(&templ);
    ccn_charbuf_destroy(&name);
    
    return(CCN_UPCALL_RESULT_OK);
}
예제 #28
0
int main(int argc, char** argv) {
	int res = 0;
	struct ccn* ccn_pub;
	struct ccn* ccn_rec;

	// Will hold the public/private key used for signing
	struct ccn_pkey* public_key = NULL;
	struct ccn_pkey* private_key = NULL;

	int complete=0;
	int outstanding_interests=0;

	// We need two ccn handles because the same handle cannot be used
	// to answer interests it issues.
	//
	ccn_pub = ccn_create();
    if (ccn_connect(ccn_pub, NULL) == -1) {
        fprintf(stderr, "Could not connect to ccnd");
        return(1);
    }
    ccn_rec = ccn_create();
    if (ccn_connect(ccn_rec, NULL) == -1) {
        fprintf(stderr, "Could not connect to ccnd");
        return(1);
    }

    // Closure to handle upcalls
    struct ccn_closure *cl = NULL;
    cl = (struct ccn_closure*) calloc(1, sizeof(struct ccn_closure));
    cl->p = &packet_handler;
    handler_data h_data = { &complete, &outstanding_interests, &public_key, &ccn_pub, &ccn_rec};
    cl->data = &h_data;

    // Setup our one test name without signature
    // The nonce here is just a random string, to avoid content store caching
    struct ccn_charbuf* name;
    name = ccn_charbuf_create();
    ccn_name_from_uri(name, TEST_URI);
    ccn_name_append_nonce(name);
    fprintf(stderr, "Our name: %s/<nonce>\n", TEST_URI);

    // Set up a filter for interests in that name
    res = ccn_set_interest_filter(ccn_pub, name, cl);
    if (res < 0) {
        fprintf(stderr, "Failed to register interest (res == %d)\n", res);
        return(1);
    }

    // Get our default keys -- Why do we have to do all this work??
    // Borrowed from ccn_client.c
    struct ccn_signing_params name_sp = CCN_SIGNING_PARAMS_INIT;
    struct ccn_signing_params p = CCN_SIGNING_PARAMS_INIT;
    struct ccn_keystore *keystore = NULL;
    struct ccn_charbuf *timestamp = NULL;
    struct ccn_charbuf *finalblockid = NULL;
    struct ccn_charbuf *keylocator = NULL;
    unsigned char* public_key_digest = NULL;
    size_t public_key_digest_length = 0;
    res = ccn_chk_signing_params(ccn_pub, &name_sp, &p, &timestamp, &finalblockid, &keylocator);
    if (res < 0)
        return(res);

    // For this test, use our default signing keys
    get_default_keys(ccn_pub, &p, &keystore,
    		&public_key, &public_key_digest, &public_key_digest_length, &private_key);

    // We'll need  a KeyLocator for our ContentObject
	// So continue borrowed code
	/* Construct a key locator containing the key itself */
    build_keylocator_from_key(&keylocator, public_key);

    // And a SignedInfo too
    struct ccn_charbuf *signed_info = ccn_charbuf_create();
    res = ccn_signed_info_create(signed_info,
    		 public_key_digest,
    		 public_key_digest_length,
			 timestamp,
			 p.type,
			 p.freshness,
			 0,  /* FinalBlockID is optional */
			 keylocator);

    // * Test using interests for a name that has one more component than our registered prefix
    // This is more representative of real apps...
    // 20-May-2011
    ccn_name_append_str(name, "some stuff in a name component");
    ccn_name_append_nonce(name);
    ccn_name_append_nonce(name);

    // Sign the interest
    struct ccn_charbuf *name_signed = ccn_charbuf_create();
    sign_interest(name_signed, name, signed_info, NULL /* default digest alg */, private_key);

    // Express the signed interest from a different ccn handle so we get the packet
    res = ccn_express_interest(ccn_rec, name_signed, cl, NULL);			// TODO: AnswerOriginKind could limit to signed interest?
    outstanding_interests++;

    // Express an interest with an incorrect namespace
    struct ccn_charbuf *name_signed_copy = ccn_charbuf_create();
    ccn_charbuf_append_charbuf(name_signed_copy, name_signed);
    size_t k = name->length + 10; // Seek into the namespace part of the buffer
    name_signed_copy->buf[k] = name_signed_copy->buf[k] + 1;
    res = ccn_express_interest(ccn_rec, name_signed_copy, cl, NULL);			// TODO: AnswerOriginKind could limit to signed interest?
    outstanding_interests++;

    // Express an interest with bogus signature
    name_signed_copy = ccn_charbuf_create();
    ccn_charbuf_append_charbuf(name_signed_copy, name_signed);
    k = name->length + 30;  // Seek into the signature part of the buffer
    name_signed_copy->buf[k] = name_signed_copy->buf[k] + 1;
    res = ccn_express_interest(ccn_rec, name_signed_copy, cl, NULL);			// TODO: AnswerOriginKind could limit to signed interest?
    outstanding_interests++;

    if (res < 0) {
    	fprintf(stderr, "Error expressing interest (res == %d)\n", res);
    }
    cl = NULL;  						// freed by ccn?

    while(!complete && outstanding_interests>0) {
    	// Not sure how to handle two ccn_runs?
        ccn_run(ccn_rec, 100); /* stop if we run dry for .1 sec */
        ccn_run(ccn_pub, 100); /* stop if we run dry for .1 sec */
        fflush(stdout);
    }

    ccn_charbuf_destroy(&timestamp);
    ccn_charbuf_destroy(&keylocator);
    ccn_charbuf_destroy(&finalblockid);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&name_signed);
    ccn_charbuf_destroy(&name_signed_copy);
    ccn_destroy(&ccn_pub);
    ccn_destroy(&ccn_rec);
    fflush(stderr);
	return(0);
}
예제 #29
0
파일: ccnslurp.c 프로젝트: GabrielLiz/ccnx
int
main(int argc, char **argv)
{
    const char *progname = argv[0];
    struct ccn *ccn = NULL;
    struct ccn_charbuf *c = NULL;
    struct upcalldata *data = NULL;
    int opt;
    int i;
    long n;
    int res;
    long counter = 0;
    struct ccn_closure *cl = NULL;
    
    while ((opt = getopt(argc, argv, "h")) != -1) {
        switch (opt) {
            case 'h':
            default:
                usage(argv[0]);
        }
    }

    if (argv[optind] == NULL || argv[optind + 1] != NULL)
        usage(argv[0]);

    passive_templ = create_passive_templ();
    c = ccn_charbuf_create();
    res = ccn_name_from_uri(c, argv[optind]);
    if (res < 0) {
        fprintf(stderr, "%s: bad ccn URI: %s\n", progname, argv[optind]);
        exit(1);
    }
        
    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }
    
    data = calloc(1, sizeof(*data));
    data->magic = 856372;
    data->warn = 1492;
    data->counter = &counter;
    cl = calloc(1, sizeof(*cl));
    cl->p = &incoming_content;
    cl->data = data;
    ccn_express_interest(ccn, c, cl, passive_templ);
    cl = NULL;
    data = NULL;
    ccn_charbuf_destroy(&c);
    for (i = 0;; i++) {
        n = counter;
        ccn_run(ccn, 1000); /* stop if we run dry for 1 sec */
        fflush(stdout);
        if (counter == n)
            break;
    }
    ccn_destroy(&ccn);
    ccn_charbuf_destroy(&passive_templ);
    exit(0);
}
예제 #30
0
enum ccn_upcall_res
ccn_text_handler(struct ccn_closure *selfp,
		    enum ccn_upcall_kind kind,
		    struct ccn_upcall_info *info)
{
    UserDataBuf *userBuf  = (UserDataBuf *)selfp->data;
    if (userBuf == NULL || userBuf->iNeedDestroy) {
        //if (userBuf != NULL) delete userBuf;
        //selfp->data = NULL;
        return CCN_UPCALL_RESULT_OK;
    }

	switch (kind) {
	case CCN_UPCALL_INTEREST_TIMED_OUT: {
		// if it's short Interest without seq, reexpress
		// TODO: check whether the user is still in the conference
		//	     don't re-express if it is not
		return (CCN_UPCALL_RESULT_REEXPRESS);
	}
	case CCN_UPCALL_CONTENT_UNVERIFIED:
		fprintf(stderr, "unverified content received\n");
		return CCN_UPCALL_RESULT_OK;
	case CCN_UPCALL_FINAL:
        return CCN_UPCALL_RESULT_OK;
	case CCN_UPCALL_CONTENT:
		break;
	default:
		return CCN_UPCALL_RESULT_OK;

	}

    struct data_buffer *buffer = &userBuf->data_buf;
    const unsigned char *content_value;
	size_t len;
    NDNState *state = buffer->state;

	const unsigned char *ccnb = info->content_ccnb;
	size_t ccnb_size = info->pco->offset[CCN_PCO_E];
	struct ccn_indexbuf *comps = info->content_comps;

	ccn_content_get_value(ccnb, ccnb_size, info->pco,
			&content_value, &len);

	unsigned char *msg = (unsigned char *)calloc((len + 1), sizeof(char));
	memcpy(msg, content_value, len);
	msg[len] = '\0';
	QString textMsg = (const char *)msg;
	state->emitTextMsgArrival(userBuf->user_name, textMsg);
	free(msg);

	long seq;
	const unsigned char *seqptr = NULL;
	char *endptr = NULL;
	size_t seq_size = 0;
	int k = comps->n - 2;

	seq = ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb,
			comps->buf[k], comps->buf[k + 1],
			&seqptr, &seq_size);
	if (seq >= 0) {
		seq = strtol((const char *)seqptr, &endptr, 10);
		if (endptr != ((const char *)seqptr) + seq_size)
			seq = -1;
	}
	if (seq < 0) {
		return CCN_UPCALL_RESULT_OK;
	}

	seq++;

	struct ccn_charbuf *path = ccn_charbuf_create();
	ccn_name_init(path);
	ccn_name_append_components(path, ccnb, comps->buf[0], comps->buf[k]);
	struct ccn_charbuf *temp = ccn_charbuf_create();
	ccn_charbuf_putf(temp, "%ld", seq);
	ccn_name_append(path, temp->buf, temp->length);
	int res = ccn_express_interest(info->h, path, selfp, NULL);
	if (res < 0) {
		fprintf(stderr, "sending the first interest failed\n");
		exit(1);
	}
	ccn_charbuf_destroy(&path);
	ccn_charbuf_destroy(&temp);

    return CCN_UPCALL_RESULT_OK;
}