Ensure interface and routing alarms stop when network interfaces are all down

This commit is contained in:
Jeremy Lakeman 2014-06-12 16:03:52 +09:30
parent 55b9de721e
commit e5e848e838
4 changed files with 42 additions and 45 deletions

View File

@ -197,7 +197,7 @@ void monitor_client_poll(struct sched_ent *alarm)
return;
}
bytes = read(c->alarm.poll.fd, &c->line[c->line_length], 1);
if (bytes < 1) {
if (bytes<0){
switch(errno) {
case EINTR:
case ENOTRECOVERABLE:
@ -210,10 +210,13 @@ void monitor_client_poll(struct sched_ent *alarm)
WHY_perror("read");
/* all other errors; close socket */
monitor_close(c);
return;
}
return;
}
if (bytes<1)
break;
// silently skip all \r characters
if (c->line[c->line_length] == '\r')
continue;

View File

@ -809,8 +809,10 @@ static int send_local_packet(int fd, const uint8_t *bytes, size_t len, const cha
ssize_t sent = sendto(fd, bytes, len, 0,
&addr.addr, addr.addrlen);
if (sent == -1)
return WHYF_perror("sendto(%d, %zu, %s)", fd, len, alloca_socket_address(&addr));
if (sent == -1){
if (errno != EAGAIN && errno != EWOULDBLOCK)
return WHYF_perror("sendto(%d, %zu, %s)", fd, len, alloca_socket_address(&addr));
}
return 0;
}
@ -1123,9 +1125,19 @@ void overlay_interface_discover(struct sched_ent *alarm)
}
// Close any interfaces that have gone away.
unsigned inet_up_count=0;
for(i = 0; i < OVERLAY_MAX_INTERFACES; i++){
if (overlay_interfaces[i].state==INTERFACE_STATE_DETECTING)
overlay_interface_close(&overlay_interfaces[i]);
if (overlay_interfaces[i].state==INTERFACE_STATE_UP &&
overlay_interfaces[i].address.addr.sa_family == AF_INET)
inet_up_count++;
}
if (inet_up_count==0 && sock_any.poll.fd>0){
unwatch(&sock_any);
close(sock_any.poll.fd);
sock_any.poll.fd=-1;
}
// if there are no real interfaces to detect, we can wait for the config file to change

View File

@ -208,13 +208,12 @@ int fd_showstats()
}
DEFINE_ALARM(fd_periodicstats);
void fd_periodicstats(struct sched_ent *alarm)
void fd_periodicstats(struct sched_ent *UNUSED(alarm))
{
fd_showstats();
fd_clearstats();
alarm->alarm = gettime_ms()+3000;
alarm->deadline = alarm->alarm+1000;
schedule(alarm);
fd_clearstats();
time_ms_t now = gettime_ms();
RESCHEDULE(&ALARM_STRUCT(fd_periodicstats), now+3000, TIME_MS_NEVER_WILL, now+3500);
}
void dump_stack(int log_level)

View File

@ -164,16 +164,7 @@ struct link_state{
time_ms_t next_update;
};
static void link_send(struct sched_ent *alarm);
static struct profile_total link_send_stats={
.name="link_send",
};
static struct sched_ent link_send_alarm={
.function = link_send,
.stats = &link_send_stats,
.alarm = TIME_MS_NEVER_WILL,
};
DEFINE_ALARM(link_send);
struct neighbour *neighbours=NULL;
int route_version=0;
@ -544,7 +535,7 @@ static int append_link(struct subscriber *subscriber, void *context)
if (state->next_update - 20 <= now){
// Other entries in our keyring are always one hop away from us.
if (append_link_state(payload, 0, my_subscriber, subscriber, -1, 1, -1, 0, 0)){
link_send_alarm.alarm = now+5;
ALARM_STRUCT(link_send).alarm = now+5;
return 1;
}
// include information about this link every 5s
@ -558,7 +549,7 @@ static int append_link(struct subscriber *subscriber, void *context)
if (state->next_update - 20 <= now){
if (append_link_state(payload, 0, state->transmitter, subscriber, -1,
best_link?best_link->link_version:-1, -1, 0, best_link?best_link->drop_rate:32)){
link_send_alarm.alarm = now+5;
ALARM_STRUCT(link_send).alarm = now+5;
return 1;
}
// include information about this link every 5s
@ -566,8 +557,8 @@ static int append_link(struct subscriber *subscriber, void *context)
}
}
if (state->next_update < link_send_alarm.alarm)
link_send_alarm.alarm = state->next_update;
if (state->next_update < ALARM_STRUCT(link_send).alarm)
ALARM_STRUCT(link_send).alarm = state->next_update;
return 0;
}
@ -884,16 +875,16 @@ static int link_send_neighbours()
send_neighbour_link(n);
}
if (n->next_neighbour_update < link_send_alarm.alarm)
link_send_alarm.alarm = n->next_neighbour_update;
if (n->next_neighbour_update < ALARM_STRUCT(link_send).alarm)
ALARM_STRUCT(link_send).alarm = n->next_neighbour_update;
struct link_out *out = n->out_links;
while(out){
if (out->destination->tick_ms>0 && out->destination->unicast){
if (out->destination->last_tx + out->destination->tick_ms < now)
overlay_send_tick_packet(out->destination);
if (out->destination->last_tx + out->destination->tick_ms < link_send_alarm.alarm)
link_send_alarm.alarm = out->destination->last_tx + out->destination->tick_ms;
if (out->destination->last_tx + out->destination->tick_ms < ALARM_STRUCT(link_send).alarm)
ALARM_STRUCT(link_send).alarm = out->destination->last_tx + out->destination->tick_ms;
}
out=out->_next;
}
@ -904,8 +895,11 @@ static int link_send_neighbours()
}
// send link details
static void link_send(struct sched_ent *alarm)
void link_send(struct sched_ent *alarm)
{
if (!neighbours)
return;
alarm->alarm=TIME_MS_NEVER_WILL;
// TODO use a separate alarm
@ -942,11 +936,8 @@ static void update_alarm(struct __sourceloc __whence, time_ms_t limit)
{
if (limit == 0)
FATALF("limit == 0");
if (link_send_alarm.alarm>limit){
unschedule(&link_send_alarm);
link_send_alarm.alarm = limit;
link_send_alarm.deadline = limit+10;
schedule(&link_send_alarm);
if (ALARM_STRUCT(link_send).alarm>limit){
RESCHEDULE(&ALARM_STRUCT(link_send), limit, limit, limit+20);
}
}
@ -1464,12 +1455,8 @@ int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payl
if (changed){
route_version++;
neighbour->path_version ++;
if (link_send_alarm.alarm>now+5){
unschedule(&link_send_alarm);
link_send_alarm.alarm=now+5;
// read all incoming packets first
link_send_alarm.deadline=now+15;
schedule(&link_send_alarm);
if (ALARM_STRUCT(link_send).alarm>now+5){
RESCHEDULE(&ALARM_STRUCT(link_send), now+5, now+5, now+25);
}
}
OUT();
@ -1537,12 +1524,8 @@ int link_state_legacy_ack(struct overlay_frame *frame, time_ms_t now)
if (changed){
route_version++;
neighbour->path_version ++;
if (link_send_alarm.alarm>now+5){
unschedule(&link_send_alarm);
link_send_alarm.alarm=now+5;
// read all incoming packets first
link_send_alarm.deadline=now+15;
schedule(&link_send_alarm);
if (ALARM_STRUCT(link_send).alarm>now+5){
RESCHEDULE(&ALARM_STRUCT(link_send), now+5, now+5, now+25);
}
}