Пример #1
0
struct ccn_forwarding_entry *
parse_ccn_forwarding_entry(struct ccndc_data *self,
                           const char *cmd_uri,
                           const char *cmd_flags,
                           int freshness)
{
    int res = 0;
    struct ccn_forwarding_entry *entry;
    
    entry= calloc(1, sizeof(*entry));
    if (entry == NULL) {
        ccndc_warn(__LINE__, "Fatal error: memory allocation failed");
        goto ExitOnError;
    }
    
    entry->name_prefix = ccn_charbuf_create();
    if (entry->name_prefix == NULL) {
        ccndc_warn(__LINE__, "Fatal error: memory allocation failed");
        goto ExitOnError;
    }
    
    // copy static info
    entry->ccnd_id = (const unsigned char *)self->ccnd_id;
    entry->ccnd_id_size = self->ccnd_id_size;
    
    /* we will be creating the face to either add/delete a prefix on it */
    if (cmd_uri == NULL) {
        ccndc_warn(__LINE__, "command erro, missing CCNx URI\n");
        goto ExitOnError;
    }
    
    res = ccn_name_from_uri(entry->name_prefix, cmd_uri);
    if (res < 0) {
        ccndc_warn(__LINE__, "command error, bad CCNx URI '%s'\n", cmd_uri);
        goto ExitOnError;
    }
    
    entry->flags = -1;
    if (cmd_flags != NULL && cmd_flags[0] != 0) {
        char *endptr;
        entry->flags = strtol(cmd_flags, &endptr, 10);
        if ((endptr != &cmd_flags[strlen(cmd_flags)]) ||
            (entry->flags & ~CCN_FORW_PUBMASK) != 0) {
            ccndc_warn(__LINE__, "command error, invalid flags %s\n", cmd_flags);
            goto ExitOnError;
        }
    }
    
    entry->lifetime = freshness;
    return (entry);
    
ExitOnError:
    ccn_forwarding_entry_destroy(&entry);
    return (NULL);
}
Пример #2
0
enum ccn_upcall_res CcnLAC_fetchFaceidCb(struct ccn_closure* selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info* info) {
	CcnLAC self = (CcnLAC)selfp->data;
	switch (kind) {
		case CCN_UPCALL_FINAL: {
			free(selfp);
			return CCN_UPCALL_RESULT_OK;
		}
		case CCN_UPCALL_INTEREST_TIMED_OUT: {
			return CCN_UPCALL_RESULT_REEXPRESS;
		}
		case CCN_UPCALL_CONTENT_UNVERIFIED:
		case CCN_UPCALL_CONTENT_KEYMISSING:
		case CCN_UPCALL_CONTENT_RAW:
		case CCN_UPCALL_CONTENT: {
			struct ccn_forwarding_entry* fe = NULL;
			const unsigned char* fe_ccnb = NULL;
			size_t fe_ccnb_size = 0;
			int res = ccn_content_get_value(info->content_ccnb, info->pco->offset[CCN_PCO_E], info->pco, &fe_ccnb, &fe_ccnb_size);
			if (res == 0) fe = ccn_forwarding_entry_parse(fe_ccnb, fe_ccnb_size);
			if (fe != NULL) {
				self->faceid = fe->faceid;
				ccn_forwarding_entry_destroy(&fe);
			} else {
				self->error = true;
			}
			PollMgr_detach(self->pm, ccn_get_connection_fd(self->ccnh), &CcnLAC_initPollCb, self);
			void* emptyPDU = malloc(CCN_EMPTY_PDU_LENGTH);
			memcpy(emptyPDU, CCN_EMPTY_PDU, CCN_EMPTY_PDU_LENGTH);
			NBS_write(self->nbs, emptyPDU, 0, CCN_EMPTY_PDU_LENGTH, NULL);
			NBS_pollAttach(self->nbs, self->pm);
			return CCN_UPCALL_RESULT_OK;
		}
		default: {
			return CCN_UPCALL_RESULT_ERR;
		}
	}
}
Пример #3
0
// creates a full structure without action, if proto == "face" only the
// faceid (from cmd_host parameter) and lifetime will be filled in.
struct ccn_face_instance *
parse_ccn_face_instance(struct ccndc_data *self,
                        const char *cmd_proto,
                        const char *cmd_host,     const char *cmd_port,
                        const char *cmd_mcastttl, const char *cmd_mcastif,
                        int freshness)
{
    struct ccn_face_instance *entry;
    struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_flags = (AI_ADDRCONFIG)};
    struct addrinfo mcasthints = {.ai_family = AF_UNSPEC, .ai_flags = (AI_ADDRCONFIG | AI_NUMERICHOST)};
    struct addrinfo *raddrinfo = NULL;
    struct addrinfo *mcastifaddrinfo = NULL;
    char rhostnamebuf [NI_MAXHOST];
    char rhostportbuf [NI_MAXSERV];
    int off_address = -1, off_port = -1, off_source_address = -1;
    int res;
    int socktype;
    
    entry = calloc(1, sizeof(*entry));
    if (entry == NULL) {
        ccndc_warn(__LINE__, "Fatal error: memory allocation failed");
        goto ExitOnError;
    }
    // allocate storage for Face data
    entry->store = ccn_charbuf_create();
    if (entry->store == NULL) {
        ccndc_warn(__LINE__, "Fatal error: memory allocation failed");
        goto ExitOnError;
    }
    // copy static info
    entry->ccnd_id = (const unsigned char *)self->ccnd_id;
    entry->ccnd_id_size = self->ccnd_id_size;
    
    if (cmd_proto == NULL) {
        ccndc_warn(__LINE__, "command error, missing address type\n");
        goto ExitOnError;
    }
    if (strcasecmp(cmd_proto, "udp") == 0) {
        entry->descr.ipproto = IPPROTO_UDP;
        socktype = SOCK_DGRAM;
    } else if (strcasecmp(cmd_proto, "tcp") == 0) {
        entry->descr.ipproto = IPPROTO_TCP;
        socktype = SOCK_STREAM;
    } else if (strcasecmp(cmd_proto, "face") == 0) {
        errno = 0;
        unsigned long faceid = strtoul(cmd_host, (char **)NULL, 10);
        if (errno == ERANGE || errno == EINVAL || faceid > UINT_MAX || faceid == 0) {
            ccndc_warn(__LINE__, "command error, face number invalid or out of range '%s'\n", cmd_host);
            goto ExitOnError;
        }
        entry->faceid = (unsigned) faceid;
        entry->lifetime = freshness;
        return (entry);
    } else {
        ccndc_warn(__LINE__, "command error, unrecognized address type '%s'\n", cmd_proto);
        goto ExitOnError;
    }
    
    if (cmd_host == NULL) {
        ccndc_warn(__LINE__, "command error, missing hostname\n");
        goto ExitOnError;
    }
    
    if (cmd_port == NULL || cmd_port[0] == 0)
        cmd_port = CCN_DEFAULT_UNICAST_PORT;
    
    hints.ai_socktype = socktype;
    res = getaddrinfo(cmd_host, cmd_port, &hints, &raddrinfo);
    if (res != 0 || raddrinfo == NULL) {
        ccndc_warn(__LINE__, "command error, getaddrinfo for host [%s] port [%s]: %s\n", cmd_host, cmd_port, gai_strerror(res));
        goto ExitOnError;
    }
    res = getnameinfo(raddrinfo->ai_addr, raddrinfo->ai_addrlen,
                      rhostnamebuf, sizeof(rhostnamebuf),
                      rhostportbuf, sizeof(rhostportbuf),
                      NI_NUMERICHOST | NI_NUMERICSERV);
    freeaddrinfo(raddrinfo);
    if (res != 0) {
        ccndc_warn(__LINE__, "command error, getnameinfo: %s\n", gai_strerror(res));
        goto ExitOnError;
    }
    
    off_address = entry->store->length;
    res = ccn_charbuf_append(entry->store, rhostnamebuf, strlen(rhostnamebuf)+1);
    if (res != 0) {
        ccndc_warn(__LINE__, "Cannot append to charbuf");
        goto ExitOnError;
    }
    
    off_port = entry->store->length;
    res = ccn_charbuf_append(entry->store, rhostportbuf, strlen(rhostportbuf)+1);
    if (res != 0) {
        ccndc_warn(__LINE__, "Cannot append to charbuf");
        goto ExitOnError;
    }
    
    entry->descr.mcast_ttl = -1;
    if (cmd_mcastttl != NULL) {
        char *endptr;
        entry->descr.mcast_ttl = strtol(cmd_mcastttl, &endptr, 10); 
        if ((endptr != &cmd_mcastttl[strlen(cmd_mcastttl)]) ||
            entry->descr.mcast_ttl < 0 || entry->descr.mcast_ttl > 255) {
            ccndc_warn(__LINE__, "command error, invalid multicast ttl: %s\n", cmd_mcastttl);
            goto ExitOnError;
        }
    }
    
    if (cmd_mcastif != NULL) {
        res = getaddrinfo(cmd_mcastif, NULL, &mcasthints, &mcastifaddrinfo);
        if (res != 0) {
            ccndc_warn(__LINE__, "command error, incorrect multicat interface [%s]: "
                       "mcastifaddr getaddrinfo: %s\n", cmd_mcastif, gai_strerror(res));
            goto ExitOnError;
        }
        
        res = getnameinfo(mcastifaddrinfo->ai_addr, mcastifaddrinfo->ai_addrlen,
                          rhostnamebuf, sizeof(rhostnamebuf),
                          NULL, 0,
                          NI_NUMERICHOST | NI_NUMERICSERV);
        freeaddrinfo(mcastifaddrinfo);
        if (res != 0) {
            ccndc_warn(__LINE__, "command error, getnameinfo: %s\n", gai_strerror(res));
            goto ExitOnError;
        }
        
        off_source_address = entry->store->length;
        res = ccn_charbuf_append(entry->store, rhostnamebuf, strlen(rhostnamebuf)+1);
        if (res != 0) {
            ccndc_warn(__LINE__, "Cannot append to charbuf");
            goto ExitOnError;
        }
    }
    
    entry->descr.address = (const char *)(entry->store->buf + off_address);
    entry->descr.port = (const char *)(entry->store->buf + off_port);
    if (off_source_address >= 0) {
        entry->descr.source_address = (const char *)(entry->store->buf + off_source_address);
    }
    
    entry->lifetime = freshness;
    
    return entry;
    
