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; return;
} }
bytes = read(c->alarm.poll.fd, &c->line[c->line_length], 1); bytes = read(c->alarm.poll.fd, &c->line[c->line_length], 1);
if (bytes < 1) { if (bytes<0){
switch(errno) { switch(errno) {
case EINTR: case EINTR:
case ENOTRECOVERABLE: case ENOTRECOVERABLE:
@ -210,10 +210,13 @@ void monitor_client_poll(struct sched_ent *alarm)
WHY_perror("read"); WHY_perror("read");
/* all other errors; close socket */ /* all other errors; close socket */
monitor_close(c); monitor_close(c);
return;
} }
return;
} }
if (bytes<1)
break;
// silently skip all \r characters // silently skip all \r characters
if (c->line[c->line_length] == '\r') if (c->line[c->line_length] == '\r')
continue; 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, ssize_t sent = sendto(fd, bytes, len, 0,
&addr.addr, addr.addrlen); &addr.addr, addr.addrlen);
if (sent == -1) if (sent == -1){
return WHYF_perror("sendto(%d, %zu, %s)", fd, len, alloca_socket_address(&addr)); if (errno != EAGAIN && errno != EWOULDBLOCK)
return WHYF_perror("sendto(%d, %zu, %s)", fd, len, alloca_socket_address(&addr));
}
return 0; return 0;
} }
@ -1123,9 +1125,19 @@ void overlay_interface_discover(struct sched_ent *alarm)
} }
// Close any interfaces that have gone away. // Close any interfaces that have gone away.
unsigned inet_up_count=0;
for(i = 0; i < OVERLAY_MAX_INTERFACES; i++){ for(i = 0; i < OVERLAY_MAX_INTERFACES; i++){
if (overlay_interfaces[i].state==INTERFACE_STATE_DETECTING) if (overlay_interfaces[i].state==INTERFACE_STATE_DETECTING)
overlay_interface_close(&overlay_interfaces[i]); 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 // 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); DEFINE_ALARM(fd_periodicstats);
void fd_periodicstats(struct sched_ent *alarm) void fd_periodicstats(struct sched_ent *UNUSED(alarm))
{ {
fd_showstats(); fd_showstats();
fd_clearstats(); fd_clearstats();
alarm->alarm = gettime_ms()+3000; time_ms_t now = gettime_ms();
alarm->deadline = alarm->alarm+1000; RESCHEDULE(&ALARM_STRUCT(fd_periodicstats), now+3000, TIME_MS_NEVER_WILL, now+3500);
schedule(alarm);
} }
void dump_stack(int log_level) void dump_stack(int log_level)

View File

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