summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/CMakeLists.txt12
-rw-r--r--src/lib/cacep.c7
-rw-r--r--src/lib/config.h.in1
-rw-r--r--src/lib/dev.c269
-rw-r--r--src/lib/frct.c125
-rw-r--r--src/lib/hash.c4
-rw-r--r--src/lib/hashtable.c4
-rw-r--r--src/lib/ipcpd_messages.proto5
-rw-r--r--src/lib/irm.c18
-rw-r--r--src/lib/irmd_messages.proto5
-rw-r--r--src/lib/md5.c4
-rw-r--r--src/lib/qos.c97
-rw-r--r--src/lib/qoscube.c30
-rw-r--r--src/lib/qosspec.proto33
-rw-r--r--src/lib/rib.c15
-rw-r--r--src/lib/rxmwheel.c2
-rw-r--r--src/lib/sha3.c4
-rw-r--r--src/lib/shm_flow_set.c84
-rw-r--r--src/lib/shm_rbuff.c24
-rw-r--r--src/lib/shm_rbuff_ll.c4
-rw-r--r--src/lib/shm_rbuff_pthr.c4
-rw-r--r--src/lib/shm_rdrbuff.c2
-rw-r--r--src/lib/sockets.c35
23 files changed, 423 insertions, 365 deletions
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 47e93d61..1c2007c3 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -6,6 +6,8 @@ include_directories(${CMAKE_BINARY_DIR}/include)
protobuf_generate_c(IRM_PROTO_SRCS IRM_PROTO_HDRS irmd_messages.proto)
protobuf_generate_c(IPCP_PROTO_SRCS IPCP_PROTO_HDRS ipcpd_messages.proto)
+protobuf_generate_c(QOSSPEC_PROTO_SRCS QOSSPEC_PROTO_HDRS
+ qosspec.proto)
protobuf_generate_c(LAYER_CONFIG_PROTO_SRCS LAYER_CONFIG_PROTO_HDRS
ipcp_config.proto)
protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto)
@@ -136,7 +138,7 @@ mark_as_advanced(LIBRT_LIBRARIES LIBPTHREAD_LIBRARIES
LIBGCRYPT_INCLUDE_DIR SYS_RND_HDR)
set(SHM_BUFFER_SIZE 4096 CACHE STRING
- "Number of blocks in SDU buffer, must be a power of 2")
+ "Number of blocks in packet buffer, must be a power of 2")
set(SYS_MAX_FLOWS 10240 CACHE STRING
"Maximum number of total flows for this system")
set(PROG_MAX_FLOWS 4096 CACHE STRING
@@ -169,11 +171,13 @@ set(SHM_FLOW_SET_PREFIX "/${SHM_PREFIX}.set." CACHE INTERNAL
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")
+ "Packet buffer block size, multiple of pagesize for performance")
set(SHM_RDRB_MULTI_BLOCK true CACHE BOOL
- "SDU buffer multiblock SDU support")
+ "Packet buffer multiblock packet support")
set(SHM_RBUFF_LOCKLESS 0 CACHE BOOL
"Enable shared memory lockless rbuff support")
+set(QOS_DISABLE_CRC 0 CACHE BOOL
+ "Ignores ber setting on all QoS cubes")
set(SOURCE_FILES_DEV
# Add source files here
@@ -213,7 +217,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
add_library(ouroboros-common SHARED ${SOURCE_FILES_COMMON} ${IRM_PROTO_SRCS}
- ${IPCP_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS})
+ ${IPCP_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS} ${QOSSPEC_PROTO_SRCS})
add_library(ouroboros-dev SHARED ${SOURCE_FILES_DEV} ${CACEP_PROTO_SRCS})
diff --git a/src/lib/cacep.c b/src/lib/cacep.c
index 6efb7295..12751078 100644
--- a/src/lib/cacep.c
+++ b/src/lib/cacep.c
@@ -32,7 +32,7 @@
#include "cacep.pb-c.h"
typedef CacepMsg cacep_msg_t;
-#define BUF_SIZE 64
+#define BUF_SIZE 128
static int read_msg(int fd,
struct conn_info * info)
@@ -49,6 +49,11 @@ static int read_msg(int fd,
if (msg == NULL)
return -1;
+ if (strlen(msg->comp_name) > CACEP_BUF_STRLEN) {
+ cacep_msg__free_unpacked(msg, NULL);
+ return -1;
+ }
+
strcpy(info->comp_name, msg->comp_name);
strcpy(info->protocol, msg->protocol);
diff --git a/src/lib/config.h.in b/src/lib/config.h.in
index 69e7f4b0..e8cfeba3 100644
--- a/src/lib/config.h.in
+++ b/src/lib/config.h.in
@@ -28,6 +28,7 @@
#cmakedefine SHM_RBUFF_LOCKLESS
#cmakedefine SHM_RDRB_MULTI_BLOCK
+#cmakedefine QOS_DISABLE_CRC
#define SHM_RBUFF_PREFIX "@SHM_RBUFF_PREFIX@"
#define SHM_LOCKFILE_NAME "@SHM_LOCKFILE_NAME@"
diff --git a/src/lib/dev.c b/src/lib/dev.c
index e69fec26..2a5c3f83 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -20,9 +20,14 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#if defined(__linux__) || defined(__CYGWIN__)
+#define _DEFAULT_SOURCE
+#else
+#define _POSIX_C_SOURCE 200809L
+#endif
+
#include <ouroboros/endian.h>
-#define _POSIX_C_SOURCE 200809L
#include "config.h"
#include <ouroboros/hash.h>
@@ -39,7 +44,6 @@
#include <ouroboros/shm_rbuff.h>
#include <ouroboros/utils.h>
#include <ouroboros/fqueue.h>
-#include <ouroboros/qoscube.h>
#include <stdlib.h>
#include <string.h>
@@ -56,6 +60,8 @@
#define NO_PART -1
#define DONE_PART -2
+#define CRCLEN (sizeof(uint32_t))
+
struct flow_set {
size_t idx;
};
@@ -89,9 +95,8 @@ struct flow {
struct shm_rbuff * rx_rb;
struct shm_rbuff * tx_rb;
struct shm_flow_set * set;
- int port_id;
+ int flow_id;
int oflags;
- qoscube_t cube;
qosspec_t spec;
ssize_t part_idx;
@@ -166,12 +171,12 @@ static void port_set_state(struct port * p,
pthread_mutex_unlock(&p->state_lock);
}
-static enum port_state port_wait_assign(int port_id)
+static enum port_state port_wait_assign(int flow_id)
{
enum port_state state;
struct port * p;
- p = &ai.ports[port_id];
+ p = &ai.ports[flow_id];
pthread_mutex_lock(&p->state_lock);
@@ -230,17 +235,16 @@ static void flow_clear(int fd)
{
memset(&ai.flows[fd], 0, sizeof(ai.flows[fd]));
- ai.flows[fd].port_id = -1;
+ ai.flows[fd].flow_id = -1;
ai.flows[fd].pid = -1;
- ai.flows[fd].cube = QOS_CUBE_BE;
}
static void flow_fini(int fd)
{
assert(fd >= 0 && fd < SYS_MAX_FLOWS);
- if (ai.flows[fd].port_id != -1) {
- port_destroy(&ai.ports[ai.flows[fd].port_id]);
+ if (ai.flows[fd].flow_id != -1) {
+ port_destroy(&ai.ports[ai.flows[fd].flow_id]);
bmp_release(ai.fds, fd);
}
@@ -256,7 +260,7 @@ static void flow_fini(int fd)
if (ai.flows[fd].set != NULL) {
shm_flow_set_notify(ai.flows[fd].set,
- ai.flows[fd].port_id,
+ ai.flows[fd].flow_id,
FLOW_DEALLOC);
shm_flow_set_close(ai.flows[fd].set);
}
@@ -267,9 +271,9 @@ static void flow_fini(int fd)
flow_clear(fd);
}
-static int flow_init(int port_id,
+static int flow_init(int flow_id,
pid_t pid,
- qoscube_t qc)
+ qosspec_t qs)
{
int fd;
int err = -ENOMEM;
@@ -282,11 +286,11 @@ static int flow_init(int port_id,
goto fail_fds;
}
- ai.flows[fd].rx_rb = shm_rbuff_open(ai.pid, port_id);
+ ai.flows[fd].rx_rb = shm_rbuff_open(ai.pid, flow_id);
if (ai.flows[fd].rx_rb == NULL)
goto fail;
- ai.flows[fd].tx_rb = shm_rbuff_open(pid, port_id);
+ ai.flows[fd].tx_rb = shm_rbuff_open(pid, flow_id);
if (ai.flows[fd].tx_rb == NULL)
goto fail;
@@ -294,16 +298,15 @@ static int flow_init(int port_id,
if (ai.flows[fd].set == NULL)
goto fail;
- ai.flows[fd].port_id = port_id;
+ ai.flows[fd].flow_id = flow_id;
ai.flows[fd].oflags = FLOWFDEFAULT;
ai.flows[fd].pid = pid;
- ai.flows[fd].cube = qc;
- ai.flows[fd].spec = qos_cube_to_spec(qc);
ai.flows[fd].part_idx = NO_PART;
+ ai.flows[fd].spec = qs;
- ai.ports[port_id].fd = fd;
+ ai.ports[flow_id].fd = fd;
- port_set_state(&ai.ports[port_id], PORT_ID_ASSIGNED);
+ port_set_state(&ai.ports[flow_id], PORT_ID_ASSIGNED);
pthread_rwlock_unlock(&ai.lock);
@@ -447,7 +450,7 @@ static void fini(void)
pthread_rwlock_wrlock(&ai.lock);
for (i = 0; i < PROG_MAX_FLOWS; ++i) {
- if (ai.flows[i].port_id != -1) {
+ if (ai.flows[i].flow_id != -1) {
ssize_t idx;
shm_rbuff_set_acl(ai.flows[i].rx_rb, ACL_FLOWDOWN);
while ((idx = shm_rbuff_read(ai.flows[i].rx_rb)) >= 0)
@@ -493,7 +496,6 @@ int flow_accept(qosspec_t * qs,
irm_msg_t msg = IRM_MSG__INIT;
irm_msg_t * recv_msg;
int fd;
- qoscube_t qc;
msg.code = IRM_MSG_CODE__IRM_FLOW_ACCEPT;
msg.has_pid = true;
@@ -521,15 +523,14 @@ int flow_accept(qosspec_t * qs,
return res;
}
- if (!recv_msg->has_pid || !recv_msg->has_port_id ||
- !recv_msg->has_qoscube) {
+ if (!recv_msg->has_pid || !recv_msg->has_flow_id ||
+ recv_msg->qosspec == NULL) {
irm_msg__free_unpacked(recv_msg, NULL);
return -EIRMD;
}
- qc = recv_msg->qoscube;
-
- fd = flow_init(recv_msg->port_id, recv_msg->pid, recv_msg->qoscube);
+ fd = flow_init(recv_msg->flow_id, recv_msg->pid,
+ msg_to_spec(recv_msg->qosspec));
irm_msg__free_unpacked(recv_msg, NULL);
@@ -538,12 +539,10 @@ int flow_accept(qosspec_t * qs,
pthread_rwlock_wrlock(&ai.lock);
- /* FIXME: check if FRCT is needed based on qc? */
-
assert(ai.flows[fd].frcti == NULL);
- if (qc != QOS_CUBE_RAW) {
- ai.flows[fd].frcti = frcti_create(fd, qc);
+ if (ai.flows[fd].spec.in_order != 0) {
+ ai.flows[fd].frcti = frcti_create(fd);
if (ai.flows[fd].frcti == NULL) {
flow_fini(fd);
pthread_rwlock_unlock(&ai.lock);
@@ -563,21 +562,21 @@ int flow_alloc(const char * dst,
qosspec_t * qs,
const struct timespec * timeo)
{
- irm_msg_t msg = IRM_MSG__INIT;
- irm_msg_t * recv_msg;
- qoscube_t qc = QOS_CUBE_RAW;
- int fd;
-
- msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC;
- msg.dst = (char *) dst;
- msg.has_pid = true;
- msg.has_qoscube = true;
- msg.pid = ai.pid;
+ irm_msg_t msg = IRM_MSG__INIT;
+ qosspec_msg_t qs_msg = QOSSPEC_MSG__INIT;
+ irm_msg_t * recv_msg;
+ int fd;
+#ifdef QOS_DISABLE_CRC
if (qs != NULL)
- qc = qos_spec_to_cube(*qs);
-
- msg.qoscube = qc;
+ qs->ber = 1;
+#endif
+ msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC;
+ msg.dst = (char *) dst;
+ msg.has_pid = true;
+ msg.pid = ai.pid;
+ qs_msg = spec_to_msg(qs);
+ msg.qosspec = &qs_msg;
if (timeo != NULL) {
msg.has_timeo_sec = true;
@@ -601,12 +600,13 @@ int flow_alloc(const char * dst,
return res;
}
- if (!recv_msg->has_pid || !recv_msg->has_port_id) {
+ if (!recv_msg->has_pid || !recv_msg->has_flow_id) {
irm_msg__free_unpacked(recv_msg, NULL);
return -EIRMD;
}
- fd = flow_init(recv_msg->port_id, recv_msg->pid, qc);
+ fd = flow_init(recv_msg->flow_id, recv_msg->pid,
+ qs == NULL ? qos_raw : *qs);
irm_msg__free_unpacked(recv_msg, NULL);
@@ -617,8 +617,8 @@ int flow_alloc(const char * dst,
assert(ai.flows[fd].frcti == NULL);
- if (qc != QOS_CUBE_RAW) {
- ai.flows[fd].frcti = frcti_create(fd, qc);
+ if (ai.flows[fd].spec.in_order != 0) {
+ ai.flows[fd].frcti = frcti_create(fd);
if (ai.flows[fd].frcti == NULL) {
flow_fini(fd);
pthread_rwlock_unlock(&ai.lock);
@@ -640,15 +640,15 @@ int flow_dealloc(int fd)
return -EINVAL;
msg.code = IRM_MSG_CODE__IRM_FLOW_DEALLOC;
- msg.has_port_id = true;
+ msg.has_flow_id = true;
msg.has_pid = true;
msg.pid = ai.pid;
pthread_rwlock_rdlock(&ai.lock);
- assert(ai.flows[fd].port_id >= 0);
+ assert(ai.flows[fd].flow_id >= 0);
- msg.port_id = ai.flows[fd].port_id;
+ msg.flow_id = ai.flows[fd].flow_id;
pthread_rwlock_unlock(&ai.lock);
@@ -676,7 +676,6 @@ int fccntl(int fd,
int cmd,
...)
{
- uint16_t sflags;
uint32_t * fflags;
uint16_t * cflags;
va_list l;
@@ -696,7 +695,7 @@ int fccntl(int fd,
pthread_rwlock_wrlock(&ai.lock);
- if (flow->port_id < 0) {
+ if (flow->flow_id < 0) {
pthread_rwlock_unlock(&ai.lock);
va_end(l);
return -ENOTALLOC;
@@ -768,13 +767,13 @@ int fccntl(int fd,
rx_acl |= ACL_FLOWDOWN;
tx_acl |= ACL_FLOWDOWN;
shm_flow_set_notify(flow->set,
- flow->port_id,
+ flow->flow_id,
FLOW_DOWN);
} else {
rx_acl &= ~ACL_FLOWDOWN;
tx_acl &= ~ACL_FLOWDOWN;
shm_flow_set_notify(flow->set,
- flow->port_id,
+ flow->flow_id,
FLOW_UP);
}
@@ -788,11 +787,6 @@ int fccntl(int fd,
goto einval;
*fflags = flow->oflags;
break;
- case FRCTSFLAGS:
- sflags = (uint16_t) va_arg(l, int);
- if (flow->frcti == NULL || frcti_setconf(flow->frcti, sflags))
- goto eperm;
- break;
case FRCTGFLAGS:
cflags = (uint16_t *) va_arg(l, int *);
if (cflags == NULL)
@@ -824,16 +818,40 @@ int fccntl(int fd,
return -EPERM;
}
+static int chk_crc(struct shm_du_buff * sdb)
+{
+ uint32_t crc;
+ uint8_t * head = shm_du_buff_head(sdb);
+ uint8_t * tail = shm_du_buff_tail_release(sdb, CRCLEN);
+
+ mem_hash(HASH_CRC32, &crc, head, tail - head);
+
+ return !(crc == *((uint32_t *) tail));
+}
+
+static int add_crc(struct shm_du_buff * sdb)
+{
+ uint8_t * head = shm_du_buff_head(sdb);
+ uint8_t * tail = shm_du_buff_tail_alloc(sdb, CRCLEN);
+ if (tail == NULL)
+ return -1;
+
+ mem_hash(HASH_CRC32, tail, head, tail - head);
+
+ return 0;
+}
+
ssize_t flow_write(int fd,
const void * buf,
size_t count)
{
- struct flow * flow;
- ssize_t idx;
- int ret;
- int flags;
- struct timespec abs;
- struct timespec * abstime = NULL;
+ struct flow * flow;
+ ssize_t idx;
+ int ret;
+ int flags;
+ struct timespec abs;
+ struct timespec * abstime = NULL;
+ struct shm_du_buff * sdb;
if (buf == NULL)
return 0;
@@ -847,7 +865,7 @@ ssize_t flow_write(int fd,
pthread_rwlock_rdlock(&ai.lock);
- if (flow->port_id < 0) {
+ if (flow->flow_id < 0) {
pthread_rwlock_unlock(&ai.lock);
return -ENOTALLOC;
}
@@ -880,18 +898,25 @@ ssize_t flow_write(int fd,
if (idx < 0)
return idx;
- if (frcti_snd(flow->frcti, shm_rdrbuff_get(ai.rdrb, idx)) < 0) {
+ sdb = shm_rdrbuff_get(ai.rdrb, idx);
+
+ if (frcti_snd(flow->frcti, sdb) < 0) {
+ shm_rdrbuff_remove(ai.rdrb, idx);
+ return -ENOMEM;
+ }
+
+ if (flow->spec.ber == 0 && add_crc(sdb) != 0) {
shm_rdrbuff_remove(ai.rdrb, idx);
return -ENOMEM;
}
pthread_rwlock_rdlock(&ai.lock);
- ret = shm_rbuff_write(ai.flows[fd].tx_rb, idx);
+ ret = shm_rbuff_write(flow->tx_rb, idx);
if (ret < 0)
shm_rdrbuff_remove(ai.rdrb, idx);
else
- shm_flow_set_notify(flow->set, flow->port_id, FLOW_PKT);
+ shm_flow_set_notify(flow->set, flow->flow_id, FLOW_PKT);
pthread_rwlock_unlock(&ai.lock);
@@ -906,7 +931,7 @@ ssize_t flow_read(int fd,
{
ssize_t idx;
ssize_t n;
- uint8_t * sdu;
+ uint8_t * packet;
struct shm_rbuff * rb;
struct shm_du_buff * sdb;
struct timespec abs;
@@ -929,7 +954,7 @@ ssize_t flow_read(int fd,
pthread_rwlock_rdlock(&ai.lock);
- if (flow->port_id < 0) {
+ if (flow->flow_id < 0) {
pthread_rwlock_unlock(&ai.lock);
return -ENOTALLOC;
}
@@ -955,23 +980,25 @@ ssize_t flow_read(int fd,
if (idx < 0)
return idx;
sdb = shm_rdrbuff_get(ai.rdrb, idx);
+ if (flow->spec.ber == 0 && chk_crc(sdb) != 0)
+ continue;
} while (frcti_rcv(flow->frcti, sdb) != 0);
}
}
- n = shm_rdrbuff_read(&sdu, ai.rdrb, idx);
+ n = shm_rdrbuff_read(&packet, ai.rdrb, idx);
assert(n >= 0);
if (n <= (ssize_t) count) {
- memcpy(buf, sdu, n);
+ memcpy(buf, packet, n);
shm_rdrbuff_remove(ai.rdrb, idx);
flow->part_idx = (partrd && n == (ssize_t) count) ?
DONE_PART : NO_PART;
return n;
} else {
if (partrd) {
- memcpy(buf, sdu, count);
+ memcpy(buf, packet, count);
sdb = shm_rdrbuff_get(ai.rdrb, idx);
shm_du_buff_head_release(sdb, n);
flow->part_idx = idx;
@@ -1053,7 +1080,7 @@ int fset_add(struct flow_set * set,
int fd)
{
int ret;
- size_t sdus;
+ size_t packets;
size_t i;
if (set == NULL || fd < 0 || fd > SYS_MAX_FLOWS)
@@ -1061,11 +1088,11 @@ int fset_add(struct flow_set * set,
pthread_rwlock_wrlock(&ai.lock);
- ret = shm_flow_set_add(ai.fqset, set->idx, ai.flows[fd].port_id);
+ ret = shm_flow_set_add(ai.fqset, set->idx, ai.flows[fd].flow_id);
- sdus = shm_rbuff_queued(ai.flows[fd].rx_rb);
- for (i = 0; i < sdus; i++)
- shm_flow_set_notify(ai.fqset, ai.flows[fd].port_id, FLOW_PKT);
+ packets = shm_rbuff_queued(ai.flows[fd].rx_rb);
+ for (i = 0; i < packets; i++)
+ shm_flow_set_notify(ai.fqset, ai.flows[fd].flow_id, FLOW_PKT);
pthread_rwlock_unlock(&ai.lock);
@@ -1080,8 +1107,8 @@ void fset_del(struct flow_set * set,
pthread_rwlock_wrlock(&ai.lock);
- if (ai.flows[fd].port_id >= 0)
- shm_flow_set_del(ai.fqset, set->idx, ai.flows[fd].port_id);
+ if (ai.flows[fd].flow_id >= 0)
+ shm_flow_set_del(ai.fqset, set->idx, ai.flows[fd].flow_id);
pthread_rwlock_unlock(&ai.lock);
}
@@ -1096,12 +1123,12 @@ bool fset_has(const struct flow_set * set,
pthread_rwlock_rdlock(&ai.lock);
- if (ai.flows[fd].port_id < 0) {
+ if (ai.flows[fd].flow_id < 0) {
pthread_rwlock_unlock(&ai.lock);
return false;
}
- ret = (shm_flow_set_has(ai.fqset, set->idx, ai.flows[fd].port_id) == 1);
+ ret = (shm_flow_set_has(ai.fqset, set->idx, ai.flows[fd].flow_id) == 1);
pthread_rwlock_unlock(&ai.lock);
@@ -1177,35 +1204,35 @@ int fevent(struct flow_set * set,
/* ipcp-dev functions. */
int np1_flow_alloc(pid_t n_pid,
- int port_id,
- qoscube_t qc)
+ int flow_id,
+ qosspec_t qs)
{
- return flow_init(port_id, n_pid, qc);
+ return flow_init(flow_id, n_pid, qs);
}
-int np1_flow_dealloc(int port_id)
+int np1_flow_dealloc(int flow_id)
{
int fd;
pthread_rwlock_rdlock(&ai.lock);
- fd = ai.ports[port_id].fd;
+ fd = ai.ports[flow_id].fd;
pthread_rwlock_unlock(&ai.lock);
return fd;
}
-int np1_flow_resp(int port_id)
+int np1_flow_resp(int flow_id)
{
int fd;
- if (port_wait_assign(port_id) != PORT_ID_ASSIGNED)
+ if (port_wait_assign(flow_id) != PORT_ID_ASSIGNED)
return -1;
pthread_rwlock_rdlock(&ai.lock);
- fd = ai.ports[port_id].fd;
+ fd = ai.ports[flow_id].fd;
pthread_rwlock_unlock(&ai.lock);
@@ -1243,29 +1270,29 @@ int ipcp_create_r(pid_t pid,
int ipcp_flow_req_arr(pid_t pid,
const uint8_t * dst,
size_t len,
- qoscube_t qc)
+ qosspec_t qs)
{
- irm_msg_t msg = IRM_MSG__INIT;
- irm_msg_t * recv_msg;
- int fd;
+ irm_msg_t msg = IRM_MSG__INIT;
+ irm_msg_t * recv_msg;
+ qosspec_msg_t qs_msg;
+ int fd;
assert(dst != NULL);
- msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR;
- msg.has_pid = true;
- msg.pid = pid;
- msg.has_hash = true;
- msg.hash.len = len;
- msg.hash.data = (uint8_t *) dst;
- msg.has_qoscube = true;
- msg.qoscube = qc;
+ msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR;
+ msg.has_pid = true;
+ msg.pid = pid;
+ msg.has_hash = true;
+ msg.hash.len = len;
+ msg.hash.data = (uint8_t *) dst;
+ qs_msg = spec_to_msg(&qs);
+ msg.qosspec = &qs_msg;
recv_msg = send_recv_irm_msg(&msg);
-
if (recv_msg == NULL)
return -EIRMD;
- if (!recv_msg->has_port_id || !recv_msg->has_pid) {
+ if (!recv_msg->has_flow_id || !recv_msg->has_pid) {
irm_msg__free_unpacked(recv_msg, NULL);
return -1;
}
@@ -1275,7 +1302,7 @@ int ipcp_flow_req_arr(pid_t pid,
return -1;
}
- fd = flow_init(recv_msg->port_id, recv_msg->pid, qc);
+ fd = flow_init(recv_msg->flow_id, recv_msg->pid, qs);
irm_msg__free_unpacked(recv_msg, NULL);
@@ -1292,11 +1319,11 @@ int ipcp_flow_alloc_reply(int fd,
assert(fd >= 0 && fd < SYS_MAX_FLOWS);
msg.code = IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY;
- msg.has_port_id = true;
+ msg.has_flow_id = true;
pthread_rwlock_rdlock(&ai.lock);
- msg.port_id = ai.flows[fd].port_id;
+ msg.flow_id = ai.flows[fd].flow_id;
pthread_rwlock_unlock(&ai.lock);
@@ -1333,7 +1360,7 @@ int ipcp_flow_read(int fd,
pthread_rwlock_rdlock(&ai.lock);
- assert(flow->port_id >= 0);
+ assert(flow->flow_id >= 0);
rb = flow->rx_rb;
@@ -1352,6 +1379,8 @@ int ipcp_flow_read(int fd,
if (idx < 0)
return idx;
*sdb = shm_rdrbuff_get(ai.rdrb, idx);
+ if (flow->spec.ber == 0 && chk_crc(*sdb) != 0)
+ continue;
} while (frcti_rcv(flow->frcti, *sdb) != 0);
return 0;
@@ -1371,7 +1400,7 @@ int ipcp_flow_write(int fd,
pthread_rwlock_rdlock(&ai.lock);
- assert(flow->port_id >= 0);
+ assert(flow->flow_id >= 0);
if ((flow->oflags & FLOWFACCMODE) == FLOWFRDONLY) {
pthread_rwlock_unlock(&ai.lock);
@@ -1387,9 +1416,15 @@ int ipcp_flow_write(int fd,
return -ENOMEM;
}
+ if (flow->spec.ber == 0 && add_crc(sdb) != 0) {
+ pthread_rwlock_unlock(&ai.lock);
+ shm_rdrbuff_remove(ai.rdrb, idx);
+ return -ENOMEM;
+ }
+
ret = shm_rbuff_write(flow->tx_rb, idx);
if (ret == 0)
- shm_flow_set_notify(flow->set, flow->port_id, FLOW_PKT);
+ shm_flow_set_notify(flow->set, flow->flow_id, FLOW_PKT);
pthread_rwlock_unlock(&ai.lock);
@@ -1435,7 +1470,7 @@ void ipcp_flow_fini(int fd)
shm_rbuff_set_acl(ai.flows[fd].tx_rb, ACL_FLOWDOWN);
shm_flow_set_notify(ai.flows[fd].set,
- ai.flows[fd].port_id,
+ ai.flows[fd].flow_id,
FLOW_DEALLOC);
rx_rb = ai.flows[fd].rx_rb;
@@ -1455,9 +1490,9 @@ int ipcp_flow_get_qoscube(int fd,
pthread_rwlock_rdlock(&ai.lock);
- assert(ai.flows[fd].port_id >= 0);
+ assert(ai.flows[fd].flow_id >= 0);
- *cube = ai.flows[fd].cube;
+ *cube = qos_spec_to_cube(ai.flows[fd].spec);
pthread_rwlock_unlock(&ai.lock);
@@ -1491,14 +1526,14 @@ int local_flow_write(int fd,
pthread_rwlock_rdlock(&ai.lock);
- if (flow->port_id < 0) {
+ if (flow->flow_id < 0) {
pthread_rwlock_unlock(&ai.lock);
return -ENOTALLOC;
}
ret = shm_rbuff_write(flow->tx_rb, idx);
if (ret == 0)
- shm_flow_set_notify(flow->set, flow->port_id, FLOW_PKT);
+ shm_flow_set_notify(flow->set, flow->flow_id, FLOW_PKT);
pthread_rwlock_unlock(&ai.lock);
diff --git a/src/lib/frct.c b/src/lib/frct.c
index 0f3173c5..db3572e3 100644
--- a/src/lib/frct.c
+++ b/src/lib/frct.c
@@ -31,16 +31,13 @@
#define TW_RESOLUTION 1 /* ms */
#define FRCT_PCILEN (sizeof(struct frct_pci))
-#define FRCT_CRCLEN (sizeof(uint32_t))
struct frct_cr {
- bool drf;
uint32_t lwe;
uint32_t rwe;
- uint32_t seqno;
- bool conf;
uint8_t cflags;
+ uint32_t seqno;
time_t rto; /* ms */
time_t act; /* s */
@@ -67,15 +64,12 @@ enum frct_flags {
FRCT_ACK = 0x03, /* ACK field valid */
FRCT_FC = 0x08, /* FC window valid */
FRCT_RDVZ = 0x10, /* Rendez-vous */
- FRCT_CFG = 0x20, /* Configuration */
- FRCT_MFGM = 0x40, /* More fragments */
- FRCT_CRC = 0x80, /* CRC present */
+ FRCT_MFGM = 0x20, /* More fragments */
+ FRCT_CRC = 0x40, /* CRC present */
};
struct frct_pci {
- uint8_t flags;
-
- uint8_t cflags;
+ uint16_t flags;
uint16_t window;
@@ -85,8 +79,7 @@ struct frct_pci {
#include <rxmwheel.c>
-static struct frcti * frcti_create(int fd,
- qoscube_t qc)
+static struct frcti * frcti_create(int fd)
{
struct frcti * frcti;
time_t delta_t;
@@ -114,16 +107,15 @@ static struct frcti * frcti_create(int fd,
delta_t = (frcti->mpl + frcti->a + frcti->r) / 1000;
- if (qc == QOS_CUBE_DATA)
- frcti->snd_cr.cflags |= FRCTFRTX;
-
- frcti->snd_cr.conf = true;
- frcti->snd_cr.inact = 3 * delta_t + 1;
+ frcti->snd_cr.inact = 3 * delta_t;
frcti->snd_cr.act = now.tv_sec - (frcti->snd_cr.inact + 1);
/* Initial rto. FIXME: recalc using Karn algorithm. */
frcti->snd_cr.rto = 120;
- frcti->rcv_cr.inact = 2 * delta_t + 1;
+ if (ai.flows[fd].spec.loss == 0)
+ frcti->snd_cr.cflags |= FRCTFRTX;
+
+ frcti->rcv_cr.inact = 2 * delta_t;
frcti->rcv_cr.act = now.tv_sec - (frcti->rcv_cr.inact + 1);
return frcti;
@@ -138,7 +130,7 @@ static void frcti_destroy(struct frcti * frcti)
{
/*
* FIXME: In case of reliable transmission we should
- * make sure everything is acked.
+ * make sure everything we sent is acked.
*/
rxmwheel_clear(frcti->fd);
@@ -148,24 +140,6 @@ static void frcti_destroy(struct frcti * frcti)
free(frcti);
}
-static int frcti_setconf(struct frcti * frcti,
- uint16_t flags)
-{
- assert(frcti);
-
- pthread_rwlock_wrlock(&frcti->lock);
-
- if (frcti->snd_cr.cflags != flags) {
- frcti->snd_cr.cflags = flags;
- frcti->snd_cr.conf = true;
- frcti->snd_cr.drf = true;
- }
-
- pthread_rwlock_unlock(&frcti->lock);
-
- return 0;
-}
-
static uint16_t frcti_getconf(struct frcti * frcti)
{
uint16_t ret;
@@ -203,14 +177,6 @@ static ssize_t __frcti_queued_pdu(struct frcti * frcti)
pos = frcti->rcv_cr.lwe & (RQ_SIZE - 1);
idx = frcti->rq[pos];
if (idx != -1) {
- struct shm_du_buff * sdb;
- struct frct_pci * pci;
-
- sdb = shm_rdrbuff_get(ai.rdrb, idx);
- pci = (struct frct_pci *) shm_du_buff_head(sdb) - 1;
- if (pci->flags & FRCT_CFG)
- frcti->rcv_cr.cflags = pci->cflags;
-
++frcti->rcv_cr.lwe;
frcti->rq[pos] = -1;
}
@@ -220,22 +186,6 @@ static ssize_t __frcti_queued_pdu(struct frcti * frcti)
return idx;
}
-static int frct_chk_crc(uint8_t * head,
- uint8_t * tail)
-{
- uint32_t crc;
-
- mem_hash(HASH_CRC32, &crc, head, tail - head);
-
- return crc == *((uint32_t *) tail);
-}
-
-static void frct_add_crc(uint8_t * head,
- uint8_t * tail)
-{
- mem_hash(HASH_CRC32, tail, head, tail - head);
-}
-
static struct frct_pci * frcti_alloc_head(struct shm_du_buff * sdb)
{
struct frct_pci * pci;
@@ -272,38 +222,20 @@ static int __frcti_snd(struct frcti * frcti,
pci->flags |= FRCT_DATA;
- if (snd_cr->cflags & FRCTFERRCHCK) {
- uint8_t * tail = shm_du_buff_tail_alloc(sdb, FRCT_CRCLEN);
- if (tail == NULL) {
- pthread_rwlock_unlock(&frcti->lock);
- return -1;
- }
-
- frct_add_crc((uint8_t *) pci, tail);
-
- pci->flags |= FRCT_CRC;
- }
-
/* Set DRF if there are no unacknowledged packets. */
if (snd_cr->seqno == snd_cr->lwe)
pci->flags |= FRCT_DRF;
- if (snd_cr->conf) {
- /* FIXME: This packet must be acked! */
- pci->flags |= FRCT_CFG;
- pci->cflags = snd_cr->cflags;
- }
-
/* Choose a new sequence number if sender inactivity expired. */
if (now.tv_sec - snd_cr->act > snd_cr->inact) {
/* There are no unacknowledged packets. */
assert(snd_cr->seqno == snd_cr->lwe);
#ifdef CONFIG_OUROBOROS_DEBUG
- frcti->snd_cr.seqno = 0;
+ snd_cr->seqno = 0;
#else
random_buffer(&snd_cr->seqno, sizeof(snd_cr->seqno));
#endif
- frcti->snd_cr.lwe = frcti->snd_cr.seqno;
+ frcti->snd_cr.lwe = snd_cr->seqno;
}
pci->seqno = hton32(snd_cr->seqno);
@@ -317,14 +249,13 @@ static int __frcti_snd(struct frcti * frcti,
snd_cr->seqno++;
snd_cr->act = now.tv_sec;
- snd_cr->conf = false;
pthread_rwlock_unlock(&frcti->lock);
return 0;
}
-/* Returns 0 when idx contains an SDU for the application. */
+/* Returns 0 when idx contains a packet for the application. */
static int __frcti_rcv(struct frcti * frcti,
struct shm_du_buff * sdb)
{
@@ -349,43 +280,33 @@ static int __frcti_rcv(struct frcti * frcti,
idx = shm_du_buff_get_idx(sdb);
- /* PDU may be corrupted. */
- if (pci->flags & FRCT_CRC) {
- uint8_t * tail = shm_du_buff_tail_release(sdb, FRCT_CRCLEN);
- if (frct_chk_crc((uint8_t *) pci, tail))
- goto drop_packet;
- }
-
seqno = ntoh32(pci->seqno);
/* Check if receiver inactivity is true. */
if (now.tv_sec - rcv_cr->act > rcv_cr->inact) {
/* Inactive receiver, check for DRF. */
if (pci->flags & FRCT_DRF) /* New run. */
- rcv_cr->lwe = seqno - 1;
+ rcv_cr->seqno = seqno;
else
goto drop_packet;
}
- if (seqno == rcv_cr->lwe + 1) {
- rcv_cr->lwe = seqno;
- /* Check for online reconfiguration. */
- if (pci->flags & FRCT_CFG)
- rcv_cr->cflags = pci->cflags;
+ if (seqno == rcv_cr->seqno) {
+ ++rcv_cr->seqno;
} else { /* Out of order. */
- if ((int32_t)(seqno - rcv_cr->lwe) <= 0) /* Duplicate. */
+ if ((int32_t)(seqno - rcv_cr->seqno) < 0) /* Duplicate. */
goto drop_packet;
if (rcv_cr->cflags & FRCTFRTX) {
size_t pos = seqno & (RQ_SIZE - 1);
- if ((seqno - rcv_cr->lwe) > RQ_SIZE /* Out of rq. */
+ if ((seqno - rcv_cr->seqno) > RQ_SIZE /* Out of rq. */
|| frcti->rq[pos] != -1) /* Duplicate in rq. */
goto drop_packet;
/* Queue. */
frcti->rq[pos] = idx;
ret = -EAGAIN;
} else {
- rcv_cr->lwe = seqno;
+ rcv_cr->seqno = seqno;
}
}
@@ -398,18 +319,18 @@ static int __frcti_rcv(struct frcti * frcti,
rcv_cr->act = now.tv_sec;
+ pthread_rwlock_unlock(&frcti->lock);
+
if (!(pci->flags & FRCT_DATA))
shm_rdrbuff_remove(ai.rdrb, idx);
- pthread_rwlock_unlock(&frcti->lock);
-
rxmwheel_move();
return ret;
drop_packet:
- shm_rdrbuff_remove(ai.rdrb, idx);
pthread_rwlock_unlock(&frcti->lock);
+ shm_rdrbuff_remove(ai.rdrb, idx);
rxmwheel_move();
return -EAGAIN;
}
diff --git a/src/lib/hash.c b/src/lib/hash.c
index 9b74967b..10e10c13 100644
--- a/src/lib/hash.c
+++ b/src/lib/hash.c
@@ -23,6 +23,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#if defined(__linux__) || defined(__CYGWIN__)
+#define _DEFAULT_SOURCE
+#endif
+
#include "config.h"
#include <ouroboros/hash.h>
diff --git a/src/lib/hashtable.c b/src/lib/hashtable.c
index be5c3ffd..68a0f545 100644
--- a/src/lib/hashtable.c
+++ b/src/lib/hashtable.c
@@ -20,6 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#if defined(__linux__) || defined(__CYGWIN__)
+#define _DEFAULT_SOURCE
+#endif
+
#include <ouroboros/hashtable.h>
#include <ouroboros/list.h>
#include <ouroboros/errno.h>
diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto
index 454af0dc..ae1014ac 100644
--- a/src/lib/ipcpd_messages.proto
+++ b/src/lib/ipcpd_messages.proto
@@ -23,6 +23,7 @@
syntax = "proto2";
import "ipcp_config.proto";
+import "qosspec.proto";
enum ipcp_msg_code {
IPCP_BOOTSTRAP = 1;
@@ -41,9 +42,9 @@ enum ipcp_msg_code {
message ipcp_msg {
required ipcp_msg_code code = 1;
optional bytes hash = 2;
- optional int32 port_id = 3;
+ optional int32 flow_id = 3;
optional string dst = 4;
- optional uint32 qoscube = 5;
+ optional qosspec_msg qosspec = 5;
optional ipcp_config_msg conf = 6;
optional int32 pid = 7;
optional layer_info_msg layer_info = 8;
diff --git a/src/lib/irm.c b/src/lib/irm.c
index 6a9f837e..d88475c4 100644
--- a/src/lib/irm.c
+++ b/src/lib/irm.c
@@ -20,7 +20,11 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#if defined(__linux__) || defined(__CYGWIN__)
+#define _DEFAULT_SOURCE
+#else
#define _POSIX_C_SOURCE 200809L
+#endif
#include <ouroboros/errno.h>
#include <ouroboros/hash.h>
@@ -315,10 +319,10 @@ static int check_prog(const char * prog)
static int check_prog_path(char ** prog)
{
- char * path = getenv("PATH");
- char * path_end = path + strlen(path) + 1;
+ char * path;
+ char * path_end;
char * pstart;
- char * pstop = path;
+ char * pstop;
char * tmp;
char * tstop;
char * tstart;
@@ -327,9 +331,15 @@ static int check_prog_path(char ** prog)
assert(prog);
- if (*prog == NULL || path == NULL)
+ if (*prog == NULL)
return -EINVAL;
+ path = getenv("PATH");
+ if (path == NULL)
+ return -ENOENT;
+
+ pstop = path;
+ path_end = path + strlen(path) + 1;
if (!strlen(path) || strchr(*prog, '/') != NULL) {
if ((ret = check_prog(*prog)) < 0)
return ret;
diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto
index 16dfe828..351b4a8e 100644
--- a/src/lib/irmd_messages.proto
+++ b/src/lib/irmd_messages.proto
@@ -23,6 +23,7 @@
syntax = "proto2";
import "ipcp_config.proto";
+import "qosspec.proto";
enum irm_msg_code {
IRM_CREATE_IPCP = 1;
@@ -66,8 +67,8 @@ message irm_msg {
optional sint32 response = 8;
optional string dst = 9;
optional bytes hash = 10;
- optional sint32 port_id = 11;
- optional sint32 qoscube = 12;
+ optional sint32 flow_id = 11;
+ optional qosspec_msg qosspec = 12;
optional ipcp_config_msg conf = 13;
optional uint32 opts = 14;
repeated ipcp_info_msg ipcps = 15;
diff --git a/src/lib/md5.c b/src/lib/md5.c
index 6f2b2e36..959865fe 100644
--- a/src/lib/md5.c
+++ b/src/lib/md5.c
@@ -40,6 +40,10 @@
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
*/
+#if defined(__linux__) || defined(__CYGWIN__)
+#define _DEFAULT_SOURCE
+#endif
+
#include <ouroboros/endian.h>
#include <ouroboros/md5.h>
diff --git a/src/lib/qos.c b/src/lib/qos.c
index bee6ed71..8607031e 100644
--- a/src/lib/qos.c
+++ b/src/lib/qos.c
@@ -28,66 +28,61 @@
#include <string.h>
qosspec_t qos_raw = {
- .delay = UINT32_MAX,
- .bandwidth = 0,
- .availability = 0,
- .loss = 1,
- .in_order = 0,
- .maximum_interruption = UINT32_MAX
+ .delay = UINT32_MAX,
+ .bandwidth = 0,
+ .availability = 0,
+ .loss = 1,
+ .ber = 1,
+ .in_order = 0,
+ .max_gap = UINT32_MAX
+};
+
+qosspec_t qos_raw_no_errors = {
+ .delay = UINT32_MAX,
+ .bandwidth = 0,
+ .availability = 0,
+ .loss = 1,
+ .ber = 0,
+ .in_order = 0,
+ .max_gap = UINT32_MAX
};
qosspec_t qos_best_effort = {
- .delay = UINT32_MAX,
- .bandwidth = 0,
- .availability = 0,
- .loss = 1,
- .in_order = 1,
- .maximum_interruption = UINT32_MAX
+ .delay = UINT32_MAX,
+ .bandwidth = 0,
+ .availability = 0,
+ .loss = 1,
+ .ber = 0,
+ .in_order = 1,
+ .max_gap = UINT32_MAX
};
-qosspec_t qos_video = {
- .delay = 100,
- .bandwidth = UINT64_MAX,
- .availability = 3,
- .loss = 1,
- .in_order = 1,
- .maximum_interruption = 100
+qosspec_t qos_video = {
+ .delay = 100,
+ .bandwidth = UINT64_MAX,
+ .availability = 3,
+ .loss = 1,
+ .ber = 0,
+ .in_order = 1,
+ .max_gap = 100
};
qosspec_t qos_voice = {
- .delay = 50,
- .bandwidth = 100000,
- .availability = 5,
- .loss = 1,
- .in_order = 1,
- .maximum_interruption = 50
+ .delay = 50,
+ .bandwidth = 100000,
+ .availability = 5,
+ .loss = 1,
+ .ber = 0,
+ .in_order = 1,
+ .max_gap = 50
};
qosspec_t qos_data = {
- .delay = 1000,
- .bandwidth = 0,
- .availability = 0,
- .in_order = 1,
- .loss = 0,
- .maximum_interruption = 2000
+ .delay = 1000,
+ .bandwidth = 0,
+ .availability = 0,
+ .loss = 0,
+ .ber = 0,
+ .in_order = 1,
+ .max_gap = 2000
};
-
-int qosspec_init(qosspec_t * qs)
-{
- if (qs == NULL)
- return -EINVAL;
-
- *qs = qos_best_effort;
-
- return 0;
-}
-
-int qosspec_fini(qosspec_t * qs)
-{
- if (qs == NULL)
- return -EINVAL;
-
- memset(qs, 0, sizeof(*qs));
-
- return 0;
-}
diff --git a/src/lib/qoscube.c b/src/lib/qoscube.c
index 5dfa35ad..efca0e42 100644
--- a/src/lib/qoscube.c
+++ b/src/lib/qoscube.c
@@ -25,38 +25,20 @@
#include <string.h>
+
+
qoscube_t qos_spec_to_cube(qosspec_t qs)
{
- if (qs.loss == 0)
- return QOS_CUBE_DATA;
- else if (qs.delay <= qos_voice.delay &&
+ if (qs.delay <= qos_voice.delay &&
qs.bandwidth <= qos_voice.bandwidth &&
qs.availability >= qos_voice.availability &&
- qs.maximum_interruption <= qos_voice.maximum_interruption)
+ qs.max_gap <= qos_voice.max_gap)
return QOS_CUBE_VOICE;
else if (qs.delay <= qos_video.delay &&
qs.bandwidth <= qos_video.bandwidth &&
qs.availability >= qos_video.availability &&
- qs.maximum_interruption <= qos_video.maximum_interruption)
+ qs.max_gap <= qos_video.max_gap)
return QOS_CUBE_VIDEO;
- else if (qs.in_order == 1)
- return QOS_CUBE_BE;
else
- return QOS_CUBE_RAW;
-}
-
-qosspec_t qos_cube_to_spec(qoscube_t qc)
-{
- switch (qc) {
- case QOS_CUBE_VOICE:
- return qos_voice;
- case QOS_CUBE_VIDEO:
- return qos_video;
- case QOS_CUBE_BE:
- return qos_best_effort;
- case QOS_CUBE_DATA:
- return qos_data;
- default:
- return qos_raw;
- }
+ return QOS_CUBE_BE;
}
diff --git a/src/lib/qosspec.proto b/src/lib/qosspec.proto
new file mode 100644
index 00000000..f355e345
--- /dev/null
+++ b/src/lib/qosspec.proto
@@ -0,0 +1,33 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2018
+ *
+ * QoS specification message
+ *
+ * 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/.
+ */
+
+syntax = "proto2";
+
+message qosspec_msg {
+ required uint32 delay = 1; /* In ms */
+ required uint64 bandwidth = 2; /* In bits/s */
+ required uint32 availability = 3; /* Class of 9s */
+ required uint32 loss = 4; /* Packet loss */
+ required uint32 ber = 5; /* Bit error rate, ppb */
+ required uint32 in_order = 6; /* In-order delivery */
+ required uint32 max_gap = 7; /* In ms */
+};
diff --git a/src/lib/rib.c b/src/lib/rib.c
index 685575e5..88db9ed8 100644
--- a/src/lib/rib.c
+++ b/src/lib/rib.c
@@ -101,6 +101,9 @@ static int rib_read(const char * path,
char comp[RIB_PATH_LEN + 1];
char * c;
+ if (strlen(path) > RIB_PATH_LEN)
+ return -1;
+
strcpy(comp, path + 1);
c = strstr(comp, "/");
@@ -183,6 +186,9 @@ static size_t __getattr(const char * path,
char comp[RIB_PATH_LEN + 1];
char * c;
+ if (strlen(path) > RIB_PATH_LEN)
+ return -1;
+
strcpy(comp, path + 1);
c = strstr(comp, "/");
@@ -282,7 +288,8 @@ int rib_init(const char * mountpt)
if (stat(rib.mnt, &st) == -1)
switch(errno) {
case ENOENT:
- mkdir(rib.mnt, 0777);
+ if (mkdir(rib.mnt, 0777))
+ return -1;
break;
case ENOTCONN:
fuse_unmount(rib.mnt, rib.ch);
@@ -385,6 +392,12 @@ int rib_reg(const char * path,
return -ENOMEM;
}
+ if (strlen(path) > RIB_PATH_LEN) {
+ pthread_rwlock_unlock(&rib.lock);
+ free(rc);
+ return -1;
+ }
+
strcpy(rc->path, path);
rc->ops = ops;
diff --git a/src/lib/rxmwheel.c b/src/lib/rxmwheel.c
index e5891081..697c6a48 100644
--- a/src/lib/rxmwheel.c
+++ b/src/lib/rxmwheel.c
@@ -192,7 +192,7 @@ static int rxmwheel_move(void)
continue;
}
- shm_flow_set_notify(f->set, f->port_id, FLOW_PKT);
+ shm_flow_set_notify(f->set, f->flow_id, FLOW_PKT);
/* Reschedule. */
shm_du_buff_wait_ack(sdb);
diff --git a/src/lib/sha3.c b/src/lib/sha3.c
index 6179af22..f6a82c57 100644
--- a/src/lib/sha3.c
+++ b/src/lib/sha3.c
@@ -42,6 +42,10 @@
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
*/
+#if defined(__linux__) || defined(__CYGWIN__)
+#define _DEFAULT_SOURCE
+#endif
+
#include <ouroboros/endian.h>
#include <ouroboros/sha3.h>
diff --git a/src/lib/shm_flow_set.c b/src/lib/shm_flow_set.c
index bb9e3caa..1c94c599 100644
--- a/src/lib/shm_flow_set.c
+++ b/src/lib/shm_flow_set.c
@@ -64,7 +64,7 @@
#define fqueue_ptr(fs, idx) (fs->fqueues + (SHM_BUFFER_SIZE) * idx)
struct portevent {
- int port_id;
+ int flow_id;
int event;
};
@@ -98,17 +98,14 @@ struct shm_flow_set * shm_flow_set_create()
mask = umask(0);
shm_fd = shm_open(fn, O_CREAT | O_RDWR, 0666);
- if (shm_fd == -1) {
- free(set);
- return NULL;
- }
+ if (shm_fd == -1)
+ goto fail_shm_open;
umask(mask);
if (ftruncate(shm_fd, SHM_FLOW_SET_FILE_SIZE - 1) < 0) {
- free(set);
close(shm_fd);
- return NULL;
+ goto fail_shm_open;
}
shm_base = mmap(NULL,
@@ -120,11 +117,8 @@ struct shm_flow_set * shm_flow_set_create()
close(shm_fd);
- if (shm_base == MAP_FAILED) {
- shm_unlink(fn);
- free(set);
- return NULL;
- }
+ if (shm_base == MAP_FAILED)
+ goto fail_mmap;
set->mtable = shm_base;
set->heads = (size_t *) (set->mtable + SYS_MAX_FLOWS);
@@ -133,21 +127,27 @@ struct shm_flow_set * shm_flow_set_create()
set->lock = (pthread_mutex_t *)
(set->fqueues + PROG_MAX_FQUEUES * (SHM_BUFFER_SIZE));
- pthread_mutexattr_init(&mattr);
+ if (pthread_mutexattr_init(&mattr))
+ goto fail_mmap;
+
#ifdef HAVE_ROBUST_MUTEX
- pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST);
+ if (pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST))
+ goto fail_mmap;
#endif
- pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
- pthread_mutex_init(set->lock, &mattr);
+ if (pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED) ||
+ pthread_mutex_init(set->lock, &mattr) ||
+ pthread_condattr_init(&cattr) ||
+ pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED))
+ goto fail_mmap;
- pthread_condattr_init(&cattr);
- pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
#ifndef __APPLE__
- pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
+ if (pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK))
+ goto fail_mmap;
#endif
for (i = 0; i < PROG_MAX_FQUEUES; ++i) {
set->heads[i] = 0;
- pthread_cond_init(&set->conds[i], &cattr);
+ if (pthread_cond_init(&set->conds[i], &cattr))
+ goto fail_mmap;
}
for (i = 0; i < SYS_MAX_FLOWS; ++i)
@@ -156,6 +156,12 @@ struct shm_flow_set * shm_flow_set_create()
set->pid = getpid();
return set;
+
+ fail_mmap:
+ shm_unlink(fn);
+ fail_shm_open:
+ free(set);
+ return NULL;
}
struct shm_flow_set * shm_flow_set_open(pid_t pid)
@@ -262,20 +268,20 @@ void shm_flow_set_zero(struct shm_flow_set * set,
int shm_flow_set_add(struct shm_flow_set * set,
size_t idx,
- int port_id)
+ int flow_id)
{
assert(set);
- assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);
+ assert(!(flow_id < 0) && flow_id < SYS_MAX_FLOWS);
assert(idx < PROG_MAX_FQUEUES);
pthread_mutex_lock(set->lock);
- if (set->mtable[port_id] != -1) {
+ if (set->mtable[flow_id] != -1) {
pthread_mutex_unlock(set->lock);
return -EPERM;
}
- set->mtable[port_id] = idx;
+ set->mtable[flow_id] = idx;
pthread_mutex_unlock(set->lock);
@@ -284,33 +290,33 @@ int shm_flow_set_add(struct shm_flow_set * set,
void shm_flow_set_del(struct shm_flow_set * set,
size_t idx,
- int port_id)
+ int flow_id)
{
assert(set);
- assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);
+ assert(!(flow_id < 0) && flow_id < SYS_MAX_FLOWS);
assert(idx < PROG_MAX_FQUEUES);
pthread_mutex_lock(set->lock);
- if (set->mtable[port_id] == (ssize_t) idx)
- set->mtable[port_id] = -1;
+ if (set->mtable[flow_id] == (ssize_t) idx)
+ set->mtable[flow_id] = -1;
pthread_mutex_unlock(set->lock);
}
int shm_flow_set_has(struct shm_flow_set * set,
size_t idx,
- int port_id)
+ int flow_id)
{
int ret = 0;
assert(set);
- assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);
+ assert(!(flow_id < 0) && flow_id < SYS_MAX_FLOWS);
assert(idx < PROG_MAX_FQUEUES);
pthread_mutex_lock(set->lock);
- if (set->mtable[port_id] == (ssize_t) idx)
+ if (set->mtable[flow_id] == (ssize_t) idx)
ret = 1;
pthread_mutex_unlock(set->lock);
@@ -319,25 +325,25 @@ int shm_flow_set_has(struct shm_flow_set * set,
}
void shm_flow_set_notify(struct shm_flow_set * set,
- int port_id,
+ int flow_id,
int event)
{
assert(set);
- assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);
+ assert(!(flow_id < 0) && flow_id < SYS_MAX_FLOWS);
pthread_mutex_lock(set->lock);
- if (set->mtable[port_id] == -1) {
+ if (set->mtable[flow_id] == -1) {
pthread_mutex_unlock(set->lock);
return;
}
- (fqueue_ptr(set, set->mtable[port_id]) +
- (set->heads[set->mtable[port_id]]))->port_id = port_id;
- (fqueue_ptr(set, set->mtable[port_id]) +
- (set->heads[set->mtable[port_id]])++)->event = event;
+ (fqueue_ptr(set, set->mtable[flow_id]) +
+ (set->heads[set->mtable[flow_id]]))->flow_id = flow_id;
+ (fqueue_ptr(set, set->mtable[flow_id]) +
+ (set->heads[set->mtable[flow_id]])++)->event = event;
- pthread_cond_signal(&set->conds[set->mtable[port_id]]);
+ pthread_cond_signal(&set->conds[set->mtable[flow_id]]);
pthread_mutex_unlock(set->lock);
}
diff --git a/src/lib/shm_rbuff.c b/src/lib/shm_rbuff.c
index 453f5183..a6eab699 100644
--- a/src/lib/shm_rbuff.c
+++ b/src/lib/shm_rbuff.c
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2018
*
- * Ring buffer implementations for incoming SDUs
+ * Ring buffer implementations for incoming packets
*
* Dimitri Staessens <dimitri.staessens@ugent.be>
* Sander Vrijders <sander.vrijders@ugent.be>
@@ -63,10 +63,10 @@ struct shm_rbuff {
size_t * tail; /* start of ringbuffer tail */
size_t * acl; /* access control */
pthread_mutex_t * lock; /* lock all free space in shm */
- pthread_cond_t * add; /* SDU arrived */
- pthread_cond_t * del; /* SDU removed */
+ pthread_cond_t * add; /* packet arrived */
+ pthread_cond_t * del; /* packet removed */
pid_t pid; /* pid of the owner */
- int port_id; /* port_id of the flow */
+ int flow_id; /* flow_id of the flow */
};
void shm_rbuff_close(struct shm_rbuff * rb)
@@ -81,7 +81,7 @@ void shm_rbuff_close(struct shm_rbuff * rb)
#define MM_FLAGS (PROT_READ | PROT_WRITE)
struct shm_rbuff * rbuff_create(pid_t pid,
- int port_id,
+ int flow_id,
int flags)
{
struct shm_rbuff * rb;
@@ -89,7 +89,7 @@ struct shm_rbuff * rbuff_create(pid_t pid,
ssize_t * shm_base;
char fn[FN_MAX_CHARS];
- sprintf(fn, SHM_RBUFF_PREFIX "%d.%d", pid, port_id);
+ sprintf(fn, SHM_RBUFF_PREFIX "%d.%d", pid, flow_id);
rb = malloc(sizeof(*rb));
if (rb == NULL)
@@ -116,7 +116,7 @@ struct shm_rbuff * rbuff_create(pid_t pid,
rb->add = (pthread_cond_t *) (rb->lock + 1);
rb->del = rb->add + 1;
rb->pid = pid;
- rb->port_id = port_id;
+ rb->flow_id = flow_id;
return rb;
@@ -131,7 +131,7 @@ struct shm_rbuff * rbuff_create(pid_t pid,
}
struct shm_rbuff * shm_rbuff_create(pid_t pid,
- int port_id)
+ int flow_id)
{
struct shm_rbuff * rb;
pthread_mutexattr_t mattr;
@@ -140,7 +140,7 @@ struct shm_rbuff * shm_rbuff_create(pid_t pid,
mask = umask(0);
- rb = rbuff_create(pid, port_id, O_CREAT | O_EXCL | O_RDWR);
+ rb = rbuff_create(pid, flow_id, O_CREAT | O_EXCL | O_RDWR);
umask(mask);
@@ -175,7 +175,7 @@ struct shm_rbuff * shm_rbuff_create(pid_t pid,
*rb->tail = 0;
rb->pid = pid;
- rb->port_id = port_id;
+ rb->flow_id = flow_id;
pthread_mutexattr_destroy(&mattr);
pthread_condattr_destroy(&cattr);
@@ -197,9 +197,9 @@ struct shm_rbuff * shm_rbuff_create(pid_t pid,
}
struct shm_rbuff * shm_rbuff_open(pid_t pid,
- int port_id)
+ int flow_id)
{
- return rbuff_create(pid, port_id, O_RDWR);
+ return rbuff_create(pid, flow_id, O_RDWR);
}
#if (defined(SHM_RBUFF_LOCKLESS) && \
diff --git a/src/lib/shm_rbuff_ll.c b/src/lib/shm_rbuff_ll.c
index c488f274..0fc9ae7b 100644
--- a/src/lib/shm_rbuff_ll.c
+++ b/src/lib/shm_rbuff_ll.c
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2018
*
- * Lockless ring buffer for incoming SDUs
+ * Lockless ring buffer for incoming packets
*
* Dimitri Staessens <dimitri.staessens@ugent.be>
* Sander Vrijders <sander.vrijders@ugent.be>
@@ -29,7 +29,7 @@ void shm_rbuff_destroy(struct shm_rbuff * rb)
assert(rb);
- sprintf(fn, SHM_RBUFF_PREFIX "%d.%d", rb->pid, rb->port_id);
+ sprintf(fn, SHM_RBUFF_PREFIX "%d.%d", rb->pid, rb->flow_id);
shm_rbuff_close(rb);
diff --git a/src/lib/shm_rbuff_pthr.c b/src/lib/shm_rbuff_pthr.c
index 3b7ea2d4..51d801f6 100644
--- a/src/lib/shm_rbuff_pthr.c
+++ b/src/lib/shm_rbuff_pthr.c
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2018
*
- * Ring buffer for incoming SDUs
+ * Ring buffer for incoming packets
*
* Dimitri Staessens <dimitri.staessens@ugent.be>
* Sander Vrijders <sander.vrijders@ugent.be>
@@ -33,7 +33,7 @@ void shm_rbuff_destroy(struct shm_rbuff * rb)
pthread_mutex_unlock(rb->lock);
#endif
- sprintf(fn, SHM_RBUFF_PREFIX "%d.%d", rb->pid, rb->port_id);
+ sprintf(fn, SHM_RBUFF_PREFIX "%d.%d", rb->pid, rb->flow_id);
shm_rbuff_close(rb);
diff --git a/src/lib/shm_rdrbuff.c b/src/lib/shm_rdrbuff.c
index 182ad084..31d9f2b6 100644
--- a/src/lib/shm_rdrbuff.c
+++ b/src/lib/shm_rdrbuff.c
@@ -82,7 +82,7 @@ struct shm_rdrbuff {
size_t * tail; /* start of ringbuffer tail */
pthread_mutex_t * lock; /* lock all free space in shm */
pthread_cond_t * full; /* flag when full */
- pthread_cond_t * healthy; /* flag when SDU is read */
+ pthread_cond_t * healthy; /* flag when packet is read */
pid_t * pid; /* pid of the irmd owner */
};
diff --git a/src/lib/sockets.c b/src/lib/sockets.c
index b148b7ca..85726783 100644
--- a/src/lib/sockets.c
+++ b/src/lib/sockets.c
@@ -165,3 +165,38 @@ char * ipcp_sock_path(pid_t pid)
return full_name;
}
+
+qosspec_msg_t spec_to_msg(qosspec_t * qs)
+{
+ qosspec_t spec;
+ qosspec_msg_t msg = QOSSPEC_MSG__INIT;
+
+ spec = (qs == NULL ? qos_raw : *qs);
+
+ msg.delay = spec.delay;
+ msg.bandwidth = spec.bandwidth;
+ msg.availability = spec.availability;
+ msg.loss = spec.loss;
+ msg.ber = spec.ber;
+ msg.in_order = spec.in_order;
+ msg.max_gap = spec.max_gap;
+
+ return msg;
+}
+
+qosspec_t msg_to_spec(qosspec_msg_t * msg)
+{
+ qosspec_t spec;
+
+ assert(msg);
+
+ spec.delay = msg->delay;
+ spec.bandwidth = msg->bandwidth;
+ spec.availability = msg->availability;
+ spec.loss = msg->loss;
+ spec.ber = msg->ber;
+ spec.in_order = msg->in_order;
+ spec.max_gap = msg->max_gap;
+
+ return spec;
+}