Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ set(COMMON_SOURCES
src/core.c
src/crypto.c
src/network.c
src/packet_validate.c
src/opus_codec.c
src/display_sdl2.c
src/config.c
Expand Down Expand Up @@ -234,6 +235,7 @@ if(UNIX AND NOT APPLE)
src/vaapi_decoder.c
src/display_sdl2.c
src/network.c
src/packet_validate.c
src/crypto.c
src/config.c
src/input.c
Expand Down Expand Up @@ -344,6 +346,10 @@ add_executable(test_encoding tests/unit/test_encoding.c)
target_include_directories(test_encoding PRIVATE ${CMAKE_SOURCE_DIR}/include)
add_test(NAME encoding_tests COMMAND test_encoding)

add_executable(test_packet tests/unit/test_packet.c src/packet_validate.c)
target_include_directories(test_packet PRIVATE ${CMAKE_SOURCE_DIR}/include)
add_test(NAME packet_tests COMMAND test_packet)

# =============================================================================
# Summary
# =============================================================================
Expand Down
8 changes: 8 additions & 0 deletions assets/rootstream.desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Name=RootStream
Comment=Secure peer-to-peer game streaming
Exec=rootstream
Icon=rootstream
Terminal=false
Categories=Game;Network;
1 change: 1 addition & 0 deletions include/rootstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ int rootstream_net_send_video(rootstream_ctx_t *ctx, peer_t *peer,
int rootstream_net_recv(rootstream_ctx_t *ctx, int timeout_ms);
int rootstream_net_handshake(rootstream_ctx_t *ctx, peer_t *peer);
void rootstream_net_tick(rootstream_ctx_t *ctx);
int rootstream_net_validate_packet(const uint8_t *buffer, size_t len);

/* --- Peer Management --- */
peer_t* rootstream_add_peer(rootstream_ctx_t *ctx, const char *rootstream_code);
Expand Down
13 changes: 13 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ install_binary() {

sudo install -m 755 rootstream /usr/local/bin/
echo -e "${GREEN}✓ Installed to /usr/local/bin/rootstream${NC}"

if [ -f assets/rootstream.desktop ]; then
sudo install -m 644 assets/rootstream.desktop /usr/local/share/applications/rootstream.desktop
fi
if [ -f assets/rootstream.png ]; then
sudo install -m 644 assets/rootstream.png /usr/local/share/icons/hicolor/256x256/apps/rootstream.png
fi
}

# Setup permissions
Expand Down Expand Up @@ -181,6 +188,12 @@ main() {
install_binary
setup_permissions
test_vaapi

if [ -f rootstream.service ]; then
echo -e "\n${BLUE}🧩 Installing systemd service template...${NC}"
sudo install -m 644 rootstream.service /etc/systemd/system/rootstream@.service
echo -e "${GREEN}✓ Installed /etc/systemd/system/rootstream@.service${NC}"
fi

echo -e "\n${GREEN}╔═══════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ 🎉 Installation Complete! ║${NC}"
Expand Down
13 changes: 3 additions & 10 deletions src/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,19 +379,12 @@ int rootstream_net_recv(rootstream_ctx_t *ctx, int timeout_ms) {
return 0;
}

packet_header_t *hdr = (packet_header_t*)buffer;

/* Validate magic number */
if (hdr->magic != PACKET_MAGIC) {
fprintf(stderr, "WARNING: Invalid magic number, ignoring packet\n");
if (rootstream_net_validate_packet(buffer, (size_t)recv_len) != 0) {
fprintf(stderr, "WARNING: Invalid packet received (%d bytes)\n", recv_len);
return 0;
}

/* Validate version */
if (hdr->version != 1) {
fprintf(stderr, "WARNING: Unsupported protocol version %d\n", hdr->version);
return 0;
}
packet_header_t *hdr = (packet_header_t*)buffer;

/* Find or create peer */
peer_t *peer = rootstream_find_peer_by_addr(ctx, &from, fromlen);
Expand Down
6 changes: 6 additions & 0 deletions src/network_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ int rootstream_net_recv(rootstream_ctx_t *ctx, int timeout_ms) {
return -1;
}

int rootstream_net_validate_packet(const uint8_t *buffer, size_t len) {
(void)buffer;
(void)len;
return -1;
}

int rootstream_net_handshake(rootstream_ctx_t *ctx, peer_t *peer) {
(void)ctx;
(void)peer;
Expand Down
26 changes: 26 additions & 0 deletions src/packet_validate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* packet_validate.c - Lightweight packet validation
*/

#include "../include/rootstream.h"

int rootstream_net_validate_packet(const uint8_t *buffer, size_t len) {
if (!buffer || len < sizeof(packet_header_t)) {
return -1;
}

const packet_header_t *hdr = (const packet_header_t*)buffer;
if (hdr->magic != 0x524F4F54) {
return -1;
}

if (hdr->version != 1) {
return -1;
}

if (hdr->payload_size > len - sizeof(packet_header_t)) {
return -1;
}

return 0;
}
46 changes: 46 additions & 0 deletions tests/unit/test_packet.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "../../include/rootstream.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void fill_random(uint8_t *buf, size_t len) {
for (size_t i = 0; i < len; i++) {
buf[i] = (uint8_t)(rand() & 0xFF);
}
}

int main(void) {
srand(1);

uint8_t buffer[512];

/* Random fuzz cases should never crash */
for (int i = 0; i < 1000; i++) {
size_t len = (size_t)(rand() % sizeof(buffer));
fill_random(buffer, len);
(void)rootstream_net_validate_packet(buffer, len);
}

/* Construct a minimal valid packet */
packet_header_t hdr = {0};
hdr.magic = 0x524F4F54;
hdr.version = 1;
hdr.type = PKT_PING;
hdr.payload_size = 0;

memcpy(buffer, &hdr, sizeof(hdr));
if (rootstream_net_validate_packet(buffer, sizeof(hdr)) != 0) {
fprintf(stderr, "Expected valid packet to pass validation\n");
return 1;
}

/* Invalid payload size should fail */
hdr.payload_size = 1024;
memcpy(buffer, &hdr, sizeof(hdr));
if (rootstream_net_validate_packet(buffer, sizeof(hdr)) == 0) {
fprintf(stderr, "Expected oversized payload to fail validation\n");
return 1;
}

return 0;
}
11 changes: 11 additions & 0 deletions tools/smoke.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

cmake -S "${ROOT_DIR}" -B "${ROOT_DIR}/build"
cmake --build "${ROOT_DIR}/build"
ctest --test-dir "${ROOT_DIR}/build"

"${ROOT_DIR}/build/rootstream" --version
"${ROOT_DIR}/build/rootstream" --help >/dev/null
Loading