ExitOnError:
    ccn_face_instance_destroy(&entry);
    return (NULL);
}

struct ccn_face_instance *
parse_ccn_face_instance_from_face(struct ccndc_data *self,
                                  const char *cmd_faceid)
{
    struct ccn_face_instance *entry = calloc(1, sizeof(*entry));
    
    // allocate storage for Face data
    entry->store = ccn_charbuf_create();
    
    // copy static info
    entry->ccnd_id = (const unsigned char *)self->ccnd_id;
    entry->ccnd_id_size = self->ccnd_id_size;
    
    /* destroy a face - the URI field will hold the face number */
    if (cmd_faceid == NULL) {
        ccndc_warn(__LINE__, "command error, missing face number for destroyface\n");
        goto ExitOnError;
    }
    
    char *endptr;
    int facenumber = strtol(cmd_faceid, &endptr, 10);
    if ((endptr != &cmd_faceid[strlen(cmd_faceid)]) ||
        facenumber < 0) {
        ccndc_warn(__LINE__, "command error invalid face number for destroyface: %d\n", facenumber);
        goto ExitOnError;
    }
    
    entry->faceid = facenumber;
    
    return entry;
    
ExitOnError:
    ccn_face_instance_destroy(&entry);
    return (NULL);
}



///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// "private section
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

