Ensure route and interface is still valid before sending packet

This commit is contained in:
Jeremy Lakeman 2012-08-30 11:49:12 +09:30
parent 211e25608e
commit cf22ef8e8c
3 changed files with 24 additions and 6 deletions

View File

@ -146,6 +146,27 @@ void enum_subscribers(struct subscriber *start, int(*callback)(struct subscriber
walk_tree(&root, 0, start, callback, context);
}
// quick test to make sure the specified route is valid.
int subscriber_is_reachable(struct subscriber *subscriber){
if (!subscriber)
return REACHABLE_NONE;
if (subscriber->reachable==REACHABLE_INDIRECT
&& !(subscriber->next_hop
&& subscriber->next_hop->reachable==REACHABLE_DIRECT
&& subscriber_is_reachable(subscriber->next_hop)==REACHABLE_DIRECT)
)
return REACHABLE_NONE;
if (subscriber->reachable==REACHABLE_DIRECT
&& !(subscriber->interface
&& subscriber->interface->state==INTERFACE_STATE_UP)
)
return REACHABLE_NONE;
return subscriber->reachable;
}
// generate a new random broadcast address
int overlay_broadcast_generate_address(struct broadcast *addr)
{

View File

@ -97,6 +97,7 @@ extern struct subscriber *my_subscriber;
struct subscriber *find_subscriber(const unsigned char *sid, int len, int create);
void enum_subscribers(struct subscriber *start, int(*callback)(struct subscriber *, void *), void *context);
int subscriber_is_reachable(struct subscriber *subscriber);
int overlay_broadcast_drop_check(struct broadcast *addr);
int overlay_broadcast_generate_address(struct broadcast *addr);

View File

@ -950,7 +950,7 @@ overlay_calc_queue_time(overlay_txqueue *queue, struct overlay_frame *frame){
time_ms_t send_time;
// ignore packet if the destination is currently unreachable
if (frame->destination && frame->destination->reachable==REACHABLE_NONE)
if (frame->destination && subscriber_is_reachable(frame->destination)==REACHABLE_NONE)
return 0;
// when is the next packet from this queue due?
@ -991,7 +991,7 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
even if we hear it from somewhere else in the mean time
*/
if (frame->destination && frame->destination->reachable==REACHABLE_NONE)
if (frame->destination && subscriber_is_reachable(frame->destination)==REACHABLE_NONE)
goto skip;
struct subscriber *next_hop = frame->destination;
@ -1001,10 +1001,6 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
case REACHABLE_INDIRECT:
next_hop=next_hop->next_hop;
// make sure the routing table is consistent
if (next_hop->reachable!=REACHABLE_DIRECT)
goto skip;
// fall through
case REACHABLE_DIRECT:
frame->sendBroadcast=0;