summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-09-25 22:47:48 -0400
committerIan Moffett <ian@osmora.org>2025-09-25 22:47:48 -0400
commit9895b548037cb63de561594d517520c738b31943 (patch)
tree067364b9d65c927d54a283c6af1d6b5b8d01f839
parent262f87964fbf2af6e7d085b5d1231254367a13ca (diff)
link: Introduce squeaking (peer discovery)
A machine may decide to squeak at another machine, those who are listening shall squeak back to announce their presence on the wire. Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--src/dgram/dgram_link.c62
-rw-r--r--src/dgram/dgram_subr.c3
-rw-r--r--src/include/dgram.h39
3 files changed, 95 insertions, 9 deletions
diff --git a/src/dgram/dgram_link.c b/src/dgram/dgram_link.c
index 1ebe353..145e716 100644
--- a/src/dgram/dgram_link.c
+++ b/src/dgram/dgram_link.c
@@ -45,11 +45,13 @@
* @dst: Destination MAC address
* @buf: Buffer to use
* @len: Length to transmit
+ * @type: Packet type to use
*/
struct dgram_params {
mac_addr_t dst;
void *buf;
uint16_t len;
+ uint8_t type;
};
/*
@@ -91,7 +93,7 @@ dgram_do_send(struct onet_link *link, struct dgram_params *params)
saddr.sll_ifindex = link->iface_idx;
saddr.sll_halen = HW_ADDR_LEN;
ether_load_route(link->hwaddr, params->dst, eth);
- dgram_load(params->len, 50, dgram);
+ dgram_load(params->len, 50, params->type, dgram);
sendto(
link->sockfd, p, dgram_len, 0,
(struct sockaddr *)&saddr, sizeof(struct sockaddr_ll)
@@ -101,6 +103,37 @@ dgram_do_send(struct onet_link *link, struct dgram_params *params)
return params->len;
}
+/*
+ * Squeak back at a machine that squeaks at
+ * us.
+ *
+ * @link: Link to squeak through
+ * @src: Who squeaked first?
+ * @dst: Who was intended to be squeaked at?
+ */
+static int
+squeak_back(struct onet_link *link, mac_addr_t src, mac_addr_t dst)
+{
+ /*
+ * If one were to spoof their address as the broadcast
+ * address, that could end up VERY badly as it would
+ * result in a feedback loop.
+ */
+ if (src == MAC_BROADCAST) {
+ return -1;
+ }
+
+ /*
+ * If we were not intended and this was a not broadcast
+ * squeak, it must have been directed to another node.
+ */
+ if (dst != link->hwaddr && dst != MAC_BROADCAST) {
+ return -1;
+ }
+
+ return dgram_squeak(link, src);
+}
+
tx_len_t
dgram_send(struct onet_link *link, mac_addr_t dst, void *buf, uint16_t len)
{
@@ -109,6 +142,20 @@ dgram_send(struct onet_link *link, mac_addr_t dst, void *buf, uint16_t len)
params.dst = dst;
params.buf = buf;
params.len = len;
+ params.type = OTYPE_DATA;
+ return dgram_do_send(link, &params);
+}
+
+tx_len_t
+dgram_squeak(struct onet_link *link, mac_addr_t dst)
+{
+ struct dgram_params params;
+ uint8_t pad[8];
+
+ params.dst = dst;
+ params.buf = pad;
+ params.len = sizeof(pad);
+ params.type = OTYPE_SQUEAK;
return dgram_do_send(link, &params);
}
@@ -122,7 +169,7 @@ dgram_recv(struct onet_link *link, void *buf, uint16_t len)
size_t dgram_len, recv_len;
uint32_t crc;
uint16_t proto;
- mac_addr_t dest_mac;
+ mac_addr_t dest_mac, src_mac;
char *p;
if (link == NULL || buf == NULL) {
@@ -158,10 +205,7 @@ dgram_recv(struct onet_link *link, void *buf, uint16_t len)
hdr = (void *)p;
proto = ntohs(hdr->proto);
dest_mac = mac_swap(hdr->dest);
-
- if (recv_len != dgram_len) {
- continue;
- }
+ src_mac = mac_swap(hdr->source);
if (proto != PROTO_ID) {
continue;
@@ -173,6 +217,12 @@ dgram_recv(struct onet_link *link, void *buf, uint16_t len)
continue;
}
+ /* Is this a squeak? */
+ if (o1p_hdr->type == OTYPE_SQUEAK) {
+ squeak_back(link, src_mac, dest_mac);
+ continue;
+ }
+
/* If this is for everyone, take it */
if (dest_mac == MAC_BROADCAST) {
break;
diff --git a/src/dgram/dgram_subr.c b/src/dgram/dgram_subr.c
index fda8178..a4712d5 100644
--- a/src/dgram/dgram_subr.c
+++ b/src/dgram/dgram_subr.c
@@ -34,7 +34,7 @@
#include "crc.h"
int
-dgram_load(uint16_t length, uint8_t port, struct onet_dgram *res)
+dgram_load(uint16_t length, uint8_t port, uint8_t type, struct onet_dgram *res)
{
if (res == NULL) {
return -EINVAL;
@@ -43,6 +43,7 @@ dgram_load(uint16_t length, uint8_t port, struct onet_dgram *res)
memset(res, 0, sizeof(*res));
res->length = (length >> 8) & 0xFF;
res->length |= (length & 0xFF) << 8;
+ res->type = type;
res->port = port;
res->crc32 = crc32(res, sizeof(*res) - sizeof(res->crc32));
return 0;
diff --git a/src/include/dgram.h b/src/include/dgram.h
index 31f7c03..779c7ef 100644
--- a/src/include/dgram.h
+++ b/src/include/dgram.h
@@ -42,6 +42,7 @@ typedef tx_len_t rx_len_t;
*
* @length: Packet length in bytes
* @reserved: Reserved for future use
+ * @type: Describes the type of packet (see OTYPE_*)
* @reserved1: Reserved for future use
* @port: Datagram port number to send on
* @crc32: CRC32 checksum of data + header
@@ -49,12 +50,31 @@ typedef tx_len_t rx_len_t;
struct onet_dgram {
uint16_t length;
uint16_t reserved;
- uint16_t reserved1;
+ uint8_t type : 3;
+ uint16_t reserved1 : 13;
uint8_t port;
uint32_t crc32;
} __attribute__((packed));
/*
+ * ONET packet types
+ *
+ * @OTYPE_DATA: Regular data to be sent
+ * @OTYPE_SQUEAK: For peer discovery
+ *
+ * [ALL OTHER VALUES ARE RESERVED]
+ *
+ * -- Squeaks --
+ *
+ * A machine may squeak at the wire and those whom the squeak is
+ * intended for shall squeak back. One thing to be aware of is that
+ * this may allow squeak storms / attacks where a machine continuously
+ * squeaks at a wire.
+ */
+#define OTYPE_DATA 0x0
+#define OTYPE_SQUEAK 0x1
+
+/*
* Get the total length of a datagram including
* the length of the ethernet header and the header
* of the datagram itself.
@@ -81,12 +101,16 @@ struct onet_dgram {
*
* @length: Length of a packet to send
* @port: Port number to send on
+ * @type: Packet type (OTYPE_*)
* @res: Result is written here
*
* Returns zero on success, otherwise a less than zero
* value on failure.
*/
-int dgram_load(uint16_t length, uint8_t port, struct onet_dgram *res);
+int dgram_load(
+ uint16_t length, uint8_t port,
+ uint8_t type, struct onet_dgram *res
+);
/*
* Send a datagram through ONET
@@ -105,6 +129,17 @@ tx_len_t dgram_send(
);
/*
+ * Send a squeak through a wire
+ *
+ * @link: Link to squeak through
+ * @dst: Destination address to squeak at
+ *
+ * Returns the length of the squeak on success, otherwise
+ * a less than zero value on failure.
+ */
+tx_len_t dgram_squeak(struct onet_link *link, mac_addr_t dst);
+
+/*
* Get data from an ONET link
*
* @link: The ONET link to recv data from