ccnr_match.c

Go to the documentation of this file.
00001 /**
00002  * @file ccnr_match.c
00003  * 
00004  * Part of ccnr - CCNx Repository Daemon.
00005  *
00006  */
00007 
00008 /*
00009  * Copyright (C) 2011 Palo Alto Research Center, Inc.
00010  *
00011  * This work is free software; you can redistribute it and/or modify it under
00012  * the terms of the GNU General Public License version 2 as published by the
00013  * Free Software Foundation.
00014  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00015  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00017  * for more details. You should have received a copy of the GNU General Public
00018  * License along with this program; if not, write to the
00019  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022  
00023  
00024 #include <errno.h>
00025 #include <fcntl.h>
00026 #include <limits.h>
00027 #include <netdb.h>
00028 #include <poll.h>
00029 #include <signal.h>
00030 #include <stddef.h>
00031 #include <stdint.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <time.h>
00036 #include <unistd.h>
00037 #include <arpa/inet.h>
00038 #include <sys/time.h>
00039 #include <sys/socket.h>
00040 #include <sys/stat.h>
00041 #include <sys/types.h>
00042 #include <sys/un.h>
00043 #include <netinet/in.h>
00044 
00045 #include <ccn/bloom.h>
00046 #include <ccn/btree_content.h>
00047 #include <ccn/ccn.h>
00048 #include <ccn/ccn_private.h>
00049 #include <ccn/charbuf.h>
00050 #include <ccn/face_mgmt.h>
00051 #include <ccn/hashtb.h>
00052 #include <ccn/indexbuf.h>
00053 #include <ccn/schedule.h>
00054 #include <ccn/reg_mgmt.h>
00055 #include <ccn/uri.h>
00056 
00057 #include "ccnr_private.h"
00058 
00059 #include "ccnr_match.h"
00060 
00061 #include "ccnr_forwarding.h"
00062 #include "ccnr_io.h"
00063 #include "ccnr_msg.h"
00064 #include "ccnr_sendq.h"
00065 #include "ccnr_store.h"
00066 
00067 PUBLIC void
00068 r_match_consume_interest(struct ccnr_handle *h, struct propagating_entry *pe)
00069 {
00070     struct fdholder *fdholder = NULL;
00071     ccn_indexbuf_destroy(&pe->outbound);
00072     if (pe->interest_msg != NULL) {
00073         free(pe->interest_msg);
00074         pe->interest_msg = NULL;
00075         fdholder = r_io_fdholder_from_fd(h, pe->filedesc);
00076         if (fdholder != NULL)
00077             fdholder->pending_interests -= 1;
00078     }
00079     if (pe->next != NULL) {
00080         pe->next->prev = pe->prev;
00081         pe->prev->next = pe->next;
00082         pe->next = pe->prev = NULL;
00083     }
00084     pe->usec = 0;
00085 }
00086 
00087 /**
00088  * Consume matching interests
00089  * given a nameprefix_entry and a piece of content.
00090  *
00091  * If fdholder is not NULL, pay attention only to interests from that fdholder.
00092  * It is allowed to pass NULL for pc, but if you have a (valid) one it
00093  * will avoid a re-parse.
00094  * @returns number of matches found.
00095  */
00096 PUBLIC int
00097 r_match_consume_matching_interests(struct ccnr_handle *h,
00098                            struct nameprefix_entry *npe,
00099                            struct content_entry *content,
00100                            struct ccn_parsed_ContentObject *pc,
00101                            struct fdholder *fdholder)
00102 {
00103     int matches = 0;
00104     struct propagating_entry *head;
00105     struct propagating_entry *next;
00106     struct propagating_entry *p;
00107     const unsigned char *content_msg;
00108     size_t content_size;
00109     struct fdholder *f;
00110     
00111     head = &npe->pe_head;
00112     // XXX - i do not think this is called in practice
00113     content_msg = r_store_content_base(h, content);
00114     content_size = r_store_content_size(h, content);
00115     f = fdholder;
00116     for (p = head->next; p != head; p = next) {
00117         next = p->next;
00118         if (p->interest_msg != NULL &&
00119             ((fdholder == NULL && (f = r_io_fdholder_from_fd(h, p->filedesc)) != NULL) ||
00120              (fdholder != NULL && p->filedesc == fdholder->filedesc))) {
00121             if (ccn_content_matches_interest(content_msg, content_size, 1, pc,
00122                                              p->interest_msg, p->size, NULL)) {
00123                 r_sendq_face_send_queue_insert(h, f, content);
00124                 if (CCNSHOULDLOG(h, (32 | 8), CCNL_FINE))
00125                     ccnr_debug_ccnb(h, __LINE__, "consume", f,
00126                                     p->interest_msg, p->size);
00127                 matches += 1;
00128                 r_match_consume_interest(h, p);
00129             }
00130         }
00131     }
00132     return(matches);
00133 }
00134 
00135 /**
00136  * Find and consume interests that match given content.
00137  *
00138  * Schedules the sending of the content.
00139  * If fdholder is not NULL, pay attention only to interests from that fdholder.
00140  * It is allowed to pass NULL for pc, but if you have a (valid) one it
00141  * will avoid a re-parse.
00142  * For new content, from_face is the source; for old content, from_face is NULL.
00143  * @returns number of matches, or -1 if the new content should be dropped.
00144  */
00145 PUBLIC int
00146 r_match_match_interests(struct ccnr_handle *h, struct content_entry *content,
00147                            struct ccn_parsed_ContentObject *pc,
00148                            struct fdholder *fdholder, struct fdholder *from_face)
00149 {
00150     int n_matched = 0;
00151     int new_matches;
00152     struct nameprefix_entry *npe = NULL;
00153     int ci = 0;
00154     int cm = 0;
00155     struct ccn_charbuf *name = NULL;
00156     struct ccn_indexbuf *namecomps = NULL;
00157     unsigned c0 = 0;
00158     
00159     name = ccn_charbuf_create();
00160     ccn_name_init(name);
00161     r_store_name_append_components(name, h, content, 0, -1);
00162     namecomps = ccn_indexbuf_create();
00163     ccn_name_split(name, namecomps);
00164     c0 = namecomps->buf[0];
00165     
00166     for (ci = namecomps->n - 1; ci >= 0; ci--) {
00167         int size = namecomps->buf[ci] - c0;
00168         npe = hashtb_lookup(h->nameprefix_tab, name->buf + c0, size);
00169         if (npe != NULL)
00170             break;
00171     }
00172     
00173     ccn_charbuf_destroy(&name);
00174     ccn_indexbuf_destroy(&namecomps);
00175     for (; npe != NULL; npe = npe->parent, ci--) {
00176 //        if (npe->fgen != h->forward_to_gen)
00177 //            r_fwd_update_forward_to(h, npe);
00178         if (from_face != NULL && (npe->flags & CCN_FORW_LOCAL) != 0 &&
00179             (from_face->flags & CCNR_FACE_GG) == 0)
00180             return(-1);
00181         new_matches = r_match_consume_matching_interests(h, npe, content, pc, fdholder);
00182 //        if (from_face != NULL && (new_matches != 0 || ci + 1 == cm))
00183 //            note_content_from(h, npe, from_face->filedesc, ci);
00184         if (new_matches != 0) {
00185             cm = ci; /* update stats for this prefix and one shorter */
00186             n_matched += new_matches;
00187         }
00188     }
00189     return(n_matched);
00190 }

Generated on Thu Feb 16 00:43:58 2012 for Content-Centric Networking in C by  doxygen 1.5.6