Enable -Weverything, fix a ton of bugs.

This commit is contained in:
Ian Gulliver
2016-02-25 23:37:37 -08:00
parent fe2486c398
commit 19a9d498bd
40 changed files with 220 additions and 184 deletions

View File

@@ -1,6 +1,7 @@
CC ?= clang CC = clang
CFLAGS ?= -Wall -Werror -Wshadow -O4 -g --std=gnu11 --pedantic-errors -fPIE -pie -fstack-protector-strong -pthread DISABLED_WARNINGS ?= -Wno-padded -Wno-disabled-macro-expansion
LDFLAGS ?= $(CFLAGS) -Wl,-z,relro -Wl,-z,now CFLAGS ?= -Weverything -Werror -O3 -g --std=gnu11 --pedantic-errors -fPIE -fstack-protector-strong -pthread -D_GNU_SOURCE $(DISABLED_WARNINGS)
LDFLAGS ?= $(CFLAGS) -Wl,-z,relro -Wl,-z,now -pie
LIBS ?= -ljansson -lprotobuf-c LIBS ?= -ljansson -lprotobuf-c
OBJ_NETWORK = incoming.o outgoing.o receive.o send.o OBJ_NETWORK = incoming.o outgoing.o receive.o send.o

View File

@@ -118,7 +118,7 @@ int main(int argc, char *argv[]) {
stats_init(); stats_init();
if (!parse_opts(argc, argv)) { if (!parse_opts(argc, argv)) {
peer_shutdown(); peer_shutdown(0);
} }
assert(!close(0)); assert(!close(0));

View File

@@ -13,17 +13,17 @@
#define SEND_MHZ 20 #define SEND_MHZ 20
struct __attribute__((packed)) airspy_adsb_common_overlay { struct __attribute__((packed)) airspy_adsb_common_overlay {
char mlat_timestamp[8]; uint8_t mlat_timestamp[8];
char semicolon1; char semicolon1;
char mlat_precision[2]; uint8_t mlat_precision[2];
char semicolon2; char semicolon2;
char rssi[4]; uint8_t rssi[4];
char semicolon3; char semicolon3;
}; };
struct __attribute__((packed)) airspy_adsb_mode_s_short_overlay { struct __attribute__((packed)) airspy_adsb_mode_s_short_overlay {
char asterisk; char asterisk;
char payload[14]; uint8_t payload[14];
char semicolon; char semicolon;
struct airspy_adsb_common_overlay common; struct airspy_adsb_common_overlay common;
char cr; char cr;
@@ -32,7 +32,7 @@ struct __attribute__((packed)) airspy_adsb_mode_s_short_overlay {
struct __attribute__((packed)) airspy_adsb_mode_s_long_overlay { struct __attribute__((packed)) airspy_adsb_mode_s_long_overlay {
char asterisk; char asterisk;
char payload[28]; uint8_t payload[28];
char semicolon; char semicolon;
struct airspy_adsb_common_overlay common; struct airspy_adsb_common_overlay common;
char cr; char cr;
@@ -49,9 +49,9 @@ static bool airspy_adsb_parse_common(const struct airspy_adsb_common_overlay *ov
overlay->semicolon3 != ';') { overlay->semicolon3 != ';') {
return false; return false;
} }
uint16_t mlat_mhz = 2 * hex_to_int(overlay->mlat_precision, sizeof(overlay->mlat_precision) / 2); uint16_t mlat_mhz = 2 * (uint16_t) hex_to_int(overlay->mlat_precision, sizeof(overlay->mlat_precision) / 2);
packet->mlat_timestamp = packet_mlat_timestamp_scale_in(hex_to_int(overlay->mlat_timestamp, sizeof(overlay->mlat_timestamp) / 2), UINT32_MAX, mlat_mhz, &state->mlat_state); packet->mlat_timestamp = packet_mlat_timestamp_scale_in(hex_to_int(overlay->mlat_timestamp, sizeof(overlay->mlat_timestamp) / 2), UINT32_MAX, mlat_mhz, &state->mlat_state);
packet->rssi = packet_rssi_scale_in(hex_to_int(overlay->rssi, sizeof(overlay->rssi) / 2), UINT16_MAX); packet->rssi = packet_rssi_scale_in((uint32_t) hex_to_int(overlay->rssi, sizeof(overlay->rssi) / 2), UINT16_MAX);
return true; return true;
} }

View File

@@ -5,6 +5,6 @@
struct buf; struct buf;
struct packet; struct packet;
void airspy_adsb_init(); void airspy_adsb_init(void);
bool airspy_adsb_parse(struct buf *, struct packet *, void *); bool airspy_adsb_parse(struct buf *, struct packet *, void *);
void airspy_adsb_serialize(struct packet *, struct buf *); void airspy_adsb_serialize(struct packet *, struct buf *);

View File

@@ -52,7 +52,7 @@ static void beast_write_mlat(uint64_t timestamp, uint8_t *mlat_timestamp) {
} }
static ssize_t beast_unescape(struct buf *out, const struct buf *in, size_t out_bytes) { static ssize_t beast_unescape(struct buf *out, const struct buf *in, size_t out_bytes) {
int o = 0, i = 0; size_t o = 0, i = 0;
for (; i < in->length && o < out_bytes; i++, o++) { for (; i < in->length && o < out_bytes; i++, o++) {
if (i > 0 && buf_chr(in, i) == 0x1a) { if (i > 0 && buf_chr(in, i) == 0x1a) {
if (i == in->length - 1 || buf_chr(in, i + 1) != 0x1a) { if (i == in->length - 1 || buf_chr(in, i + 1) != 0x1a) {
@@ -63,14 +63,14 @@ static ssize_t beast_unescape(struct buf *out, const struct buf *in, size_t out_
buf_chr(out, o) = buf_chr(in, i); buf_chr(out, o) = buf_chr(in, i);
} }
if (o == out_bytes) { if (o == out_bytes) {
return i; return (ssize_t) i;
} else { } else {
return -1; return -1;
} }
} }
static void beast_escape(struct buf *out, const struct buf *in) { static void beast_escape(struct buf *out, const struct buf *in) {
for (int i = 0; i < in->length; i++, out->length++) { for (size_t i = 0; i < in->length; i++, out->length++) {
buf_chr(out, out->length) = buf_chr(in, i); buf_chr(out, out->length) = buf_chr(in, i);
if (i > 0 && buf_chr(in, i) == 0x1a) { if (i > 0 && buf_chr(in, i) == 0x1a) {
buf_chr(out, ++(out->length)) = 0x1a; buf_chr(out, ++(out->length)) = 0x1a;
@@ -90,7 +90,7 @@ static bool beast_parse_mode_s_short(struct buf *buf, struct packet *packet, str
packet->mlat_timestamp = packet_mlat_timestamp_scale_in(source_mlat, UINT64_C(0xffffffffffff), 12, &state->mlat_state); packet->mlat_timestamp = packet_mlat_timestamp_scale_in(source_mlat, UINT64_C(0xffffffffffff), 12, &state->mlat_state);
packet->rssi = packet_rssi_scale_in(overlay->rssi, UINT8_MAX); packet->rssi = packet_rssi_scale_in(overlay->rssi, UINT8_MAX);
memcpy(packet->payload, overlay->payload, sizeof(overlay->payload)); memcpy(packet->payload, overlay->payload, sizeof(overlay->payload));
buf_consume(buf, in_bytes); buf_consume(buf, (size_t) in_bytes);
return true; return true;
} }
@@ -106,10 +106,50 @@ static bool beast_parse_mode_s_long(struct buf *buf, struct packet *packet, stru
packet->mlat_timestamp = packet_mlat_timestamp_scale_in(source_mlat, UINT64_C(0xffffffffffff), 12, &state->mlat_state); packet->mlat_timestamp = packet_mlat_timestamp_scale_in(source_mlat, UINT64_C(0xffffffffffff), 12, &state->mlat_state);
packet->rssi = packet_rssi_scale_in(overlay->rssi == UINT8_MAX ? 0 : overlay->rssi, UINT8_MAX); packet->rssi = packet_rssi_scale_in(overlay->rssi == UINT8_MAX ? 0 : overlay->rssi, UINT8_MAX);
memcpy(packet->payload, overlay->payload, sizeof(overlay->payload)); memcpy(packet->payload, overlay->payload, sizeof(overlay->payload));
buf_consume(buf, in_bytes); buf_consume(buf, (size_t) in_bytes);
return true; return true;
} }
static void beast_serialize_mode_s_short(struct packet *packet, struct buf *buf) {
struct buf buf2 = BUF_INIT;
struct beast_mode_s_short_overlay *overlay = (struct beast_mode_s_short_overlay *) buf_at(&buf2, 0);
overlay->common.one_a = 0x1a;
overlay->common.type = 0x32;
memcpy(overlay->payload, packet->payload, sizeof(overlay->payload));
beast_write_mlat(
packet_mlat_timestamp_scale_out(packet->mlat_timestamp, UINT64_C(0xffffffffffff), 12),
overlay->mlat_timestamp);
if (packet->rssi) {
overlay->rssi = (uint8_t) packet_rssi_scale_out(packet->rssi, UINT8_MAX);
} else {
overlay->rssi = UINT8_MAX;
}
buf2.length = sizeof(*overlay);
beast_escape(buf, &buf2);
}
static void beast_serialize_mode_s_long(struct packet *packet, struct buf *buf) {
struct buf buf2 = BUF_INIT;
struct beast_mode_s_long_overlay *overlay = (struct beast_mode_s_long_overlay *) buf_at(&buf2, 0);
overlay->common.one_a = 0x1a;
overlay->common.type = 0x33;
memcpy(overlay->payload, packet->payload, sizeof(overlay->payload));
beast_write_mlat(
packet_mlat_timestamp_scale_out(packet->mlat_timestamp, UINT64_C(0xffffffffffff), 12),
overlay->mlat_timestamp);
if (packet->rssi) {
overlay->rssi = (uint8_t) packet_rssi_scale_out(packet->rssi, UINT8_MAX);
} else {
overlay->rssi = UINT8_MAX;
}
buf2.length = sizeof(*overlay);
beast_escape(buf, &buf2);
}
void beast_init() { void beast_init() {
assert(sizeof(struct beast_parser_state) <= PARSER_STATE_LEN); assert(sizeof(struct beast_parser_state) <= PARSER_STATE_LEN);
assert(sizeof(struct beast_mode_s_short_overlay) * 2 <= BUF_LEN_MAX); assert(sizeof(struct beast_mode_s_short_overlay) * 2 <= BUF_LEN_MAX);
@@ -139,46 +179,6 @@ bool beast_parse(struct buf *buf, struct packet *packet, void *state_in) {
return false; return false;
} }
void beast_serialize_mode_s_short(struct packet *packet, struct buf *buf) {
struct buf buf2 = BUF_INIT;
struct beast_mode_s_short_overlay *overlay = (struct beast_mode_s_short_overlay *) buf_at(&buf2, 0);
overlay->common.one_a = 0x1a;
overlay->common.type = 0x32;
memcpy(overlay->payload, packet->payload, sizeof(overlay->payload));
beast_write_mlat(
packet_mlat_timestamp_scale_out(packet->mlat_timestamp, UINT64_C(0xffffffffffff), 12),
overlay->mlat_timestamp);
if (packet->rssi) {
overlay->rssi = packet_rssi_scale_out(packet->rssi, UINT8_MAX);
} else {
overlay->rssi = UINT8_MAX;
}
buf2.length = sizeof(*overlay);
beast_escape(buf, &buf2);
}
void beast_serialize_mode_s_long(struct packet *packet, struct buf *buf) {
struct buf buf2 = BUF_INIT;
struct beast_mode_s_long_overlay *overlay = (struct beast_mode_s_long_overlay *) buf_at(&buf2, 0);
overlay->common.one_a = 0x1a;
overlay->common.type = 0x33;
memcpy(overlay->payload, packet->payload, sizeof(overlay->payload));
beast_write_mlat(
packet_mlat_timestamp_scale_out(packet->mlat_timestamp, UINT64_C(0xffffffffffff), 12),
overlay->mlat_timestamp);
if (packet->rssi) {
overlay->rssi = packet_rssi_scale_out(packet->rssi, UINT8_MAX);
} else {
overlay->rssi = UINT8_MAX;
}
buf2.length = sizeof(*overlay);
beast_escape(buf, &buf2);
}
void beast_serialize(struct packet *packet, struct buf *buf) { void beast_serialize(struct packet *packet, struct buf *buf) {
if (!packet) { if (!packet) {
return; return;

View File

@@ -5,6 +5,6 @@
struct buf; struct buf;
struct packet; struct packet;
void beast_init(); void beast_init(void);
bool beast_parse(struct buf *, struct packet *, void *); bool beast_parse(struct buf *, struct packet *, void *);
void beast_serialize(struct packet *, struct buf *); void beast_serialize(struct packet *, struct buf *);

View File

@@ -21,7 +21,7 @@ ssize_t buf_fill(struct buf *buf, int fd) {
if (in <= 0) { if (in <= 0) {
return in; return in;
} }
buf->length += in; buf->length += (size_t) in;
return in; return in;
} }

View File

@@ -1,11 +1,12 @@
#pragma once #pragma once
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include <unistd.h> #include <unistd.h>
#define BUF_LEN_MAX 256 #define BUF_LEN_MAX 256
struct buf { struct buf {
char buf[BUF_LEN_MAX]; uint8_t buf[BUF_LEN_MAX];
size_t start; size_t start;
size_t length; size_t length;
}; };

View File

@@ -1,30 +1,33 @@
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include "hex.h" #include "hex.h"
static uint8_t hex_table[256] = {0}; static uint8_t hex_table[256] = {0};
static char hex_upper_table[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', }; static uint8_t hex_upper_table[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', };
static char hex_lower_table[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', }; static uint8_t hex_lower_table[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', };
void hex_init() { void hex_init() {
for (int i = '0'; i <= '9'; i++) { for (uint8_t i = '0'; i <= '9'; i++) {
hex_table[i] = i - '0'; hex_table[i] = i - '0';
} }
for (int i = 'a'; i <= 'f'; i++) { for (uint8_t i = 'a'; i <= 'f'; i++) {
hex_table[i] = 10 + i - 'a'; hex_table[i] = 10 + i - 'a';
} }
for (int i = 'A'; i <= 'F'; i++) { for (uint8_t i = 'A'; i <= 'F'; i++) {
hex_table[i] = 10 + i - 'A'; hex_table[i] = 10 + i - 'A';
} }
} }
void hex_to_bin(uint8_t *out, const char *in, size_t bytes) { void hex_to_bin(uint8_t *out, const uint8_t *in, size_t bytes) {
const uint8_t *in2 = (uint8_t *) in;
for (size_t i = 0, j = 0; i < bytes; i++, j += 2) { for (size_t i = 0, j = 0; i < bytes; i++, j += 2) {
out[i] = (hex_table[in2[j]] << 4) | hex_table[in2[j + 1]]; out[i] = (uint8_t) (hex_table[in[j]] << 4) | hex_table[in[j + 1]];
} }
} }
uint64_t hex_to_int(const char *in, size_t bytes) { uint64_t hex_to_int(const uint8_t *in, size_t bytes) {
const uint8_t *in2 = (uint8_t *) in; const uint8_t *in2 = (const uint8_t *) in;
uint64_t ret = 0; uint64_t ret = 0;
bytes *= 2; bytes *= 2;
for (size_t i = 0; i < bytes; i++) { for (size_t i = 0; i < bytes; i++) {
@@ -34,33 +37,34 @@ uint64_t hex_to_int(const char *in, size_t bytes) {
return ret; return ret;
} }
static void hex_from_bin(char *out, const uint8_t *in, size_t bytes, char table[]) { static void hex_from_bin(uint8_t *out, const uint8_t *in, size_t bytes, uint8_t table[]) {
for (size_t i = 0, j = 0; i < bytes; i++, j += 2) { for (size_t i = 0, j = 0; i < bytes; i++, j += 2) {
out[j] = table[in[i] >> 4]; out[j] = table[in[i] >> 4];
out[j + 1] = table[in[i] & 0xf]; out[j + 1] = table[in[i] & 0xf];
} }
} }
static void hex_from_int(char *out, uint64_t in, size_t bytes, char table[]) { static void hex_from_int(uint8_t *out, uint64_t in, size_t bytes, uint8_t table[]) {
bytes *= 2; bytes *= 2;
for (int o = bytes - 1; o >= 0; o--) { assert(bytes < SSIZE_MAX);
for (ssize_t o = (ssize_t) bytes - 1; o >= 0; o--) {
out[o] = table[in & 0xf]; out[o] = table[in & 0xf];
in >>= 4; in >>= 4;
} }
} }
void hex_from_bin_upper(char *out, const uint8_t *in, size_t bytes) { void hex_from_bin_upper(uint8_t *out, const uint8_t *in, size_t bytes) {
hex_from_bin(out, in, bytes, hex_upper_table); hex_from_bin(out, in, bytes, hex_upper_table);
} }
void hex_from_bin_lower(char *out, const uint8_t *in, size_t bytes) { void hex_from_bin_lower(uint8_t *out, const uint8_t *in, size_t bytes) {
hex_from_bin(out, in, bytes, hex_lower_table); hex_from_bin(out, in, bytes, hex_lower_table);
} }
void hex_from_int_upper(char *out, uint64_t in, size_t bytes) { void hex_from_int_upper(uint8_t *out, uint64_t in, size_t bytes) {
hex_from_int(out, in, bytes, hex_upper_table); hex_from_int(out, in, bytes, hex_upper_table);
} }
void hex_from_int_lower(char *out, uint64_t in, size_t bytes) { void hex_from_int_lower(uint8_t *out, uint64_t in, size_t bytes) {
hex_from_int(out, in, bytes, hex_lower_table); hex_from_int(out, in, bytes, hex_lower_table);
} }

View File

@@ -3,10 +3,10 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
void hex_init(); void hex_init(void);
void hex_to_bin(uint8_t *, const char *, size_t); void hex_to_bin(uint8_t *, const uint8_t *, size_t);
uint64_t hex_to_int(const char *, size_t); uint64_t hex_to_int(const uint8_t *, size_t);
void hex_from_bin_upper(char *, const uint8_t *, size_t); void hex_from_bin_upper(uint8_t *, const uint8_t *, size_t);
void hex_from_bin_lower(char *, const uint8_t *, size_t); void hex_from_bin_lower(uint8_t *, const uint8_t *, size_t);
void hex_from_int_upper(char *, uint64_t, size_t); void hex_from_int_upper(uint8_t *, uint64_t, size_t);
void hex_from_int_lower(char *, uint64_t, size_t); void hex_from_int_lower(uint8_t *, uint64_t, size_t);

View File

@@ -1,5 +1,3 @@
#define _GNU_SOURCE
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -20,7 +18,7 @@
struct incoming { struct incoming {
struct peer peer; struct peer peer;
char id[UUID_LEN]; uint8_t id[UUID_LEN];
char *node; char *node;
char *service; char *service;
struct addrinfo *addrs; struct addrinfo *addrs;

View File

@@ -4,6 +4,6 @@
struct peer; struct peer;
void incoming_cleanup(); void incoming_cleanup(void);
typedef void (*incoming_connection_handler)(int fd, void *, struct peer *); typedef void (*incoming_connection_handler)(int fd, void *, struct peer *);
void incoming_new(char *, char *, incoming_connection_handler, void *, uint32_t *); void incoming_new(char *, char *, incoming_connection_handler, void *, uint32_t *);

View File

@@ -47,9 +47,9 @@ static void json_hello(struct buf *buf) {
static void json_add_common(struct packet *packet, json_t *obj) { static void json_add_common(struct packet *packet, json_t *obj) {
json_object_set_new(obj, "type", json_string(packet_type_names[packet->type])); json_object_set_new(obj, "type", json_string(packet_type_names[packet->type]));
json_object_set_new(obj, "source_id", json_string(packet->source_id)); json_object_set_new(obj, "source_id", json_string((const char *) packet->source_id));
if (packet->mlat_timestamp) { if (packet->mlat_timestamp) {
json_object_set_new(obj, "mlat_timestamp", json_integer(packet->mlat_timestamp)); json_object_set_new(obj, "mlat_timestamp", json_integer(packet->mlat_timestamp % INT64_MAX));
} }
if (packet->rssi) { if (packet->rssi) {
json_object_set_new(obj, "rssi", json_integer(packet->rssi)); json_object_set_new(obj, "rssi", json_integer(packet->rssi));
@@ -58,7 +58,7 @@ static void json_add_common(struct packet *packet, json_t *obj) {
static void json_serialize_mode_s_short(struct packet *packet, struct buf *buf) { static void json_serialize_mode_s_short(struct packet *packet, struct buf *buf) {
assert(packet->mlat_timestamp < PACKET_MLAT_MAX); assert(packet->mlat_timestamp < PACKET_MLAT_MAX);
char hexbuf[14]; uint8_t hexbuf[14];
hex_from_bin_upper(hexbuf, packet->payload, 7); hex_from_bin_upper(hexbuf, packet->payload, 7);
json_t *out = json_pack("{ss#}", "payload", hexbuf, 14); json_t *out = json_pack("{ss#}", "payload", hexbuf, 14);
json_add_common(packet, out); json_add_common(packet, out);
@@ -67,7 +67,7 @@ static void json_serialize_mode_s_short(struct packet *packet, struct buf *buf)
static void json_serialize_mode_s_long(struct packet *packet, struct buf *buf) { static void json_serialize_mode_s_long(struct packet *packet, struct buf *buf) {
assert(packet->mlat_timestamp < PACKET_MLAT_MAX); assert(packet->mlat_timestamp < PACKET_MLAT_MAX);
char hexbuf[28]; uint8_t hexbuf[28];
hex_from_bin_upper(hexbuf, packet->payload, 14); hex_from_bin_upper(hexbuf, packet->payload, 14);
json_t *out = json_pack("{ss#}", "payload", hexbuf, 28); json_t *out = json_pack("{ss#}", "payload", hexbuf, 28);
json_add_common(packet, out); json_add_common(packet, out);
@@ -91,11 +91,17 @@ static bool json_parse_header(json_t *in, struct packet *packet, struct json_par
return false; return false;
} }
state->mlat_timestamp_mhz = mlat_timestamp_mhz; if (mlat_timestamp_mhz > UINT16_MAX ||
state->mlat_timestamp_max = mlat_timestamp_max; mlat_timestamp_max < 0 ||
state->rssi_max = rssi_max; rssi_max > UINT32_MAX) {
return false;
}
if (!strcmp(json_server_id, server_id)) { state->mlat_timestamp_mhz = (uint16_t) mlat_timestamp_mhz;
state->mlat_timestamp_max = (uint64_t) mlat_timestamp_max;
state->rssi_max = (uint32_t) rssi_max;
if (!strcmp(json_server_id, (const char *) server_id)) {
fprintf(stderr, "R %s: Attempt to receive json data from our own server ID (%s); loop!\n", packet->source_id, server_id); fprintf(stderr, "R %s: Attempt to receive json data from our own server ID (%s); loop!\n", packet->source_id, server_id);
return false; return false;
} }
@@ -118,8 +124,12 @@ static bool json_parse_common(json_t *in, struct packet *packet, struct json_par
json_t *mlat_timestamp = json_object_get(in, "mlat_timestamp"); json_t *mlat_timestamp = json_object_get(in, "mlat_timestamp");
if (mlat_timestamp && json_is_integer(mlat_timestamp)) { if (mlat_timestamp && json_is_integer(mlat_timestamp)) {
json_int_t val = json_integer_value(mlat_timestamp);
if (val < 0) {
return false;
}
packet->mlat_timestamp = packet_mlat_timestamp_scale_in( packet->mlat_timestamp = packet_mlat_timestamp_scale_in(
json_integer_value(mlat_timestamp), (uint64_t) val,
state->mlat_timestamp_max, state->mlat_timestamp_max,
state->mlat_timestamp_mhz, state->mlat_timestamp_mhz,
&state->mlat_state); &state->mlat_state);
@@ -127,7 +137,11 @@ static bool json_parse_common(json_t *in, struct packet *packet, struct json_par
json_t *rssi = json_object_get(in, "rssi"); json_t *rssi = json_object_get(in, "rssi");
if (rssi && json_is_integer(rssi)) { if (rssi && json_is_integer(rssi)) {
packet->rssi = packet_rssi_scale_in(json_integer_value(rssi), state->rssi_max); json_int_t val = json_integer_value(rssi);
if (val > state->rssi_max) {
return false;
}
packet->rssi = packet_rssi_scale_in((uint32_t) val, state->rssi_max);
} }
return true; return true;
@@ -143,7 +157,7 @@ static bool json_parse_mode_s_short(json_t *in, struct packet *packet, struct js
return false; return false;
} }
hex_to_bin(packet->payload, json_string_value(payload), 7); hex_to_bin(packet->payload, (const uint8_t *) json_string_value(payload), 7);
packet->type = PACKET_TYPE_MODE_S_SHORT; packet->type = PACKET_TYPE_MODE_S_SHORT;
return true; return true;
} }
@@ -158,7 +172,7 @@ static bool json_parse_mode_s_long(json_t *in, struct packet *packet, struct jso
return false; return false;
} }
hex_to_bin(packet->payload, json_string_value(payload), 14); hex_to_bin(packet->payload, (const uint8_t *) json_string_value(payload), 14);
packet->type = PACKET_TYPE_MODE_S_LONG; packet->type = PACKET_TYPE_MODE_S_LONG;
return true; return true;
} }
@@ -187,7 +201,7 @@ bool json_parse(struct buf *buf, struct packet *packet, void *state_in) {
} }
json_error_t err; json_error_t err;
json_t *in = json_loadb(buf_at(buf, 0), buf->length, JSON_DISABLE_EOF_CHECK | JSON_REJECT_DUPLICATES, &err); json_t *in = json_loadb((const char *) buf_at(buf, 0), buf->length, JSON_DISABLE_EOF_CHECK | JSON_REJECT_DUPLICATES, &err);
if (!in) { if (!in) {
return false; return false;
} }
@@ -216,7 +230,8 @@ bool json_parse(struct buf *buf, struct packet *packet, void *state_in) {
return false; return false;
} }
buf_consume(buf, err.position); assert(err.position > 0);
buf_consume(buf, (size_t) err.position);
while (buf->length && (buf_chr(buf, 0) == '\r' || buf_chr(buf, 0) == '\n')) { while (buf->length && (buf_chr(buf, 0) == '\r' || buf_chr(buf, 0) == '\n')) {
buf_consume(buf, 1); buf_consume(buf, 1);
} }
@@ -231,6 +246,9 @@ void json_serialize(struct packet *packet, struct buf *buf) {
} }
switch (packet->type) { switch (packet->type) {
case PACKET_TYPE_NONE:
break;
case PACKET_TYPE_MODE_S_SHORT: case PACKET_TYPE_MODE_S_SHORT:
json_serialize_mode_s_short(packet, buf); json_serialize_mode_s_short(packet, buf);
break; break;
@@ -238,9 +256,6 @@ void json_serialize(struct packet *packet, struct buf *buf) {
case PACKET_TYPE_MODE_S_LONG: case PACKET_TYPE_MODE_S_LONG:
json_serialize_mode_s_long(packet, buf); json_serialize_mode_s_long(packet, buf);
break; break;
default:
break;
} }
} }

View File

@@ -5,8 +5,8 @@
struct buf; struct buf;
struct packet; struct packet;
void json_init(); void json_init(void);
void json_cleanup(); void json_cleanup(void);
bool json_parse(struct buf *, struct packet *, void *); bool json_parse(struct buf *, struct packet *, void *);
void json_serialize(struct packet *, struct buf *); void json_serialize(struct packet *, struct buf *);

View File

@@ -87,7 +87,7 @@ bool opts_add_listen_send(char *arg) {
return true; return true;
} }
bool opts_add_stdin(char *arg) { bool opts_add_stdin(char __attribute__((unused)) *arg) {
receive_new(dup(0), NULL, NULL); receive_new(dup(0), NULL, NULL);
return true; return true;
} }

View File

@@ -18,7 +18,7 @@
struct outgoing { struct outgoing {
struct peer peer; struct peer peer;
char id[UUID_LEN]; uint8_t id[UUID_LEN];
char *node; char *node;
char *service; char *service;
struct addrinfo *addrs; struct addrinfo *addrs;

View File

@@ -2,6 +2,6 @@
struct peer; struct peer;
void outgoing_cleanup(); void outgoing_cleanup(void);
typedef void (*outgoing_connection_handler)(int fd, void *, struct peer *); typedef void (*outgoing_connection_handler)(int fd, void *, struct peer *);
void outgoing_new(char *, char *, outgoing_connection_handler, void *, uint32_t *); void outgoing_new(char *, char *, outgoing_connection_handler, void *, uint32_t *);

View File

@@ -4,7 +4,7 @@
#define PACKET_DATA_LEN_MAX 14 #define PACKET_DATA_LEN_MAX 14
struct packet { struct packet {
const char *source_id; const uint8_t *source_id;
enum { enum {
PACKET_TYPE_NONE, PACKET_TYPE_NONE,
PACKET_TYPE_MODE_S_SHORT, PACKET_TYPE_MODE_S_SHORT,

View File

@@ -1,5 +1,3 @@
#define _GNU_SOURCE
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@@ -50,7 +48,7 @@ void peer_cleanup() {
assert(!close(peer_epoll_fd)); assert(!close(peer_epoll_fd));
} }
void peer_shutdown(int signal) { void peer_shutdown(int __attribute__((unused)) signal) {
assert(!close(peer_shutdown_fd)); assert(!close(peer_shutdown_fd));
} }

View File

@@ -12,10 +12,10 @@ struct peer {
extern uint32_t peer_count_in, peer_count_out; extern uint32_t peer_count_in, peer_count_out;
void peer_init(); void peer_init(void);
void peer_cleanup(); void peer_cleanup(void);
void peer_shutdown(); void peer_shutdown(int signal);
void peer_epoll_add(struct peer *, uint32_t); void peer_epoll_add(struct peer *, uint32_t);
void peer_epoll_del(struct peer *); void peer_epoll_del(struct peer *);
void peer_call(struct peer *); void peer_call(struct peer *);
void peer_loop(); void peer_loop(void);

View File

@@ -1,3 +1,6 @@
#pragma GCC diagnostic ignored "-Wcast-qual"
#pragma GCC diagnostic ignored "-Wpacked"
#include <arpa/inet.h> #include <arpa/inet.h>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
@@ -12,7 +15,7 @@
#define PROTO_MAGIC "aDsB" #define PROTO_MAGIC "aDsB"
struct proto_header { struct __attribute__((packed)) proto_header {
uint32_t length; uint32_t length;
}; };
@@ -30,7 +33,7 @@ static void proto_obj_to_buf(Adsb *wrapper, struct buf *buf) {
assert(!buf->length); assert(!buf->length);
struct proto_header *header = (struct proto_header *) buf_at(buf, 0); struct proto_header *header = (struct proto_header *) buf_at(buf, 0);
assert(sizeof(*header) <= BUF_LEN_MAX); assert(sizeof(*header) <= BUF_LEN_MAX);
uint32_t msg_len = adsb__get_packed_size(wrapper); size_t msg_len = adsb__get_packed_size(wrapper);
buf->length = sizeof(*header) + msg_len; buf->length = sizeof(*header) + msg_len;
assert(buf->length <= BUF_LEN_MAX); assert(buf->length <= BUF_LEN_MAX);
assert(adsb__pack(wrapper, (uint8_t *) buf_at(buf, sizeof(*header))) == msg_len); assert(adsb__pack(wrapper, (uint8_t *) buf_at(buf, sizeof(*header))) == msg_len);
@@ -72,11 +75,14 @@ static bool proto_parse_header(AdsbHeader *header, struct packet *packet, struct
return false; return false;
} }
state->mlat_timestamp_mhz = header->mlat_timestamp_mhz; if (header->mlat_timestamp_mhz > UINT16_MAX) {
return false;
}
state->mlat_timestamp_mhz = (uint16_t) header->mlat_timestamp_mhz;
state->mlat_timestamp_max = header->mlat_timestamp_max; state->mlat_timestamp_max = header->mlat_timestamp_max;
state->rssi_max = header->rssi_max; state->rssi_max = header->rssi_max;
if (!strcmp(header->server_id, server_id)) { if (!strcmp(header->server_id, (const char *) server_id)) {
fprintf(stderr, "R %s: Attempt to receive proto data from our own server ID (%s); loop!\n", packet->source_id, server_id); fprintf(stderr, "R %s: Attempt to receive proto data from our own server ID (%s); loop!\n", packet->source_id, server_id);
return false; return false;
} }
@@ -90,7 +96,7 @@ static bool proto_parse_packet(AdsbPacket *in, struct packet *packet, struct pro
return false; return false;
} }
packet->source_id = in->source_id; packet->source_id = (uint8_t *) in->source_id;
memcpy(packet->payload, in->payload.data, len); memcpy(packet->payload, in->payload.data, len);
if (in->has_mlat_timestamp) { if (in->has_mlat_timestamp) {
@@ -170,7 +176,7 @@ void proto_serialize(struct packet *packet, struct buf *buf) {
AdsbHeader header = ADSB_HEADER__INIT; AdsbHeader header = ADSB_HEADER__INIT;
header.magic = PROTO_MAGIC; header.magic = PROTO_MAGIC;
header.server_version = server_version; header.server_version = server_version;
header.server_id = server_id; header.server_id = (char *) server_id;
header.mlat_timestamp_mhz = PACKET_MLAT_MHZ; header.mlat_timestamp_mhz = PACKET_MLAT_MHZ;
header.mlat_timestamp_max = PACKET_MLAT_MAX; header.mlat_timestamp_max = PACKET_MLAT_MAX;
header.rssi_max = PACKET_RSSI_MAX; header.rssi_max = PACKET_RSSI_MAX;

View File

@@ -5,6 +5,6 @@
struct buf; struct buf;
struct packet; struct packet;
void proto_cleanup(); void proto_cleanup(void);
bool proto_parse(struct buf *, struct packet *, void *); bool proto_parse(struct buf *, struct packet *, void *);
void proto_serialize(struct packet *, struct buf *); void proto_serialize(struct packet *, struct buf *);

View File

@@ -1,17 +1,18 @@
#include <assert.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#include "buf.h" #include "buf.h"
#include "rand.h" #include "rand.h"
struct buf rand_buf = BUF_INIT; static struct buf rand_buf = BUF_INIT;
static int rand_fd; static int rand_fd;
void rand_init() { void rand_init() {
@@ -43,7 +44,9 @@ void rand_fill(void *value, size_t size) {
}, },
}; };
assert(readv(rand_fd, iov, 2) == rand_buf.start + size); size_t bytes = rand_buf.start + size;
assert(bytes < SSIZE_MAX);
assert(readv(rand_fd, iov, 2) == (ssize_t) bytes);
rand_buf.start = 0; rand_buf.start = 0;
rand_buf.length = BUF_LEN_MAX; rand_buf.length = BUF_LEN_MAX;
} }

View File

@@ -2,6 +2,6 @@
#include <stddef.h> #include <stddef.h>
void rand_init(); void rand_init(void);
void rand_cleanup(); void rand_cleanup(void);
void rand_fill(void *, size_t); void rand_fill(void *, size_t);

View File

@@ -11,7 +11,7 @@
struct __attribute__((packed)) raw_mode_s_short_overlay { struct __attribute__((packed)) raw_mode_s_short_overlay {
char asterisk; char asterisk;
char payload[14]; uint8_t payload[14];
char semicolon; char semicolon;
char cr_lf; char cr_lf;
char lf; char lf;
@@ -19,7 +19,7 @@ struct __attribute__((packed)) raw_mode_s_short_overlay {
struct __attribute__((packed)) raw_mode_s_long_overlay { struct __attribute__((packed)) raw_mode_s_long_overlay {
char asterisk; char asterisk;
char payload[28]; uint8_t payload[28];
char semicolon; char semicolon;
char cr_lf; char cr_lf;
char lf; char lf;
@@ -78,7 +78,7 @@ void raw_init() {
assert(sizeof(struct raw_mode_s_long_overlay) < BUF_LEN_MAX); assert(sizeof(struct raw_mode_s_long_overlay) < BUF_LEN_MAX);
} }
bool raw_parse(struct buf *buf, struct packet *packet, void *state_in) { bool raw_parse(struct buf *buf, struct packet *packet, void __attribute__((unused)) *state_in) {
return ( return (
raw_parse_mode_s_short(buf, packet) || raw_parse_mode_s_short(buf, packet) ||
raw_parse_mode_s_long(buf, packet)); raw_parse_mode_s_long(buf, packet));

View File

@@ -5,6 +5,6 @@
struct buf; struct buf;
struct packet; struct packet;
void raw_init(); void raw_init(void);
bool raw_parse(struct buf *, struct packet *, void *); bool raw_parse(struct buf *, struct packet *, void *);
void raw_serialize(struct packet *, struct buf *); void raw_serialize(struct packet *, struct buf *);

View File

@@ -25,7 +25,7 @@ typedef bool (*parser)(struct buf *, struct packet *, void *state);
struct receive { struct receive {
struct peer peer; struct peer peer;
struct peer *on_close; struct peer *on_close;
char id[UUID_LEN]; uint8_t id[UUID_LEN];
struct buf buf; struct buf buf;
char parser_state[PARSER_STATE_LEN]; char parser_state[PARSER_STATE_LEN];
parser_wrapper parser_wrapper; parser_wrapper parser_wrapper;
@@ -33,9 +33,9 @@ struct receive {
struct receive *prev; struct receive *prev;
struct receive *next; struct receive *next;
}; };
struct receive *receive_head = NULL; static struct receive *receive_head = NULL;
struct parser { static struct parser {
char *name; char *name;
parser parse; parser parse;
} parsers[] = { } parsers[] = {
@@ -70,7 +70,7 @@ static bool receive_autodetect_parse(struct receive *receive, struct packet *pac
struct buf *buf = &receive->buf; struct buf *buf = &receive->buf;
void *state = receive->parser_state; void *state = receive->parser_state;
for (int i = 0; i < NUM_PARSERS; i++) { for (size_t i = 0; i < NUM_PARSERS; i++) {
if (parsers[i].parse(buf, packet, state)) { if (parsers[i].parse(buf, packet, state)) {
fprintf(stderr, "R %s: Detected input format %s\n", receive->id, parsers[i].name); fprintf(stderr, "R %s: Detected input format %s\n", receive->id, parsers[i].name);
receive->parser_wrapper = receive_parse_wrapper; receive->parser_wrapper = receive_parse_wrapper;
@@ -129,7 +129,7 @@ void receive_cleanup() {
} }
} }
void receive_new(int fd, void *unused, struct peer *on_close) { void receive_new(int fd, void __attribute__((unused)) *passthrough, struct peer *on_close) {
peer_count_in++; peer_count_in++;
int res = shutdown(fd, SHUT_WR); int res = shutdown(fd, SHUT_WR);
@@ -158,7 +158,7 @@ void receive_new(int fd, void *unused, struct peer *on_close) {
void receive_print_usage() { void receive_print_usage() {
fprintf(stderr, "\nSupported receive formats (auto-detected):\n"); fprintf(stderr, "\nSupported receive formats (auto-detected):\n");
for (int i = 0; i < NUM_PARSERS; i++) { for (size_t i = 0; i < NUM_PARSERS; i++) {
fprintf(stderr, "\t%s\n", parsers[i].name); fprintf(stderr, "\t%s\n", parsers[i].name);
} }
} }

View File

@@ -6,6 +6,6 @@
struct peer; struct peer;
void receive_cleanup(); void receive_cleanup(void);
void receive_new(int, void *, struct peer *); void receive_new(int, void *, struct peer *);
void receive_print_usage(); void receive_print_usage(void);

View File

@@ -1,5 +1,3 @@
#define _GNU_SOURCE
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <netdb.h> #include <netdb.h>
@@ -38,7 +36,7 @@ static void resolve_handler(struct peer *peer) {
} }
static void *resolve_main(void *arg) { static void *resolve_main(void *arg) {
int fd = (intptr_t) arg; int fd = (int) (intptr_t) arg;
struct resolve_request *request; struct resolve_request *request;
ssize_t ret; ssize_t ret;
while ((ret = read(fd, &request, sizeof(request))) == sizeof(request)) { while ((ret = read(fd, &request, sizeof(request))) == sizeof(request)) {

View File

@@ -3,6 +3,6 @@
struct peer; struct peer;
struct addrinfo; struct addrinfo;
void resolve_init(); void resolve_init(void);
void resolve_cleanup(); void resolve_cleanup(void);
void resolve(struct peer *, const char *, const char *, int, struct addrinfo **, const char **); void resolve(struct peer *, const char *, const char *, int, struct addrinfo **, const char **);

View File

@@ -24,14 +24,14 @@
struct send { struct send {
struct peer peer; struct peer peer;
struct peer *on_close; struct peer *on_close;
char id[UUID_LEN]; uint8_t id[UUID_LEN];
struct serializer *serializer; struct serializer *serializer;
struct send *prev; struct send *prev;
struct send *next; struct send *next;
}; };
typedef void (*serialize)(struct packet *, struct buf *); typedef void (*serialize)(struct packet *, struct buf *);
struct serializer { static struct serializer {
char *name; char *name;
serialize serialize; serialize serialize;
struct send *send_head; struct send *send_head;
@@ -90,7 +90,7 @@ static bool send_hello(int fd, struct serializer *serializer) {
if (buf.length == 0) { if (buf.length == 0) {
return true; return true;
} }
if (write(fd, buf_at(&buf, 0), buf.length) != buf.length) { if (write(fd, buf_at(&buf, 0), buf.length) != (ssize_t) buf.length) {
return false; return false;
} }
return true; return true;
@@ -101,7 +101,7 @@ void send_init() {
} }
void send_cleanup() { void send_cleanup() {
for (int i = 0; i < NUM_SERIALIZERS; i++) { for (size_t i = 0; i < NUM_SERIALIZERS; i++) {
struct serializer *serializer = &serializers[i]; struct serializer *serializer = &serializers[i];
while (serializer->send_head) { while (serializer->send_head) {
send_del(serializer->send_head); send_del(serializer->send_head);
@@ -110,7 +110,7 @@ void send_cleanup() {
} }
struct serializer *send_get_serializer(char *name) { struct serializer *send_get_serializer(char *name) {
for (int i = 0; i < NUM_SERIALIZERS; i++) { for (size_t i = 0; i < NUM_SERIALIZERS; i++) {
if (strcasecmp(serializers[i].name, name) == 0) { if (strcasecmp(serializers[i].name, name) == 0) {
return &serializers[i]; return &serializers[i];
} }
@@ -155,7 +155,7 @@ void send_new_wrapper(int fd, void *passthrough, struct peer *on_close) {
} }
void send_write(struct packet *packet) { void send_write(struct packet *packet) {
for (int i = 0; i < NUM_SERIALIZERS; i++) { for (size_t i = 0; i < NUM_SERIALIZERS; i++) {
struct serializer *serializer = &serializers[i]; struct serializer *serializer = &serializers[i];
if (serializer->send_head == NULL) { if (serializer->send_head == NULL) {
continue; continue;
@@ -167,7 +167,7 @@ void send_write(struct packet *packet) {
} }
struct send *send = serializer->send_head; struct send *send = serializer->send_head;
while (send) { while (send) {
if (write(send->peer.fd, buf_at(&buf, 0), buf.length) != buf.length) { if (write(send->peer.fd, buf_at(&buf, 0), buf.length) != (ssize_t) buf.length) {
// peer_loop() will see this shutdown and call send_del // peer_loop() will see this shutdown and call send_del
int res = shutdown(send->peer.fd, SHUT_WR); int res = shutdown(send->peer.fd, SHUT_WR);
assert(res == 0 || (res == -1 && errno == ENOTSOCK)); assert(res == 0 || (res == -1 && errno == ENOTSOCK));
@@ -179,7 +179,7 @@ void send_write(struct packet *packet) {
void send_print_usage() { void send_print_usage() {
fprintf(stderr, "\nSupported send formats:\n"); fprintf(stderr, "\nSupported send formats:\n");
for (int i = 0; i < NUM_SERIALIZERS; i++) { for (size_t i = 0; i < NUM_SERIALIZERS; i++) {
fprintf(stderr, "\t%s\n", serializers[i].name); fprintf(stderr, "\t%s\n", serializers[i].name);
} }
} }

View File

@@ -3,10 +3,10 @@
struct packet; struct packet;
struct peer; struct peer;
void send_init(); void send_init(void);
void send_cleanup(); void send_cleanup(void);
struct serializer *send_get_serializer(char *); struct serializer *send_get_serializer(char *);
void send_new(int, struct serializer *, struct peer *); void send_new(int, struct serializer *, struct peer *);
void send_new_wrapper(int, void *, struct peer *); void send_new_wrapper(int, void *, struct peer *);
void send_write(struct packet *); void send_write(struct packet *);
void send_print_usage(); void send_print_usage(void);

View File

@@ -4,7 +4,7 @@
#include "server.h" #include "server.h"
char server_id[UUID_LEN]; uint8_t server_id[UUID_LEN];
char server_version[] = "https://github.com/flamingcowtv/adsb-tools#1"; char server_version[] = "https://github.com/flamingcowtv/adsb-tools#1";
void server_init() { void server_init() {

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
extern char server_id[]; extern uint8_t server_id[];
extern char server_version[]; extern char server_version[];
void server_init(); void server_init(void);

View File

@@ -12,7 +12,9 @@ static struct stats_state {
uint64_t total_count; uint64_t total_count;
uint64_t type_count[NUM_TYPES]; uint64_t type_count[NUM_TYPES];
struct timespec start; struct timespec start;
} stats_state = { 0 }; } stats_state = {
.type_count = { 0 },
};
void stats_init() { void stats_init() {
assert(!clock_gettime(CLOCK_MONOTONIC_COARSE, &stats_state.start)); assert(!clock_gettime(CLOCK_MONOTONIC_COARSE, &stats_state.start));
@@ -31,7 +33,7 @@ void stats_serialize(struct packet *packet, struct buf *buf) {
if (i == PACKET_TYPE_NONE) { if (i == PACKET_TYPE_NONE) {
continue; continue;
} }
json_object_set_new(counts, packet_type_names[i], json_integer(stats_state.type_count[i])); json_object_set_new(counts, packet_type_names[i], json_integer((json_int_t) stats_state.type_count[i]));
} }
struct timespec now; struct timespec now;
assert(!clock_gettime(CLOCK_MONOTONIC_COARSE, &now)); assert(!clock_gettime(CLOCK_MONOTONIC_COARSE, &now));

View File

@@ -3,5 +3,5 @@
struct packet; struct packet;
struct buf; struct buf;
void stats_init(); void stats_init(void);
void stats_serialize(struct packet *, struct buf *); void stats_serialize(struct packet *, struct buf *);

View File

@@ -5,7 +5,7 @@
#include "uuid.h" #include "uuid.h"
void uuid_gen(char *out) { void uuid_gen(uint8_t *out) {
uint8_t uuid[16]; uint8_t uuid[16];
rand_fill(uuid, 16); rand_fill(uuid, 16);
uuid[6] = (uuid[6] & 0x0F) | 0x40; uuid[6] = (uuid[6] & 0x0F) | 0x40;

View File

@@ -1,4 +1,6 @@
#pragma once #pragma once
#include <stdint.h>
#define UUID_LEN 37 #define UUID_LEN 37
void uuid_gen(char *); void uuid_gen(uint8_t *);

View File

@@ -1,14 +1,14 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <time.h> #include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <time.h>
#include <unistd.h>
#include "peer.h" #include "peer.h"
#include "rand.h" #include "rand.h"
@@ -22,14 +22,16 @@ struct wakeup_entry {
struct wakeup_entry *next; struct wakeup_entry *next;
}; };
struct wakeup_entry *head = NULL; static struct wakeup_entry *head = NULL;
static uint64_t wakeup_get_time_ms() { static uint64_t wakeup_get_time_ms() {
struct timespec tp; struct timespec tp;
assert(!clock_gettime(CLOCK_MONOTONIC_COARSE, &tp)); assert(!clock_gettime(CLOCK_MONOTONIC_COARSE, &tp));
#define MS_PER_S 1000 #define MS_PER_S UINT64_C(1000)
#define NS_PER_MS 1000000 #define NS_PER_MS UINT64_C(1000000)
return (tp.tv_sec * MS_PER_S) + (tp.tv_nsec / NS_PER_MS); assert(tp.tv_sec >= 0);
assert(tp.tv_nsec >= 0);
return ((uint64_t) tp.tv_sec * MS_PER_S) + ((uint64_t) tp.tv_nsec / NS_PER_MS);
} }
void wakeup_init() { void wakeup_init() {
@@ -47,8 +49,14 @@ int wakeup_get_delay() {
if (!head) { if (!head) {
return -1; return -1;
} }
int delay = head->absolute_time_ms - wakeup_get_time_ms(); uint64_t now = wakeup_get_time_ms();
return delay < 0 ? 0 : delay; if (head->absolute_time_ms > now) {
uint64_t delta = head->absolute_time_ms - now;
assert(delta < INT_MAX);
return (int) delta;
} else {
return 0;
}
} }
void wakeup_dispatch() { void wakeup_dispatch() {

View File

@@ -4,9 +4,9 @@
struct peer; struct peer;
void wakeup_init(); void wakeup_init(void);
void wakeup_cleanup(); void wakeup_cleanup(void);
int wakeup_get_delay(); int wakeup_get_delay(void);
void wakeup_dispatch(); void wakeup_dispatch(void);
void wakeup_add(struct peer *, uint32_t); void wakeup_add(struct peer *, uint32_t);
uint32_t wakeup_get_retry_delay_ms(uint32_t); uint32_t wakeup_get_retry_delay_ms(uint32_t);