int
ccndc_get_ccnd_id(struct ccndc_data *self)
{
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *resultbuf = NULL;
    struct ccn_parsed_ContentObject pcobuf = {0};
    char ccndid_uri[] = "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY";
    const unsigned char *ccndid_result;
    int res = 0;
    
    name = ccn_charbuf_create();
    if (name == NULL) {
        ccndc_warn(__LINE__, "Unable to allocate storage for service locator name charbuf\n");
        return -1;
    }
    
    resultbuf = ccn_charbuf_create();
    if (resultbuf == NULL) {
        ccndc_warn(__LINE__, "Unable to allocate storage for result charbuf");
        res = -1;
        goto Cleanup;
    }
    
    res = ccn_name_from_uri(name, ccndid_uri);
    if (res < 0) {
        ccndc_warn(__LINE__, "Unable to parse service locator URI for ccnd key");
        goto Cleanup;
    }
    
    res = ccn_get(self->ccn_handle,
                  name,
                  self->local_scope_template,
                  4500, resultbuf, &pcobuf, NULL, 0);
    if (res < 0) {
        ccndc_warn(__LINE__, "Unable to get key from ccnd");
        goto Cleanup;
    }
    
    res = ccn_ref_tagged_BLOB (CCN_DTAG_PublisherPublicKeyDigest,
                               resultbuf->buf,
                               pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest],
                               pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest],
                               &ccndid_result, &self->ccnd_id_size);
    if (res < 0) {
        ccndc_warn(__LINE__, "Unable to parse ccnd response for ccnd id");
        goto Cleanup;
    }
    
    if (self->ccnd_id_size > sizeof (self->ccnd_id))
    {
        ccndc_warn(__LINE__, "Incorrect size for ccnd id in response");
        goto Cleanup;
    }
    
    memcpy(self->ccnd_id, ccndid_result, self->ccnd_id_size);
    
