Use acked updates for seqno request replies
This commit is contained in:
parent
aa15b96d39
commit
758611ccd2
6 changed files with 56 additions and 12 deletions
|
@ -40,6 +40,7 @@ static uint16_t nonce = 0;
|
|||
|
||||
typedef struct _ack_arg_t {
|
||||
void (*cb)(uint16_t nonce, void *arg);
|
||||
void (*free)(uint16_t nonce, void *arg);
|
||||
void *arg;
|
||||
|
||||
uint16_t nonce;
|
||||
|
@ -56,6 +57,7 @@ static void ack_resend(const struct timespec *timeout, void *argp) {
|
|||
ack_arg_t *arg = argp;
|
||||
|
||||
if (GET_ACK(arg->nonce) || !(--arg->retries)) {
|
||||
arg->free(arg->nonce, arg->arg);
|
||||
free(arg);
|
||||
return;
|
||||
}
|
||||
|
@ -65,12 +67,13 @@ static void ack_resend(const struct timespec *timeout, void *argp) {
|
|||
ffd_queue_put_delayed(&ack_requests, ack_resend, timeout, arg->interval, arg);
|
||||
}
|
||||
|
||||
void ffd_ack_request(void (*cb)(uint16_t nonce, void *arg), unsigned interval, unsigned retries, void *arg) {
|
||||
void ffd_ack_request(void (*cb)(uint16_t nonce, void *arg), void (*free_cb)(uint16_t nonce, void *arg), unsigned interval, unsigned retries, void *arg) {
|
||||
UNSET_ACK(nonce);
|
||||
cb(nonce, arg);
|
||||
|
||||
ack_arg_t *ack_arg = malloc(sizeof(ack_arg_t));
|
||||
ack_arg->cb = cb;
|
||||
ack_arg->free = free_cb;
|
||||
ack_arg->arg = arg;
|
||||
ack_arg->nonce = nonce++;
|
||||
ack_arg->interval = interval;
|
||||
|
|
|
@ -407,14 +407,14 @@ static void handle_tlv_seqno_req(const ffd_tlv_seqno_req_t *tlv_req, size_t len,
|
|||
|
||||
if ((int16_t)(seqno-announce->selected->metric_seqno.seqno) <= 0) {
|
||||
fprintf(stderr, "debug: received seqno request, seqno already ok\n");
|
||||
ffd_update_enqueue(&announce->node, announce->type, announce->key, neigh, false);
|
||||
ffd_update_enqueue(&announce->node, announce->type, announce->key, neigh, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!announce->selected->neigh) {
|
||||
fprintf(stderr, "debug: received seqno request, incrementing seqno\n");
|
||||
announce->selected->metric_seqno.seqno++;
|
||||
ffd_update_enqueue(&announce->node, announce->type, announce->key, neigh, false);
|
||||
ffd_update_enqueue(&announce->node, announce->type, announce->key, neigh, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ bool ffd_announce_seqno_request(ffd_announce_t *announce, ffd_neigh_t *neigh, ui
|
|||
void ffd_announce_free(ffd_announce_t *announce);
|
||||
|
||||
void ffd_ack_handle(uint16_t n);
|
||||
void ffd_ack_request(void (*cb)(uint16_t nonce, void *arg), unsigned interval, unsigned retries, void *arg);
|
||||
void ffd_ack_request(void (*cb)(uint16_t nonce, void *arg), void (*free_cb)(uint16_t nonce, void *arg), unsigned interval, unsigned retries, void *arg);
|
||||
int ffd_ack_timeout(void);
|
||||
void ffd_ack_run(void);
|
||||
|
||||
|
|
17
ffd/send.c
17
ffd/send.c
|
@ -188,6 +188,18 @@ void ffd_send_hellos(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool add_ack_request(ffd_packet_t *packet, uint16_t nonce) {
|
||||
ffd_tlv_ack_req_t *tlv = ffd_tlv_add(packet, FFD_PACKET_MAX, TLV_ACK_REQ, sizeof(ffd_tlv_ack_req_t));
|
||||
if (!tlv)
|
||||
return false;
|
||||
|
||||
tlv->reserved = 0;
|
||||
tlv->nonce = htons(nonce);
|
||||
tlv->interval = htons(FFD_ACK_INTERVAL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool add_node_id(ffd_packet_t *packet, size_t max_len, ffd_node_id_t node_id) {
|
||||
ffd_tlv_node_id_t *tlv = ffd_tlv_add(packet, FFD_PACKET_MAX, TLV_NODE_ID, sizeof(ffd_tlv_node_id_t));
|
||||
if (!tlv)
|
||||
|
@ -329,7 +341,7 @@ void ffd_send_retract(ffd_neigh_t *neigh, ffd_node_id_t node, uint16_t type, uin
|
|||
send_neigh(neigh, packet);
|
||||
}
|
||||
|
||||
ffd_update_t* ffd_send_update_new(ffd_iface_t *iface, ffd_neigh_t *neigh) {
|
||||
ffd_update_t* ffd_send_update_new(ffd_iface_t *iface, ffd_neigh_t *neigh, const uint16_t *nonce) {
|
||||
unsigned max_updates = (FFD_PACKET_MAX+sizeof(ffd_tlv_update_t)+1)/(sizeof(ffd_tlv_update_t)+2);
|
||||
ffd_update_t *update = calloc(1, sizeof(ffd_update_t) + max_updates*sizeof(announce_info_t));
|
||||
update->iface = iface;
|
||||
|
@ -340,6 +352,9 @@ ffd_update_t* ffd_send_update_new(ffd_iface_t *iface, ffd_neigh_t *neigh) {
|
|||
update->packet->version_magic = htons(FFD_VERSION_MAGIC);
|
||||
update->packet->len = 0;
|
||||
|
||||
if (nonce)
|
||||
add_ack_request(update->packet, *nonce);
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ void ffd_send_retract(ffd_neigh_t *neigh, ffd_node_id_t node, uint16_t type, uin
|
|||
void ffd_send_announce_request(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_node_id_t node, uint16_t type, uint16_t key, bool with_data);
|
||||
void ffd_send_seqno_request(ffd_neigh_t *neigh, ffd_announce_t *announce, uint16_t seqno);
|
||||
|
||||
ffd_update_t* ffd_send_update_new(ffd_iface_t *iface, ffd_neigh_t *neigh);
|
||||
ffd_update_t* ffd_send_update_new(ffd_iface_t *iface, ffd_neigh_t *neigh, const uint16_t *nonce);
|
||||
bool ffd_send_update_add(ffd_update_t *update, ffd_announce_t *announce);
|
||||
bool ffd_send_update_retract(ffd_update_t *update, ffd_node_id_t node, uint16_t type, uint16_t key);
|
||||
void ffd_send_update_finish(ffd_update_t *update);
|
||||
|
|
28
ffd/update.c
28
ffd/update.c
|
@ -75,6 +75,27 @@ static inline void update_unref(update_arg_t *arg) {
|
|||
}
|
||||
}
|
||||
|
||||
static void update_request_ack(uint16_t nonce, void *argp) {
|
||||
update_arg_t *arg = argp;
|
||||
|
||||
fprintf(stderr, "debug: sending acked update with nonce %u.\n", nonce);
|
||||
|
||||
ffd_update_t *update = ffd_send_update_new(NULL, arg->neigh, &nonce);
|
||||
|
||||
ffd_announce_t *announce = ffd_announce_find(&arg->node, arg->type, arg->key);
|
||||
|
||||
if (announce)
|
||||
ffd_send_update_add(update, announce);
|
||||
else
|
||||
ffd_send_update_retract(update, arg->node, arg->type, arg->key);
|
||||
|
||||
ffd_send_update_finish(update);
|
||||
}
|
||||
|
||||
static void update_request_ack_free(uint16_t nonce, void *arg) {
|
||||
update_unref(arg);
|
||||
}
|
||||
|
||||
void ffd_update_enqueue(const ffd_node_id_t *node, uint16_t type, uint16_t key, ffd_neigh_t *neigh, bool urgent) {
|
||||
if (neigh)
|
||||
ffd_neigh_ref(neigh);
|
||||
|
@ -82,12 +103,17 @@ void ffd_update_enqueue(const ffd_node_id_t *node, uint16_t type, uint16_t key,
|
|||
update_arg_t *arg = update_new(node, type, key, neigh);
|
||||
|
||||
if (urgent) {
|
||||
if (neigh) {
|
||||
ffd_ack_request(update_request_ack, update_request_ack_free, FFD_ACK_INTERVAL, 10, update_ref(arg));
|
||||
}
|
||||
else {
|
||||
ffd_queue_put_delayed(&pending_updates, NULL, &now, FFD_URGENT_DELAY, update_ref(arg));
|
||||
ffd_queue_put_delayed(&pending_updates, NULL, &now, 2*FFD_URGENT_DELAY, update_ref(arg));
|
||||
ffd_queue_put_delayed(&pending_updates, NULL, &now, 3*FFD_URGENT_DELAY, update_ref(arg));
|
||||
ffd_queue_put_delayed(&pending_updates, NULL, &now, 4*FFD_URGENT_DELAY, update_ref(arg));
|
||||
ffd_queue_put_delayed(&pending_updates, NULL, &now, 5*FFD_URGENT_DELAY, update_ref(arg));
|
||||
}
|
||||
}
|
||||
else {
|
||||
ffd_queue_put_delayed(&pending_updates, NULL, &now, FFD_DELAY, update_ref(arg));
|
||||
}
|
||||
|
@ -101,7 +127,7 @@ void ffd_update_run(void) {
|
|||
while (!ffd_update_timeout()) {
|
||||
ffd_neigh_t *neigh = ((update_arg_t*)pending_updates->arg)->neigh;
|
||||
|
||||
ffd_update_t *update = ffd_send_update_new(NULL, neigh);
|
||||
ffd_update_t *update = ffd_send_update_new(NULL, neigh, NULL);
|
||||
|
||||
fprintf(stderr, "debug: sending scheduled updates.\n");
|
||||
|
||||
|
|
Reference in a new issue