Пример #1
0
int main(int argc, char *argv[])
{
    const char *progname = argv[0];
    struct ccn_ping_client client = {.sent = 0, .received = 0, .total = -1, .number = -1, .interval = 1};
    struct ccn_closure in_content = {.p = &incoming_content};
    struct hashtb_param param = {0};
    int res;

    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = &handle_interrupt;
    sigaction(SIGINT, &sa, &osa);

    memset(&sta, 0, sizeof(sta));
    gettimeofday(&sta.start, 0);
    sta.min = INT_MAX;

    while ((res = getopt(argc, argv, "hi:c:n:")) != -1) {
        switch (res) {
            case 'c':
                client.total = atol(optarg);
                if (client.total <= 0)
                    usage(progname);
                break;
            case 'i':
                client.interval = atof(optarg);
                if (client.interval < PING_MIN_INTERVAL)
                    usage(progname);
                break;
            case 'n':
                client.number = atol(optarg);
                if (client.number < 0)
                    usage(progname);
                break;
            case 'h':
            default:
                usage(progname);
                break;
        }
    }

    if (client.number < 0)
        srandom(time(NULL));

    argc -= optind;
    argv += optind;

    if (argv[0] == NULL)
        usage(progname);

    sta.prefix = argv[0];

    client.original_prefix = argv[0];
    client.prefix = ccn_charbuf_create();
    res = ccn_name_from_uri(client.prefix, 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);

    //append "/ping" to the given name prefix
    res = ccn_name_append_str(client.prefix, PING_COMPONENT);
    if (res < 0) {
        fprintf(stderr, "%s: error constructing ccn URI: %s/%s\n", progname, argv[0], PING_COMPONENT);
        exit(1);
    }

    /* Connect to ccnd */
    client.h = ccn_create();
    if (ccn_connect(client.h, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }

    client.closure = &in_content;
    in_content.data = &client;

    client.ccn_ping_table = hashtb_create(sizeof(struct ccn_ping_entry), &param);

    client.sched = ccn_schedule_create(&client, &ccn_ping_ticker);
    client.event = ccn_schedule_event(client.sched, 0, &do_ping, NULL, 0);

    printf("CCNPING %s\n", client.original_prefix);

    res = 0;

    while (res >= 0 && (client.total <= 0 || client.sent < client.total || hashtb_n(client.ccn_ping_table) > 0))
    {
        if (client.total <= 0 || client.sent < client.total)
            ccn_schedule_run(client.sched);
        res = ccn_run(client.h, 10);
    }

    ccn_schedule_destroy(&client.sched);
    ccn_destroy(&client.h);
    ccn_charbuf_destroy(&client.prefix);

    print_statistics();

    return 0;
}
Пример #2
0
/**
 * Create a new ccnr instance
 * @param progname - name of program binary, used for locating helpers
 * @param logger - logger function
 * @param loggerdata - data to pass to logger function
 */
PUBLIC struct ccnr_handle *
r_init_create(const char *progname, ccnr_logger logger, void *loggerdata)
{
    char *sockname = NULL;
    const char *portstr = NULL;
    const char *listen_on = NULL;
    const char *d = NULL;
    struct ccnr_handle *h = NULL;
    struct hashtb_param param = {0};
    struct ccn_charbuf *config = NULL;
    int res;
    
    h = calloc(1, sizeof(*h));
    if (h == NULL)
        return(h);
    h->notify_after = 0; //CCNR_MAX_ACCESSION;
    h->logger = logger;
    h->loggerdata = loggerdata;
    h->logpid = (int)getpid();
    h->progname = progname;
    h->debug = -1;
    config = r_init_read_config(h);
    if (config == NULL)
        goto Bail;
    r_init_parse_config(h, config, 0); /* silent pass to pick up CCNR_DEBUG */
    h->debug = 1; /* so that we see any complaints */
    h->debug = r_init_debug_getenv(h, "CCNR_DEBUG");
    res = r_init_parse_config(h, config, 1);
    if (res < 0) {
        h->running = -1;
        goto Bail;
    }
    r_init_parse_config(h, config, 2);
    sockname = r_net_get_local_sockname();
    h->skiplinks = ccn_indexbuf_create();
    h->face_limit = 10; /* soft limit */
    h->fdholder_by_fd = calloc(h->face_limit, sizeof(h->fdholder_by_fd[0]));
    param.finalize_data = h;
    param.finalize = &r_fwd_finalize_nameprefix;
    h->nameprefix_tab = hashtb_create(sizeof(struct nameprefix_entry), &param);
    param.finalize = 0; // PRUNED &r_fwd_finalize_propagating;
    h->propagating_tab = hashtb_create(sizeof(struct propagating_entry), &param);
    param.finalize = &r_proto_finalize_enum_state;
    h->enum_state_tab = hashtb_create(sizeof(struct enum_state), &param);
    h->min_stale = ~0;
    h->max_stale = 0;
    h->unsol = ccn_indexbuf_create();
    h->ticktock.descr[0] = 'C';
    h->ticktock.micros_per_base = 1000000;
    h->ticktock.gettime = &r_util_gettime;
    h->ticktock.data = h;
    h->sched = ccn_schedule_create(h, &h->ticktock);
    h->starttime = h->sec;
    h->starttime_usec = h->usec;
    h->oldformatcontentgrumble = 1;
    h->oldformatinterestgrumble = 1;
    h->cob_limit = 4201;
    h->start_write_scope_limit = r_init_confval(h, "CCNR_START_WRITE_SCOPE_LIMIT", 0, 3, 3);
    h->debug = 1; /* so that we see any complaints */
    h->debug = r_init_debug_getenv(h, "CCNR_DEBUG");
    h->syncdebug = r_init_debug_getenv(h, "CCNS_DEBUG");
    portstr = getenv("CCNR_STATUS_PORT");
    if (portstr == NULL || portstr[0] == 0 || strlen(portstr) > 10)
        portstr = "";
    h->portstr = portstr;
    ccnr_msg(h, "CCNR_DEBUG=%d CCNR_DIRECTORY=%s CCNR_STATUS_PORT=%s", h->debug, h->directory, h->portstr);
    listen_on = getenv("CCNR_LISTEN_ON");
    if (listen_on != NULL && listen_on[0] != 0)
        ccnr_msg(h, "CCNR_LISTEN_ON=%s", listen_on);
    
    if (ccnr_init_repo_keystore(h, NULL) < 0) {
        h->running = -1;
        goto Bail;
    }
    r_util_reseed(h);
    r_store_init(h);
    if (h->running == -1) goto Bail;
    while (h->active_in_fd >= 0) {
        r_dispatch_process_input(h, h->active_in_fd);
        r_store_trim(h, h->cob_limit);
        ccn_schedule_run(h->sched);
    }
    ccnr_msg(h, "Repository file is indexed");
    if (h->face0 == NULL) {
        struct fdholder *fdholder;
        fdholder = calloc(1, sizeof(*fdholder));
        if (dup2(open("/dev/null", O_RDONLY), 0) == -1)
            ccnr_msg(h, "stdin: %s", strerror(errno));
        fdholder->filedesc = 0;
        fdholder->flags = (CCNR_FACE_GG | CCNR_FACE_NORECV);
        r_io_enroll_face(h, fdholder);
    }
    ccnr_direct_client_start(h);
    d = getenv("CCNR_SKIP_VERIFY");
#if (CCN_API_VERSION >= 4004)
    if (d != NULL && strcmp(d, "1") == 0) {
        ccnr_msg(h, "CCNR_SKIP_VERIFY=%s", d);
        ccn_defer_verification(h->direct_client, 1);
    }
#endif
    if (ccn_connect(h->direct_client, NULL) != -1) {
        int af = 0;
        int bufsize;
        int flags;
        int fd;
        struct fdholder *fdholder;

        fd = ccn_get_connection_fd(h->direct_client);
        // Play a dirty trick here - if this wins, we can fix it right in the c lib later on...
        af = try_tcp_instead(fd);  
        flags = CCNR_FACE_CCND;
        if (af == AF_INET)
            flags |= CCNR_FACE_INET;
        else if (af == AF_INET6)
            flags |= CCNR_FACE_INET6;
        else
            flags |= CCNR_FACE_LOCAL;
        fdholder = r_io_record_fd(h, fd, "CCND", 5, flags);
        if (fdholder == NULL) abort();
        ccnr_uri_listen(h, h->direct_client, "ccnx:/%C1.M.S.localhost/%C1.M.SRV/repository",
                        &ccnr_answer_req, OP_SERVICE);
        ccnr_uri_listen(h, h->direct_client, "ccnx:/%C1.M.S.neighborhood/%C1.M.SRV/repository",
                        &ccnr_answer_req, OP_SERVICE);
        bufsize = r_init_confval(h, "CCNR_MIN_SEND_BUFSIZE", 1, 2097152, 16384);
        establish_min_send_bufsize(h, fd, bufsize);
    }
    else
        ccn_disconnect(h->direct_client); // Apparently ccn_connect error case needs work.
    if (1 == r_init_confval(h, "CCNS_ENABLE", 0, 1, 1)) {
        h->sync_plumbing = calloc(1, sizeof(struct sync_plumbing));
        h->sync_plumbing->ccn = h->direct_client;
        h->sync_plumbing->sched = h->sched;
        h->sync_plumbing->client_methods = &sync_client_methods;
        h->sync_plumbing->client_data = h;
        h->sync_base = SyncNewBaseForActions(h->sync_plumbing);
    }
    if (-1 == load_policy(h))
        goto Bail;
    r_net_listen_on(h, listen_on);
    ccnr_internal_client_start(h);
    r_proto_init(h);
    r_proto_activate_policy(h, h->parsed_policy);
    if (merge_files(h) == -1)
        r_init_fail(h, __LINE__, "Unable to merge additional repository data files.", errno);
    if (h->running == -1) goto Bail;
    if (h->sync_plumbing) {
        // Start sync running
        // returns < 0 if a failure occurred
        // returns 0 if the name updates should fully restart
        // returns > 0 if the name updates should restart at last fence
        res = h->sync_plumbing->sync_methods->sync_start(h->sync_plumbing, NULL);
        if (res < 0) {
            r_init_fail(h, __LINE__, "starting sync", res);
            abort();
        }
        else if (res > 0) {
            // XXX: need to work out details of starting from last fence.
            // By examination of code, SyncActions won't take this path
        }
    }
Bail:
    if (sockname)
        free(sockname);
    sockname = NULL;
    ccn_charbuf_destroy(&config);
    if (h->running == -1)
        r_init_destroy(&h);
    return(h);
}