Cleanup:
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&resultbuf);
    return (res);
}


struct ccn_face_instance *
ccndc_do_face_action(struct ccndc_data *self,
                     const char *action,
                     struct ccn_face_instance *face_instance)
{
    struct ccn_charbuf *newface = NULL;
    struct ccn_charbuf *signed_info = NULL;
    struct ccn_charbuf *temp = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *resultbuf = NULL;
    struct ccn_parsed_ContentObject pcobuf = {0};
    struct ccn_face_instance *new_face_instance = NULL;
    const unsigned char *ptr = NULL;
    size_t length = 0;
    int res = 0;
    
    face_instance->action = action;
    
    /* Encode the given face instance */
    newface = ccn_charbuf_create();
    ON_NULL_CLEANUP(newface);
    ON_ERROR_CLEANUP(ccnb_append_face_instance(newface, face_instance));
    
    temp = ccn_charbuf_create();
    ON_NULL_CLEANUP(temp);
    res = ccn_sign_content(self->ccn_handle, temp, self->no_name, NULL, newface->buf, newface->length);
    ON_ERROR_CLEANUP(res);
    resultbuf = ccn_charbuf_create();
    ON_NULL_CLEANUP(resultbuf);
    
    /* Construct the Interest name that will create the face */
    name = ccn_charbuf_create();
    ON_NULL_CLEANUP(name);
    ON_ERROR_CLEANUP(ccn_name_init(name));
    ON_ERROR_CLEANUP(ccn_name_append_str(name, "ccnx"));
    ON_ERROR_CLEANUP(ccn_name_append(name, face_instance->ccnd_id, face_instance->ccnd_id_size));
    ON_ERROR_CLEANUP(ccn_name_append_str(name, face_instance->action));
    ON_ERROR_CLEANUP(ccn_name_append(name, temp->buf, temp->length));
    
    res = ccn_get(self->ccn_handle, name, self->local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0);
    ON_ERROR_CLEANUP(res);
    
    ON_ERROR_CLEANUP(ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length));
    new_face_instance = ccn_face_instance_parse(ptr, length);
    ON_NULL_CLEANUP(new_face_instance);
    ccn_charbuf_destroy(&newface);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&resultbuf);
    ccn_charbuf_destroy(&name);
    return (new_face_instance);
    
Cleanup:
    ccn_charbuf_destroy(&newface);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&resultbuf);
    ccn_charbuf_destroy(&name);
    ccn_face_instance_destroy(&new_face_instance);
    return (NULL);
}

int
ccndc_do_prefix_action(struct ccndc_data *self,
                       const char *action,
                       struct ccn_forwarding_entry *forwarding_entry)
{
    struct ccn_charbuf *temp = NULL;
    struct ccn_charbuf *resultbuf = NULL;
    struct ccn_charbuf *signed_info = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *prefixreg = NULL;
    struct ccn_parsed_ContentObject pcobuf = {0};
    struct ccn_forwarding_entry *new_forwarding_entry = NULL;
    
    const unsigned char *ptr = NULL;
    size_t length = 0;
    int res;
    
    forwarding_entry->action = action;
    
