diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-08-16 18:55:15 +0000 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-08-31 08:31:45 +0200 |
| commit | 5c239c128c04883dbed6d66f574edf8b48d11e11 (patch) | |
| tree | 6dfcc043c81bd10e1366172b9db5cf5ce93bb8d8 /include | |
| parent | a830ed966eb3b7d6dbcc43e42a7b6b7c5d796c6a (diff) | |
| download | ouroboros-5c239c128c04883dbed6d66f574edf8b48d11e11.tar.gz ouroboros-5c239c128c04883dbed6d66f574edf8b48d11e11.zip | |
lib: Replace shim IPCPs with points of attachment
Removes the UDP and Ethernet shim IPCPs. The unicast and broadcast
IPCPs can now directly attach to a "legacy" socket. We adopt Saltzer's
Point-of-Attachment terminology, also advocated in Day's "Patterns in
Network Architecture". The "poa" component manages these
PoA's with one management thread, one link monitoring thread and one
thread per attached point.
For Ethernet PoA's the irm connect and enroll can resolve the
destination IPCP or Layer name with a broadcast name query over the
attached PoAs (first reply wins). UDP PoA's require a destination IP
address or FQDN.
attach to a local endpoint (required both server and client side):
irm ipcp poa attach name a udp 10.0.0.1
irm ipcp poa attach name a udp 10.0.0.1:3435
irm ipcp poa attach name a udp [::1]:3435
irm ipcp poa attach name a eth dev eth0
irm ipcp poa attach name a eth dev eth0 ethertype 0xA000
release a PoA (refused while it carries a flow):
irm ipcp poa detach name a udp 10.0.0.1:3435
irm ipcp poa detach name a eth eth0
list an IPCP's PoAs:
irm ipcp poa list name a
connect to a peer, by name or at an address:
irm ipcp connect name b dst a
irm ipcp connect name b dst a eth
irm ipcp connect name b dst a eth dev eth0
irm ipcp connect name b dst a udp 10.0.0.1:3435
irm ipcp connect name b dst a udp peer.example.com:3435
disconnect by peer name, no address:
irm ipcp disconnect name b dst a
irm ipcp disconnect name b dst a component mgmt
enroll has the same shape as connect:
irm ipcp enroll name b layer lr autobind
irm ipcp enroll name b layer lr autobind eth dev eth0
irm ipcp enroll name b layer lr autobind udp 10.0.0.1:3435
the IRMd config file attaches PoAs and names peers the same way:
udp = [ "10.0.0.1", "10.0.0.1:3436" ]
eth = [ "eth0", {dev="eth1", ethertype=0xA007} ]
enrol={dst="LAN", eth={dev="eth0"}}
conn=[{dst="lan3", eth={}}, {dst="lan4", udp="10.0.0.1:3435"}]
Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks>
Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'include')
| -rw-r--r-- | include/ouroboros/ipcp-dev.h | 113 | ||||
| -rw-r--r-- | include/ouroboros/ipcp.h | 97 | ||||
| -rw-r--r-- | include/ouroboros/irm.h | 25 | ||||
| -rw-r--r-- | include/ouroboros/protobuf.h | 30 | ||||
| -rw-r--r-- | include/ouroboros/qos.h | 6 | ||||
| -rw-r--r-- | include/ouroboros/serdes-irm.h | 17 |
6 files changed, 189 insertions, 99 deletions
diff --git a/include/ouroboros/ipcp-dev.h b/include/ouroboros/ipcp-dev.h index d00d6f08..8677adf0 100644 --- a/include/ouroboros/ipcp-dev.h +++ b/include/ouroboros/ipcp-dev.h @@ -24,55 +24,106 @@ #define OUROBOROS_LIB_IPCP_DEV_H #include <ouroboros/ipcp.h> +#include <ouroboros/qos.h> #include <ouroboros/qoscube.h> #include <ouroboros/ssm_pool.h> #include <ouroboros/utils.h> +#include <stdbool.h> #include <stdint.h> +#include <time.h> -int ipcp_create_r(const struct ipcp_info * info); +int ipcp_create_r(const struct ipcp_info * info); -int ipcp_flow_req_arr(const buffer_t * dst, - qosspec_t qs, - time_t mpl, - uint32_t mtu, - const buffer_t * data); +int ipcp_flow_req_arr(const buffer_t * dst, + qosspec_t qs, + time_t mpl, + uint32_t mtu, + const buffer_t * data); -int ipcp_flow_update_arr(int flow_id, - const buffer_t * data); - -int ipcp_flow_alloc_reply(int fd, - int response, - time_t mpl, - uint32_t mtu, +int ipcp_flow_update_arr(int flow_id, const buffer_t * data); -int ipcp_flow_read(int fd, - struct ssm_pk_buff ** spb); +int ipcp_flow_alloc_reply(int fd, + int response, + time_t mpl, + uint32_t mtu, + const buffer_t * data); + +int ipcp_flow_read(int fd, + struct ssm_pk_buff ** spb); + +int ipcp_flow_write(int fd, + struct ssm_pk_buff * spb); + +int np1_flow_read(int fd, + struct ssm_pk_buff ** spb, + struct ssm_pool * pool); + +int np1_flow_write(int fd, + struct ssm_pk_buff * spb, + struct ssm_pool * pool); + +int ipcp_flow_dealloc(int fd); + +int ipcp_flow_fini(int fd); + +int ipcp_flow_get_qoscube(int fd, + qoscube_t * cube); + +size_t ipcp_flow_queued(int fd); -int ipcp_flow_write(int fd, - struct ssm_pk_buff * spb); +/* + * Identifies the transmit queue behind the flow. Flows attached to + * one point of attachment share a queue and answer the same id. + */ +int ipcp_flow_queue_id(int fd); + +int ipcp_spb_reserve(struct ssm_pk_buff ** spb, + size_t len); + +void ipcp_spb_release(struct ssm_pk_buff * spb); + +/* PoA lifecycle; an IPCP owns its PoAs, applications have none. */ +int poa_init(const char * name); -int np1_flow_read(int fd, - struct ssm_pk_buff ** spb, - struct ssm_pool * pool); +int poa_start(void); -int np1_flow_write(int fd, - struct ssm_pk_buff * spb, - struct ssm_pool * pool); +void poa_stop(void); -int ipcp_flow_dealloc(int fd); +void poa_fini(void); -int ipcp_flow_fini(int fd); +/* Also answer name queries for the layer; set at bootstrap/enroll. */ +int poa_set_layer(const char * layer); -int ipcp_flow_get_qoscube(int fd, - qoscube_t * cube); +/* Attach or release a PoA; the type in the spec picks the transport. */ +int poa_attach(const struct poa_spec * poa); -size_t ipcp_flow_queued(int fd); +int poa_detach(const struct poa_spec * poa); + +/* The PoAs this process has attached. */ +ssize_t poa_list(struct poa_spec * specs, + size_t max); + +/* Allocate a flow to dst over the PoA that carries addr. */ +int poa_flow_alloc(const char * dst, + const struct poa_addr * addr, + qosspec_t * qs, + const struct timespec * timeo); + +/* Resolve dst on the attached PoAs; no flow is created. */ +int poa_query(const char * dst, + const struct timespec * timeo, + struct poa_addr * addr); + +/* PoA counterparts of the ipcp_flow_* operations */ +int poa_flow_alloc_resp(int flow_id, + int response, + const buffer_t * data); -int ipcp_spb_reserve(struct ssm_pk_buff ** spb, - size_t len); +int poa_flow_update(int flow_id, + const buffer_t * data); -void ipcp_spb_release(struct ssm_pk_buff * spb); +int poa_flow_dealloc(int flow_id); #endif /* OUROBOROS_LIB_IPCP_DEV_H */ diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h index 135b8fcb..4da3b81d 100644 --- a/include/ouroboros/ipcp.h +++ b/include/ouroboros/ipcp.h @@ -48,13 +48,19 @@ enum ipcp_type { /* IRMd uses order to select an IPCP for flow allocation. */ IPCP_LOCAL = 0, IPCP_UNICAST, IPCP_BROADCAST, - IPCP_ETH_LLC, - IPCP_ETH_DIX, - IPCP_UDP4, - IPCP_UDP6, IPCP_INVALID }; +/* The medium a PoA sits on. */ +enum poa_type { + POA_UDP4 = 0, + POA_UDP6, + /* A name to resolve; the family is DNS's pick. Port in udp4. */ + POA_UDP, + POA_ETH, + POA_INVALID +}; + struct ipcp_info { enum ipcp_type type; pid_t pid; @@ -256,23 +262,52 @@ static const struct uni_config default_uni_config = { .cong_avoid = CA_MB_ECN }; -struct eth_config { +#define POA_UDP_PORT 3435 /* default UDP PoA port */ +#define POA_ETHERTYPE 0xA000 /* default Ethertype */ +#define POA_MAC_SIZE 6 +#define POA_HOST_STRLEN 255 + +struct eth_poa { char dev[DEV_NAME_SIZE + 1]; - uint16_t ethertype; /* DIX only*/ + uint16_t ethertype; + uint8_t mac[POA_MAC_SIZE]; }; -struct udp4_config { +struct udp4_poa { struct in_addr ip_addr; - struct in_addr dns_addr; uint16_t port; }; -struct udp6_config { +struct udp6_poa { struct in6_addr ip_addr; - struct in6_addr dns_addr; uint16_t port; }; +/* PoA a unicast or broadcast IPCP attaches to. */ +struct poa_spec { + enum poa_type type; + union { + struct udp4_poa udp4; + struct udp6_poa udp6; + struct eth_poa eth; + }; +}; + + +/* Peer PoA to connect to. */ +struct poa_addr { + enum poa_type type; + char hostname[POA_HOST_STRLEN + 1]; /* resolved by IRMd */ + union { + struct udp4_poa udp4; + struct udp6_poa udp6; + struct { + struct eth_poa src; + struct eth_poa dst; + } eth; + }; +}; + /* Layers */ struct layer_info { char name[LAYER_NAME_SIZE + 1]; @@ -285,58 +320,22 @@ struct ipcp_config { struct layer_info layer_info; enum ipcp_type type; - union { - struct uni_config unicast; - struct udp4_config udp4; - struct udp6_config udp6; - struct eth_config eth; - }; + struct uni_config unicast; }; /* default configurations */ static const struct ipcp_config local_default_conf = { - .type = IPCP_LOCAL, - .layer_info = { - .dir_hash_algo = DIR_HASH_SHA3_256 - } -}; - -static const struct ipcp_config eth_dix_default_conf = { - .type = IPCP_ETH_DIX, .layer_info = { .dir_hash_algo = DIR_HASH_SHA3_256 }, - .eth = { - .ethertype=0xA000, - } -}; - -static const struct ipcp_config eth_llc_default_conf = { - .type = IPCP_ETH_LLC, - .layer_info = { - .dir_hash_algo = DIR_HASH_SHA3_256 - } -}; - -static const struct ipcp_config udp4_default_conf = { - .type = IPCP_UDP4, - .udp4 = { - .port = 3435 - } -}; - -static const struct ipcp_config udp6_default_conf = { - .type = IPCP_UDP6, - .udp6 = { - .port = 3435 - } + .type = IPCP_LOCAL }; static const struct ipcp_config uni_default_conf = { - .type = IPCP_UNICAST, .layer_info = { .dir_hash_algo = DIR_HASH_SHA3_256 }, + .type = IPCP_UNICAST, .unicast = { .dt = { .addr_size = 4, diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h index 7cb71c21..3e8a24af 100644 --- a/include/ouroboros/irm.h +++ b/include/ouroboros/irm.h @@ -46,16 +46,29 @@ int irm_destroy_ipcp(pid_t pid); ssize_t irm_list_ipcps(struct ipcp_list_info ** ipcps); -int irm_enroll_ipcp(pid_t pid, - const char * dst); +int irm_enroll_ipcp(pid_t pid, + const char * dst, + const struct poa_addr * addr); int irm_bootstrap_ipcp(pid_t pid, const struct ipcp_config * conf); -int irm_connect_ipcp(pid_t pid, - const char * dst, - const char * component, - qosspec_t qs); +/* Attach an IPCP to a medium; repeat for more than one PoA. */ +int irm_attach_ipcp(pid_t pid, + const struct poa_spec * poa); + +int irm_detach_ipcp(pid_t pid, + const struct poa_spec * poa); + +/* Caller frees *poas. */ +ssize_t irm_list_poas(pid_t pid, + struct poa_spec ** poas); + +int irm_connect_ipcp(pid_t pid, + const char * dst, + const char * component, + qosspec_t qs, + const struct poa_addr * addr); int irm_disconnect_ipcp(pid_t pid, const char * dst, diff --git a/include/ouroboros/protobuf.h b/include/ouroboros/protobuf.h index 951e8fd6..7937f86b 100644 --- a/include/ouroboros/protobuf.h +++ b/include/ouroboros/protobuf.h @@ -24,9 +24,9 @@ #define OUROBOROS_LIB_PROTOBUF_H #include <ouroboros/flow.h> -#include <ouroboros/qos.h> #include <ouroboros/ipcp.h> #include <ouroboros/irm.h> +#include <ouroboros/qos.h> #include <ouroboros/serdes-irm.h> #include <ouroboros/serdes-oep.h> @@ -37,9 +37,10 @@ typedef RoutingConfigMsg routing_config_msg_t; typedef DtConfigMsg dt_config_msg_t; typedef DirConfigMsg dir_config_msg_t; typedef DirDhtConfigMsg dir_dht_config_msg_t; -typedef EthConfigMsg eth_config_msg_t; -typedef Udp4ConfigMsg udp4_config_msg_t; -typedef Udp6ConfigMsg udp6_config_msg_t; +typedef EthPoaMsg eth_poa_msg_t; +typedef Udp4PoaMsg udp4_poa_msg_t; +typedef PoaSpecMsg poa_spec_msg_t; +typedef Udp6PoaMsg udp6_poa_msg_t; typedef UniConfigMsg uni_config_msg_t; #include "ipcp.pb-c.h" @@ -56,6 +57,7 @@ typedef FlowInfoMsg flow_info_msg_t; typedef NameInfoMsg name_info_msg_t; typedef LayerInfoMsg layer_info_msg_t; typedef QosspecMsg qosspec_msg_t; +typedef PoaAddrMsg poa_addr_msg_t; #include "enroll.pb-c.h" typedef EnrollReqMsg enroll_req_msg_t; @@ -79,6 +81,10 @@ layer_info_msg_t * layer_info_s_to_msg(const struct layer_info * s); struct layer_info layer_info_msg_to_s(const layer_info_msg_t * msg); +poa_addr_msg_t * poa_addr_s_to_msg(const struct poa_addr * s); + +struct poa_addr poa_addr_msg_to_s(const poa_addr_msg_t * msg); + ipcp_info_msg_t * ipcp_info_s_to_msg(const struct ipcp_info * s); struct ipcp_info ipcp_info_msg_to_s(const ipcp_info_msg_t * msg); @@ -91,20 +97,24 @@ uni_config_msg_t * uni_config_s_to_msg(const struct uni_config * s); struct uni_config uni_config_msg_to_s(const uni_config_msg_t * msg); -eth_config_msg_t * eth_config_s_to_msg(const struct eth_config * s); +eth_poa_msg_t * eth_poa_s_to_msg(const struct eth_poa * s); -struct eth_config eth_config_msg_to_s(const eth_config_msg_t * msg); +struct eth_poa eth_poa_msg_to_s(const eth_poa_msg_t * msg); -udp4_config_msg_t * udp4_config_s_to_msg(const struct udp4_config * s); +udp4_poa_msg_t * udp4_poa_s_to_msg(const struct udp4_poa * s); -struct udp4_config udp4_config_msg_to_s(const udp4_config_msg_t * msg); +struct udp4_poa udp4_poa_msg_to_s(const udp4_poa_msg_t * msg); -udp6_config_msg_t * udp6_config_s_to_msg(const struct udp6_config * s); +udp6_poa_msg_t * udp6_poa_s_to_msg(const struct udp6_poa * s); -struct udp6_config udp6_config_msg_to_s(const udp6_config_msg_t * msg); +struct udp6_poa udp6_poa_msg_to_s(const udp6_poa_msg_t * msg); ipcp_config_msg_t * ipcp_config_s_to_msg(const struct ipcp_config * s); +poa_spec_msg_t * poa_spec_s_to_msg(const struct poa_spec * s); + +struct poa_spec poa_spec_msg_to_s(const poa_spec_msg_t * msg); + struct ipcp_config ipcp_config_msg_to_s(const ipcp_config_msg_t * msg); /* QoS */ diff --git a/include/ouroboros/qos.h b/include/ouroboros/qos.h index 7980ad00..26fc2637 100644 --- a/include/ouroboros/qos.h +++ b/include/ouroboros/qos.h @@ -30,9 +30,9 @@ /* qos_spec.service: framing / reliability class. */ enum qos_service { - SVC_RAW = 0, /* No FRCT; best-effort raw messages */ - SVC_MESSAGE = 1, /* FRCT, reliable ordered messages */ - SVC_STREAM = 2, /* FRCT, reliable ordered byte stream */ + SVC_RAW = 0, /* No FRCT; best-effort raw messages */ + SVC_MESSAGE = 1, /* FRCT, ordered messages, optional reliability */ + SVC_STREAM = 2, /* FRCT, reliable ordered byte stream */ }; typedef struct qos_spec { diff --git a/include/ouroboros/serdes-irm.h b/include/ouroboros/serdes-irm.h index a5854d5b..bc3c46d2 100644 --- a/include/ouroboros/serdes-irm.h +++ b/include/ouroboros/serdes-irm.h @@ -52,6 +52,23 @@ int ipcp_flow_req_arr__irm_req_ser(buffer_t * buf, const struct flow_info * flow, const buffer_t * data); +int poa_flow_alloc__irm_req_ser(buffer_t * buf, + const struct flow_info * flow, + const char * dst); + +int poa_flow_alloc_r__irm_req_ser(buffer_t * buf, + const struct flow_info * flow, + const buffer_t * data, + int response); + +int ipcp_poa_flow_req_arr__irm_req_ser(buffer_t * buf, + const struct flow_info * flow, + const buffer_t * data); + +int poa_flow__irm_result_des(buffer_t * buf, + struct flow_info * flow, + buffer_t * data); + int ipcp_flow_update_arr__irm_req_ser(buffer_t * buf, const struct flow_info * flow, const buffer_t * data); |
