aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/hicn/core
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-light/src/hicn/core')
-rw-r--r--hicn-light/src/hicn/core/CMakeLists.txt3
-rw-r--r--hicn-light/src/hicn/core/address.h6
-rw-r--r--hicn-light/src/hicn/core/address_pair.h8
-rw-r--r--hicn-light/src/hicn/core/connection.c33
-rw-r--r--hicn-light/src/hicn/core/connection.h13
-rw-r--r--hicn-light/src/hicn/core/connection_table.c2
-rw-r--r--hicn-light/src/hicn/core/connection_vft.h3
-rw-r--r--hicn-light/src/hicn/core/content_store.c183
-rw-r--r--hicn-light/src/hicn/core/content_store.h134
-rw-r--r--hicn-light/src/hicn/core/forwarder.c572
-rw-r--r--hicn-light/src/hicn/core/forwarder.h119
-rw-r--r--hicn-light/src/hicn/core/listener.c149
-rw-r--r--hicn-light/src/hicn/core/listener.h25
-rw-r--r--hicn-light/src/hicn/core/listener_table.c2
-rw-r--r--hicn-light/src/hicn/core/listener_vft.h7
-rw-r--r--hicn-light/src/hicn/core/mapme.c12
-rw-r--r--hicn-light/src/hicn/core/mapme.h14
-rw-r--r--hicn-light/src/hicn/core/messageHandler.h7
-rw-r--r--hicn-light/src/hicn/core/messagePacketType.h35
-rw-r--r--hicn-light/src/hicn/core/msgbuf.h100
-rw-r--r--hicn-light/src/hicn/core/msgbuf_pool.c84
-rw-r--r--hicn-light/src/hicn/core/msgbuf_pool.h65
-rw-r--r--hicn-light/src/hicn/core/name.c57
-rw-r--r--hicn-light/src/hicn/core/name.h10
-rw-r--r--hicn-light/src/hicn/core/nexthops.h7
-rw-r--r--hicn-light/src/hicn/core/pit.c132
-rw-r--r--hicn-light/src/hicn/core/pit.h71
-rw-r--r--hicn-light/src/hicn/core/strategy.h15
-rw-r--r--hicn-light/src/hicn/core/strategy_vft.h11
-rw-r--r--hicn-light/src/hicn/core/wldr.c9
-rw-r--r--hicn-light/src/hicn/core/wldr.h7
31 files changed, 1142 insertions, 753 deletions
diff --git a/hicn-light/src/hicn/core/CMakeLists.txt b/hicn-light/src/hicn/core/CMakeLists.txt
index b1f952a43..f877717aa 100644
--- a/hicn-light/src/hicn/core/CMakeLists.txt
+++ b/hicn-light/src/hicn/core/CMakeLists.txt
@@ -26,8 +26,8 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/listener.h
${CMAKE_CURRENT_SOURCE_DIR}/listener_table.h
${CMAKE_CURRENT_SOURCE_DIR}/listener_vft.h
- ${CMAKE_CURRENT_SOURCE_DIR}/messagePacketType.h
${CMAKE_CURRENT_SOURCE_DIR}/msgbuf.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/msgbuf_pool.h
${CMAKE_CURRENT_SOURCE_DIR}/packet_cache.h
${CMAKE_CURRENT_SOURCE_DIR}/pit.h
${CMAKE_CURRENT_SOURCE_DIR}/prefix_stats.h
@@ -57,6 +57,7 @@ list(APPEND SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/listener_vft.c
${CMAKE_CURRENT_SOURCE_DIR}/mapme.c
${CMAKE_CURRENT_SOURCE_DIR}/msgbuf.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/msgbuf_pool.c
${CMAKE_CURRENT_SOURCE_DIR}/nameBitvector.c
${CMAKE_CURRENT_SOURCE_DIR}/name.c
${CMAKE_CURRENT_SOURCE_DIR}/packet_cache.c
diff --git a/hicn-light/src/hicn/core/address.h b/hicn-light/src/hicn/core/address.h
index d13fc99ed..35d0f63ea 100644
--- a/hicn-light/src/hicn/core/address.h
+++ b/hicn-light/src/hicn/core/address.h
@@ -18,8 +18,8 @@
* \brief Address
*/
-#ifndef HICN_ADDRESS_H
-#define HICN_ADDRESS_H
+#ifndef HICNLIGHT_ADDRESS_H
+#define HICNLIGHT_ADDRESS_H
#include <netinet/in.h>
@@ -84,5 +84,5 @@ extern const char * _address_family_str[];
#define address6_empty(address) (memcmp(address6_ip(address).s6_addr, &in6addr_any, sizeof(struct in6_addr)) == 0)
#define address_empty(address) (address_family(address) == AF_INET ? address4_empty(address) : address6_empty(address))
-#endif /* HICN_ADDRESS_H */
+#endif /* HICNLIGHT_ADDRESS_H */
diff --git a/hicn-light/src/hicn/core/address_pair.h b/hicn-light/src/hicn/core/address_pair.h
index 7a08426a4..4dfdfd9de 100644
--- a/hicn-light/src/hicn/core/address_pair.h
+++ b/hicn-light/src/hicn/core/address_pair.h
@@ -18,8 +18,8 @@
* \brief Address pair
*/
-#ifndef HICN_ADDRESS_PAIR_H
-#define HICN_ADDRESS_PAIR_H
+#ifndef HICNLIGHT_ADDRESS_PAIR_H
+#define HICNLIGHT_ADDRESS_PAIR_H
#include <hicn/core/address.h>
#include <hicn/util/ip_address.h>
@@ -40,9 +40,9 @@ int address_pair_from_ip_port(address_pair_t * pair, int family,
(address_family(address_pair_get_local(pair)))
#define address_pair_get_remote_family(pair) \
(address_family(address_pair_get_remote(pair)))
-#define address_pair_get_family(pair) address_pair_local_family(pair)
+#define address_pair_get_family(pair) address_pair_get_local_family(pair)
#define address_pair_is_valid(pair) \
(address_pair_get_local_family(pair) == address_pair_get_remote_family(pair))
-#endif /* HICN_ADDRESS_PAIR_H */
+#endif /* HICNLIGHT_ADDRESS_PAIR_H */
diff --git a/hicn-light/src/hicn/core/connection.c b/hicn-light/src/hicn/core/connection.c
index ba56ce459..680e82b9b 100644
--- a/hicn-light/src/hicn/core/connection.c
+++ b/hicn-light/src/hicn/core/connection.c
@@ -399,9 +399,9 @@ connection_process_buffer(connection_t * connection, const uint8_t * buffer, siz
msgbuf_t msgbuf;
MessagePacketType packet_type;
if (messageHandler_IsInterest(message->messageHead)) {
- packet_type = MESSAGE_TYPE_INTEREST;
+ packet_type = MSGBUF_TYPE_INTEREST;
} else if (messageHandler_IsData(message->messageHead)) {
- packet_type = MESSAGE_TYPE_DATA;
+ packet_type = MSGBUF_TYPE_DATA;
} else {
ERROR("Dropped packet that is not interest nor data");
return -1;
@@ -457,18 +457,27 @@ _connection_send(const connection_t * connection, msgbuf_t * msgbuf, bool queue)
}
bool
-connection_send(const connection_t * connection, msgbuf_t * msgbuf, bool queue)
+connection_flush(const connection_t * connection)
{
- assert(connection);
+ // XXX Replace this with a proper flush function to avoid implementing the
+ // same thing everywhere
+ return _connection_send(connection, NULL, false);
+}
- /* NULL message means flush */
- if (!msgbuf)
- return _connection_send(connection, NULL, false);
+bool
+connection_send(const connection_t * connection, off_t msgbuf_id, bool queue)
+{
+ assert(connection);
+ assert(msgbuf_id_is_valid(msgbuf_id)); // XXX we now have a flush() function
if (!connection_is_up(connection))
return false;
- if (msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA) {
+ const forwarder_t * forwarder = connection_get_forwarder(connection);
+ const msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+
+ if (msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA) {
uint8_t conn_id = (uint8_t)connection_get_id(connection);
msgbuf_update_pathlabel(msgbuf, conn_id);
}
@@ -504,7 +513,7 @@ connection_resend(const connection_t * connection, msgbuf_t * msgbuf, bool
if (!connection_is_up(connection))
return ret;
- if (msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA) {
+ if (msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA) {
uint8_t conn_id = (uint8_t)connection_get_id(connection);
uint32_t old_path_label = msgbuf_get_pathlabel(msgbuf);
msgbuf_update_pathlabel(msgbuf, conn_id);
@@ -551,7 +560,7 @@ connection_wldr_allow_autostart(connection_t * connection, bool value)
}
bool
-connection_wldr_autostart_is_allowed(connection_t * connection)
+connection_wldr_autostart_is_allowed(const connection_t * connection)
{
return connection->wldr_autostart;
}
@@ -579,7 +588,7 @@ connection_has_wldr(const connection_t * connection)
}
void
-connection_wldr_detect_losses(const connection_t * connection, msgbuf_t * msgbuf)
+connection_wldr_detect_losses(const connection_t * connection, const msgbuf_t * msgbuf)
{
if (!connection->wldr)
return;
@@ -587,7 +596,7 @@ connection_wldr_detect_losses(const connection_t * connection, msgbuf_t * msgbuf
}
void
-connection_wldr_handle_notification(const connection_t * connection, msgbuf_t * msgbuf)
+connection_wldr_handle_notification(const connection_t * connection, const msgbuf_t * msgbuf)
{
if (!connection->wldr)
return;
diff --git a/hicn-light/src/hicn/core/connection.h b/hicn-light/src/hicn/core/connection.h
index 6297e193c..d9ef817d2 100644
--- a/hicn-light/src/hicn/core/connection.h
+++ b/hicn-light/src/hicn/core/connection.h
@@ -87,6 +87,7 @@ typedef struct {
#define connection_get_name(C) ((C)->name)
#define connection_get_type(C) ((C)->type)
#define connection_has_valid_id(C) (connection_id_is_valid(connection_get_id(C)))
+#define connection_has_valid_type(C) (face_type_is_valid(connection_get_type(C)))
#define connection_get_pair(C) (&(C)->pair)
#define connection_get_local(C) (address_pair_local(connection_get_pair(C)))
#define connection_get_remote(C) (address_pair_remote(connection_get_pair(C)))
@@ -191,7 +192,9 @@ int connection_finalize(connection_t * connection);
int connection_send_packet(const connection_t * connection,
const uint8_t * packet, size_t size);
-bool connection_send(const connection_t * connection, msgbuf_t * msgbuf,
+bool connection_flush(const connection_t * connection);
+
+bool connection_send(const connection_t * connection, off_t msgbuf_id,
bool queue);
size_t connection_process_buffer(connection_t * connection, const uint8_t * buffer, size_t size);
@@ -200,14 +203,16 @@ size_t connection_process_buffer(connection_t * connection, const uint8_t * buff
void connection_wldr_allow_autostart(connection_t * connection, bool value);
-bool connection_wldr_autostart_is_allowed(connection_t * connection);
+bool connection_wldr_autostart_is_allowed(const connection_t * connection);
void connection_wldr_enable(connection_t * connection, bool value);
bool connection_has_wldr(const connection_t * connection);
-void connection_wldr_detect_losses(const connection_t * connection, msgbuf_t * msgbuf);
+void connection_wldr_detect_losses(const connection_t * connection, const msgbuf_t * msgbuf);
+
+void connection_wldr_handle_notification(const connection_t * connection, const msgbuf_t * msgbuf);
-void connection_wldr_handle_notification(const connection_t * connection, msgbuf_t * msgbuf);
+#define connection_get_forwarder(connection) (connection->forwarder)
#endif /* HICNLIGHT_CONNECTION_H */
diff --git a/hicn-light/src/hicn/core/connection_table.c b/hicn-light/src/hicn/core/connection_table.c
index 0b7df0384..c4010fe40 100644
--- a/hicn-light/src/hicn/core/connection_table.c
+++ b/hicn-light/src/hicn/core/connection_table.c
@@ -46,7 +46,7 @@ _connection_table_create(size_t init_size, size_t max_size)
* We start by allocating a reasonably-sized pool, as this will eventually
* be resized if needed.
*/
- pool_init(table->connections, init_size);
+ pool_init(table->connections, init_size, 0);
return table;
}
diff --git a/hicn-light/src/hicn/core/connection_vft.h b/hicn-light/src/hicn/core/connection_vft.h
index 589f39536..1ff4d7702 100644
--- a/hicn-light/src/hicn/core/connection_vft.h
+++ b/hicn-light/src/hicn/core/connection_vft.h
@@ -42,10 +42,11 @@ const connection_ops_t connection_ ## NAME = { \
.get_socket = listener_ ## NAME ## _get_socket, \
.send = connection_ ## NAME ## _send, \
.send_packet = connection_ ## NAME ## _send_packet, \
- .read_callback = connection_ ## NAME ## _read_callback, \
.data_size = sizeof(connection_ ## NAME ## _data_t), \
};
+// .read_callback = connection_ ## NAME ## _read_callback,
+
extern const connection_ops_t * connection_vft[];
#endif /* HICNLIGHT_CONNECTION_VFT_H */
diff --git a/hicn-light/src/hicn/core/content_store.c b/hicn-light/src/hicn/core/content_store.c
index 77d40ace5..74b675224 100644
--- a/hicn-light/src/hicn/core/content_store.c
+++ b/hicn-light/src/hicn/core/content_store.c
@@ -26,10 +26,10 @@
#include "content_store.h"
-extern const content_store_ops_t content_store_lru;
+extern const cs_ops_t cs_lru;
-const content_store_ops_t * const content_store_vft[] = {
- [CONTENT_STORE_TYPE_LRU] = &content_store_lru,
+const cs_ops_t * const cs_vft[] = {
+ [CS_TYPE_LRU] = &cs_lru,
};
// XXX TODO replace by a single packet cache
@@ -37,26 +37,35 @@ const content_store_ops_t * const content_store_vft[] = {
// XXX TODO getting rid of logger and the need to acquire
// XXX TODO separate cs from vft, same with strategy
-#define content_store_entry_from_msgbuf(entry, msgbuf) \
+#define cs_entry_from_msgbuf(entry, msgbuf) \
do { \
(entry)->hasExpiryTimeTicks = msgbuf_HasContentExpiryTime(msgbuf); \
if ((entry)->hasExpiryTimeTicks) \
(entry)->expiryTimeTicks = msgbuf_GetContentExpiryTimeTicks(msgbuf); \
} while(0)
+/* This is only used as a hint for first allocation, as the table is resizeable */
+#define DEFAULT_CS_SIZE 64
-content_store_t *
-_content_store_create(content_store_type_t type, size_t init_size, size_t max_size)
+cs_t *
+_cs_create(cs_type_t type, size_t init_size, size_t max_size)
{
- content_store_t * cs = malloc(sizeof(content_store_t));
+ if (!CS_TYPE_VALID(type)) {
+ ERROR("[cs_create] Invalid content store type");
+ return NULL;
+ }
+
+ if (init_size == 0)
+ init_size = DEFAULT_CS_SIZE;
+
+ cs_t * cs = malloc(sizeof(cs_t));
if (!cs)
- goto ERR_MALLOC;
- if (!CONTENT_STORE_TYPE_VALID(type))
- goto ERR_TYPE;
+ return NULL;
+
cs->type = type;
// XXX TODO an entry = data + metadata specific to each policy
- pool_init(cs->entries, init_size);
+ pool_init(cs->entries, init_size, max_size);
// data
// options
@@ -66,59 +75,65 @@ _content_store_create(content_store_type_t type, size_t init_size, size_t max_si
// index by name
cs->index_by_name = kh_init(cs_name);
+#if 0
cs->index_by_expiry_time = NULL;
if (!cs->index_by_expiry_time) {
ERROR("Could not create index (expiry time)");
goto ERR_INDEX_EXPIRY;
}
+#endif
+ cs_vft[type]->initialize(cs);
- // XXX indices specific to each policy => vft
- // index by expiration time
- // lru ?
-
- content_store_vft[type]->initialize(cs);
-
+ return cs;
+#if 0
ERR_INDEX_EXPIRY:
- // XXX TODO
-ERR_TYPE:
-ERR_MALLOC:
+ free(cs);
+ // XXX
+
return NULL;
+#endif
}
void
-content_store_free(content_store_t * cs)
+cs_free(cs_t * cs)
{
- content_store_vft[cs->type]->finalize(cs);
+ cs_vft[cs->type]->finalize(cs);
+#if 0
if (cs->index_by_expiry_time)
; //listTimeOrdered_Release(&(store->indexByExpirationTime));
+#endif
}
-void content_store_clear(content_store_t * cs)
+void cs_clear(cs_t * cs)
{
// XXX TODO
}
-msgbuf_t *
-content_store_match(content_store_t * cs, msgbuf_t * msgbuf, uint64_t now)
+off_t
+cs_match(cs_t * cs, off_t msgbuf_id, uint64_t now)
{
assert(cs);
+
+ const msgbuf_pool_t * msgbuf_pool = cs_get_msgbuf_pool(cs);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+
assert(msgbuf);
- assert(msgbuf_get_type(msgbuf) == MESSAGE_TYPE_INTEREST);
+ assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
/* Lookup entry by name */
khiter_t k = kh_get_cs_name(cs->index_by_name, msgbuf_get_name(msgbuf));
if (k == kh_end(cs->index_by_name))
- return NULL;
- content_store_entry_t * entry = cs->entries + kh_val(cs->index_by_name, k);
+ return INVALID_MSGBUF_ID;
+ cs_entry_t * entry = cs->entries + kh_val(cs->index_by_name, k);
assert(entry);
/* Remove any expired entry */
- if (content_store_entry_has_expiry_time(entry) &&
- content_store_entry_expiry_time(entry) < now) {
+ if (cs_entry_has_expiry_time(entry) &&
+ cs_entry_get_expiry_time(entry) < now) {
// the entry is expired, we can remove it
- content_store_remove_entry(cs, entry);
+ cs_remove_entry(cs, entry);
goto NOT_FOUND;
}
@@ -130,69 +145,139 @@ content_store_match(content_store_t * cs, msgbuf_t * msgbuf, uint64_t now)
DEBUG("CS %p LRU match %p (hits %" PRIu64 ", misses %" PRIu64 ")",
cs, msgbuf, cs->stats.lru.countHits, cs->stats.lru.countMisses);
- return content_store_entry_message(entry);
+ return cs_entry_get_msgbuf_id(entry);
NOT_FOUND:
cs->stats.lru.countMisses++;
DEBUG("ContentStoreLRU %p missed msgbuf %p (hits %" PRIu64 ", misses %" PRIu64 ")",
cs, msgbuf, cs->stats.lru.countHits, cs->stats.lru.countMisses);
- return NULL;
+ return INVALID_MSGBUF_ID;
}
-void
-content_store_add(content_store_t * cs, msgbuf_t * msgbuf, uint64_t now)
+// XXX temp
+// XXX pool member pointer might change, not the ID.
+#define msgbuf_acquire(x) (x)
+
+cs_entry_t *
+cs_add(cs_t * cs, off_t msgbuf_id, uint64_t now)
{
assert(cs);
- assert(msgbuf);
- assert(msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA);
+ assert(msgbuf_id_is_valid(msgbuf_id));
+
+#if DEBUG
+ forwarder_t * forwarder = cs_get_forwarder(cs);
+ msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+ assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA);
+#endif
- content_store_entry_t * entry = NULL;
+#if 0
+ // entry exists ?
+ cs_entry_t *dataEntry = parcHashCodeTable_Get(data->storageByName, content);
+ if(dataEntry)
+ _cs_lru_purge_entry(data, dataEntry);
+#endif
+
+#if 0
+ // check expiration
+ uint64_t expiryTimeTicks = contentStoreEntry_MaxExpiryTime;
+ if (message_HasContentExpiryTime(content))
+ expiryTimeTicks = message_GetContentExpiryTimeTicks(content);
+
+ // Don't add anything that's already expired or has exceeded RCT.
+ if (now >= expiryTimeTicks)
+ return false;
+#endif
+
+#if 0
+ // evict
+ if (data->objectCount >= data->objectCapacity)
+ // Store is full. Need to make room.
+ _evictByStorePolicy(data, now);
+#endif
+
+ cs_entry_t * entry = NULL;
+ off_t entry_id = pool_get(cs->entries, entry);
+ if (!entry)
+ goto ERR_ENTRY;
+
+ *entry = (cs_entry_t) {
+ .msgbuf_id = msgbuf_id,
+ .hasExpiryTimeTicks = false, // XXX
+ .expiryTimeTicks = 0, // XXX
+ };
+
+ // update indices
+
+ // update policy index
+ /* eg. LRU: add new the entry at the head of the LRU */
+ if (!cs_vft[cs->type]->add_entry(cs, entry_id))
+ goto ERR_VFT;
- /* borrow from content_store_lru_add_entry */
+#if 0
+ // update expiry time index
+ if (cs_entry_has_expiry_time(entry)) {
+ }
+#endif
+
+#if 0
+ // stats
+ data->objectCount++;
+ data->stats.countAdds++;
+#endif
+
+ return entry;
- content_store_vft[cs->type]->add_entry(cs, entry);
+ERR_VFT:
+ pool_put(cs->entries, entry);
+ERR_ENTRY:
+ return NULL;
}
-void
-content_store_remove_entry(content_store_t * cs, content_store_entry_t * entry)
+int
+cs_remove_entry(cs_t * cs, cs_entry_t * entry)
{
assert(cs);
assert(entry);
- if (content_store_entry_has_expiry_time(entry))
+ if (cs_entry_has_expiry_time(entry))
; // XXX TODO listTimeOrdered_Remove(store->indexByExpirationTime, entryToPurge);
- msgbuf_t * msgbuf = content_store_entry_message(entry);
+ off_t msgbuf_id = cs_entry_get_msgbuf_id(entry);
+
+ const msgbuf_pool_t * msgbuf_pool = cs_get_msgbuf_pool(cs);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+
khiter_t k = kh_get_cs_name(cs->index_by_name, msgbuf_get_name(msgbuf));
if (k != kh_end(cs->index_by_name))
kh_del(cs_name, cs->index_by_name, k);
// This will take care of LRU entry for instance
- content_store_vft[cs->type]->remove_entry(cs, entry);
+ cs_vft[cs->type]->remove_entry(cs, entry);
//store->objectCount--;
pool_put(cs->entries, entry);
+ return 0;
}
//
// XXX TODO what is the difference between purge and remove ?
bool
-content_store_remove(content_store_t * cs, msgbuf_t * msgbuf)
+cs_remove(cs_t * cs, msgbuf_t * msgbuf)
{
assert(cs);
assert(msgbuf);
- assert(msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA);
+ assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA);
/* Lookup entry by name */
khiter_t k = kh_get_cs_name(cs->index_by_name, msgbuf_get_name(msgbuf));
if (k == kh_end(cs->index_by_name))
return false;
- content_store_entry_t * entry = cs->entries + kh_val(cs->index_by_name, k);
+ cs_entry_t * entry = cs->entries + kh_val(cs->index_by_name, k);
assert(entry);
- content_store_remove_entry(cs, entry);
+ cs_remove_entry(cs, entry);
return true;
}
diff --git a/hicn-light/src/hicn/core/content_store.h b/hicn-light/src/hicn/core/content_store.h
index 5cddeaa87..2973b3955 100644
--- a/hicn-light/src/hicn/core/content_store.h
+++ b/hicn-light/src/hicn/core/content_store.h
@@ -1,41 +1,44 @@
-#ifndef HICNLIGHT_CONTENT_STORE_H
-#define HICNLIGHT_CONTENT_STORE_H
+#ifndef HICNLIGHT_CS_H
+#define HICNLIGHT_CS_H
-#include <hicn/base/khash.h>
-#include <hicn/base/pool.h>
-#include <hicn/core/msgbuf.h>
-#include <hicn/core/name.h>
-#include <hicn/content_store/lru.h>
+#include "msgbuf.h"
+#include "msgbuf_pool.h"
+#include "name.h"
+#include "../base/khash.h"
+#include "../base/pool.h"
+#include "../content_store/lru.h"
+
+#define INVALID_ENTRY_ID ~0ul /* off_t */
typedef struct {
- msgbuf_t * message;
+ off_t msgbuf_id;
//ListLruEntry *lruEntry;
bool hasExpiryTimeTicks;
uint64_t expiryTimeTicks; // single value for both ? 0 allowed ?
-} content_store_entry_t;
+ union {
+ off_t prev;
+ off_t next;
+ } lru;
+} cs_entry_t;
-#define content_store_entry_message(entry) ((entry)->message)
-#define content_store_entry_has_expiry_time(entry) ((entry)->hasExpiryTimeTicks)
-#define content_store_entry_expiry_time(entry) ((entry)->expiryTimeTicks)
+#define cs_entry_get_msgbuf_id(entry) ((entry)->msgbuf_id)
+#define cs_entry_has_expiry_time(entry) ((entry)->hasExpiryTimeTicks)
+#define cs_entry_get_expiry_time(entry) ((entry)->expiryTimeTicks)
typedef enum {
- CONTENT_STORE_TYPE_UNDEFINED,
- CONTENT_STORE_TYPE_LRU,
- CONTENT_STORE_TYPE_N,
-} content_store_type_t;
+ CS_TYPE_UNDEFINED,
+ CS_TYPE_LRU,
+ CS_TYPE_N,
+} cs_type_t;
-#define CONTENT_STORE_TYPE_VALID(type) \
- (type != CONTENT_STORE_TYPE_UNDEFINED) && \
- (type != CONTENT_STORE_TYPE_N)
+#define CS_TYPE_VALID(type) \
+ (type != CS_TYPE_UNDEFINED) && \
+ (type != CS_TYPE_N)
typedef struct {
/* The maximum allowed expiry time (will never be exceeded). */
uint64_t max_expiry_time; // XXX part of lru ?
-} content_store_options_t;
-
-typedef union {
- content_store_lru_stats_t lru;
-} content_store_stats_t;
+} cs_options_t;
// XXX TODO
#define name_hash(name) (name_HashCode(name))
@@ -44,22 +47,30 @@ typedef union {
KHASH_INIT(cs_name, const Name *, unsigned, 0, name_hash, name_hash_eq);
typedef struct {
- content_store_type_t type;
- size_t max_size;
+ cs_type_t type;
// XXX TODO api to dynamically set max size
- content_store_entry_t * entries; // pool
+ cs_entry_t * entries; // pool
kh_cs_name_t * index_by_name;
+#if 0
void * index_by_expiry_time;
- //ListTimeOrdered *indexByExpirationTime;
-
+#endif
+ const msgbuf_pool_t * msgbuf_pool;
void * data; // per cs type data
void * options;
- content_store_stats_t stats;
-} content_store_t;
+
+ union {
+ cs_lru_stats_t lru;
+ } stats;
+
+
+ union {
+ cs_lru_state_t lru;
+ };
+} cs_t;
/**
* @brief Create a new content store (extended parameters)
@@ -68,42 +79,53 @@ typedef struct {
* @param[in] init_size Initially allocated size (hint, 0 = use default value)
* @param[in] max_size Maximum size (0 = unlimited)
*
- * @return content_store_t* - The newly created content store
+ * @return cs_t* - The newly created content store
*/
-content_store_t * _content_store_create(content_store_type_t type, size_t init_size, size_t max_size);
+cs_t * _cs_create(cs_type_t type, size_t init_size, size_t max_size);
/**
* @brief Create a new content store
*
* @param[in] type Content store type
*
- * @return content_store_t* - The newly created content store
+ * @return cs_t* - The newly created content store
*/
-#define content_store_create( TYPE) _content_store_create((TYPE), 0, 0)
+#define cs_create(TYPE) _cs_create((TYPE), 0, 0)
+
+void cs_free(cs_t * cs);
+
+void cs_clear(cs_t * cs);
+
+off_t cs_match(cs_t * cs, off_t msgbuf_id, uint64_t now);
-void content_store_free(content_store_t * cs);
+cs_entry_t * cs_add(cs_t * cs, off_t msgbuf_id, uint64_t now);
-void content_store_clear(content_store_t * cs);
+int cs_remove_entry(cs_t * cs, cs_entry_t * entry);
-msgbuf_t * content_store_match(content_store_t * cs, msgbuf_t * msgbuf, uint64_t now);
+bool cs_remove(cs_t * cs, msgbuf_t * msgbuf);
-void content_store_add(content_store_t * cs, msgbuf_t * msgbuf, uint64_t now);
+#define cs_size(content_store) (pool_len(cs->entries))
-void content_store_remove_entry(content_store_t * cs, content_store_entry_t * entry);
+void cs_purge_entry(cs_t * cs, cs_entry_t * entry);
-bool content_store_remove(content_store_t * cs, msgbuf_t * msgbuf);
+#define cs_get_entry_id(cs, entry) (entry - cs->entries)
-#define content_store_size(content_store) (pool_len(cs->entries))
+#define cs_entry_at(cs, id) (&(cs)->entries[id])
-void content_store_purge_entry(content_store_t * cs, content_store_entry_t * entry);
+static inline
+const msgbuf_pool_t *
+cs_get_msgbuf_pool(const cs_t * cs)
+{
+ return cs->msgbuf_pool;
+}
typedef struct {
const char * name;
- void (*initialize)(content_store_t * cs);
+ void (*initialize)(cs_t * cs);
- void (*finalize)(content_store_t * cs);
+ void (*finalize)(cs_t * cs);
/**
* Place a Message representing a ContentObject into the ContentStore. If
@@ -116,7 +138,7 @@ typedef struct {
* UTC epoch.
*/
// XXX Do we always get now before adding ?
- bool (*add_entry)(content_store_t * cs, content_store_entry_t * entry);
+ int (*add_entry)(cs_t * cs, off_t entry_id);
/**
* The function to call to remove content from the ContentStore.
@@ -126,19 +148,19 @@ typedef struct {
* @param storeImpl - a pointer to this ContentStoreInterface instance.
* @param content - a pointer to a `Message` to remove from the store.
*/
- void (*remove_entry)(content_store_t * cs, content_store_entry_t * entry);
+ int (*remove_entry)(cs_t * cs, cs_entry_t * entry);
-} content_store_ops_t;
+} cs_ops_t;
-extern const content_store_ops_t * const content_store_vft[];
+extern const cs_ops_t * const cs_vft[];
-#define DECLARE_CONTENT_STORE(NAME) \
- const content_store_ops_t content_store_ ## NAME = { \
+#define DECLARE_CS(NAME) \
+ const cs_ops_t cs_ ## NAME = { \
.name = #NAME, \
- .initialize = content_store_ ## NAME ## _initialize, \
- .finalize = content_store_ ## NAME ## _finalize, \
- .add_entry = content_store_ ## NAME ## _add_entry, \
- .remove_entry = content_store_ ## NAME ## _remove_entry, \
+ .initialize = cs_ ## NAME ## _initialize, \
+ .finalize = cs_ ## NAME ## _finalize, \
+ .add_entry = cs_ ## NAME ## _add_entry, \
+ .remove_entry = cs_ ## NAME ## _remove_entry, \
}
-#endif /* HICNLIGHT_CONTENT_STORE_H */
+#endif /* HICNLIGHT_CS_H */
diff --git a/hicn-light/src/hicn/core/forwarder.c b/hicn-light/src/hicn/core/forwarder.c
index 9c3df906d..543fc99e4 100644
--- a/hicn-light/src/hicn/core/forwarder.c
+++ b/hicn-light/src/hicn/core/forwarder.c
@@ -31,7 +31,7 @@
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
-#include <hicn/hicn-light/config.h>
+//#include <hicn/hicn-light/config.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -41,18 +41,20 @@
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
-#include <hicn/core/connection_table.h>
-#include <hicn/core/listener_table.h>
-#include <hicn/core/pit.h>
-#include <hicn/core/fib.h>
-#include <hicn/core/content_store.h>
-#include <hicn/core/forwarder.h>
-#include <hicn/core/messagePacketType.h>
+#include "connection_table.h"
+#include "content_store.h"
+#include "fib.h"
+#include "forwarder.h"
+#include "listener_table.h"
#ifdef WITH_MAPME
-#include <hicn/core/mapme.h>
+#include "mapme.h"
#endif /* WITH_MAPME */
-#include <hicn/config/configuration.h>
-#include <hicn/config/configuration_file.h>
+#include "msgbuf.h"
+#include "msgbuf_pool.h"
+#include "pit.h"
+#include "../config/configuration.h"
+#include "../config/configuration_file.h"
+#include "../io/base.h" // MAX_MSG
#ifdef WITH_PREFIX_STATS
#include <hicn/core/prefix_stats.h>
@@ -61,10 +63,8 @@
#include <hicn/core/wldr.h>
#include <hicn/util/log.h>
-#define DEFAULT_PIT_SIZE 65535
-
typedef struct {
- uint32_t countReceived;
+ uint32_t countReceived; // Interest & Data only
uint32_t countInterestsReceived;
uint32_t countObjectsReceived;
@@ -110,15 +110,16 @@ struct forwarder_s {
pit_t * pit;
- content_store_t * content_store;
+ cs_t * cs;
fib_t * fib;
+ msgbuf_pool_t * msgbuf_pool;
#ifdef WITH_MAPME
mapme_t * mapme;
#endif /* WITH_MAPME */
- bool store_in_content_store;
- bool serve_from_content_store;
+ bool store_in_cs;
+ bool serve_from_cs;
forwarder_stats_t stats;
#ifdef WITH_PREFIX_STATS
@@ -132,7 +133,7 @@ struct forwarder_s {
unsigned pending_conn[MAX_MSG];
size_t num_pending_conn;
- msgbuf_t msgbuf; /* Storage for msgbuf, which are currently processed 1 by 1 */
+ //msgbuf_t msgbuf; /* Storage for msgbuf, which are currently processed 1 by 1 */
};
@@ -172,27 +173,6 @@ forwarder_seed(forwarder_t * forwarder) {
#endif
}
-int
-init_batch_buffers(batch_buffer_t * bb)
-{
- /* Setup recvmmsg data structures. */
- for (unsigned i = 0; i < MAX_MSG; i++) {
- char *buf = &bb->buffers[i][0];
- struct iovec *iovec = &bb->iovecs[i];
- struct mmsghdr *msg = &bb->msghdr[i];
-
- msg->msg_hdr.msg_iov = iovec;
- msg->msg_hdr.msg_iovlen = 1;
-
- msg->msg_hdr.msg_name = &bb->addrs[i];
- msg->msg_hdr.msg_namelen = sizeof(struct sockaddr_storage);
-
- iovec->iov_base = &buf[0];
- iovec->iov_len = MTU;
- }
- return 0;
-}
-
forwarder_t *
forwarder_create()
{
@@ -218,22 +198,26 @@ forwarder_create()
if (!forwarder->fib)
goto ERR_FIB;
- forwarder->pit = pit_create(DEFAULT_PIT_SIZE);
+ forwarder->msgbuf_pool = msgbuf_pool_create();
+ if (!forwarder->msgbuf_pool)
+ goto ERR_PACKET_POOL;
+
+ forwarder->pit = pit_create();
if (!forwarder->pit)
goto ERR_PIT;
size_t objectStoreSize =
- configuration_content_store_get_size(forwarder_get_configuration(forwarder));
- forwarder->content_store = _content_store_create(CONTENT_STORE_TYPE_LRU,
+ configuration_cs_get_size(forwarder_get_configuration(forwarder));
+ forwarder->cs = _cs_create(CS_TYPE_LRU,
objectStoreSize, 0);
- if (!forwarder->content_store)
- goto ERR_CONTENT_STORE;
+ if (!forwarder->cs)
+ goto ERR_CS;
- // the two flags for the content_store are set to true by default. If the content_store
+ // the two flags for the cs are set to true by default. If the cs
// is active it always work as expected unless the use modifies this
// values using controller
- forwarder->store_in_content_store = true;
- forwarder->serve_from_content_store = true;
+ forwarder->store_in_cs = true;
+ forwarder->serve_from_cs = true;
#if 0
forwarder->signal_term = dispatcher_CreateSignalEvent(
@@ -293,10 +277,12 @@ ERR_MAPME:
dispatcher_Destroy(&(forwarder->dispatcher));
#endif
- content_store_free(forwarder->content_store);
-ERR_CONTENT_STORE:
+ cs_free(forwarder->cs);
+ERR_CS:
pit_free(forwarder->pit);
ERR_PIT:
+ msgbuf_pool_free(forwarder->msgbuf_pool);
+ERR_PACKET_POOL:
fib_free(forwarder->fib);
ERR_FIB:
connection_table_free(forwarder->connection_table);
@@ -335,8 +321,9 @@ forwarder_free(forwarder_t * forwarder)
dispatcher_Destroy(&(forwarder->dispatcher));
#endif
- content_store_free(forwarder->content_store);
+ cs_free(forwarder->cs);
pit_free(forwarder->pit);
+ msgbuf_pool_free(forwarder->msgbuf_pool);
fib_free(forwarder->fib);
connection_table_free(forwarder->connection_table);
listener_table_free(forwarder->listener_table);
@@ -394,63 +381,56 @@ forwarder_get_listener_table(forwarder_t * forwarder)
}
void
-forwarder_content_store_set_store(forwarder_t * forwarder, bool val)
+forwarder_cs_set_store(forwarder_t * forwarder, bool val)
{
assert(forwarder);
- forwarder->store_in_content_store = val;
+ forwarder->store_in_cs = val;
}
bool
-forwarder_content_store_get_store(forwarder_t * forwarder)
+forwarder_cs_get_store(forwarder_t * forwarder)
{
assert(forwarder);
- return forwarder->store_in_content_store;
+ return forwarder->store_in_cs;
}
void
-forwarder_content_store_set_serve(forwarder_t * forwarder, bool val)
+forwarder_cs_set_serve(forwarder_t * forwarder, bool val)
{
assert(forwarder);
- forwarder->serve_from_content_store = val;
+ forwarder->serve_from_cs = val;
}
bool
-forwarder_content_store_get_serve(forwarder_t * forwarder)
+forwarder_cs_get_serve(forwarder_t * forwarder)
{
assert(forwarder);
- return forwarder->serve_from_content_store;
+ return forwarder->serve_from_cs;
}
void
-forwarder_content_store_set_size(forwarder_t * forwarder, size_t size)
+forwarder_cs_set_size(forwarder_t * forwarder, size_t size)
{
assert(forwarder);
- content_store_free(forwarder->content_store);
+ cs_free(forwarder->cs);
// XXX TODO
#if 0
- ContentStoreConfig content_storeConfig = {.objectCapacity =
+ ContentStoreConfig csConfig = {.objectCapacity =
maximumContentStoreSize};
- forwarder->content_store =
- content_storeLRU_Create(&content_storeConfig, forwarder->logger);
+ forwarder->cs =
+ csLRU_Create(&csConfig, forwarder->logger);
#endif
}
void
-forwarder_content_store_clear(forwarder_t * forwarder)
+forwarder_cs_clear(forwarder_t * forwarder)
{
assert(forwarder);
- content_store_clear(forwarder->content_store);
-}
-
-void
-forwarder_receive_command(forwarder_t * forwarder, command_type_t command_type,
- uint8_t * packet, unsigned connection_id)
-{
- configuration_receive_command(forwarder->config, command_type, packet, connection_id);
+ cs_clear(forwarder->cs);
}
/**
@@ -465,17 +445,20 @@ forwarder_receive_command(forwarder_t * forwarder, command_type_t command_type,
*
*/
static
-void
-forwarder_drop(forwarder_t * forwarder, msgbuf_t *message)
+ssize_t
+forwarder_drop(forwarder_t * forwarder, off_t msgbuf_id)
{
forwarder->stats.countDropped++;
- switch (msgbuf_get_type(message)) {
- case MESSAGE_TYPE_INTEREST:
+ const msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+
+ switch (msgbuf_get_type(msgbuf)) {
+ case MSGBUF_TYPE_INTEREST:
forwarder->stats.countInterestsDropped++;
break;
- case MESSAGE_TYPE_DATA:
+ case MSGBUF_TYPE_DATA:
forwarder->stats.countObjectsDropped++;
break;
@@ -484,6 +467,7 @@ forwarder_drop(forwarder_t * forwarder, msgbuf_t *message)
break;
}
+ return msgbuf_get_len(msgbuf);
// dont destroy message here, its done at end of receive
}
@@ -493,23 +477,26 @@ forwarder_drop(forwarder_t * forwarder, msgbuf_t *message)
*
*/
static
-void
-forwarder_forward_via_connection(forwarder_t * forwarder, msgbuf_t * msgbuf,
+ssize_t
+forwarder_forward_via_connection(forwarder_t * forwarder, off_t msgbuf_id,
unsigned conn_id)
{
connection_table_t * table = forwarder_get_connection_table(forwarder);
+
+ const msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+
const connection_t * conn = connection_table_get_by_id(table, conn_id);
if (!conn) {
forwarder->stats.countDroppedConnectionNotFound++;
- DEBUG("forward msgbuf %p to interface %u not found (count %u)",
- msgbuf, conn_id, forwarder->stats.countDroppedConnectionNotFound);
- forwarder_drop(forwarder, msgbuf);
- return;
+ DEBUG("forward msgbuf %lu to interface %u not found (count %u)",
+ msgbuf_id, conn_id, forwarder->stats.countDroppedConnectionNotFound);
+ return forwarder_drop(forwarder, msgbuf_id);
}
/* Always queue the packet... */
- bool success = connection_send(conn, msgbuf, true);
+ bool success = connection_send(conn, msgbuf_id, true);
/* ... and mark the connection as pending if this is not yet the case */
unsigned i;
@@ -523,18 +510,17 @@ forwarder_forward_via_connection(forwarder_t * forwarder, msgbuf_t * msgbuf,
if (!success) {
forwarder->stats.countSendFailures++;
- DEBUG("forward msgbuf %p to interface %u send failure (count %u)", msgbuf,
- conn_id, forwarder->stats.countSendFailures);
- forwarder_drop(forwarder, msgbuf);
- return;
+ DEBUG("forward msgbuf %llu to interface %u send failure (count %u)",
+ msgbuf_id, conn_id, forwarder->stats.countSendFailures);
+ return forwarder_drop(forwarder, msgbuf_id);
}
switch (msgbuf_get_type(msgbuf)) {
- case MESSAGE_TYPE_INTEREST:
+ case MSGBUF_TYPE_INTEREST:
forwarder->stats.countInterestForwarded++;
break;
- case MESSAGE_TYPE_DATA:
+ case MSGBUF_TYPE_DATA:
forwarder->stats.countObjectsForwarded++;
break;
@@ -546,6 +532,7 @@ forwarder_forward_via_connection(forwarder_t * forwarder, msgbuf_t * msgbuf,
conn_id, forwarder->stats.countInterestForwarded,
forwarder->stats.countObjectsForwarded);
+ return (msgbuf_get_len(msgbuf));
}
/**
@@ -559,14 +546,16 @@ forwarder_forward_via_connection(forwarder_t * forwarder, msgbuf_t * msgbuf,
static
unsigned
forwarder_forward_to_nexthops(forwarder_t * forwarder,
- msgbuf_t *msgbuf, const nexthops_t * nexthops)
+ off_t msgbuf_id, const nexthops_t * nexthops)
{
unsigned forwardedCopies = 0;
+ const msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
unsigned ingressId = msgbuf_get_connection_id(msgbuf);
uint32_t old_path_label = 0;
- if (msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA)
+ if (msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA)
old_path_label = msgbuf_get_pathlabel(msgbuf);
unsigned nexthop;
@@ -575,13 +564,13 @@ forwarder_forward_to_nexthops(forwarder_t * forwarder,
continue;
forwardedCopies++;
- forwarder_forward_via_connection(forwarder, msgbuf, nexthop);
+ forwarder_forward_via_connection(forwarder, msgbuf_id, nexthop);
// everytime we send out a message we need to restore the original path
// label of the message this is important because we keep a single copy
// of the message (single pointer) and we modify the path label at each
// send.
- if (msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA)
+ if (msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA)
msgbuf_set_pathlabel(msgbuf, old_path_label);
});
@@ -591,12 +580,15 @@ forwarder_forward_to_nexthops(forwarder_t * forwarder,
static
bool
-forwarder_forward_via_fib(forwarder_t * forwarder, msgbuf_t *msgbuf,
+forwarder_forward_via_fib(forwarder_t * forwarder, off_t msgbuf_id,
pit_verdict_t verdict)
{
assert(forwarder);
- assert(msgbuf);
- assert(msgbuf_get_type(msgbuf) == MESSAGE_TYPE_INTEREST);
+ assert(msgbuf_id_is_valid(msgbuf_id));
+
+ const msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+ assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
fib_entry_t *fib_entry = fib_match_message(forwarder->fib, msgbuf);
if (!fib_entry)
@@ -650,7 +642,7 @@ forwarder_forward_via_fib(forwarder_t * forwarder, msgbuf_t *msgbuf,
entry_Release(&entry);
#endif
- if (forwarder_forward_to_nexthops(forwarder, msgbuf, nexthops) <= 0) {
+ if (forwarder_forward_to_nexthops(forwarder, msgbuf_id, nexthops) <= 0) {
DEBUG("Message %p returned an emtpy next hop set", msgbuf);
return false;
}
@@ -661,43 +653,49 @@ forwarder_forward_via_fib(forwarder_t * forwarder, msgbuf_t *msgbuf,
static
bool
-_satisfy_from_content_store(forwarder_t * forwarder, msgbuf_t *interest_msgbuf)
+_satisfy_from_cs(forwarder_t * forwarder, off_t msgbuf_id)
{
assert(forwarder);
- assert(msgbuf_get_type(interest_msgbuf) == MESSAGE_TYPE_INTEREST);
+ assert(msgbuf_id_is_valid(msgbuf_id));
+
+ const msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+
+ assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
- if (msgbuf_get_interest_lifetime(interest_msgbuf) == 0)
+ if (msgbuf_get_lifetime(msgbuf) == 0)
return false;
- if (!forwarder->serve_from_content_store)
+ if (!forwarder->serve_from_cs)
return false;
// See if there's a match in the store.
- msgbuf_t * data_msgbuf = content_store_match(forwarder->content_store,
- interest_msgbuf, ticks_now());
+ off_t data_msgbuf_id = cs_match(forwarder_get_cs(forwarder), msgbuf_id,
+ ticks_now());
- if (!data_msgbuf)
+ if (msgbuf_id_is_valid(data_msgbuf_id))
return false;
// Remove it from the PIT. nexthops is allocated, so need to destroy
- nexthops_t * nexthops = pit_on_data(forwarder->pit, data_msgbuf);
+ nexthops_t * nexthops = pit_on_data(forwarder->pit, data_msgbuf_id);
assert(nexthops); // Illegal state: got a null nexthops for an interest we just inserted
// send message in reply, then done
forwarder->stats.countInterestsSatisfiedFromStore++;
- DEBUG("Message %p satisfied from content store (satisfied count %u)",
- interest_msgbuf, forwarder->stats.countInterestsSatisfiedFromStore);
+ DEBUG("Message %lu satisfied from content store (satisfied count %u)",
+ msgbuf_id, forwarder->stats.countInterestsSatisfiedFromStore);
+ msgbuf_t * data_msgbuf = msgbuf_pool_at(msgbuf_pool, data_msgbuf_id);
msgbuf_reset_pathlabel(data_msgbuf);
- forwarder_forward_to_nexthops(forwarder, data_msgbuf, nexthops);
+ forwarder_forward_to_nexthops(forwarder, data_msgbuf_id, nexthops);
return true;
}
/**
- * @function forwarder_receive_interest
+ * @function forwarder_process_interest
* @abstract Receive an interest from the network
* @discussion
* (1) if interest in the PIT, aggregate in PIT
@@ -707,22 +705,34 @@ _satisfy_from_content_store(forwarder_t * forwarder, msgbuf_t *interest_msgbuf)
*
*/
static
-void
-forwarder_receive_interest(forwarder_t * forwarder, msgbuf_t * msgbuf)
+ssize_t
+forwarder_process_interest(forwarder_t * forwarder, off_t msgbuf_id)
{
assert(forwarder);
- assert(msgbuf);
- assert(msgbuf_get_type(msgbuf) == MESSAGE_TYPE_INTEREST);
+ assert(msgbuf_id_is_valid(msgbuf_id));
+
+ const msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+
+ assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
+
+ forwarder->stats.countReceived++;
forwarder->stats.countInterestsReceived++;
+ char *nameString = name_ToString(msgbuf_get_name(msgbuf));
+ DEBUG( "Message %p ingress %3u length %5u received name %s", msgbuf,
+ msgbuf_get_connection_id(msgbuf), msgbuf_get_len(msgbuf), nameString);
+ free(nameString);
+
+
// (1) Try to aggregate in PIT
- pit_verdict_t verdict = pit_on_interest(forwarder->pit, msgbuf);
+ pit_verdict_t verdict = pit_on_interest(forwarder->pit, msgbuf_id);
switch(verdict) {
case PIT_VERDICT_AGGREGATE:
forwarder->stats.countInterestsAggregated++;
DEBUG("Message %p aggregated in PIT (aggregated count %u)",
msgbuf, forwarder->stats.countInterestsAggregated);
- return;
+ return msgbuf_get_len(msgbuf);
case PIT_VERDICT_FORWARD:
case PIT_VERDICT_RETRANSMIT:
@@ -735,30 +745,30 @@ forwarder_receive_interest(forwarder_t * forwarder, msgbuf_t * msgbuf)
// interest, we need to remove the PIT entry.
// (2) Try to satisfy from content store
- if (_satisfy_from_content_store(forwarder, msgbuf)) {
+ if (_satisfy_from_cs(forwarder, msgbuf_id)) {
// done
// If we found a content object in the CS,
- // messageProcess_Satisfy_from_content_store already cleared the PIT state
- return;
+ // messageProcess_Satisfy_from_cs already cleared the PIT state
+ return msgbuf_get_len(msgbuf);
}
// (3) Try to forward it
- if (forwarder_forward_via_fib(forwarder, msgbuf, verdict)) {
+ if (forwarder_forward_via_fib(forwarder, msgbuf_id, verdict)) {
// done
- return;
+ return msgbuf_get_len(msgbuf);
}
// Remove the PIT entry?
forwarder->stats.countDroppedNoRoute++;
- DEBUG("Message %p did not match FIB, no route (count %u)",
- msgbuf, forwarder->stats.countDroppedNoRoute);
+ DEBUG("Message %lu did not match FIB, no route (count %u)",
+ msgbuf_id, forwarder->stats.countDroppedNoRoute);
- forwarder_drop(forwarder, msgbuf);
+ return forwarder_drop(forwarder, msgbuf_id);
}
/**
- * @function forwarder_receive_data
+ * @function forwarder_process_data
* @abstract Process an in-bound content object
* @discussion
* (1) If it does not match anything in the PIT, drop it
@@ -768,19 +778,27 @@ forwarder_receive_interest(forwarder_t * forwarder, msgbuf_t * msgbuf)
* @param <#param1#>
*/
static
-void
-forwarder_receive_data(forwarder_t * forwarder,
- msgbuf_t *msgbuf)
+ssize_t
+forwarder_process_data(forwarder_t * forwarder, off_t msgbuf_id)
{
+ const msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+
+ char *nameString = name_ToString(msgbuf_get_name(msgbuf));
+ DEBUG( "Message %lu ingress %3u length %5u received name %s", msgbuf_id,
+ msgbuf_get_connection_id(msgbuf), msgbuf_get_len(msgbuf), nameString);
+ free(nameString);
+
+ forwarder->stats.countReceived++;
forwarder->stats.countObjectsReceived++;
- nexthops_t * ingressSetUnion = pit_on_data(forwarder->pit, msgbuf);
+ nexthops_t * ingressSetUnion = pit_on_data(forwarder->pit, msgbuf_id);
if (!ingressSetUnion) {
// (1) If it does not match anything in the PIT, drop it
forwarder->stats.countDroppedNoReversePath++;
- DEBUG("Message %p did not match PIT, no reverse path (count %u)",
- msgbuf, forwarder->stats.countDroppedNoReversePath);
+ DEBUG("Message %lu did not match PIT, no reverse path (count %u)",
+ msgbuf_id, forwarder->stats.countDroppedNoReversePath);
// MOVE PROBE HOOK ELSEWHERE
// XXX relationship with forwarding strategy... insert hooks
@@ -803,95 +821,68 @@ forwarder_receive_data(forwarder_t * forwarder,
const connection_table_t * table = forwarder_get_connection_table(forwarder);
const connection_t * conn = connection_table_get_by_id(table, msgbuf_get_connection_id(msgbuf));
- if (forwarder->store_in_content_store && connection_is_local(conn)) {
- content_store_add(forwarder->content_store, msgbuf, ticks_now());
+ if (forwarder->store_in_cs && connection_is_local(conn)) {
+ cs_add(forwarder->cs, msgbuf_id, ticks_now());
DEBUG("Message %p store in CS anyway", msgbuf);
}
- forwarder_drop(forwarder, msgbuf);
+ return forwarder_drop(forwarder, msgbuf_id);
} else {
// (2) Add to Content Store. Store may remove expired content, if necessary,
// depending on store policy.
- if (forwarder->store_in_content_store) {
- content_store_add(forwarder->content_store, msgbuf, ticks_now());
+ if (forwarder->store_in_cs) {
+ cs_add(forwarder->cs, msgbuf_id, ticks_now());
}
// (3) Reverse path forward via PIT entries
- forwarder_forward_to_nexthops(forwarder, msgbuf, ingressSetUnion);
+ return forwarder_forward_to_nexthops(forwarder, msgbuf_id, ingressSetUnion);
}
}
-
-/**
- * A NULL msgbuf is used to indicate the end of a batch
- */
void
-forwarder_receive(forwarder_t * forwarder, msgbuf_t * msgbuf)
+forwarder_flush_connections(forwarder_t * forwarder)
{
- assert(forwarder);
-
- /* Send batch ? */
- if (!msgbuf) {
- const connection_table_t * table = forwarder_get_connection_table(forwarder);
- for (unsigned i = 0; i < forwarder->num_pending_conn; i++) {
- const connection_t * conn = connection_table_at(table, forwarder->pending_conn[i]);
- // flush
- connection_send(conn, NULL, false);
+ const connection_table_t * table = forwarder_get_connection_table(forwarder);
+
+ for (unsigned i = 0; i < forwarder->num_pending_conn; i++) {
+ unsigned conn_id = forwarder->pending_conn[i];
+ const connection_t * conn = connection_table_at(table, conn_id);
+ if (!connection_flush(conn)) {
+ WARN("Could not flush connection queue");
+ // XXX keep track of non flushed connections...
}
- forwarder->num_pending_conn = 0;
}
+ forwarder->num_pending_conn = 0;
+}
+// XXX move to wldr file, worst case in connection.
+void
+forwarder_apply_wldr(const forwarder_t * forwarder, const msgbuf_t * msgbuf, connection_t * connection)
+{
// this are the checks needed to implement WLDR. We set wldr only on the STAs
- // and we let the AP to react according to choise of the client.
+ // and we let the AP to react according to choice of the client.
// if the STA enables wldr using the set command, the AP enable wldr as well
// otherwise, if the STA disable it the AP remove wldr
// WLDR should be enabled only on the STAs using the command line
// TODO
// disable WLDR command line on the AP
- connection_table_t * table = forwarder_get_connection_table(forwarder);
- connection_t * conn = connection_table_get_by_id(table, msgbuf_get_connection_id(msgbuf));
- if (!conn)
- return;
-
if (msgbuf_has_wldr(msgbuf)) {
- if (connection_has_wldr(conn)) {
+ if (connection_has_wldr(connection)) {
// case 1: WLDR is enabled
- connection_wldr_detect_losses(conn, msgbuf);
- } else if (!connection_has_wldr(conn) &&
- connection_wldr_autostart_is_allowed(conn)) {
+ connection_wldr_detect_losses(connection, msgbuf);
+ } else if (!connection_has_wldr(connection) &&
+ connection_wldr_autostart_is_allowed(connection)) {
// case 2: We are on an AP. We enable WLDR
- connection_wldr_enable(conn, true);
- connection_wldr_detect_losses(conn, msgbuf);
+ connection_wldr_enable(connection, true);
+ connection_wldr_detect_losses(connection, msgbuf);
}
// case 3: Ignore WLDR
} else {
- if (connection_has_wldr(conn) && connection_wldr_autostart_is_allowed(conn)) {
+ if (connection_has_wldr(connection) && connection_wldr_autostart_is_allowed(connection)) {
// case 1: STA do not use WLDR, we disable it
- connection_wldr_enable(conn, false);
+ connection_wldr_enable(connection, false);
}
}
-
- forwarder->stats.countReceived++;
-
- char *nameString = name_ToString(msgbuf_get_name(msgbuf));
- DEBUG( "Message %p ingress %3u length %5u received name %s", msgbuf,
- msgbuf_get_connection_id(msgbuf), msgbuf_get_len(msgbuf), nameString);
- free(nameString);
-
- switch (msgbuf_get_type(msgbuf)) {
- case MESSAGE_TYPE_INTEREST:
- forwarder_receive_interest(forwarder, msgbuf);
- break;
-
- case MESSAGE_TYPE_DATA:
- forwarder_receive_data(forwarder, msgbuf);
- break;
-
- default:
- forwarder_drop(forwarder, msgbuf);
- break;
- }
-
}
bool
@@ -1006,7 +997,7 @@ forwarder_set_strategy(forwarder_t * forwarder, Name * name_prefix,
{
assert(forwarder);
assert(name_prefix);
- // assert(strategy_type_is_valid(strategy_type));
+ assert(STRATEGY_TYPE_VALID(strategy_type));
/* strategy_options might be NULL */
fib_entry_t * entry = fib_contains(forwarder->fib, name_prefix);
@@ -1016,12 +1007,12 @@ forwarder_set_strategy(forwarder_t * forwarder, Name * name_prefix,
fib_entry_set_strategy(entry, strategy_type, strategy_options);
}
-content_store_t *
-forwarder_get_content_store(const forwarder_t * forwarder)
+cs_t *
+forwarder_get_cs(const forwarder_t * forwarder)
{
assert(forwarder);
- return forwarder->content_store;
+ return forwarder->cs;
}
// =======================================================
@@ -1055,10 +1046,17 @@ static void _signal_cb(int sig, PARCEventType events, void *user_data) {
#endif
fib_t *
-forwarder_get_fib(forwarder_t * forwarder) {
+forwarder_get_fib(forwarder_t * forwarder)
+{
return forwarder->fib;
}
+msgbuf_pool_t *
+forwarder_get_msgbuf_pool(const forwarder_t * forwarder)
+{
+ return forwarder->msgbuf_pool;
+}
+
#ifdef WITH_MAPME
void
forwarder_on_connection_event(const forwarder_t * forwarder,
@@ -1082,116 +1080,120 @@ forwarder_get_prefix_stats_mgr(const forwarder_t * forwarder)
}
#endif /* WITH_PREFIX_STATS */
-static
-void
-process_interest(forwarder_t * forwarder, listener_t * listener,
- unsigned conn_id, uint8_t * packet, size_t size, const address_pair_t * pair)
-{
- if (!connection_id_is_valid(conn_id)) {
- conn_id = listener_create_connection(listener, pair);
- }
-
- assert(messageHandler_GetTotalPacketLength(packet) == size);
-
- msgbuf_from_packet(&forwarder->msgbuf, packet, size, MESSAGE_TYPE_INTEREST, conn_id, ticks_now());
- forwarder_receive(listener->forwarder, &forwarder->msgbuf);
-}
+/**
+ * @brief Process a packet by creating the corresponding message buffer and
+ * dispatching it to the forwarder for further processing.
+ * @param[in] forwarder Forwarder instance.
+ *
+ */
+// XXX ??? XXX = process for listener as we are resolving connection id
+//
-static
-void
-process_data(forwarder_t * forwarder, listener_t * listener,
- unsigned conn_id, uint8_t * packet, size_t size, const address_pair_t * pair)
+msgbuf_type_t get_type_from_packet(uint8_t * packet)
{
- if (!connection_id_is_valid(conn_id)) {
- INFO("Ignoring data packet associated to no connection");
- return;
- }
+ if (messageHandler_IsTCP(packet)) {
+ if (messageHandler_IsData(packet)) {
+ return MSGBUF_TYPE_DATA;
+ } else if (messageHandler_IsInterest(packet)) {
+ return MSGBUF_TYPE_INTEREST;
+ } else {
+ return MSGBUF_TYPE_UNDEFINED;
+ }
- assert(messageHandler_GetTotalPacketLength(packet) == size);
+ } else if (messageHandler_IsWldrNotification(packet)) {
+ return MSGBUF_TYPE_WLDR_NOTIFICATION;
- msgbuf_from_packet(&forwarder->msgbuf, packet, size, MESSAGE_TYPE_DATA, conn_id, ticks_now());
- forwarder_receive(listener->forwarder, &forwarder->msgbuf);
+ } else if (mapme_match_packet(packet)) {
+ return MSGBUF_TYPE_MAPME;
-}
+ } else if (*packet == REQUEST_LIGHT) {
+ return MSGBUF_TYPE_COMMAND;
-static
-void
-process_wldr_notification(forwarder_t * forwarder, listener_t * listener,
- unsigned conn_id, uint8_t * packet, size_t size, const address_pair_t * pair)
-{
- if (!connection_id_is_valid(conn_id)) {
- INFO("Ignoring WLDR notification not associated to a connection");
- return;
+ } else {
+ return MSGBUF_TYPE_UNDEFINED;
}
-
- assert(messageHandler_GetTotalPacketLength(packet) == size);
-
- connection_table_t * table = forwarder_get_connection_table(forwarder);
- connection_t * connection = connection_table_at(table, conn_id);
-
- msgbuf_from_packet(&forwarder->msgbuf, packet, size, MESSAGE_TYPE_WLDR_NOTIFICATION, conn_id, ticks_now());
- connection_wldr_handle_notification(connection, &forwarder->msgbuf);
-
}
-static
-void
-process_mapme(forwarder_t * forwarder, listener_t * listener,
- unsigned conn_id, uint8_t * packet, size_t size, const address_pair_t * pair)
+ssize_t
+forwarder_receive(forwarder_t * forwarder, listener_t * listener,
+ off_t msgbuf_id, address_pair_t * pair, Ticks now)
{
- if (!connection_id_is_valid(conn_id))
- conn_id = listener_create_connection(listener, pair);
- mapme_process(forwarder->mapme, packet, conn_id);
-}
+ assert(forwarder);
+ /* listener can be NULL */
+ assert(msgbuf_id_is_valid(msgbuf_id));
+ assert(pair);
-static
-void
-process_command(const forwarder_t * forwarder, listener_t * listener,
- unsigned conn_id, uint8_t * packet, size_t size, const address_pair_t * pair)
-{
- if (!connection_id_is_valid(conn_id))
- conn_id = listener_create_connection(listener, pair);
+ const msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
- command_type_t command_type= *(packet + 1);
- if (command_type >= COMMAND_TYPE_N) {
- ERROR("Invalid command");
- return;
- }
- forwarder_receive_command(listener->forwarder, command_type, packet, conn_id);
+ assert(msgbuf);
-}
+ uint8_t * packet = msgbuf_get_packet(msgbuf);
+ size_t size = msgbuf_get_len(msgbuf);
+ assert(messageHandler_GetTotalPacketLength(packet) == size); // XXX confirm ?
-// = process for listener as we are resolving connection id
-// XXX this would typically be inside the forwarder
-void
-process_packet(forwarder_t * forwarder, listener_t * listener, uint8_t * packet, size_t size, address_pair_t * pair)
-{
/* Connection lookup */
const connection_table_t * table = forwarder_get_connection_table(listener->forwarder);
- const connection_t * conn = connection_table_get_by_pair(table, pair);
- unsigned conn_id = conn ? connection_table_get_connection_id(table, conn): CONNECTION_ID_UNDEFINED;
+ connection_t * connection = connection_table_get_by_pair(table, pair);
+ unsigned conn_id = connection
+ ? connection_table_get_connection_id(table, connection)
+ : CONNECTION_ID_UNDEFINED;
assert((conn_id != CONNECTION_ID_UNDEFINED) || listener);
- // Actually hooks should be defined for each packet type to avoid this
- // spaghetti code
- if (messageHandler_IsTCP(packet)) {
- if (messageHandler_IsData(packet)) {
- process_data(forwarder, listener, conn_id, packet, size, pair);
- } else if (messageHandler_IsInterest(packet)) {
- process_interest(forwarder, listener, conn_id, packet, size, pair);
- } else {
- INFO("Unknown TCP packet received");
- forwarder_drop(forwarder, NULL);
- }
- } else if (messageHandler_IsWldrNotification(packet)) {
- process_wldr_notification(forwarder, listener, conn_id, packet, size, pair);
- } else if (mapme_match_packet(packet)) {
- process_mapme(forwarder, listener, conn_id, packet, size, pair);
- } else if (*packet == REQUEST_LIGHT) {
- process_command(forwarder, listener, conn_id, packet, size, pair);
- } else {
- INFO("Unknown packet received");
- forwarder_drop(forwarder, NULL);
+ msgbuf_type_t type = get_type_from_packet(msgbuf_get_packet(msgbuf));
+
+ msgbuf->type = type;
+ msgbuf->connection_id = conn_id;
+ msgbuf->recv_ts = now;
+ msgbuf->refs = 1;
+
+ switch(type) {
+ case MSGBUF_TYPE_INTEREST:
+ if (!connection_id_is_valid(msgbuf->connection_id))
+ msgbuf->connection_id = listener_create_connection(listener, pair);
+ msgbuf->id.name = name_create_from_interest(packet);
+ forwarder_apply_wldr(forwarder, msgbuf, connection);
+ forwarder_process_interest(forwarder, msgbuf_id);
+ break;
+
+ case MSGBUF_TYPE_DATA:
+ if (!connection_id_is_valid(msgbuf->connection_id))
+ return forwarder_drop(forwarder, msgbuf_id);
+ msgbuf->id.name = name_create_from_data(packet);
+ forwarder_apply_wldr(forwarder, msgbuf, connection);
+ forwarder_process_data(forwarder, msgbuf_id);
+ break;
+
+ case MSGBUF_TYPE_WLDR_NOTIFICATION:
+ if (!connection_id_is_valid(msgbuf->connection_id))
+ return forwarder_drop(forwarder, msgbuf_id);
+ connection_wldr_handle_notification(connection, msgbuf);
+ return msgbuf_get_len(msgbuf);
+
+ case MSGBUF_TYPE_MAPME:
+ // XXX what about acks ?
+ if (!connection_id_is_valid(msgbuf->connection_id))
+ msgbuf->connection_id = listener_create_connection(listener, pair);
+ mapme_process(forwarder->mapme, msgbuf);
+ return msgbuf_get_len(msgbuf);
+
+ case MSGBUF_TYPE_COMMAND:
+ // XXX before it used to create the connection
+ if (!connection_id_is_valid(msgbuf->connection_id))
+ return forwarder_drop(forwarder, msgbuf_id);
+ msgbuf->command.type = *(packet + 1); // XXX use header
+ if (msgbuf->command.type >= COMMAND_TYPE_N) {
+ ERROR("Invalid command");
+ return -msgbuf_get_len(msgbuf);
+ }
+ return configuration_receive_command(forwarder->config, msgbuf);
+
+ case MSGBUF_TYPE_UNDEFINED:
+ case MSGBUF_TYPE_N:
+ // XXX Unexpected... shall we abort ?
+ return forwarder_drop(forwarder, msgbuf_id);
}
+
+ return size;
}
diff --git a/hicn-light/src/hicn/core/forwarder.h b/hicn-light/src/hicn/core/forwarder.h
index 5d999a319..a76e36530 100644
--- a/hicn-light/src/hicn/core/forwarder.h
+++ b/hicn-light/src/hicn/core/forwarder.h
@@ -18,8 +18,8 @@
* only be called within the forwarders thread of execution.
*/
-#ifndef forwarder_h
-#define forwarder_h
+#ifndef HICNLIGHT_FORWARDER_H
+#define HICN_LIGHT_FORWARDER_H
//#ifndef _WIN32
//#include <sys/time.h>
@@ -34,6 +34,7 @@
#include <hicn/core/connection.h>
#include <hicn/core/connection_table.h>
#include <hicn/core/listener_table.h>
+#include <hicn/core/msgbuf_pool.h>
#include <hicn/config/configuration.h>
@@ -46,27 +47,12 @@
#include <hicn/utils/commands.h>
-#define MAX_MSG 64 //16 //32
-#define MTU 1500
-
-
-typedef struct batch_buffer_s {
- /* sendmmsg / recvmmsg data structures */
- struct mmsghdr msghdr[MAX_MSG]; // XXX = {0};
- char buffers[MAX_MSG][MTU];
- struct iovec iovecs[MAX_MSG]; // XXX = {0};
- struct sockaddr_storage addrs[MAX_MSG];
-} batch_buffer_t;
-
-int init_batch_buffers(batch_buffer_t * bb);
-
// ==============================================
typedef struct forwarder_s forwarder_t;
/**
- * @function forwarder_Create
- * @abstract Create the forwarder and use the provided logger for diagnostic
+ * @brief Create the forwarder and use the provided logger for diagnostic
* output
* @discussion
* If the logger is null, hicn-light will create a STDOUT logger.
@@ -76,14 +62,12 @@ typedef struct forwarder_s forwarder_t;
forwarder_t * forwarder_create();
/**
- * @function forwarder_Destroy
- * @abstract Destroys the forwarder, stopping all traffic and freeing all memory
+ * @brief Destroys the forwarder, stopping all traffic and freeing all memory
*/
void forwarder_free(forwarder_t * forwarder);
/**
- * @function forwarder_SetupAllListeners
- * @abstract Setup all listeners (tcp, udp, local, ether, ip multicast) on all
+ * @brief Setup all listeners (tcp, udp, local, ether, ip multicast) on all
* interfaces
* @discussion
* Sets up all listeners on all running interfaces. This provides a quick and
@@ -97,8 +81,7 @@ void forwarder_free(forwarder_t * forwarder);
void forwarder_setup_all_listeners(forwarder_t * forwarder, uint16_t port, const
char *local_path);
/**
- * @function forwarder_SetupAllListeners
- * @abstract Setup one tcp and one udp listener on address 127.0.0.1 and the
+ * @brief Setup one tcp and one udp listener on address 127.0.0.1 and the
* given port
*/
void forwarder_setup_local_listeners(forwarder_t * forwarder, uint16_t port);
@@ -110,14 +93,13 @@ void forwarder_setup_local_listeners(forwarder_t * forwarder, uint16_t port);
* You need to have "add listener" lines in the file to receive connections. No
* default listeners are configured.
*
- * @param [in] forwarder An alloated forwarder_t
- * @param [in] filename The path to the configuration file
+ * @param[in] forwarder An alloated forwarder_t
+ * @param[in] filename The path to the configuration file
*/
void forwarder_read_config(forwarder_t * forwarder, const char * filename);
/**
- * @function forwarder_GetConfiguration
- * @abstract The configuration object
+ * @brief The configuration object
* @discussion
* The configuration contains all user-issued commands. It does not include
* dynamic state.
@@ -127,7 +109,7 @@ configuration_t * forwarder_get_configuration(forwarder_t * forwarder);
/**
* Returns the set of currently active listeners
*
- * @param [in] forwarder An allocated hicn-light forwarder
+ * @param[in] forwarder An allocated hicn-light forwarder
*
* @retval non-null The set of active listeners
* @retval null An error
@@ -137,7 +119,7 @@ listener_table_t * forwarder_get_listener_table(forwarder_t *forwarder);
/**
* Returns the forwrder's connection table
*
- * @param [in] forwarder An allocated hicn-light forwarder
+ * @param[in] forwarder An allocated hicn-light forwarder
*
* @retval non-null The connection tabler
* @retval null An error
@@ -145,54 +127,46 @@ listener_table_t * forwarder_get_listener_table(forwarder_t *forwarder);
*/
connection_table_t * forwarder_get_connection_table(const forwarder_t *forwarder);
-void forwarder_content_store_set_store(forwarder_t * forwarder, bool val);
+void forwarder_cs_set_store(forwarder_t * forwarder, bool val);
-bool forwarder_content_store_get_store(forwarder_t * forwarder);
+bool forwarder_cs_get_store(forwarder_t * forwarder);
-void forwarder_content_store_set_serve(forwarder_t * forwarder, bool val);
+void forwarder_cs_set_serve(forwarder_t * forwarder, bool val);
-bool forwarder_content_store_get_serve(forwarder_t * forwarder);
+bool forwarder_cs_get_serve(forwarder_t * forwarder);
/**
* Sets the maximum number of content objects in the content store
*
* Implementation dependent - may wipe the cache.
*/
-void forwarder_content_store_set_size(forwarder_t * forwarder, size_t size);
+void forwarder_cs_set_size(forwarder_t * forwarder, size_t size);
-void forwarder_content_store_clear(forwarder_t *forwarder);
+void forwarder_cs_clear(forwarder_t *forwarder);
-void forwarder_receive_command(forwarder_t * forwarder, command_type_t command_type,
- uint8_t * packet, unsigned connection_id);
-
-void forwarder_receive(forwarder_t * forwarder, msgbuf_t * message);
+ssize_t forwarder_receive_command(forwarder_t * forwarder, msgbuf_t * msgbuf);
/**
- * @function forwarder_add_or_update_route
- * @abstract Adds or updates a route on all the message processors
+ * @brief Adds or updates a route on all the message processors
*/
bool forwarder_add_or_update_route(forwarder_t * forwarder,
ip_prefix_t * prefix, unsigned ingress_id);
/**
- * @function forwarder_remove_route
- * @abstract Removes a route from all the message processors
+ * @brief Removes a route from all the message processors
*/
bool forwarder_remove_route(forwarder_t * forwarder, ip_prefix_t * prefix,
unsigned ingress_id);
#ifdef WITH_POLICY
/**
- * @function forwarder_add_or_update_policy
- * @abstract Adds or updates a policy on the message processor
+ * @brief Adds or updates a policy on the message processor
*/
bool forwarder_add_or_update_policy(forwarder_t * forwarder,
ip_prefix_t * prefix, policy_t * policy);
-
/**
- * @function forwarder_RemovePolicy
- * @abstract Removes a policy from the message processor
+ * @brief Removes a policy from the message processor
*/
bool forwarder_remove_policy(forwarder_t * forwarder, ip_prefix_t * prefix);
@@ -207,37 +181,42 @@ void forwarder_remove_connection_id_from_routes(forwarder_t * forwarder,
void forwarder_set_strategy(forwarder_t * forwarder, Name * name_prefix,
strategy_type_t strategy_type, strategy_options_t * strategy_options);
-content_store_t * forwarder_get_content_store(const forwarder_t * forwarder);
+cs_t * forwarder_get_cs(const forwarder_t * forwarder);
/**
- * @function forwarder_getFib
- * @abstract Returns the hICN forwarder's FIB.
- * @param [in] forwarder - Pointer to the hICN forwarder.
+ * @brief Returns the forwarder's FIB.
+ * @param[in] forwarder - Pointer to the forwarder.
* @returns Pointer to the hICN FIB.
*/
fib_t * forwarder_get_fib(forwarder_t * forwarder);
+/**
+ * @brief Return the forwarder packet pool.
+ * @param[in] forwarder The forwarder from which to retrieve the packet
+ * pool.
+ * @return msgbuf_pool_t * The forwarder packet pool.
+ */
+msgbuf_pool_t * forwarder_get_msgbuf_pool(const forwarder_t * forwarder);
+
#ifdef WITH_MAPME
/**
- * @function forwarder_onConnectionEvent
- * @abstract Callback fired upon addition of a new connection through the
+ * @brief Callback fired upon addition of a new connection through the
* control protocol.
- * @param [in] forwarder - Pointer to the hICN forwarder.
- * @param [in] conn - Pointer to the newly added connection.
- * @param [in] event - Connection event
+ * @param[in] forwarder - Pointer to the forwarder.
+ * @param[in] conn - Pointer to the newly added connection.
+ * @param[in] event - Connection event
*/
void forwarder_on_connection_event(const forwarder_t * forwarder,
const connection_t * connection, connection_event_t event);
/**
- * @function forwarder_ProcessMapMe
- * @abstract Callback fired by an hICN listener upon reception of a MAP-Me
+ * @brief Callback fired by an hICN listener upon reception of a MAP-Me
* message.
- * @param [in] forwarder - Pointer to the hICN forwarder.
- * @param [in] msgBuffer - MAP-Me buffer
- * @param [in] conn_id - Ingress connection id
+ * @param[in] forwarder - Pointer to the forwarder.
+ * @param[in] msgBuffer - MAP-Me buffer
+ * @param[in] conn_id - Ingress connection id
*/
void forwarder_process_mapme(const forwarder_t * forwarder, const uint8_t * packet,
unsigned conn_id);
@@ -250,7 +229,15 @@ struct mapme_s * forwarder_get_mapme(const forwarder_t * forwarder);
const prefix_stats_mgr_t * forwarder_get_prefix_stats_mgr(const forwarder_t * forwarder);
#endif /* WITH_PREFIX_STATS */
-void process_packet(forwarder_t * forwarder, listener_t * listener,
- uint8_t * packet, size_t size, address_pair_t * pair);
+void forwarder_flush_connections(forwarder_t * forwarder);
+
+/**
+ * @brief Handles a newly received packet from a listener.
+ *
+ * NOTE: the received msgbuf is incomplete and only holds the packet content and
+ * size/
+ */
+ssize_t forwarder_receive(forwarder_t * forwarder, listener_t * listener,
+ off_t msgbuf_id, address_pair_t * pair, Ticks now);
-#endif // forwarder_h
+#endif // HICN_LIGHT_FORWARDER_H
diff --git a/hicn-light/src/hicn/core/listener.c b/hicn-light/src/hicn/core/listener.c
index 5857c0c88..d24fafba0 100644
--- a/hicn-light/src/hicn/core/listener.c
+++ b/hicn-light/src/hicn/core/listener.c
@@ -19,14 +19,14 @@
*/
-
#include <string.h> // strdup
-#include <hicn/core/listener_vft.h>
-#include <hicn/base/loop.h>
-#include <hicn/core/forwarder.h>
#include <hicn/util/log.h>
-#include "listener.h"
+
+#include "forwarder.h"
+#include "listener_vft.h"
+#include "../base/loop.h"
+#include "../io/base.h"
listener_t *
listener_create(face_type_t type, const address_t * address,
@@ -89,7 +89,7 @@ listener_initialize(listener_t * listener, face_type_t type, const char * name,
// XXX data should be pre-allocated here
loop_fd_event_create(&listener->event_data, MAIN_LOOP, listener->fd, listener,
- (fd_callback_t)listener_vft[listener->type]->read_callback, NULL);
+ (fd_callback_t)listener_read_callback, NULL);
if (!listener->event_data) {
goto ERR_REGISTER_FD;
@@ -151,7 +151,8 @@ int listener_get_socket(const listener_t * listener, const address_t * local,
{
assert(listener);
assert(listener_has_valid_type(listener));
- // assert(pair);
+ assert(local);
+ assert(remote);
return listener_vft[listener->type]->get_socket(listener, local, remote,
interface_name);
@@ -201,63 +202,115 @@ listener_punt(const listener_t * listener, const char * prefix_s)
return listener_vft[listener_get_type(listener)]->punt(listener, prefix_s);
}
+
ssize_t
-listener_read_callback(forwarder_t * forwarder, listener_t * listener, int fd,
- address_t * local_addr, uint8_t * packet, size_t size)
+listener_read_single(listener_t * listener)
{
- // XXX TODO mutualize code across all listeners
- // some do not support batches
- //
- // XXX negative in case of error
- // 0 if we don't consume yet because we don't have enough
- // needed for TCP !!
- return size;
+ assert(listener);
+
+ size_t processed_size;
+ size_t total_size = 0;
+
+ msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(listener->forwarder);
+
+ for (;;) {
+
+ msgbuf_t * msgbuf = NULL;
+ off_t msgbuf_id = msgbuf_pool_get(msgbuf_pool, msgbuf);
+ if (!msgbuf_id_is_valid(msgbuf_id))
+ return 0;
+
+ address_pair_t pair;
+ pair.local = *listener_get_address(listener);
+
+ ssize_t n = listener_vft[listener->type]->read_single(listener->fd, msgbuf,
+ address_pair_get_remote(&pair));
+ if (n < 1)
+ return 0;
+
+ /* Process received packet */
+ processed_size = forwarder_receive(listener->forwarder, listener,
+ msgbuf_id, &pair, ticks_now());
+ if (processed_size <= 0)
+ break;
+
+ total_size += processed_size;
+ }
+
+ /*
+ * Even through the current listener does not allow batching, the connection
+ * on which we went packets might do batching (even without sendmmsg), and
+ * we need to inform the system that we want to proceed to sending packets.
+ */
+ forwarder_flush_connections(listener->forwarder);
+ return total_size;
+
}
-void
-listener_batch_read_callback(forwarder_t * forwarder, listener_t * listener,
- int fd, address_t * local_addr, batch_buffer_t * bb)
+ssize_t
+listener_read_batch(listener_t * listener)
{
- assert(bb);
+ assert(listener);
- // XXX potential improvement : receive in a loop while we have messages to
- // read
+ size_t processed_size;
+ size_t total_size = 0;
+
+ forwarder_t * forwarder = listener->forwarder;
+ msgbuf_pool_t * msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ /* Receive messages in the loop as long as we manage to fill the buffers */
+ int r = 0;
+ do {
+ /* Prepare the msgbuf and address pair arrays */
+ msgbuf_t * msgbuf[MAX_MSG];
+ if (!msgbuf_pool_getn(msgbuf_pool, msgbuf, MAX_MSG))
+ break;
+
+ address_pair_t pair[MAX_MSG];
+ address_t * address_remote[MAX_MSG];
+ for (unsigned i = 0; i < MAX_MSG; i++)
+ address_remote[i] = address_pair_get_remote(&pair[i]);
+
+ ssize_t n = listener_vft[listener->type]->read_batch(listener->fd,
+ msgbuf, address_remote, MAX_MSG);
+ // XXX error check
+
+ for (unsigned i = 0; i < n; i++) {
+ processed_size = forwarder_receive(forwarder, listener,
+ msgbuf_pool_get_id(msgbuf_pool, msgbuf[i]),
+ &pair[i], ticks_now());
+ if (processed_size <= 0)
+ break;
+
+ total_size += processed_size;
+ }
- // XXX
- int r = recvmmsg(fd, bb->msghdr, MAX_MSG, 0, NULL);
- if (r == 0)
- return;
+ } while(r == MAX_MSG); /* backpressure based on queue size ? */
- if (r < 0) {
- if (errno == EINTR)
- return;
- perror("recv()");
- return;
- }
+ /*
+ * Signal to the forwarder that we reached the end of a batch and we need to
+ * flush connections out
+ */
+ forwarder_flush_connections(forwarder);
- for (int i = 0; i < r; i++) {
- struct mmsghdr *msg = &bb->msghdr[i];
- uint8_t * packet = msg->msg_hdr.msg_iov->iov_base;
- size_t size = msg->msg_hdr.msg_iovlen;
+ return total_size;
- /* BEGIN packet processing */
+}
-#ifdef __APPLE__
- // XXX explain
- msg->msg_hdr.msg_namelen = 0x00;
-#endif
+ssize_t
+listener_read_callback(listener_t * listener, int fd, void * user_data)
+{
+ // XXX make a single callback and arbitrate between read and readbatch
+ assert(listener);
+ assert(fd == listener->fd);
- /* Construct address pair used for connection lookup */
- address_pair_t pair;
- pair.local = *local_addr;
- pair.remote = *(address_t*)msg->msg_hdr.msg_name;
- // in the case of a connection, we should assert the remote
+ if (listener_vft[listener->type]->read_batch)
+ return listener_read_batch(listener);
- process_packet(forwarder, listener, packet, size, &pair);
- }
+ return listener_read_single(listener);
}
+
#if 0
void
_listener_callback(evutil_socket_t fd, short what, void * arg)
diff --git a/hicn-light/src/hicn/core/listener.h b/hicn-light/src/hicn/core/listener.h
index ea2a5d3d8..eb1ec6893 100644
--- a/hicn-light/src/hicn/core/listener.h
+++ b/hicn-light/src/hicn/core/listener.h
@@ -23,10 +23,11 @@
#include <hicn/core/address_pair.h>
#include <hicn/face.h>
-#include <hicn/base/loop.h>
+
+#include "msgbuf.h"
+#include "../base/loop.h"
struct forwarder_s;
-struct batch_buffer_s;
typedef struct {
address_t address;
@@ -89,11 +90,21 @@ void listener_setup_local_ipv4(const struct forwarder_s * forwarder, uint16_t p
void listener_process_packet(const listener_t * listener,
const uint8_t * packet, size_t size);
-ssize_t listener_read_callback(struct forwarder_s * forwarder, listener_t * listener,
- int fd, address_t * local_addr, uint8_t * packet, size_t size);
-void listener_batch_read_callback(struct forwarder_s * forwarder,
- listener_t * listener, int fd, address_t * local_addr,
- struct batch_buffer_s * bb);
+ssize_t listener_read_single(listener_t * listener);
+ssize_t listener_read_batch(listener_t * listener);
+
+/**
+ * @brief Callback helper function for batch reading data from listener fd.
+ *
+ * This function is usually called from the listener read callback to proceed to
+ * actual reading of data from the fd.
+ *
+ * @see listener_read_callback
+ *
+ * NOTE: the function returns size_t as for TCP we might need to know how much
+ * data we can consume from the socket.
+ */
+ssize_t listener_read_callback(listener_t * listener, int fd, void * user_data);
#endif /* HICNLIGHT_LISTENER_H */
diff --git a/hicn-light/src/hicn/core/listener_table.c b/hicn-light/src/hicn/core/listener_table.c
index f69ad7535..9750fbbe8 100644
--- a/hicn-light/src/hicn/core/listener_table.c
+++ b/hicn-light/src/hicn/core/listener_table.c
@@ -46,7 +46,7 @@ _listener_table_create(size_t init_size, size_t max_size)
* We start by allocating a reasonably-sized pool, as this will eventually
* be resized if needed.
*/
- pool_init(table->listeners, init_size);
+ pool_init(table->listeners, init_size, 0);
return table;
}
diff --git a/hicn-light/src/hicn/core/listener_vft.h b/hicn-light/src/hicn/core/listener_vft.h
index 2f70dd67d..6440475e7 100644
--- a/hicn-light/src/hicn/core/listener_vft.h
+++ b/hicn-light/src/hicn/core/listener_vft.h
@@ -36,7 +36,9 @@ typedef struct {
msgbuf_t * msgbuf, bool queue);
int (*send_packet)(const connection_t * connection,
const uint8_t * packet, size_t size);
- void (*read_callback)(listener_t * listener, int fd, void * data);
+ ssize_t (*read_single)(int fd, msgbuf_t * msgbuf, address_t * address);
+ ssize_t (*read_batch)(int fd, msgbuf_t ** msgbuf, address_t ** address,
+ size_t len);
size_t data_size;
} listener_ops_t;
@@ -46,7 +48,8 @@ const listener_ops_t listener_ ## NAME = { \
.finalize = listener_ ## NAME ## _finalize, \
.punt = listener_ ## NAME ## _punt, \
.get_socket = listener_ ## NAME ## _get_socket, \
- .read_callback = listener_ ## NAME ## _read_callback, \
+ .read_single = listener_ ## NAME ## _read_single, \
+ .read_batch = listener_ ## NAME ## _read_batch, \
.data_size = sizeof(listener_ ## NAME ## _data_t), \
}
diff --git a/hicn-light/src/hicn/core/mapme.c b/hicn-light/src/hicn/core/mapme.c
index ae4a29f13..8f40cb34a 100644
--- a/hicn-light/src/hicn/core/mapme.c
+++ b/hicn-light/src/hicn/core/mapme.c
@@ -120,7 +120,6 @@
#include <hicn/core/connection.h>
#include <hicn/core/forwarder.h>
#include <hicn/core/msgbuf.h>
-#include <hicn/core/messagePacketType.h> // packet types
#include <hicn/core/ticks.h>
#include <hicn/core/fib_entry.h>
#include <hicn/core/pit.h>
@@ -757,7 +756,7 @@ mapme_on_interest(mapme_t * mapme, uint8_t * packet,
ERROR("Failed to send ACK packet");
}
- Name *name = name_CreateFromPacket(packet, MESSAGE_TYPE_INTEREST);
+ Name *name = name_create_from_interest(packet);
name_setLen(name, prefix->len);
char *name_str = name_ToString(name);
@@ -871,8 +870,7 @@ mapme_on_data(mapme_t *mapme, const uint8_t * packet,
{
INFO("Receive IU/IN Ack on connection %d", ingress_id);
- const Name * name =
- name_CreateFromPacket(packet, MESSAGE_TYPE_DATA);
+ const Name * name = name_create_from_data(packet);
name_setLen((Name*) name, prefix->len);
char * name_str = name_ToString(name);
@@ -919,10 +917,14 @@ mapme_on_data(mapme_t *mapme, const uint8_t * packet,
* processed by MAP-Me core.
*/
void
-mapme_process(mapme_t *mapme, uint8_t *packet, unsigned conn_id)
+mapme_process(mapme_t *mapme, msgbuf_t * msgbuf)
{
hicn_prefix_t prefix;
mapme_params_t params;
+
+ uint8_t * packet = msgbuf_get_packet(msgbuf);
+ unsigned conn_id = msgbuf_get_connection_id(msgbuf);
+
int rc = hicn_mapme_parse_packet(packet, &prefix, &params);
if (rc < 0)
return;
diff --git a/hicn-light/src/hicn/core/mapme.h b/hicn-light/src/hicn/core/mapme.h
index 2bf5a413b..d1d21079f 100644
--- a/hicn-light/src/hicn/core/mapme.h
+++ b/hicn-light/src/hicn/core/mapme.h
@@ -27,9 +27,11 @@
#include <stdint.h>
#include <hicn/hicn.h>
-#include <hicn/core/connection.h>
-#include <hicn/utils/commands.h>
-#include <hicn/core/fib_entry.h>
+
+#include "connection.h"
+#include "fib_entry.h"
+#include "msgbuf.h"
+#include "../utils/commands.h"
typedef struct mapme_s mapme_t;
@@ -64,7 +66,7 @@ bool mapme_match_packet(const uint8_t *msgBuffer);
* @param [in] message - MAP-Me buffer
* @param [in] conn_id - Ingress connection id
*/
-void mapme_process(mapme_t *mapme, uint8_t * packet, unsigned conn_id);
+void mapme_process(mapme_t *mapme, msgbuf_t * msgbuf);
int mapme_send_to_nexthop(const mapme_t * mapme, fib_entry_t * fib_entry, unsigned nexthop);
@@ -117,10 +119,6 @@ void mapme_on_connection_event(const mapme_t *mapme, const connection_t * conn,
nexthops_t * mapme_get_nexthops(const mapme_t *mapme, fib_entry_t *fib_entry,
const msgbuf_t *interest);
-hicn_mapme_type_t mapme_PktType_To_LibHicnPktType(MessagePacketType type);
-
-MessagePacketType mapme_LibHicnPktType_To_PktType(hicn_mapme_type_t type);
-
#endif /* WITH_MAPME */
#endif // mapme_h
diff --git a/hicn-light/src/hicn/core/messageHandler.h b/hicn-light/src/hicn/core/messageHandler.h
index e0eef5e7c..bc7ecf597 100644
--- a/hicn-light/src/hicn/core/messageHandler.h
+++ b/hicn-light/src/hicn/core/messageHandler.h
@@ -13,8 +13,8 @@
* limitations under the License.
*/
-#ifndef messageHandler
-#define messageHandler
+#ifndef HICNLIGHT_MESSAGE_HANDLER_H
+#define HICNLIGHT_MESSAGE_HANDLER_H
#include <stdlib.h>
#ifndef _WIN32
@@ -22,7 +22,6 @@
#endif /* _WIN32 */
#include <hicn/hicn.h>
-#include <hicn/core/messagePacketType.h>
//#include <hicn/core/connection_table.h>
@@ -620,4 +619,4 @@ static inline bool messageHandler_IsAProbe(const uint8_t *packet){
return false;
}
-#endif // Metis_metis_MessageHandler
+#endif /* HICNLIGHT_MESSAGE_HANDLER_H */
diff --git a/hicn-light/src/hicn/core/messagePacketType.h b/hicn-light/src/hicn/core/messagePacketType.h
deleted file mode 100644
index 9a559069e..000000000
--- a/hicn-light/src/hicn/core/messagePacketType.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file message_packet_type_h
- * @brief Defines the packet type for a HICN message
- *
- */
-
-#ifndef message_packet_type_h
-#define message_packet_type_h
-
-typedef enum message_type {
- MESSAGE_TYPE_UNDEFINED,
- MESSAGE_TYPE_INTEREST,
- MESSAGE_TYPE_DATA,
- MESSAGE_TYPE_WLDR_NOTIFICATION,
- MESSAGE_TYPE_MAPME,
- MESSAGE_TYPE_COMMAND,
- MESSAGE_TYPE_N,
-} MessagePacketType;
-
-#endif // message_packet_type_h
diff --git a/hicn-light/src/hicn/core/msgbuf.h b/hicn-light/src/hicn/core/msgbuf.h
index 3e96b3bbc..72480b535 100644
--- a/hicn-light/src/hicn/core/msgbuf.h
+++ b/hicn-light/src/hicn/core/msgbuf.h
@@ -18,63 +18,83 @@
* \brief hICN message buffer
*/
-#ifndef HICN_MSGBUF
-#define HICN_MSGBUF
+#ifndef HICNLIGHT_MSGBUF
+#define HICNLIGHT_MSGBUF
-#include <hicn/core/name.h>
-#include <hicn/core/ticks.h>
-#include <hicn/core/messageHandler.h>
+#include "name.h"
+#include "ticks.h"
+#include "messageHandler.h"
+#include "../utils/commands.h"
+
+struct name_s;
+
+#define MTU 1500
+#define INVALID_MSGBUF_ID ~0ul
+
+#define msgbuf_id_is_valid(msgbuf_id) (msgbuf_id != INVALID_MSGBUF_ID)
+
+#define foreach_type \
+ _(UNDEFINED) \
+ _(INTEREST) \
+ _(DATA) \
+ _(WLDR_NOTIFICATION) \
+ _(MAPME) \
+ _(COMMAND) \
+ _(N)
+
+typedef enum {
+#define _(x) MSGBUF_TYPE_ ## x,
+ foreach_type
+#undef _
+} msgbuf_type_t;
typedef struct {
- Ticks receiveTime;
- unsigned connection_id;
- Name *name;
- uint8_t *messageHead;
unsigned length;
- uint8_t packetType;
+ msgbuf_type_t type;
+ unsigned connection_id;
+ Ticks recv_ts;
+ unsigned refs;
+ union {
+ /* Interest or data packet */
+ struct {
+ struct name_s * name;
+ } id;
+ /* Command packet */
+ struct {
+ command_type_t type;
+ } command;
+ };
+ uint8_t packet[MTU];
} msgbuf_t;
-#define msgbuf_from_packet(MSGBUF, PACKET, LENGTH, TYPE, CONNID, RECV_TIME) \
-do { \
- *MSGBUF = (msgbuf_t) { \
- .receiveTime = (RECV_TIME), \
- .connection_id = (CONNID), \
- .messageHead = (PACKET), \
- .length = (LENGTH), \
- .packetType = (TYPE), \
- .name = (TYPE != MESSAGE_TYPE_WLDR_NOTIFICATION \
- ? name_CreateFromPacket((PACKET), (TYPE)) \
- : NULL), \
- }; \
-} while(0)
-
-#define msgbuf_get_name(M) ((M)->name)
+#define msgbuf_get_name(M) ((M)->id.name)
#define msgbuf_get_connection_id(M) ((M)->connection_id)
-#define msgbuf_get_type(M) ((M)->packetType)
-#define msgbuf_has_wldr(M) (messageHandler_HasWldr((M)->messageHead))
+#define msgbuf_get_type(M) ((M)->type)
+#define msgbuf_has_wldr(M) (messageHandler_HasWldr((M)->packet))
#define msgbuf_get_len(M) ((M)->length)
-#define msgbuf_get_packet(M) ((M)->messageHead)
+#define msgbuf_get_packet(M) ((M)->packet)
+#define msgbuf_get_command_type(M) ((M)->command.type) \
// XXX TODO EXPLAIN THE CONSTANT
-#define msgbuf_get_interest_lifetime(M) (NSEC_TO_TICKS(messageHandler_GetInterestLifetime((M)->messageHead) * 1000000ULL))
+#define msgbuf_get_lifetime(M) (NSEC_TO_TICKS(messageHandler_GetInterestLifetime((M)->packet) * 1000000ULL))
-#define msgbuf_is_probe(M) messageHandler_IsAProbe((M)->messageHead)
+#define msgbuf_is_probe(M) messageHandler_IsAProbe((M)->packet)
/* Path label */
-#define msgbuf_get_pathlabel(M) (messageHandler_GetPathLabel((M)->messageHead))
-#define msgbuf_set_pathlabel(M, label) (messageHandler_SetPathLabel((M)->messageHead, label))
-#define msgbuf_update_pathlabel(M, outface) (messageHandler_SetPathLabel((M)->messageHead, outface))
-#define msgbuf_reset_pathlabel(M) (messageHandler_ResetPathLabel((M)->messageHead))
+#define msgbuf_get_pathlabel(M) (messageHandler_GetPathLabel((M)->packet))
+#define msgbuf_set_pathlabel(M, label) (messageHandler_SetPathLabel((M)->packet, label))
+#define msgbuf_update_pathlabel(M, outface) (messageHandler_SetPathLabel((M)->packet, outface))
+#define msgbuf_reset_pathlabel(M) (messageHandler_ResetPathLabel((M)->packet))
/* WLDR */
-#define msgbuf_reset_wldr_label(M) (messageHandler_ResetWldrLabel((M)->messageHead))
-#define msgbuf_get_wldr_label(M) (messageHandler_GetWldrLabel((M)->messageHead))
-#define msgbuf_get_wldr_expected_label(M) (messageHandler_GetWldrExpectedLabel((M)->messageHead))
-#define msgbuf_get_wldr_last_received(M) (messageHandler_GetWldrLastReceived((M)->messageHead))
-#define msgbuf_set_wldr_label(M, label) (messageHandler_GetWldrLabel((M)->messageHead, label))
+#define msgbuf_reset_wldr_label(M) (messageHandler_ResetWldrLabel((M)->packet))
+#define msgbuf_get_wldr_label(M) (messageHandler_GetWldrLabel((M)->packet))
+#define msgbuf_get_wldr_expected_label(M) (messageHandler_GetWldrExpectedLabel((M)->packet))
+#define msgbuf_get_wldr_last_received(M) (messageHandler_GetWldrLastReceived((M)->packet))
+#define msgbuf_set_wldr_label(M, label) (messageHandler_GetWldrLabel((M)->packet, label))
-#endif /* HICN_MSGBUF */
+#endif /* HICNLIGHT_MSGBUF */
diff --git a/hicn-light/src/hicn/core/msgbuf_pool.c b/hicn-light/src/hicn/core/msgbuf_pool.c
new file mode 100644
index 000000000..597123a7a
--- /dev/null
+++ b/hicn-light/src/hicn/core/msgbuf_pool.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file msgbuf_pool.c
+ * @brief Implementation of hICN packet pool.
+ */
+
+#include "../base/pool.h"
+#include "msgbuf_pool.h"
+
+#define PACKET_POOL_DEFAULT_INIT_SIZE 1024
+
+msgbuf_pool_t *
+_msgbuf_pool_create(size_t init_size, size_t max_size)
+{
+ msgbuf_pool_t * msgbuf_pool = malloc(sizeof(msgbuf_pool_t));
+
+ if (init_size == 0)
+ init_size = PACKET_POOL_DEFAULT_INIT_SIZE;
+
+ pool_init(msgbuf_pool->buffers, init_size, 0);
+
+ return msgbuf_pool;
+}
+
+void
+msgbuf_pool_free(msgbuf_pool_t * msgbuf_pool)
+{
+ pool_free(msgbuf_pool->buffers);
+ free(msgbuf_pool);
+}
+
+int
+msgbuf_pool_get(msgbuf_pool_t * msgbuf_pool, msgbuf_t * msgbuf)
+{
+ pool_get(msgbuf_pool->buffers, msgbuf);
+ return 0;
+}
+
+void
+msgbuf_pool_put(msgbuf_pool_t * msgbuf_pool, msgbuf_t * msgbuf)
+{
+ pool_put(msgbuf_pool->buffers, msgbuf);
+}
+
+int
+msgbuf_pool_getn(msgbuf_pool_t * msgbuf_pool, msgbuf_t ** msgbuf, size_t n)
+{
+ for (unsigned i = 0; i < n; i++) {
+ if (!msgbuf_pool_get(msgbuf_pool, msgbuf[i])) {
+ for (unsigned j = 0; j < i; j++) {
+ msgbuf_pool_put(msgbuf_pool, msgbuf[j]);
+ return 0;
+ }
+ break;
+ }
+ }
+ return -1;
+}
+
+off_t
+msgbuf_pool_get_id(msgbuf_pool_t * msgbuf_pool, msgbuf_t * msgbuf)
+{
+ return msgbuf - msgbuf_pool->buffers;
+}
+
+msgbuf_t *
+msgbuf_pool_at(const msgbuf_pool_t * msgbuf_pool, off_t id)
+{
+ return msgbuf_pool->buffers + id;
+}
diff --git a/hicn-light/src/hicn/core/msgbuf_pool.h b/hicn-light/src/hicn/core/msgbuf_pool.h
new file mode 100644
index 000000000..2ada9fa14
--- /dev/null
+++ b/hicn-light/src/hicn/core/msgbuf_pool.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file msgbuf_pool.h
+ * @brief hICN msgbuf pool.
+ *
+ * THe msgbuf pool is used to store packet payloads while the packets are in
+ * transit, as well as holding them into the packet cache (PIT, CSS), WLDR,
+ * mapme, etc.
+ *
+ * Control packets might receive a special treatment in that they are eventually
+ * transformed into a ack/nack, but this should not affect any part of this
+ * design.
+ *
+ * Do we need a reference count, or simply a lock ?
+ * What about weak references ?
+ * We need to be sure that a pool element is never referenced ever again after
+ * it is deleted from the pool as its ID might be reaffected.
+ *
+ * It might even be better to store references to msgbuf's as they might hold
+ * additional information of interest about the packet... a bit like a skbuff in
+ * linux. Is this relevant for the packet cache ?
+ */
+
+#ifndef HICNLIGHT_MSGBUF_POOL_H
+#define HICNLIGHT_MSGBUF_POOL_H
+
+#include "msgbuf.h"
+
+#define MTU 1500
+
+typedef struct {
+ msgbuf_t * buffers;
+} msgbuf_pool_t;
+
+// 0 for init size means a default value (of 1024)
+// 0 for max_size means no limit
+msgbuf_pool_t * _msgbuf_pool_create(size_t init_size, size_t max_size);
+
+#define msgbuf_pool_create() _msgbuf_pool_create(0, 0)
+
+void msgbuf_pool_free(msgbuf_pool_t * msgbuf_pool);
+
+int msgbuf_pool_get(msgbuf_pool_t * msgbuf_pool, msgbuf_t * msgbuf);
+
+int msgbuf_pool_getn(msgbuf_pool_t * msgbuf_pool, msgbuf_t ** msgbuf, size_t n);
+
+off_t msgbuf_pool_get_id(msgbuf_pool_t * msgbuf_pool, msgbuf_t * msgbuf);
+
+msgbuf_t * msgbuf_pool_at(const msgbuf_pool_t * msgbuf_pool, off_t id);
+
+#endif /* HICNLIGHT_MSGBUF_POOL_H */
diff --git a/hicn-light/src/hicn/core/name.c b/hicn-light/src/hicn/core/name.c
index d50ce4cc2..1b606d3c1 100644
--- a/hicn-light/src/hicn/core/name.c
+++ b/hicn-light/src/hicn/core/name.c
@@ -30,7 +30,9 @@
// assumption: the IPv6 address is the name, the TCP segment number is the ICN
// segment
-struct name {
+// XXX leverage libhicn more here
+
+struct name_s {
NameBitvector *content_name;
uint32_t segment;
uint32_t name_hash;
@@ -71,33 +73,44 @@ static uint32_t _computeHash(Name *name) {
// ============================================================================
Name *
-name_CreateFromPacket(const uint8_t *packet, MessagePacketType type)
+name_create_from_interest(const uint8_t * packet)
{
Name *name = malloc(sizeof(Name));
assert(name); // XXX TODO error handling
if (messageHandler_GetIPPacketType(packet) == IPv6_TYPE) {
- if (type == MESSAGE_TYPE_INTEREST) {
- name->content_name = nameBitvector_CreateFromIn6Addr(
- (struct in6_addr *)messageHandler_GetDestination(packet), 128);
- } else if (type == MESSAGE_TYPE_DATA) {
- name->content_name = nameBitvector_CreateFromIn6Addr(
- (struct in6_addr *)messageHandler_GetSource(packet), 128);
- } else {
- free(name);
- return NULL;
- }
+ name->content_name = nameBitvector_CreateFromIn6Addr( (struct in6_addr
+ *)messageHandler_GetDestination(packet), 128);
} else if (messageHandler_GetIPPacketType(packet) == IPv4_TYPE) {
- if (type == MESSAGE_TYPE_INTEREST) {
- name->content_name = nameBitvector_CreateFromInAddr(
- *((uint32_t *)messageHandler_GetDestination(packet)), 32);
- } else if (type == MESSAGE_TYPE_DATA) {
- name->content_name = nameBitvector_CreateFromInAddr(
- *((uint32_t *)messageHandler_GetSource(packet)), 32);
- } else {
- free(name);
- return NULL;
- }
+ name->content_name = nameBitvector_CreateFromInAddr( *((uint32_t
+ *)messageHandler_GetDestination(packet)), 32);
+ } else {
+ printf("Error: unknown message type\n");
+ free(name);
+ return NULL;
+ }
+
+ name->segment = messageHandler_GetSegment(packet);
+ name->name_hash = _computeHash(name);
+
+ name->refCountPtr = malloc(sizeof(unsigned));
+ assert(name->refCountPtr); // XXX TODO error handling
+ *name->refCountPtr = 1;
+ return name;
+}
+
+Name *
+name_create_from_data(const uint8_t * packet)
+{
+ Name *name = malloc(sizeof(Name));
+ assert(name); // XXX TODO error handling
+
+ if (messageHandler_GetIPPacketType(packet) == IPv6_TYPE) {
+ name->content_name = nameBitvector_CreateFromIn6Addr( (struct in6_addr
+ *)messageHandler_GetSource(packet), 128);
+ } else if (messageHandler_GetIPPacketType(packet) == IPv4_TYPE) {
+ name->content_name = nameBitvector_CreateFromInAddr( *((uint32_t
+ *)messageHandler_GetSource(packet)), 32);
} else {
printf("Error: unknown message type\n");
free(name);
diff --git a/hicn-light/src/hicn/core/name.h b/hicn-light/src/hicn/core/name.h
index f3b3f2a02..ef725c00f 100644
--- a/hicn-light/src/hicn/core/name.h
+++ b/hicn-light/src/hicn/core/name.h
@@ -19,20 +19,20 @@
#include <stdbool.h>
#include <stdlib.h>
-#include <hicn/core/messagePacketType.h>
-#include <hicn/core/nameBitvector.h>
+#include "nameBitvector.h"
//#include <hicn/utils/address.h>
//#include <hicn/utils/commands.h>
-struct name;
-typedef struct name Name;
+struct name_s;
+typedef struct name_s Name;
/**
* Creates a name from packet
*
*/
-Name *name_CreateFromPacket(const uint8_t *memory, MessagePacketType type);
+Name *name_create_from_interest(const uint8_t * packet);
+Name *name_create_from_data(const uint8_t * packet);
/**
* Releases one reference count, and frees memory after last reference
diff --git a/hicn-light/src/hicn/core/nexthops.h b/hicn-light/src/hicn/core/nexthops.h
index b45ae360f..8e4878b45 100644
--- a/hicn-light/src/hicn/core/nexthops.h
+++ b/hicn-light/src/hicn/core/nexthops.h
@@ -18,11 +18,12 @@
* \brief Nexthops
*/
-#ifndef HICN_NEXTHOPS_H
-#define HICN_NEXTHOPS_H
+#ifndef HICNLIGHT_NEXTHOPS_H
+#define HICNLIGHT_NEXTHOPS_H
#include <stdint.h>
#include <stdbool.h>
+#include <stdlib.h>
#include <hicn/core/strategy.h>
@@ -151,4 +152,4 @@ nexthops_contains(nexthops_t * nexthops, unsigned nexthop)
#define nexthops_select(nexthops, i) ((nexthops)->flags = 1 << (i))
#define nexthops_select_one(nexthops) (nexthops_select((nexthops), 0))
-#endif /* HICN_NEXTHOPS_H */
+#endif /* HICNLIGHT_NEXTHOPS_H */
diff --git a/hicn-light/src/hicn/core/pit.c b/hicn-light/src/hicn/core/pit.c
index fa54e2429..e80d895ec 100644
--- a/hicn-light/src/hicn/core/pit.c
+++ b/hicn-light/src/hicn/core/pit.c
@@ -31,43 +31,56 @@
#include <assert.h>
#include <stdio.h>
+#include <stdlib.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
-#include <hicn/core/msgbuf.h>
-#include <hicn/base/pool.h>
-#include <hicn/core/ticks.h>
#include <hicn/util/log.h>
+#include "msgbuf.h"
+#include "msgbuf_pool.h"
+#include "ticks.h"
+#include "../base/pool.h"
+
#include "pit.h"
// XXX TODO Should not be defined here
#define DEFAULT_INTEREST_LIFETIME 4000000000ULL
-static Ticks _pit_calculate_lifetime(pit_t * pit,
- msgbuf_t *interest_msgbuf) {
- uint64_t interestLifetimeTicks =
- msgbuf_get_interest_lifetime(interest_msgbuf);
- if (interestLifetimeTicks == 0) {
- interestLifetimeTicks = NSEC_TO_TICKS(DEFAULT_INTEREST_LIFETIME);
- }
+static
+Ticks
+_pit_calculate_lifetime(pit_t * pit, const msgbuf_t * msgbuf)
+{
+ uint64_t lifetime = msgbuf_get_lifetime(msgbuf);
+ if (lifetime == 0)
+ lifetime = NSEC_TO_TICKS(DEFAULT_INTEREST_LIFETIME);
- Ticks expiry_time = ticks_now() + interestLifetimeTicks;
- return expiry_time;
+ return ticks_now() + lifetime;
}
-// max_elts default is 65535
+/* This is only used as a hint for first allocation, as the table is resizeable */
+#define DEFAULT_PIT_SIZE 65535
+
pit_t *
-pit_create(size_t max_elts)
+_pit_create(size_t init_size, size_t max_size)
{
pit_t * pit = malloc(sizeof(pit_t));
if (!pit)
return NULL;
- pool_init(pit->entries, max_elts);
+ if (init_size == 0)
+ init_size = DEFAULT_PIT_SIZE;
+
+ pit->max_size = max_size;
+
+ /* Initialize indices */
pit->index_by_name = kh_init(pit_name);
- DEBUG("PIT %p created", pit);
+ /*
+ * We start by allocating a reasonably-sized pool, as this will eventually
+ * be resized if needed.
+ */
+ pool_init(pit->entries, init_size, 0);
return pit;
}
@@ -76,53 +89,57 @@ void
pit_free(pit_t * pit)
{
assert(pit);
- // XXX TODO
+
+ free(pit);
DEBUG("PIT %p destroyed", pit);
}
pit_verdict_t
-pit_on_interest(pit_t * pit, msgbuf_t * interest_msgbuf)
+pit_on_interest(pit_t * pit, off_t msgbuf_id)
{
assert(pit);
- assert(interest_msgbuf);
- assert(msgbuf_get_type(interest_msgbuf) == MESSAGE_TYPE_INTEREST);
+ assert(msgbuf_id_is_valid(msgbuf_id));
+
+ const msgbuf_pool_t * msgbuf_pool = pit_get_msgbuf_pool(pit);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+ assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
fib_entry_t * fib_entry;
- Ticks expiry_time;
+ Ticks expire_ts;
/* Lookup entry by name */
- khiter_t k = kh_get_pit_name(pit->index_by_name, msgbuf_get_name(interest_msgbuf));
+ khiter_t k = kh_get_pit_name(pit->index_by_name, msgbuf_get_name(msgbuf));
if (k == kh_end(pit->index_by_name))
goto NOT_FOUND;
pit_entry_t * entry = pit->entries + kh_val(pit->index_by_name, k);
assert(entry);
// has it expired?
- if (ticks_now() >= pit_entry_get_expiry_time(entry))
+ if (ticks_now() >= pit_entry_get_expire_ts(entry))
goto TIMEOUT;
/* Extend entry lifetime */
- expiry_time = _pit_calculate_lifetime(pit, interest_msgbuf);
- if (expiry_time > pit_entry_get_expiry_time(entry))
- pit_entry_set_expiry_time(entry, expiry_time);
+ expire_ts = _pit_calculate_lifetime(pit, msgbuf);
+ if (expire_ts > pit_entry_get_expire_ts(entry))
+ pit_entry_set_expire_ts(entry, expire_ts);
- unsigned connection_id = msgbuf_get_connection_id(interest_msgbuf);
+ unsigned connection_id = msgbuf_get_connection_id(msgbuf);
// Is the reverse path already in the PIT entry?
if (pit_entry_ingress_contains(entry, connection_id)) {
// It is already in the PIT entry, so this is a retransmission, so
// forward it.
- DEBUG("Message %p existing entry (expiry %" PRIu64 ") and reverse path, forwarding",
- interest_msgbuf, pit_entry_get_expiry_time(entry));
+ DEBUG("Message %lu existing entry (expiry %" PRIu64 ") and reverse path, forwarding",
+ msgbuf_id, pit_entry_get_expire_ts(entry));
return PIT_VERDICT_RETRANSMIT;
}
// It is in the PIT but this is the first interest for the reverse path
pit_entry_ingress_add(entry, connection_id);
- DEBUG("Message %p existing entry (expiry %" PRIu64 ") and reverse path is new, aggregate",
- interest_msgbuf, pit_entry_get_expiry_time(entry));
+ DEBUG("Message %lu existing entry (expiry %" PRIu64 ") and reverse path is new, aggregate",
+ msgbuf_id, pit_entry_get_expire_ts(entry));
return PIT_VERDICT_AGGREGATE;
TIMEOUT:
@@ -131,36 +148,46 @@ TIMEOUT:
fib_entry_on_timeout(fib_entry, pit_entry_get_egress(entry));
// it's an old entry, remove it
- k = kh_get(pit_name, pit->index_by_name, msgbuf_get_name(interest_msgbuf));
+ k = kh_get(pit_name, pit->index_by_name, msgbuf_get_name(msgbuf));
if (k != kh_end(pit->index_by_name))
kh_del(pit_name, pit->index_by_name, k);
NOT_FOUND:
/* Create PIT entry */
- expiry_time = _pit_calculate_lifetime(pit, interest_msgbuf);
+ expire_ts = _pit_calculate_lifetime(pit, msgbuf);
- pit_allocate(pit, entry, interest_msgbuf);
- pit_entry_from_msgbuf(entry, interest_msgbuf, expiry_time, ticks_now());
+ pit_allocate(pit, entry, msgbuf);
- DEBUG("Message %p added to PIT (expiry %" PRIu64 ") ingress %u",
- interest_msgbuf, pit_entry_get_expiry_time(entry),
- msgbuf_get_connection_id(interest_msgbuf));
+ *entry = (pit_entry_t) {
+ .msgbuf_id = msgbuf_id,
+ .fib_entry = NULL,
+ .create_ts = ticks_now(),
+ .expire_ts = expire_ts,
+ };
+ pit_entry_ingress_add(entry, msgbuf_get_connection_id(msgbuf));
+
+ DEBUG("Message %lu added to PIT (expiry %" PRIu64 ") ingress %u",
+ msgbuf_id, pit_entry_get_expire_ts(entry),
+ msgbuf_get_connection_id(msgbuf));
return PIT_VERDICT_FORWARD;
}
nexthops_t *
-pit_on_data(pit_t * pit, const msgbuf_t * data_msgbuf)
+pit_on_data(pit_t * pit, off_t msgbuf_id)
{
assert(pit);
- assert(data_msgbuf);
- assert(msgbuf_get_type(data_msgbuf) == MESSAGE_TYPE_DATA);
+ assert(msgbuf_id_is_valid(msgbuf_id));
+
+ const msgbuf_pool_t * msgbuf_pool = pit_get_msgbuf_pool(pit);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+ assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA);
nexthops_t * nexthops = NULL;
/* Lookup entry by name */
- khiter_t k = kh_get_pit_name(pit->index_by_name, msgbuf_get_name(data_msgbuf));
+ khiter_t k = kh_get_pit_name(pit->index_by_name, msgbuf_get_name(msgbuf));
if (k == kh_end(pit->index_by_name))
goto NOT_FOUND;
@@ -170,14 +197,14 @@ pit_on_data(pit_t * pit, const msgbuf_t * data_msgbuf)
// here we need to check if the PIT entry is expired
// if so, remove the PIT entry.
Ticks now = ticks_now();
- if (now >= pit_entry_get_expiry_time(entry))
+ if (now >= pit_entry_get_expire_ts(entry))
goto TIMEOUT;
/* PIT entry is not expired, use it */
fib_entry_t * fib_entry = pit_entry_get_fib_entry(entry);
if (fib_entry)
fib_entry_on_data(fib_entry, pit_entry_get_egress(entry),
- data_msgbuf, pit_entry_get_creation_time(entry), ticks_now());
+ msgbuf, pit_entry_get_create_ts(entry), ticks_now());
// XXX TODO : be sure nexthops are valid b/c pit entry is removed
// XXX TODO eventually pass holding structure as parameter
@@ -192,20 +219,25 @@ NOT_FOUND:
}
void
-pit_remove(pit_t * pit, const msgbuf_t * interest_msgbuf)
+pit_remove(pit_t * pit, off_t msgbuf_id)
{
assert(pit);
- assert(interest_msgbuf);
- assert(msgbuf_get_type(interest_msgbuf) == MESSAGE_TYPE_INTEREST);
+ assert(msgbuf_id_is_valid(msgbuf_id));
+
+ const msgbuf_pool_t * msgbuf_pool = pit_get_msgbuf_pool(pit);
+ const msgbuf_t * msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+
+ assert(msgbuf);
+ assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
- khiter_t k = kh_get(pit_name, pit->index_by_name, msgbuf_get_name(interest_msgbuf));
+ khiter_t k = kh_get(pit_name, pit->index_by_name, msgbuf_get_name(msgbuf));
if (k == kh_end(pit->index_by_name))
return;
//off_t index = kh_val(pit->index_by_name, k);
//pit_entry_t * entry = pit_at(pit, index);
kh_del(pit_name, pit->index_by_name, k);
- DEBUG("Message %p removed from PIT", interest_msgbuf);
+ DEBUG("Message %p removed from PIT", msgbuf);
}
pit_entry_t *
@@ -213,7 +245,7 @@ pit_lookup(const pit_t * pit, const msgbuf_t * interest_msgbuf)
{
assert(pit);
assert(interest_msgbuf);
- assert(msgbuf_get_type(interest_msgbuf) == MESSAGE_TYPE_INTEREST);
+ assert(msgbuf_get_type(interest_msgbuf) == MSGBUF_TYPE_INTEREST);
khiter_t k = kh_get(pit_name, pit->index_by_name,
msgbuf_get_name(interest_msgbuf));
diff --git a/hicn-light/src/hicn/core/pit.h b/hicn-light/src/hicn/core/pit.h
index 1aedcfab9..5607827fe 100644
--- a/hicn-light/src/hicn/core/pit.h
+++ b/hicn-light/src/hicn/core/pit.h
@@ -1,7 +1,26 @@
+/*
+ * Copyright (c) 2017-2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file pit.h
+ * @brief hICN Pending Interest Table (PIT)
+ */
+
#ifndef HICNLIGHT_PIT_H
#define HICNLIGHT_PIT_H
-
#include <hicn/base/khash.h>
#include <hicn/core/nexthops.h>
#include <hicn/core/msgbuf.h>
@@ -10,14 +29,14 @@
#include <hicn/core/ticks.h>
typedef struct {
- msgbuf_t * msgbuf;
+ off_t msgbuf_id;
nexthops_t ingressIdSet;
nexthops_t egressIdSet;
fib_entry_t * fib_entry;
- Ticks creation_time;
- Ticks expiry_time;
+ Ticks create_ts;
+ Ticks expire_ts;
} pit_entry_t;
typedef enum {
@@ -30,10 +49,10 @@ typedef enum {
#define pit_entry_get_egress(E) (&((E)->egressIdSet))
#define pit_entry_get_fib_entry(E) ((E)->fib_entry)
#define pit_entry_set_fib_entry(E, FIB_ENTRY) ((E)->fib_entry = FIB_ENTRY)
-#define pit_entry_get_creation_time(E) ((E)->creation_time)
-#define pit_entry_get_expiry_time(E) ((E)->expiry_time)
-#define pit_entry_set_expiry_time(E, EXPIRY_TIME) \
- (entry)->expiry_time = EXPIRY_TIME
+#define pit_entry_get_create_ts(E) ((E)->create_ts)
+#define pit_entry_get_expire_ts(E) ((E)->expire_ts)
+#define pit_entry_set_expire_ts(E, EXPIRY_TIME) \
+ (entry)->expire_ts = EXPIRY_TIME
#define pit_entry_ingress_add(E, NH) \
nexthops_add(pit_entry_get_ingress(E), (NH))
@@ -44,26 +63,34 @@ typedef enum {
#define pit_entry_egress_add(E, NH) \
nexthops_add(pit_entry_get_egress(E), (NH))
-#define pit_entry_from_msgbuf(E, MSGBUF, EXPIRY_TIME, CREATION_TIME) \
-do { \
- E->msgbuf = MSGBUF; \
- pit_entry_ingress_add(E, msgbuf_get_connection_id(MSGBUF)); \
- E->fib_entry = NULL; \
- E->creation_time = CREATION_TIME; \
- E->expiry_time = EXPIRY_TIME; \
-} while(0)
-
#define name_hash(name) (name_HashCode(name))
#define name_hash_eq(a, b) (name_hash(b) - name_hash(a))
KHASH_INIT(pit_name, const Name *, unsigned, 0, name_hash, name_hash_eq);
typedef struct {
+ msgbuf_pool_t * msgbuf_pool;
+ size_t max_size;
pit_entry_t * entries; // pool
kh_pit_name_t * index_by_name;
} pit_t;
-pit_t * pit_create(size_t max_elts);
+/**
+ * @brief Allocate a new PIT data structure (extended parameters)
+ *
+ * @param init_size Initial size (0 = default)
+ * @param max_size Maximum size (0 = unbounded)
+ *
+ * @return pit_t* Newly allocated PIT data structure
+ */
+pit_t * _pit_create(size_t init_size, size_t max_size);
+
+/**
+ * @brief Allocate a new PIT data structure
+ *
+ * @return pit_t* Newly allocated PIT data structure
+ */
+#define pit_create() _pit_create(0, 0)
void pit_free(pit_t * pit);
@@ -81,12 +108,14 @@ do {
#define pit_at(pit, i) (pit->entries + i)
-pit_verdict_t pit_on_interest(pit_t * pit, msgbuf_t * msgbuf);
+pit_verdict_t pit_on_interest(pit_t * pit, off_t msgbuf_id);
-nexthops_t * pit_on_data(pit_t * pit, const msgbuf_t * msgbuf);
+nexthops_t * pit_on_data(pit_t * pit, off_t msgbuf_id);
-void pit_remove(pit_t * pit, const msgbuf_t * msgbuf);
+void pit_remove(pit_t * pit, off_t msgbuf_id);
pit_entry_t * pit_lookup(const pit_t * pit, const msgbuf_t * msgbuf);
+#define pit_get_msgbuf_pool(pit) (pit->msgbuf_pool)
+
#endif /* HICNLIGHT_PIT_H */
diff --git a/hicn-light/src/hicn/core/strategy.h b/hicn-light/src/hicn/core/strategy.h
index 3d48c5510..67630bbab 100644
--- a/hicn-light/src/hicn/core/strategy.h
+++ b/hicn-light/src/hicn/core/strategy.h
@@ -17,15 +17,12 @@
* \file strategy.h
* \brief hICN forwarding strategy
*/
-#ifndef HICN_STRATEGY_H
-#define HICN_STRATEGY_H
+#ifndef HICNLIGHT_STRATEGY_H
+#define HICNLIGHT_STRATEGY_H
-#include <hicn/core/name.h>
-#include <hicn/core/msgbuf.h>
-
-#include <hicn/strategies/load_balancer.h>
-#include <hicn/strategies/low_latency.h>
-#include <hicn/strategies/random.h>
+#include "../strategies/load_balancer.h"
+#include "../strategies/low_latency.h"
+#include "../strategies/random.h"
typedef enum {
STRATEGY_TYPE_UNDEFINED,
@@ -67,4 +64,4 @@ typedef struct {
} strategy_entry_t;
-#endif /* HICN_STRATEGY_H */
+#endif /* HICNLIGHT_STRATEGY_H */
diff --git a/hicn-light/src/hicn/core/strategy_vft.h b/hicn-light/src/hicn/core/strategy_vft.h
index e698c9d94..61166d3dd 100644
--- a/hicn-light/src/hicn/core/strategy_vft.h
+++ b/hicn-light/src/hicn/core/strategy_vft.h
@@ -17,11 +17,12 @@
* \file strategy_vft.h
* \brief hICN forwarding strategy VFT
*/
-#ifndef HICN_STRATEGY_VFT_H
-#define HICN_STRATEGY_VFT_H
+#ifndef HICNLIGHT_STRATEGY_VFT_H
+#define HICNLIGHT_STRATEGY_VFT_H
-#include <hicn/core/strategy.h>
-#include <hicn/core/nexthops.h>
+#include "msgbuf.h"
+#include "nexthops.h"
+#include "strategy.h"
/**
* @typedef strategy_ops_t
@@ -73,4 +74,4 @@ const strategy_ops_t strategy_ ## NAME = { \
.on_timeout = strategy_ ## NAME ## _on_timeout, \
}
-#endif /* HICN_STRATEGY_VFT_H */
+#endif /* HICNLIGHT_STRATEGY_VFT_H */
diff --git a/hicn-light/src/hicn/core/wldr.c b/hicn-light/src/hicn/core/wldr.c
index 5a6c876b9..e9b1f77f9 100644
--- a/hicn-light/src/hicn/core/wldr.c
+++ b/hicn-light/src/hicn/core/wldr.c
@@ -151,7 +151,9 @@ void wldr_set_label(wldr_t * wldr, msgbuf_t *msgbuf) {
#endif
}
-void wldr_detect_losses(wldr_t * wldr, const connection_t * conn, msgbuf_t *msgbuf) {
+void wldr_detect_losses(wldr_t * wldr, const connection_t * connection,
+ const msgbuf_t * msgbuf)
+{
#if 0
if (message_HasWldr(msgbuf)) {
// this is a normal wldr packet
@@ -179,8 +181,9 @@ void wldr_detect_losses(wldr_t * wldr, const connection_t * conn, msgbuf_t *msgb
#endif
}
-void wldr_handle_notification(wldr_t * wldr, const connection_t * conn,
- msgbuf_t *msgbuf) {
+void wldr_handle_notification(wldr_t * wldr, const connection_t * connection,
+ const msgbuf_t *msgbuf)
+{
#if 0
uint16_t expected_lbl = (uint16_t)message_GetWldrExpectedLabel(msgbuf);
uint16_t received_lbl = (uint16_t)message_GetWldrLastReceived(msgbuf);
diff --git a/hicn-light/src/hicn/core/wldr.h b/hicn-light/src/hicn/core/wldr.h
index cb2f0e2cf..529977223 100644
--- a/hicn-light/src/hicn/core/wldr.h
+++ b/hicn-light/src/hicn/core/wldr.h
@@ -44,8 +44,9 @@ void wldr_reset_state(wldr_t * wldr);
void wldr_set_label(wldr_t * wldr, msgbuf_t * msgbuf);
-void wldr_detect_losses(wldr_t * wldr, const connection_t * conn, msgbuf_t * msgbuf);
+void wldr_detect_losses(wldr_t * wldr, const connection_t * connection,
+ const msgbuf_t * msgbuf);
-void wldr_handle_notification(wldr_t *wldr, const connection_t * conn,
- msgbuf_t * msgbuf);
+void wldr_handle_notification(wldr_t *wldr, const connection_t * connection,
+ const msgbuf_t * msgbuf);
#endif // wldr_h