    prefixreg = ccn_charbuf_create();
    ON_NULL_CLEANUP(prefixreg);
    ON_ERROR_CLEANUP(ccnb_append_forwarding_entry(prefixreg, forwarding_entry));
    temp = ccn_charbuf_create();
    ON_NULL_CLEANUP(temp);
    res = ccn_sign_content(self->ccn_handle, temp, self->no_name, NULL, prefixreg->buf, prefixreg->length);
    ON_ERROR_CLEANUP(res);    
    resultbuf = ccn_charbuf_create();
    ON_NULL_CLEANUP(resultbuf);
    name = ccn_charbuf_create();
    ON_ERROR_CLEANUP(ccn_name_init(name));
    ON_ERROR_CLEANUP(ccn_name_append_str(name, "ccnx"));
    ON_ERROR_CLEANUP(ccn_name_append(name, forwarding_entry->ccnd_id, forwarding_entry->ccnd_id_size));
    ON_ERROR_CLEANUP(ccn_name_append_str(name, forwarding_entry->action));
    ON_ERROR_CLEANUP(ccn_name_append(name, temp->buf, temp->length));
    res = ccn_get(self->ccn_handle, name, self->local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0);
    ON_ERROR_CLEANUP(res);
    ON_ERROR_CLEANUP(ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length));
    new_forwarding_entry = ccn_forwarding_entry_parse(ptr, length);
    ON_NULL_CLEANUP(new_forwarding_entry);
    
    res = new_forwarding_entry->faceid;
    
    ccn_forwarding_entry_destroy(&new_forwarding_entry);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&resultbuf);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&prefixreg);
    
    return (res);
    
    /* This is where ON_ERROR_CLEANUP sends us in case of an error
     * and we must free any storage we allocated before returning.
     */
Cleanup:
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&resultbuf);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&prefixreg);
    
    return (-1);
}
Пример #4
0
int
ccndc_srv(struct ccndc_data *self,
          const unsigned char *domain,
          size_t domain_size)
{
    char *proto = NULL;
    char *host = NULL;
    int port = 0;
    char port_str[10];
    struct ccn_charbuf *uri;
    struct ccn_charbuf *uri_auto;
    struct ccn_face_instance *face;
    struct ccn_face_instance *newface;
    struct ccn_forwarding_entry *prefix;
    struct ccn_forwarding_entry *prefix_auto;
    int res;
    
    res = ccndc_query_srv(domain, domain_size, &host, &port, &proto);
    if (res < 0) {
        return -1;
    }
    
    uri = ccn_charbuf_create();
    ccn_charbuf_append_string(uri, "ccnx:/");
    if (domain_size != 0) {
        ccn_uri_append_percentescaped(uri, domain, domain_size);
    }
    
    snprintf (port_str, sizeof(port_str), "%d", port);
    
    /* now process the results */
    /* pflhead, lineno=0, "add" "ccnx:/asdfasdf.com/" "tcp|udp", host, portstring, NULL NULL NULL */
    
    ccndc_note(__LINE__, " >>> trying:   add %s %s %s %s <<<\n", ccn_charbuf_as_string(uri), proto, host, port_str);
    
    face = parse_ccn_face_instance(self, proto, host, port_str, NULL, NULL,
                                   (~0U) >> 1);
    
    prefix = parse_ccn_forwarding_entry(self, ccn_charbuf_as_string(uri), NULL,
                                        self->lifetime);
    if (face == NULL || prefix == NULL) {
        res = -1;
        goto Cleanup;
    }
    
    // crazy operation
    // First. "Create" face, which will do nothing if face already exists
    // Second. Destroy the face
    // Third. Create face for real
    
    newface = ccndc_do_face_action(self, "newface", face);
    if (newface == NULL) {
        ccndc_warn(__LINE__, "Cannot create/lookup face");
        res = -1;
        goto Cleanup;
    }
    
    face->faceid = newface->faceid;
    ccn_face_instance_destroy(&newface);
    
    newface = ccndc_do_face_action(self, "destroyface", face);
    if (newface == NULL) {
        ccndc_warn(__LINE__, "Cannot destroy face");
    } else {
        ccn_face_instance_destroy(&newface);
    }
    
    newface = ccndc_do_face_action(self, "newface", face);
    if (newface == NULL) {
        ccndc_warn(__LINE__, "Cannot create/lookup face");
        res = -1;
        goto Cleanup;
    }
    
    prefix->faceid = newface->faceid;
    ccn_face_instance_destroy(&newface);
    
    res = ccndc_do_prefix_action(self, "prefixreg", prefix);
    if (res < 0) {
        ccndc_warn(__LINE__, "Cannot register prefix [%s]\n", ccn_charbuf_as_string(uri));
    }

    uri_auto = ccn_charbuf_create();
    ccn_charbuf_append_string(uri_auto, "ccnx:/autoconf-route");
    prefix_auto = parse_ccn_forwarding_entry(self, ccn_charbuf_as_string(uri_auto), NULL,
                                        self->lifetime);
    if (prefix_auto == NULL) {
        res = -1;
        goto Cleanup;
    }

    prefix_auto->faceid = prefix->faceid;
    res = ccndc_do_prefix_action(self, "prefixreg", prefix_auto);
    if (res < 0) {
        ccndc_warn(__LINE__, "Cannot register prefix_auto [%s]\n", ccn_charbuf_as_string(uri_auto));
    }
    
Cleanup:
    free(host);
    ccn_charbuf_destroy(&uri);
    ccn_charbuf_destroy(&uri_auto);
    ccn_face_instance_destroy(&face);
    ccn_forwarding_entry_destroy(&prefix);
    ccn_forwarding_entry_destroy(&prefix_auto);
    return res;
}
Пример #5
0
/*
 *   uri (udp|tcp) host [port [flags [mcastttl [mcastif]]]])
 *   uri face faceid
 */
