From 025d14c6a6e7143856429989a8641c008b6dde7f Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Tue, 23 Feb 2016 21:30:29 -0800 Subject: [PATCH] Add framing to proto, since it isn't built in to protobuf. --- adsbus/proto.c | 28 +++++++++++++++++++++++----- adsbus/send.c | 1 + 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/adsbus/proto.c b/adsbus/proto.c index fdfd1b8..1e9ada1 100644 --- a/adsbus/proto.c +++ b/adsbus/proto.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -11,6 +12,10 @@ #define PROTO_MAGIC "aDsB" +struct proto_header { + uint32_t length; +}; + struct proto_parser_state { struct packet_mlat_state mlat_state; uint16_t mlat_timestamp_mhz; @@ -23,9 +28,13 @@ static Adsb *proto_prev = NULL; static void proto_obj_to_buf(Adsb *wrapper, struct buf *buf) { assert(!buf->length); - assert(adsb__get_packed_size(wrapper) <= BUF_LEN_MAX); - buf->length = adsb__pack(wrapper, (uint8_t *) buf_at(buf, 0)); - assert(buf->length); + struct proto_header *header = (struct proto_header *) buf_at(buf, 0); + assert(sizeof(*header) <= BUF_LEN_MAX); + uint32_t msg_len = adsb__get_packed_size(wrapper); + buf->length = sizeof(*header) + msg_len; + assert(buf->length <= BUF_LEN_MAX); + assert(adsb__pack(wrapper, (uint8_t *) buf_at(buf, sizeof(*header))) == msg_len); + header->length = htonl(msg_len); } static void proto_serialize_packet(struct packet *packet, AdsbPacket *out, size_t len) { @@ -113,7 +122,16 @@ bool proto_parse(struct buf *buf, struct packet *packet, void *state_in) { proto_prev = NULL; } - Adsb *wrapper = adsb__unpack(NULL, buf->length, (uint8_t *) buf_at(buf, 0)); + struct proto_header *header = (struct proto_header *) buf_at(buf, 0); + if (buf->length < sizeof(*header)) { + return false; + } + uint32_t msg_len = ntohl(header->length); + if (buf->length < sizeof(*header) + msg_len) { + return false; + } + + Adsb *wrapper = adsb__unpack(NULL, msg_len, (uint8_t *) buf_at(buf, sizeof(*header))); if (!wrapper) { return false; } @@ -143,7 +161,7 @@ bool proto_parse(struct buf *buf, struct packet *packet, void *state_in) { } proto_prev = wrapper; - buf_consume(buf, adsb__get_packed_size(wrapper)); + buf_consume(buf, sizeof(*header) + msg_len); return true; } diff --git a/adsbus/send.c b/adsbus/send.c index d4ea899..97e8853 100644 --- a/adsbus/send.c +++ b/adsbus/send.c @@ -120,6 +120,7 @@ struct serializer *send_get_serializer(char *name) { void send_add(int fd, struct serializer *serializer) { if (!send_hello(fd, serializer)) { fprintf(stderr, "S xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx: Failed to write hello\n"); + assert(!close(fd)); return; }