|
STAR
Cal STAR — firmware, DAQ server, and engine design
|
#include <arpa/inet.h>#include <netinet/in.h>#include <sys/socket.h>#include <unistd.h>#include <atomic>#include <cstring>#include <iostream>#include <string>#include <thread>#include <vector>#include "elodin/ElodinClient.hpp"Go to the source code of this file.
Classes | |
| struct | FakeDb |
| Fake elodin-db: accept one connection, write blob, then hold the socket open. More... | |
Functions | |
| static void | check (bool ok, const std::string &what) |
| static std::vector< uint8_t > | frame (uint8_t hi, uint8_t lo, size_t payload_len, uint8_t fill) |
| One wire packet: len(4, LE) then len bytes of body, where the first 4 body bytes are ty/packet_id(2)/request_id. | |
| int | main () |
Variables | |
| static int | g_failures = 0 |
| ElodinClient::read_packet() framing — what happens when a packet does not fit. | |
|
static |
Definition at line 39 of file test_elodin_read_path.cpp.
References g_failures, and ok.
Referenced by main().
|
static |
One wire packet: len(4, LE) then len bytes of body, where the first 4 body bytes are ty/packet_id(2)/request_id.
So len = payload + 4, and the whole frame is payload + 8. read_packet() reports packet_len + 4, i.e. the same payload + 8.
Definition at line 50 of file test_elodin_read_path.cpp.
Referenced by ack(), configure(), gnss_core_request_status(), main(), main(), pvt(), sd_command(), sd_read_cid(), send_config(), anonymous_namespace{idle_e2e.cpp}::send_heartbeat(), test_command_frames(), test_send_keeps_a_packet_that_just_arrived(), test_send_refuses_bad_input_and_dead_chip(), test_send_returns_to_duty_cycle_not_continuous(), test_send_times_out(), and test_send_waits_for_tx_done_and_returns_to_rx().
| int main | ( | ) |
Definition at line 121 of file test_elodin_read_path.cpp.
References check(), fsw::elodin::ElodinClient::connect(), frame(), g_failures, fsw::elodin::ElodinClient::is_connected(), kMax, FakeDb::port, r, fsw::elodin::ElodinClient::read_packet(), FakeDb::start(), and FakeDb::stop().
|
static |
ElodinClient::read_packet() framing — what happens when a packet does not fit.
The stream is length-prefixed packets back to back on one TCP connection, so the only thing keeping a reader aligned is consuming exactly as many bytes as each length announced.
read_packet() used to break that. On a packet larger than the caller's buffer it returned -1 having already consumed the 8-byte header but not the body, leaving the rest of that packet in the socket. Every later read then parsed payload bytes as a header, and since nothing marked the socket dead, is_connected() kept reporting true and callers looped on garbage forever. Observed against a real elodin-db: one 179-byte packet against a 160-byte buffer, then "Invalid packet length: 1638688", "134742016", "268436225" ... indefinitely.
It also mis-sized its own bound. The check was packet_len > max_len, but the function writes 8 + (packet_len - 4) = packet_len + 4 bytes, so packet_len == max_len passed and overran the caller's buffer by 4. Confirmed with a guard page: the kernel returned EFAULT at exactly that boundary.
These tests use a fake elodin-db rather than the real one so they can produce packet sizes on demand — nothing a live db emits today is big enough to trip either bug, which is why neither was noticed.
Definition at line 37 of file test_elodin_read_path.cpp.