Commit 0de5fc1a authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Implement resending of updates.

parent 29c0063e
...@@ -317,7 +317,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix, ...@@ -317,7 +317,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
send_unicast_request(successor, prefix, plen, hop_count - 1, send_unicast_request(successor, prefix, plen, hop_count - 1,
seqno, router_hash); seqno, router_hash);
record_request(prefix, plen, seqno, router_hash, neigh->network, 0); record_resend(RESEND_REQUEST, prefix, plen, seqno, router_hash,
neigh->network, 0);
} }
...@@ -551,7 +552,7 @@ send_request_resend(struct neighbour *neigh, ...@@ -551,7 +552,7 @@ send_request_resend(struct neighbour *neigh,
time = MIN(time, wireless_hello_interval / 2); time = MIN(time, wireless_hello_interval / 2);
time = MIN(time, wired_hello_interval / 2); time = MIN(time, wired_hello_interval / 2);
time = MAX(time, 10); time = MAX(time, 10);
record_request(prefix, plen, seqno, router_hash, record_resend(RESEND_REQUEST, prefix, plen, seqno, router_hash,
neigh ? neigh->network : NULL, time); neigh ? neigh->network : NULL, time);
} }
......
...@@ -73,11 +73,11 @@ find_request(const unsigned char *prefix, unsigned char plen, ...@@ -73,11 +73,11 @@ find_request(const unsigned char *prefix, unsigned char plen,
} }
int int
record_request(const unsigned char *prefix, unsigned char plen, record_resend(int kind, const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash, unsigned short seqno, unsigned short router_hash,
struct network *network, int delay) struct network *network, int delay)
{ {
struct resend *request; struct resend *resend;
unsigned int ifindex = network ? network->ifindex : 0; unsigned int ifindex = network ? network->ifindex : 0;
if(input_filter(NULL, prefix, plen, NULL, ifindex) >= INFINITY || if(input_filter(NULL, prefix, plen, NULL, ifindex) >= INFINITY ||
...@@ -87,42 +87,42 @@ record_request(const unsigned char *prefix, unsigned char plen, ...@@ -87,42 +87,42 @@ record_request(const unsigned char *prefix, unsigned char plen,
if(delay >= 0xFFFF) if(delay >= 0xFFFF)
delay = 0xFFFF; delay = 0xFFFF;
request = find_request(prefix, plen, NULL); resend = find_resend(kind, prefix, plen, NULL);
if(request) { if(resend) {
if(request->delay && delay) if(resend->delay && delay)
request->delay = MIN(request->delay, delay); resend->delay = MIN(resend->delay, delay);
else if(delay) else if(delay)
request->delay = delay; resend->delay = delay;
request->time = now; resend->time = now;
request->max = 128; resend->max = kind == RESEND_REQUEST ? 128 : UPDATE_MAX;
if(request->router_hash == router_hash && if(resend->router_hash == router_hash &&
seqno_compare(request->seqno, seqno) > 0) { seqno_compare(resend->seqno, seqno) > 0) {
return 0; return 0;
} }
request->router_hash = router_hash; resend->router_hash = router_hash;
request->seqno = seqno; resend->seqno = seqno;
if(request->network != network) if(resend->network != network)
request->network = NULL; resend->network = NULL;
} else { } else {
request = malloc(sizeof(struct resend)); resend = malloc(sizeof(struct resend));
if(request == NULL) if(resend == NULL)
return -1; return -1;
request->kind = RESEND_REQUEST; resend->kind = kind;
request->max = 128; resend->max = kind == RESEND_REQUEST ? 128 : UPDATE_MAX;
request->delay = delay; resend->delay = delay;
memcpy(request->prefix, prefix, 16); memcpy(resend->prefix, prefix, 16);
request->plen = plen; resend->plen = plen;
request->seqno = seqno; resend->seqno = seqno;
request->router_hash = router_hash; resend->router_hash = router_hash;
request->network = network; resend->network = network;
request->time = now; resend->time = now;
request->next = to_resend; resend->next = to_resend;
to_resend = request; to_resend = resend;
} }
if(request->delay) { if(resend->delay) {
struct timeval timeout; struct timeval timeout;
timeval_plus_msec(&timeout, &request->time, request->delay); timeval_plus_msec(&timeout, &resend->time, resend->delay);
timeval_min(&resend_time, &timeout); timeval_min(&resend_time, &timeout);
} }
return 1; return 1;
...@@ -235,21 +235,32 @@ recompute_resend_time() ...@@ -235,21 +235,32 @@ recompute_resend_time()
void void
do_resend() do_resend()
{ {
struct resend *request; struct resend *resend;
request = to_resend; resend = to_resend;
while(request) { while(resend) {
if(!resend_expired(request) && request->delay > 0 && request->max > 0) { if(!resend_expired(resend) && resend->delay > 0 && resend->max > 0) {
struct timeval timeout; struct timeval timeout;
timeval_plus_msec(&timeout, &request->time, request->delay); timeval_plus_msec(&timeout, &resend->time, resend->delay);
if(timeval_compare(&now, &timeout) >= 0) { if(timeval_compare(&now, &timeout) >= 0) {
send_request(NULL, request->prefix, request->plen, 127, switch(resend->kind) {
request->seqno, request->router_hash); case RESEND_REQUEST:
request->delay *= 2; send_request(resend->network,
request->max--; resend->prefix, resend->plen, 127,
resend->seqno, resend->router_hash);
resend->delay *= 2;
break;
case RESEND_UPDATE:
send_update(resend->network, 1,
resend->prefix, resend->plen);
/* No back-off for updates */
break;
default: abort();
}
resend->max--;
} }
} }
request = request->next; resend = resend->next;
} }
recompute_resend_time(); recompute_resend_time();
} }
...@@ -21,6 +21,7 @@ THE SOFTWARE. ...@@ -21,6 +21,7 @@ THE SOFTWARE.
*/ */
#define REQUEST_TIMEOUT 125000 #define REQUEST_TIMEOUT 125000
#define UPDATE_MAX 4
#define RESEND_REQUEST 1 #define RESEND_REQUEST 1
#define RESEND_UPDATE 2 #define RESEND_UPDATE 2
...@@ -42,7 +43,7 @@ extern struct timeval resend_time; ...@@ -42,7 +43,7 @@ extern struct timeval resend_time;
struct resend *find_request(const unsigned char *prefix, unsigned char plen, struct resend *find_request(const unsigned char *prefix, unsigned char plen,
struct resend **previous_return); struct resend **previous_return);
int record_request(const unsigned char *prefix, unsigned char plen, int record_resend(int kind, const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash, unsigned short seqno, unsigned short router_hash,
struct network *net, int delay); struct network *net, int delay);
int unsatisfied_request(const unsigned char *prefix, unsigned char plen, int unsatisfied_request(const unsigned char *prefix, unsigned char plen,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment