diff --git a/Makefile b/Makefile index 96b7245..51b1674 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all bp_socket daemon clean format check-format +.PHONY: all bp_socket daemon clean format check-format install all: bp_socket daemon @@ -15,3 +15,15 @@ clean: format: $(MAKE) -C bp_socket format $(MAKE) -C daemon format + +install: + install -d /usr/local/include + install -m 644 include/bp_socket.h /usr/local/include/ + $(MAKE) -C daemon clean + $(MAKE) -C daemon + $(MAKE) -C bp_socket clean + $(MAKE) -C bp_socket + @if lsmod | grep -q "^bp "; then \ + sudo rmmod bp; \ + fi + sudo insmod bp_socket/bp.ko \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile index 7119cf0..992f4c4 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -24,7 +24,7 @@ Vagrant.configure("2") do |config| EOF ion.vm.provision "shell", inline: <<-EOF export DEBIAN_FRONTEND=noninteractive - apt install -y curl git ca-certificates make pkg-config libnl-genl-3-dev libevent-dev build-essential linux-headers-$(uname -r) + apt install -y curl git ca-certificates make pkg-config libnl-genl-3-dev libnl-3-dev libevent-dev build-essential clang-format sparse linux-headers-$(uname -r) cd /opt wget -q https://github.com/nasa-jpl/ION-DTN/archive/refs/tags/ion-open-source-4.1.3.tar.gz diff --git a/bp_client.c b/bp_client.c index ac35bec..be6b453 100644 --- a/bp_client.c +++ b/bp_client.c @@ -1,4 +1,4 @@ -#include "include/bp_socket.h" +#include "bp_socket.h" #include #include #include @@ -40,7 +40,8 @@ void *send_thread(void *arg) { message_count); int flags = 0; - flags |= MSG_ACK_REQUESTED; + // flags |= MSG_ACK_REQUESTED; + flags |= MSG_NO_CUSTODY_REQUIRED; int ret = sendto(data->fd, send_buffer, strlen(send_buffer) + 1, flags, diff --git a/bp_socket/Makefile b/bp_socket/Makefile index f38c313..9fb0faf 100644 --- a/bp_socket/Makefile +++ b/bp_socket/Makefile @@ -6,7 +6,7 @@ PWD := $(shell pwd) SRC_FILES := $(wildcard *.c *.h) -.PHONY: all clean sparse +.PHONY: all clean sparse install all: $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules @@ -18,4 +18,11 @@ sparse: $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules C=1 CHECK=sparse format: - clang-format -i --style=file $(SRC_FILES) \ No newline at end of file + clang-format -i --style=file $(SRC_FILES) + +install: all + @echo "Installing kernel module..." + install -d /lib/modules/$(shell uname -r)/extra + install -m 644 bp.ko /lib/modules/$(shell uname -r)/extra/ + depmod -a + @echo "Kernel module installed. Use 'modprobe bp' to load it." \ No newline at end of file diff --git a/configs/cloud-init/ion.cloud-config.cfg b/configs/cloud-init/ion.cloud-config.cfg index 55e467a..823ef83 100644 --- a/configs/cloud-init/ion.cloud-config.cfg +++ b/configs/cloud-init/ion.cloud-config.cfg @@ -10,8 +10,11 @@ packages: - make - pkg-config - libnl-genl-3-dev +- libnl-3-dev - libevent-dev - build-essential +- clang-format +- sparse ssh_pwauth: false users: @@ -19,8 +22,6 @@ users: sudo: ALL=(ALL) NOPASSWD:ALL groups: users,admin lock_passwd: false - ssh_authorized_keys: - - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCo3kxULSxGtVb70NZ/dI9HUBizF1ooyGT97vf0ORB7ONG4BnNHp4ijuVpBpo9r9LgB8p+M1dhZarrTaQ2u/1lUDrjNGERMt1HfDWmHzbcqr24oGqqOgDcCGrCmcGxqpWcHAu1HfcVfBO4YeJMHYQOkV/0vS3fdhocbGf0vkE13QAfjVmbZvR/dnaaVIdVeoovC2vz6DKCGgfZDM1GB35WzJ5oXoRsHuOReCywea2p5oB90ttM50bnX/Uv7DRn8e3f/8Pwf0Rp/R/JzlLtAeC9HulNyo4LVlWcom4G55D8/g11n03sp7SR2Zl2VorF6Ep6Phuha1izjHj+aCM2TbxSCq7DJnCW7n3GZ4/DqAMP4cglE0IEjGsM6jrDTdbjMlqt6u1RZ+XgUtJktf9g086s/4Rx29V1wtUbqYfjHf3dwYB59Lj3d/mGvuMY0VpcVehYh2CRShPGoFxJ8+FqJSYQsrlu0CeC0QASBx7LUo7PX4N8QLCrmXf2ELzzGoEQl1UWomyufrd/+KcP8hvbWaZZSgoy4ww+3hHCf+RuuLsj4twyhwsFdS4/M0nVQrvTFjsIjeePI9Cwi/yeRph17AIKIjrxgCxHROz1cg3dZD/1fb2m5m6d+SJkuzEAvsP7eypncGOZpO/djhAMD/AfJpJA15uOl/G84G80bZCCFnpK8Rw== spierrot@Sylvains-Air.localdomain" shell: /bin/bash disable_root: true @@ -49,8 +50,46 @@ write_files: make make install permissions: '0755' +- path: /etc/systemd/system/bp-socket-daemon.service + content: | + [Unit] + Description=BP Socket Daemon + After=network.target + + [Service] + Type=simple + User=root + WorkingDirectory=/bp-socket + Environment=LD_LIBRARY_PATH=/usr/local/lib + ExecStart=/bp-socket/daemon/bp_daemon + Restart=always + RestartSec=5 + + [Install] + WantedBy=multi-user.target + permissions: '0644' +- path: /etc/systemd/system/ion-dtn.service + content: | + [Unit] + Description=ION DTN Stack + After=network.target + Wants=network-online.target + + [Service] + Type=oneshot + User=root + WorkingDirectory=/bp-socket/configs + Environment=LD_LIBRARY_PATH=/usr/local/lib + ExecStart=/usr/local/bin/ionstart -I /bp-socket/configs/host.rc + RemainAfterExit=yes + + [Install] + WantedBy=multi-user.target + permissions: '0644' runcmd: - bash /var/run/scripts/provision.sh - apt-get -y install linux-headers-$(uname -r) -- netplan apply \ No newline at end of file +- netplan apply +- cd /bp-socket && make && insmod /bp-socket/bp_socket/bp.ko +- systemctl daemon-reload \ No newline at end of file diff --git a/configs/cloud-init/ud3tn.cloud-config.cfg b/configs/cloud-init/ud3tn.cloud-config.cfg index 432c835..78b6841 100644 --- a/configs/cloud-init/ud3tn.cloud-config.cfg +++ b/configs/cloud-init/ud3tn.cloud-config.cfg @@ -20,8 +20,6 @@ users: sudo: ALL=(ALL) NOPASSWD:ALL groups: users,admin lock_passwd: false - ssh_authorized_keys: - - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCo3kxULSxGtVb70NZ/dI9HUBizF1ooyGT97vf0ORB7ONG4BnNHp4ijuVpBpo9r9LgB8p+M1dhZarrTaQ2u/1lUDrjNGERMt1HfDWmHzbcqr24oGqqOgDcCGrCmcGxqpWcHAu1HfcVfBO4YeJMHYQOkV/0vS3fdhocbGf0vkE13QAfjVmbZvR/dnaaVIdVeoovC2vz6DKCGgfZDM1GB35WzJ5oXoRsHuOReCywea2p5oB90ttM50bnX/Uv7DRn8e3f/8Pwf0Rp/R/JzlLtAeC9HulNyo4LVlWcom4G55D8/g11n03sp7SR2Zl2VorF6Ep6Phuha1izjHj+aCM2TbxSCq7DJnCW7n3GZ4/DqAMP4cglE0IEjGsM6jrDTdbjMlqt6u1RZ+XgUtJktf9g086s/4Rx29V1wtUbqYfjHf3dwYB59Lj3d/mGvuMY0VpcVehYh2CRShPGoFxJ8+FqJSYQsrlu0CeC0QASBx7LUo7PX4N8QLCrmXf2ELzzGoEQl1UWomyufrd/+KcP8hvbWaZZSgoy4ww+3hHCf+RuuLsj4twyhwsFdS4/M0nVQrvTFjsIjeePI9Cwi/yeRph17AIKIjrxgCxHROz1cg3dZD/1fb2m5m6d+SJkuzEAvsP7eypncGOZpO/djhAMD/AfJpJA15uOl/G84G80bZCCFnpK8Rw== spierrot@Sylvains-Air.localdomain" shell: /bin/bash disable_root: true @@ -51,9 +49,32 @@ write_files: make virtualenv source .venv/bin/activate make update-virtualenv - permissions: '0755' + permissions: '0755' +- path: /etc/systemd/system/ud3tn.service + content: | + [Unit] + Description=uD3TN Bundle Protocol Implementation + After=network.target + + [Service] + Type=simple + User=root + WorkingDirectory=/opt/ud3tn + ExecStart=/opt/ud3tn/build/posix/ud3tn \ + --allow-remote-config \ + --eid ipn:20.0 \ + --aap2-socket ./ud3tn.aap2.socket.2 \ + --cla "tcpclv3:*,4556" -L 4 + Restart=always + RestartSec=5 + + [Install] + WantedBy=multi-user.target + permissions: '0644' runcmd: - bash /var/run/scripts/provision.sh - chown -R ubuntu:ubuntu /opt/ud3tn -- netplan apply \ No newline at end of file +- netplan apply +- systemctl daemon-reload +- systemctl enable --now ud3tn.service \ No newline at end of file diff --git a/daemon/Makefile b/daemon/Makefile index f7bf80c..f1b4e5f 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -11,7 +11,7 @@ OBJECTS := $(SOURCES:.c=.o) SRC_FILES := $(wildcard *.c *.h) -.PHONY: all release clean format +.PHONY: all release clean format install all: $(EXEC) @@ -28,4 +28,10 @@ clean: rm -f $(EXEC) $(OBJECTS) format: - clang-format -i --style=file $(SRC_FILES) \ No newline at end of file + clang-format -i --style=file $(SRC_FILES) + +install: $(EXEC) + @echo "Installing daemon..." + install -d /usr/local/bin + install -m 755 $(EXEC) /usr/local/bin/ + @echo "Daemon installed successfully!" \ No newline at end of file diff --git a/daemon/bp_genl.c b/daemon/bp_genl.c index fb6b4d8..8bc01e5 100644 --- a/daemon/bp_genl.c +++ b/daemon/bp_genl.c @@ -72,7 +72,8 @@ int bp_genl_message_handler(struct nl_msg *msg, void *arg) { err = nla_parse(attrs, BP_GENL_A_MAX, genlmsg_attrdata(genlhdr, 0), genlmsg_attrlen(genlhdr, 0), NULL); if (err < 0) { - log_error("Failed to parse Netlink attributes: %s", nl_geterror(err)); + log_error("bp_genl_handle_msg: failed to parse Netlink attributes for cmd %d: %s", + genlhdr->cmd, nl_geterror(err)); return NL_SKIP; } @@ -86,7 +87,7 @@ int bp_genl_message_handler(struct nl_msg *msg, void *arg) { case BP_GENL_CMD_DESTROY_BUNDLE: return handle_destroy_bundle(daemon, attrs); default: - log_error("Unknown Generic Netlink command: %d", genlhdr->cmd); + log_error("bp_genl_handle_msg: unknown Generic Netlink command: %d", genlhdr->cmd); return NL_SKIP; } } diff --git a/daemon/bp_genl_handlers.c b/daemon/bp_genl_handlers.c index c7ebe1e..d25d578 100644 --- a/daemon/bp_genl_handlers.c +++ b/daemon/bp_genl_handlers.c @@ -30,9 +30,10 @@ int handle_open_endpoint(Daemon *daemon, struct nlattr **attrs) { ret = ion_open_endpoint(node_id, service_id, daemon->genl_bp_sock, &daemon->netlink_mutex, daemon->genl_bp_family_id); if (ret == 0) { - log_info("[ipn:%u.%u] OPEN_ENDPOINT: endpoint opened successfully", node_id, service_id); + log_info("[ipn:%u.%u] Endpoint opened: spawning receiver and sender threads", node_id, + service_id); } else { - log_error("[ipn:%u.%u] OPEN_ENDPOINT: failed to open endpoint (error %d)", node_id, + log_error("handle_open_endpoint: failed to open endpoint ipn:%u.%u (error %d)", node_id, service_id, ret); } return ret; @@ -51,9 +52,9 @@ int handle_close_endpoint(Daemon *daemon, struct nlattr **attrs) { int ret = ion_close_endpoint(node_id, service_id); if (ret == 0) { - log_info("[ipn:%u.%u] CLOSE_ENDPOINT: closing endpoint", node_id, service_id); + log_info("[ipn:%u.%u] Endpoint closed gracefully", node_id, service_id); } else { - log_error("[ipn:%u.%u] CLOSE_ENDPOINT: failed to close endpoint (error %d)", node_id, + log_error("handle_close_endpoint: failed to close endpoint ipn:%u.%u (error %d)", node_id, service_id, ret); } @@ -89,7 +90,7 @@ int handle_send_bundle(Daemon *daemon, struct nlattr **attrs) { written = snprintf(dest_eid, sizeof(dest_eid), "ipn:%u.%u", dest_node_id, dest_service_id); if (written < 0 || written >= (int)sizeof(dest_eid)) { - log_error("[ipn:%u.%u] handle_send_bundle: failed to construct EID string", src_node_id, + log_error("handle_send_bundle: failed to construct EID string for ipn:%u.%u", src_node_id, src_service_id); return -EINVAL; } @@ -97,14 +98,11 @@ int handle_send_bundle(Daemon *daemon, struct nlattr **attrs) { ret = endpoint_registry_enqueue_send(src_node_id, src_service_id, dest_eid, payload, payload_size, flags); if (ret < 0) { - log_error("[ipn:%u.%u] handle_send_bundle: failed to enqueue send (error: %d)", src_node_id, - src_service_id, ret); + log_error("handle_send_bundle: failed to enqueue send for ipn:%u.%u (error: %d)", + src_node_id, src_service_id, ret); return ret; } - log_info("[ipn:%u.%u] SEND_BUNDLE: bundle queued for sending to EID %s, size %zu (bytes)", - src_node_id, src_service_id, dest_eid, payload_size); - return 0; } @@ -126,7 +124,7 @@ int handle_destroy_bundle(Daemon *daemon, struct nlattr **attrs) { return ret; } - log_info("DESTROY_BUNDLE: bundle consumed by a socket (adu: %llu)", (unsigned long long)adu); + log_info("Bundle consumed: successfully destroyed ADU %llu", (unsigned long long)adu); return 0; } \ No newline at end of file diff --git a/daemon/daemon.c b/daemon/daemon.c index f92edda..bafc0c8 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -44,8 +44,8 @@ int daemon_run(Daemon *self) { log_error("Failed to create libevent base"); return -ENOMEM; } - log_info("Using libevent version %s with %s behind the scenes", (char *)event_get_version(), - (char *)event_base_get_method(self->base)); + log_debug("Using libevent version %s with %s behind the scenes", (char *)event_get_version(), + (char *)event_base_get_method(self->base)); self->event_on_sigint = evsignal_new(self->base, SIGINT, on_sigint, self->base); if (!self->event_on_sigint) { @@ -79,8 +79,6 @@ int daemon_run(Daemon *self) { daemon_free(self); return -ENOMEM; } - log_info("Generic Netlink: GENL_BP open socket"); - fd = nl_socket_get_fd(self->genl_bp_sock); self->event_on_nl_sock = event_new(self->base, fd, EV_READ | EV_PERSIST, on_netlink, self); if (!self->event_on_nl_sock) { @@ -109,9 +107,8 @@ int daemon_run(Daemon *self) { return -EAGAIN; } sdr = bp_get_sdr(); - log_info("Successfully attached to ION"); - log_info("Daemon started successfully"); + log_info("Daemon started successfully - attached to ION, Netlink ready"); event_base_dispatch(self->base); log_info("Daemon terminated"); @@ -124,13 +121,12 @@ int daemon_run(Daemon *self) { void daemon_free(Daemon *self) { if (!self) return; - bp_genl_socket_destroy(self); - if (self->event_on_nl_sock) event_free(self->event_on_nl_sock); if (self->event_on_sigpipe) event_free(self->event_on_sigpipe); if (self->event_on_sigint) event_free(self->event_on_sigint); if (self->base) event_base_free(self->base); + bp_genl_socket_destroy(self); pthread_mutex_destroy(&self->netlink_mutex); #if LIBEVENT_VERSION_NUMBER >= 0x02010000 diff --git a/daemon/endpoint_registry.c b/daemon/endpoint_registry.c index b0035c1..ebd69fb 100644 --- a/daemon/endpoint_registry.c +++ b/daemon/endpoint_registry.c @@ -150,9 +150,10 @@ int endpoint_registry_enqueue_send(uint32_t node_id, uint32_t service_id, const pthread_mutex_lock(&ctx->send_queue_mutex); - if (ctx->send_queue_size >= 1000) { // Limite de queue + if (ctx->send_queue_size >= 5000) { pthread_mutex_unlock(&ctx->send_queue_mutex); - log_warn("endpoint_registry_enqueue_send: queue full for ipn:%u.%u", node_id, service_id); + log_warn("endpoint_registry_enqueue_send: queue full for ipn:%u.%u (size: %d)", node_id, + service_id, ctx->send_queue_size); free(item->dest_eid); free(item->payload); free(item); @@ -172,4 +173,4 @@ int endpoint_registry_enqueue_send(uint32_t node_id, uint32_t service_id, const pthread_mutex_unlock(&ctx->send_queue_mutex); return 0; -} +} \ No newline at end of file diff --git a/daemon/ion.c b/daemon/ion.c index e81c07b..c84664e 100644 --- a/daemon/ion.c +++ b/daemon/ion.c @@ -159,15 +159,13 @@ void *ion_send_thread(void *arg) { Object adu = 0; struct bp_send_flags parsed_flags; - log_info("ion_send_thread: started for ipn:%u.%u", ctx->node_id, ctx->service_id); - - while (__atomic_load_n(&ctx->running, __ATOMIC_RELAXED)) { + while (true) { pthread_mutex_lock(&ctx->send_queue_mutex); while (ctx->send_queue_head == NULL && __atomic_load_n(&ctx->running, __ATOMIC_RELAXED)) { pthread_cond_wait(&ctx->send_queue_cond, &ctx->send_queue_mutex); } - if (!__atomic_load_n(&ctx->running, __ATOMIC_RELAXED)) { + if (ctx->send_queue_head == NULL && !__atomic_load_n(&ctx->running, __ATOMIC_RELAXED)) { pthread_mutex_unlock(&ctx->send_queue_mutex); break; } @@ -194,7 +192,8 @@ void *ion_send_thread(void *arg) { sdr_buffer = sdr_malloc(sdr, item->payload_size); if (sdr_buffer == 0) { pthread_mutex_unlock(&sdrmutex); - log_error("ion_send_thread: no space for payload"); + log_error("ion_send_thread: no space for payload (size: %zu) - ION SDR full", + item->payload_size); goto cleanup_item; } @@ -223,8 +222,9 @@ void *ion_send_thread(void *arg) { goto cleanup_item; } - log_info("ion_send_thread: bundle sent to %s (size: %zu)", item->dest_eid, - item->payload_size); + log_info("[ipn:%u.%u] Outbound bundle: destination=%s, payload_size=%zu bytes, " + "flags=0x%08x", + ctx->node_id, ctx->service_id, item->dest_eid, item->payload_size, item->flags); cleanup_item: free(item->dest_eid); @@ -232,7 +232,6 @@ void *ion_send_thread(void *arg) { free(item); } - log_info("ion_send_thread: exiting for ipn:%u.%u", ctx->node_id, ctx->service_id); free(args); return NULL; } @@ -370,8 +369,8 @@ void *ion_receive_thread(void *arg) { bp_release_delivery(&dlv, 0); if (!payload) { - log_info("ion_receive_thread: no payload received for node_id=%u service_id=%u", - dest_node_id, dest_service_id); + log_debug("ion_receive_thread: no payload received for node_id=%u service_id=%u", + dest_node_id, dest_service_id); continue; } @@ -382,8 +381,8 @@ void *ion_receive_thread(void *arg) { log_error("[ipn:%u.%u] bp_genl_enqueue_bundle: failed with error %d", dest_node_id, dest_service_id, err); } else { - log_info("[ipn:%u.%u] ENQUEUE_BUNDLE: incoming bundle queued in the kernel (adu: %llu)", - dest_node_id, dest_service_id, (unsigned long long)dlv.adu); + log_info("[ipn:%u.%u] Inbound bundle: source=ipn:%u.%u, payload_size=%zu bytes", + ctx->node_id, ctx->service_id, src_node_id, src_service_id, payload_size); } free(payload); diff --git a/receiver.c b/receiver.c index 840fab7..7aa277e 100644 --- a/receiver.c +++ b/receiver.c @@ -1,4 +1,4 @@ -#include "include/bp_socket.h" +#include "bp_socket.h" #include #include #include diff --git a/sender.c b/sender.c index 9cc334d..f9ed212 100644 --- a/sender.c +++ b/sender.c @@ -1,4 +1,4 @@ -#include "include/bp_socket.h" +#include "bp_socket.h" #include #include #include