From 758611ccd2a8ce105258cf766fc5aa7b0719ae95 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 21 Oct 2012 05:32:43 +0200 Subject: Use acked updates for seqno request replies --- ffd/ack.c | 5 ++++- ffd/ffd.c | 4 ++-- ffd/ffd.h | 2 +- ffd/send.c | 17 ++++++++++++++++- ffd/send.h | 2 +- ffd/update.c | 38 ++++++++++++++++++++++++++++++++------ 6 files changed, 56 insertions(+), 12 deletions(-) (limited to 'ffd') diff --git a/ffd/ack.c b/ffd/ack.c index 0dbb13c..cd21d0f 100644 --- a/ffd/ack.c +++ b/ffd/ack.c @@ -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; diff --git a/ffd/ffd.c b/ffd/ffd.c index 6b01cd3..0504085 100644 --- a/ffd/ffd.c +++ b/ffd/ffd.c @@ -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; } diff --git a/ffd/ffd.h b/ffd/ffd.h index b78f7af..2999be4 100644 --- a/ffd/ffd.h +++ b/ffd/ffd.h @@ -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); diff --git a/ffd/send.c b/ffd/send.c index dc6544b..2cd57bf 100644 --- a/ffd/send.c +++ b/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; } diff --git a/ffd/send.h b/ffd/send.h index fbd9062..50a61e2 100644 --- a/ffd/send.h +++ b/ffd/send.h @@ -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); diff --git a/ffd/update.c b/ffd/update.c index d273fec..77319bd 100644 --- a/ffd/update.c +++ b/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,11 +103,16 @@ 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) { - 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)); + 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"); -- cgit v1.2.3