コード例 #1
0
ファイル: sync_api.c プロジェクト: IthacaDream/ccnx
// my_response is used to handle a reply
static enum ccn_upcall_res
my_response(struct ccn_closure *selfp,
            enum ccn_upcall_kind kind,
            struct ccn_upcall_info *info) {
    static char *here = "sync_track.my_response";
    enum ccn_upcall_res ret = CCN_UPCALL_RESULT_ERR;
    switch (kind) {
        case CCN_UPCALL_FINAL:
            free(selfp);
            ret = CCN_UPCALL_RESULT_OK;
            break;
        case CCN_UPCALL_CONTENT_UNVERIFIED:
            ret = CCN_UPCALL_RESULT_VERIFY;
            break;
        case CCN_UPCALL_CONTENT_KEYMISSING:
            ret = CCN_UPCALL_RESULT_FETCHKEY;
            break;
        case CCN_UPCALL_INTEREST_TIMED_OUT: {
            struct sync_diff_fetch_data *fd = selfp->data;
            //enum local_flags flags = selfp->intdata;
            if (fd == NULL) break;
            struct sync_diff_data *diff_data = fd->diff_data;
            if (diff_data == NULL) break;
            struct ccns_handle *ch = diff_data->client_data;
            free_fetch_data(ch, fd);
            start_round(ch, 10);
            ret = CCN_UPCALL_RESULT_OK;
            break;
        }
        case CCN_UPCALL_CONTENT_RAW:
        case CCN_UPCALL_CONTENT: {
            struct sync_diff_fetch_data *fd = selfp->data;
            enum local_flags flags = selfp->intdata;
            if (fd == NULL) break;
            struct sync_diff_data *diff_data = fd->diff_data;
            if (diff_data == NULL) break;
            struct SyncRootStruct *root = diff_data->root;
            if (root == NULL) break;
            struct ccns_handle *ch = diff_data->client_data;
            struct SyncNodeComposite *nc = extractNode(root, info);
            if (ch->debug >= CCNL_FINE) {
                char fs[1024];
                int pos = 0;
                switch (flags) {
                    case LF_NULL: 
                        pos += snprintf(fs+pos, sizeof(fs)-pos, "null");
                        break;
                    case LF_ADVISE:
                        pos += snprintf(fs+pos, sizeof(fs)-pos, "advise");
                        break;
                    case LF_NODE:
                        pos += snprintf(fs+pos, sizeof(fs)-pos, "node");
                        break;
                    default: 
                        pos += snprintf(fs+pos, sizeof(fs)-pos, "??%d", flags);
                        break;
                }
                if (nc != NULL)
                    pos += snprintf(fs+pos, sizeof(fs)-pos, ", nc OK");
                struct ccn_charbuf *nm = SyncNameForIndexbuf(info->content_ccnb,
                                                             info->content_comps);
                struct ccn_charbuf *uri = SyncUriForName(nm);
                pos += snprintf(fs+pos, sizeof(fs)-pos, ", %s", ccn_charbuf_as_string(uri));
                SyncNoteSimple(diff_data->root, here, fs);
                ccn_charbuf_destroy(&nm);
                ccn_charbuf_destroy(&uri);
            }
            if (nc != NULL) {
                // the node exists, so store it
                // TBD: check the hash?
                struct ccns_handle *ch = diff_data->client_data;
                struct SyncHashCacheEntry *ce = SyncHashEnter(root->ch,
                                                              nc->hash->buf, nc->hash->length,
                                                              SyncHashState_remote);
                if (flags == LF_ADVISE) {
                    ch->hashSeen = SyncNoteHash(ch->hashSeen, ce);
                    if (ch->next_ce == NULL)
                        // have to have an initial place to start
                        ch->next_ce = ce;
                }
                if (ce->ncR == NULL) {
                    // store the node
                    ce->ncR = nc;
                    SyncNodeIncRC(nc);
                } else {
                    // flush the node
                    SyncNodeDecRC(nc);
                    nc = NULL;
                }
                if (flags != LF_NULL) {
                    // from start_interest
                    start_round(ch, 10);
                } else {
                    // from sync_diff
                    sync_diff_note_node(diff_data, ce);
                }
                ret = CCN_UPCALL_RESULT_OK;
            }
            free_fetch_data(ch, fd);
            break;
        default:
            // SHOULD NOT HAPPEN
            break;
        }
    }
    return ret;
}
コード例 #2
0
ファイル: sync_api.c プロジェクト: IthacaDream/ccnx
static enum ccn_upcall_res
advise_interest_arrived(struct ccn_closure *selfp,
                        enum ccn_upcall_kind kind,
                        struct ccn_upcall_info *info) {
    // the reason to have a listener is to be able to listen for changes
    // in the collection without relying on the replies to our root advise
    // interests, which may not receive timely replies (althoug they eventually
    // get replies)
    static char *here = "sync_track.advise_interest_arrived";
    enum ccn_upcall_res ret = CCN_UPCALL_RESULT_ERR;
    switch (kind) {
        case CCN_UPCALL_FINAL:
            free(selfp);
            ret = CCN_UPCALL_RESULT_OK;
            break;
        case CCN_UPCALL_INTEREST: {
            struct ccns_handle *ch = selfp->data;
            if (ch == NULL) {
                // this got cancelled
                ret = CCN_UPCALL_RESULT_OK;
                break;
            }
            struct sync_diff_data *diff_data = ch->diff_data;
            struct SyncRootStruct *root = ch->root;
            //struct SyncBaseStruct *base = root->base;
            int skipToHash = SyncComponentCount(diff_data->root->topoPrefix) + 2;
            // skipToHash gets to the new hash
            // topo + marker + sliceHash
            const unsigned char *hp = NULL;
            size_t hs = 0;
            if (ch->debug >= CCNL_FINE) {
                struct ccn_charbuf *name = SyncNameForIndexbuf(info->interest_ccnb,
                                                               info->interest_comps);
                SyncNoteUri(root, here, "entered", name);
                ccn_charbuf_destroy(&name);
            }
            int cres = ccn_name_comp_get(info->interest_ccnb, info->interest_comps, skipToHash, &hp, &hs);
            if (cres < 0) {
                if (ch->debug >= CCNL_INFO)
                    SyncNoteSimple(diff_data->root, here, "wrong number of interest name components");
                break;
            }
            struct SyncHashCacheEntry *ce = SyncHashEnter(root->ch, hp, hs,
                                                          SyncHashState_remote);
            if (ce == NULL || ce->state & SyncHashState_covered) {
                // should not be added
                if (ch->debug >= CCNL_FINE)
                    SyncNoteSimple(diff_data->root, here, "skipped");
            } else {
                // remember the remote hash, maybe start something
                if (ch->debug >= CCNL_FINE)
                    SyncNoteSimple(diff_data->root, here, "noting");
                ch->hashSeen = SyncNoteHash(ch->hashSeen, ce);
                start_interest(diff_data);
            }
            ret = CCN_UPCALL_RESULT_OK;
            break;
        }
        default:
            // SHOULD NOT HAPPEN
            break;
    }
    return ret;
}
コード例 #3
0
ファイル: SyncBase.c プロジェクト: YichiLL/ccnx
// Enumeration support
extern int
SyncNotifyContent(struct SyncBaseStruct *base,
                  int enumeration,
                  ccnr_accession item,
                  struct ccn_charbuf *name) {
    // here for any updates, whether from time-based enumeration
    // or from prefix-based enumeration
    char *here = "Sync.SyncNotifyContent";
    
    if (base != NULL && base->ccnr != NULL) {
        struct SyncPrivate *priv = base->priv;
        int debug = base->debug;
        
        if (name == NULL) {
            // end of an enumeration
            if (enumeration == 0) {
                if (debug >= CCNL_WARNING)
                    ccnr_msg(base->ccnr, "%s, end of time-based enum?", here);
            } else if (enumeration == priv->sliceEnum) {
                priv->sliceEnum = 0;
                if (debug >= CCNL_INFO)
                    ccnr_msg(base->ccnr, "%s, all slice names seen", here);
            } else if (enumeration == priv->sliceBusy) {
                priv->sliceBusy = 0;
                struct SyncRootStruct *root = priv->rootHead;
                while (root != NULL) {
                    struct SyncRootPrivate *rp = root->priv;
                    if (enumeration == rp->sliceBusy) {
                        rp->sliceBusy = 0;
                        if (debug >= CCNL_INFO)
                            SyncNoteSimple(root, here, "slice enum done");
                        break;
                    }
                    root = root->next;
                }
                // may need a new enumeration started
                root = priv->rootHead;
                while (root != NULL) {
                    struct SyncRootPrivate *rp = root->priv;
                    if (rp->sliceBusy < 0) {
                        SyncStartSliceEnum(root);
                        break;
                    }
                    root = root->next;
                }  
            } else {
                if (debug >= CCNL_WARNING)
                    ccnr_msg(base->ccnr, "%s, end of what enum?", here);
            }
            return -1;
        }
        
        if (debug >= CCNL_FINE) {
            struct ccn_charbuf *uri = SyncUriForName(name);
            ccnr_msg(base->ccnr,
                     "%s, enum %d, %s!",
                     here, enumeration, ccn_charbuf_as_string(uri));
            ccn_charbuf_destroy(&uri);
        }
        
        struct ccn_indexbuf *comps = priv->comps;
        int splitRes = ccn_name_split(name, comps);
        if (splitRes < 0) {
            // really hould not happen!  but it does not hurt to log and ignore it
            if (debug >= CCNL_SEVERE)
                ccnr_msg(base->ccnr, "%s, invalid name!", here);
            return 0;
        }
        
        unsigned char *comp0 = NULL;
        size_t size0 = 0;
        unsigned char *comp1 = NULL;
        size_t size1 = 0;
        ccn_name_comp_get(name->buf, comps, 0, 
                          (const unsigned char **) &comp0, &size0);
        ccn_name_comp_get(name->buf, comps, 1,
                          (const unsigned char **) &comp1, &size1);
        ccnr_accession mark = item;
        if (SyncPrefixMatch(priv->localHostPrefix, name, 0)) {
            // to the local host, don't update the stable target
            mark = CCNR_NULL_ACCESSION;
            if (SyncPrefixMatch(priv->sliceCmdPrefix, name, 0))
                // this is a new slice
                SyncHandleSlice(base, name);
        }
        if (mark != CCNR_NULL_ACCESSION)
            priv->stableTarget = ccnr_hwm_update(base->ccnr, priv->stableTarget, mark);
        
        // add the name to any applicable roots
        SyncAddName(base, name, item);
        return 0;
    }
    return -1;
}