summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/CMakeLists.txt4
-rw-r--r--src/tools/irm/CMakeLists.txt8
-rw-r--r--src/tools/irm/irm.c12
-rw-r--r--src/tools/irm/irm_bind.c8
-rw-r--r--src/tools/irm/irm_bind_ipcp.c16
-rw-r--r--src/tools/irm/irm_bind_process.c6
-rw-r--r--src/tools/irm/irm_bind_program.c6
-rw-r--r--src/tools/irm/irm_ipcp.c15
-rw-r--r--src/tools/irm/irm_ipcp_bootstrap.c182
-rw-r--r--src/tools/irm/irm_ipcp_connect.c76
-rw-r--r--src/tools/irm/irm_ipcp_create.c41
-rw-r--r--src/tools/irm/irm_ipcp_destroy.c15
-rw-r--r--src/tools/irm/irm_ipcp_disconnect.c52
-rw-r--r--src/tools/irm/irm_ipcp_enroll.c123
-rw-r--r--src/tools/irm/irm_ipcp_list.c52
-rw-r--r--src/tools/irm/irm_name.c99
-rw-r--r--src/tools/irm/irm_name_create.c96
-rw-r--r--src/tools/irm/irm_name_destroy.c72
-rw-r--r--src/tools/irm/irm_name_list.c115
-rw-r--r--src/tools/irm/irm_name_reg.c (renamed from src/tools/irm/irm_register.c)84
-rw-r--r--src/tools/irm/irm_name_unreg.c (renamed from src/tools/irm/irm_unregister.c)44
-rw-r--r--src/tools/irm/irm_ops.h22
-rw-r--r--src/tools/irm/irm_unbind.c8
-rw-r--r--src/tools/irm/irm_unbind_ipcp.c16
-rw-r--r--src/tools/irm/irm_unbind_process.c6
-rw-r--r--src/tools/irm/irm_unbind_program.c6
-rw-r--r--src/tools/irm/irm_utils.c8
-rw-r--r--src/tools/irm/irm_utils.h6
-rw-r--r--src/tools/obc/CMakeLists.txt16
-rw-r--r--src/tools/obc/obc.c155
-rw-r--r--src/tools/ocbr/CMakeLists.txt5
-rw-r--r--src/tools/ocbr/ocbr.c34
-rw-r--r--src/tools/ocbr/ocbr_client.c11
-rw-r--r--src/tools/ocbr/ocbr_server.c39
-rw-r--r--src/tools/oecho/oecho.c20
-rw-r--r--src/tools/operf/operf.c111
-rw-r--r--src/tools/operf/operf_client.c134
-rw-r--r--src/tools/operf/operf_server.c75
-rw-r--r--src/tools/oping/oping.c179
-rw-r--r--src/tools/oping/oping_client.c67
-rw-r--r--src/tools/oping/oping_server.c42
-rw-r--r--src/tools/ovpn/CMakeLists.txt21
-rw-r--r--src/tools/ovpn/ovpn.c335
-rw-r--r--src/tools/time_utils.h81
44 files changed, 1946 insertions, 577 deletions
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index b81e5439..7c40d9ae 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -1,5 +1,9 @@
add_subdirectory(irm)
add_subdirectory(ocbr)
add_subdirectory(oecho)
+add_subdirectory(obc)
add_subdirectory(oping)
add_subdirectory(operf)
+if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ add_subdirectory(ovpn)
+endif ()
diff --git a/src/tools/irm/CMakeLists.txt b/src/tools/irm/CMakeLists.txt
index ca32e9c7..e5e5c466 100644
--- a/src/tools/irm/CMakeLists.txt
+++ b/src/tools/irm/CMakeLists.txt
@@ -23,8 +23,12 @@ set(SOURCE_FILES
irm_unbind.c
irm_bind.c
irm_ipcp.c
- irm_register.c
- irm_unregister.c
+ irm_name.c
+ irm_name_create.c
+ irm_name_destroy.c
+ irm_name_reg.c
+ irm_name_unreg.c
+ irm_name_list.c
irm_utils.c
)
diff --git a/src/tools/irm/irm.c b/src/tools/irm/irm.c
index bc4c2cd9..ba0f4713 100644
--- a/src/tools/irm/irm.c
+++ b/src/tools/irm/irm.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* A tool to instruct the IRM daemon
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -49,8 +49,7 @@
static void usage(void)
{
printf("Usage: irm [OPERATION]\n\n"
- "where OPERATION = {ipcp bind unbind\n"
- " register unregister}\n");
+ "where OPERATION in { ipcp bind unbind name }\n");
}
static int do_help(int argc,
@@ -70,8 +69,7 @@ static const struct cmd {
{ "ipcp", ipcp_cmd },
{ "bind", bind_cmd },
{ "unbind", unbind_cmd },
- { "register", do_register },
- { "unregister", do_unregister },
+ { "name", name_cmd },
{ "help", do_help },
{ NULL, NULL }
};
diff --git a/src/tools/irm/irm_bind.c b/src/tools/irm/irm_bind.c
index 20a4e077..2e8b14ef 100644
--- a/src/tools/irm/irm_bind.c
+++ b/src/tools/irm/irm_bind.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Bind names in the processing system
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -47,7 +47,7 @@ static void usage(void)
{
printf("Usage: irm bind [OPERATION]\n"
"\n"
- "where OPERATION = {program process ipcp help}\n");
+ "where OPERATION in {program process ipcp help}\n");
}
static int do_help(int argc,
diff --git a/src/tools/irm/irm_bind_ipcp.c b/src/tools/irm/irm_bind_ipcp.c
index a30b4192..7d5dd636 100644
--- a/src/tools/irm/irm_bind_ipcp.c
+++ b/src/tools/irm/irm_bind_ipcp.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Bind IPCP Instance to a name
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -55,11 +55,11 @@ static void usage(void)
int do_bind_ipcp(int argc,
char ** argv)
{
- char * ipcp = NULL;
- char * name = NULL;
- struct ipcp_info * ipcps;
- ssize_t len;
- ssize_t i;
+ char * ipcp = NULL;
+ char * name = NULL;
+ struct ipcp_list_info * ipcps;
+ ssize_t len;
+ ssize_t i;
while (argc > 0) {
if (matches(*argv, "name") == 0) {
diff --git a/src/tools/irm/irm_bind_process.c b/src/tools/irm/irm_bind_process.c
index dbab5c7f..fffd5fe9 100644
--- a/src/tools/irm/irm_bind_process.c
+++ b/src/tools/irm/irm_bind_process.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Bind a process to a name
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/src/tools/irm/irm_bind_program.c b/src/tools/irm/irm_bind_program.c
index a3d9e4ac..8a0dc33c 100644
--- a/src/tools/irm/irm_bind_program.c
+++ b/src/tools/irm/irm_bind_program.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Bind programs to a name
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/src/tools/irm/irm_ipcp.c b/src/tools/irm/irm_ipcp.c
index 72e32805..63e617d9 100644
--- a/src/tools/irm/irm_ipcp.c
+++ b/src/tools/irm/irm_ipcp.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* A tool to instruct the IRM daemon
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -44,10 +44,11 @@
static void usage(void)
{
printf("Usage: irm ipcp [OPERATION]\n\n"
- "where OPERATION = {create destroy\n"
- " bootstrap enroll\n"
- " connect disconnect\n"
- " list help}\n");
+ "where OPERATION in {create destroy\n"
+ " bootstrap enroll\n"
+ " connect disconnect\n"
+ " list\n"
+ " help}\n");
}
static int do_help(int argc, char **argv)
diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c
index e1f75956..b8e5c54d 100644
--- a/src/tools/irm/irm_ipcp_bootstrap.c
+++ b/src/tools/irm/irm_ipcp_bootstrap.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Bootstrap IPC Processes
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -50,12 +50,12 @@
#include <sys/socket.h>
#endif
-#define NORMAL "normal"
+#define UNICAST "unicast"
+#define BROADCAST "broadcast"
#define UDP "udp"
#define ETH_LLC "eth-llc"
#define ETH_DIX "eth-dix"
#define LOCAL "local"
-#define RAPTOR "raptor"
#define MD5 "MD5"
#define SHA3_224 "SHA3_224"
@@ -64,20 +64,22 @@
#define SHA3_512 "SHA3_512"
#define DEFAULT_ADDR_SIZE 4
-#define DEFAULT_EID_SIZE 2
+#define DEFAULT_EID_SIZE 8
#define DEFAULT_DDNS 0
#define DEFAULT_TTL 60
#define DEFAULT_ADDR_AUTH ADDR_AUTH_FLAT_RANDOM
#define DEFAULT_ROUTING ROUTING_LINK_STATE
-#define DEFAULT_PFF PFF_SIMPLE
+#define DEFAULT_CONG_AVOID CA_MB_ECN
#define DEFAULT_HASH_ALGO DIR_HASH_SHA3_256
#define DEFAULT_ETHERTYPE 0xA000
+#define DEFAULT_UDP_PORT 0x0D6B /* 3435 */
#define FLAT_RANDOM_ADDR_AUTH "flat"
#define LINK_STATE_ROUTING "link_state"
#define LINK_STATE_LFA_ROUTING "lfa"
-#define SIMPLE_PFF "simple"
-#define ALTERNATE_PFF "alternate"
+#define LINK_STATE_ECM_ROUTING "ecmp"
+#define NONE_CA "none"
+#define MB_ECN_CA "mb-ecn"
static void usage(void)
{
@@ -86,76 +88,77 @@ static void usage(void)
" name <ipcp name>\n"
" layer <layer name>\n"
" [type [TYPE]]\n"
- "where TYPE = {" NORMAL " " LOCAL " "
- UDP " " ETH_LLC " " ETH_DIX " " RAPTOR "},\n\n"
- "if TYPE == " NORMAL "\n"
+ "where TYPE in {" UNICAST " " BROADCAST " " LOCAL " "
+ UDP " " ETH_LLC " " ETH_DIX "},\n\n"
+ "if TYPE == " UNICAST "\n"
" [addr <address size> (default: %d)]\n"
" [eid <eid size> (default: %d)]\n"
" [ttl (max time-to-live value, default: %d)]\n"
" [addr_auth <ADDRESS_POLICY> (default: %s)]\n"
" [routing <ROUTING_POLICY> (default: %s)]\n"
- " [pff [PFF_POLICY] (default: %s)]\n"
+ " [congestion <CONG_POLICY> (default: %s)]\n"
" [hash [ALGORITHM] (default: %s)]\n"
" [autobind]\n"
- "where ADDRESS_POLICY = {"FLAT_RANDOM_ADDR_AUTH"}\n"
- " ROUTING_POLICY = {"LINK_STATE_ROUTING " "
- LINK_STATE_LFA_ROUTING "}\n"
- " PFF_POLICY = {" SIMPLE_PFF " " ALTERNATE_PFF "}\n"
- " ALGORITHM = {" SHA3_224 " " SHA3_256 " "
+ "where ADDRESS_POLICY in {" FLAT_RANDOM_ADDR_AUTH "}\n"
+ " ROUTING_POLICY in {" LINK_STATE_ROUTING " "
+ LINK_STATE_LFA_ROUTING " " LINK_STATE_ECM_ROUTING "}\n"
+ " CONG_POLICY in {" NONE_CA " " MB_ECN_CA "}\n"
+ " ALGORITHM in {" SHA3_224 " " SHA3_256 " "
SHA3_384 " " SHA3_512 "}\n\n"
"if TYPE == " UDP "\n"
" ip <IP address in dotted notation>\n"
+ " [port <UDP port> (default: %d)]\n"
" [dns <DDNS IP address in dotted notation>"
" (default: none)]\n\n"
"if TYPE == " ETH_LLC "\n"
" dev <interface name>\n"
" [hash [ALGORITHM] (default: %s)]\n"
- "where ALGORITHM = {" SHA3_224 " " SHA3_256 " "
+ "where ALGORITHM in {" SHA3_224 " " SHA3_256 " "
SHA3_384 " " SHA3_512 "}\n\n"
"if TYPE == " ETH_DIX "\n"
" dev <interface name>\n"
" [ethertype <ethertype> (default: 0x%4X)]\n"
" [hash [ALGORITHM] (default: %s)]\n"
- "where ALGORITHM = {" SHA3_224 " " SHA3_256 " "
+ "where ALGORITHM in {" SHA3_224 " " SHA3_256 " "
SHA3_384 " " SHA3_512 "}\n\n"
"if TYPE == " LOCAL "\n"
" [hash [ALGORITHM] (default: %s)]\n"
- "where ALGORITHM = {" SHA3_224 " " SHA3_256 " "
+ "where ALGORITHM in {" SHA3_224 " " SHA3_256 " "
SHA3_384 " " SHA3_512 "}\n\n"
- "if TYPE == " RAPTOR "\n"
- " [hash [ALGORITHM] (default: %s)]\n"
- "where ALGORITHM = {" SHA3_224 " " SHA3_256 " "
- SHA3_384 " " SHA3_512 "}\n\n",
+ "if TYPE == " BROADCAST "\n"
+ " [autobind]\n\n",
DEFAULT_ADDR_SIZE, DEFAULT_EID_SIZE, DEFAULT_TTL,
- FLAT_RANDOM_ADDR_AUTH, LINK_STATE_ROUTING, SIMPLE_PFF,
- SHA3_256, SHA3_256, 0xA000, SHA3_256, SHA3_256, SHA3_256);
+ FLAT_RANDOM_ADDR_AUTH, LINK_STATE_ROUTING, MB_ECN_CA,
+ SHA3_256, DEFAULT_UDP_PORT, SHA3_256, 0xA000, SHA3_256,
+ SHA3_256);
}
int do_bootstrap_ipcp(int argc,
char ** argv)
{
- char * ipcp = NULL;
- pid_t pid = -1;
- struct ipcp_config conf;
- uint8_t addr_size = DEFAULT_ADDR_SIZE;
- uint8_t eid_size = DEFAULT_EID_SIZE;
- uint8_t max_ttl = DEFAULT_TTL;
- enum pol_addr_auth addr_auth_type = DEFAULT_ADDR_AUTH;
- enum pol_routing routing_type = DEFAULT_ROUTING;
- enum pol_pff pff_type = DEFAULT_PFF;
- enum pol_dir_hash hash_algo = DEFAULT_HASH_ALGO;
- uint32_t ip_addr = 0;
- uint32_t dns_addr = DEFAULT_DDNS;
- char * ipcp_type = NULL;
- enum ipcp_type type = IPCP_INVALID;
- char * layer = NULL;
- char * dev = NULL;
- uint16_t ethertype = DEFAULT_ETHERTYPE;
- struct ipcp_info * ipcps;
- ssize_t len = 0;
- int i = 0;
- bool autobind = false;
- int cargs;
+ char * ipcp = NULL;
+ pid_t pid = -1;
+ struct ipcp_config conf;
+ uint8_t addr_size = DEFAULT_ADDR_SIZE;
+ uint8_t eid_size = DEFAULT_EID_SIZE;
+ uint8_t max_ttl = DEFAULT_TTL;
+ enum pol_addr_auth addr_auth_type = DEFAULT_ADDR_AUTH;
+ enum pol_routing routing_type = DEFAULT_ROUTING;
+ enum pol_dir_hash hash_algo = DEFAULT_HASH_ALGO;
+ enum pol_cong_avoid cong_avoid = DEFAULT_CONG_AVOID;
+ uint32_t ip_addr = 0;
+ uint32_t dns_addr = DEFAULT_DDNS;
+ char * ipcp_type = NULL;
+ enum ipcp_type type = IPCP_INVALID;
+ char * layer = NULL;
+ char * dev = NULL;
+ uint16_t ethertype = DEFAULT_ETHERTYPE;
+ struct ipcp_list_info * ipcps;
+ ssize_t len = 0;
+ int i = 0;
+ bool autobind = false;
+ int cargs;
+ int port = DEFAULT_UDP_PORT;
while (argc > 0) {
cargs = 2;
@@ -190,7 +193,7 @@ int do_bootstrap_ipcp(int argc,
ethertype = strtol(*(argv + 1), NULL, 0);
else
ethertype = strtol(*(argv + 1), NULL, 16);
- if (ethertype < 0x0600 || ethertype == 0xFFFF) {
+ if (ethertype < 0x0600 || ethertype >= 0xFFFF) {
printf("Invalid Ethertype: \"%s\".\n"
"Recommended range: 0xA000-0xEFFF.\n",
*(argv + 1));
@@ -202,6 +205,8 @@ int do_bootstrap_ipcp(int argc,
eid_size = atoi(*(argv + 1));
} else if (matches(*argv, "ttl") == 0) {
max_ttl = atoi(*(argv + 1));
+ } else if (matches(*argv, "port") == 0) {
+ port = atoi(*(argv + 1));
} else if (matches(*argv, "autobind") == 0) {
autobind = true;
cargs = 1;
@@ -216,13 +221,17 @@ int do_bootstrap_ipcp(int argc,
else if (strcmp(LINK_STATE_LFA_ROUTING,
*(argv + 1)) == 0)
routing_type = ROUTING_LINK_STATE_LFA;
+ else if (strcmp(LINK_STATE_ECM_ROUTING,
+ *(argv + 1)) == 0)
+ routing_type = ROUTING_LINK_STATE_ECMP;
else
goto unknown_param;
- } else if (matches(*argv, "pff") == 0) {
- if (strcmp(SIMPLE_PFF, *(argv + 1)) == 0)
- pff_type = PFF_SIMPLE;
- else if (strcmp(ALTERNATE_PFF, *(argv + 1)) == 0)
- pff_type = PFF_ALTERNATE;
+ } else if (matches(*argv, "congestion") == 0) {
+ if (strcmp(NONE_CA, *(argv + 1)) == 0)
+ cong_avoid = CA_NONE;
+ else if (strcmp(MB_ECN_CA,
+ *(argv + 1)) == 0)
+ cong_avoid = CA_MB_ECN;
else
goto unknown_param;
} else {
@@ -248,8 +257,10 @@ int do_bootstrap_ipcp(int argc,
}
if (ipcp_type != NULL) {
- if (strcmp(ipcp_type, NORMAL) == 0)
- type = IPCP_NORMAL;
+ if (strcmp(ipcp_type, UNICAST) == 0)
+ type = IPCP_UNICAST;
+ else if (strcmp(ipcp_type, BROADCAST) == 0)
+ type = IPCP_BROADCAST;
else if (strcmp(ipcp_type, UDP) == 0)
type = IPCP_UDP;
else if (strcmp(ipcp_type, ETH_LLC) == 0)
@@ -258,8 +269,6 @@ int do_bootstrap_ipcp(int argc,
type = IPCP_ETH_DIX;
else if (strcmp(ipcp_type, LOCAL) == 0)
type = IPCP_LOCAL;
- else if (strcmp(ipcp_type, RAPTOR) == 0)
- type = IPCP_RAPTOR;
else goto fail_usage;
}
@@ -283,47 +292,56 @@ int do_bootstrap_ipcp(int argc,
printf("Types do not match.\n\n");
goto fail;
}
+
conf.type = ipcps[i].type;
- if (autobind && conf.type != IPCP_NORMAL) {
- printf("Can only bind normal IPCPs, "
- "autobind disabled.\n");
+ if (autobind && (conf.type != IPCP_UNICAST &&
+ conf.type != IPCP_BROADCAST)) {
+ printf("Can not bind this IPCP type,"
+ "autobind disabled.\n\n");
autobind = false;
}
- strcpy(conf.layer_info.layer_name, layer);
- if (conf.type != IPCP_UDP)
- conf.layer_info.dir_hash_algo = hash_algo;
+ if (strlen(layer) > LAYER_NAME_SIZE) {
+ printf("Layer name too long.\n\n");
+ goto fail_usage;
+ }
+
+ strcpy(conf.layer_info.name, layer);
+ conf.layer_info.dir_hash_algo = hash_algo;
switch (conf.type) {
- case IPCP_NORMAL:
- conf.addr_size = addr_size;
- conf.eid_size = eid_size;
- conf.max_ttl = max_ttl;
- conf.addr_auth_type = addr_auth_type;
- conf.routing_type = routing_type;
- conf.pff_type = pff_type;
+ case IPCP_UNICAST:
+ conf.unicast.dt.addr_size = addr_size;
+ conf.unicast.dt.eid_size = eid_size;
+ conf.unicast.dt.max_ttl = max_ttl;
+ conf.unicast.dt.routing_type = routing_type;
+ conf.unicast.addr_auth_type = addr_auth_type;
+ conf.unicast.cong_avoid = cong_avoid;
break;
case IPCP_UDP:
if (ip_addr == 0)
goto fail_usage;
- conf.ip_addr = ip_addr;
- conf.dns_addr = dns_addr;
+ conf.udp.ip_addr = ip_addr;
+ conf.udp.dns_addr = dns_addr;
+ conf.udp.port = port;
break;
+ case IPCP_ETH_DIX:
+ conf.eth.ethertype = ethertype;
+ /* FALLTHRU */
case IPCP_ETH_LLC:
if (dev == NULL)
goto fail_usage;
- conf.dev = dev;
- break;
- case IPCP_ETH_DIX:
- if (dev == NULL)
+ if (strlen(dev) > DEV_NAME_SIZE) {
+ printf("Device name too long.\n\n");
goto fail_usage;
- conf.dev = dev;
- conf.ethertype = ethertype;
+ }
+
+ strcpy(conf.eth.dev, dev);
break;
- case IPCP_LOCAL:
+ case IPCP_BROADCAST:
/* FALLTHRU */
- case IPCP_RAPTOR:
+ case IPCP_LOCAL:
break;
default:
assert(false);
diff --git a/src/tools/irm/irm_ipcp_connect.c b/src/tools/irm/irm_ipcp_connect.c
index 42c07354..68e13bd0 100644
--- a/src/tools/irm/irm_ipcp_connect.c
+++ b/src/tools/irm/irm_ipcp_connect.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
- * Connect components of normal IPC Processes
+ * Connect components of unicast or broadcast IPC processes
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,6 +37,7 @@
*/
#include <ouroboros/irm.h>
+#include <ouroboros/qos.h>
#include "irm_ops.h"
#include "irm_utils.h"
@@ -45,28 +46,34 @@
#include <stdlib.h>
#include <string.h>
-#define DT "dt"
-#define MGMT "mgmt"
+#define DT "dt"
+#define MGMT "mgmt"
static void usage(void)
{
printf("Usage: irm ipcp connect\n"
" name <ipcp name>\n"
- " component [COMPONENT]\n"
- " dst <name of destination IPCP>\n\n"
- "where COMPONENT = {" DT " " MGMT "}\n");
+ " dst <name of destination IPCP>\n"
+ " [component [COMPONENT]]\n"
+ "where COMPONENT in {" DT " " MGMT "}\n\n"
+ "if COMPONENT == " DT "\n"
+ " [qos [QOS]\n"
+ "where QOS in {raw, best, voice, video, data}\n");
}
int do_connect_ipcp(int argc,
char ** argv)
{
- char * ipcp = NULL;
- char * dst = NULL;
- char * comp = NULL;
- struct ipcp_info * ipcps;
- ssize_t len = 0;
- pid_t pid = -1;
- ssize_t i;
+ char * ipcp = NULL;
+ char * dst = NULL;
+ char * comp = "*";
+ char * component = NULL;
+ char * qos = NULL;
+ struct ipcp_list_info * ipcps;
+ ssize_t len = 0;
+ pid_t pid = -1;
+ ssize_t i;
+ qosspec_t qs = qos_raw;
while (argc > 0) {
if (matches(*argv, "name") == 0) {
@@ -75,9 +82,11 @@ int do_connect_ipcp(int argc,
dst = *(argv + 1);
} else if (matches(*argv, "component") == 0) {
comp = *(argv + 1);
+ } else if (matches(*argv, "qos") == 0) {
+ qos = *(argv + 1);
} else {
printf("\"%s\" is unknown, try \"irm "
- "ipcpi connect\".\n", *argv);
+ "ipcp connect\".\n", *argv);
return -1;
}
@@ -90,6 +99,21 @@ int do_connect_ipcp(int argc,
return -1;
}
+ if (qos != NULL) {
+ if (strcmp(qos, "best") == 0)
+ qs = qos_best_effort;
+ else if (strcmp(qos, "raw") == 0)
+ qs = qos_raw;
+ else if (strcmp(qos, "video") == 0)
+ qs = qos_video;
+ else if (strcmp(qos, "voice") == 0)
+ qs = qos_voice;
+ else if (strcmp(qos, "data") == 0)
+ qs = qos_data;
+ else
+ printf("Unknown QoS cube, defaulting to raw.\n");
+ }
+
len = irm_list_ipcps(&ipcps);
for (i = 0; i < len; i++)
if (strcmp(ipcps[i].name, ipcp) == 0)
@@ -100,14 +124,18 @@ int do_connect_ipcp(int argc,
if (pid == -1)
return -1;
- if (!strcmp(comp, DT))
- comp = DT_COMP;
-
- if (!strcmp(comp , MGMT))
- comp = MGMT_COMP;
+ if (wildcard_match(comp, MGMT) == 0) {
+ component = MGMT_COMP;
+ /* FIXME: move to qos_data when stable */
+ if (irm_connect_ipcp(pid, dst, component, qos_raw))
+ return -1;
+ }
- if (irm_connect_ipcp(pid, dst, comp))
- return -1;
+ if (wildcard_match(comp, DT) == 0) {
+ component = DT_COMP;
+ if (irm_connect_ipcp(pid, dst, component, qs))
+ return -1;
+ }
return 0;
}
diff --git a/src/tools/irm/irm_ipcp_create.c b/src/tools/irm/irm_ipcp_create.c
index c8866962..35d33782 100644
--- a/src/tools/irm/irm_ipcp_create.c
+++ b/src/tools/irm/irm_ipcp_create.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Create IPC Processes
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -44,29 +44,29 @@
#include "irm_ops.h"
#include "irm_utils.h"
-#define NORMAL "normal"
-#define UDP "udp"
-#define ETH_LLC "eth-llc"
-#define ETH_DIX "eth-dix"
-#define LOCAL "local"
-#define RAPTOR "raptor"
+#define UNICAST "unicast"
+#define BROADCAST "broadcast"
+#define UDP "udp"
+#define ETH_LLC "eth-llc"
+#define ETH_DIX "eth-dix"
+#define LOCAL "local"
static void usage(void)
{
printf("Usage: irm ipcp create\n"
" name <ipcp name>\n"
" type [TYPE]\n\n"
- "where TYPE = {" NORMAL " " LOCAL " "
- UDP " " ETH_LLC " " RAPTOR "}\n");
+ "where TYPE in {" UNICAST " " BROADCAST " " LOCAL " "
+ UDP " " ETH_LLC " " ETH_DIX "}\n");
}
int do_create_ipcp(int argc,
char ** argv)
{
- char * ipcp_type = NULL;
- char * ipcp_name = NULL;
- enum ipcp_type type = 0;
- pid_t pid;
+ char * ipcp_type = NULL;
+ char * ipcp_name = NULL;
+ enum ipcp_type type = 0;
+ pid_t pid;
while (argc > 0) {
if (matches(*argv, "type") == 0) {
@@ -88,8 +88,10 @@ int do_create_ipcp(int argc,
return -1;
}
- if (strcmp(ipcp_type, NORMAL) == 0)
- type = IPCP_NORMAL;
+ if (strcmp(ipcp_type, UNICAST) == 0)
+ type = IPCP_UNICAST;
+ else if (strcmp(ipcp_type, BROADCAST) == 0)
+ type = IPCP_BROADCAST;
else if (strcmp(ipcp_type, UDP) == 0)
type = IPCP_UDP;
else if (strcmp(ipcp_type, LOCAL) == 0)
@@ -98,15 +100,14 @@ int do_create_ipcp(int argc,
type = IPCP_ETH_LLC;
else if (strcmp(ipcp_type, ETH_DIX) == 0)
type = IPCP_ETH_DIX;
- else if (strcmp(ipcp_type, RAPTOR) == 0)
- type = IPCP_RAPTOR;
else {
+ printf("IPCP type \"%s\" is unknown.\n", ipcp_type);
usage();
return -1;
}
pid = irm_create_ipcp(ipcp_name, type);
- if (pid <= 0)
+ if (pid < 0)
return -1;
return 0;
diff --git a/src/tools/irm/irm_ipcp_destroy.c b/src/tools/irm/irm_ipcp_destroy.c
index cb86b167..1a5e564e 100644
--- a/src/tools/irm/irm_ipcp_destroy.c
+++ b/src/tools/irm/irm_ipcp_destroy.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Destroy IPC Processes
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -55,10 +55,10 @@ static void usage(void)
int do_destroy_ipcp(int argc,
char ** argv)
{
- char * ipcp = NULL;
- struct ipcp_info * ipcps;
- ssize_t len;
- int i;
+ char * ipcp = NULL;
+ struct ipcp_list_info * ipcps;
+ ssize_t len;
+ int i;
while (argc > 0) {
if (matches(*argv, "name") == 0) {
@@ -89,6 +89,7 @@ int do_destroy_ipcp(int argc,
break;
}
+ free(ipcps);
return 0;
fail_destroy:
diff --git a/src/tools/irm/irm_ipcp_disconnect.c b/src/tools/irm/irm_ipcp_disconnect.c
index 73f1588d..7ce724e1 100644
--- a/src/tools/irm/irm_ipcp_disconnect.c
+++ b/src/tools/irm/irm_ipcp_disconnect.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
- * Connect components of normal IPC Processes
+ * Connect components of unicast or broadcast IPC processes
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -45,28 +45,29 @@
#include <stdlib.h>
#include <string.h>
-#define DT "dt"
-#define MGMT "mgmt"
+#define DT "dt"
+#define MGMT "mgmt"
static void usage(void)
{
printf("Usage: irm ipcp disconnect\n"
" name <ipcp name>\n"
- " component [COMPONENT]\n"
- " dst <name of destination IPCP>\n\n"
- "where COMPONENT = {" DT " " MGMT "}\n");
+ " dst <name of destination IPCP>\n"
+ " [component [COMPONENT]]\n\n"
+ "where COMPONENT in {" DT " " MGMT "}\n");
}
int do_disconnect_ipcp(int argc,
char ** argv)
{
- char * ipcp = NULL;
- char * dst = NULL;
- char * comp = NULL;
- struct ipcp_info * ipcps;
- ssize_t len = 0;
- pid_t pid = -1;
- ssize_t i;
+ char * ipcp = NULL;
+ char * dst = NULL;
+ char * comp = "*";
+ char * component = NULL;
+ struct ipcp_list_info * ipcps;
+ ssize_t len = 0;
+ pid_t pid = -1;
+ ssize_t i;
while (argc > 0) {
if (matches(*argv, "name") == 0) {
@@ -77,7 +78,7 @@ int do_disconnect_ipcp(int argc,
comp = *(argv + 1);
} else {
printf("\"%s\" is unknown, try \"irm "
- "ipcpi connect\".\n", *argv);
+ "ipcp connect\".\n", *argv);
return -1;
}
@@ -100,14 +101,17 @@ int do_disconnect_ipcp(int argc,
if (pid == -1)
return -1;
- if (!strcmp(comp, DT))
- comp = DT_COMP;
-
- if (!strcmp(comp , MGMT))
- comp = MGMT_COMP;
+ if (wildcard_match(comp, DT) == 0) {
+ component = DT_COMP;
+ if (irm_disconnect_ipcp(pid, dst, component))
+ return -1;
+ }
- if (irm_disconnect_ipcp(pid, dst, comp))
- return -1;
+ if (wildcard_match(comp, MGMT) == 0) {
+ component = MGMT_COMP;
+ if (irm_disconnect_ipcp(pid, dst, component))
+ return -1;
+ }
return 0;
}
diff --git a/src/tools/irm/irm_ipcp_enroll.c b/src/tools/irm/irm_ipcp_enroll.c
index c1628af6..86a22a71 100644
--- a/src/tools/irm/irm_ipcp_enroll.c
+++ b/src/tools/irm/irm_ipcp_enroll.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Enroll IPC Processes
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,32 +46,65 @@
#include <string.h>
+#define UNICAST "unicast"
+#define BROADCAST "broadcast"
+
static void usage(void)
{
printf("Usage: irm ipcp enroll\n"
" name <ipcp name>\n"
- " layer <layer to enroll in>\n"
- " [autobind]\n");
+ " [layer <layer to enroll with>]\n"
+ " [dst <destination to enroll with>]\n"
+ " [type [TYPE], default = " UNICAST "]\n"
+ " [autobind]\n"
+ "where TYPE in {" UNICAST " " BROADCAST "}\n");
+}
+
+static int get_layer_name(const char * ipcp,
+ char * layer_name)
+{
+ struct ipcp_list_info * ipcps;
+ ssize_t len;
+ ssize_t i;
+
+ len = irm_list_ipcps(&ipcps);
+ for (i = 0; i < len; i++)
+ if (strcmp(ipcps[i].name, ipcp) == 0) {
+ strcpy(layer_name, ipcps[i].layer);
+ free(ipcps);
+ return 0;
+ }
+
+ free(ipcps);
+
+ return -1;
}
int do_enroll_ipcp(int argc,
char ** argv)
{
- char * ipcp = NULL;
- char * layer = NULL;
- struct ipcp_info * ipcps;
- pid_t pid = -1;
- ssize_t len = 0;
- int i = 0;
- bool autobind = false;
- int cargs;
+ char * ipcp = NULL;
+ char * layer = NULL;
+ char * dst = NULL;
+ struct ipcp_list_info * ipcps;
+ pid_t pid = -1;
+ ssize_t len = 0;
+ int i = 0;
+ bool autobind = false;
+ int cargs;
+ char * ipcp_type = UNICAST;
+ enum ipcp_type type = IPCP_INVALID;
while (argc > 0) {
cargs = 2;
if (matches(*argv, "name") == 0) {
ipcp = *(argv + 1);
+ } else if (matches(*argv, "type") == 0) {
+ ipcp_type = *(argv + 1);
} else if (matches(*argv, "layer") == 0) {
layer = *(argv + 1);
+ } else if (matches(*argv, "dst") == 0) {
+ dst = *(argv + 1);
} else if (matches(*argv, "autobind") == 0) {
autobind = true;
cargs = 1;
@@ -85,19 +118,27 @@ int do_enroll_ipcp(int argc,
argv += cargs;
}
- if (layer == NULL || ipcp == NULL) {
+ if ((layer == NULL && dst == NULL) || ipcp == NULL) {
usage();
return -1;
}
+ if (dst == NULL)
+ dst = layer;
+
+ if (strcmp(ipcp_type, UNICAST) == 0)
+ type = IPCP_UNICAST;
+ else if (strcmp(ipcp_type, BROADCAST) == 0)
+ type = IPCP_BROADCAST;
+
len = irm_list_ipcps(&ipcps);
for (i = 0; i < len; i++)
if (wildcard_match(ipcps[i].name, ipcp) == 0 &&
- ipcps[i].type == IPCP_NORMAL)
+ ipcps[i].type == type)
pid = ipcps[i].pid;
if (pid < 0) {
- pid = irm_create_ipcp(ipcp, IPCP_NORMAL);
+ pid = irm_create_ipcp(ipcp, type);
if (pid < 0)
goto fail;
free(ipcps);
@@ -105,25 +146,39 @@ int do_enroll_ipcp(int argc,
}
for (i = 0; i < len; i++) {
- if (ipcps[i].type != IPCP_NORMAL)
+ char enr_layer[LAYER_NAME_SIZE];
+ if (ipcps[i].type != type)
continue;
- if (wildcard_match(ipcps[i].name, ipcp) == 0) {
- pid = ipcps[i].pid;
- if (autobind && irm_bind_process(pid, ipcp)) {
- printf("Failed to bind %d to %s.\n", pid, ipcp);
- goto fail;
- }
-
- if (irm_enroll_ipcp(pid, layer)) {
- if (autobind)
- irm_unbind_process(pid, ipcp);
- goto fail;
- }
-
- if (autobind && irm_bind_process(pid, layer)) {
- printf("Failed to bind %d to %s.\n", pid, layer);
- goto fail;
- }
+
+ if (wildcard_match(ipcps[i].name, ipcp) != 0)
+ continue;
+
+ pid = ipcps[i].pid;
+
+ if (irm_enroll_ipcp(pid, dst)) {
+ printf("Failed to enroll IPCP.\n");
+ goto fail;
+ }
+
+ if (get_layer_name(ipcps[i].name, enr_layer)) {
+ printf("Could not get layer name.\n");
+ goto fail;
+ }
+
+ if (layer != NULL && strcmp(enr_layer, layer)) {
+ printf("Enrollment destination does not "
+ "match requested layer.\n");
+ goto fail;
+ }
+
+ if (autobind && irm_bind_process(pid, ipcp)) {
+ printf("Failed to bind %d to %s.\n", pid, ipcp);
+ goto fail;
+ }
+
+ if (autobind && irm_bind_process(pid, enr_layer)) {
+ printf("Failed to bind %d to %s.\n", pid, enr_layer);
+ goto fail;
}
}
diff --git a/src/tools/irm/irm_ipcp_list.c b/src/tools/irm/irm_ipcp_list.c
index 5a9ecaff..dfa3099f 100644
--- a/src/tools/irm/irm_ipcp_list.c
+++ b/src/tools/irm/irm_ipcp_list.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
- * Create IPC Processes
+ * List IPC Processes
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,12 +46,12 @@
#include <stdlib.h>
#include <string.h>
-#define NORMAL "normal"
-#define UDP "udp"
-#define ETH_LLC "eth-llc"
-#define ETH_DIX "eth-dix"
-#define LOCAL "local"
-#define RAPTOR "raptor"
+#define UNICAST "unicast"
+#define BROADCAST "broadcast"
+#define UDP "udp"
+#define ETH_LLC "eth-llc"
+#define ETH_DIX "eth-dix"
+#define LOCAL "local"
static void usage(void)
{
@@ -59,23 +59,23 @@ static void usage(void)
" [name <ipcp name>]\n"
" [layer <layer_name>]\n\n"
" [type [TYPE]]\n\n"
- "where TYPE = {" NORMAL " " LOCAL " "
- UDP " " ETH_LLC " " ETH_DIX " " RAPTOR "}\n");
+ "where TYPE = {" UNICAST " " LOCAL " "
+ UDP " " ETH_LLC " " ETH_DIX "}\n");
}
static char * str_type(enum ipcp_type type)
{
switch(type) {
- case IPCP_NORMAL:
- return NORMAL;
+ case IPCP_UNICAST:
+ return UNICAST;
+ case IPCP_BROADCAST:
+ return BROADCAST;
case IPCP_ETH_LLC:
return ETH_LLC;
case IPCP_ETH_DIX:
return ETH_DIX;
case IPCP_UDP:
return UDP;
- case IPCP_RAPTOR:
- return RAPTOR;
case IPCP_LOCAL:
return LOCAL;
default:
@@ -86,12 +86,12 @@ static char * str_type(enum ipcp_type type)
int do_list_ipcp(int argc,
char ** argv)
{
- char * ipcp_type = NULL;
- char * ipcp_name = NULL;
- enum ipcp_type type = -1;
- struct ipcp_info * ipcps;
- ssize_t len;
- ssize_t i;
+ char * ipcp_type = NULL;
+ char * ipcp_name = NULL;
+ enum ipcp_type type = -1;
+ struct ipcp_list_info * ipcps;
+ ssize_t len;
+ ssize_t i;
while (argc > 0) {
if (matches(*argv, "type") == 0) {
@@ -109,8 +109,10 @@ int do_list_ipcp(int argc,
}
if (ipcp_type != NULL) {
- if (strcmp(ipcp_type, NORMAL) == 0)
- type = IPCP_NORMAL;
+ if (strcmp(ipcp_type, UNICAST) == 0)
+ type = IPCP_UNICAST;
+ else if (strcmp(ipcp_type, BROADCAST) == 0)
+ type = IPCP_BROADCAST;
else if (strcmp(ipcp_type, UDP) == 0)
type = IPCP_UDP;
else if (strcmp(ipcp_type, LOCAL) == 0)
@@ -119,8 +121,6 @@ int do_list_ipcp(int argc,
type = IPCP_ETH_LLC;
else if (strcmp(ipcp_type, ETH_DIX) == 0)
type = IPCP_ETH_DIX;
- else if (strcmp(ipcp_type, RAPTOR) == 0)
- type = IPCP_RAPTOR;
else {
usage();
return -1;
diff --git a/src/tools/irm/irm_name.c b/src/tools/irm/irm_name.c
new file mode 100644
index 00000000..d60b6c78
--- /dev/null
+++ b/src/tools/irm/irm_name.c
@@ -0,0 +1,99 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * A tool to instruct the IRM daemon
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "irm_ops.h"
+#include "irm_utils.h"
+
+static void usage(void)
+{
+ printf("Usage: irm name [OPERATION]\n\n"
+ "where OPERATION in {create destroy\n"
+ " register unregister\n"
+ " list\n"
+ " help}\n");
+}
+
+static int do_help(int argc, char **argv)
+{
+ (void) argc;
+ (void) argv;
+
+ usage();
+ return 0;
+}
+
+static const struct cmd {
+ const char * cmd;
+ int (* func)(int argc, char ** argv);
+} cmds[] = {
+ { "create", do_create_name },
+ { "destroy", do_destroy_name },
+ { "register", do_reg_name },
+ { "unregister", do_unreg_name },
+ { "list", do_list_name},
+ { "help", do_help },
+ { NULL, NULL }
+};
+
+static int do_cmd(const char * argv0,
+ int argc,
+ char ** argv)
+{
+ const struct cmd * c;
+
+ for (c = cmds; c->cmd; ++c) {
+ if (matches(argv0, c->cmd) == 0)
+ return c->func(argc - 1, argv + 1);
+ }
+
+ fprintf(stderr, "\"%s\" is unknown, try \"irm ipcp help\".\n", argv0);
+
+ return -1;
+}
+
+int name_cmd(int argc, char ** argv)
+{
+ if (argc < 1) {
+ usage();
+ return -1;
+ }
+
+ return do_cmd(argv[0], argc, argv);
+}
diff --git a/src/tools/irm/irm_name_create.c b/src/tools/irm/irm_name_create.c
new file mode 100644
index 00000000..a0079cad
--- /dev/null
+++ b/src/tools/irm/irm_name_create.c
@@ -0,0 +1,96 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Create IPC Processes
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ouroboros/irm.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "irm_ops.h"
+#include "irm_utils.h"
+
+#define RR "round-robin"
+#define SPILL "spillover"
+
+static void usage(void)
+{
+ printf("Usage: irm name create\n"
+ " <name>\n"
+ " lb [LB_POLICY], default: %s\n\n"
+ "where LB_POLICY in {" RR " " SPILL "}\n", RR);
+}
+
+int do_create_name(int argc,
+ char ** argv)
+{
+ char * name = NULL;
+ char * lb_pol = RR;
+ enum pol_balance pol_lb = LB_RR;
+
+ name = *(argv++);
+ --argc;
+
+ while (argc > 0) {
+ if (matches(*argv, "lb") == 0) {
+ lb_pol = *(argv + 1);
+ } else {
+ printf("\"%s\" is unknown, try \"irm "
+ "name create\".\n", *argv);
+ return -1;
+ }
+
+ argc -= 2;
+ argv += 2;
+ }
+
+ if (name == NULL) {
+ usage();
+ return -1;
+ }
+
+ if (strcmp(lb_pol, RR) == 0)
+ pol_lb = LB_RR;
+ else if (strcmp(lb_pol, SPILL) == 0)
+ pol_lb = LB_SPILL;
+ else {
+ usage();
+ return -1;
+ }
+
+ return irm_create_name(name, pol_lb);
+}
diff --git a/src/tools/irm/irm_name_destroy.c b/src/tools/irm/irm_name_destroy.c
new file mode 100644
index 00000000..d4bd6c82
--- /dev/null
+++ b/src/tools/irm/irm_name_destroy.c
@@ -0,0 +1,72 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Create IPC Processes
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ouroboros/irm.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "irm_ops.h"
+#include "irm_utils.h"
+
+static void usage(void)
+{
+ printf("Usage: irm name destroy <name>\n");
+}
+
+int do_destroy_name(int argc,
+ char ** argv)
+{
+ char * name = NULL;
+
+ name = *(argv++);
+ --argc;
+
+ if (argc > 0) {
+ printf("\"%s\" is unknown, try \"irm "
+ "name destroy\".\n", *argv);
+ return -1;
+ }
+
+ if (name == NULL) {
+ usage();
+ return -1;
+ }
+
+ return irm_destroy_name(name);
+}
diff --git a/src/tools/irm/irm_name_list.c b/src/tools/irm/irm_name_list.c
new file mode 100644
index 00000000..a807008c
--- /dev/null
+++ b/src/tools/irm/irm_name_list.c
@@ -0,0 +1,115 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * List names
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ouroboros/irm.h>
+#include <ouroboros/errno.h>
+
+#include "irm_ops.h"
+#include "irm_utils.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define RR "round-robin"
+#define SPILL "spillover"
+
+static char * str_pol(enum pol_balance p)
+{
+ switch(p) {
+ case LB_RR:
+ return RR;
+ case LB_SPILL:
+ return SPILL;
+ default:
+ return "UNKNOWN";
+ }
+};
+
+int do_list_name(int argc,
+ char ** argv)
+{
+ char * name = NULL;
+ struct name_info * names;
+ ssize_t len;
+ ssize_t i;
+
+ while (argc > 0) {
+ if (matches(*argv, "list") == 0) {
+ name = *(argv + 1);
+ } else {
+ printf("\"%s\" is unknown, try \"irm "
+ "name list.\n", *argv);
+ return -1;
+ }
+
+ argc -= 2;
+ argv += 2;
+ }
+
+ len = irm_list_names(&names);
+ if (len == 0) {
+ printf("No names in system.\n\n");
+ return 0;
+ } else if (len == -EIRMD) {
+ printf("Failed to communicate with the "
+ "Ouroboros IPC Resource Manager daemon.\n");
+ return -1;
+ } else if (len < 0)
+ return len;
+
+ printf("+----------------------------------------------------"
+ "+----------------------+\n");
+ printf("| %50s | %20s |\n", "name", "load-balance policy");
+ printf("+----------------------------------------------------"
+ "+----------------------+\n");
+
+ for (i = 0; i < len; i++) {
+ if (name != NULL && matches(names[i].name, name))
+ continue;
+ printf("| %50s | %20s |\n",
+ names[i].name,
+ str_pol(names[i].pol_lb));
+ }
+ printf("+----------------------------------------------------"
+ "+----------------------+\n");
+
+ free(names);
+
+ return 0;
+}
diff --git a/src/tools/irm/irm_register.c b/src/tools/irm/irm_name_reg.c
index 23c65f7d..061ed8be 100644
--- a/src/tools/irm/irm_register.c
+++ b/src/tools/irm/irm_name_reg.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
- * Register names in IPCPs
+ * Register names with IPCPs
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -38,7 +38,6 @@
#include <ouroboros/irm.h>
-
#include "irm_ops.h"
#include "irm_utils.h"
@@ -51,8 +50,7 @@
static void usage(void)
{
- printf("Usage: irm register\n"
- " name <name>\n"
+ printf("Usage: irm name register <name>\n"
" ipcp <ipcp to register with>\n"
" [ipcp <ipcp to register with>]\n"
" [... (maximum %d ipcps)]\n"
@@ -63,23 +61,26 @@ static void usage(void)
}
-int do_register(int argc,
+int do_reg_name(int argc,
char ** argv)
{
- char * name = NULL;
- char * layers[MAX_LAYERS];
- size_t layers_len = 0;
- char * ipcp[MAX_IPCPS];
- size_t ipcp_len = 0;
- struct ipcp_info * ipcps;
- ssize_t len;
- ssize_t i;
-
+ char * name = NULL;
+ char * layers[MAX_LAYERS];
+ size_t layers_len = 0;
+ char * ipcp[MAX_IPCPS];
+ size_t ipcp_len = 0;
+ struct ipcp_list_info * ipcps;
+ ssize_t ipcps_len;
+ struct name_info * names;
+ ssize_t names_len;
+ bool name_create = true;
+ ssize_t i;
+
+ name = *(argv++);
+ --argc;
while (argc > 0) {
- if (matches(*argv, "name") == 0) {
- name = *(argv + 1);
- } else if (matches(*argv, "layer") == 0) {
+ if (matches(*argv, "layer") == 0) {
layers[layers_len++] = *(argv + 1);
if (layers_len > MAX_LAYERS) {
printf("Too many layers specified.\n");
@@ -92,7 +93,7 @@ int do_register(int argc,
return -1;
}
} else {
- printf("\"%s\" is unknown, try \"irm "
+ printf("\"%s\" is unknown, try \"irm name "
"register\".\n", *argv);
return -1;
}
@@ -106,33 +107,54 @@ int do_register(int argc,
return -1;
}
- len = irm_list_ipcps(&ipcps);
- if (len < 0)
- return len;
+ ipcps_len = irm_list_ipcps(&ipcps);
+ if (ipcps_len < 0)
+ return ipcps_len;
+
+ names_len = irm_list_names(&names);
+ if (names_len < 0) {
+ free(ipcps);
+ return names_len;
+ }
+
+ for (i = 0; i < names_len; ++i) {
+ if (strcmp(names[i].name, name) == 0) {
+ name_create = false;
+ break;
+ }
+ }
+
+ if (name_create && irm_create_name(name, LB_SPILL)) {
+ printf("Error creating name.");
+ free(ipcps);
+ free(name);
+ return -1;
+ }
- for (i = 0; i < len; ++i) {
+ for (i = 0; i < ipcps_len; ++i) {
size_t j;
for (j = 0; j < layers_len; j++) {
- if (wildcard_match(ipcps[i].layer, layers[j]) == 0) {
- if (irm_reg(ipcps[i].pid, name)) {
+ if (wildcard_match(layers[j], ipcps[i].layer) == 0) {
+ if (irm_reg_name(name, ipcps[i].pid)) {
free(ipcps);
+ free(names);
return -1;
}
- break;
}
}
for (j = 0; j < ipcp_len; j++) {
- if (wildcard_match(ipcps[i].name, ipcp[j]) == 0) {
- if (irm_reg(ipcps[i].pid, name)) {
+ if (wildcard_match(ipcp[j], ipcps[i].name) == 0) {
+ if (irm_reg_name(name, ipcps[i].pid)) {
free(ipcps);
+ free(names);
return -1;
}
- break;
}
}
}
free(ipcps);
+ free(names);
return 0;
}
diff --git a/src/tools/irm/irm_unregister.c b/src/tools/irm/irm_name_unreg.c
index 52491b42..6e579f04 100644
--- a/src/tools/irm/irm_unregister.c
+++ b/src/tools/irm/irm_name_unreg.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Unregister names from IPCPs
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -50,8 +50,7 @@
static void usage(void)
{
- printf("Usage: irm unregister\n"
- " name <name>\n"
+ printf("Usage: irm name unregister <name>\n"
" ipcp <ipcp to register with>\n"
" [ipcp <ipcp to register with>]\n"
" [... (maximum %d ipcps)]\n"
@@ -61,21 +60,23 @@ static void usage(void)
, MAX_IPCPS, MAX_LAYERS);
}
-int do_unregister(int argc, char ** argv)
+int do_unreg_name(int argc,
+ char ** argv)
{
- char * name = NULL;
- char * layers[MAX_LAYERS];
- size_t layers_len = 0;
- char * ipcp[MAX_IPCPS];
- size_t ipcp_len = 0;
- struct ipcp_info * ipcps;
- size_t len;
- size_t i;
+ char * name = NULL;
+ char * layers[MAX_LAYERS];
+ size_t layers_len = 0;
+ char * ipcp[MAX_IPCPS];
+ size_t ipcp_len = 0;
+ struct ipcp_list_info * ipcps;
+ ssize_t len;
+ size_t i;
+
+ name = *(argv++);
+ --argc;
while (argc > 0) {
- if (matches(*argv, "name") == 0) {
- name = *(argv + 1);
- } else if (matches(*argv, "layer") == 0) {
+ if (matches(*argv, "layer") == 0) {
layers[layers_len++] = *(argv + 1);
if (layers_len > MAX_LAYERS) {
printf("Too many layers specified.\n");
@@ -103,11 +104,14 @@ int do_unregister(int argc, char ** argv)
}
len = irm_list_ipcps(&ipcps);
- for (i = 0; i < len; ++i) {
+ if (len < 0)
+ return -1;
+
+ for (i = 0; i < (size_t) len; ++i) {
size_t j;
for (j = 0; j < layers_len; j++) {
if (wildcard_match(ipcps[i].layer, layers[j]) == 0) {
- if (irm_unreg(ipcps[i].pid, name)) {
+ if (irm_unreg_name(name, ipcps[i].pid)) {
free(ipcps);
return -1;
}
@@ -116,7 +120,7 @@ int do_unregister(int argc, char ** argv)
}
for (j = 0; j < ipcp_len; j++) {
if (wildcard_match(ipcps[i].name, ipcp[j]) == 0) {
- if (irm_unreg(ipcps[i].pid, name)) {
+ if (irm_unreg_name(name, ipcps[i].pid)) {
free(ipcps);
return -1;
}
diff --git a/src/tools/irm/irm_ops.h b/src/tools/irm/irm_ops.h
index 74035434..e04ffc02 100644
--- a/src/tools/irm/irm_ops.h
+++ b/src/tools/irm/irm_ops.h
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Functions of the IRM tool that are one level deep
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -84,8 +84,20 @@ int do_unbind_process(int argc,
int do_unbind_ipcp(int argc,
char ** argv);
-int do_register(int argc,
+int name_cmd(int argc,
+ char ** argv);
+
+int do_create_name(int argc,
+ char ** argv);
+
+int do_destroy_name(int argc,
+ char ** argv);
+
+int do_reg_name(int argc,
char ** argv);
-int do_unregister(int argc,
+int do_unreg_name(int argc,
char ** argv);
+
+int do_list_name(int argc,
+ char ** argv);
diff --git a/src/tools/irm/irm_unbind.c b/src/tools/irm/irm_unbind.c
index f7b078f8..d6594d01 100644
--- a/src/tools/irm/irm_unbind.c
+++ b/src/tools/irm/irm_unbind.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Unbind names in the processing system
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -47,7 +47,7 @@ static void usage(void)
{
printf("Usage: irm unbind [OPERATION]\n"
"\n"
- "where OPERATION = {program process ipcp help}\n");
+ "where OPERATION in {program process ipcp help}\n");
}
static int do_help(int argc,
diff --git a/src/tools/irm/irm_unbind_ipcp.c b/src/tools/irm/irm_unbind_ipcp.c
index 9b2a930a..53a2d16c 100644
--- a/src/tools/irm/irm_unbind_ipcp.c
+++ b/src/tools/irm/irm_unbind_ipcp.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Unbind name from IPCP Instance
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -57,11 +57,11 @@ static void usage(void)
int do_unbind_ipcp(int argc,
char ** argv)
{
- char * ipcp = NULL;
- char * name = NULL;
- struct ipcp_info * ipcps;
- ssize_t len;
- ssize_t i;
+ char * ipcp = NULL;
+ char * name = NULL;
+ struct ipcp_list_info * ipcps;
+ ssize_t len;
+ ssize_t i;
while (argc > 0) {
if (matches(*argv, "name") == 0) {
diff --git a/src/tools/irm/irm_unbind_process.c b/src/tools/irm/irm_unbind_process.c
index 7a1c495d..264ed538 100644
--- a/src/tools/irm/irm_unbind_process.c
+++ b/src/tools/irm/irm_unbind_process.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Unbind process names
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/src/tools/irm/irm_unbind_program.c b/src/tools/irm/irm_unbind_program.c
index 47cf9255..0c751e80 100644
--- a/src/tools/irm/irm_unbind_program.c
+++ b/src/tools/irm/irm_unbind_program.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Unbind programs
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/src/tools/irm/irm_utils.c b/src/tools/irm/irm_utils.c
index c5ea9246..9694d647 100644
--- a/src/tools/irm/irm_utils.c
+++ b/src/tools/irm/irm_utils.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Handy helper functions for the IRM tool
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -109,7 +109,7 @@ int wildcard_match(const char * pattern,
return 0;
/* General case, use recursion. */
- while ((c = *string) != '\0') {
+ while (*string != '\0') {
if (!wildcard_match(pattern, string))
return 0;
++string;
diff --git a/src/tools/irm/irm_utils.h b/src/tools/irm/irm_utils.h
index 03113f12..27a0b941 100644
--- a/src/tools/irm/irm_utils.h
+++ b/src/tools/irm/irm_utils.h
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Handy helper functions for the IRM tool
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/src/tools/obc/CMakeLists.txt b/src/tools/obc/CMakeLists.txt
new file mode 100644
index 00000000..db5e999b
--- /dev/null
+++ b/src/tools/obc/CMakeLists.txt
@@ -0,0 +1,16 @@
+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
+ obc.c
+ )
+
+add_executable(obc ${SOURCE_FILES})
+
+target_link_libraries(obc LINK_PUBLIC ouroboros-dev)
+
+install(TARGETS obc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/src/tools/obc/obc.c b/src/tools/obc/obc.c
new file mode 100644
index 00000000..462cbea9
--- /dev/null
+++ b/src/tools/obc/obc.c
@@ -0,0 +1,155 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * A simple broadcast application
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _POSIX_C_SOURCE 199309L
+
+#include <ouroboros/dev.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define BUF_SIZE 256
+
+static void usage(void)
+{
+ printf("Usage: obc [OPTION]...\n"
+ "Sends a message to a broadcast network\n\n"
+ " -n --name Name of the broadcast layer\n"
+ " -m --message A message to send\n"
+ " [-l, --listen Listen mode]\n"
+ " --help Display this help text and exit\n");
+}
+
+static int reader_main(const char * dst)
+{
+ int fd;
+ char buf[BUF_SIZE];
+
+ printf("Starting a reader.\n");
+
+ fd = flow_join(dst, NULL, NULL);
+ if (fd < 0) {
+ printf("Failed to join broadcast.\n");
+ return -1;
+ }
+
+ printf("New flow.\n");
+
+ while (true) {
+ ssize_t count = flow_read(fd, &buf, BUF_SIZE);
+ if (count < 0) {
+ printf("Failed to read.\n");
+ flow_dealloc(fd);
+ break;
+ }
+
+ printf("Message is %.*s.\n", (int) count, buf);
+ }
+
+ return 0;
+}
+
+static int writer_main(const char * dst,
+ const char * message)
+{
+ int fd = 0;
+ size_t len = strlen(message) + 1;
+
+ fd = flow_join(dst, NULL, NULL);
+ if (fd < 0) {
+ printf("Failed to join broadcast.\n");
+ return -1;
+ }
+
+ if (flow_write(fd, message, len) < 0) {
+ printf("Failed to write packet.\n");
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ flow_dealloc(fd);
+
+ return 0;
+}
+
+int main(int argc,
+ char ** argv)
+{
+ int ret = -1;
+ bool reader = false;
+ char * name = NULL;
+ char * msg = "Ouroboros multicast rocks!";
+
+ argc--;
+ argv++;
+ while (argc > 0) {
+ if (strcmp(*argv, "-l") == 0 ||
+ strcmp(*argv, "--listen") == 0) {
+ reader = true;
+ } else if (strcmp(*argv, "-n") == 0 ||
+ strcmp(*argv, "--name") == 0) {
+ name = *(argv + 1);
+ argc--;
+ argv++;
+ } else if (strcmp(*argv, "-m") == 0 ||
+ strcmp(*argv, "--message") == 0) {
+ msg = *(argv + 1);
+ argc--;
+ argv++;
+ } else {
+ usage();
+ return 0;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (name == NULL) {
+ printf("Please specify a name.\n\n");
+ usage();
+ exit(EXIT_FAILURE);
+ }
+
+ if (reader)
+ ret = reader_main(name);
+ else
+ ret = writer_main(name, msg);
+
+ return ret;
+}
diff --git a/src/tools/ocbr/CMakeLists.txt b/src/tools/ocbr/CMakeLists.txt
index 5dac3e63..f7ba66cd 100644
--- a/src/tools/ocbr/CMakeLists.txt
+++ b/src/tools/ocbr/CMakeLists.txt
@@ -4,6 +4,11 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_BINARY_DIR}/include)
+get_filename_component(CURRENT_SOURCE_PARENT_DIR
+ ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
+
+include_directories(${CURRENT_SOURCE_PARENT_DIR})
+
set(SOURCE_FILES
# Add source files here
ocbr.c
diff --git a/src/tools/ocbr/ocbr.c b/src/tools/ocbr/ocbr.c
index e2bd84af..775bcaac 100644
--- a/src/tools/ocbr/ocbr.c
+++ b/src/tools/ocbr/ocbr.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* CBR traffic generator
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,6 +39,8 @@
#define _POSIX_C_SOURCE 199506L
#define __XSI_VISIBLE 500
+#include "time_utils.h"
+
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
@@ -60,7 +62,7 @@ struct s {
static void usage(void)
{
printf("Usage: cbr [OPTION]...\n"
- "Sends SDUs from client to server at a constant bit rate.\n\n"
+ "Sends packets from client to server at a constant bit rate.\n\n"
" -l, --listen Run in server mode\n"
"\n"
"Server options:\n"
@@ -70,10 +72,11 @@ static void usage(void)
"Client options:\n"
" -n, --server_apn Specify the name of the server.\n"
" -d, --duration Duration for sending (s)\n"
- " -f, --flood Send SDUs as fast as possible\n"
- " -s, --size SDU size (B, max %ld B)\n"
+ " -f, --flood Send packets as fast as possible\n"
+ " -s, --size packet size (B, max %ld B)\n"
" -r, --rate Rate (b/s)\n"
- " --sleep Sleep in between sending SDUs\n"
+ " --sleep Sleep in between sending packets\n"
+ " --spin Spin CPU between sending packets\n"
"\n\n"
" --help Display this help text and exit\n",
BUF_SIZE);
@@ -82,10 +85,10 @@ static void usage(void)
int main(int argc, char ** argv)
{
int duration = 60; /* One minute test */
- int size = 1000; /* 1000 byte SDUs */
+ int size = 1000; /* 1000 byte packets */
long rate = 1000000; /* 1 Mb/s */
bool flood = false;
- bool sleep = false;
+ bool sleep = true;
int ret = 0;
char * rem = NULL;
char * s_apn = NULL;
@@ -136,6 +139,8 @@ int main(int argc, char ** argv)
flood = true;
} else if (strcmp(*argv, "--sleep") == 0) {
sleep = true;
+ } else if (strcmp(*argv, "--spin") == 0) {
+ sleep = false;
} else {
usage();
return 0;
@@ -150,17 +155,22 @@ int main(int argc, char ** argv)
if (s_apn == NULL) {
printf("No server specified.\n");
usage();
- return 0;
+ return 1;
}
if (size > BUF_SIZE) {
printf("Maximum size: %ld.\n", BUF_SIZE);
- return 0;
+ return 1;
}
if (size < 0) {
printf("Size overflow.\n");
- return 0;
+ return 1;
+ }
+
+ if (rate <= 0) {
+ printf("Invalid rate.\n");
+ return 1;
}
ret = client_main(s_apn, duration, size, rate, flood, sleep);
diff --git a/src/tools/ocbr/ocbr_client.c b/src/tools/ocbr/ocbr_client.c
index 026ab001..ba7b41f4 100644
--- a/src/tools/ocbr/ocbr_client.c
+++ b/src/tools/ocbr/ocbr_client.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* A simple CBR generator
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,7 +37,6 @@
*/
#include <ouroboros/dev.h>
-#include <ouroboros/time_utils.h>
#include <signal.h>
@@ -136,7 +135,7 @@ int client_main(char * server,
} else { /* flood */
while (!stop) {
clock_gettime(CLOCK_REALTIME, &end);
- if (flow_write(fd, buf, (size_t) size) < 0) {
+ if (flow_write(fd, buf, size) < 0) {
stop = true;
continue;
}
@@ -155,7 +154,7 @@ int client_main(char * server,
ms = ts_diff_ms(&start, &end);
printf("sent statistics: "
- "%9ld SDUs, %12ld bytes in %9d ms, %4.4f Mb/s\n",
+ "%9ld packets, %12ld bytes in %9d ms, %4.4f Mb/s\n",
seqnr, seqnr * size, ms, (seqnr / (ms * 1000.0)) * size * 8.0);
flow_dealloc(fd);
diff --git a/src/tools/ocbr/ocbr_server.c b/src/tools/ocbr/ocbr_server.c
index 4f080eff..a4bbadd4 100644
--- a/src/tools/ocbr/ocbr_server.c
+++ b/src/tools/ocbr/ocbr_server.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* A simple CBR generator
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,7 +37,6 @@
*/
#include <ouroboros/dev.h>
-#include <ouroboros/time_utils.h>
#include <ouroboros/fccntl.h>
#include <stdbool.h>
@@ -84,14 +83,15 @@ static void handle_flow(int fd)
struct timespec now;
struct timespec alive;
struct timespec intv = {server_settings.interval, 0};
+ struct timespec tic = {0, 100 * MILLION};
struct timespec iv_start;
struct timespec iv_end;
bool stop = false;
- long sdus = 0;
- long sdus_intv = 0;
+ long packets = 0;
+ long packets_intv = 0;
long bytes_read = 0;
long bytes_read_intv = 0;
@@ -100,7 +100,8 @@ static void handle_flow(int fd)
alive = iv_start;
ts_add(&iv_start, &intv, &iv_end);
- fccntl(fd, FLOWSFLAGS, FLOWFRNOBLOCK | FLOWFRDWR | FLOWFRNOPART);
+ fccntl(fd, FLOWSFLAGS, FLOWFRDWR | FLOWFRNOPART);
+ fccntl(fd, FLOWSRCVTIMEO, &tic);
while (!stop) {
clock_gettime(CLOCK_REALTIME, &now);
@@ -109,7 +110,7 @@ static void handle_flow(int fd)
if (count > 0) {
clock_gettime(CLOCK_REALTIME, &alive);
- sdus++;
+ packets++;
bytes_read += count;
}
@@ -121,17 +122,18 @@ static void handle_flow(int fd)
if (stop || ts_diff_ms(&now, &iv_end) < 0) {
long us = ts_diff_us(&iv_start, &now);
- printf("Flow %4d: %9ld SDUs (%12ld bytes) in %9ld ms"
- " => %9.4f p/s, %9.4f Mb/s\n",
+ printf("Flow %4d: %9ld packets (%12ld bytes) in %9ld ms"
+ " => %9.4f pps, %9.4f Mbps\n",
fd,
- sdus - sdus_intv,
+ packets - packets_intv,
bytes_read - bytes_read_intv,
us / 1000,
- ((sdus - sdus_intv) / (double) us) * MILLION,
+ ((packets - packets_intv) / (double) us)
+ * MILLION,
8 * ((bytes_read - bytes_read_intv)
/ (double)(us)));
iv_start = iv_end;
- sdus_intv = sdus;
+ packets_intv = packets;
bytes_read_intv = bytes_read;
ts_add(&iv_start, &intv, &iv_end);
}
@@ -140,6 +142,11 @@ static void handle_flow(int fd)
flow_dealloc(fd);
}
+static void __cleanup_mutex_unlock(void * mutex)
+{
+ pthread_mutex_unlock((pthread_mutex_t *) mutex);
+}
+
static void * worker(void * o)
{
int cli_fd;
@@ -148,8 +155,7 @@ static void * worker(void * o)
while (true) {
pthread_mutex_lock(&fds_lock);
- pthread_cleanup_push((void(*)(void *)) pthread_mutex_unlock,
- (void *) &fds_lock);
+ pthread_cleanup_push(__cleanup_mutex_unlock, &fds_lock);
while (fds[fds_index] == -1)
pthread_cond_wait(&fds_signal, &fds_lock);
@@ -182,8 +188,7 @@ static void * listener(void * o)
while (true) {
pthread_mutex_lock(&fds_lock);
- pthread_cleanup_push((void(*)(void *)) pthread_mutex_unlock,
- (void *) &fds_lock);
+ pthread_cleanup_push(__cleanup_mutex_unlock, &fds_lock);
while (fds_count == THREADS_SIZE) {
printf("Can't accept any more flows, waiting.\n");
diff --git a/src/tools/oecho/oecho.c b/src/tools/oecho/oecho.c
index cc173988..d5d03027 100644
--- a/src/tools/oecho/oecho.c
+++ b/src/tools/oecho/oecho.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* A simple echo application
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -72,15 +72,15 @@ static int server_main(void)
count = flow_read(fd, &buf, BUF_SIZE);
if (count < 0) {
- printf("Failed to read SDU.\n");
+ printf("Failed to read packet.\n");
flow_dealloc(fd);
continue;
}
printf("Message from client is %.*s.\n", (int) count, buf);
- if (flow_write(fd, buf, count) == -1) {
- printf("Failed to write SDU.\n");
+ if (flow_write(fd, buf, count) < 0) {
+ printf("Failed to write packet.\n");
flow_dealloc(fd);
continue;
}
@@ -93,10 +93,10 @@ static int server_main(void)
static int client_main(void)
{
- int fd = 0;
+ int fd;
char buf[BUF_SIZE];
char * message = "Client says hi!";
- ssize_t count = 0;
+ ssize_t count;
fd = flow_alloc("oecho", NULL, NULL);
if (fd < 0) {
@@ -105,14 +105,14 @@ static int client_main(void)
}
if (flow_write(fd, message, strlen(message) + 1) < 0) {
- printf("Failed to write SDU.\n");
+ printf("Failed to write packet.\n");
flow_dealloc(fd);
return -1;
}
count = flow_read(fd, buf, BUF_SIZE);
if (count < 0) {
- printf("Failed to read SDU.\n");
+ printf("Failed to read packet.\n");
flow_dealloc(fd);
return -1;
}
diff --git a/src/tools/operf/operf.c b/src/tools/operf/operf.c
index fe387724..10896bd5 100644
--- a/src/tools/operf/operf.c
+++ b/src/tools/operf/operf.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Ouroboros perf application
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -62,19 +62,32 @@
#define OPERF_MAX_FLOWS 256
+#define TEST_TYPE_UNI 0
+#define TEST_TYPE_BI 1
+
+struct conf {
+ uint32_t test_type;
+} __attribute__((packed));
+
+struct msg {
+ uint32_t id;
+} __attribute__((packed));
+
struct c {
- char * s_apn;
- int size;
+ char * server_name;
long rate;
bool flood;
bool sleep;
int duration;
+ int size;
unsigned long sent;
unsigned long rcvd;
pthread_t reader_pt;
pthread_t writer_pt;
+
+ struct conf conf;
} client;
struct s {
@@ -82,6 +95,7 @@ struct s {
fset_t * flows;
fqueue_t * fq;
pthread_mutex_t lock;
+ struct conf conf[OPERF_MAX_FLOWS];
uint8_t buffer[OPERF_BUF_SIZE];
ssize_t timeout;
@@ -99,26 +113,62 @@ static void usage(void)
printf("Usage: operf [OPTION]...\n"
"Measures bandwidth between a client and a server\n"
" -l, --listen Run in server mode\n"
- "\n"
- " -n, --server-apn Name of the operf server\n"
- " -d, --duration Test duration (s, default 60)\n"
+ " -t, --test The type of test [uni, bi]"
+ " (default uni)\n"
+ " -n, --server-name Name of the operf server\n"
+ " -d, --duration Test duration (default 60s)\n"
" -r, --rate Rate (b/s)\n"
" -s, --size Payload size (B, default 1500)\n"
- " -f, --flood Send SDUs as fast as possible\n"
- " --sleep Sleep in between sending SDUs\n"
+ " -f, --flood Send packets as fast as possible\n"
+ " --sleep Sleep in between sending packets\n"
+ "\n"
" --help Display this help text and exit\n");
}
+/* Times are in ms. */
+static int time_mul(const char * rem)
+{
+ if (strcmp(rem, "ms") == 0 || strcmp(rem, "") == 0)
+ return 1;
+ else if(strcmp(rem, "s") == 0)
+ return 1000;
+ else if (strcmp(rem, "m") == 0)
+ return 60 * 1000;
+ else if (strcmp(rem, "h") == 0)
+ return 60 * 60 * 1000;
+ else if (strcmp(rem, "d") == 0)
+ return 60 * 60 * 24 * 1000;
+
+ printf("Unknown time unit: %s.\n", rem);
+
+ exit(EXIT_FAILURE);
+}
+
+static int rate_mul(const char * rem)
+{
+ if (strcmp(rem, "k") == 0 || strcmp(rem, "") == 0)
+ return 1000;
+ else if(strcmp(rem, "M") == 0)
+ return MILLION;
+ else if (strcmp(rem, "G") == 0)
+ return BILLION;
+
+ printf("Unknown rate unit: %s.\n", rem);
+
+ exit(EXIT_FAILURE);
+}
+
int main(int argc, char ** argv)
{
- int ret = -1;
- char * rem = NULL;
- bool serv = false;
+ int ret = -1;
+ char * rem = NULL;
+ bool serv = false;
+ char * type = "uni";
argc--;
argv++;
- client.s_apn = NULL;
+ client.server_name = NULL;
client.size = 1500;
client.duration = 60000;
server.timeout = 1000; /* ms */
@@ -128,8 +178,8 @@ int main(int argc, char ** argv)
while (argc > 0) {
if (strcmp(*argv, "-n") == 0 ||
- strcmp(*argv, "--server_apn") == 0) {
- client.s_apn = *(++argv);
+ strcmp(*argv, "--server-name") == 0) {
+ client.server_name = *(++argv);
--argc;
} else if (strcmp(*argv, "-s") == 0 ||
strcmp(*argv, "--size") == 0) {
@@ -137,17 +187,13 @@ int main(int argc, char ** argv)
--argc;
} else if (strcmp(*argv, "-d") == 0 ||
strcmp(*argv, "--duration") == 0) {
- client.duration = strtol(*(++argv), &rem, 10) * 1000;
+ client.duration = strtol(*(++argv), &rem, 10);
+ client.duration *= time_mul(rem);
--argc;
} else if (strcmp(*argv, "-r") == 0 ||
strcmp(*argv, "--rate") == 0) {
client.rate = strtol(*(++argv), &rem, 10);
- if (*rem == 'k')
- client.rate *= 1000;
- if (*rem == 'M')
- client.rate *= MILLION;
- if (*rem == 'G')
- client.rate *= BILLION;
+ client.rate *= rate_mul(rem);
--argc;
} else if (strcmp(*argv, "-f") == 0 ||
strcmp(*argv, "--flood") == 0) {
@@ -157,6 +203,10 @@ int main(int argc, char ** argv)
} else if (strcmp(*argv, "-l") == 0 ||
strcmp(*argv, "--listen") == 0) {
serv = true;
+ } else if (strcmp(*argv, "-t") == 0 ||
+ strcmp(*argv, "--test") == 0) {
+ type = *(++argv);
+ --argc;
} else {
usage();
exit(EXIT_SUCCESS);
@@ -168,11 +218,20 @@ int main(int argc, char ** argv)
if (serv) {
ret = server_main();
} else {
- if (client.s_apn == NULL) {
+ if (client.server_name == NULL) {
printf("No server specified.\n");
- usage();
- exit(EXIT_SUCCESS);
+ exit(EXIT_FAILURE);
}
+
+ if (strcmp(type, "uni") == 0)
+ client.conf.test_type = TEST_TYPE_UNI;
+ else if (strcmp(type, "bi") == 0)
+ client.conf.test_type = TEST_TYPE_BI;
+ else {
+ printf("Invalid test type.\n");
+ exit(EXIT_FAILURE);
+ }
+
if (client.size > OPERF_BUF_SIZE) {
printf("Packet size truncated to %d bytes.\n",
OPERF_BUF_SIZE);
diff --git a/src/tools/operf/operf_client.c b/src/tools/operf/operf_client.c
index 1518bdf5..63f98299 100644
--- a/src/tools/operf/operf_client.c
+++ b/src/tools/operf/operf_client.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Ouroboros ping application
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,6 +36,8 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+bool stop;
+
static void busy_wait_until(const struct timespec * deadline)
{
struct timespec now;
@@ -45,7 +47,6 @@ static void busy_wait_until(const struct timespec * deadline)
while (now.tv_sec == deadline->tv_sec
&& now.tv_nsec < deadline->tv_nsec)
clock_gettime(CLOCK_REALTIME, &now);
- pthread_testcancel();
}
void shutdown_client(int signo, siginfo_t * info, void * c)
@@ -57,8 +58,7 @@ void shutdown_client(int signo, siginfo_t * info, void * c)
case SIGINT:
case SIGTERM:
case SIGHUP:
- pthread_cancel(client.reader_pt);
- pthread_cancel(client.writer_pt);
+ stop = true;
default:
return;
}
@@ -74,7 +74,14 @@ void * reader(void * o)
fccntl(fd, FLOWSRCVTIMEO, &timeout);
- while ((msg_len = flow_read(fd, buf, OPERF_BUF_SIZE)) != -ETIMEDOUT) {
+ while (!stop) {
+ msg_len = flow_read(fd, buf, OPERF_BUF_SIZE);
+ if (msg_len == -ETIMEDOUT) {
+ printf("Server timed out.\n");
+ stop = true;
+ break;
+ }
+
if (msg_len != client.size) {
printf("Invalid message on fd %d.\n", fd);
continue;
@@ -96,62 +103,64 @@ void * writer(void * o)
struct timespec intv = {(gap / BILLION), gap % BILLION};
struct timespec end = {0, 0};
- char * buf = malloc(client.size);
+ char * buf;
+ struct msg * msg;
+
+ buf = malloc(client.size);
if (buf == NULL)
return (void *) -ENOMEM;
- if (fdp == NULL)
+ if (fdp == NULL) {
+ free(buf);
return (void *) -EINVAL;
+ }
memset(buf, 0, client.size);
+ msg = (struct msg *) buf;
+
if (client.flood)
- printf("Flooding %s with %d byte SDUs for %d seconds.\n\n",
- client.s_apn, client.size, client.duration / 1000);
+ printf("Flooding %s with %d byte packets for %d seconds.\n\n",
+ client.server_name, client.size,
+ client.duration / 1000);
else
- printf("Sending %d byte SDUs for %d s to %s at %.3lf Mb/s.\n\n",
- client.size, client.duration / 1000, client.s_apn,
+ printf("Sending %d byte packets for %d s to %s "
+ "at %.3lf Mb/s.\n\n",
+ client.size, client.duration / 1000,
+ client.server_name,
client.rate / (double) MILLION);
clock_gettime(CLOCK_REALTIME, &start);
clock_gettime(CLOCK_REALTIME, &now);
- pthread_cleanup_push((void (*) (void *)) free, buf);
-
- if (client.flood) {
- while (ts_diff_ms(&start, &now) < client.duration) {
- if (flow_write(*fdp, buf, client.size) == -1) {
- printf("Failed to send SDU.\n");
- flow_dealloc(*fdp);
- free(buf);
- return (void *) -1;
- }
+ while (!stop && ts_diff_ms(&start, &now) < client.duration) {
+ if (!client.flood) {
+ clock_gettime(CLOCK_REALTIME, &now);
+ ts_add(&now, &intv, &end);
+ }
- ++client.sent;
+ msg->id = client.sent;
- clock_gettime(CLOCK_REALTIME, &now);
+ if (flow_write(*fdp, buf, client.size) < 0) {
+ printf("Failed to send packet.\n");
+ flow_dealloc(*fdp);
+ free(buf);
+ return (void *) -1;
}
- } else {
- while (ts_diff_ms(&start, &now) < client.duration) {
- clock_gettime(CLOCK_REALTIME, &now);
- ts_add(&now, &intv, &end);
- if (flow_write(*fdp, buf, client.size) == -1) {
- printf("Failed to send SDU.\n");
- flow_dealloc(*fdp);
- free(buf);
- return (void *) -1;
- }
+ ++client.sent;
- ++client.sent;
+ if (!client.flood) {
if (client.sleep)
nanosleep(&intv, NULL);
else
busy_wait_until(&end);
+ } else {
+ clock_gettime(CLOCK_REALTIME, &now);
}
}
- pthread_cleanup_pop(true);
+ free(buf);
printf("Test finished.\n");
@@ -181,34 +190,51 @@ int client_main(void)
client.sent = 0;
client.rcvd = 0;
+ stop = false;
- fd = flow_alloc(client.s_apn, NULL, NULL);
+ /* FIXME: Allow selecting QoS. */
+ fd = flow_alloc(client.server_name, NULL, NULL);
if (fd < 0) {
printf("Failed to allocate flow.\n");
return -1;
}
- clock_gettime(CLOCK_REALTIME, &tic);
+ if (client.conf.test_type == TEST_TYPE_BI)
+ printf("Doing a bidirectional test.\n");
+ else
+ printf("Doing a unidirectional test.\n");
- pthread_create(&client.reader_pt, NULL, reader, &fd);
- pthread_create(&client.writer_pt, NULL, writer, &fd);
+ if (flow_write(fd, &client.conf, sizeof(client.conf)) < 0) {
+ printf("Failed to send configuration.\n");
+ flow_dealloc(fd);
+ return -1;
+ }
- pthread_join(client.writer_pt, NULL);
+ sleep(1);
+
+ clock_gettime(CLOCK_REALTIME, &tic);
- clock_gettime(CLOCK_REALTIME, &toc);
+ if (client.conf.test_type == TEST_TYPE_BI)
+ pthread_create(&client.reader_pt, NULL, reader, &fd);
- pthread_join(client.reader_pt, NULL);
+ pthread_create(&client.writer_pt, NULL, writer, &fd);
+ pthread_join(client.writer_pt, NULL);
- printf("\n");
- printf("--- %s perf statistics ---\n", client.s_apn);
- printf("%ld SDUs transmitted, ", client.sent);
- printf("%ld received, ", client.rcvd);
- printf("%ld%% packet loss, ", client.sent == 0 ? 0 :
- 100 - ((100 * client.rcvd) / client.sent));
- printf("time: %.3f ms, ", ts_diff_us(&tic, &toc) / 1000.0);
- printf("bandwidth: %.3lf Mb/s.\n",
- (client.rcvd * client.size * 8)
- / (double) ts_diff_us(&tic, &toc));
+ if (client.conf.test_type == TEST_TYPE_BI){
+ clock_gettime(CLOCK_REALTIME, &toc);
+ pthread_join(client.reader_pt, NULL);
+
+ printf("\n");
+ printf("--- %s perf statistics ---\n", client.server_name);
+ printf("%ld packets transmitted, ", client.sent);
+ printf("%ld received, ", client.rcvd);
+ printf("%ld%% packet loss, ", client.sent == 0 ? 0 :
+ 100 - ((100 * client.rcvd) / client.sent));
+ printf("time: %.3f ms, ", ts_diff_us(&tic, &toc) / 1000.0);
+ printf("bandwidth: %.3lf Mb/s.\n",
+ (client.rcvd * client.size * 8)
+ / (double) ts_diff_us(&tic, &toc));
+ }
flow_dealloc(fd);
diff --git a/src/tools/operf/operf_server.c b/src/tools/operf/operf_server.c
index 11eb92fc..d11f3486 100644
--- a/src/tools/operf/operf_server.c
+++ b/src/tools/operf/operf_server.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Ouroboros perf application
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,6 +36,8 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+bool stop;
+
void shutdown_server(int signo, siginfo_t * info, void * c)
{
(void) info;
@@ -46,6 +48,7 @@ void shutdown_server(int signo, siginfo_t * info, void * c)
case SIGTERM:
case SIGHUP:
pthread_cancel(server.accept_pt);
+ stop = true;
default:
return;
}
@@ -58,7 +61,7 @@ void * cleaner_thread(void * o)
(void) o;
- while (true) {
+ while (!stop) {
clock_gettime(CLOCK_REALTIME, &now);
pthread_mutex_lock(&server.lock);
for (i = 0; i < OPERF_MAX_FLOWS; ++i)
@@ -73,18 +76,21 @@ void * cleaner_thread(void * o)
pthread_mutex_unlock(&server.lock);
sleep(1);
}
+
+ return (void *) 0;
}
-void * server_thread(void *o)
+void * server_thread(void * o)
{
- int msg_len = 0;
+ int msg_len = 0;
struct timespec timeout = {0, 100 * MILLION};
- struct timespec now = {0, 0};
- int fd;
+ struct timespec now = {0, 0};
+ int fd;
+ struct msg * msg;
(void) o;
- while (fevent(server.flows, server.fq, &timeout))
+ while (!stop && fevent(server.flows, server.fq, &timeout))
while ((fd = fqueue_next(server.fq)) >= 0) {
msg_len = flow_read(fd, server.buffer, OPERF_BUF_SIZE);
if (msg_len < 0)
@@ -96,9 +102,21 @@ void * server_thread(void *o)
server.times[fd] = now;
pthread_mutex_unlock(&server.lock);
- if (flow_write(fd, server.buffer, msg_len) < 0) {
- printf("Error writing to flow (fd %d).\n", fd);
- flow_dealloc(fd);
+ msg = (struct msg *) server.buffer;
+
+ if (server.conf[fd].test_type == TEST_TYPE_UNI)
+ printf("Seqno %d from fd %d: %zd.%06zu\n",
+ msg->id, fd,
+ (ssize_t) now.tv_sec,
+ (size_t) now.tv_nsec / 1000);
+
+ if (server.conf[fd].test_type == TEST_TYPE_BI) {
+ if (flow_write(fd, server.buffer,
+ msg_len) < 0) {
+ printf("Error writing to flow "
+ "(fd %d).\n", fd);
+ flow_dealloc(fd);
+ }
}
}
@@ -110,12 +128,13 @@ void * accept_thread(void * o)
int fd = 0;
struct timespec now = {0, 0};
qosspec_t qs;
+ int len = 0;
(void) o;
printf("Ouroboros perf server started.\n");
- while (true) {
+ while (!stop) {
fd = flow_accept(&qs, NULL);
if (fd < 0) {
printf("Failed to accept flow.\n");
@@ -124,6 +143,27 @@ void * accept_thread(void * o)
printf("New flow %d.\n", fd);
+ /* Read test type. */
+ len = flow_read(fd, &(server.conf[fd]),
+ sizeof(server.conf[fd]));
+ if (len == -ETIMEDOUT) {
+ printf("Failed to read config message.\n");
+ flow_dealloc(fd);
+ break;
+ }
+
+ /* Check if length was correct. */
+ if (flow_read(fd, NULL, 0) != 0) {
+ printf("Invalid config message.\n");
+ flow_dealloc(fd);
+ break;
+ }
+
+ if (server.conf[fd].test_type == TEST_TYPE_BI)
+ printf("Doing a bidirectional test.\n");
+ else
+ printf("Doing a unidirectional test.\n");
+
clock_gettime(CLOCK_REALTIME, &now);
pthread_mutex_lock(&server.lock);
@@ -161,20 +201,19 @@ int server_main(void)
return -1;
}
+ stop = false;
+
pthread_create(&server.cleaner_pt, NULL, cleaner_thread, NULL);
pthread_create(&server.accept_pt, NULL, accept_thread, NULL);
pthread_create(&server.server_pt, NULL, server_thread, NULL);
pthread_join(server.accept_pt, NULL);
- pthread_cancel(server.server_pt);
- pthread_cancel(server.cleaner_pt);
+ pthread_join(server.server_pt, NULL);
+ pthread_join(server.cleaner_pt, NULL);
fset_destroy(server.flows);
fqueue_destroy(server.fq);
- pthread_join(server.server_pt, NULL);
- pthread_join(server.cleaner_pt, NULL);
-
return 0;
}
diff --git a/src/tools/oping/oping.c b/src/tools/oping/oping.c
index 3c1d4fe9..ed3529e5 100644
--- a/src/tools/oping/oping.c
+++ b/src/tools/oping/oping.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Ouroboros ping application
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,9 +42,11 @@
#include <ouroboros/dev.h>
#include <ouroboros/fccntl.h>
#include <ouroboros/fqueue.h>
+#include <ouroboros/qos.h>
#include "time_utils.h"
+#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
@@ -58,22 +60,43 @@
#include <errno.h>
#include <float.h>
-#define OPING_BUF_SIZE 1500
-
-#define ECHO_REQUEST 0
-#define ECHO_REPLY 1
-
+#define OPING_BUF_SIZE 1500
+#define ECHO_REQUEST 0
+#define ECHO_REPLY 1
#define OPING_MAX_FLOWS 256
-struct c {
- char * s_apn;
- int interval;
- uint32_t count;
- int size;
+#define USAGE_STRING \
+"Usage: oping [OPTION]...\n" \
+"\n" \
+"Checks liveness between a client and a server\n" \
+"and reports the Round Trip Time (RTT)\n" \
+"\n" \
+" -l, --listen Run in server mode\n" \
+"\n" \
+" -c, --count Number of packets\n" \
+" -d, --duration Duration of the test (default 1s)\n" \
+" -i, --interval Interval (default 1000ms)\n" \
+" -n, --server-name Name of the oping server\n" \
+" -q, --qos QoS (raw, raw_crypt, best, video, voice, data)\n" \
+" -s, --size Payload size (B, default 64)\n" \
+" -Q, --quiet Only print final statistics\n" \
+" -D, --timeofday Print time of day before each line\n" \
+"\n" \
+" --help Display this help text and exit\n" \
+
+struct {
+ char * s_apn;
+ int interval;
+ uint32_t count;
+ int size;
+ bool timestamp;
+ qosspec_t qs;
/* stats */
uint32_t sent;
uint32_t rcvd;
+ size_t ooo;
+ bool quiet;
double rtt_min;
double rtt_max;
@@ -84,12 +107,14 @@ struct c {
pthread_t writer_pt;
} client;
-struct s {
+struct {
struct timespec times[OPING_MAX_FLOWS];
fset_t * flows;
fqueue_t * fq;
pthread_mutex_t lock;
+ bool quiet;
+
pthread_t cleaner_pt;
pthread_t accept_pt;
pthread_t server_pt;
@@ -108,67 +133,130 @@ struct oping_msg {
static void usage(void)
{
- printf("Usage: oping [OPTION]...\n"
- "Checks liveness between a client and a server\n"
- "and reports the Round Trip Time (RTT)\n\n"
- " -l, --listen Run in server mode\n"
- "\n"
- " -c, --count Number of packets (default 1000)\n"
- " -i, --interval Interval (ms, default 1000)\n"
- " -n, --server-apn Name of the oping server\n"
- " -s, --size Payload size (B, default 64)\n"
- " --help Display this help text and exit\n");
+ printf(USAGE_STRING);
+}
+
+/* Times are in ms. */
+static int time_mul(const char * rem)
+{
+ if (strcmp(rem, "ms") == 0 || strcmp(rem, "") == 0)
+ return 1;
+ else if(strcmp(rem, "s") == 0)
+ return 1000;
+ else if (strcmp(rem, "m") == 0)
+ return 60 * 1000;
+ else if (strcmp(rem, "h") == 0)
+ return 60 * 60 * 1000;
+ else if (strcmp(rem, "d") == 0)
+ return 60 * 60 * 24 * 1000;
+
+ printf("Unknown time unit: %s.\n", rem);
+
+ exit(EXIT_FAILURE);
}
-int main(int argc, char ** argv)
+int main(int argc,
+ char ** argv)
{
- int ret = -1;
- char * rem = NULL;
- bool serv = false;
+ int ret = -1;
+ char * rem = NULL;
+ bool serv = false;
+ long duration = 0;
+ char * qos = NULL;
argc--;
argv++;
- client.s_apn = NULL;
- client.interval = 1000;
- client.size = 64;
- client.count = 1000;
+ client.s_apn = NULL;
+ client.interval = 1000;
+ client.size = 64;
+ client.count = INT_MAX;
+ client.timestamp = false;
+ client.qs = qos_raw;
+ client.quiet = false;
+ server.quiet = false;
while (argc > 0) {
- if (strcmp(*argv, "-i") == 0 ||
- strcmp(*argv, "--interval") == 0) {
+ if ((strcmp(*argv, "-i") == 0 ||
+ strcmp(*argv, "--interval") == 0) &&
+ argc > 1) {
client.interval = strtol(*(++argv), &rem, 10);
+ client.interval *= time_mul(rem);
--argc;
- } else if (strcmp(*argv, "-n") == 0 ||
- strcmp(*argv, "--server_apn") == 0) {
+ } else if ((strcmp(*argv, "-n") == 0 ||
+ strcmp(*argv, "--server-name") == 0) &&
+ argc > 1) {
client.s_apn = *(++argv);
--argc;
- } else if (strcmp(*argv, "-c") == 0 ||
- strcmp(*argv, "--count") == 0) {
+ } else if ((strcmp(*argv, "-c") == 0 ||
+ strcmp(*argv, "--count") == 0) &&
+ argc > 1) {
client.count = strtol(*(++argv), &rem, 10);
--argc;
- } else if (strcmp(*argv, "-s") == 0 ||
- strcmp(*argv, "--size") == 0) {
+ } else if ((strcmp(*argv, "-d") == 0 ||
+ strcmp(*argv, "--duration") == 0) &&
+ argc > 1) {
+ duration = strtol(*(++argv), &rem, 10);
+ duration *= time_mul(rem);
+ --argc;
+ } else if ((strcmp(*argv, "-s") == 0 ||
+ strcmp(*argv, "--size") == 0) &&
+ argc > 1) {
client.size = strtol(*(++argv), &rem, 10);
--argc;
+ } else if ((strcmp(*argv, "-q") == 0 ||
+ strcmp(*argv, "--qos") == 0) &&
+ argc > 1) {
+ qos = *(++argv);
+ --argc;
} else if (strcmp(*argv, "-l") == 0 ||
strcmp(*argv, "--listen") == 0) {
serv = true;
+ } else if (strcmp(*argv, "-D") == 0 ||
+ strcmp(*argv, "--timeofday") == 0) {
+ client.timestamp = true;
+ } else if (strcmp(*argv, "-Q") == 0 ||
+ strcmp(*argv, "--quiet") == 0) {
+ client.quiet = true;
+ server.quiet = true;
} else {
- usage();
- exit(EXIT_SUCCESS);
+ goto fail;
}
argc--;
argv++;
}
+ if (duration > 0) {
+ if (client.interval == 0)
+ client.count = duration * 10;
+ else
+ client.count = duration / client.interval;
+ }
+
+ if (qos != NULL) {
+ if (strcmp(qos, "best") == 0)
+ client.qs = qos_best_effort;
+ else if (strcmp(qos, "raw") == 0)
+ client.qs = qos_raw;
+ else if (strcmp(qos, "video") == 0)
+ client.qs = qos_video;
+ else if (strcmp(qos, "voice") == 0)
+ client.qs = qos_voice;
+ else if (strcmp(qos, "data") == 0)
+ client.qs = qos_data;
+ else if (strcmp(qos, "raw_crypt") == 0)
+ client.qs = qos_raw_crypt;
+ else
+ printf("Unknown QoS cube, defaulting to raw.\n");
+ }
+
if (serv) {
ret = server_main();
} else {
if (client.s_apn == NULL) {
printf("No server specified.\n");
usage();
- exit(EXIT_SUCCESS);
+ exit(EXIT_FAILURE);
}
if (client.interval > 10000) {
printf("Ping interval truncated to 10s.\n");
@@ -179,7 +267,6 @@ int main(int argc, char ** argv)
OPING_BUF_SIZE);
client.size = OPING_BUF_SIZE;
}
-
if (client.size < 64) {
printf("Packet size set to 64 bytes.\n");
client.size = 64;
@@ -192,4 +279,8 @@ int main(int argc, char ** argv)
exit(EXIT_FAILURE);
exit(EXIT_SUCCESS);
+
+ fail:
+ usage();
+ exit(EXIT_FAILURE);
}
diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c
index 6f874dd9..7b03c83d 100644
--- a/src/tools/oping/oping_client.c
+++ b/src/tools/oping/oping_client.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Ouroboros ping application
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -65,10 +65,13 @@ void * reader(void * o)
int msg_len = 0;
double ms = 0;
double d = 0;
+ uint32_t exp_id = 0;
fccntl(fd, FLOWSRCVTIMEO, &timeout);
while (!stop && client.rcvd != client.count) {
+ uint32_t id;
+
msg_len = flow_read(fd, buf, OPING_BUF_SIZE);
if (msg_len == -ETIMEDOUT) {
printf("Server timed out.\n");
@@ -84,7 +87,8 @@ void * reader(void * o)
continue;
}
- if ((uint32_t) ntohl(msg->id) >= client.count) {
+ id = (uint32_t) ntohl(msg->id);
+ if (id >= client.count) {
printf("Invalid id.\n");
continue;
}
@@ -98,11 +102,25 @@ void * reader(void * o)
ms = ts_diff_us(&sent, &now) / 1000.0;
- printf("%d bytes from %s: seq=%d time=%.3f ms\n",
- msg_len,
- client.s_apn,
- ntohl(msg->id),
- ms);
+ if (id < exp_id)
+ ++client.ooo;
+
+ if (!client.quiet) {
+ if (client.timestamp) {
+ struct timespec rtc;
+ clock_gettime(CLOCK_REALTIME, &rtc);
+ printf("[%zd.%06zu] ",
+ (ssize_t) rtc.tv_sec,
+ (size_t) rtc.tv_nsec / 1000);
+ }
+
+ printf("%d bytes from %s: seq=%d time=%.3f ms%s\n",
+ msg_len,
+ client.s_apn,
+ ntohl(msg->id),
+ ms,
+ id < exp_id ? " [out-of-order]" : "");
+ }
if (ms < client.rtt_min)
client.rtt_min = ms;
@@ -112,6 +130,9 @@ void * reader(void * o)
d = (ms - client.rtt_avg);
client.rtt_avg += d / client.rcvd;
client.rtt_m2 += d * (ms - client.rtt_avg);
+
+ if (id >= exp_id)
+ exp_id = id + 1;
}
return (void *) 0;
@@ -129,17 +150,20 @@ void * writer(void * o)
if (buf == NULL)
return (void *) -ENOMEM;
- if (fdp == NULL)
+ if (fdp == NULL) {
+ free(buf);
return (void *) -EINVAL;
+ }
memset(buf, 0, client.size);
msg = (struct oping_msg *) buf;
- printf("Pinging %s with %d bytes of data:\n\n",
- client.s_apn, client.size);
+ if (!client.quiet)
+ printf("Pinging %s with %d bytes of data (%u packets):\n\n",
+ client.s_apn, client.size, client.count);
- pthread_cleanup_push((void (*) (void *)) free, buf);
+ pthread_cleanup_push(free, buf);
while (!stop && client.sent < client.count) {
nanosleep(&wait, NULL);
@@ -151,11 +175,9 @@ void * writer(void * o)
msg->tv_sec = now.tv_sec;
msg->tv_nsec = now.tv_nsec;
- if (flow_write(*fdp, buf, client.size) == -1) {
- printf("Failed to send SDU.\n");
- flow_dealloc(*fdp);
- free(buf);
- return (void *) -1;
+ if (flow_write(*fdp, buf, client.size) < 0) {
+ printf("Failed to send packet.\n");
+ stop = true;
}
}
@@ -208,13 +230,15 @@ static int client_main(void)
return -1;
}
- fd = flow_alloc(client.s_apn, NULL, NULL);
+ fd = flow_alloc(client.s_apn, &client.qs, NULL);
if (fd < 0) {
- printf("Failed to allocate flow.\n");
+ printf("Failed to allocate flow: %d.\n", fd);
client_fini();
return -1;
}
+ fccntl(fd, FLOWSFLAGS, FLOWFRDWR | FLOWFRNOPART);
+
clock_gettime(CLOCK_REALTIME, &tic);
pthread_create(&client.reader_pt, NULL, reader, &fd);
@@ -227,8 +251,9 @@ static int client_main(void)
printf("\n");
printf("--- %s ping statistics ---\n", client.s_apn);
- printf("%d SDUs transmitted, ", client.sent);
+ printf("%d packets transmitted, ", client.sent);
printf("%d received, ", client.rcvd);
+ printf("%zd out-of-order, ", client.ooo);
printf("%.0lf%% packet loss, ", client.sent == 0 ? 0 :
ceil(100 - (100 * (client.rcvd / (float) client.sent))));
printf("time: %.3f ms\n", ts_diff_us(&tic, &toc) / 1000.0);
diff --git a/src/tools/oping/oping_server.c b/src/tools/oping/oping_server.c
index 391da197..6f76869c 100644
--- a/src/tools/oping/oping_server.c
+++ b/src/tools/oping/oping_server.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Ouroboros ping application
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,16 +61,21 @@ void * cleaner_thread(void * o)
while (true) {
clock_gettime(CLOCK_REALTIME, &now);
- pthread_mutex_lock(&server.lock);
+
for (i = 0; i < OPING_MAX_FLOWS; ++i)
- if (fset_has(server.flows, i) &&
- ts_diff_ms(&server.times[i], &now) > deadline_ms) {
- printf("Flow %d timed out.\n", i);
- fset_del(server.flows, i);
- flow_dealloc(i);
+ if (fset_has(server.flows, i)) {
+ time_t diff;
+
+ pthread_mutex_lock(&server.lock);
+ diff = ts_diff_ms(&server.times[i], &now);
+ pthread_mutex_unlock(&server.lock);
+
+ if (diff > deadline_ms) {
+ printf("Flow %d timed out.\n", i);
+ fset_del(server.flows, i);
+ flow_dealloc(i);
+ }
}
-
- pthread_mutex_unlock(&server.lock);
sleep(1);
}
}
@@ -96,10 +101,13 @@ void * server_thread(void *o)
continue;
if (ntohl(msg->type) != ECHO_REQUEST) {
- printf("Invalid message on fd %d.", fd);
+ printf("Invalid message on fd %d.\n", fd);
continue;
}
+ if (!server.quiet)
+ printf("Received %d bytes on fd %d.\n", msg_len, fd);
+
clock_gettime(CLOCK_REALTIME, &now);
pthread_mutex_lock(&server.lock);
@@ -118,9 +126,9 @@ void * server_thread(void *o)
void * accept_thread(void * o)
{
- int fd;
+ int fd;
struct timespec now;
- qosspec_t qs;
+ qosspec_t qs;
(void) o;
@@ -137,12 +145,14 @@ void * accept_thread(void * o)
clock_gettime(CLOCK_REALTIME, &now);
- pthread_mutex_lock(&server.lock);
fset_add(server.flows, fd);
+
+ pthread_mutex_lock(&server.lock);
server.times[fd] = now;
pthread_mutex_unlock(&server.lock);
- fccntl(fd, FLOWSFLAGS, FLOWFRNOBLOCK | FLOWFRDWR);
+ fccntl(fd, FLOWSFLAGS,
+ FLOWFRNOBLOCK | FLOWFRDWR | FLOWFRNOPART);
}
return (void *) 0;
diff --git a/src/tools/ovpn/CMakeLists.txt b/src/tools/ovpn/CMakeLists.txt
new file mode 100644
index 00000000..f3a2cac8
--- /dev/null
+++ b/src/tools/ovpn/CMakeLists.txt
@@ -0,0 +1,21 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+include_directories(${CMAKE_SOURCE_DIR}/include)
+include_directories(${CMAKE_BINARY_DIR}/include)
+
+get_filename_component(CURRENT_SOURCE_PARENT_DIR
+ ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
+
+include_directories(${CURRENT_SOURCE_PARENT_DIR})
+
+set(SOURCE_FILES
+ # Add source files here
+ ovpn.c
+ )
+
+add_executable(ovpn ${SOURCE_FILES})
+
+target_link_libraries(ovpn LINK_PUBLIC ouroboros-dev)
+
+install(TARGETS ovpn RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/src/tools/ovpn/ovpn.c b/src/tools/ovpn/ovpn.c
new file mode 100644
index 00000000..5333ff40
--- /dev/null
+++ b/src/tools/ovpn/ovpn.c
@@ -0,0 +1,335 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Ouroboros VPN
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _POSIX_C_SOURCE 200109L
+
+#include <ouroboros/dev.h>
+
+#include <stdio.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <getopt.h>
+
+#define BUF_SIZE 65536
+
+int t_fd;
+int o_fd;
+
+static void usage(void)
+{
+ printf("Usage: ovpn [OPTION]...\n"
+ "Sends TCP/IP traffic over Ouroboros\n\n"
+ " -n, --name Run as client, name of ovpn "
+ "server to connect to\n"
+ " -i, --ip IP address to give to TUN device\n"
+ " -m, --mask Subnet mask to give to TUN device\n"
+ " -C, --crypt AES encryption (default: off)\n"
+ "\n"
+ " --help Display this help text and exit\n");
+}
+
+static int tun_open(char * dev,
+ uint32_t ip,
+ uint32_t mask)
+{
+ struct ifreq ifr;
+ int fd;
+ int s;
+ int ret;
+ char * clonedev = "/dev/net/tun";
+ struct sockaddr_in * addr;
+
+ fd = open(clonedev, O_RDWR);
+ if (fd < 0)
+ return -1;
+
+ memset(&ifr, 0, sizeof(ifr));
+
+ ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+
+ ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
+ if (ret < 0)
+ goto fail;
+
+ strcpy(dev, ifr.ifr_name);
+
+ /* Now get the i/f up and running. */
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ goto fail;
+
+ /* Set IP address. */
+ ifr.ifr_addr.sa_family = AF_INET;
+ addr = (struct sockaddr_in *) &ifr.ifr_addr;
+ addr->sin_addr.s_addr = ip;
+
+ if (ioctl(s, SIOCSIFADDR, &ifr))
+ goto fail_ioctl;
+
+ /* Set subnet mask. */
+ addr->sin_addr.s_addr = mask;
+ if (ioctl(s, SIOCSIFNETMASK, &ifr))
+ goto fail_ioctl;
+
+ /* Bring interface up. */
+ if (ioctl(s, SIOCGIFFLAGS, &ifr))
+ goto fail_ioctl;
+ ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
+ if (ioctl(s, SIOCSIFFLAGS, &ifr))
+ goto fail_ioctl;
+
+ close(s);
+
+ return fd;
+
+ fail_ioctl:
+ close(s);
+ fail:
+ close(fd);
+ return -1;
+}
+
+void * o_reader(void * o)
+{
+ char buf[BUF_SIZE];
+ int len = 0;
+
+ (void) o;
+
+ while (true) {
+ len = flow_read(o_fd, buf, BUF_SIZE);
+ if (len <= 0)
+ continue;
+
+ if (write(t_fd, buf, len))
+ continue;
+ }
+}
+
+void * t_reader(void * o)
+{
+ char buf[BUF_SIZE];
+ int len = 0;
+
+ (void) o;
+
+ while (true) {
+ len = read(t_fd, buf, BUF_SIZE);
+ if (len <= 0)
+ continue;
+
+ if (flow_write(o_fd, buf, len) < 0)
+ continue;
+ }
+}
+
+static int check_mask(uint32_t mask)
+{
+ if (mask == 0)
+ return 0;
+
+ return ((~mask & (~mask + 1)) != 0);
+}
+
+int main(int argc,
+ char ** argv)
+{
+ char * name = NULL;
+ uint32_t ip = 0;
+ int32_t mask = -1;
+ char dev[IFNAMSIZ];
+ pthread_t t_thr;
+ pthread_t o_thr;
+ sigset_t sigset;
+ int sig;
+ int c;
+ qosspec_t qs;
+
+ static struct option long_options[] =
+ {{"ip", required_argument, NULL, 'i'},
+ {"mask", required_argument, NULL, 'm'},
+ {"name", required_argument, NULL, 'n'},
+ {"crypt", no_argument, NULL, 'C'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGINT);
+ sigaddset(&sigset, SIGQUIT);
+ sigaddset(&sigset, SIGHUP);
+ sigaddset(&sigset, SIGTERM);
+
+ if (geteuid() != 0) {
+ printf("ovpn must be run as root.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ qs = qos_raw;
+
+ while ((c = getopt_long(argc, argv, "i:m:n:Ch",
+ long_options, NULL)) != -1) {
+ switch (c) {
+ case 'i':
+ if (inet_pton(AF_INET, optarg, &ip) != 1) {
+ printf("Invalid IP address: %s.\n\n", optarg);
+ goto fail_usage;
+ }
+ break;
+ case 'm':
+ if (inet_pton(AF_INET, optarg, &mask) != 1 ||
+ check_mask(htonl(mask))) {
+ printf("Invalid subnet mask: %s.\n\n", optarg);
+ goto fail_usage;
+ }
+ break;
+ case 'n':
+ name = optarg;
+ break;
+ case 'C':
+ qs = qos_raw_crypt;
+ break;
+ case 'h':
+ usage();
+ exit(EXIT_SUCCESS);
+ default:
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (optind < argc) {
+ printf("Unknown arguments specified: ");
+ while (optind < argc)
+ printf("%s ", argv[optind++]);
+ printf("\n\n");
+ goto fail_usage;
+ }
+
+ if (ip == 0) {
+ printf("Please specify an IP address.\n\n");
+ goto fail_usage;
+ }
+
+ if (mask == -1) {
+ printf("Please specify a subnetmask.\n\n");
+ goto fail_usage;
+ }
+
+ if (name != NULL) {
+ printf("Allocating a flow to %s.\n", name);
+
+ o_fd = flow_alloc(name, &qs, NULL);
+ if (o_fd < 0) {
+ printf("Failed to allocate flow.\n");
+ goto fail_alloc;
+ }
+ } else {
+ printf("Waiting for a new flow...\n");
+
+ o_fd = flow_accept(NULL, NULL);
+ if (o_fd < 0) {
+ printf("Failed to accept flow.\n");
+ goto fail_alloc;
+ }
+ }
+
+ printf("Flow allocated.\n");
+
+ t_fd = tun_open(dev, ip, mask);
+ if (t_fd < 0) {
+ printf("Failed to open tunnel device.\n");
+ goto fail_tun;
+ }
+
+ printf("Tunnel device name is %s.\n", dev);
+
+ pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+
+ printf("Starting read/write threads.\n");
+
+ if (pthread_create(&o_thr, NULL, o_reader, NULL))
+ goto fail_thread;
+
+ if (pthread_create(&t_thr, NULL, t_reader, NULL))
+ goto fail_thread2;
+
+ while (true) {
+ if (sigwait(&sigset, &sig) != 0) {
+ printf("Bad signal.\n");
+ continue;
+ }
+
+ printf("Shutting down...\n");
+ break;
+ }
+
+ pthread_cancel(o_thr);
+ pthread_cancel(t_thr);
+
+ pthread_join(o_thr, NULL);
+ pthread_join(t_thr, NULL);
+
+ close(t_fd);
+ flow_dealloc(o_fd);
+
+ pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
+
+ exit(EXIT_SUCCESS);
+ fail_usage:
+ usage();
+ exit(EXIT_FAILURE);
+ fail_thread2:
+ pthread_cancel(o_thr);
+ pthread_join(o_thr, NULL);
+ fail_thread:
+ close(t_fd);
+ fail_tun:
+ flow_dealloc(o_fd);
+ fail_alloc:
+ exit(EXIT_FAILURE);
+}
diff --git a/src/tools/time_utils.h b/src/tools/time_utils.h
index c9760a8b..c17282dc 100644
--- a/src/tools/time_utils.h
+++ b/src/tools/time_utils.h
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Time utilities
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,7 +35,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#ifndef OUROBOROS_TOOLS_TIME_UTILS_H
#define OUROBOROS_TOOLS_TIME_UTILS_H
@@ -52,7 +51,6 @@
#include <time.h>
#include <sys/time.h>
-#include <limits.h> /* LONG_MAX */
/* functions for timespecs */
#define ts_diff_ns(t0, tx) (((tx)->tv_sec - (t0)->tv_sec) * BILLION \
@@ -69,29 +67,70 @@
+ ((tx)->tv_usec - (t0)->tv_usec) / MILLION)
/* functions for timespecs */
-int ts_add(const struct timespec * t,
- const struct timespec * intv,
- struct timespec * res);
-int ts_diff(const struct timespec * t,
- const struct timespec * intv,
- struct timespec * res);
+#define ts_add(t, intv, res) \
+ do { \
+ time_t nanos = 0; \
+ nanos = (t)->tv_nsec + (intv)->tv_nsec; \
+ (res)->tv_sec = (t)->tv_sec + (intv)->tv_sec; \
+ while (nanos >= BILLION) { \
+ nanos -= BILLION; \
+ ++((res)->tv_sec); \
+ } \
+ (res)->tv_nsec = nanos; \
+ } while (0);
+
+#define ts_diff(t, intv, res) \
+ do { \
+ time_t nanos = 0; \
+ nanos = (t)->tv_nsec - (intv)->tv_nsec; \
+ (res)->tv_sec = (t)->tv_sec - (intv)->tv_sec; \
+ while (nanos < 0) { \
+ nanos += BILLION; \
+ --((res)->tv_sec); \
+ } \
+ (res)->tv_nsec = nanos; \
+ } while (0);
/* functions for timevals */
-int tv_add(const struct timeval * t,
- const struct timeval * intv,
- struct timeval * res);
-int tv_diff(const struct timeval * t,
- const struct timeval * intv,
- struct timeval * res);
+#define tv_add(t, intv, res) \
+ do { \
+ time_t micros = 0; \
+ nanos = (t)->tv_usec + (intv)->tv_usec; \
+ (res)->tv_sec = (t)->tv_sec + (intv)->tv_sec; \
+ while (micros >= MILLION) { \
+ micros -= MILLION; \
+ ++((res)->tv_sec); \
+ } \
+ (res)->tv_nsec = nanos; \
+ } while (0);
+
+#define tv_diff(t, intv, res) \
+ do { \
+ time_t micros = 0; \
+ micros = (t)->tv_usec - (intv)->tv_usec; \
+ (res)->tv_sec = (t)->tv_sec - (intv)->tv_sec; \
+ while (micros < 0) { \
+ micros += MILLION; \
+ --((res)->tv_sec); \
+ } \
+ (res)->tv_usec = micros; \
+ } while (0);
+
/* copying a timeval into a timespec */
-int tv_to_ts(const struct timeval * src,
- struct timespec * dst);
+#define tv_to_ts(tv, ts) \
+ do { \
+ (ts)->tv_sec = (tv)->tv_sec; \
+ (ts)->tv_nsec = (tv)->tv_usec * 1000L; \
+ } while (0);
/* copying a timespec into a timeval (loss of resolution) */
-int ts_to_tv(const struct timespec * src,
- struct timeval * dst);
+#define ts_to_tv(ts, tv) \
+ do { \
+ (tv)->tv_sec = (ts)->tv_sec; \
+ (tv)->tv_usec = (ts)->tv_nsec / 1000L; \
+ } while (0);
#endif /* OUROBOROS_TOOLS_TIME_UTILS_H */