Save maximum length in packet buffers

This commit is contained in:
Matthias Schiffer 2013-03-21 20:34:51 +01:00
parent ca758c85d2
commit 8fe8ed1942
5 changed files with 28 additions and 21 deletions

View file

@ -43,11 +43,17 @@ struct __attribute__((packed)) gp_babel_packet {
uint8_t tlv[]; uint8_t tlv[];
}; };
struct gp_babel_packet_buf {
size_t max_len;
gp_babel_packet_t packet;
};
#define gp_babel_packet_alloca(size) ({ \ #define gp_babel_packet_alloca(size) ({ \
gp_babel_packet_t *__packet = alloca(sizeof(gp_babel_packet_t)+size); \ gp_babel_packet_buf_t *__buf = alloca(sizeof(gp_babel_packet_buf_t) + size - sizeof(gp_babel_packet_t)); \
__packet->version = htons(GP_BABEL_VERSION); \ __buf->max_len = size - sizeof(gp_babel_packet_t); \
__packet->len = 0; \ __buf->packet.version = htons(GP_BABEL_VERSION); \
__packet; \ __buf->packet.len = 0; \
__buf; \
}) })
static inline size_t gp_babel_packet_size(const gp_babel_packet_t *packet) { static inline size_t gp_babel_packet_size(const gp_babel_packet_t *packet) {

View file

@ -44,22 +44,22 @@ static inline bool send_neigh(gmrf_t *gmrf, const gp_babel_neigh_t *neigh, const
} }
void gp_babel_send_ack(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, uint16_t nonce) { void gp_babel_send_ack(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, uint16_t nonce) {
gp_babel_packet_t *packet = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX); gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX);
gp_babel_tlv_ack_t *ack = gp_babel_tlv_add(packet, GP_BABEL_PACKET_MAX, TLV_ACK, sizeof(gp_babel_tlv_ack_t)); gp_babel_tlv_ack_t *ack = gp_babel_tlv_add(buf, TLV_ACK, sizeof(gp_babel_tlv_ack_t));
if (!ack) if (!ack)
return; return;
ack->nonce = htons(nonce); ack->nonce = htons(nonce);
send_neigh(gmrf, neigh, packet); send_neigh(gmrf, neigh, &buf->packet);
} }
static void add_ihus(gmrf_t *gmrf, gp_babel_packet_t *packet, size_t max_len, const gp_babel_iface_t *iface) { static void add_ihus(gmrf_t *gmrf, gp_babel_packet_buf_t *buf, const gp_babel_iface_t *iface) {
const gp_babel_neigh_t *neigh; const gp_babel_neigh_t *neigh;
for (neigh = iface->neighbours; neigh; neigh = neigh->next) { for (neigh = iface->neighbours; neigh; neigh = neigh->next) {
gp_babel_tlv_ihu_t *ihu = gp_babel_tlv_add(packet, GP_BABEL_PACKET_MAX, TLV_IHU, sizeof(gp_babel_tlv_ihu_t)+sizeof(gmrf_addr_t)); gp_babel_tlv_ihu_t *ihu = gp_babel_tlv_add(buf, TLV_IHU, sizeof(gp_babel_tlv_ihu_t)+sizeof(gmrf_addr_t));
if (!ihu) if (!ihu)
return; return;
@ -74,25 +74,25 @@ static void add_ihus(gmrf_t *gmrf, gp_babel_packet_t *packet, size_t max_len, co
void gp_babel_send_hellos(gmrf_t *gmrf, gmrf_context_t *ctx) { void gp_babel_send_hellos(gmrf_t *gmrf, gmrf_context_t *ctx) {
gmrf_logf(gmrf, LOG_DEBUG, "sending hellos..."); gmrf_logf(gmrf, LOG_DEBUG, "sending hellos...");
gp_babel_packet_t *packet = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX); gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX);
gp_babel_tlv_hello_t *hello = gp_babel_tlv_add(packet, GP_BABEL_PACKET_MAX, TLV_HELLO, sizeof(gp_babel_tlv_hello_t)); gp_babel_tlv_hello_t *hello = gp_babel_tlv_add(buf, TLV_HELLO, sizeof(gp_babel_tlv_hello_t));
if (!hello) if (!hello)
return; return;
hello->reserved = 0; hello->reserved = 0;
hello->interval = htons(GP_BABEL_HELLO_INTERVAL); hello->interval = htons(GP_BABEL_HELLO_INTERVAL);
uint16_t len = packet->len; uint16_t len = buf->packet.len;
gp_babel_iface_t *iface; gp_babel_iface_t *iface;
for (iface = ctx->interfaces; iface; iface = iface->next) { for (iface = ctx->interfaces; iface; iface = iface->next) {
hello->seqno = htons(iface->seqno++); hello->seqno = htons(iface->seqno++);
packet->len = len; buf->packet.len = len;
add_ihus(gmrf, packet, GP_BABEL_PACKET_MAX, iface); add_ihus(gmrf, buf, iface);
gmrf_iface_send_bc(gmrf, iface->gmrf_iface, packet, gp_babel_packet_size(packet)); gmrf_iface_send_bc(gmrf, iface->gmrf_iface, &buf->packet, gp_babel_packet_size(&buf->packet));
} }
} }

View file

@ -57,18 +57,18 @@ bool gp_babel_tlv_parse(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_packet
return true; return true;
} }
void* gp_babel_tlv_add(gp_babel_packet_t *packet, size_t max_len, gp_babel_tlv_type_t type, size_t len) { void* gp_babel_tlv_add(gp_babel_packet_buf_t *buf, gp_babel_tlv_type_t type, size_t len) {
size_t pktlen = ntohs(packet->len); size_t pktlen = ntohs(buf->packet.len);
if (pktlen+len+2 > max_len) if (pktlen+len+2 > buf->max_len)
return NULL; return NULL;
uint8_t *data = packet->tlv+pktlen+2; uint8_t *data = buf->packet.tlv+pktlen+2;
data[-2] = type; data[-2] = type;
data[-1] = len; data[-1] = len;
packet->len = htons(pktlen+len+2); buf->packet.len = htons(pktlen+len+2);
return data; return data;
} }

View file

@ -57,7 +57,7 @@ typedef void (*gp_babel_tlv_cb)(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_tlv_
bool gp_babel_tlv_parse(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_packet_t *packet, gp_babel_tlv_cb cb, void *arg); bool gp_babel_tlv_parse(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_packet_t *packet, gp_babel_tlv_cb cb, void *arg);
void* gp_babel_tlv_add(gp_babel_packet_t *packet, size_t max_len, gp_babel_tlv_type_t type, size_t len); void* gp_babel_tlv_add(gp_babel_packet_buf_t *buf, gp_babel_tlv_type_t type, size_t len);
#endif /* _GMRF_PROTO_BABEL_TLV_H_ */ #endif /* _GMRF_PROTO_BABEL_TLV_H_ */

View file

@ -35,6 +35,7 @@ typedef struct __attribute__((packed)) gp_gabel_node_id {
} gp_babel_node_id_t; } gp_babel_node_id_t;
typedef struct gp_babel_packet gp_babel_packet_t; typedef struct gp_babel_packet gp_babel_packet_t;
typedef struct gp_babel_packet_buf gp_babel_packet_buf_t;
typedef struct gp_babel_iface gp_babel_iface_t; typedef struct gp_babel_iface gp_babel_iface_t;
typedef struct gp_babel_neigh gp_babel_neigh_t; typedef struct gp_babel_neigh gp_babel_neigh_t;