summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/ipcpd/CMakeLists.txt16
-rw-r--r--src/ipcpd/config.h.in (renamed from src/ipcpd/timerwheel.h)36
-rw-r--r--src/ipcpd/ipcp.c19
-rw-r--r--src/ipcpd/ipcp.h12
-rw-r--r--src/ipcpd/local/CMakeLists.txt2
-rw-r--r--src/ipcpd/local/main.c34
-rw-r--r--src/ipcpd/normal/CMakeLists.txt11
-rw-r--r--src/ipcpd/normal/addr_auth.c1
-rw-r--r--src/ipcpd/normal/connmgr.c164
-rw-r--r--src/ipcpd/normal/dht.c5
-rw-r--r--src/ipcpd/normal/dir.c3
-rw-r--r--src/ipcpd/normal/dt.c5
-rw-r--r--src/ipcpd/normal/dt_pci.c1
-rw-r--r--src/ipcpd/normal/enroll.c6
-rw-r--r--src/ipcpd/normal/fa.c5
-rw-r--r--src/ipcpd/normal/gam.c3
-rw-r--r--src/ipcpd/normal/main.c7
-rw-r--r--src/ipcpd/normal/neighbors.c3
-rw-r--r--src/ipcpd/normal/pff.c5
-rw-r--r--src/ipcpd/normal/pol/complete.c3
-rw-r--r--src/ipcpd/normal/pol/flat.c3
-rw-r--r--src/ipcpd/normal/pol/graph.c3
-rw-r--r--src/ipcpd/normal/pol/link_state.c3
-rw-r--r--src/ipcpd/normal/pol/tests/graph_test.c3
-rw-r--r--src/ipcpd/normal/ribmgr.c3
-rw-r--r--src/ipcpd/normal/routing.c3
-rw-r--r--src/ipcpd/normal/sdu_sched.c5
-rw-r--r--src/ipcpd/shim-data.c5
-rw-r--r--src/ipcpd/shim-data.h6
-rw-r--r--src/ipcpd/shim-eth-llc/CMakeLists.txt65
-rw-r--r--src/ipcpd/shim-eth-llc/main.c82
-rw-r--r--src/ipcpd/shim-udp/CMakeLists.txt17
-rw-r--r--src/ipcpd/shim-udp/main.c40
-rw-r--r--src/ipcpd/shim-udp/shim_udp_config.h.in28
-rw-r--r--src/ipcpd/shim-udp/tests/CMakeLists.txt33
-rw-r--r--src/ipcpd/shim-udp/tests/shim_udp_test.c100
-rw-r--r--src/ipcpd/tests/CMakeLists.txt34
-rw-r--r--src/ipcpd/timerwheel.c366
-rw-r--r--src/irmd/CMakeLists.txt22
-rw-r--r--src/irmd/api_table.c5
-rw-r--r--src/irmd/config.h.in46
-rw-r--r--src/irmd/ipcp.c31
-rw-r--r--src/irmd/irm_flow.c5
-rw-r--r--src/irmd/main.c8
-rw-r--r--src/irmd/registry.c5
-rw-r--r--src/irmd/registry.h1
-rw-r--r--src/irmd/utils.c3
-rw-r--r--src/lib/CMakeLists.txt106
-rw-r--r--src/lib/cacep.c3
-rw-r--r--src/lib/cdap.c3
-rw-r--r--src/lib/cdap_req.c5
-rw-r--r--src/lib/cdap_req.h1
-rw-r--r--src/lib/config.h.in57
-rw-r--r--src/lib/dev.c478
-rw-r--r--src/lib/frct_pci.c112
-rw-r--r--src/lib/hash.c43
-rw-r--r--src/lib/irm.c3
-rw-r--r--src/lib/lockfile.c15
-rw-r--r--src/lib/md5.c2
-rw-r--r--src/lib/nsm.c55
-rw-r--r--src/lib/random.c3
-rw-r--r--src/lib/rib.c5
-rw-r--r--src/lib/shm_flow_set.c52
-rw-r--r--src/lib/shm_rbuff.c7
-rw-r--r--src/lib/shm_rbuff_ll.c15
-rw-r--r--src/lib/shm_rbuff_pthr.c15
-rw-r--r--src/lib/shm_rdrbuff.c5
-rw-r--r--src/lib/sockets.c31
-rw-r--r--src/lib/tests/CMakeLists.txt7
-rw-r--r--src/lib/tests/rib_test.c3
-rw-r--r--src/lib/tests/timerwheel_test.c (renamed from src/ipcpd/tests/timerwheel_test.c)20
-rw-r--r--src/lib/time_utils.c3
-rw-r--r--src/lib/timerwheel.c232
-rw-r--r--src/lib/tpm.c5
-rw-r--r--src/nsmd/CMakeLists.txt24
-rw-r--r--src/nsmd/main.c32
-rw-r--r--src/nsmd/tests/CMakeLists.txt19
-rw-r--r--src/tools/operf/operf.c1
-rw-r--r--src/tools/operf/operf_client.c4
-rw-r--r--src/tools/operf/operf_server.c4
-rw-r--r--src/tools/oping/CMakeLists.txt2
-rw-r--r--src/tools/oping/oping.c1
-rw-r--r--src/tools/oping/oping_client.c4
-rw-r--r--src/tools/oping/oping_server.c4
85 files changed, 1507 insertions, 1143 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0037d437..54fdd8ab 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,5 +1,4 @@
+add_subdirectory(lib)
add_subdirectory(ipcpd)
add_subdirectory(irmd)
-add_subdirectory(nsmd)
-add_subdirectory(lib)
add_subdirectory(tools)
diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt
index 0ead1fed..6356b1ba 100644
--- a/src/ipcpd/CMakeLists.txt
+++ b/src/ipcpd/CMakeLists.txt
@@ -1,14 +1,22 @@
+set(IPCP_ACCEPT_TIMEOUT 100 CACHE STRING
+ "Timeout for accept in IPCP mainloop threads (ms)")
+set(IPCP_SCHED_THREADS 2 CACHE STRING
+ "Number of scheduler threads in the normal IPCP")
+set(IPCP_MIN_THREADS 4 CACHE STRING
+ "Minimum number of worker threads in the IPCP")
+set(IPCP_ADD_THREADS 4 CACHE STRING
+ "Number of extra threads to start when an IPCP faces thread starvation")
+
set(IPCP_SOURCES
# Add source files here
${CMAKE_CURRENT_SOURCE_DIR}/ipcp.c
${CMAKE_CURRENT_SOURCE_DIR}/shim-data.c
- ${CMAKE_CURRENT_SOURCE_DIR}/timerwheel.c
)
add_subdirectory(local)
add_subdirectory(normal)
add_subdirectory(shim-udp)
add_subdirectory(shim-eth-llc)
-if (NOT APPLE)
- add_subdirectory(tests)
-endif ()
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
diff --git a/src/ipcpd/timerwheel.h b/src/ipcpd/config.h.in
index 37a6d06a..0bef20be 100644
--- a/src/ipcpd/timerwheel.h
+++ b/src/ipcpd/config.h.in
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2017
*
- * Ring buffer for incoming SDUs
+ * IPC process configuration
*
* Dimitri Staessens <dimitri.staessens@ugent.be>
* Sander Vrijders <sander.vrijders@ugent.be>
@@ -20,20 +20,30 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_IPCPD_TIMERWHEEL_H
-#define OUROBOROS_IPCPD_TIMERWHEEL_H
+#define PTHREAD_COND_CLOCK @PTHREAD_COND_CLOCK@
-struct timerwheel;
+#define SYS_MAX_FLOWS @SYS_MAX_FLOWS@
+#define AP_RES_FDS @AP_RES_FDS@
+#define AP_MAX_FLOWS @AP_MAX_FLOWS@
-struct timerwheel * timerwheel_create(unsigned int resolution,
- unsigned int max_delay);
+#define IPCP_ACCEPT_TIMEOUT @IPCP_ACCEPT_TIMEOUT@
-void timerwheel_destroy(struct timerwheel * tw);
+#define SOCKET_TIMEOUT @SOCKET_TIMEOUT@
-int timerwheel_add(struct timerwheel * tw,
- void (* func)(void *),
- void * arg,
- size_t arg_len,
- unsigned int delay); /* ms */
+#define SHM_BUFFER_SIZE @SHM_BUFFER_SIZE@
-#endif /* OUROBOROS_IPCPD_TIMERWHEEL_H */
+#define IPCP_MIN_THREADS @IPCP_MIN_THREADS@
+#define IPCP_ADD_THREADS @IPCP_ADD_THREADS@
+
+/* normal IPCP */
+#define IPCP_SCHED_THREADS @IPCP_SCHED_THREADS@
+#define PFT_SIZE @PFT_SIZE@
+
+/* shim-udp */
+#define NSUPDATE_EXEC "@NSUPDATE_EXECUTABLE@"
+#define NSLOOKUP_EXEC "@NSLOOKUP_EXECUTABLE@"
+
+/* shim-eth-llc */
+#cmakedefine HAVE_NETMAP
+#cmakedefine HAVE_BPF
+#cmakedefine HAVE_RAW_SOCKETS
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index 368c6eb8..300c22f4 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -20,9 +20,13 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+#define __XSI_VISIBLE 500
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "ipcpd/ipcp"
-#include <ouroboros/config.h>
#include <ouroboros/hash.h>
#include <ouroboros/logs.h>
#include <ouroboros/time_utils.h>
@@ -533,7 +537,6 @@ int ipcp_init(int argc,
ipcpi.irmd_fd = -1;
ipcpi.state = IPCP_NULL;
- ipcpi.shim_data = NULL;
ipcpi.sock_path = ipcp_sock_path(getpid());
if (ipcpi.sock_path == NULL)
@@ -597,20 +600,10 @@ int ipcp_init(int argc,
ipcpi.alloc_id = -1;
ipcpi.csockfd = -1;
- if (type != IPCP_NORMAL) {
- ipcpi.shim_data = shim_data_create();
- if (ipcpi.shim_data == NULL) {
- ret = -ENOMEM;
- goto fail_shim_data;
- }
- }
-
pthread_condattr_destroy(&cattr);
return 0;
- fail_shim_data:
- pthread_cond_destroy(&ipcpi.acc_cond);
fail_acc_cond:
pthread_cond_destroy(&ipcpi.cmd_cond);
fail_cmd_cond:
@@ -702,8 +695,6 @@ void ipcp_fini()
free(ipcpi.sock_path);
- shim_data_destroy(ipcpi.shim_data);
-
pthread_cond_destroy(&ipcpi.state_cond);
pthread_mutex_destroy(&ipcpi.state_mtx);
pthread_cond_destroy(&ipcpi.alloc_cond);
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index 422670d7..cd18d198 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -20,16 +20,14 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef IPCPD_IPCP_H
-#define IPCPD_IPCP_H
+#ifndef OUROBOROS_IPCPD_IPCP_H
+#define OUROBOROS_IPCPD_IPCP_H
-#include <ouroboros/config.h>
#include <ouroboros/hash.h>
#include <ouroboros/ipcp.h>
+#include <ouroboros/qoscube.h>
#include <ouroboros/sockets.h>
-#include "shim-data.h"
-
#include <pthread.h>
#include <time.h>
#include <signal.h>
@@ -80,8 +78,6 @@ struct ipcp {
struct ipcp_ops * ops;
int irmd_fd;
- struct shim_data * shim_data;
-
enum ipcp_state state;
pthread_rwlock_t state_lock;
pthread_mutex_t state_mtx;
@@ -136,4 +132,4 @@ uint8_t * ipcp_hash_dup(const uint8_t * hash);
void ipcp_hash_str(char buf[],
const uint8_t * hash);
-#endif
+#endif /* OUROBOROS_IPCPD_IPCP_H */
diff --git a/src/ipcpd/local/CMakeLists.txt b/src/ipcpd/local/CMakeLists.txt
index 824b4ca6..925092bd 100644
--- a/src/ipcpd/local/CMakeLists.txt
+++ b/src/ipcpd/local/CMakeLists.txt
@@ -12,7 +12,7 @@ include_directories(${CURRENT_BINARY_PARENT_DIR})
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_BINARY_DIR}/include)
-set(IPCP_LOCAL_TARGET ipcpd-local CACHE STRING "IPCP_LOCAL")
+set(IPCP_LOCAL_TARGET ipcpd-local CACHE INTERNAL "")
set(SHIM_LOCAL_SOURCES
# Add source files here
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index 241a47eb..37d23fc3 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "ipcpd-local"
-#include <ouroboros/config.h>
#include <ouroboros/hash.h>
#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
@@ -33,6 +36,7 @@
#include <ouroboros/local-dev.h>
#include "ipcp.h"
+#include "shim-data.h"
#include <string.h>
#include <stdlib.h>
@@ -44,18 +48,20 @@
#define THIS_TYPE IPCP_LOCAL
struct {
- int in_out[IRMD_MAX_FLOWS];
- flow_set_t * flows;
- fqueue_t * fq;
+ struct shim_data * shim_data;
- pthread_rwlock_t lock;
- pthread_t sduloop;
+ int in_out[SYS_MAX_FLOWS];
+ flow_set_t * flows;
+ fqueue_t * fq;
+
+ pthread_rwlock_t lock;
+ pthread_t sduloop;
} local_data;
static int local_data_init(void)
{
int i;
- for (i = 0; i < IRMD_MAX_FLOWS; ++i)
+ for (i = 0; i < SYS_MAX_FLOWS; ++i)
local_data.in_out[i] = -1;
local_data.flows = flow_set_create();
@@ -68,12 +74,20 @@ static int local_data_init(void)
return -ENOMEM;
}
+ local_data.shim_data = shim_data_create();
+ if (local_data.shim_data == NULL) {
+ fqueue_destroy(local_data.fq);
+ flow_set_destroy(local_data.flows);
+ return -ENOMEM;
+ }
+
pthread_rwlock_init(&local_data.lock, NULL);
return 0;
}
static void local_data_fini(void){
+ shim_data_destroy(local_data.shim_data);
flow_set_destroy(local_data.flows);
fqueue_destroy(local_data.fq);
pthread_rwlock_destroy(&local_data.lock);
@@ -142,7 +156,7 @@ static int ipcp_local_reg(const uint8_t * hash)
return -ENOMEM;
}
- if (shim_data_reg_add_entry(ipcpi.shim_data, hash_dup)) {
+ if (shim_data_reg_add_entry(local_data.shim_data, hash_dup)) {
log_dbg("Failed to add " HASH_FMT " to local registry.",
HASH_VAL(hash));
free(hash_dup);
@@ -156,7 +170,7 @@ static int ipcp_local_reg(const uint8_t * hash)
static int ipcp_local_unreg(const uint8_t * hash)
{
- shim_data_reg_del_entry(ipcpi.shim_data, hash);
+ shim_data_reg_del_entry(local_data.shim_data, hash);
log_info("Unregistered " HASH_FMT ".", HASH_VAL(hash));
@@ -167,7 +181,7 @@ static int ipcp_local_query(const uint8_t * hash)
{
int ret;
- ret = (shim_data_reg_has(ipcpi.shim_data, hash) ? 0 : -1);
+ ret = (shim_data_reg_has(local_data.shim_data, hash) ? 0 : -1);
return ret;
}
diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt
index 8c2d4efc..7a40e94c 100644
--- a/src/ipcpd/normal/CMakeLists.txt
+++ b/src/ipcpd/normal/CMakeLists.txt
@@ -12,7 +12,7 @@ include_directories(${CURRENT_BINARY_PARENT_DIR})
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_BINARY_DIR}/include)
-set(IPCP_NORMAL_TARGET ipcpd-normal CACHE STRING "IPCP_NORMAL_TARGET")
+set(IPCP_NORMAL_TARGET ipcpd-normal CACHE INTERNAL "")
protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS flow_alloc.proto)
protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS kademlia.proto)
@@ -20,6 +20,10 @@ protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS kademlia.proto)
# Add GPB sources of policies last
protobuf_generate_c(FSO_SRCS FSO_HDRS pol/fso.proto)
+math(EXPR PFT_EXPR "1 << 12")
+set(PFT_SIZE ${PFT_EXPR} CACHE STRING
+ "Size of the PDU forwarding table")
+
set(SOURCE_FILES
# Add source files here
addr_auth.c
@@ -56,4 +60,7 @@ endif (CMAKE_BUILD_TYPE MATCHES Debug)
install(TARGETS ipcpd-normal RUNTIME DESTINATION sbin)
add_subdirectory(pol/tests)
-add_subdirectory(tests)
+
+if (NOT GNU)
+ add_subdirectory(tests)
+endif ()
diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c
index 56b41384..e327e2fa 100644
--- a/src/ipcpd/normal/addr_auth.c
+++ b/src/ipcpd/normal/addr_auth.c
@@ -22,7 +22,6 @@
#define OUROBOROS_PREFIX "addr_auth"
-#include <ouroboros/config.h>
#include <ouroboros/logs.h>
#include "addr_auth.h"
diff --git a/src/ipcpd/normal/connmgr.c b/src/ipcpd/normal/connmgr.c
index 1513c12a..a83d71c3 100644
--- a/src/ipcpd/normal/connmgr.c
+++ b/src/ipcpd/normal/connmgr.c
@@ -20,14 +20,16 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#define OUROBOROS_PREFIX "normal-ipcp"
-#include <ouroboros/config.h>
-#include <ouroboros/logs.h>
#include <ouroboros/dev.h>
#include <ouroboros/cacep.h>
#include <ouroboros/cdap.h>
#include <ouroboros/errno.h>
+#include <ouroboros/list.h>
+#include <ouroboros/logs.h>
#include "ae.h"
#include "connmgr.h"
@@ -58,15 +60,39 @@ struct {
pthread_t acceptor;
struct list_head aes;
- pthread_mutex_t aes_lock;
+ pthread_rwlock_t aes_lock;
} connmgr;
-static int add_ae_conn(struct ae * ae,
+
+static int get_info_by_name(const char * name,
+ struct conn_info * info)
+{
+ struct list_head * p;
+
+ pthread_rwlock_rdlock(&connmgr.aes_lock);
+
+ list_for_each(p, &connmgr.aes) {
+ struct ae * ae = list_entry(p, struct ae, next);
+ if (strcmp(ae->info.ae_name, name) == 0) {
+ memcpy(info, &ae->info, sizeof(*info));
+ pthread_rwlock_unlock(&connmgr.aes_lock);
+ return 0;
+ }
+ }
+
+ pthread_rwlock_unlock(&connmgr.aes_lock);
+
+ return -1;
+}
+
+static int add_ae_conn(const char * name,
int fd,
qosspec_t qs,
struct conn_info * rcv_info)
{
- struct ae_conn * ae_conn = NULL;
+ struct ae_conn * ae_conn;
+ struct list_head * p;
+ struct ae * ae = NULL;
ae_conn = malloc(sizeof(*ae_conn));
if (ae_conn == NULL) {
@@ -74,40 +100,45 @@ static int add_ae_conn(struct ae * ae,
return -1;
}
- ae_conn->conn.conn_info = *rcv_info;
+ ae_conn->conn.conn_info = *rcv_info;
ae_conn->conn.flow_info.fd = fd;
ae_conn->conn.flow_info.qs = qs;
list_head_init(&ae_conn->next);
+ pthread_rwlock_wrlock(&connmgr.aes_lock);
+
+ list_for_each(p, &connmgr.aes) {
+ ae = list_entry(p, struct ae, next);
+ if (strcmp(ae->info.ae_name, name) == 0)
+ break;
+ }
+
+ /* Check if entry was removed during allocation. */
+ if (ae == NULL || strcmp(ae->info.ae_name, name) != 0) {
+ pthread_rwlock_unlock(&connmgr.aes_lock);
+ return -1;
+ }
+
pthread_mutex_lock(&ae->conn_lock);
+
list_add(&ae_conn->next, &ae->conn_list);
pthread_cond_signal(&ae->conn_cond);
- pthread_mutex_unlock(&ae->conn_lock);
- return 0;
-}
+ pthread_mutex_unlock(&ae->conn_lock);
-static struct ae * find_ae_by_name(char * name)
-{
- struct list_head * p = NULL;
+ pthread_rwlock_unlock(&connmgr.aes_lock);
- list_for_each(p, &connmgr.aes) {
- struct ae * ae = list_entry(p, struct ae, next);
- if (strcmp(ae->info.ae_name, name) == 0)
- return ae;
- }
-
- return NULL;
+ return 0;
}
static void * flow_acceptor(void * o)
{
int fd;
qosspec_t qs;
+ struct conn_info snd_info;
struct conn_info rcv_info;
struct conn_info fail_info;
- struct ae * ae = NULL;
(void) o;
@@ -132,25 +163,23 @@ static void * flow_acceptor(void * o)
continue;
}
- pthread_mutex_lock(&connmgr.aes_lock);
- ae = find_ae_by_name(rcv_info.ae_name);
- pthread_mutex_unlock(&connmgr.aes_lock);
-
- if (ae != NULL) {
- if (cacep_snd(fd, &ae->info)) {
- log_err("Failed to respond to req.");
- flow_dealloc(fd);
- continue;
- }
-
- if (add_ae_conn(ae, fd, qs, &rcv_info)) {
- log_err("Failed to add ae conn.");
- flow_dealloc(fd);
- continue;
- }
- } else {
+ if (get_info_by_name(rcv_info.ae_name, &snd_info)) {
+ log_err("Failed to get info for %s.", rcv_info.ae_name);
cacep_snd(fd, &fail_info);
flow_dealloc(fd);
+ continue;
+ }
+
+ if (cacep_snd(fd, &snd_info)) {
+ log_err("Failed to respond to request.");
+ flow_dealloc(fd);
+ continue;
+ }
+
+ if (add_ae_conn(rcv_info.ae_name, fd, qs, &rcv_info)) {
+ log_err("Failed to add new connection.");
+ flow_dealloc(fd);
+ continue;
}
}
@@ -159,11 +188,11 @@ static void * flow_acceptor(void * o)
int connmgr_init(void)
{
- list_head_init(&connmgr.aes);
-
- if (pthread_mutex_init(&connmgr.aes_lock, NULL))
+ if (pthread_rwlock_init(&connmgr.aes_lock, NULL))
return -1;
+ list_head_init(&connmgr.aes);
+
return 0;
}
@@ -178,13 +207,12 @@ int connmgr_start(void)
void connmgr_stop(void)
{
pthread_cancel(connmgr.acceptor);
- pthread_join(connmgr.acceptor, NULL);
}
static void destroy_ae(struct ae * ae)
{
- struct list_head * p = NULL;
- struct list_head * h = NULL;
+ struct list_head * p;
+ struct list_head * h;
pthread_mutex_lock(&ae->conn_lock);
@@ -204,20 +232,22 @@ static void destroy_ae(struct ae * ae)
void connmgr_fini(void)
{
- struct list_head * p = NULL;
- struct list_head * n = NULL;
+ struct list_head * p;
+ struct list_head * h;
+
+ pthread_join(connmgr.acceptor, NULL);
- pthread_mutex_lock(&connmgr.aes_lock);
+ pthread_rwlock_wrlock(&connmgr.aes_lock);
- list_for_each_safe(p, n, &connmgr.aes) {
+ list_for_each_safe(p, h, &connmgr.aes) {
struct ae * e = list_entry(p, struct ae, next);
list_del(&e->next);
destroy_ae(e);
}
- pthread_mutex_unlock(&connmgr.aes_lock);
+ pthread_rwlock_unlock(&connmgr.aes_lock);
- pthread_mutex_destroy(&connmgr.aes_lock);
+ pthread_rwlock_destroy(&connmgr.aes_lock);
}
struct ae * connmgr_ae_create(struct conn_info info)
@@ -226,42 +256,46 @@ struct ae * connmgr_ae_create(struct conn_info info)
ae = malloc(sizeof(*ae));
if (ae == NULL)
- return NULL;
+ goto fail_malloc;
list_head_init(&ae->next);
list_head_init(&ae->conn_list);
ae->info = info;
- if (pthread_mutex_init(&ae->conn_lock, NULL)) {
- free(ae);
- return NULL;
- }
+ if (pthread_mutex_init(&ae->conn_lock, NULL))
+ goto fail_mutex_init;
- if (pthread_cond_init(&ae->conn_cond, NULL)) {
- pthread_mutex_destroy(&ae->conn_lock);
- free(ae);
- return NULL;
- }
+ if (pthread_cond_init(&ae->conn_cond, NULL))
+ goto fail_cond_init;
+
+ pthread_rwlock_wrlock(&connmgr.aes_lock);
- pthread_mutex_lock(&connmgr.aes_lock);
list_add(&ae->next, &connmgr.aes);
- pthread_mutex_unlock(&connmgr.aes_lock);
+
+ pthread_rwlock_unlock(&connmgr.aes_lock);
return ae;
+
+ fail_cond_init:
+ pthread_mutex_destroy(&ae->conn_lock);
+ fail_mutex_init:
+ free(ae);
+ fail_malloc:
+ return NULL;
}
void connmgr_ae_destroy(struct ae * ae)
{
assert(ae);
- pthread_mutex_lock(&connmgr.aes_lock);
+ pthread_rwlock_wrlock(&connmgr.aes_lock);
list_del(&ae->next);
- destroy_ae(ae);
+ pthread_rwlock_unlock(&connmgr.aes_lock);
- pthread_mutex_unlock(&connmgr.aes_lock);
+ destroy_ae(ae);
}
int connmgr_alloc(struct ae * ae,
@@ -311,7 +345,7 @@ int connmgr_alloc(struct ae * ae,
int connmgr_wait(struct ae * ae,
struct conn * conn)
{
- struct ae_conn * ae_conn = NULL;
+ struct ae_conn * ae_conn;
assert(ae);
assert(conn);
diff --git a/src/ipcpd/normal/dht.c b/src/ipcpd/normal/dht.c
index f41541d2..65e26406 100644
--- a/src/ipcpd/normal/dht.c
+++ b/src/ipcpd/normal/dht.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "dht"
-#include <ouroboros/config.h>
#include <ouroboros/hash.h>
#include <ouroboros/bitmap.h>
#include <ouroboros/errno.h>
diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c
index 231ba110..feae7013 100644
--- a/src/ipcpd/normal/dir.c
+++ b/src/ipcpd/normal/dir.c
@@ -20,9 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#define OUROBOROS_PREFIX "directory"
-#include <ouroboros/config.h>
#include <ouroboros/endian.h>
#include <ouroboros/errno.h>
#include <ouroboros/logs.h>
diff --git a/src/ipcpd/normal/dt.c b/src/ipcpd/normal/dt.c
index 290c409d..173266f4 100644
--- a/src/ipcpd/normal/dt.c
+++ b/src/ipcpd/normal/dt.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "dt-ae"
-#include <ouroboros/config.h>
#include <ouroboros/bitmap.h>
#include <ouroboros/errno.h>
#include <ouroboros/logs.h>
diff --git a/src/ipcpd/normal/dt_pci.c b/src/ipcpd/normal/dt_pci.c
index e139cf91..9e6dfa89 100644
--- a/src/ipcpd/normal/dt_pci.c
+++ b/src/ipcpd/normal/dt_pci.c
@@ -20,7 +20,6 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
#include <ouroboros/errno.h>
#include <ouroboros/rib.h>
diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c
index be1596d0..a33239a0 100644
--- a/src/ipcpd/normal/enroll.c
+++ b/src/ipcpd/normal/enroll.c
@@ -19,9 +19,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+
+#define _POSIX_C_SOURCE 199309L
+
#define OUROBOROS_PREFIX "enrollment"
-#include <ouroboros/config.h>
#include <ouroboros/endian.h>
#include <ouroboros/errno.h>
#include <ouroboros/cdap.h>
@@ -322,6 +324,7 @@ int enroll_init(void)
void enroll_fini(void)
{
+ pthread_join(enroll.listener, NULL);
cdap_destroy(enroll.cdap);
connmgr_ae_destroy(enroll.ae);
}
@@ -337,5 +340,4 @@ int enroll_start(void)
void enroll_stop(void)
{
pthread_cancel(enroll.listener);
- pthread_join(enroll.listener, NULL);
}
diff --git a/src/ipcpd/normal/fa.c b/src/ipcpd/normal/fa.c
index 2488f017..682dc5c6 100644
--- a/src/ipcpd/normal/fa.c
+++ b/src/ipcpd/normal/fa.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "flow-allocator"
-#include <ouroboros/config.h>
#include <ouroboros/logs.h>
#include <ouroboros/fqueue.h>
#include <ouroboros/rib.h>
diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c
index 9997506c..3b4cc5de 100644
--- a/src/ipcpd/normal/gam.c
+++ b/src/ipcpd/normal/gam.c
@@ -20,9 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#define OUROBOROS_PREFIX "dt-gam"
-#include <ouroboros/config.h>
#include <ouroboros/cdap.h>
#include <ouroboros/dev.h>
#include <ouroboros/logs.h>
diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c
index 27fefdb6..53762415 100644
--- a/src/ipcpd/normal/main.c
+++ b/src/ipcpd/normal/main.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200809L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "normal-ipcp"
-#include <ouroboros/config.h>
#include <ouroboros/endian.h>
#include <ouroboros/logs.h>
#include <ouroboros/ipcp-dev.h>
@@ -156,6 +159,7 @@ static int boot_components(void)
ipcp_set_state(IPCP_OPERATIONAL);
if (connmgr_start()) {
+ ipcp_set_state(IPCP_INIT);
log_err("Failed to start AP connection manager.");
goto fail_connmgr_start;
}
@@ -163,7 +167,6 @@ static int boot_components(void)
return 0;
fail_connmgr_start:
- ipcp_set_state(IPCP_INIT);
enroll_stop();
fail_enroll_start:
dir_fini();
diff --git a/src/ipcpd/normal/neighbors.c b/src/ipcpd/normal/neighbors.c
index 0ac5e958..5da0f0df 100644
--- a/src/ipcpd/normal/neighbors.c
+++ b/src/ipcpd/normal/neighbors.c
@@ -20,9 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 199309L
+
#define OUROBOROS_PREFIX "neighbors"
-#include <ouroboros/config.h>
#include <ouroboros/qoscube.h>
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/errno.h>
diff --git a/src/ipcpd/normal/pff.c b/src/ipcpd/normal/pff.c
index acf4db1a..d6c9ddee 100644
--- a/src/ipcpd/normal/pff.c
+++ b/src/ipcpd/normal/pff.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "pff"
-#include <ouroboros/config.h>
#include <ouroboros/logs.h>
#include <ouroboros/hashtable.h>
#include <ouroboros/errno.h>
diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c
index e31f345a..6c6e7372 100644
--- a/src/ipcpd/normal/pol/complete.c
+++ b/src/ipcpd/normal/pol/complete.c
@@ -20,9 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#define OUROBOROS_PREFIX "complete"
-#include <ouroboros/config.h>
#include <ouroboros/qoscube.h>
#include <ouroboros/rib.h>
#include <ouroboros/dev.h>
diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c
index 966d0d03..1fece07f 100644
--- a/src/ipcpd/normal/pol/flat.c
+++ b/src/ipcpd/normal/pol/flat.c
@@ -20,9 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#define OUROBOROS_PREFIX "flat-addr-auth"
-#include <ouroboros/config.h>
#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
#include <ouroboros/time_utils.h>
diff --git a/src/ipcpd/normal/pol/graph.c b/src/ipcpd/normal/pol/graph.c
index 7ec9c035..3611f0b0 100644
--- a/src/ipcpd/normal/pol/graph.c
+++ b/src/ipcpd/normal/pol/graph.c
@@ -20,9 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#define OUROBOROS_PREFIX "graph"
-#include <ouroboros/config.h>
#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
#include <ouroboros/list.h>
diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c
index 322b22d7..9dfed5c0 100644
--- a/src/ipcpd/normal/pol/link_state.c
+++ b/src/ipcpd/normal/pol/link_state.c
@@ -20,9 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#define OUROBOROS_PREFIX "link-state-routing"
-#include <ouroboros/config.h>
#include <ouroboros/errno.h>
#include <ouroboros/list.h>
#include <ouroboros/logs.h>
diff --git a/src/ipcpd/normal/pol/tests/graph_test.c b/src/ipcpd/normal/pol/tests/graph_test.c
index 30201800..87574187 100644
--- a/src/ipcpd/normal/pol/tests/graph_test.c
+++ b/src/ipcpd/normal/pol/tests/graph_test.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200112L
+
#include <ouroboros/utils.h>
#include <stdio.h>
diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c
index ee81581f..ab2aa430 100644
--- a/src/ipcpd/normal/ribmgr.c
+++ b/src/ipcpd/normal/ribmgr.c
@@ -20,9 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#define OUROBOROS_PREFIX "rib-manager"
-#include <ouroboros/config.h>
#include <ouroboros/logs.h>
#include <ouroboros/cdap.h>
#include <ouroboros/list.h>
diff --git a/src/ipcpd/normal/routing.c b/src/ipcpd/normal/routing.c
index 5bf985fb..c00ec67c 100644
--- a/src/ipcpd/normal/routing.c
+++ b/src/ipcpd/normal/routing.c
@@ -20,9 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#define OUROBOROS_PREFIX "routing"
-#include <ouroboros/config.h>
#include <ouroboros/logs.h>
#include "routing.h"
diff --git a/src/ipcpd/normal/sdu_sched.c b/src/ipcpd/normal/sdu_sched.c
index b46f2563..f3550d5c 100644
--- a/src/ipcpd/normal/sdu_sched.c
+++ b/src/ipcpd/normal/sdu_sched.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 199309L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "sdu-scheduler"
-#include <ouroboros/config.h>
#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c
index 0b81a36a..747a210b 100644
--- a/src/ipcpd/shim-data.c
+++ b/src/ipcpd/shim-data.c
@@ -20,7 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#include <ouroboros/list.h>
#include <ouroboros/time_utils.h>
#include <ouroboros/errno.h>
diff --git a/src/ipcpd/shim-data.h b/src/ipcpd/shim-data.h
index 4fd1ad3d..983f97f6 100644
--- a/src/ipcpd/shim-data.h
+++ b/src/ipcpd/shim-data.h
@@ -20,8 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef IPCPD_IPCP_DATA_H
-#define IPCPD_IPCP_DATA_H
+#ifndef OUROBOROS_IPCPD_IPCP_DATA_H
+#define OUROBOROS_IPCPD_IPCP_DATA_H
#include <ouroboros/qoscube.h>
#include <ouroboros/list.h>
@@ -93,4 +93,4 @@ void shim_data_dir_query_destroy(struct dir_query * query);
int shim_data_dir_query_wait(struct dir_query * query,
const struct timespec * timeout);
-#endif /* IPCPD_SHIM_DATA_H */
+#endif /* OUROBOROS_IPCPD_SHIM_DATA_H */
diff --git a/src/ipcpd/shim-eth-llc/CMakeLists.txt b/src/ipcpd/shim-eth-llc/CMakeLists.txt
index 21003cf0..e10a715f 100644
--- a/src/ipcpd/shim-eth-llc/CMakeLists.txt
+++ b/src/ipcpd/shim-eth-llc/CMakeLists.txt
@@ -15,26 +15,59 @@ include_directories(${CMAKE_BINARY_DIR}/include)
find_path(NETMAP_C_INCLUDE_DIR
net/netmap_user.h
HINTS /usr/include /usr/local/include
- )
+)
+
+mark_as_advanced(NETMAP_C_INCLUDE_DIR)
+
+if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ set(DISABLE_RAW_SOCKETS FALSE CACHE BOOL
+ "Disable raw socket support for LLC shim")
+ if (NOT DISABLE_RAW_SOCKETS)
+ message(STATUS "Raw socket support for shim-eth-llc enabled")
+ set(HAVE_RAW_SOCKETS TRUE PARENT_SCOPE)
+ set(HAVE_LLC TRUE)
+ else ()
+ message(STATUS "Raw socket support for shim-eth-llc disabled by user")
+ endif ()
+endif ()
-find_path(BPF_C_INCLUDE_DIR
- net/bpf.h
- HINTS /usr/include /usr/local/include
+if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ find_path(BPF_C_INCLUDE_DIR
+ net/bpf.h
+ HINTS /usr/include /usr/local/include
)
-if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
- NOT BPF_C_INCLUDE_DIR STREQUAL "BPF_C_INCLUDE_DIR-NOTFOUND")
- message(STATUS "Found Berkeley Packet Filter headers in ${BPF_C_INCLUDE_DIR}")
- set(HAVE_BPF "1" CACHE STRING "Have Berkeley Packet Filter")
+ mark_as_advanced(BPF_C_INCLUDE_DIR)
+
+ if (BPF_C_INCLUDE_DIR)
+ set(DISABLE_BPF FALSE CACHE BOOL
+ "Disable Berkeley Packet Filter support for LLC shim")
+ if (NOT DISABLE_BPF)
+ message(STATUS "Berkeley Packet Filter support "
+ "for shim-eth-llc enabled")
+ set(HAVE_BPF TRUE PARENT_SCOPE)
+ set(HAVE_LLC TRUE)
+ else ()
+ message(STATUS "Berkeley Packet Filter support "
+ "for shim-eth-llc disabled by user")
+ endif ()
+ endif ()
endif ()
-if (NOT NETMAP_C_INCLUDE_DIR STREQUAL "NETMAP_C_INCLUDE_DIR-NOTFOUND")
- message(STATUS "Found netmap headers in ${NETMAP_C_INCLUDE_DIR}")
- set(HAVE_NETMAP "1" CACHE STRING "Have netmap")
- test_and_set_c_compiler_flag_global(-std=c99)
+if (NETMAP_C_INCLUDE_DIR)
+ set(DISABLE_NETMAP FALSE CACHE BOOL
+ "Disable netmap support for LLC shim")
+ if (NOT DISABLE_NETMAP)
+ message(STATUS "Netmap support for shim-eth-llc enabled")
+ set(HAVE_NETMAP TRUE PARENT_SCOPE)
+ test_and_set_c_compiler_flag_global(-std=c99)
+ set(HAVE_LLC TRUE)
+ else ()
+ message(STATUS "Netmap support for shim-eth-llc disabled by user")
+ endif ()
endif ()
-if (HAVE_NETMAP OR HAVE_BPF OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
+if (HAVE_LLC)
message(STATUS "Supported raw Ethernet API found, building shim-eth-llc")
protobuf_generate_c(SHIM_ETH_LLC_PROTO_SRCS SHIM_ETH_LLC_PROTO_HDRS
shim_eth_llc_messages.proto)
@@ -44,8 +77,7 @@ if (HAVE_NETMAP OR HAVE_BPF OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
${CMAKE_CURRENT_SOURCE_DIR}/main.c
)
- set(IPCP_SHIM_ETH_LLC_TARGET ipcpd-shim-eth-llc
- CACHE STRING "IPCP_SHIM_ETH_LLC_TARGET")
+ set(IPCP_SHIM_ETH_LLC_TARGET ipcpd-shim-eth-llc CACHE INTERNAL "")
add_executable(ipcpd-shim-eth-llc ${SHIM_ETH_LLC_SOURCES} ${IPCP_SOURCES}
${SHIM_ETH_LLC_PROTO_SRCS})
@@ -55,7 +87,8 @@ if (HAVE_NETMAP OR HAVE_BPF OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
endif ()
if (HAVE_NETMAP AND NOT APPLE)
- target_include_directories(ipcpd-shim-eth-llc PUBLIC ${NETMAP_C_INCLUDE_DIR})
+ target_include_directories(ipcpd-shim-eth-llc PUBLIC
+ ${NETMAP_C_INCLUDE_DIR})
endif ()
target_link_libraries(ipcpd-shim-eth-llc LINK_PUBLIC ouroboros
diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c
index 55406a00..bcf5abe2 100644
--- a/src/ipcpd/shim-eth-llc/main.c
+++ b/src/ipcpd/shim-eth-llc/main.c
@@ -20,9 +20,17 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#ifdef __APPLE__
+#define _BSD_SOURCE
+#define _DARWIN_C_SOURCE
+#else
+#define _POSIX_C_SOURCE 200112L
+#endif
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "ipcpd/shim-eth-llc"
-#include <ouroboros/config.h>
#include <ouroboros/hash.h>
#include <ouroboros/errno.h>
#include <ouroboros/list.h>
@@ -35,6 +43,7 @@
#include <ouroboros/time_utils.h>
#include "ipcp.h"
+#include "shim-data.h"
#include "shim_eth_llc_messages.pb-c.h"
#include <signal.h>
@@ -79,6 +88,7 @@
#endif
#define THIS_TYPE IPCP_SHIM_ETH_LLC
+
#define MGMT_SAP 0x01
#define MAC_SIZE 6
#define LLC_HEADER_SIZE 3
@@ -117,6 +127,8 @@ struct mgmt_frame {
};
struct {
+ struct shim_data * shim_data;
+
#if defined(HAVE_NETMAP)
struct nm_desc * nmd;
uint8_t hw_addr[MAC_SIZE];
@@ -125,7 +137,7 @@ struct {
#elif defined(HAVE_BPF)
int bpf;
uint8_t hw_addr[MAC_SIZE];
-#elif defined __linux__
+#elif defined HAVE_RAW_SOCKETS
int s_fd;
struct sockaddr_ll device;
#endif /* HAVE_NETMAP */
@@ -154,7 +166,7 @@ static int eth_llc_data_init(void)
int ret = -ENOMEM;
pthread_condattr_t cattr;
- eth_llc_data.fd_to_ef = malloc(sizeof(struct ef) * IRMD_MAX_FLOWS);
+ eth_llc_data.fd_to_ef = malloc(sizeof(struct ef) * SYS_MAX_FLOWS);
if (eth_llc_data.fd_to_ef == NULL)
goto fail_fd_to_ef;
@@ -177,12 +189,16 @@ static int eth_llc_data_init(void)
for (i = 0; i < MAX_SAPS; ++i)
eth_llc_data.ef_to_fd[i] = -1;
- for (i = 0; i < IRMD_MAX_FLOWS; ++i) {
+ for (i = 0; i < SYS_MAX_FLOWS; ++i) {
eth_llc_data.fd_to_ef[i].sap = -1;
eth_llc_data.fd_to_ef[i].r_sap = -1;
memset(&eth_llc_data.fd_to_ef[i].r_addr, 0, MAC_SIZE);
}
+ eth_llc_data.shim_data = shim_data_create();
+ if (eth_llc_data.shim_data == NULL)
+ goto fail_shim_data;
+
ret = -1;
if (pthread_rwlock_init(&eth_llc_data.flows_lock, NULL))
@@ -206,6 +222,7 @@ static int eth_llc_data_init(void)
list_head_init(&eth_llc_data.mgmt_frames);
return 0;
+
fail_mgmt_cond:
pthread_condattr_destroy(&cattr);
fail_condattr:
@@ -213,6 +230,8 @@ static int eth_llc_data_init(void)
fail_mgmt_lock:
pthread_rwlock_destroy(&eth_llc_data.flows_lock);
fail_flows_lock:
+ shim_data_destroy(eth_llc_data.shim_data);
+ fail_shim_data:
fqueue_destroy(eth_llc_data.fq);
fail_fq:
flow_set_destroy(eth_llc_data.np1_flows);
@@ -232,12 +251,13 @@ void eth_llc_data_fini(void)
nm_close(eth_llc_data.nmd);
#elif defined(HAVE_BPF)
close(eth_llc_data.bpf);
-#elif defined(__linux__)
+#elif defined(HAVE_RAW_SOCKETS)
close(eth_llc_data.s_fd);
#endif
pthread_cond_destroy(&eth_llc_data.mgmt_cond);
pthread_mutex_destroy(&eth_llc_data.mgmt_lock);
pthread_rwlock_destroy(&eth_llc_data.flows_lock);
+ shim_data_destroy(eth_llc_data.shim_data);
fqueue_destroy(eth_llc_data.fq);
flow_set_destroy(eth_llc_data.np1_flows);
bmp_destroy(eth_llc_data.saps);
@@ -280,7 +300,7 @@ static int eth_llc_ipcp_send_frame(const uint8_t * dst_addr,
memcpy(llc_frame->src_hwaddr,
#if defined(HAVE_NETMAP) || defined(HAVE_BPF)
eth_llc_data.hw_addr,
-#elif defined(__linux__)
+#elif defined(HAVE_RAW_SOCKETS)
eth_llc_data.device.sll_addr,
#endif /* HAVE_NETMAP */
MAC_SIZE);
@@ -306,7 +326,7 @@ static int eth_llc_ipcp_send_frame(const uint8_t * dst_addr,
return -1;
}
-#elif defined(__linux__)
+#elif defined(HAVE_RAW_SOCKETS)
if (sendto(eth_llc_data.s_fd,
frame,
frame_len,
@@ -475,7 +495,7 @@ static int eth_llc_ipcp_name_query_req(const uint8_t * hash,
{
shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT;
- if (shim_data_reg_has(ipcpi.shim_data, hash)) {
+ if (shim_data_reg_has(eth_llc_data.shim_data, hash)) {
msg.code = SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REPLY;
msg.has_hash = true;
msg.hash.len = ipcp_dir_hash_len();
@@ -495,11 +515,11 @@ static int eth_llc_ipcp_name_query_reply(const uint8_t * hash,
memcpy(&address, r_addr, MAC_SIZE);
- shim_data_dir_add_entry(ipcpi.shim_data, hash, address);
+ shim_data_dir_add_entry(eth_llc_data.shim_data, hash, address);
- pthread_mutex_lock(&ipcpi.shim_data->dir_queries_lock);
+ pthread_mutex_lock(&eth_llc_data.shim_data->dir_queries_lock);
- list_for_each(pos, &ipcpi.shim_data->dir_queries) {
+ list_for_each(pos, &eth_llc_data.shim_data->dir_queries) {
struct dir_query * e =
list_entry(pos, struct dir_query, next);
if (memcmp(e->hash, hash, ipcp_dir_hash_len()) == 0) {
@@ -507,7 +527,7 @@ static int eth_llc_ipcp_name_query_reply(const uint8_t * hash,
}
}
- pthread_mutex_unlock(&ipcpi.shim_data->dir_queries_lock);
+ pthread_mutex_unlock(&eth_llc_data.shim_data->dir_queries_lock);
return 0;
}
@@ -526,7 +546,7 @@ static int eth_llc_ipcp_mgmt_frame(const uint8_t * buf,
switch (msg->code) {
case SHIM_ETH_LLC_MSG_CODE__FLOW_REQ:
- if (shim_data_reg_has(ipcpi.shim_data, msg->hash.data)) {
+ if (shim_data_reg_has(eth_llc_data.shim_data, msg->hash.data)) {
eth_llc_ipcp_sap_req(msg->ssap,
r_addr,
msg->hash.data,
@@ -614,7 +634,7 @@ static void * eth_llc_ipcp_sdu_reader(void * o)
struct nm_pkthdr hdr;
#elif defined(HAVE_BPF)
uint8_t buf[BPF_BLEN];
-#elif defined(__linux__)
+#elif defined(HAVE_RAW_SOCKETS)
uint8_t buf[ETH_FRAME_SIZE];
#endif
int frame_len = 0;
@@ -641,7 +661,7 @@ static void * eth_llc_ipcp_sdu_reader(void * o)
}
#elif defined(HAVE_BPF)
frame_len = read(eth_llc_data.bpf, buf, BPF_BLEN);
-#elif defined(__linux__)
+#elif defined(HAVE_RAW_SOCKETS)
frame_len = recv(eth_llc_data.s_fd, buf,
SHIM_ETH_LLC_MAX_SDU_SIZE, 0);
#endif
@@ -659,7 +679,7 @@ static void * eth_llc_ipcp_sdu_reader(void * o)
#if !defined(HAVE_BPF)
#if defined(HAVE_NETMAP)
if (memcmp(eth_llc_data.hw_addr,
- #elif defined(__linux__)
+ #elif defined(HAVE_RAW_SOCKETS)
if (memcmp(eth_llc_data.device.sll_addr,
#endif /* HAVE_NETMAP */
llc_frame->dst_hwaddr,
@@ -792,7 +812,7 @@ static int eth_llc_ipcp_bootstrap(const struct ipcp_config * conf)
int disable = 0;
int blen;
struct timeval tv = {0, EVENT_WAIT_TIMEOUT};
-#elif defined(__linux__)
+#elif defined(HAVE_RAW_SOCKETS)
struct timeval tv = {0, EVENT_WAIT_TIMEOUT};
#endif /* HAVE_NETMAP */
@@ -825,8 +845,10 @@ static int eth_llc_ipcp_bootstrap(const struct ipcp_config * conf)
log_dbg("Interface %s found.", conf->if_name);
#if defined(HAVE_NETMAP) || defined(HAVE_BPF)
- memcpy(eth_llc_data.hw_addr, LLADDR((struct sockaddr_dl *)(ifa)->ifa_addr), MAC_SIZE);
- #else
+ memcpy(eth_llc_data.hw_addr,
+ LLADDR((struct sockaddr_dl *) (ifa)->ifa_addr),
+ MAC_SIZE);
+ #elif defined (HAVE_RAW_SOCKETS)
memcpy(&ifr.ifr_addr, ifa->ifa_addr, sizeof(*ifa->ifa_addr));
#endif
break;
@@ -927,7 +949,7 @@ static int eth_llc_ipcp_bootstrap(const struct ipcp_config * conf)
}
log_info("Using Berkeley Packet Filter.");
-#elif defined(__linux__)
+#elif defined(HAVE_RAW_SOCKETS)
memset(&(eth_llc_data.device), 0, sizeof(eth_llc_data.device));
eth_llc_data.device.sll_ifindex = idx;
eth_llc_data.device.sll_family = AF_PACKET;
@@ -991,7 +1013,7 @@ static int eth_llc_ipcp_reg(const uint8_t * hash)
return -ENOMEM;
}
- if (shim_data_reg_add_entry(ipcpi.shim_data, hash_dup)) {
+ if (shim_data_reg_add_entry(eth_llc_data.shim_data, hash_dup)) {
log_err("Failed to add " HASH_FMT " to local registry.",
HASH_VAL(hash));
free(hash_dup);
@@ -1005,7 +1027,7 @@ static int eth_llc_ipcp_reg(const uint8_t * hash)
static int eth_llc_ipcp_unreg(const uint8_t * hash)
{
- shim_data_reg_del_entry(ipcpi.shim_data, hash);
+ shim_data_reg_del_entry(eth_llc_data.shim_data, hash);
return 0;
}
@@ -1019,7 +1041,7 @@ static int eth_llc_ipcp_query(const uint8_t * hash)
struct dir_query * query;
int ret;
- if (shim_data_dir_has(ipcpi.shim_data, hash))
+ if (shim_data_dir_has(eth_llc_data.shim_data, hash))
return 0;
msg.code = SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REQ;
@@ -1033,18 +1055,18 @@ static int eth_llc_ipcp_query(const uint8_t * hash)
if (query == NULL)
return -1;
- pthread_mutex_lock(&ipcpi.shim_data->dir_queries_lock);
- list_add(&query->next, &ipcpi.shim_data->dir_queries);
- pthread_mutex_unlock(&ipcpi.shim_data->dir_queries_lock);
+ pthread_mutex_lock(&eth_llc_data.shim_data->dir_queries_lock);
+ list_add(&query->next, &eth_llc_data.shim_data->dir_queries);
+ pthread_mutex_unlock(&eth_llc_data.shim_data->dir_queries_lock);
eth_llc_ipcp_send_mgmt_frame(&msg, r_addr);
ret = shim_data_dir_query_wait(query, &timeout);
- pthread_mutex_lock(&ipcpi.shim_data->dir_queries_lock);
+ pthread_mutex_lock(&eth_llc_data.shim_data->dir_queries_lock);
list_del(&query->next);
shim_data_dir_query_destroy(query);
- pthread_mutex_unlock(&ipcpi.shim_data->dir_queries_lock);
+ pthread_mutex_unlock(&eth_llc_data.shim_data->dir_queries_lock);
return ret;
}
@@ -1066,11 +1088,11 @@ static int eth_llc_ipcp_flow_alloc(int fd,
return -1;
}
- if (!shim_data_dir_has(ipcpi.shim_data, hash)) {
+ if (!shim_data_dir_has(eth_llc_data.shim_data, hash)) {
log_err("Destination unreachable.");
return -1;
}
- addr = shim_data_dir_get_addr(ipcpi.shim_data, hash);
+ addr = shim_data_dir_get_addr(eth_llc_data.shim_data, hash);
pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
diff --git a/src/ipcpd/shim-udp/CMakeLists.txt b/src/ipcpd/shim-udp/CMakeLists.txt
index 3ff8dd5f..eff3f5d0 100644
--- a/src/ipcpd/shim-udp/CMakeLists.txt
+++ b/src/ipcpd/shim-udp/CMakeLists.txt
@@ -15,18 +15,14 @@ include_directories(${CMAKE_BINARY_DIR}/include)
protobuf_generate_c(SHIM_UDP_PROTO_SRCS SHIM_UDP_PROTO_HDRS
shim_udp_messages.proto)
-configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/shim_udp_config.h.in"
- "${CMAKE_CURRENT_BINARY_DIR}/shim_udp_config.h")
-
-set(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET")
+set(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE INTERNAL "")
set(SHIM_UDP_SOURCES
# Add source files here
${CMAKE_CURRENT_SOURCE_DIR}/main.c)
add_executable(ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES}
- ${SHIM_UDP_PROTO_SRCS} "${CMAKE_CURRENT_BINARY_DIR}/shim_udp_config.h")
+ ${SHIM_UDP_PROTO_SRCS})
target_link_libraries(ipcpd-shim-udp LINK_PUBLIC ouroboros
${PROTOBUF_C_LIBRARY})
@@ -40,10 +36,12 @@ find_program(NSLOOKUP_EXECUTABLE
NAMES nslookup
DOC "The nslookup tool that resolves DNS names")
+mark_as_advanced(NSLOOKUP_EXECUTABLE NSUPDATE_EXECUTABLE)
+
include(AddCompileFlags)
-if (${NSUPDATE_EXECUTABLE} STREQUAL "NSUPDATE_EXECUTABLE-NOTFOUND")
+if (NOT NSUPDATE_EXECUTABLE)
message(STATUS "Could not find nsupdate. Disabling DDNS functionality.")
-elseif (${NSLOOKUP_EXECUTABLE} STREQUAL "NSLOOKUP_EXECUTABLE-NOTFOUND")
+elseif (NOT NSLOOKUP_EXECUTABLE)
message(STATUS "Could not find nslookup. Disabling DNS lookups.")
else ()
message(STATUS "Found nsupdate: ${NSUPDATE_EXECUTABLE}")
@@ -56,6 +54,3 @@ if (CMAKE_BUILD_TYPE MATCHES Debug)
endif (CMAKE_BUILD_TYPE MATCHES Debug)
install(TARGETS ipcpd-shim-udp RUNTIME DESTINATION sbin)
-
-# Enable once ipcp-shim-udp has tests
-# add_subdirectory(tests)
diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c
index 195e3bc0..55fe19a6 100644
--- a/src/ipcpd/shim-udp/main.c
+++ b/src/ipcpd/shim-udp/main.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "ipcpd/shim-udp"
-#include <ouroboros/config.h>
#include <ouroboros/hash.h>
#include <ouroboros/list.h>
#include <ouroboros/utils.h>
@@ -32,9 +35,9 @@
#include <ouroboros/errno.h>
#include <ouroboros/logs.h>
-#include "shim_udp_messages.pb-c.h"
#include "ipcp.h"
-#include "shim_udp_config.h"
+#include "shim-data.h"
+#include "shim_udp_messages.pb-c.h"
#include <string.h>
#include <sys/socket.h>
@@ -68,6 +71,8 @@ struct uf {
};
struct {
+ struct shim_data * shim_data;
+
uint32_t ip_addr;
uint32_t dns_addr;
/* listen server */
@@ -79,7 +84,7 @@ struct {
fd_set flow_fd_s;
/* bidir mappings of (n - 1) file descriptor to (n) flow descriptor */
int uf_to_fd[FD_SETSIZE];
- struct uf fd_to_uf[IRMD_MAX_FLOWS];
+ struct uf fd_to_uf[SYS_MAX_FLOWS];
pthread_rwlock_t flows_lock;
pthread_t sduloop;
@@ -98,7 +103,7 @@ static int udp_data_init(void)
for (i = 0; i < FD_SETSIZE; ++i)
udp_data.uf_to_fd[i] = -1;
- for (i = 0; i < IRMD_MAX_FLOWS; ++i) {
+ for (i = 0; i < SYS_MAX_FLOWS; ++i) {
udp_data.fd_to_uf[i].skfd = -1;
udp_data.fd_to_uf[i].udp = -1;
}
@@ -115,6 +120,13 @@ static int udp_data_init(void)
return -ENOMEM;
}
+ udp_data.shim_data = shim_data_create();
+ if (udp_data.shim_data == NULL) {
+ fqueue_destroy(udp_data.fq);
+ flow_set_destroy(udp_data.np1_flows);
+ return -ENOMEM;
+ }
+
pthread_rwlock_init(&udp_data.flows_lock, NULL);
pthread_cond_init(&udp_data.fd_set_cond, NULL);
pthread_mutex_init(&udp_data.fd_set_lock, NULL);
@@ -127,6 +139,8 @@ static void udp_data_fini(void)
flow_set_destroy(udp_data.np1_flows);
fqueue_destroy(udp_data.fq);
+ shim_data_destroy(udp_data.shim_data);
+
pthread_rwlock_destroy(&udp_data.flows_lock);
pthread_mutex_destroy(&udp_data.fd_set_lock);
pthread_cond_destroy(&udp_data.fd_set_cond);
@@ -322,7 +336,7 @@ static int udp_port_to_fd(int udp_port)
{
int i;
- for (i = 0; i < IRMD_MAX_FLOWS; ++i)
+ for (i = 0; i < SYS_MAX_FLOWS; ++i)
if (udp_data.fd_to_uf[i].udp == udp_port)
return i;
@@ -765,7 +779,7 @@ static int ipcp_udp_reg(const uint8_t * hash)
return -ENOMEM;
}
- if (shim_data_reg_add_entry(ipcpi.shim_data, hash_dup)) {
+ if (shim_data_reg_add_entry(udp_data.shim_data, hash_dup)) {
log_err("Failed to add " HASH_FMT " to local registry.",
HASH_VAL(hash));
free(hash_dup);
@@ -794,7 +808,7 @@ static int ipcp_udp_reg(const uint8_t * hash)
dnsstr, hashstr, DNS_TTL, ipstr);
if (ddns_send(cmd)) {
- shim_data_reg_del_entry(ipcpi.shim_data, hash_dup);
+ shim_data_reg_del_entry(udp_data.shim_data, hash_dup);
return -1;
}
}
@@ -835,7 +849,7 @@ static int ipcp_udp_unreg(const uint8_t * hash)
}
#endif
- shim_data_reg_del_entry(ipcpi.shim_data, hash);
+ shim_data_reg_del_entry(udp_data.shim_data, hash);
log_dbg("Unregistered " HASH_FMT ".", HASH_VAL(hash));
@@ -855,7 +869,7 @@ static int ipcp_udp_query(const uint8_t * hash)
ipcp_hash_str(hashstr, hash);
- if (shim_data_dir_has(ipcpi.shim_data, hash))
+ if (shim_data_dir_has(udp_data.shim_data, hash))
return 0;
#ifdef CONFIG_OUROBOROS_ENABLE_DNS
@@ -880,7 +894,7 @@ static int ipcp_udp_query(const uint8_t * hash)
}
#endif
- if (shim_data_dir_add_entry(ipcpi.shim_data, hash, ip_addr)) {
+ if (shim_data_dir_add_entry(udp_data.shim_data, hash, ip_addr)) {
log_err("Failed to add directory entry.");
return -1;
}
@@ -926,12 +940,12 @@ static int ipcp_udp_flow_alloc(int fd,
return -1;
}
- if (!shim_data_dir_has(ipcpi.shim_data, dst)) {
+ if (!shim_data_dir_has(udp_data.shim_data, dst)) {
log_dbg("Could not resolve destination.");
close(skfd);
return -1;
}
- ip_addr = (uint32_t) shim_data_dir_get_addr(ipcpi.shim_data, dst);
+ ip_addr = (uint32_t) shim_data_dir_get_addr(udp_data.shim_data, dst);
/* connect to server (store the remote IP address in the fd) */
memset((char *) &r_saddr, 0, sizeof(r_saddr));
diff --git a/src/ipcpd/shim-udp/shim_udp_config.h.in b/src/ipcpd/shim-udp/shim_udp_config.h.in
deleted file mode 100644
index c32210e9..00000000
--- a/src/ipcpd/shim-udp/shim_udp_config.h.in
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Configuration information specific for the shim UDP
- *
- * Sander Vrijders <sander.vrijders@intec.ugent.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#ifndef OUROBOROS_SHIM_UDP_CONFIG
-#define OUROBOROS_SHIM_UDP_CONFIG
-
-#define NSUPDATE_EXEC "@NSUPDATE_EXECUTABLE@"
-#define NSLOOKUP_EXEC "@NSLOOKUP_EXECUTABLE@"
-
-#endif
diff --git a/src/ipcpd/shim-udp/tests/CMakeLists.txt b/src/ipcpd/shim-udp/tests/CMakeLists.txt
deleted file mode 100644
index bdd7defb..00000000
--- a/src/ipcpd/shim-udp/tests/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-get_filename_component(PARENT_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(PARENT_BINARY_PATH ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
-get_filename_component(PARENT_DIR ${PARENT_SOURCE_PATH} NAME)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${PARENT_SOURCE_PATH})
-include_directories(${PARENT_BINARY_PATH})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
-create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
- # Add new tests here
- shim_udp_test.c
-)
-
-add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${IPCP_SOURCES} ${${PARENT_DIR}_tests})
-target_link_libraries(${PARENT_DIR}_test ouroboros)
-
-include(MacroAddCompileFlags)
-MACRO_ADD_COMPILE_FLAGS(${PARENT_DIR}_test -DMAKE_CHECK)
-
-add_dependencies(check ${PARENT_DIR}_test)
-
-set(tests_to_run ${${PARENT_DIR}_tests})
-remove(tests_to_run test_suite.c)
-
-foreach(test ${tests_to_run})
- get_filename_component(test_name ${test} NAME_WE)
- add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name})
-endforeach(test)
diff --git a/src/ipcpd/shim-udp/tests/shim_udp_test.c b/src/ipcpd/shim-udp/tests/shim_udp_test.c
deleted file mode 100644
index 88669a9e..00000000
--- a/src/ipcpd/shim-udp/tests/shim_udp_test.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Test of the Shim UDP IPCP Daemon
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#include <ouroboros/config.h>
-#include <ouroboros/ipcp.h>
-#include <ouroboros/utils.h>
-#include <ouroboros/shm_du_map.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include "main.c"
-
-#include <ouroboros/logs.h>
-
-struct ipcp * _ipcp;
-
-int shim_udp_test(int argc, char ** argv)
-{
- struct shm_du_map * dum;
- char * ipcp_name = "test-shim-ipcp";
- int i = 0;
-
- char bogus[16];
- memset(&bogus, 0, 16);
-
- struct ipcp_config conf;
- memset(&conf, 0, sizeof conf);
- conf.dif_name = strdup("test-dif");
- conf.type = IPCP_SHIM_UDP;
- conf.ip_addr = 0;
-
- dum = shm_du_map_create();
- if (dum == NULL) {
- log_err("Failed to create shared memory.");
- exit(1);
- }
-
- _ipcp = ipcp_udp_create(ipcp_name);
- if (_ipcp == NULL) {
- log_err("Could not instantiate shim IPCP.");
- shm_du_map_destroy(dum);
- exit(1);
- }
-
- if (ipcp_udp_bootstrap(&conf)) {
- log_err("Could not bootstrap.");
- }
-
- if (ipcp_udp_name_reg("bogus name")) {
- log_err("Failed to register application.");
- shm_du_map_destroy(dum);
- exit(1);
- }
-
- if (ipcp_udp_name_unreg("bogus name")) {
- log_err("Failed to unregister application.");
- shm_du_map_destroy(dum);
- exit(1);
- }
-
- for (i = 0; i < 1000; ++i) {
- sprintf(bogus, "bogus name %4d", i);
- if (ipcp_udp_name_reg(bogus)) {
- log_err("Failed to register application %s.", bogus);
- shm_du_map_destroy(dum);
- exit(1);
- }
- }
-
- for (i = 0; i < 1000; ++i) {
- sprintf(bogus, "bogus name %4d", i);
- if(ipcp_udp_name_unreg(bogus)) {
- log_err("Failed to unregister application %s.", bogus);
- shm_du_map_destroy(dum);
- exit(1);
- }
- }
-
- shm_du_map_destroy(dum);
-
- exit(0);
-}
diff --git a/src/ipcpd/tests/CMakeLists.txt b/src/ipcpd/tests/CMakeLists.txt
deleted file mode 100644
index 9b5eeaa1..00000000
--- a/src/ipcpd/tests/CMakeLists.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-get_filename_component(CURRENT_SOURCE_PARENT_DIR
- ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(CURRENT_BINARY_PARENT_DIR
- ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${CURRENT_SOURCE_PARENT_DIR})
-include_directories(${CURRENT_BINARY_PARENT_DIR})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
-get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(PARENT_DIR ${PARENT_PATH} NAME)
-
-create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
- # Add new tests here
- timerwheel_test.c
- )
-
-add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests})
-target_link_libraries(${PARENT_DIR}_test ouroboros)
-
-add_dependencies(check ${PARENT_DIR}_test)
-
-set(tests_to_run ${${PARENT_DIR}_tests})
-remove(tests_to_run test_suite.c)
-
-foreach (test ${tests_to_run})
- get_filename_component(test_name ${test} NAME_WE)
- add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name})
-endforeach (test)
diff --git a/src/ipcpd/timerwheel.c b/src/ipcpd/timerwheel.c
deleted file mode 100644
index 6086181a..00000000
--- a/src/ipcpd/timerwheel.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Timerwheel
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#include <ouroboros/config.h>
-#include <ouroboros/time_utils.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/list.h>
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-#define FRAC 10 /* accuracy of the timer */
-
-#define tw_used(tw) ((tw->head + tw->elements - tw->tail) & (tw->elements - 1));
-#define tw_free(tw) (tw_used(tw) + 1 < tw->elements)
-#define tw_empty(tw) (tw->head == tw->tail)
-
-enum tw_state {
- TW_NULL = 0,
- TW_RUNNING,
- TW_DESTROY
-};
-
-struct tw_f {
- struct list_head next;
- void (* func)(void *);
- void * arg;
-};
-
-struct tw_el {
- struct list_head funcs;
- struct timespec expiry;
-};
-
-struct timerwheel {
- struct tw_el * wheel;
-
- struct timespec intv;
-
- size_t pos;
-
- struct list_head wq;
-
- pthread_cond_t work;
- pthread_mutex_t lock;
-
- int resolution;
- unsigned int elements;
-
- enum tw_state state;
- pthread_mutex_t s_lock;
-
- pthread_t ticker;
- pthread_t worker;
-};
-
-static void tw_el_fini(struct tw_el * e)
-{
- struct list_head * p;
- struct list_head * h;
-
- list_for_each_safe(p, h, &e->funcs) {
- struct tw_f * f = list_entry(p, struct tw_f, next);
- list_del(&f->next);
- if (f->arg != NULL)
- free(f->arg);
- }
-}
-
-static enum tw_state tw_get_state(struct timerwheel * tw)
-{
- enum tw_state state;
-
- assert(tw);
-
- pthread_mutex_lock(&tw->s_lock);
-
- state = tw->state;
-
- pthread_mutex_unlock(&tw->s_lock);
-
- return state;
-}
-
-static void tw_set_state(struct timerwheel * tw, enum tw_state state)
-{
- assert(tw);
- assert(state != TW_NULL);
-
- pthread_mutex_lock(&tw->s_lock);
-
- tw->state = state;
-
- pthread_mutex_unlock(&tw->s_lock);
-}
-
-static void * worker(void * o)
-{
- struct list_head * p;
- struct list_head * h;
-
- struct timerwheel * tw = (struct timerwheel *) o;
- struct timespec dl;
- struct timespec now;
-
- clock_gettime(PTHREAD_COND_CLOCK, &now);
-
- ts_add(&now, &tw->intv, &dl);
-
- pthread_mutex_lock(&tw->lock);
-
- while (tw_get_state(tw) == TW_RUNNING) {
- if (pthread_cond_timedwait(&tw->work, &tw->lock, &dl)
- == ETIMEDOUT)
- ts_add(&dl, &tw->intv, &dl);
-
- list_for_each_safe(p, h, &tw->wq) {
- struct tw_f * f = list_entry(p, struct tw_f, next);
- list_del(&f->next);
- pthread_mutex_unlock(&tw->lock);
- f->func(f->arg);
- if (f->arg != NULL)
- free(f->arg);
- free(f);
-
- pthread_mutex_lock(&tw->lock);
- }
- }
-
- pthread_mutex_unlock(&tw->lock);
-
- return (void *) o;
-}
-
-static void * movement(void * o)
-{
- struct timerwheel * tw = (struct timerwheel *) o;
- struct timespec now = {0, 0};
- long ms = tw->resolution * tw->elements;
- struct timespec total = {ms / 1000,
- (ms % 1000) * MILLION};
- struct list_head * p;
- struct list_head * h;
-
- while (tw_get_state(tw) == TW_RUNNING) {
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- pthread_mutex_lock(&tw->lock);
-
- if (ts_diff_us(&tw->wheel[tw->pos].expiry, &now) < 0) {
- pthread_mutex_unlock(&tw->lock);
- nanosleep(&tw->intv, NULL);
- continue;
- }
-
- list_for_each_safe(p, h, &tw->wheel[tw->pos].funcs) {
- struct tw_f * f = list_entry(p, struct tw_f, next);
- list_del(&f->next);
- list_add(&f->next, &tw->wq);
- }
-
- ts_add(&tw->wheel[tw->pos].expiry,
- &total,
- &tw->wheel[tw->pos].expiry);
-
- tw->pos = (tw->pos + 1) & (tw->elements - 1);
-
- pthread_cond_signal(&tw->work);
-
- pthread_mutex_unlock(&tw->lock);
- }
-
- return (void *) 0;
-}
-
-struct timerwheel * timerwheel_create(unsigned int resolution,
- unsigned int max_delay)
-{
- struct timespec now = {0, 0};
- struct timespec res_ts = {resolution / 1000,
- (resolution % 1000) * MILLION};
- unsigned long i;
-
- struct timerwheel * tw;
-
- pthread_condattr_t cattr;
-
- assert(resolution != 0);
-
- tw = malloc(sizeof(*tw));
- if (tw == NULL)
- return NULL;
-
- if (pthread_mutex_init(&tw->lock, NULL))
- return NULL;
-
- tw->elements = 1;
-
- while (tw->elements < max_delay / resolution)
- tw->elements <<= 1;
-
- tw->wheel = malloc(sizeof(*tw->wheel) * tw->elements);
- if (tw->wheel == NULL) {
- free(tw);
- return NULL;
- }
-
- tw->resolution = resolution;
-
- tw->intv.tv_sec = (tw->resolution / FRAC) / 1000;
- tw->intv.tv_nsec = ((tw->resolution / FRAC) % 1000) * MILLION;
-
- list_head_init(&tw->wq);
-
- if (pthread_mutex_init(&tw->lock, NULL)) {
- free(tw->wheel);
- free(tw);
- return NULL;
- }
-
- if (pthread_mutex_init(&tw->s_lock, NULL)) {
- pthread_mutex_destroy(&tw->lock);
- free(tw->wheel);
- free(tw);
- return NULL;
- }
-
- if (pthread_condattr_init(&cattr)) {
- pthread_mutex_destroy(&tw->lock);
- free(tw->wheel);
- free(tw);
- return NULL;
- }
-#ifndef __APPLE__
- pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
-#endif
- if (pthread_cond_init(&tw->work, &cattr)) {
- pthread_mutex_destroy(&tw->s_lock);
- pthread_mutex_destroy(&tw->lock);
- free(tw->wheel);
- free(tw);
- return NULL;
- }
-
- tw->pos = 0;
- tw->state = TW_RUNNING;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- now.tv_nsec -= (now.tv_nsec % MILLION);
-
- for (i = 0; i < tw->elements; ++i) {
- list_head_init(&tw->wheel[i].funcs);
- tw->wheel[i].expiry = now;
- ts_add(&now, &res_ts, &now);
- }
-
- if (pthread_create(&tw->worker, NULL, worker, (void *) tw)) {
- pthread_cond_destroy(&tw->work);
- pthread_mutex_destroy(&tw->s_lock);
- pthread_mutex_destroy(&tw->lock);
- free(tw->wheel);
- free(tw);
- return NULL;
- }
-
- if (pthread_create(&tw->ticker, NULL, movement, (void *) tw)) {
- tw_set_state(tw, TW_DESTROY);
- pthread_join(tw->worker, NULL);
- pthread_cond_destroy(&tw->work);
- pthread_mutex_destroy(&tw->s_lock);
- pthread_mutex_destroy(&tw->lock);
- free(tw->wheel);
- free(tw);
- return NULL;
- }
-
- return tw;
-}
-
-void timerwheel_destroy(struct timerwheel * tw)
-{
- unsigned long i;
-
- struct list_head * p;
- struct list_head * h;
-
- tw_set_state(tw, TW_DESTROY);
-
- pthread_join(tw->ticker, NULL);
- pthread_join(tw->worker, NULL);
-
- for (i = 0; i < tw->elements; ++i)
- tw_el_fini(&tw->wheel[i]);
-
- pthread_mutex_lock(&tw->lock);
-
- list_for_each_safe(p, h, &tw->wq) {
- struct tw_f * f = list_entry(p, struct tw_f, next);
- list_del(&f->next);
- if (f->arg != NULL)
- free(f->arg);
- free(f);
- }
-
- pthread_mutex_unlock(&tw->lock);
-
- pthread_cond_destroy(&tw->work);
- pthread_mutex_destroy(&tw->lock);
- pthread_mutex_destroy(&tw->s_lock);
-
- free(tw->wheel);
- free(tw);
-}
-
-int timerwheel_add(struct timerwheel * tw,
- void (* func)(void *),
- void * arg,
- size_t arg_len,
- unsigned int delay)
-{
- int pos;
- struct tw_f * f = malloc(sizeof(*f));
- if (f == NULL)
- return -ENOMEM;
-
- f->func = func;
- f->arg = malloc(arg_len);
- if (f->arg == NULL) {
- free(f);
- return -ENOMEM;
- }
-
- memcpy(f->arg, arg, arg_len);
-
- assert(delay < tw->elements * tw->resolution);
-
- pthread_mutex_lock(&tw->lock);
-
- pos = (tw->pos + delay / tw->resolution) & (tw->elements - 1);
- list_add(&f->next, &tw->wheel[pos].funcs);
-
- pthread_mutex_unlock(&tw->lock);
-
- return 0;
-}
diff --git a/src/irmd/CMakeLists.txt b/src/irmd/CMakeLists.txt
index 930c7b05..3339991a 100644
--- a/src/irmd/CMakeLists.txt
+++ b/src/irmd/CMakeLists.txt
@@ -4,6 +4,28 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_BINARY_DIR}/include)
+set(IRMD_ACCEPT_TIMEOUT 100 CACHE STRING
+ "Timeout for accept in IRMD mainloop threads (ms)")
+set(IRMD_REQ_ARR_TIMEOUT 500 CACHE STRING
+ "Timeout for an application to respond to a new flow (ms)")
+set(IRMD_FLOW_TIMEOUT 5000 CACHE STRING
+ "Timeout for a flow allocation response (ms)")
+set(BOOTSTRAP_TIMEOUT 5000 CACHE STRING
+ "Timeout for an IPCP to bootstrap (ms)")
+set(ENROLL_TIMEOUT 60000 CACHE STRING
+ "Timeout for an IPCP to enroll (ms)")
+set(REG_TIMEOUT 10000 CACHE STRING
+ "Timeout for registering a name (ms)")
+set(QUERY_TIMEOUT 3000 CACHE STRING
+ "Timeout to query a name with an IPCP (ms)")
+set(IRMD_MIN_THREADS 8 CACHE STRING
+ "Minimum number of worker threads in the IRMd.")
+set(IRMD_ADD_THREADS 8 CACHE STRING
+ "Number of extra threads to start when the IRMD faces thread starvation")
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
+
set(SOURCE_FILES
# Add source files here
api_table.c
diff --git a/src/irmd/api_table.c b/src/irmd/api_table.c
index 5765916e..df56dd02 100644
--- a/src/irmd/api_table.c
+++ b/src/irmd/api_table.c
@@ -20,7 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#include <ouroboros/list.h>
#include <ouroboros/errno.h>
#include <ouroboros/time_utils.h>
diff --git a/src/irmd/config.h.in b/src/irmd/config.h.in
new file mode 100644
index 00000000..eb396bbc
--- /dev/null
+++ b/src/irmd/config.h.in
@@ -0,0 +1,46 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Configuration for the IPC Resource Manager
+ *
+ * Dimitri Staessens <dimitri.staessens@ugent.be>
+ * Sander Vrijders <sander.vrijders@ugent.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#define IPCP_SHIM_UDP_EXEC "@IPCP_SHIM_UDP_TARGET@"
+#define IPCP_SHIM_ETH_LLC_EXEC "@IPCP_SHIM_ETH_LLC_TARGET@"
+#define IPCP_NORMAL_EXEC "@IPCP_NORMAL_TARGET@"
+#define IPCP_LOCAL_EXEC "@IPCP_LOCAL_TARGET@"
+
+#define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
+
+#define PTHREAD_COND_CLOCK @PTHREAD_COND_CLOCK@
+
+#define SOCKET_TIMEOUT @SOCKET_TIMEOUT@
+
+#define IRMD_ACCEPT_TIMEOUT @IRMD_ACCEPT_TIMEOUT@
+#define IRMD_REQ_ARR_TIMEOUT @IRMD_REQ_ARR_TIMEOUT@
+#define IRMD_FLOW_TIMEOUT @IRMD_FLOW_TIMEOUT@
+
+#define BOOTSTRAP_TIMEOUT @BOOTSTRAP_TIMEOUT@
+#define ENROLL_TIMEOUT @ENROLL_TIMEOUT@
+#define REG_TIMEOUT @REG_TIMEOUT@
+#define QUERY_TIMEOUT @QUERY_TIMEOUT@
+
+#define SYS_MAX_FLOWS @SYS_MAX_FLOWS@
+
+#define IRMD_MIN_THREADS @IRMD_MIN_THREADS@
+#define IRMD_ADD_THREADS @IRMD_ADD_THREADS@
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c
index f3f97811..e1689b91 100644
--- a/src/irmd/ipcp.c
+++ b/src/irmd/ipcp.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 199309L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "irmd/ipcp"
-#include <ouroboros/config.h>
#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
#include <ouroboros/utils.h>
@@ -49,9 +52,9 @@ ipcp_msg_t * send_recv_ipcp_msg(pid_t api,
ipcp_msg_t * msg)
{
int sockfd = 0;
- buffer_t buf;
+ uint8_t buf[IPCP_MSG_BUF_SIZE];
char * sock_path = NULL;
- ssize_t count = 0;
+ ssize_t len;
ipcp_msg_t * recv_msg = NULL;
struct timeval tv;
@@ -70,14 +73,8 @@ ipcp_msg_t * send_recv_ipcp_msg(pid_t api,
free(sock_path);
- buf.len = ipcp_msg__get_packed_size(msg);
- if (buf.len == 0) {
- close(sockfd);
- return NULL;
- }
-
- buf.data = malloc(IPCP_MSG_BUF_SIZE);
- if (buf.data == NULL) {
+ len = ipcp_msg__get_packed_size(msg);
+ if (len == 0) {
close(sockfd);
return NULL;
}
@@ -110,18 +107,16 @@ ipcp_msg_t * send_recv_ipcp_msg(pid_t api,
log_warn("Failed to set timeout on socket.");
pthread_cleanup_push(close_ptr, (void *) &sockfd);
- pthread_cleanup_push((void (*)(void *)) free, (void *) buf.data);
- ipcp_msg__pack(msg, buf.data);
+ ipcp_msg__pack(msg, buf);
- if (write(sockfd, buf.data, buf.len) != -1)
- count = read(sockfd, buf.data, IPCP_MSG_BUF_SIZE);
+ if (write(sockfd, buf, len) != -1)
+ len = read(sockfd, buf, IPCP_MSG_BUF_SIZE);
- if (count > 0)
- recv_msg = ipcp_msg__unpack(NULL, count, buf.data);
+ if (len > 0)
+ recv_msg = ipcp_msg__unpack(NULL, len, buf);
pthread_cleanup_pop(true);
- pthread_cleanup_pop(true);
return recv_msg;
}
diff --git a/src/irmd/irm_flow.c b/src/irmd/irm_flow.c
index ae5585a2..e335ef48 100644
--- a/src/irmd/irm_flow.c
+++ b/src/irmd/irm_flow.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 199309L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "irm_flow"
-#include <ouroboros/config.h>
#include <ouroboros/errno.h>
#include <ouroboros/logs.h>
#include <ouroboros/time_utils.h>
diff --git a/src/irmd/main.c b/src/irmd/main.c
index a7c2bd4c..66c230c8 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -20,9 +20,13 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200812L
+#define __XSI_VISIBLE 500
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "irmd"
-#include <ouroboros/config.h>
#include <ouroboros/hash.h>
#include <ouroboros/errno.h>
#include <ouroboros/sockets.h>
@@ -2070,7 +2074,7 @@ static int irm_init(void)
list_head_init(&irmd.registry);
list_head_init(&irmd.irm_flows);
- irmd.port_ids = bmp_create(IRMD_MAX_FLOWS, 0);
+ irmd.port_ids = bmp_create(SYS_MAX_FLOWS, 0);
if (irmd.port_ids == NULL) {
log_err("Failed to create port_ids bitmap.");
goto fail_port_ids;
diff --git a/src/irmd/registry.c b/src/irmd/registry.c
index ad6a10d4..3cc9b5f5 100644
--- a/src/irmd/registry.c
+++ b/src/irmd/registry.c
@@ -20,9 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200809L
+
+#include "config.h"
+
#define OUROBOROS_PREFIX "registry"
-#include <ouroboros/config.h>
#include <ouroboros/errno.h>
#include <ouroboros/logs.h>
#include <ouroboros/irm.h>
diff --git a/src/irmd/registry.h b/src/irmd/registry.h
index d1733f6c..486843a2 100644
--- a/src/irmd/registry.h
+++ b/src/irmd/registry.h
@@ -23,7 +23,6 @@
#ifndef OUROBOROS_IRMD_REGISTRY_H
#define OUROBOROS_IRMD_REGISTRY_H
-#include <ouroboros/config.h>
#include <ouroboros/hash.h>
#include <ouroboros/ipcp.h>
#include <ouroboros/list.h>
diff --git a/src/irmd/utils.c b/src/irmd/utils.c
index 5a3da732..08699a05 100644
--- a/src/irmd/utils.c
+++ b/src/irmd/utils.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200809L
+
#include <stdlib.h>
#include <string.h>
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 550bbc08..9d8fbf9c 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -15,7 +15,7 @@ protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto)
if (NOT APPLE)
find_library(LIBRT_LIBRARIES rt)
if (NOT LIBRT_LIBRARIES)
- message(FATAL_ERROR "Could not find librt.")
+ message(FATAL_ERROR "Could not find librt")
endif ()
else ()
set(LIBRT_LIBRARIES "")
@@ -23,7 +23,7 @@ endif ()
find_library(LIBPTHREAD_LIBRARIES pthread)
if (NOT LIBPTHREAD_LIBRARIES)
- message(FATAL_ERROR "Could not find libpthread.")
+ message(FATAL_ERROR "Could not find libpthread")
endif ()
include(CheckSymbolExists)
@@ -31,30 +31,60 @@ list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200809L)
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__XSI_VISIBLE=500)
list(APPEND CMAKE_REQUIRED_LIBRARIES pthread)
check_symbol_exists(pthread_mutexattr_setrobust pthread.h HAVE_ROBUST_MUTEX)
-set(HAVE_ROBUST_MUTEX CACHE STRING "Have robust mutexes")
+
+if (HAVE_ROBUST_MUTEX)
+ set(DISABLE_ROBUST_MUTEXES FALSE CACHE BOOL "Disable robust mutex support")
+ if (NOT DISABLE_ROBUST_MUTEXES)
+ message(STATUS "Robust mutex support enabled")
+ set(HAVE_ROBUST_MUTEX TRUE)
+ else ()
+ message(STATUS "Robust mutex support disabled by user")
+ set(HAVE_ROBUST_MUTEX FALSE)
+ endif ()
+endif ()
find_library(LIBGCRYPT_LIBRARIES gcrypt)
if (LIBGCRYPT_LIBRARIES)
- find_path(LIBGCRYPT_INCLUDE_DIR gcrypt.h HINTS /usr/include /usr/local/include)
- if (NOT LIBGCRYPT_INCLUDE_DIR STREQUAL "GRYPT_INCLUDE_DIR-NOTFOUND")
+ find_path(LIBGCRYPT_INCLUDE_DIR gcrypt.h
+ HINTS /usr/include /usr/local/include)
+ if (LIBGCRYPT_INCLUDE_DIR)
file(STRINGS ${LIBGCRYPT_INCLUDE_DIR}/gcrypt.h GCSTR
REGEX "^#define GCRYPT_VERSION ")
string(REGEX REPLACE "^#define GCRYPT_VERSION \"(.*)\".*$" "\\1"
GCVER "${GCSTR}")
- message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES} (found version \"${GCVER}\")")
+ message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES}"
+ "(found version \"${GCVER}\")")
if (NOT GCVER VERSION_LESS "1.7.0")
- set(HAVE_LIBGCRYPT "1" CACHE STRING "Have libgcrypt")
+ set (DISABLE_LIBGCRYPT FALSE CACHE BOOL "Disable libgcrypt support")
+ if (NOT DISABLE_LIBGCRYPT)
+ message(STATUS "libgcrypt support enabled")
+ set(HAVE_LIBGCRYPT TRUE)
+ else ()
+ message(STATUS "libgcrpyt support disabled by user")
+ endif()
+ else ()
+ message(STATUS "Install version > \"1.7.0\" to enable libgcrypt support")
endif()
endif ()
-else ()
+endif ()
+
+if (NOT HAVE_LIBGCRYPT)
set(LIBGCRYPT_LIBRARIES "")
set(LIBGCRYPT_INCLUDE_DIR "")
endif ()
find_package(OpenSSL)
if (OPENSSL_FOUND)
- set(HAVE_OPENSSL "1" CACHE STRING "Have OpenSSL")
-else ()
+ set (DISABLE_OPENSSL FALSE CACHE BOOL "Disable OpenSSL support")
+ if (NOT DISABLE_OPENSSL)
+ message(STATUS "OpenSSL support enabled")
+ set(HAVE_OPENSSL TRUE)
+ else()
+ message(STATUS "OpenSSL support disabled by user")
+ endif()
+endif ()
+
+if (NOT HAVE_OPENSSL)
set (OPENSSL_INCLUDE_DIR "")
endif ()
@@ -62,9 +92,9 @@ if (APPLE OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(SYS_RND_HDR "")
else ()
find_path(SYS_RND_HDR sys/random.h PATH /usr/include/ /usr/local/include/)
- if (NOT SYS_RND_HDR STREQUAL "SYS_RND_HDR-NOTFOUND")
+ if (SYS_RND_HDR)
message(STATUS "Found sys/random.h in ${SYS_RND_HDR}")
- set(HAVE_SYS_RANDOM "1" CACHE STRING "Have random header")
+ set(HAVE_SYS_RANDOM TRUE)
else ()
set(SYS_RND_HDR "")
endif ()
@@ -73,10 +103,52 @@ endif()
if (NOT ((CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") OR APPLE OR
HAVE_SYS_RANDOM OR HAVE_OPENSSL OR HAVE_LIBGCRYPT))
message(FATAL_ERROR "No secure random generator found, "
- "please install libgcrypt (> 1.7.0) or OpenSSL"
- )
+ "please install libgcrypt (> 1.7.0) or OpenSSL")
endif ()
+mark_as_advanced(LIBRT_LIBRARIES LIBPTHREAD_LIBRARIES
+ LIBGCRYPT_LIBRARIES OPENSSL_LIBRARIES SYS_RND_INCLUDE_DIR
+ LIBGCRYPT_INCLUDE_DIR SYS_RND_HDR)
+
+math(EXPR SHM_BUFFER_EXPR "1 << 20")
+set(SHM_BUFFER_SIZE ${SHM_BUFFER_EXPR} CACHE STRING
+ "Number of blocks in SDU buffer, must be a power of 2")
+set(SYS_MAX_FLOWS 4096 CACHE STRING
+ "Maximum number of total flows for this system")
+set(AP_MAX_FLOWS 1024 CACHE STRING
+ "Maximum number of flows in an application")
+set(AP_RES_FDS 64 CACHE STRING
+ "Number of reserved flow descriptors per application")
+set(AP_MAX_FQUEUES 32 CACHE STRING
+ "Maximum number of flow sets per application")
+set(DU_BUFF_HEADSPACE 128 CACHE STRING
+ "Bytes of headspace to reserve for future headers")
+set(DU_BUFF_TAILSPACE 16 CACHE STRING
+ "Bytes of tailspace to reserve for future tails")
+if (NOT APPLE)
+ set(PTHREAD_COND_CLOCK "CLOCK_MONOTONIC" CACHE STRING
+ "Clock to use for condition variable timing")
+else ()
+ set (PTHREAD_COND_CLOCK "CLOCK_REALTIME" CACHE INTERNAL
+ "Clock to use for condition variable timing")
+endif ()
+set(SOCKET_TIMEOUT 1000 CACHE STRING
+ "Default timeout for responses from IPCPs (ms)")
+set(CDAP_REPLY_TIMEOUT 6000 CACHE STRING
+ "Timeout for CDAP to wait for reply")
+set(SHM_PREFIX "ouroboros" CACHE STRING
+ "String to prepend to POSIX shared memory filenames")
+set(SHM_RBUFF_PREFIX "/${SHM_PREFIX}.rbuff." CACHE INTERNAL
+ "Prefix for rbuff POSIX shared memory filenames")
+set(SHM_LOCKFILE_NAME "/${SHM_PREFIX}.lockfile" CACHE INTERNAL
+ "Filename for the POSIX shared memory lockfile")
+set(SHM_FLOW_SET_PREFIX "/${SHM_PREFIX}.set." CACHE INTERNAL
+ "Prefix for the POSIX shared memory flow set")
+set(SHM_RDRB_NAME "/${SHM_PREFIX}.rdrb" CACHE INTERNAL
+ "Name for the main POSIX shared memory buffer")
+set(SHM_RDRB_BLOCK_SIZE "sysconf(_SC_PAGESIZE)" CACHE STRING
+ "SDU buffer block size, multiple of pagesize for performance")
+
set(SOURCE_FILES
# Add source files here
bitmap.c
@@ -86,6 +158,7 @@ set(SOURCE_FILES
cdap_req.c
crc32.c
dev.c
+ frct_pci.c
hash.c
hashtable.c
irm.c
@@ -93,7 +166,6 @@ set(SOURCE_FILES
lockfile.c
logs.c
md5.c
- nsm.c
qos.c
qoscube.c
random.c
@@ -104,10 +176,14 @@ set(SOURCE_FILES
shm_rdrbuff.c
sockets.c
time_utils.c
+ timerwheel.c
tpm.c
utils.c
)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
+
add_library(ouroboros SHARED ${SOURCE_FILES} ${IRM_PROTO_SRCS}
${IPCP_PROTO_SRCS} ${DIF_CONFIG_PROTO_SRCS} ${CDAP_PROTO_SRCS}
${CACEP_PROTO_SRCS} ${RO_PROTO_SRCS})
diff --git a/src/lib/cacep.c b/src/lib/cacep.c
index 55d11b0f..722adca1 100644
--- a/src/lib/cacep.c
+++ b/src/lib/cacep.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 199309L
+
#include <ouroboros/cacep.h>
#include <ouroboros/dev.h>
#include <ouroboros/errno.h>
diff --git a/src/lib/cdap.c b/src/lib/cdap.c
index bf8d5816..679771f5 100644
--- a/src/lib/cdap.c
+++ b/src/lib/cdap.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200809L
+
#include <ouroboros/cdap.h>
#include <ouroboros/bitmap.h>
#include <ouroboros/dev.h>
diff --git a/src/lib/cdap_req.c b/src/lib/cdap_req.c
index 7aded62f..a9b85525 100644
--- a/src/lib/cdap_req.c
+++ b/src/lib/cdap_req.c
@@ -20,7 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200809L
+
+#include "config.h"
+
#include <ouroboros/time_utils.h>
#include <ouroboros/errno.h>
diff --git a/src/lib/cdap_req.h b/src/lib/cdap_req.h
index 89f4145a..4c9cd15b 100644
--- a/src/lib/cdap_req.h
+++ b/src/lib/cdap_req.h
@@ -23,7 +23,6 @@
#ifndef OUROBOROS_CDAP_REQ_H
#define OUROBOROS_CDAP_REQ_H
-#include <ouroboros/config.h>
#include <ouroboros/cdap.h>
#include <ouroboros/list.h>
#include <ouroboros/utils.h>
diff --git a/src/lib/config.h.in b/src/lib/config.h.in
new file mode 100644
index 00000000..e9c43389
--- /dev/null
+++ b/src/lib/config.h.in
@@ -0,0 +1,57 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Ouroboros library configuration
+ *
+ * Dimitri Staessens <dimitri.staessens@ugent.be>
+ * Sander Vrijders <sander.vrijders@ugent.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#cmakedefine HAVE_SYS_RANDOM
+#cmakedefine HAVE_LIBGCRYPT
+#cmakedefine HAVE_OPENSSL
+
+#define SYS_MAX_FLOWS @SYS_MAX_FLOWS@
+
+#cmakedefine SHM_RBUFF_LOCKLESS
+
+#define SHM_RBUFF_PREFIX "@SHM_RBUFF_PREFIX@"
+#define SHM_LOCKFILE_NAME "@SHM_LOCKFILE_NAME@"
+#define SHM_FLOW_SET_PREFIX "@SHM_FLOW_SET_PREFIX@"
+#define SHM_RDRB_NAME "@SHM_RDRB_NAME@"
+#define SHM_RDRB_BLOCK_SIZE @SHM_RDRB_BLOCK_SIZE@
+#define SHM_BUFFER_SIZE @SHM_BUFFER_SIZE@
+
+#if defined(__linux__) || (defined(__MACH__) && !defined(__APPLE__))
+/* Avoid a bug in robust mutex implementation of glibc 2.25 */
+ #include <features.h>
+ #if !defined(__GLIBC__) || !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 25)
+ #cmakedefine HAVE_ROBUST_MUTEX
+ #endif
+#else
+#cmakedefine HAVE_ROBUST_MUTEX
+#endif
+
+#define PTHREAD_COND_CLOCK @PTHREAD_COND_CLOCK@
+
+#define AP_MAX_FLOWS @AP_MAX_FLOWS@
+#define AP_RES_FDS @AP_RES_FDS@
+#define AP_MAX_FQUEUES @AP_MAX_FQUEUES@
+
+#define DU_BUFF_HEADSPACE @DU_BUFF_HEADSPACE@
+#define DU_BUFF_TAILSPACE @DU_BUFF_TAILSPACE@
+
+#define CDAP_REPLY_TIMEOUT @CDAP_REPLY_TIMEOUT@
diff --git a/src/lib/dev.c b/src/lib/dev.c
index 9354855b..b6c6087f 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -20,7 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200809L
+
+#include "config.h"
+
#include <ouroboros/errno.h>
#include <ouroboros/dev.h>
#include <ouroboros/ipcp-dev.h>
@@ -34,6 +37,8 @@
#include <ouroboros/utils.h>
#include <ouroboros/fqueue.h>
#include <ouroboros/qoscube.h>
+#include <ouroboros/timerwheel.h>
+#include <ouroboros/frct_pci.h>
#include <stdlib.h>
#include <string.h>
@@ -41,8 +46,14 @@
#define BUF_SIZE 1500
+#define TW_ELEMENTS 6000
+#define TW_RESOLUTION 1 /* ms */
+
+#define MPL 2000 /* ms */
+
struct flow_set {
size_t idx;
+ bool np1_set;
};
struct fqueue {
@@ -59,6 +70,22 @@ enum port_state {
PORT_DESTROY
};
+struct frcti {
+ bool used;
+
+ struct tw_f * snd_inact;
+ bool snd_drf;
+ uint64_t snd_lwe;
+ uint64_t snd_rwe;
+
+ struct tw_f * rcv_inact;
+ bool rcv_drf;
+ uint64_t rcv_lwe;
+ uint64_t rcv_rwe;
+
+ uint8_t conf_flags;
+};
+
struct port {
int fd;
@@ -89,10 +116,13 @@ struct {
struct shm_rdrbuff * rdrb;
struct shm_flow_set * fqset;
+ struct timerwheel * tw;
+
struct bmp * fds;
struct bmp * fqueues;
struct flow * flows;
struct port * ports;
+ struct frcti * frcti;
pthread_rwlock_t lock;
} ai;
@@ -203,6 +233,268 @@ static int api_announce(char * ap_name)
return ret;
}
+/* Call under flows lock */
+static int finalize_write(int fd,
+ size_t idx)
+{
+ if (shm_rbuff_write(ai.flows[fd].tx_rb, idx) < 0)
+ return -ENOTALLOC;
+
+ shm_flow_set_notify(ai.flows[fd].set, ai.flows[fd].port_id);
+
+ return 0;
+}
+
+static int frcti_init(int fd)
+{
+ struct frcti * frcti;
+
+ frcti = &(ai.frcti[fd]);
+
+ frcti->used = true;
+
+ frcti->snd_drf = true;
+ frcti->snd_lwe = 0;
+ frcti->snd_rwe = 0;
+
+ frcti->rcv_drf = true;
+ frcti->rcv_lwe = 0;
+ frcti->rcv_rwe = 0;
+
+ frcti->conf_flags = CONF_ERROR_CHECK;
+
+ return 0;
+}
+
+static void frcti_clear(int fd)
+{
+ struct frcti * frcti;
+
+ frcti = &(ai.frcti[fd]);
+
+ frcti->used = false;
+ frcti->snd_inact = NULL;
+ frcti->rcv_inact = NULL;
+}
+
+static void frcti_fini(int fd)
+{
+ struct frcti * frcti;
+
+ frcti = &(ai.frcti[fd]);
+
+ /* FIXME: We actually need to wait until these timers become NULL. */
+ if (frcti->snd_inact != NULL)
+ timerwheel_stop(ai.tw, frcti->snd_inact);
+
+ if (frcti->rcv_inact != NULL)
+ timerwheel_stop(ai.tw, frcti->rcv_inact);
+
+ frcti_clear(fd);
+}
+
+static int frcti_configure(int fd,
+ qosspec_t * qos)
+{
+ /* FIXME: Send configuration message here to other side. */
+
+ (void) fd;
+ (void) qos;
+
+ return 0;
+}
+
+static void frcti_snd_inactivity(void * arg)
+{
+ struct frcti * frcti;
+
+ pthread_rwlock_wrlock(&ai.lock);
+
+ frcti = (struct frcti * ) arg;
+
+ frcti->snd_drf = true;
+ frcti->snd_inact = NULL;
+
+ pthread_rwlock_unlock(&ai.lock);
+}
+
+/* Called under flows lock */
+static int frcti_write(int fd,
+ struct shm_du_buff * sdb)
+{
+ struct frcti * frcti;
+ struct frct_pci pci;
+
+ memset(&pci, 0, sizeof(pci));
+
+ frcti = &(ai.frcti[fd]);
+
+ pthread_rwlock_unlock(&ai.lock);
+
+ timerwheel_move(ai.tw);
+
+ pthread_rwlock_rdlock(&ai.lock);
+
+ /*
+ * Set the DRF in the first packet of a new run of SDUs,
+ * otherwise simply recharge the timer.
+ */
+ if (frcti->snd_drf) {
+ frcti->snd_inact = timerwheel_start(ai.tw, frcti_snd_inactivity,
+ frcti, 2 * MPL);
+ if (frcti->snd_inact == NULL)
+ return -1;
+
+ pci.flags |= FLAG_DATA_RUN;
+ frcti->snd_drf = false;
+ } else {
+ if (timerwheel_restart(ai.tw, frcti->snd_inact, 2 * MPL))
+ return -1;
+ }
+
+ pci.seqno = frcti->snd_lwe++;
+ pci.type |= PDU_TYPE_DATA;
+
+ if (frct_pci_ser(sdb, &pci, frcti->conf_flags & CONF_ERROR_CHECK))
+ return -1;
+
+ if (finalize_write(fd, shm_du_buff_get_idx(sdb)))
+ return -ENOTALLOC;
+
+ return 0;
+}
+
+static void frcti_rcv_inactivity(void * arg)
+{
+ struct frcti * frcti;
+
+ pthread_rwlock_wrlock(&ai.lock);
+
+ frcti = (struct frcti * ) arg;
+
+ frcti->rcv_drf = true;
+ frcti->rcv_inact = NULL;
+
+ pthread_rwlock_unlock(&ai.lock);
+}
+
+static ssize_t frcti_read(int fd)
+{
+ ssize_t idx = -1;
+ struct timespec abstime;
+ struct frcti * frcti;
+ struct frct_pci pci;
+ struct shm_du_buff * sdb;
+
+ timerwheel_move(ai.tw);
+
+ pthread_rwlock_rdlock(&ai.lock);
+
+ if (ai.flows[fd].oflags & FLOW_O_NONBLOCK) {
+ idx = shm_rbuff_read(ai.flows[fd].rx_rb);
+ pthread_rwlock_unlock(&ai.lock);
+ } else {
+ struct shm_rbuff * rb = ai.flows[fd].rx_rb;
+ bool timeo = ai.flows[fd].timesout;
+ struct timespec timeout = ai.flows[fd].rcv_timeo;
+
+ pthread_rwlock_unlock(&ai.lock);
+
+ if (timeo) {
+ clock_gettime(PTHREAD_COND_CLOCK, &abstime);
+ ts_add(&abstime, &timeout, &abstime);
+ idx = shm_rbuff_read_b(rb, &abstime);
+ } else {
+ idx = shm_rbuff_read_b(rb, NULL);
+ }
+ }
+
+ if (idx < 0)
+ return idx;
+
+ pthread_rwlock_rdlock(&ai.lock);
+
+ frcti = &(ai.frcti[fd]);
+
+ sdb = shm_rdrbuff_get(ai.rdrb, idx);
+
+ /* SDU may be corrupted. */
+ if (frct_pci_des(sdb, &pci, frcti->conf_flags & CONF_ERROR_CHECK)) {
+ pthread_rwlock_unlock(&ai.lock);
+ shm_rdrbuff_remove(ai.rdrb, idx);
+ return -EAGAIN;
+ }
+
+ /* We don't accept packets when there is no inactivity timer. */
+ if (frcti->rcv_drf && !(pci.flags & FLAG_DATA_RUN)) {
+ pthread_rwlock_unlock(&ai.lock);
+ shm_rdrbuff_remove(ai.rdrb, idx);
+ return -EAGAIN;
+ }
+
+ /*
+ * If there is an inactivity timer and the DRF is set,
+ * reset the state of the connection.
+ */
+ if (pci.flags & FLAG_DATA_RUN) {
+ frcti->rcv_drf = true;
+ if (frcti->rcv_inact != NULL)
+ timerwheel_stop(ai.tw, frcti->rcv_inact);
+ frcti->rcv_lwe = pci.seqno;
+ }
+
+ /*
+ * Start receiver inactivity if this packet has the DRF,
+ * otherwise simply restart it.
+ */
+ if (frcti->rcv_drf) {
+ frcti->rcv_inact = timerwheel_start(ai.tw, frcti_rcv_inactivity,
+ frcti, 3 * MPL);
+ if (frcti->rcv_inact == NULL) {
+ pthread_rwlock_unlock(&ai.lock);
+ shm_rdrbuff_remove(ai.rdrb, idx);
+ return -EAGAIN;
+ }
+
+ frcti->rcv_drf = false;
+ } else {
+ if (timerwheel_restart(ai.tw, frcti->rcv_inact, 3 * MPL)) {
+ pthread_rwlock_unlock(&ai.lock);
+ shm_rdrbuff_remove(ai.rdrb, idx);
+ return -EAGAIN;
+ }
+ }
+
+ pthread_rwlock_unlock(&ai.lock);
+
+ return idx;
+}
+
+static int frcti_event_wait(struct flow_set * set,
+ struct fqueue * fq,
+ const struct timespec * timeout)
+{
+ int ret;
+
+ assert(set);
+ assert(fq);
+
+ timerwheel_move(ai.tw);
+
+ /*
+ * FIXME: Return the fq only if a data SDU
+ * for the application is available.
+ */
+
+ ret = shm_flow_set_wait(ai.fqset, set->idx, fq->fqueue, timeout);
+ if (ret == -ETIMEDOUT) {
+ fq->fqsize = 0;
+ return -ETIMEDOUT;
+ }
+
+ return ret;
+}
+
static void flow_clear(int fd)
{
assert(!(fd < 0));
@@ -230,6 +522,9 @@ static void flow_fini(int fd)
if (ai.flows[fd].set != NULL)
shm_flow_set_close(ai.flows[fd].set);
+ if (ai.frcti[fd].used)
+ frcti_fini(fd);
+
flow_clear(fd);
}
@@ -316,10 +611,16 @@ int ouroboros_init(const char * ap_name)
if (ai.flows == NULL)
goto fail_flows;
- for (i = 0; i < AP_MAX_FLOWS; ++i)
+ ai.frcti = malloc(sizeof(*ai.frcti) * AP_MAX_FLOWS);
+ if (ai.frcti == NULL)
+ goto fail_frcti;
+
+ for (i = 0; i < AP_MAX_FLOWS; ++i) {
flow_clear(i);
+ frcti_clear(i);
+ }
- ai.ports = malloc(sizeof(*ai.ports) * IRMD_MAX_FLOWS);
+ ai.ports = malloc(sizeof(*ai.ports) * SYS_MAX_FLOWS);
if (ai.ports == NULL)
goto fail_ports;
@@ -334,7 +635,7 @@ int ouroboros_init(const char * ap_name)
}
}
- for (i = 0; i < IRMD_MAX_FLOWS; ++i) {
+ for (i = 0; i < SYS_MAX_FLOWS; ++i) {
ai.ports[i].state = PORT_INIT;
if (pthread_mutex_init(&ai.ports[i].state_lock, NULL)) {
int j;
@@ -353,24 +654,33 @@ int ouroboros_init(const char * ap_name)
if (pthread_rwlock_init(&ai.lock, NULL))
goto fail_lock;
+ ai.tw = timerwheel_create(TW_RESOLUTION,
+ TW_RESOLUTION * TW_ELEMENTS);
+ if (ai.tw == NULL)
+ goto fail_timerwheel;
+
return 0;
+ fail_timerwheel:
+ pthread_rwlock_destroy(&ai.lock);
fail_lock:
- for (i = 0; i < IRMD_MAX_FLOWS; ++i)
+ for (i = 0; i < SYS_MAX_FLOWS; ++i)
pthread_cond_destroy(&ai.ports[i].state_cond);
fail_state_cond:
- for (i = 0; i < IRMD_MAX_FLOWS; ++i)
+ for (i = 0; i < SYS_MAX_FLOWS; ++i)
pthread_mutex_destroy(&ai.ports[i].state_lock);
fail_announce:
free(ai.ap_name);
fail_ap_name:
free(ai.ports);
fail_ports:
+ free(ai.frcti);
+ fail_frcti:
free(ai.flows);
fail_flows:
shm_rdrbuff_close(ai.rdrb);
fail_rdrb:
- shm_flow_set_destroy(ai.fqset);
+ shm_flow_set_destroy(ai.fqset);
fail_fqset:
bmp_destroy(ai.fqueues);
fail_fqueues:
@@ -402,13 +712,16 @@ void ouroboros_fini()
}
}
- for (i = 0; i < IRMD_MAX_FLOWS; ++i) {
+ for (i = 0; i < SYS_MAX_FLOWS; ++i) {
pthread_mutex_destroy(&ai.ports[i].state_lock);
pthread_cond_destroy(&ai.ports[i].state_cond);
}
shm_rdrbuff_close(ai.rdrb);
+ if (ai.tw != NULL)
+ timerwheel_destroy(ai.tw);
+
free(ai.flows);
free(ai.ports);
@@ -463,9 +776,15 @@ int flow_accept(qosspec_t * qs,
if (fd < 0)
return fd;
+ pthread_rwlock_wrlock(&ai.lock);
+
+ frcti_init(fd);
+
if (qs != NULL)
*qs = ai.flows[fd].spec;
+ pthread_rwlock_unlock(&ai.lock);
+
return fd;
}
@@ -505,7 +824,7 @@ int flow_alloc(const char * dst_name,
return -EIRMD;
}
- if (recv_msg->result != 0) {
+ if (recv_msg->result != 0) {
int res = recv_msg->result;
irm_msg__free_unpacked(recv_msg, NULL);
return res;
@@ -520,6 +839,22 @@ int flow_alloc(const char * dst_name,
irm_msg__free_unpacked(recv_msg, NULL);
+ if (fd < 0)
+ return fd;
+
+ pthread_rwlock_wrlock(&ai.lock);
+
+ frcti_init(fd);
+
+ if (frcti_configure(fd, qs)) {
+ flow_fini(fd);
+ bmp_release(ai.fds, fd);
+ pthread_rwlock_unlock(&ai.lock);
+ return -1;
+ }
+
+ pthread_rwlock_unlock(&ai.lock);
+
return fd;
}
@@ -720,34 +1055,31 @@ ssize_t flow_write(int fd,
return idx;
}
- if (shm_rbuff_write(ai.flows[fd].tx_rb, idx) < 0) {
- shm_rdrbuff_remove(ai.rdrb, idx);
- pthread_rwlock_unlock(&ai.lock);
- return -ENOTALLOC;
- }
} else { /* blocking */
- struct shm_rdrbuff * rdrb = ai.rdrb;
- struct shm_rbuff * tx_rb = ai.flows[fd].tx_rb;
-
pthread_rwlock_unlock(&ai.lock);
- assert(tx_rb);
-
- idx = shm_rdrbuff_write_b(rdrb,
+ idx = shm_rdrbuff_write_b(ai.rdrb,
DU_BUFF_HEADSPACE,
DU_BUFF_TAILSPACE,
buf,
count);
- if (shm_rbuff_write(tx_rb, idx) < 0) {
- shm_rdrbuff_remove(rdrb, idx);
- return -ENOTALLOC;
- }
-
pthread_rwlock_rdlock(&ai.lock);
}
- shm_flow_set_notify(ai.flows[fd].set, ai.flows[fd].port_id);
+ if (!ai.frcti[fd].used) {
+ if (finalize_write(fd, idx)) {
+ pthread_rwlock_unlock(&ai.lock);
+ shm_rdrbuff_remove(ai.rdrb, idx);
+ return -ENOTALLOC;
+ }
+ } else {
+ if (frcti_write(fd, shm_rdrbuff_get(ai.rdrb, idx))) {
+ pthread_rwlock_unlock(&ai.lock);
+ shm_rdrbuff_remove(ai.rdrb, idx);
+ return -1;
+ }
+ }
pthread_rwlock_unlock(&ai.lock);
@@ -772,21 +1104,12 @@ ssize_t flow_read(int fd,
return -ENOTALLOC;
}
- if (ai.flows[fd].oflags & FLOW_O_NONBLOCK) {
- idx = shm_rbuff_read(ai.flows[fd].rx_rb);
- pthread_rwlock_unlock(&ai.lock);
- } else {
- struct shm_rbuff * rb = ai.flows[fd].rx_rb;
- bool timeo = ai.flows[fd].timesout;
- struct timespec timeout = ai.flows[fd].rcv_timeo;
-
- pthread_rwlock_unlock(&ai.lock);
+ pthread_rwlock_unlock(&ai.lock);
- if (timeo)
- idx = shm_rbuff_read_b(rb, &timeout);
- else
- idx = shm_rbuff_read_b(rb, NULL);
- }
+ if (!ai.frcti[fd].used)
+ idx = shm_rbuff_read(ai.flows[fd].rx_rb);
+ else
+ idx = frcti_read(fd);
if (idx < 0) {
assert(idx == -EAGAIN || idx == -ETIMEDOUT);
@@ -823,6 +1146,8 @@ struct flow_set * flow_set_create()
return NULL;
}
+ set->np1_set = false;
+
pthread_rwlock_unlock(&ai.lock);
return set;
@@ -891,6 +1216,9 @@ int flow_set_add(struct flow_set * set,
for (i = 0; i < sdus; i++)
shm_flow_set_notify(ai.fqset, ai.flows[fd].port_id);
+ if (ai.frcti[fd].used)
+ set->np1_set = true;
+
pthread_rwlock_unlock(&ai.lock);
return ret;
@@ -960,7 +1288,9 @@ int flow_event_wait(struct flow_set * set,
struct fqueue * fq,
const struct timespec * timeout)
{
- ssize_t ret;
+ ssize_t ret;
+ struct timespec abstime;
+ struct timespec * t = NULL;
if (set == NULL || fq == NULL)
return -EINVAL;
@@ -970,7 +1300,18 @@ int flow_event_wait(struct flow_set * set,
assert(!fq->next);
- ret = shm_flow_set_wait(ai.fqset, set->idx, fq->fqueue, timeout);
+ if (timeout != NULL) {
+ clock_gettime(PTHREAD_COND_CLOCK, &abstime);
+ ts_add(&abstime, timeout, &abstime);
+ t = &abstime;
+ }
+
+ if (set->np1_set)
+ ret = frcti_event_wait(set, fq, t);
+ else
+ ret = shm_flow_set_wait(ai.fqset, set->idx,
+ fq->fqueue, t);
+
if (ret == -ETIMEDOUT) {
fq->fqsize = 0;
return -ETIMEDOUT;
@@ -1132,9 +1473,8 @@ int ipcp_flow_read(int fd,
{
ssize_t idx = -1;
int port_id = -1;
- struct shm_rbuff * rb;
- assert(fd >=0);
+ assert(fd >= 0);
assert(sdb);
pthread_rwlock_rdlock(&ai.lock);
@@ -1144,11 +1484,13 @@ int ipcp_flow_read(int fd,
return -ENOTALLOC;
}
- rb = ai.flows[fd].rx_rb;
-
pthread_rwlock_unlock(&ai.lock);
- idx = shm_rbuff_read(rb);
+ if (!ai.frcti[fd].used)
+ idx = shm_rbuff_read(ai.flows[fd].rx_rb);
+ else
+ idx = frcti_read(fd);
+
if (idx < 0)
return idx;
@@ -1160,8 +1502,6 @@ int ipcp_flow_read(int fd,
int ipcp_flow_write(int fd,
struct shm_du_buff * sdb)
{
- size_t idx;
-
if (sdb == NULL)
return -EINVAL;
@@ -1179,10 +1519,17 @@ int ipcp_flow_write(int fd,
assert(ai.flows[fd].tx_rb);
- idx = shm_du_buff_get_idx(sdb);
-
- shm_rbuff_write(ai.flows[fd].tx_rb, idx);
- shm_flow_set_notify(ai.flows[fd].set, ai.flows[fd].port_id);
+ if (!ai.frcti[fd].used) {
+ if (finalize_write(fd, shm_du_buff_get_idx(sdb))) {
+ pthread_rwlock_unlock(&ai.lock);
+ return -ENOTALLOC;
+ }
+ } else {
+ if (frcti_write(fd, sdb)) {
+ pthread_rwlock_unlock(&ai.lock);
+ return -1;
+ }
+ }
pthread_rwlock_unlock(&ai.lock);
@@ -1274,32 +1621,11 @@ int local_flow_write(int fd,
return -ENOTALLOC;
}
- shm_rbuff_write(ai.flows[fd].tx_rb, idx);
-
- shm_flow_set_notify(ai.flows[fd].set, ai.flows[fd].port_id);
-
- pthread_rwlock_unlock(&ai.lock);
-
- return 0;
-}
-
-int ipcp_read_shim(int fd,
- struct shm_du_buff ** sdb)
-{
- ssize_t idx;
-
- pthread_rwlock_rdlock(&ai.lock);
-
- assert(ai.flows[fd].rx_rb);
-
- idx = shm_rbuff_read(ai.flows[fd].rx_rb);
- if (idx < 0) {
+ if (finalize_write(fd, idx)) {
pthread_rwlock_unlock(&ai.lock);
- return -EAGAIN;
+ return -ENOTALLOC;
}
- *sdb = shm_rdrbuff_get(ai.rdrb, idx);
-
pthread_rwlock_unlock(&ai.lock);
return 0;
diff --git a/src/lib/frct_pci.c b/src/lib/frct_pci.c
new file mode 100644
index 00000000..5ee14829
--- /dev/null
+++ b/src/lib/frct_pci.c
@@ -0,0 +1,112 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Protocol Control Information of FRCT
+ *
+ * Dimitri Staessens <dimitri.staessens@ugent.be>
+ * Sander Vrijders <sander.vrijders@ugent.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#include <ouroboros/frct_pci.h>
+#include <ouroboros/hash.h>
+#include <ouroboros/errno.h>
+
+#define OUROBOROS_PREFIX "frct-pci"
+#include <ouroboros/logs.h>
+
+#include <assert.h>
+#include <string.h>
+
+#define TYPE_SIZE 1
+#define SEQNO_SIZE 8
+#define FLAGS_SIZE 1
+
+/* FIXME: Head size will differ on type */
+#define HEAD_SIZE TYPE_SIZE + FLAGS_SIZE + SEQNO_SIZE
+
+int frct_pci_ser(struct shm_du_buff * sdb,
+ struct frct_pci * pci,
+ bool error_check)
+{
+ uint8_t * head;
+ uint8_t * tail;
+
+ assert(sdb);
+ assert(pci);
+
+ head = shm_du_buff_head_alloc(sdb, HEAD_SIZE);
+ if (head == NULL)
+ return -EPERM;
+
+ memcpy(head, &pci->type, TYPE_SIZE);
+ memcpy(head + TYPE_SIZE, &pci->flags, FLAGS_SIZE);
+ memcpy(head + TYPE_SIZE + FLAGS_SIZE, &pci->seqno, SEQNO_SIZE);
+
+ if (error_check) {
+ tail = shm_du_buff_tail_alloc(sdb, hash_len(HASH_CRC32));
+ if (tail == NULL) {
+ shm_du_buff_head_release(sdb, HEAD_SIZE);
+ return -EPERM;
+ }
+
+ *((uint32_t *) tail) = 0;
+ mem_hash(HASH_CRC32, (uint32_t *) tail, head, tail - head);
+ }
+
+ return 0;
+}
+
+int frct_pci_des(struct shm_du_buff * sdb,
+ struct frct_pci * pci,
+ bool error_check)
+{
+ uint8_t * head;
+ uint8_t * tail;
+ uint32_t crc;
+ uint32_t crc2;
+
+ assert(sdb);
+ assert(pci);
+
+ head = shm_du_buff_head(sdb);
+
+ /* FIXME: Depending on the type a different deserialization */
+ memcpy(&pci->type, head, TYPE_SIZE);
+ memcpy(&pci->flags, head + TYPE_SIZE, FLAGS_SIZE);
+ memcpy(&pci->seqno, head + TYPE_SIZE + FLAGS_SIZE, SEQNO_SIZE);
+
+ if (error_check) {
+ tail = shm_du_buff_tail(sdb);
+ if (tail == NULL)
+ return -EPERM;
+
+ mem_hash(HASH_CRC32, &crc, head,
+ tail - head - hash_len(HASH_CRC32));
+
+ memcpy(&crc2, tail - hash_len(HASH_CRC32),
+ hash_len(HASH_CRC32));
+
+ /* Corrupted SDU */
+ if (crc != crc2)
+ return -1;
+
+ shm_du_buff_tail_release(sdb, hash_len(HASH_CRC32));
+ }
+
+ shm_du_buff_head_release(sdb, HEAD_SIZE);
+
+ return 0;
+}
diff --git a/src/lib/hash.c b/src/lib/hash.c
index d8cabfd3..09e5be8c 100644
--- a/src/lib/hash.c
+++ b/src/lib/hash.c
@@ -23,7 +23,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#include "config.h"
+
#include <ouroboros/hash.h>
#ifndef HAVE_LIBGCRYPT
@@ -64,45 +65,46 @@ uint16_t hash_len(enum hash_algo algo)
#endif
}
-void str_hash(enum hash_algo algo,
- void * buf,
- const char * str)
+void mem_hash(enum hash_algo algo,
+ void * dst,
+ const uint8_t * buf,
+ size_t len)
{
#ifdef HAVE_LIBGCRYPT
- gcry_md_hash_buffer(algo, buf, str, strlen(str));
+ gcry_md_hash_buffer(algo, dst, buf, len);
#else
struct sha3_ctx sha3_ctx;
struct md5_ctx md5_ctx;
switch (algo) {
case HASH_CRC32:
- memset(buf, 0, CRC32_HASH_LEN);
- crc32((uint32_t *) buf, str, strlen(str));
+ memset(dst, 0, CRC32_HASH_LEN);
+ crc32((uint32_t *) dst, buf, len);
break;
case HASH_MD5:
rhash_md5_init(&md5_ctx);
- rhash_md5_update(&md5_ctx, str, strlen(str));
- rhash_md5_final(&md5_ctx, (uint8_t *) buf);
+ rhash_md5_update(&md5_ctx, buf, len);
+ rhash_md5_final(&md5_ctx, (uint8_t *) dst);
break;
case HASH_SHA3_224:
rhash_sha3_224_init(&sha3_ctx);
- rhash_sha3_update(&sha3_ctx, str, strlen(str));
- rhash_sha3_final(&sha3_ctx, (uint8_t *) buf);
+ rhash_sha3_update(&sha3_ctx, buf, len);
+ rhash_sha3_final(&sha3_ctx, (uint8_t *) dst);
break;
case HASH_SHA3_256:
rhash_sha3_256_init(&sha3_ctx);
- rhash_sha3_update(&sha3_ctx, str, strlen(str));
- rhash_sha3_final(&sha3_ctx, (uint8_t *) buf);
+ rhash_sha3_update(&sha3_ctx, buf, len);
+ rhash_sha3_final(&sha3_ctx, (uint8_t *) dst);
break;
case HASH_SHA3_384:
rhash_sha3_384_init(&sha3_ctx);
- rhash_sha3_update(&sha3_ctx, str, strlen(str));
- rhash_sha3_final(&sha3_ctx, (uint8_t *) buf);
+ rhash_sha3_update(&sha3_ctx, buf, len);
+ rhash_sha3_final(&sha3_ctx, (uint8_t *) dst);
break;
case HASH_SHA3_512:
rhash_sha3_512_init(&sha3_ctx);
- rhash_sha3_update(&sha3_ctx, str, strlen(str));
- rhash_sha3_final(&sha3_ctx, (uint8_t *) buf);
+ rhash_sha3_update(&sha3_ctx, buf, len);
+ rhash_sha3_final(&sha3_ctx, (uint8_t *) dst);
break;
default:
assert(false);
@@ -110,3 +112,10 @@ void str_hash(enum hash_algo algo,
}
#endif
}
+
+void str_hash(enum hash_algo algo,
+ void * dst,
+ const char * str)
+{
+ return mem_hash(algo, dst, (const uint8_t *) str, strlen(str));
+}
diff --git a/src/lib/irm.c b/src/lib/irm.c
index a6075d33..4232cec1 100644
--- a/src/lib/irm.c
+++ b/src/lib/irm.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200809L
+
#include <ouroboros/errno.h>
#include <ouroboros/hash.h>
#include <ouroboros/irm.h>
diff --git a/src/lib/lockfile.c b/src/lib/lockfile.c
index e2e4d289..4a3dcb91 100644
--- a/src/lib/lockfile.c
+++ b/src/lib/lockfile.c
@@ -20,7 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#include <ouroboros/lockfile.h>
#include <stdlib.h>
@@ -47,7 +50,7 @@ struct lockfile * lockfile_create() {
mask = umask(0);
- fd = shm_open(LOCKFILE_NAME, O_CREAT | O_EXCL | O_RDWR, 0666);
+ fd = shm_open(SHM_LOCKFILE_NAME, O_CREAT | O_EXCL | O_RDWR, 0666);
if (fd == -1) {
free(lf);
return NULL;
@@ -69,7 +72,7 @@ struct lockfile * lockfile_create() {
close (fd);
if (lf->api == MAP_FAILED) {
- shm_unlink(LOCKFILE_NAME);
+ shm_unlink(SHM_LOCKFILE_NAME);
free(lf);
return NULL;
}
@@ -85,7 +88,7 @@ struct lockfile * lockfile_open() {
if (lf == NULL)
return NULL;
- fd = shm_open(LOCKFILE_NAME, O_RDWR, 0666);
+ fd = shm_open(SHM_LOCKFILE_NAME, O_RDWR, 0666);
if (fd < 0) {
free(lf);
return NULL;
@@ -100,7 +103,7 @@ struct lockfile * lockfile_open() {
close(fd);
if (lf->api == MAP_FAILED) {
- shm_unlink(LOCKFILE_NAME);
+ shm_unlink(SHM_LOCKFILE_NAME);
free(lf);
return NULL;
}
@@ -126,7 +129,7 @@ void lockfile_destroy(struct lockfile * lf)
munmap(lf->api, LF_SIZE);
- shm_unlink(LOCKFILE_NAME);
+ shm_unlink(SHM_LOCKFILE_NAME);
free(lf);
}
diff --git a/src/lib/md5.c b/src/lib/md5.c
index a4d92de3..3394f406 100644
--- a/src/lib/md5.c
+++ b/src/lib/md5.c
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2017
*
- * SHA3 algorithm
+ * MD5 algorithm
*
* Dimitri Staessens <dimitri.staessens@ugent.be>
* Sander Vrijders <sander.vrijders@ugent.be>
diff --git a/src/lib/nsm.c b/src/lib/nsm.c
deleted file mode 100644
index 2dd5729b..00000000
--- a/src/lib/nsm.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * The API to instruct the global Namespace Manager
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#include <ouroboros/nsm.h>
-
-int nsm_reg(char * name,
- char ** dafs,
- size_t dafs_size)
-{
- (void) name;
- (void) dafs;
- (void) dafs_size;
-
- return -1;
-}
-
-int nsm_unreg(char * name,
- char ** dafs,
- size_t dafs_size)
-{
- (void) name;
- (void) dafs;
- (void) dafs_size;
-
-
- return -1;
-}
-
-ssize_t nsm_resolve(char * name,
- char ** dafs)
-{
- (void) name;
- (void) dafs;
-
- return -1;
-}
diff --git a/src/lib/random.c b/src/lib/random.c
index 66aefaa3..27719b26 100644
--- a/src/lib/random.c
+++ b/src/lib/random.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#include "config.h"
+
#include <ouroboros/random.h>
#if defined(__APPLE__) /* Barf */
diff --git a/src/lib/rib.c b/src/lib/rib.c
index e8cf97d4..104dc0cc 100644
--- a/src/lib/rib.c
+++ b/src/lib/rib.c
@@ -20,7 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200809L
+
+#include "config.h"
+
#include <ouroboros/errno.h>
#include <ouroboros/list.h>
#include <ouroboros/rib.h>
diff --git a/src/lib/shm_flow_set.c b/src/lib/shm_flow_set.c
index cd6946d4..78fdce36 100644
--- a/src/lib/shm_flow_set.c
+++ b/src/lib/shm_flow_set.c
@@ -20,7 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200809L
+
+#include "config.h"
+
#include <ouroboros/lockfile.h>
#include <ouroboros/time_utils.h>
#include <ouroboros/shm_flow_set.h>
@@ -38,11 +41,22 @@
#include <string.h>
#include <assert.h>
+/*
+ * pthread_cond_timedwait has a WONTFIX bug as of glibc 2.25 where it
+ * doesn't test pthread cancellation when passed an expired timeout
+ * with the clock set to CLOCK_MONOTONIC.
+ */
+#if ((defined(__linux__) || (defined(__MACH__) && !defined(__APPLE__))) \
+ && (defined(__GLIBC__) && ((__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2025)) \
+ && (PTHREAD_COND_CLOCK == CLOCK_MONOTONIC))
+#define HAVE_CANCEL_BUG
+#endif
+
#define FN_MAX_CHARS 255
#define FQUEUESIZE ((SHM_BUFFER_SIZE) * sizeof(int))
-#define SHM_FLOW_SET_FILE_SIZE (IRMD_MAX_FLOWS * sizeof(ssize_t) \
+#define SHM_FLOW_SET_FILE_SIZE (SYS_MAX_FLOWS * sizeof(ssize_t) \
+ AP_MAX_FQUEUES * sizeof(size_t) \
+ AP_MAX_FQUEUES * sizeof(pthread_cond_t) \
+ AP_MAX_FQUEUES * FQUEUESIZE \
@@ -109,7 +123,7 @@ struct shm_flow_set * shm_flow_set_create()
}
set->mtable = shm_base;
- set->heads = (size_t *) (set->mtable + IRMD_MAX_FLOWS);
+ set->heads = (size_t *) (set->mtable + SYS_MAX_FLOWS);
set->conds = (pthread_cond_t *)(set->heads + AP_MAX_FQUEUES);
set->fqueues = (int *) (set->conds + AP_MAX_FQUEUES);
set->lock = (pthread_mutex_t *)
@@ -132,7 +146,7 @@ struct shm_flow_set * shm_flow_set_create()
pthread_cond_init(&set->conds[i], &cattr);
}
- for (i = 0; i < IRMD_MAX_FLOWS; ++i)
+ for (i = 0; i < SYS_MAX_FLOWS; ++i)
set->mtable[i] = -1;
set->api = getpid();
@@ -175,7 +189,7 @@ struct shm_flow_set * shm_flow_set_open(pid_t api)
}
set->mtable = shm_base;
- set->heads = (size_t *) (set->mtable + IRMD_MAX_FLOWS);
+ set->heads = (size_t *) (set->mtable + SYS_MAX_FLOWS);
set->conds = (pthread_cond_t *)(set->heads + AP_MAX_FQUEUES);
set->fqueues = (int *) (set->conds + AP_MAX_FQUEUES);
set->lock = (pthread_mutex_t *)
@@ -233,7 +247,7 @@ void shm_flow_set_zero(struct shm_flow_set * set,
pthread_mutex_lock(set->lock);
- for (i = 0; i < IRMD_MAX_FLOWS; ++i)
+ for (i = 0; i < SYS_MAX_FLOWS; ++i)
if (set->mtable[i] == (ssize_t) idx)
set->mtable[i] = -1;
@@ -248,7 +262,7 @@ int shm_flow_set_add(struct shm_flow_set * set,
int port_id)
{
assert(set);
- assert(!(port_id < 0) && port_id < IRMD_MAX_FLOWS);
+ assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);
assert(idx < AP_MAX_FQUEUES);
pthread_mutex_lock(set->lock);
@@ -270,7 +284,7 @@ void shm_flow_set_del(struct shm_flow_set * set,
int port_id)
{
assert(set);
- assert(!(port_id < 0) && port_id < IRMD_MAX_FLOWS);
+ assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);
assert(idx < AP_MAX_FQUEUES);
pthread_mutex_lock(set->lock);
@@ -288,7 +302,7 @@ int shm_flow_set_has(struct shm_flow_set * set,
int ret = 0;
assert(set);
- assert(!(port_id < 0) && port_id < IRMD_MAX_FLOWS);
+ assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);
assert(idx < AP_MAX_FQUEUES);
pthread_mutex_lock(set->lock);
@@ -305,7 +319,7 @@ void shm_flow_set_notify(struct shm_flow_set * set,
int port_id)
{
assert(set);
- assert(!(port_id < 0) && port_id < IRMD_MAX_FLOWS);
+ assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);
pthread_mutex_lock(set->lock);
@@ -326,10 +340,9 @@ void shm_flow_set_notify(struct shm_flow_set * set,
ssize_t shm_flow_set_wait(const struct shm_flow_set * set,
size_t idx,
int * fqueue,
- const struct timespec * timeout)
+ const struct timespec * abstime)
{
ssize_t ret = 0;
- struct timespec abstime;
assert(set);
assert(idx < AP_MAX_FQUEUES);
@@ -341,22 +354,23 @@ ssize_t shm_flow_set_wait(const struct shm_flow_set * set,
if (pthread_mutex_lock(set->lock) == EOWNERDEAD)
pthread_mutex_consistent(set->lock);
#endif
- if (timeout != NULL) {
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
- ts_add(&abstime, timeout, &abstime);
- }
pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock,
(void *) set->lock);
while (set->heads[idx] == 0 && ret != -ETIMEDOUT) {
- if (timeout != NULL)
+ if (abstime != NULL) {
ret = -pthread_cond_timedwait(set->conds + idx,
set->lock,
- &abstime);
- else
+ abstime);
+#ifdef HAVE_CANCEL_BUG
+ if (ret == -ETIMEDOUT)
+ pthread_testcancel();
+#endif
+ } else {
ret = -pthread_cond_wait(set->conds + idx,
set->lock);
+ }
#ifdef HAVE_ROBUST_MUTEX
if (ret == -EOWNERDEAD)
pthread_mutex_consistent(set->lock);
diff --git a/src/lib/shm_rbuff.c b/src/lib/shm_rbuff.c
index 7f8af9f5..93108332 100644
--- a/src/lib/shm_rbuff.c
+++ b/src/lib/shm_rbuff.c
@@ -19,9 +19,12 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
-#if ((SHM_RBUFF_LOCKLESS > 0) && \
+#define _POSIX_C_SOURCE 200809L
+
+#include "config.h"
+
+#if (defined(SHM_RBUFF_LOCKLESS) && \
(defined(__GNUC__) || defined (__clang__)))
#include "shm_rbuff_ll.c"
#else
diff --git a/src/lib/shm_rbuff_ll.c b/src/lib/shm_rbuff_ll.c
index 33e236b0..ec0199c0 100644
--- a/src/lib/shm_rbuff_ll.c
+++ b/src/lib/shm_rbuff_ll.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#include "config.h"
+
#include <ouroboros/shm_rbuff.h>
#include <ouroboros/lockfile.h>
#include <ouroboros/time_utils.h>
@@ -281,9 +282,8 @@ ssize_t shm_rbuff_read(struct shm_rbuff * rb)
}
ssize_t shm_rbuff_read_b(struct shm_rbuff * rb,
- const struct timespec * timeout)
+ const struct timespec * abstime)
{
- struct timespec abstime;
ssize_t idx = -1;
assert(rb);
@@ -293,11 +293,6 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff * rb,
if (idx != -EAGAIN)
return idx;
- if (timeout != NULL) {
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
- ts_add(&abstime, timeout, &abstime);
- }
-
#ifndef HAVE_ROBUST_MUTEX
pthread_mutex_lock(rb->lock);
#else
@@ -308,10 +303,10 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff * rb,
(void *) rb->lock);
while (shm_rbuff_empty(rb) && (idx != -ETIMEDOUT)) {
- if (timeout != NULL)
+ if (abstime != NULL)
idx = -pthread_cond_timedwait(rb->add,
rb->lock,
- &abstime);
+ abstime);
else
idx = -pthread_cond_wait(rb->add, rb->lock);
#ifdef HAVE_ROBUST_MUTEX
diff --git a/src/lib/shm_rbuff_pthr.c b/src/lib/shm_rbuff_pthr.c
index 44001458..9567762f 100644
--- a/src/lib/shm_rbuff_pthr.c
+++ b/src/lib/shm_rbuff_pthr.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200809L
+
#include <ouroboros/shm_rbuff.h>
#include <ouroboros/lockfile.h>
#include <ouroboros/time_utils.h>
@@ -284,18 +285,12 @@ ssize_t shm_rbuff_read(struct shm_rbuff * rb)
}
ssize_t shm_rbuff_read_b(struct shm_rbuff * rb,
- const struct timespec * timeout)
+ const struct timespec * abstime)
{
- struct timespec abstime;
ssize_t idx = -1;
assert(rb);
- if (timeout != NULL) {
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
- ts_add(&abstime, timeout, &abstime);
- }
-
#ifndef HAVE_ROBUST_MUTEX
pthread_mutex_lock(rb->lock);
#else
@@ -306,10 +301,10 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff * rb,
(void *) rb->lock);
while (shm_rbuff_empty(rb) && (idx != -ETIMEDOUT)) {
- if (timeout != NULL)
+ if (abstime != NULL)
idx = -pthread_cond_timedwait(rb->add,
rb->lock,
- &abstime);
+ abstime);
else
idx = -pthread_cond_wait(rb->add, rb->lock);
#ifdef HAVE_ROBUST_MUTEX
diff --git a/src/lib/shm_rdrbuff.c b/src/lib/shm_rdrbuff.c
index 0919b1e0..447f8b35 100644
--- a/src/lib/shm_rdrbuff.c
+++ b/src/lib/shm_rdrbuff.c
@@ -20,7 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200809L
+
+#include "config.h"
+
#include <ouroboros/errno.h>
#include <ouroboros/shm_rdrbuff.h>
#include <ouroboros/shm_du_buff.h>
diff --git a/src/lib/sockets.c b/src/lib/sockets.c
index 7f0c4dd4..9f1b326e 100644
--- a/src/lib/sockets.c
+++ b/src/lib/sockets.c
@@ -20,7 +20,6 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
#include <ouroboros/errno.h>
#include <ouroboros/sockets.h>
#include <ouroboros/utils.h>
@@ -96,40 +95,32 @@ static void close_ptr(void * o)
irm_msg_t * send_recv_irm_msg(irm_msg_t * msg)
{
- int sockfd;
- buffer_t buf;
- ssize_t count = 0;
- irm_msg_t * recv_msg = NULL;
+ int sockfd;
+ uint8_t buf[IRM_MSG_BUF_SIZE];
+ ssize_t len;
+ irm_msg_t * recv_msg;
sockfd = client_socket_open(IRM_SOCK_PATH);
if (sockfd < 0)
return NULL;
- buf.len = irm_msg__get_packed_size(msg);
- if (buf.len == 0) {
- close(sockfd);
- return NULL;
- }
-
- buf.data = malloc(IRM_MSG_BUF_SIZE);
- if (buf.data == NULL) {
+ len = irm_msg__get_packed_size(msg);
+ if (len == 0) {
close(sockfd);
return NULL;
}
pthread_cleanup_push(close_ptr, &sockfd);
- pthread_cleanup_push((void (*)(void *)) free, (void *) buf.data);
- irm_msg__pack(msg, buf.data);
+ irm_msg__pack(msg, buf);
- if (write(sockfd, buf.data, buf.len) != -1)
- count = read(sockfd, buf.data, IRM_MSG_BUF_SIZE);
+ if (write(sockfd, buf, len) != -1)
+ len = read(sockfd, buf, IRM_MSG_BUF_SIZE);
- if (count > 0)
- recv_msg = irm_msg__unpack(NULL, count, buf.data);
+ if (len > 0)
+ recv_msg = irm_msg__unpack(NULL, len, buf);
pthread_cleanup_pop(true);
- pthread_cleanup_pop(true);
return recv_msg;
}
diff --git a/src/lib/tests/CMakeLists.txt b/src/lib/tests/CMakeLists.txt
index 41c2074a..0223262a 100644
--- a/src/lib/tests/CMakeLists.txt
+++ b/src/lib/tests/CMakeLists.txt
@@ -1,6 +1,12 @@
get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
get_filename_component(PARENT_DIR ${PARENT_PATH} NAME)
+if (NOT (APPLE OR GNU))
+ set(TIMERWHEEL_TEST "timerwheel_test.c")
+else ()
+ set(TIMERWHEEL_TEST "")
+endif ()
+
create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
# Add new tests here
bitmap_test.c
@@ -11,6 +17,7 @@ create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
rib_test.c
sha3_test.c
time_utils_test.c
+ ${TIMERWHEEL_TEST}
)
add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests})
diff --git a/src/lib/tests/rib_test.c b/src/lib/tests/rib_test.c
index e1fa427d..6a2446b9 100644
--- a/src/lib/tests/rib_test.c
+++ b/src/lib/tests/rib_test.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 199309L
+
#include <ouroboros/time_utils.h>
#include <ouroboros/rib.h>
#include <ouroboros/rqueue.h>
diff --git a/src/ipcpd/tests/timerwheel_test.c b/src/lib/tests/timerwheel_test.c
index 6ba1b890..d7478487 100644
--- a/src/ipcpd/tests/timerwheel_test.c
+++ b/src/lib/tests/timerwheel_test.c
@@ -51,6 +51,9 @@ int timerwheel_test(int argc, char ** argv)
int check_total = 0;
int i;
+ int var = 5;
+
+ struct tw_f * f;
(void) argc;
(void) argv;
@@ -75,13 +78,12 @@ int timerwheel_test(int argc, char ** argv)
for (i = 0; i < additions; ++i) {
int delay = rand() % (resolution * elements);
- int var = rand() % 5;
check_total += var;
- if (timerwheel_add(tw,
- (void (*)(void *)) add,
- (void *) &var,
- sizeof(var),
- delay)) {
+ f = timerwheel_start(tw,
+ (void (*)(void *)) add,
+ (void *) &var,
+ delay);
+ if (f == NULL) {
printf("Failed to add function.");
return -1;
}
@@ -89,14 +91,12 @@ int timerwheel_test(int argc, char ** argv)
nanosleep(&wait, NULL);
- /* On some systems and VMs, the scheduler may be too slow. */
- if (total != check_total)
- nanosleep(&wait, NULL);
+ timerwheel_move(tw);
timerwheel_destroy(tw);
if (total != check_total) {
- printf("Totals do not match.\n");
+ printf("Totals do not match: %d and %d.\n", total, check_total);
return -1;
}
diff --git a/src/lib/time_utils.c b/src/lib/time_utils.c
index 2dec4524..22937d4b 100644
--- a/src/lib/time_utils.c
+++ b/src/lib/time_utils.c
@@ -20,7 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 199309L
+
#include <ouroboros/time_utils.h>
#include <stddef.h>
diff --git a/src/lib/timerwheel.c b/src/lib/timerwheel.c
new file mode 100644
index 00000000..2952c5d3
--- /dev/null
+++ b/src/lib/timerwheel.c
@@ -0,0 +1,232 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Timerwheel
+ *
+ * Dimitri Staessens <dimitri.staessens@ugent.be>
+ * Sander Vrijders <sander.vrijders@ugent.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
+#include <ouroboros/time_utils.h>
+#include <ouroboros/errno.h>
+#include <ouroboros/list.h>
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#define FRAC 10 /* accuracy of the timer */
+
+#define tw_used(tw) ((tw->head + tw->elements - tw->tail) & (tw->elements - 1));
+#define tw_free(tw) (tw_used(tw) + 1 < tw->elements)
+#define tw_empty(tw) (tw->head == tw->tail)
+
+struct tw_f {
+ struct list_head next;
+ void (* func)(void *);
+ void * arg;
+};
+
+struct tw_el {
+ struct list_head funcs;
+ struct timespec expiry;
+};
+
+struct timerwheel {
+ struct tw_el * wheel;
+
+ struct timespec intv;
+
+ size_t pos;
+
+ pthread_mutex_t lock;
+
+ time_t resolution;
+ unsigned int elements;
+};
+
+static void tw_el_fini(struct tw_el * e)
+{
+ struct list_head * p;
+ struct list_head * h;
+
+ list_for_each_safe(p, h, &e->funcs) {
+ struct tw_f * f = list_entry(p, struct tw_f, next);
+ list_del(&f->next);
+ }
+}
+
+void timerwheel_move(struct timerwheel * tw)
+{
+ struct timespec now = {0, 0};
+ long ms = tw->resolution * tw->elements;
+ struct timespec total = {ms / 1000,
+ (ms % 1000) * MILLION};
+ struct list_head * p;
+ struct list_head * h;
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+
+ pthread_mutex_lock(&tw->lock);
+
+ while (ts_diff_us(&tw->wheel[tw->pos].expiry, &now) > 0) {
+ list_for_each_safe(p, h, &tw->wheel[tw->pos].funcs) {
+ struct tw_f * f = list_entry(p, struct tw_f, next);
+ list_del(&f->next);
+ f->func(f->arg);
+ free(f);
+ }
+
+ ts_add(&tw->wheel[tw->pos].expiry,
+ &total,
+ &tw->wheel[tw->pos].expiry);
+
+ tw->pos = (tw->pos + 1) & (tw->elements - 1);
+ }
+
+ pthread_mutex_unlock(&tw->lock);
+}
+
+struct timerwheel * timerwheel_create(time_t resolution,
+ time_t max_delay)
+{
+ struct timespec now = {0, 0};
+ struct timespec res_ts = {resolution / 1000,
+ (resolution % 1000) * MILLION};
+ unsigned long i;
+
+ struct timerwheel * tw;
+
+ assert(resolution != 0);
+
+ tw = malloc(sizeof(*tw));
+ if (tw == NULL)
+ return NULL;
+
+ if (pthread_mutex_init(&tw->lock, NULL))
+ return NULL;
+
+ tw->elements = 1;
+
+ while (tw->elements < max_delay / resolution)
+ tw->elements <<= 1;
+
+ tw->wheel = malloc(sizeof(*tw->wheel) * tw->elements);
+ if (tw->wheel == NULL)
+ goto fail_wheel_malloc;
+
+ tw->resolution = resolution;
+
+ tw->intv.tv_sec = (tw->resolution / FRAC) / 1000;
+ tw->intv.tv_nsec = ((tw->resolution / FRAC) % 1000) * MILLION;
+
+ if (pthread_mutex_init(&tw->lock, NULL))
+ goto fail_lock_init;
+
+ tw->pos = 0;
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ now.tv_nsec -= (now.tv_nsec % MILLION);
+
+ for (i = 0; i < tw->elements; ++i) {
+ list_head_init(&tw->wheel[i].funcs);
+ tw->wheel[i].expiry = now;
+ ts_add(&now, &res_ts, &now);
+ }
+
+ return tw;
+
+ fail_lock_init:
+ free(tw->wheel);
+ fail_wheel_malloc:
+ free(tw);
+ return NULL;
+}
+
+void timerwheel_destroy(struct timerwheel * tw)
+{
+ unsigned long i;
+
+ for (i = 0; i < tw->elements; ++i)
+ tw_el_fini(&tw->wheel[i]);
+
+ pthread_mutex_destroy(&tw->lock);
+ free(tw->wheel);
+ free(tw);
+}
+
+struct tw_f * timerwheel_start(struct timerwheel * tw,
+ void (* func)(void *),
+ void * arg,
+ time_t delay)
+{
+ int pos;
+ struct tw_f * f = malloc(sizeof(*f));
+ if (f == NULL)
+ return NULL;
+
+ f->func = func;
+ f->arg = arg;
+
+ assert(delay < tw->elements * tw->resolution);
+
+ pthread_mutex_lock(&tw->lock);
+
+ pos = (tw->pos + delay / tw->resolution) & (tw->elements - 1);
+ list_add(&f->next, &tw->wheel[pos].funcs);
+
+ pthread_mutex_unlock(&tw->lock);
+
+ return f;
+}
+
+int timerwheel_restart(struct timerwheel * tw,
+ struct tw_f * f,
+ time_t delay)
+{
+ int pos;
+
+ assert(tw);
+ assert(delay < tw->elements * tw->resolution);
+
+ pthread_mutex_lock(&tw->lock);
+
+ list_del(&f->next);
+ pos = (tw->pos + delay / tw->resolution) & (tw->elements - 1);
+ list_add(&f->next, &tw->wheel[pos].funcs);
+
+ pthread_mutex_unlock(&tw->lock);
+
+ return 0;
+}
+
+void timerwheel_stop(struct timerwheel * tw,
+ struct tw_f * f)
+{
+ assert(tw);
+
+ pthread_mutex_lock(&tw->lock);
+
+ list_del(&f->next);
+ free(f);
+
+ pthread_mutex_unlock(&tw->lock);
+}
diff --git a/src/lib/tpm.c b/src/lib/tpm.c
index 739996c4..dd71d276 100644
--- a/src/lib/tpm.c
+++ b/src/lib/tpm.c
@@ -20,7 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include <ouroboros/config.h>
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
#include <ouroboros/errno.h>
#include <ouroboros/list.h>
#include <ouroboros/time_utils.h>
diff --git a/src/nsmd/CMakeLists.txt b/src/nsmd/CMakeLists.txt
deleted file mode 100644
index 2995b725..00000000
--- a/src/nsmd/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
-set(SOURCE_FILES
- # Add source files here
- main.c
- )
-
-add_executable(nsmd ${SOURCE_FILES})
-
-target_link_libraries(nsmd LINK_PUBLIC ouroboros)
-
-include(AddCompileFlags)
-if (CMAKE_BUILD_TYPE MATCHES Debug)
- add_compile_flags(nsmd -DCONFIG_OUROBOROS_DEBUG)
-endif (CMAKE_BUILD_TYPE MATCHES Debug)
-
-install(TARGETS nsmd RUNTIME DESTINATION sbin)
-
-# Enable once nsmd has tests
-# add_subdirectory(tests)
diff --git a/src/nsmd/main.c b/src/nsmd/main.c
deleted file mode 100644
index 537aaa81..00000000
--- a/src/nsmd/main.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Normal IPC Process
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#define OUROBOROS_PREFIX "nsmd"
-
-#include <ouroboros/logs.h>
-
-int main(void)
-{
- log_dbg("Test of the NSMd");
-
- return 0;
-}
diff --git a/src/nsmd/tests/CMakeLists.txt b/src/nsmd/tests/CMakeLists.txt
deleted file mode 100644
index 68bd762d..00000000
--- a/src/nsmd/tests/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-get_filename_component(tmp ".." ABSOLUTE)
-get_filename_component(src_folder "${tmp}" NAME)
-
-create_test_sourcelist(${src_folder}_tests test_suite.c
- # Add new tests here
-)
-
-add_executable(${src_folder}_test EXCLUDE_FROM_ALL ${${src_folder}_tests})
-target_link_libraries(${src_folder}_test ouroboros)
-
-add_dependencies(check ${src_folder}_test)
-
-set(tests_to_run ${${src_folder}_tests})
-remove(tests_to_run test_suite.c)
-
-foreach(test ${tests_to_run})
- get_filename_component(test_name ${test} NAME_WE)
- add_test(${test_name} ${C_TEST_PATH}/${src_folder}_test ${test_name})
-endforeach(test)
diff --git a/src/tools/operf/operf.c b/src/tools/operf/operf.c
index d2dfeaa3..e54fbc6b 100644
--- a/src/tools/operf/operf.c
+++ b/src/tools/operf/operf.c
@@ -21,6 +21,7 @@
*/
#define _POSIX_C_SOURCE 199506L
+#define __XSI_VISIBLE 500
#include <ouroboros/fqueue.h>
#include <ouroboros/dev.h>
diff --git a/src/tools/operf/operf_client.c b/src/tools/operf/operf_client.c
index a905b05e..4ad26d13 100644
--- a/src/tools/operf/operf_client.c
+++ b/src/tools/operf/operf_client.c
@@ -24,10 +24,6 @@
#include <ouroboros/fcntl.h>
#include <ouroboros/time_utils.h>
-#ifdef __FreeBSD__
-#define __XSI_VISIBLE 500
-#endif
-
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
diff --git a/src/tools/operf/operf_server.c b/src/tools/operf/operf_server.c
index 3b43ece4..c016ad63 100644
--- a/src/tools/operf/operf_server.c
+++ b/src/tools/operf/operf_server.c
@@ -20,10 +20,6 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifdef __FreeBSD__
-#define __XSI_VISIBLE 500
-#endif
-
#include <stdlib.h>
#include <signal.h>
#include <arpa/inet.h>
diff --git a/src/tools/oping/CMakeLists.txt b/src/tools/oping/CMakeLists.txt
index f129a02b..b95add7e 100644
--- a/src/tools/oping/CMakeLists.txt
+++ b/src/tools/oping/CMakeLists.txt
@@ -9,6 +9,8 @@ if(NOT LIBM_LIBRARIES)
message(FATAL_ERROR "libm not found")
endif()
+mark_as_advanced(LIBM_LIBRARIES)
+
set(SOURCE_FILES
# Add source files here
oping.c
diff --git a/src/tools/oping/oping.c b/src/tools/oping/oping.c
index be87343e..13132815 100644
--- a/src/tools/oping/oping.c
+++ b/src/tools/oping/oping.c
@@ -21,6 +21,7 @@
*/
#define _POSIX_C_SOURCE 199506L
+#define __XSI_VISIBLE 500
#include <ouroboros/fqueue.h>
#include <ouroboros/dev.h>
diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c
index d0fc2d66..db0ef199 100644
--- a/src/tools/oping/oping_client.c
+++ b/src/tools/oping/oping_client.c
@@ -24,10 +24,6 @@
#include <ouroboros/fcntl.h>
#include <ouroboros/time_utils.h>
-#ifdef __FreeBSD__
-#define __XSI_VISIBLE 500
-#endif
-
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
diff --git a/src/tools/oping/oping_server.c b/src/tools/oping/oping_server.c
index 3a7f061c..57d1fd7c 100644
--- a/src/tools/oping/oping_server.c
+++ b/src/tools/oping/oping_server.c
@@ -20,10 +20,6 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifdef __FreeBSD__
-#define __XSI_VISIBLE 500
-#endif
-
#include <stdlib.h>
#include <signal.h>
#include <arpa/inet.h>