diff -rupN ccnx-0.5.0/csrc/ccnd/ccnd.c ccnx-0.5.0.lc/csrc/ccnd/ccnd.c
--- ccnx-0.5.0/csrc/ccnd/ccnd.c	2012-02-02 03:03:05.000000000 +0100
+++ ccnx-0.5.0.lc/csrc/ccnd/ccnd.c	2012-02-22 11:40:35.265962037 +0100
@@ -47,6 +47,14 @@
     #include "dummyin6.h"
 #endif
 
+#ifndef min
+	#define min( a, b ) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef max
+	#define max( a, b ) (((a) > (b)) ? (a) : (b))
+#endif
+
 #include <ccn/bloom.h>
 #include <ccn/ccn.h>
 #include <ccn/ccn_private.h>
@@ -2162,12 +2170,239 @@ age_forwarding_needed(struct ccnd_handle
                                                NULL, 0);
 }
 
+static int
+mngmt_forwarding_check(struct ccnd_handle *h_) {
+
+    struct ccnd_handle *h = h_;
+
+    struct hashtb_enumerator eef;
+    struct hashtb_enumerator *ef = &eef;
+    struct ccn_forwarding *f;
+    struct ccn_forwarding *next;
+    struct ccn_forwarding **p;
+    struct nameprefix_entry *npe_f;
+    int G, ito, max_ito, threshold, count_all, count_inactive, count_general;
+    unsigned int itime; // inactivity time
+    unsigned char key_del[500];
+    memset(key_del,0x00,500);
+
+    max_ito=5*h->lc_isit*1000;	// max interarrival time out ms
+    G = 500000/2; // minimum value of itvar
+
+    struct timeval now = {0};
+    gettimeofday(&now, 0);
+
+    count_all = 0;
+    count_inactive = 0;
+    count_general = 0;
+    threshold = h->lc_fib_size;
+    hashtb_start(h->fib_nameprefix_tab, ef);
+
+    // select the least recently timed out among inactive routes
+	for (npe_f = ef->data; npe_f != NULL; npe_f = ef->data) {
+		count_general++;
+			p = &npe_f->forwarding;
+			for (f = npe_f->forwarding; f != NULL; f = next) {
+				next = f->next;
+				if (((f->flags) & (CCN_FORW_LC)) !=0){
+					ito=min(max_ito,2*(npe_f->forwarding->mit+max(G,4*npe_f->forwarding->itvar)));
+					itime=(now.tv_sec-npe_f->forwarding->lat.tv_sec)*1000000 + (now.tv_usec-npe_f->forwarding->lat.tv_usec);
+					count_all++;
+
+					if (itime>ito) {
+						count_inactive ++;
+					}
+				}
+				p = &(f->next);
+			}
+		hashtb_next(ef);
+	}
+
+	hashtb_end(ef);
+	itime=(now.tv_sec-h->last_query_time.tv_sec)*1000000 + (now.tv_usec-h->last_query_time.tv_usec);
+
+	if (itime>h->lc_lookup_delay*1000) {
+		h->sliding_query_counter=0;
+	}
+	if (count_inactive<=h->sliding_query_counter && count_all>=threshold) // too much outstanding queries or no inactive routes
+		return -1;
+	else
+		return 1;
+}
+
+static int
+mngmt_forwarding_LRU(struct ccnd_handle *h_) {
+
+	struct ccnd_handle *h = h_;
+    struct hashtb_enumerator eef;
+    struct hashtb_enumerator *ef = &eef;
+    struct ccn_forwarding *f;
+    struct ccn_forwarding *next;
+    struct ccn_forwarding **p;
+    struct nameprefix_entry *npe;
+    int count;
+    int threshold;
+    int diff;
+    size_t key_l_del;
+    unsigned char key_del[500];
+    memset(key_del,0x00,500);
+    struct timeval curr_time = {0};
+    struct timeval now = {0};
+
+    count =0;
+    diff=0;
+    key_l_del=0;
+    gettimeofday(&now, 0);
+    threshold = h->lc_fib_size;
+    hashtb_start(h->fib_nameprefix_tab, ef);
+
+	// select the least recently used for LRU
+	for (npe = ef->data; npe != NULL; npe = ef->data) {
+					p = &npe->forwarding;
+					for (f = npe->forwarding; f != NULL; f = next) {
+						next = f->next;
+						if ((f->flags & CCN_FORW_LC) !=0){
+							count ++;
+							if (count == 1){
+								curr_time.tv_sec = npe->forwarding->lat.tv_sec;
+								curr_time.tv_usec = npe->forwarding->lat.tv_usec;
+								key_l_del=ef->keysize;
+								memcpy(key_del, ef->key,ef->keysize);
+							}
+							else {
+								diff = (int)((1.0*npe->forwarding->lat.tv_sec - 1.0*curr_time.tv_sec)*1000000.0 + (1.0*npe->forwarding->lat.tv_usec - 1.0*curr_time.tv_usec));
+								if(diff< 0){
+									curr_time.tv_sec = npe->forwarding->lat.tv_sec;
+									curr_time.tv_usec = npe->forwarding->lat.tv_usec;
+									memcpy(key_del, ef->key,ef->keysize);
+									key_l_del=ef->keysize;
+								}
+							}
+						}
+						p = &(f->next);
+					}
+		hashtb_next(ef);
+	}
+
+	// try to delete the entry
+    if (count>=threshold) {
+    	diff = (int)((1.0*now.tv_sec - 1.0*curr_time.tv_sec)*1000000.0 + (1.0*now.tv_usec - 1.0*curr_time.tv_usec));
+    	if(diff <  h->lc_isit){
+    		hashtb_end(ef);
+    		return -1;
+    	}
+
+    	npe= hashtb_lookup(h->nameprefix_tab,key_del,key_l_del);
+     	p = &npe->forwarding;
+    	f = npe->forwarding;
+    	*p = f->next;
+        free(f);
+        f = NULL;
+        h->forward_to_gen += 1;
+
+        hashtb_seek(ef,key_del, key_l_del, 0);
+    	hashtb_delete(ef);
+
+    }
+
+    hashtb_end(ef);
+	return 1;
+}
+
+static int
+mngmt_forwarding_ITO_WITHOUT_PREEMPTION(struct ccnd_handle *h_) {
+    struct ccnd_handle *h = h_;
+
+    struct hashtb_enumerator eef;
+    struct hashtb_enumerator *ef = &eef;
+    struct ccn_forwarding *f;
+    struct ccn_forwarding *next;
+    struct ccn_forwarding **p;
+    struct nameprefix_entry *npe;
+    int count_all, count_inactive, G, ito, max_ito, threshold;
+    size_t key_l_del;
+    unsigned int itime, lrto;
+    struct timeval now = {0};
+    unsigned char key_del[500];
+    memset(key_del,0x00,500);
+
+    key_l_del=0;
+    count_all = 0;
+    count_inactive = 0;
+    max_ito=5*h->lc_isit*1000;	// max interarrival time out ms
+    G = 500000/2; // minimum value of itvar
+    gettimeofday(&now, 0);
+    threshold = h->lc_fib_size;
+    hashtb_start(h->fib_nameprefix_tab, ef);
+
+    // select the least recently timed out among inactive routes
+		for (npe = ef->data; npe != NULL; npe = ef->data) {
+				p = &npe->forwarding;
+					for (f = npe->forwarding; f != NULL; f = next) {
+						next = f->next;
+						if ((f->flags & CCN_FORW_LC) !=0){
+							ito=min(max_ito,2*(npe->forwarding->mit+max(G,4*npe->forwarding->itvar)));
+							itime=(now.tv_sec-npe->forwarding->lat.tv_sec)*1000000 + (now.tv_usec-npe->forwarding->lat.tv_usec);
+							count_all++;
+							if (itime>ito) {
+								count_inactive ++;
+								if (count_inactive == 1){
+									lrto=itime;
+									key_l_del=ef->keysize;
+									memcpy(key_del, ef->key,ef->keysize);
+								}
+								else {
+									if((itime)>lrto){
+										lrto=itime;
+										key_l_del=ef->keysize;
+										memcpy(key_del, ef->key,ef->keysize);
+									}
+								}
+							}
+						}
+						p = &(f->next);
+					}
+			hashtb_next(ef);
+		}
+    if (count_all>=threshold) {
+    	if(count_inactive == 0){
+    		hashtb_end(ef);
+    		ccnd_msg(h,"Blocked reg for overload ***********************");
+    		return -1;
+    	}
+    	npe= hashtb_lookup(h->nameprefix_tab,key_del,key_l_del);
+     	p = &npe->forwarding;
+    	f = npe->forwarding;
+    	*p = f->next;
+        free(f);
+        f = NULL;
+        h->forward_to_gen += 1;
+        hashtb_seek(ef,key_del, key_l_del, 0);
+    	hashtb_delete(ef);
+    }
+
+    hashtb_end(ef);
+	return 1;
+}
+
+static int
+mngmt_forwarding(struct ccnd_handle *h_) {
+	struct ccnd_handle *h = h_;
+	if(h->lc_rep_policy==1)
+		return (mngmt_forwarding_LRU(h_));
+	if(h->lc_rep_policy==2)
+		return (mngmt_forwarding_ITO_WITHOUT_PREEMPTION(h_));
+	else
+		return -1;
+}
+
+
 static struct ccn_forwarding *
 seek_forwarding(struct ccnd_handle *h,
                 struct nameprefix_entry *npe, unsigned faceid)
 {
     struct ccn_forwarding *f;
-    
+
     for (f = npe->forwarding; f != NULL; f = f->next)
         if (f->faceid == faceid)
             return(f);
@@ -2182,6 +2417,38 @@ seek_forwarding(struct ccnd_handle *h,
     return(f);
 }
 
+static int
+ccnd_reg_prefix_fib(struct ccnd_handle *h,
+                const unsigned char *msg,
+                struct ccn_indexbuf *comps,
+                int ncomps,
+                unsigned faceid,
+                int flags,
+                int expires)
+{
+
+    struct hashtb_enumerator eef;
+    struct hashtb_enumerator *ef = &eef;
+    int res;
+    struct nameprefix_entry *npe = NULL;
+
+    hashtb_start(h->fib_nameprefix_tab, ef);
+    struct ccn_forwarding *f = NULL;
+
+    res=nameprefix_seek(h, ef, msg, comps, ncomps);
+	npe = ef->data;
+	f = seek_forwarding(h, npe, faceid);
+	f->mit=0;
+	f->itvar=0;
+	gettimeofday(&f->lat,0);
+	f->window_max_int=0;
+	f->pkt_counter=0;
+	f->flags = (CCN_FORW_REFRESHED | flags);
+    hashtb_end(ef);
+
+    return(res);
+}
+
 /**
  * Register or update a prefix in the forwarding table (FIB).
  *
@@ -2210,7 +2477,26 @@ ccnd_reg_prefix(struct ccnd_handle *h,
     struct nameprefix_entry *npe = NULL;
     int res;
     struct face *face = NULL;
-    
+
+    short to_insert=1;
+    int base;
+    if (h->lc_routing){
+		hashtb_start(h->nameprefix_tab, e);
+		base = comps->buf[0];
+		npe = hashtb_lookup(h->nameprefix_tab, msg + base, comps->buf[ncomps] - base);
+		if (npe != NULL)
+			if (npe->forwarding != NULL)
+				to_insert=0;
+		hashtb_end(e);
+		npe = NULL;
+		if (h->lc_rep_policy==2)
+			h->sliding_query_counter=max(0,h->sliding_query_counter-1);
+		if ((flags & CCN_FORW_LC) != 0  && to_insert) {
+			if(mngmt_forwarding(h)== -1)
+				return -1;
+		}
+    }
+
     if (flags >= 0 &&
         (flags & CCN_FORW_PUBMASK) != flags)
         return(-1);
@@ -2227,6 +2513,13 @@ ccnd_reg_prefix(struct ccnd_handle *h,
         npe = e->data;
         f = seek_forwarding(h, npe, faceid);
         if (f != NULL) {
+        	if (h->lc_routing){
+				if (res != HT_OLD_ENTRY) {
+					f->mit=h->lc_isit*1000;
+					f->itvar=0;
+					gettimeofday(&f->lat,0);
+				}
+        	}
             h->forward_to_gen += 1; // XXX - too conservative, should check changes
             f->expires = expires;
             if (flags < 0)
@@ -2256,6 +2549,11 @@ ccnd_reg_prefix(struct ccnd_handle *h,
             res = -1;
     }
     hashtb_end(e);
+    if (h->lc_routing){
+    	if (res != -1 && (flags & CCN_FORW_LC) != 0) {
+    		ccnd_reg_prefix_fib(h,msg,comps,ncomps,faceid,flags,expires);
+    	}
+    }
     return(res);
 }
 
@@ -2890,6 +3188,36 @@ update_forward_to(struct ccnd_handle *h,
     npe->tap = tap;
 }
 
+
+/**
+ * Finds the longest matching nameprefix, returns the npe or NULL if not found.
+ */
+
+struct nameprefix_entry *
+fib_nameprefix_longest_match(struct ccnd_handle *h, const unsigned char *msg,
+                         struct ccn_indexbuf *comps, int ncomps)
+{
+    int i;
+    int base;
+    int answer = 0;
+    struct nameprefix_entry *npe = NULL;
+
+    if (ncomps + 1 > comps->n)
+        return(NULL);
+    base = comps->buf[0];
+    for (i = 0; i <= ncomps; i++) {
+        npe = hashtb_lookup(h->fib_nameprefix_tab, msg + base, comps->buf[i] - base);
+        if (npe == NULL)
+            break;
+        answer = i;
+        if (npe->children == 0)
+            break;
+    }
+  //  ccnd_msg(h, "nameprefix_longest_match returning %d", answer);
+    return(npe);
+}
+
+
 /**
  * This is where we consult the interest forwarding table.
  * @param h is the ccnd handle
@@ -2914,6 +3242,24 @@ get_outbound_faces(struct ccnd_handle *h
     int n;
     unsigned faceid;
     
+    struct timeval now = {0};
+    gettimeofday(&now, 0);
+
+    unsigned int current_int,ito;
+    int max_ito=5*h->lc_isit*1000;
+    int G = 500000/2;
+    struct hashtb_enumerator eef;
+    struct hashtb_enumerator *ef = &eef;
+    struct nameprefix_entry *npe_f;
+    struct ccn_indexbuf *comps = indexbuf_obtain(h);
+    int ncomps;
+    int base;
+    size_t size=pi->offset[CCN_PI_E];
+    ncomps = ccn_parse_interest(msg, size, pi, comps);
+
+
+
+
     while (npe->parent != NULL && npe->forwarding == NULL)
         npe = npe->parent;
     if (npe->fgen != h->forward_to_gen)
@@ -2940,9 +3286,55 @@ get_outbound_faces(struct ccnd_handle *h
             ccn_indexbuf_append_element(x, face->faceid);
         }
     }
-    return(x);
-}
 
+    if (h->lc_routing) {
+    	if (((npe->forwarding->flags) & (CCN_FORW_LC)) !=0){
+    		hashtb_start(h->fib_nameprefix_tab, ef);
+    		base = comps->buf[0];
+            npe_f = fib_nameprefix_longest_match(h,msg,comps,pi->prefix_comps);
+    		if (npe_f != NULL && npe_f->forwarding != NULL){
+    			//Note: When fib_entry is created npe_f->forwarding->mit is set equal to 0
+        		//Note: First time fib_entry is used, npe_f->forwarding->mit is set to h->lc_isit*1000, and mit and forwarding->itvar must not be updated
+    			//Note: Second time fib_entry is used, we have the first delay sample
+
+    			npe_f->forwarding->pkt_counter++;
+    			if (npe_f->forwarding->mit==0) {
+        			// First time of FIB entry use
+        			npe_f->forwarding->mit=h->lc_isit*1000;
+        			npe_f->forwarding->itvar=0;
+        			gettimeofday(&(npe_f->forwarding->last_sample),0);
+        			npe_f->forwarding->window_max_int=0;
+        		} else {
+
+    				current_int=(now.tv_sec-npe_f->forwarding->lat.tv_sec)*1000000 + (now.tv_usec-npe_f->forwarding->lat.tv_usec);
+    				npe_f->forwarding->window_max_int=max(npe_f->forwarding->window_max_int,current_int);
+    				if (current_int>h->lc_max_burst_period*1000 || npe_f->forwarding->pkt_counter>h->lc_mcth) {
+    					if (npe_f->forwarding->mit!=h->lc_isit*1000) {
+    						if (npe_f->forwarding->mit > npe_f->forwarding->window_max_int)
+    							npe_f->forwarding->itvar=0.75 * npe_f->forwarding->itvar + 0.25 * (npe_f->forwarding->mit -npe_f->forwarding->window_max_int);
+    						else
+    							npe_f->forwarding->itvar=0.75 * npe_f->forwarding->itvar + 0.25 * (npe_f->forwarding->window_max_int - npe_f->forwarding->mit);
+
+    						npe_f->forwarding->mit= 0.875 * npe_f->forwarding->mit + 0.125 * npe_f->forwarding->window_max_int;
+    					} else {
+    						// First delay sample conditioned to the burst filtering
+    						npe_f->forwarding->mit=npe_f->forwarding->window_max_int;
+    						npe_f->forwarding->itvar=npe_f->forwarding->window_max_int/2;
+    					}
+    					npe_f->forwarding->window_max_int=0;
+    					npe_f->forwarding->pkt_counter=0;
+    					gettimeofday(&(npe_f->forwarding->last_sample),0);
+    				}
+        		}
+    			gettimeofday(&(npe_f->forwarding->lat),0);
+    			//ito=min(max_ito,2*(npe_f->forwarding->mit+max(G,4*npe_f->forwarding->itvar)));
+    			//ccnd_msg(h,"mit %d itvar %d curr_int %d msg %s ito %d ", npe_f->forwarding->mit, npe_f->forwarding->itvar, current_int, msg, ito);
+    		}
+    	    hashtb_end(ef);
+    	}
+    }
+	return(x);
+}
 static int
 pe_next_usec(struct ccnd_handle *h,
              struct propagating_entry *pe, int next_delay, int lineno)
@@ -3037,7 +3429,7 @@ do_propagate(struct ccn_schedule *sched,
         if (pe->usec <= CCN_INTEREST_LIFETIME_MICROSEC / 4)
             next_delay = CCN_INTEREST_LIFETIME_MICROSEC;
         else if (special_delay == 0)
-            next_delay = CCN_INTEREST_LIFETIME_MICROSEC / 16;
+        	next_delay = CCN_INTEREST_LIFETIME_MICROSEC / 64;
         if (pe->fgen != h->forward_to_gen)
             replan_propagation(h, pe);
     }
@@ -3216,6 +3608,11 @@ propagate_interest(struct ccnd_handle *h
     int extra_delay = 0;
     struct ccn_indexbuf *outbound = NULL;
     intmax_t lifetime;
+    char* uri;
+    unsigned short uri_len;
+    struct timeval now = {0};
+
+    gettimeofday(&now,0);
     
     lifetime = ccn_interest_lifetime(msg, pi);
     outbound = get_outbound_faces(h, face, msg, pi, npe);
@@ -3235,6 +3632,29 @@ propagate_interest(struct ccnd_handle *h
             return(0);
         }
     }
+    else {
+       	if (h->lc_routing) {
+       	// Perform lookup & cache request to name server
+       	uri_len = pi->offset[CCN_PI_E_Name]-pi->offset[CCN_PI_B_Name]-3;
+   		uri = (char*) calloc (uri_len,sizeof(char));// -3 is to eliminate the first  charachters that should (to verify) represent ccnx:/ in an encoded form
+   		memcpy ( uri, msg+pi->offset[CCN_PI_B_Name]+3, (char) uri_len );
+   		//if replacement policy == ITO_WITHOUT_PREEMPTION check if there are inactive flows before send a request to name server
+   		int res = 0;
+   		if(h->lc_rep_policy==2){
+   			res=mngmt_forwarding_check(h);
+   			if (res==1) {
+   				h->last_query_time.tv_sec=now.tv_sec;
+   				h->last_query_time.tv_usec=now.tv_usec;
+   				h->sliding_query_counter++;
+   				sendto(h->lc_routing_server_sock, uri,uri_len, 0, (struct sockaddr *)&(h->lc_routing_serveraddr),sizeof(h->lc_routing_serveraddr));
+   			}
+   			else if (res == -1)
+   				ccnd_msg(h,"Route query prevented *************************************** %s",uri);
+   		}
+   		else
+   			sendto(h->lc_routing_server_sock, uri,uri_len, 0, (struct sockaddr *)&(h->lc_routing_serveraddr),sizeof(h->lc_routing_serveraddr));
+   		}
+       }
     if (pi->offset[CCN_PI_B_Nonce] == pi->offset[CCN_PI_E_Nonce]) {
         /* This interest has no nonce; add one before going on */
         size_t nonce_start = 0;
@@ -4327,6 +4747,7 @@ ccnd_send(struct ccnd_handle *h,
           const void *data, size_t size)
 {
     ssize_t res;
+    short not_sent=1;
     if ((face->flags & CCN_FACE_NOSEND) != 0)
         return;
     face->surplus++;
@@ -4340,11 +4761,17 @@ ccnd_send(struct ccnd_handle *h,
         process_internal_client_buffer(h);
         return;
     }
-    if ((face->flags & CCN_FACE_DGRAM) == 0)
-        res = send(face->recv_fd, data, size, 0);
-    else
-        res = sendto(sending_fd(h, face), data, size, 0,
-                     face->addr, face->addrlen);
+    while (not_sent) { //while added
+		if ((face->flags & CCN_FACE_DGRAM) == 0)
+			res = send(face->recv_fd, data, size, 0);
+		else
+			res = sendto(sending_fd(h, face), data, size, 0,
+						 face->addr, face->addrlen);
+		if (res == -1 && errno == EAGAIN)
+			usleep(500);
+		else
+			not_sent=0;
+    }
     if (res > 0)
         ccnd_meter_bump(h, face->meter[FM_BYTO], res);
     if (res == size)
@@ -4813,7 +5240,15 @@ ccnd_create(const char *progname, ccnd_l
     int fd;
     struct ccnd_handle *h;
     struct hashtb_param param = {0};
-    
+
+    const char *lc_fib_size;
+    const char *lc_isit;
+    const char *lc_rep_policy;
+    const char *lc_lookup_delay;
+    const char *lc_routing;
+    const char *lc_max_burst_period;
+    const char *lc_mcth;
+
     sockname = ccnd_get_local_sockname();
     h = calloc(1, sizeof(*h));
     if (h == NULL)
@@ -4835,6 +5270,7 @@ ccnd_create(const char *progname, ccnd_l
     h->content_tab = hashtb_create(sizeof(struct content_entry), &param);
     param.finalize = &finalize_nameprefix;
     h->nameprefix_tab = hashtb_create(sizeof(struct nameprefix_entry), &param);
+    h->fib_nameprefix_tab = hashtb_create(sizeof(struct nameprefix_entry), &param);
     param.finalize = &finalize_propagating;
     h->propagating_tab = hashtb_create(sizeof(struct propagating_entry), &param);
     param.finalize = 0;
@@ -4925,6 +5361,74 @@ ccnd_create(const char *progname, ccnd_l
     clean_needed(h);
     age_forwarding_needed(h);
     ccnd_internal_client_start(h);
+
+    h->lc_routing=0;
+    lc_routing = getenv("CCND_LC_ROUTING");
+    if(lc_routing != NULL && lc_routing[0] !=0){
+ 	   h->lc_routing = atoi(lc_routing);
+       	   ccnd_msg(h, "lc_routing:%d",  h->lc_routing);
+       }
+
+    if (h->lc_routing) {
+
+    	h->lc_fib_size = 10000;
+        lc_fib_size = getenv("CCND_LC_FIB_SIZE");
+        if (lc_fib_size != NULL && lc_fib_size[0] != 0) {
+     	   h->lc_fib_size = atoi(lc_fib_size);
+     	   ccnd_msg(h, "lc_fib_size:%d",  h->lc_fib_size);
+        }
+
+        h->lc_isit = 1000;
+        lc_isit =  getenv("CCND_LC_ISIT");
+        if(lc_isit != NULL && lc_isit[0] !=0){
+     	   h->lc_isit = atoi(lc_isit);
+     	   ccnd_msg(h, "lc_isit:%d",  h->lc_isit);
+        }
+
+        h->lc_rep_policy = 1;
+        lc_rep_policy = getenv("CCND_LC_REP");
+        if(lc_rep_policy != NULL && lc_rep_policy[0] !=0){
+       	   h->lc_rep_policy = atoi(lc_rep_policy);
+       	   if (h->lc_rep_policy == 1)
+       		   ccnd_msg(h, "lc_rep_policy: LRU");
+       	   else if (h->lc_rep_policy == 2)
+       	  		   ccnd_msg(h, "lc_rep_policy: ITO_WITHOUT_PREEMPTION");
+       	   else{
+       		   h->lc_rep_policy = 1;
+       		   ccnd_msg(h, "lc_rep_policy: LRU");
+       	   }
+        }
+
+        h->lc_max_burst_period = 4000;
+        lc_max_burst_period = getenv("CCND_LC_MAX_BURST_PERIOD");
+        if(lc_max_burst_period != NULL && lc_max_burst_period[0] !=0){
+     	   h->lc_max_burst_period = atoi(lc_max_burst_period);
+     	   ccnd_msg(h, "lc_max_burst_period:%d",  h->lc_max_burst_period);
+        }
+
+        h->lc_lookup_delay = 200;
+        lc_lookup_delay = getenv("CCND_LC_LOOKUP_DELAY");
+        if(lc_lookup_delay != NULL && lc_lookup_delay[0] !=0){
+     	   h->lc_lookup_delay = atoi(lc_lookup_delay);
+        	   ccnd_msg(h, "lc_lookup_delay:%d",  h->lc_lookup_delay);
+	}
+        h->lc_mcth = 16;
+        lc_mcth = getenv("CCND_LC_MCTH");
+        if(lc_mcth != NULL && lc_mcth[0] !=0){
+     	   h->lc_mcth = atoi(lc_mcth);
+        	   ccnd_msg(h, "lc_mcth:%d",  h->lc_mcth);
+        }
+
+        h->lc_routing_server_sock=socket(AF_INET,SOCK_DGRAM,0);
+        bzero(&(h->lc_routing_serveraddr),sizeof(h->lc_routing_serveraddr));
+        h->lc_routing_serveraddr.sin_family = AF_INET;
+        h->lc_routing_serveraddr.sin_addr.s_addr=inet_addr("127.0.0.1");
+        h->lc_routing_serveraddr.sin_port=htons(CCN_CCND_LC_SERVER_PORT);
+
+        gettimeofday(&h->last_query_time,0);
+        h->sliding_query_counter = 0;
+    }
+
     free(sockname);
     sockname = NULL;
     return(h);
diff -rupN ccnx-0.5.0/csrc/ccnd/ccnd_private.h ccnx-0.5.0.lc/csrc/ccnd/ccnd_private.h
--- ccnx-0.5.0/csrc/ccnd/ccnd_private.h	2011-12-10 04:07:06.000000000 +0100
+++ ccnx-0.5.0.lc/csrc/ccnd/ccnd_private.h	2012-02-22 11:49:12.665962364 +0100
@@ -30,6 +30,7 @@
 #include <stdint.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <netinet/in.h>
 
 #include <ccn/ccn_private.h>
 #include <ccn/coding.h>
@@ -72,6 +73,7 @@ struct ccnd_handle {
     struct hashtb *content_tab;     /**< keyed by portion of ContentObject */
     struct hashtb *nameprefix_tab;  /**< keyed by name prefix components */
     struct hashtb *propagating_tab; /**< keyed by nonce */
+    struct hashtb *fib_nameprefix_tab;  /**< keyed by name prefix components */
     struct ccn_indexbuf *skiplinks; /**< skiplist for content-ordered ops */
     unsigned forward_to_gen;        /**< for forward_to updates */
     unsigned face_gen;              /**< faceid generation number */
@@ -143,6 +145,17 @@ struct ccnd_handle {
     unsigned data_pause_microsec;   /**< tunable, see choose_face_delay() */
     void (*appnonce)(struct ccnd_handle *, struct face *, struct ccn_charbuf *);
                                     /**< pluggable nonce generation */
+    int lc_routing_server_sock;	// socket toward the local lookup&cache server
+    struct sockaddr_in lc_routing_serveraddr; // socket address of the lookup&cache server
+    int lc_fib_size; //lookup_cache capacity
+    int lc_isit;   //default initial value for the smoothed inter-arrival time (ms)
+    int lc_rep_policy;    //replacement policy for lookup and cache : 1 LRU 2 LFU 3 LRU_ITO 4 LFU_ITO
+    int lc_max_burst_period; // maximum period after that a ITO computation is forced to be done (ms)
+    int lc_lookup_delay; // maximum lookup delay, including the insert of the route in the FIB (ms)
+    int lc_routing;      //enable lookup and cache routing
+    struct timeval last_query_time; // time of last route query
+    unsigned int sliding_query_counter; // upper-bound of the number of queries sent in the last last_query_time
+    int lc_mcth; // size of the packet window used to compute the maximum inter-arrival time
 };
 
 /**
@@ -328,6 +341,15 @@ struct ccn_forwarding {
     unsigned flags;              /**< CCN_FORW_* - c.f. <ccn/reg_mgnt.h> */
     int expires;                 /**< time remaining, in seconds */
     struct ccn_forwarding *next;
+
+    unsigned mit;
+    unsigned mean_delay;
+    unsigned window_max_int;
+    struct timeval lat;
+    struct timeval last_sample;
+    struct timeval first_window_sample;
+    unsigned itvar;		
+    unsigned int pkt_counter;
 };
 
 /* create and destroy procs for separately allocated meters */
diff -rupN ccnx-0.5.0/csrc/cmd/ccncatchunks2.c ccnx-0.5.0.lc/csrc/cmd/ccncatchunks2.c
--- ccnx-0.5.0/csrc/cmd/ccncatchunks2.c	2011-12-06 23:09:31.000000000 +0100
+++ ccnx-0.5.0.lc/csrc/cmd/ccncatchunks2.c	2012-02-22 11:28:08.881461461 +0100
@@ -169,6 +169,7 @@ static int
 reporter(struct ccn_schedule *sched, void *clienth, 
          struct ccn_scheduled_event *ev, int flags)
 {
+    return(3000000);
     struct timeval now = {0};
     struct mydata *md = clienth;
     gettimeofday(&now, 0);
@@ -328,7 +329,7 @@ fill_holes(struct ccn_schedule *sched, v
     if (md->delivered == md->lastcheck && md->ooo_count > 0) {
         if (backoff == 0) {
             md->holes++;
-            fprintf(stderr, "*** Hole at %jd\n", md->delivered);
+            //fprintf(stderr, "*** Hole at %jd\n", md->delivered);
             reporter(sched, md, NULL, 0);
             md->curwindow = 1;
             cl = calloc(1, sizeof(*cl));
@@ -351,6 +352,8 @@ fill_holes(struct ccn_schedule *sched, v
     delay = (md->rtte << backoff);
     if (delay < 10000)
         delay = 10000;
+    if (delay > 5000000)
+        delay = 5000000;
     return(delay);
 }
 
@@ -621,7 +624,7 @@ main(int argc, char **argv)
     res = ccn_run(ccn, 500);
     if (mydata->delivered == 0) {
         fprintf(stderr, "%s: not found: %s\n", argv[0], arg);
-        exit(1);
+        exit(-1);
     }
     /* We got something, run until end of data or somebody kills us */
     while (res >= 0) {
diff -rupN ccnx-0.5.0/csrc/include/ccn/ccnd.h ccnx-0.5.0.lc/csrc/include/ccn/ccnd.h
--- ccnx-0.5.0/csrc/include/ccn/ccnd.h	2011-05-04 17:48:34.000000000 +0200
+++ ccnx-0.5.0.lc/csrc/include/ccn/ccnd.h	2012-02-22 11:28:08.881461461 +0100
@@ -38,4 +38,11 @@
  */
 #define CCN_EMPTY_PDU "CCN\202\000"
 #define CCN_EMPTY_PDU_LENGTH 5
+
+/**
+ * ccnx lookup&cache routing
+ * port of the lookup&cache local server
+ */
+#define CCN_CCND_LC_SERVER_PORT 9696
+
 #endif
diff -rupN ccnx-0.5.0/csrc/include/ccn/reg_mgmt.h ccnx-0.5.0.lc/csrc/include/ccn/reg_mgmt.h
--- ccnx-0.5.0/csrc/include/ccn/reg_mgmt.h	2011-05-12 09:55:23.000000000 +0200
+++ ccnx-0.5.0.lc/csrc/include/ccn/reg_mgmt.h	2012-02-22 11:28:08.881461461 +0100
@@ -43,6 +43,7 @@ struct ccn_forwarding_entry {
 #define CCN_FORW_LOCAL         32
 #define CCN_FORW_TAP           64
 #define CCN_FORW_CAPTURE_OK   128
+#define CCN_FORW_LC      256
 #define CCN_FORW_PUBMASK (CCN_FORW_ACTIVE        | \
                           CCN_FORW_CHILD_INHERIT | \
                           CCN_FORW_ADVERTISE     | \
@@ -50,7 +51,8 @@ struct ccn_forwarding_entry {
                           CCN_FORW_CAPTURE       | \
                           CCN_FORW_LOCAL         | \
                           CCN_FORW_TAP           | \
-                          CCN_FORW_CAPTURE_OK    )
+                          CCN_FORW_CAPTURE_OK    | \
+                          CCN_FORW_LC)
 
 struct ccn_forwarding_entry *
 ccn_forwarding_entry_parse(const unsigned char *p, size_t size);
diff -rupN ccnx-0.5.0/csrc/util/ccndstart.sh ccnx-0.5.0.lc/csrc/util/ccndstart.sh
--- ccnx-0.5.0/csrc/util/ccndstart.sh	2011-05-04 17:48:34.000000000 +0200
+++ ccnx-0.5.0.lc/csrc/util/ccndstart.sh	2012-02-22 11:28:08.881461461 +0100
@@ -34,7 +34,7 @@ StuffPreload () {
 # Provide defaults
 : ${CCND_CAP:=50000}
 : ${CCND_DEBUG:=''}
-export CCN_LOCAL_PORT CCND_CAP CCND_DEBUG CCND_AUTOREG CCND_LISTEN_ON CCND_MTU
+export CCN_LOCAL_PORT CCND_CAP CCND_DEBUG CCND_AUTOREG CCND_LISTEN_ON CCND_MTU CCND_LC_FIB_SIZE CCND_LC_ISIT CCND_LC_REP CCND_LC_MAX_BURST_PERIOD CCND_LC_LOOKUP_DELAY CCND_LC_ROUTING
 # The following are rarely used, but include them for completeness
 export CCN_LOCAL_SOCKNAME CCND_DATA_PAUSE_MICROSEC CCND_KEYSTORE_DIRECTORY
 
