Fix handling of announces without payload

This commit is contained in:
Matthias Schiffer 2013-03-26 04:00:47 +01:00
parent 3dbdeacfdb
commit 79c6fd3f14
4 changed files with 25 additions and 18 deletions

View file

@ -47,6 +47,9 @@
#define GP_BABEL_MAINTENANCE_INTERVAL GP_BABEL_HELLO_INTERVAL #define GP_BABEL_MAINTENANCE_INTERVAL GP_BABEL_HELLO_INTERVAL
#define GP_BABEL_UPDATE_FLAG_HAS_PAYLOAD 0x01
struct gmrf_context { struct gmrf_context {
gp_babel_node_id_t self; gp_babel_node_id_t self;
@ -99,9 +102,9 @@ struct gp_babel_announce {
gp_babel_nexthop_t *selected; gp_babel_nexthop_t *selected;
gp_babel_nexthop_t *nexthops; gp_babel_nexthop_t *nexthops;
/* an incomplete announcement is specified by a len value of 0xff with NULL data */ /* an incomplete announcement is specified by a len value of 0xff with NULL payload */
uint8_t len; uint8_t len;
uint8_t *data; uint8_t *payload;
}; };
struct gp_babel_nexthop { struct gp_babel_nexthop {
@ -165,7 +168,7 @@ void gp_babel_handle_packet(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t
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);
void gp_babel_send_hellos(gmrf_t *gmrf, gmrf_context_t *ctx); void gp_babel_send_hellos(gmrf_t *gmrf, gmrf_context_t *ctx);
void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, bool with_data); void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, bool with_payload);
gp_babel_announce_t* gp_babel_announce_new(gmrf_t *gmrf, gmrf_context_t *ctx); gp_babel_announce_t* gp_babel_announce_new(gmrf_t *gmrf, gmrf_context_t *ctx);

View file

@ -115,8 +115,8 @@ static inline bool add_node_id(gp_babel_packet_buf_t *buf, const gp_babel_node_i
return true; return true;
} }
static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_node_id_t *node_id, gp_babel_announce_t *announce, bool with_data, bool targetted) { static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_node_id_t *node_id, gp_babel_announce_t *announce, bool with_payload, bool targetted) {
if (announce->len && !announce->data) { if (announce->len && !announce->payload) {
/* incomplete announce, handle like non-existent announce */ /* incomplete announce, handle like non-existent announce */
return true; return true;
} }
@ -131,8 +131,8 @@ static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_node_id_t *node_id,
*node_id = announce->node; *node_id = announce->node;
} }
uint8_t data_len = (with_data && announce->metric.metric != GP_BABEL_INFINITY) ? announce->len : 0; uint8_t payload_len = (with_payload && announce->metric.metric != GP_BABEL_INFINITY) ? announce->len : 0;
gp_babel_tlv_update_t *update = gp_babel_tlv_add(buf, TLV_UPDATE, sizeof(gp_babel_tlv_update_t)+data_len); gp_babel_tlv_update_t *update = gp_babel_tlv_add(buf, TLV_UPDATE, sizeof(gp_babel_tlv_update_t)+payload_len);
if (!update) { if (!update) {
/* reset length to remove possibly added node ID record */ /* reset length to remove possibly added node ID record */
buf->packet.len = len; buf->packet.len = len;
@ -147,8 +147,12 @@ static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_node_id_t *node_id,
update->type = htons(announce->type); update->type = htons(announce->type);
update->key = htons(announce->key); update->key = htons(announce->key);
if (data_len) if (announce->metric.metric != GP_BABEL_INFINITY && announce->len) {
memcpy(update->data, announce->data, data_len); update->flags |= GP_BABEL_UPDATE_FLAG_HAS_PAYLOAD;
if (payload_len)
memcpy(update->payload, announce->payload, payload_len);
}
if (gp_babel_is_metric_better(announce->metric, announce->feasibility_distance)) if (gp_babel_is_metric_better(announce->metric, announce->feasibility_distance))
announce->feasibility_distance = announce->metric; announce->feasibility_distance = announce->metric;
@ -159,18 +163,18 @@ static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_node_id_t *node_id,
return true; return true;
} }
void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, bool with_data) { void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, bool with_payload) {
gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX); gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX);
if (announce) { if (announce) {
add_update(buf, NULL, announce, with_data, neigh); add_update(buf, NULL, announce, with_payload, neigh);
} }
else { else {
gp_babel_node_id_t node_id = gp_babel_node_id_unspec; gp_babel_node_id_t node_id = gp_babel_node_id_unspec;
gp_babel_announce_t *a; gp_babel_announce_t *a;
for (a = ctx->announces; a; a = a->next) { for (a = ctx->announces; a; a = a->next) {
if (!add_update(buf, &node_id, a, with_data, neigh)) { if (!add_update(buf, &node_id, a, with_payload, neigh)) {
if (neigh) if (neigh)
send_neigh(gmrf, neigh, &buf->packet); send_neigh(gmrf, neigh, &buf->packet);
else else
@ -179,7 +183,7 @@ void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *i
node_id = gp_babel_node_id_unspec; node_id = gp_babel_node_id_unspec;
buf->packet.len = 0; buf->packet.len = 0;
if (!add_update(buf, &node_id, a, with_data, neigh)) { if (!add_update(buf, &node_id, a, with_payload, neigh)) {
gmrf_logf(gmrf, LOG_ERR, "add_update failed"); gmrf_logf(gmrf, LOG_ERR, "add_update failed");
return; return;
} }

View file

@ -195,16 +195,16 @@ static void handle_tlv_update(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_
} }
} }
if (!announce->data) { if ((tlv_update->flags & GP_BABEL_UPDATE_FLAG_HAS_PAYLOAD) && !announce->payload) {
if (len > sizeof(gp_babel_tlv_update_t)) { if (len > sizeof(gp_babel_tlv_update_t)) {
announce->len = len - sizeof(gp_babel_tlv_update_t); announce->len = len - sizeof(gp_babel_tlv_update_t);
announce->data = malloc(announce->len); announce->payload = malloc(announce->len);
memcpy(announce->data, tlv_update->data, announce->len); memcpy(announce->payload, tlv_update->payload, announce->len);
} }
else { else {
announce->len = 0xff; announce->len = 0xff;
/* request data */ /* request payload */
//if (nexthop) //if (nexthop)
// gp_babel_send_announce_request(arg->iface, neigh, announce->node, announce->type, announce->key, true); // gp_babel_send_announce_request(arg->iface, neigh, announce->node, announce->type, announce->key, true);
} }

View file

@ -66,7 +66,7 @@ typedef struct __attribute__((packed)) gp_babel_tlv_update {
uint16_t metric; uint16_t metric;
uint16_t type; uint16_t type;
uint16_t key; uint16_t key;
uint8_t data[]; uint8_t payload[];
} gp_babel_tlv_update_t; } gp_babel_tlv_update_t;
typedef struct __attribute__((packed)) gp_babel_tlv_announce_req { typedef struct __attribute__((packed)) gp_babel_tlv_announce_req {