int
ccndc_renew(struct ccndc_data *self,
            int check_only,
            const char *cmd_orig)
{
    int ret_code = -1;
    char *cmd, *cmd_token;
    char *cmd_uri = NULL;
    char *cmd_proto = NULL;
    char *cmd_host = NULL;
    char *cmd_port = NULL;
    char *cmd_flags = NULL;
    char *cmd_mcastttl = NULL;
    char *cmd_mcastif = NULL;
    struct ccn_face_instance *face = NULL;
    struct ccn_face_instance *newface = NULL;
    struct ccn_forwarding_entry *prefix = NULL;
    
    if (cmd_orig == NULL) {
        ccndc_warn(__LINE__, "command error\n");
        return -1;
    }
    
    cmd = strdup(cmd_orig);
    if (cmd == NULL) {
        ccndc_warn(__LINE__, "Cannot allocate memory for copy of the command\n");
        return -1;
    }            
    cmd_token = cmd;
    GET_NEXT_TOKEN(cmd_token, cmd_uri);
    GET_NEXT_TOKEN(cmd_token, cmd_proto);
    GET_NEXT_TOKEN(cmd_token, cmd_host);
    GET_NEXT_TOKEN(cmd_token, cmd_port);
    GET_NEXT_TOKEN(cmd_token, cmd_flags);
    GET_NEXT_TOKEN(cmd_token, cmd_mcastttl);
    GET_NEXT_TOKEN(cmd_token, cmd_mcastif);
    
    // perform sanity checking
    face = parse_ccn_face_instance(self, cmd_proto, cmd_host, cmd_port,
                                   cmd_mcastttl, cmd_mcastif, (~0U) >> 1);
    prefix = parse_ccn_forwarding_entry(self, cmd_uri, cmd_flags, self->lifetime);
    if (face == NULL || prefix == NULL)
        goto Cleanup;
    
    if (!check_only) {
        // look up the old face ("queryface" would be useful)
        newface = ccndc_do_face_action(self, "newface", face);
        if (newface == NULL) {
            ccndc_warn(__LINE__, "Cannot create/lookup face");
            goto Cleanup;
        }
        face->faceid = newface->faceid;
        ccn_face_instance_destroy(&newface);
        // destroy the old face
        newface = ccndc_do_face_action(self, "destroyface", face);
        if (newface == NULL) {
            ccndc_warn(__LINE__, "Cannot destroy face %d or the face does not exist\n", face->faceid);
            goto Cleanup;
        }
        ccn_face_instance_destroy(&newface);
        // recreate the face
        newface = ccndc_do_face_action(self, "newface", face);
        if (newface == NULL) {
            ccndc_warn(__LINE__, "Cannot create/lookup face");
            goto Cleanup;
        }
        prefix->faceid = newface->faceid;
        ccn_face_instance_destroy(&newface);
        // and add the prefix to it
        ret_code = ccndc_do_prefix_action(self, "prefixreg", prefix);
        if (ret_code < 0) {
            ccndc_warn(__LINE__, "Cannot register prefix [%s]\n", cmd_uri);
            goto Cleanup;
        }
    }  
    ret_code = 0;
Cleanup:
    ccn_face_instance_destroy(&face);
    ccn_forwarding_entry_destroy(&prefix);
    free(cmd);
    return (ret_code);
}
Пример #6
0
int
ccndc_del(struct ccndc_data *self,
          int check_only,
          const char *cmd_orig)
{
    int ret_code = -1;
    char *cmd, *cmd_token;
    char *cmd_uri = NULL;
    char *cmd_proto = NULL;
    char *cmd_host = NULL;
    char *cmd_port = NULL;
    char *cmd_flags = NULL;
    char *cmd_mcastttl = NULL;
    char *cmd_mcastif = NULL;
    struct ccn_face_instance *face = NULL;
    struct ccn_face_instance *newface = NULL;
    struct ccn_forwarding_entry *prefix = NULL;
    
    if (cmd_orig == NULL) {
        ccndc_warn(__LINE__, "command error\n");
        return -1;
    }
    
    cmd = strdup(cmd_orig);
    if (cmd == NULL) {
        ccndc_warn(__LINE__, "Cannot allocate memory for copy of the command\n");
        return -1;
    }            
    cmd_token = cmd;
    GET_NEXT_TOKEN(cmd_token, cmd_uri);
    GET_NEXT_TOKEN(cmd_token, cmd_proto);
    GET_NEXT_TOKEN(cmd_token, cmd_host);
    GET_NEXT_TOKEN(cmd_token, cmd_port);
    GET_NEXT_TOKEN(cmd_token, cmd_flags);
    GET_NEXT_TOKEN(cmd_token, cmd_mcastttl);
    GET_NEXT_TOKEN(cmd_token, cmd_mcastif);
    
    face = parse_ccn_face_instance(self, cmd_proto, cmd_host, cmd_port,
                                   cmd_mcastttl, cmd_mcastif, (~0U) >> 1);
    prefix = parse_ccn_forwarding_entry(self, cmd_uri, cmd_flags, (~0U) >> 1);
    if (face == NULL || prefix == NULL)
        goto Cleanup;
    
    if (!check_only) {
        if (0 != strcasecmp(cmd_proto, "face")) {
            newface = ccndc_do_face_action(self, "newface", face);
            if (newface == NULL) {
                ccndc_warn(__LINE__, "Cannot create/lookup face");
                goto Cleanup;
            }
            prefix->faceid = newface->faceid;
            ccn_face_instance_destroy(&newface);
        } else {
            prefix->faceid = face->faceid;
        }
        ret_code = ccndc_do_prefix_action(self, "unreg", prefix);
        if (ret_code < 0) {
            ccndc_warn(__LINE__, "Cannot unregister prefix [%s]\n", cmd_uri);
            goto Cleanup;
        }
    }
    ret_code = 0;
Cleanup:
    ccn_face_instance_destroy(&face);
    ccn_forwarding_entry_destroy(&prefix);
    free(cmd);
    return (ret_code);
}
Пример #7
0
/**
 * 
 * Bind a prefix to a face
 *
 */
static int 
register_unregister_prefix(struct ccn *h, struct ccn_charbuf *local_scope_template,
        struct ccn_charbuf *no_name, struct ccn_charbuf *name_prefix,
        struct ccn_face_instance *face_instance, int operation)
{
	struct ccn_charbuf *temp = NULL;
	struct ccn_charbuf *resultbuf = NULL;
	struct ccn_charbuf *signed_info = NULL;
	struct ccn_charbuf *name = NULL;
	struct ccn_charbuf *prefixreg = NULL;
	struct ccn_parsed_ContentObject pcobuf = {0};
	struct ccn_forwarding_entry forwarding_entry_storage = {0};
	struct ccn_forwarding_entry *forwarding_entry = &forwarding_entry_storage;
	struct ccn_forwarding_entry *new_forwarding_entry;
	const unsigned char *ptr = NULL;
	size_t length = 0;
	int res;

	/* Register or unregister the prefix */
	forwarding_entry->action = (operation == OP_REG) ? "prefixreg" : "unreg";
	forwarding_entry->name_prefix = name_prefix;
	forwarding_entry->ccnd_id = face_instance->ccnd_id;
	forwarding_entry->ccnd_id_size = face_instance->ccnd_id_size;
	forwarding_entry->faceid = face_instance->faceid;
	forwarding_entry->flags = -1;
	forwarding_entry->lifetime = 2100;

