Fix handling of announces without payload
This commit is contained in:
parent
3dbdeacfdb
commit
79c6fd3f14
4 changed files with 25 additions and 18 deletions
|
@ -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);
|
||||||
|
|
24
src/send.c
24
src/send.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Reference in a new issue