Commit 49a9c3a0 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Remember forwarded requests, satisfy them later.

parent 167be8b8
......@@ -58,6 +58,8 @@ find_destination(const unsigned char *d, int create, unsigned char seqno)
dests[i].seqno = seqno;
dests[i].metric = INFINITY;
dests[i].time = now.tv_sec;
dests[i].requested_seqno = -1;
dests[i].requested_net = NULL;
return &dests[i];
}
......@@ -73,3 +75,47 @@ update_destination(struct destination *dest,
dest->time = now.tv_sec;
}
void
notice_request(struct destination *dest, unsigned char seqno,
struct network *net)
{
if(dest->requested_seqno < 0) {
dest->requested_seqno = seqno;
dest->requested_net = net;
} else {
if(seqno_compare(dest->requested_seqno, seqno) < 0)
dest->requested_seqno = seqno;
if(net == NULL || net != dest->requested_net)
dest->requested_net = NULL;
}
}
int
request_requested(struct destination *dest, unsigned char seqno,
struct network *net)
{
if(dest->requested_seqno < 0)
return 0;
if(seqno_compare(dest->requested_seqno, seqno) < 0)
return 0;
if(net == NULL || net != dest->requested_net)
return 0;
return 1;
}
void
satisfy_request(struct destination *dest, unsigned char seqno,
struct network *net)
{
if(dest->requested_seqno >= 0) {
if(net == NULL || net == dest->requested_net) {
if(seqno_compare(seqno, dest->requested_seqno) >= 0) {
dest->requested_seqno = -1;
dest->requested_net = NULL;
}
}
}
}
......@@ -25,9 +25,17 @@ struct destination {
unsigned char seqno;
unsigned short metric;
int time;
int requested_seqno;
struct network *requested_net;
};
struct destination *find_destination(const unsigned char *d,
int create, unsigned char seqno);
void update_destination(struct destination *dest,
unsigned char seqno, unsigned short metric);
void notice_request(struct destination *dest, unsigned char seqno,
struct network *net);
int request_requested(struct destination *dest, unsigned char seqno,
struct network *net);
void satisfy_request(struct destination *dest, unsigned char seqno,
struct network *net);
......@@ -144,14 +144,16 @@ parse_packet(const unsigned char *from, struct network *net,
if(seqno_compare(installed->seqno,
theirseqno) >= 0)
send_update(dest, neigh->network);
else if(hopcount >= 2) {
send_unicast_request(installed->nexthop,
dest,
hopcount - 1,
theirseqno);
/* For now, let's hope the new seqno
arrives before the update is flushed. */
send_update(dest, neigh->network);
else if(!request_requested(dest,
theirseqno,
neigh->network)) {
if(hopcount >= 2)
send_unicast_request(installed->nexthop,
dest,
hopcount - 1,
theirseqno);
notice_request(dest, theirseqno,
neigh->network);
}
}
}
......@@ -530,6 +532,7 @@ flushupdates(void)
accumulate_byte(net, seqno);
accumulate_short(net, metric);
accumulate_data(net, buffered_updates[i]->address, 16);
satisfy_request(buffered_updates[i], seqno, net);
}
}
schedule_flush_now(net);
......@@ -578,6 +581,12 @@ send_update(struct destination *dest, struct network *net)
if(net == NULL) {
for(i = 0; i < numnets; i++)
send_update(dest, &nets[i]);
if(dest != NULL) {
/* This case is not handled by flushupdates. */
struct route *installed = find_installed_route(dest);
satisfy_request(dest, installed ? installed->seqno : dest->seqno,
NULL);
}
return;
}
......
......@@ -428,6 +428,9 @@ send_triggered_update(struct route *route, int oldmetric)
if((route->metric >= INFINITY && oldmetric < INFINITY) ||
(route->metric - oldmetric >= 256 || oldmetric - route->metric >= 256))
send_update(route->dest, NULL);
else if(route->dest->requested_seqno >= 0 &&
seqno_compare(route->dest->requested_seqno, route->seqno) <= 0)
send_update(route->dest, route->dest->requested_net);
if(oldmetric < INFINITY) {
if(route->metric >= INFINITY) {
......
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