	prefixreg = ccn_charbuf_create();
	ccnb_append_forwarding_entry(prefixreg, forwarding_entry);
	temp = ccn_charbuf_create();
	res = ccn_sign_content(h, temp, no_name, NULL, prefixreg->buf, prefixreg->length);
	resultbuf = ccn_charbuf_create();

	/* construct Interest containing prefixreg request */
	name = ccn_charbuf_create();
	ccn_name_init(name);
	ccn_name_append_str(name, "ccnx");
	ccn_name_append(name, face_instance->ccnd_id, face_instance->ccnd_id_size);
	ccn_name_append_str(name, (operation == OP_REG) ? "prefixreg" : "unreg");
	ccn_name_append(name, temp->buf, temp->length);

	/* send Interest, get Data */
	res = ccn_get(h, name, local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0);
	ON_ERROR_CLEANUP(res);

	res = ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length);
	ON_ERROR_CLEANUP(res);
    
	/* extract new forwarding entry from Data */
	new_forwarding_entry = ccn_forwarding_entry_parse(ptr, length);
	ON_NULL_CLEANUP(new_forwarding_entry);

	res = new_forwarding_entry->faceid;

	ccn_forwarding_entry_destroy(&new_forwarding_entry);
	ccn_charbuf_destroy(&signed_info);
	ccn_charbuf_destroy(&temp);
	ccn_charbuf_destroy(&resultbuf);
	ccn_charbuf_destroy(&name);
	ccn_charbuf_destroy(&prefixreg);

	return res;

	cleanup:
		ccn_forwarding_entry_destroy(&new_forwarding_entry);
		ccn_charbuf_destroy(&signed_info);
		ccn_charbuf_destroy(&temp);
		ccn_charbuf_destroy(&resultbuf);
		ccn_charbuf_destroy(&name);
		ccn_charbuf_destroy(&prefixreg);

	return -1;
}
Пример #8
0
struct ccn_forwarding_entry *
ccn_forwarding_entry_parse(const unsigned char *p, size_t size)
{
    struct ccn_buf_decoder decoder;
    struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size);
    struct ccn_charbuf *store = ccn_charbuf_create();
    struct ccn_forwarding_entry *result;
    const unsigned char *val;
    size_t sz;
    size_t start;
    size_t end;
    int action_off = -1;
    int ccnd_id_off = -1;
    
    if (store == NULL)
        return(NULL);
    result = calloc(1, sizeof(*result));
    if (result == NULL) {
        ccn_charbuf_destroy(&store);
        return(NULL);
    }
    if (ccn_buf_match_dtag(d, CCN_DTAG_ForwardingEntry)) {
        ccn_buf_advance(d);
        action_off = ccn_parse_tagged_string(d, CCN_DTAG_Action, store);
        if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
            result->name_prefix = ccn_charbuf_create();
            start = d->decoder.token_index;
            ccn_parse_Name(d, NULL);
            end = d->decoder.token_index;
            ccn_charbuf_append(result->name_prefix, p + start, end - start);
        }
        else
            result->name_prefix = NULL;
        if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest)) {
            ccn_buf_advance(d);
            if (ccn_buf_match_blob(d, &val, &sz)) {
                ccn_buf_advance(d);
                if (sz != 32)
                    d->decoder.state = -__LINE__;
            }
            ccn_buf_check_close(d);
            if (d->decoder.state >= 0) {
                ccnd_id_off = store->length;
                ccn_charbuf_append(store, val, sz);
                result->ccnd_id_size = sz;
            }
        }
        result->faceid = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FaceID);
        result->flags = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_ForwardingFlags);
        result->lifetime = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds);
        ccn_buf_check_close(d);
    }
    else
        d->decoder.state = -__LINE__;
    
    if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state) ||
        store->length > sizeof(result->store))
        ccn_forwarding_entry_destroy(&result);
    else {
        char *b = (char *)result->store;
        memcpy(b, store->buf, store->length);
        result->action = (action_off == -1) ? NULL : b + action_off;
        result->ccnd_id = (ccnd_id_off == -1) ? NULL : result->store + ccnd_id_off;
    }
    ccn_charbuf_destroy(&store);
    return(result);
}