Avoid several race conditions by using distinct variables for the different
signals. In particular different signals received in quick succession don't
overwrite each other any more, and odhcp6c_signal_process doesn't return true
anymore when a new SIGIO is received while another is still being processed.
static uint8_t *state_data[_STATE_MAX] = {NULL};
static size_t state_len[_STATE_MAX] = {0};
static uint8_t *state_data[_STATE_MAX] = {NULL};
static size_t state_len[_STATE_MAX] = {0};
-static volatile int do_signal = 0;
+static volatile bool signal_io = false;
+static volatile bool signal_usr1 = false;
+static volatile bool signal_usr2 = false;
+static volatile bool signal_term = false;
+
static int urandom_fd = -1, allow_slaac_only = 0;
static bool bound = false, release = true;
static time_t last_update = 0;
static int urandom_fd = -1, allow_slaac_only = 0;
static bool bound = false, release = true;
static time_t last_update = 0;
- while (do_signal != SIGTERM) { // Main logic
+ while (!signal_term) { // Main logic
odhcp6c_clear_state(STATE_SERVER_ID);
odhcp6c_clear_state(STATE_IA_NA);
odhcp6c_clear_state(STATE_IA_PD);
odhcp6c_clear_state(STATE_SERVER_ID);
odhcp6c_clear_state(STATE_IA_NA);
odhcp6c_clear_state(STATE_IA_PD);
syslog(LOG_NOTICE, "(re)starting transaction on %s", ifname);
syslog(LOG_NOTICE, "(re)starting transaction on %s", ifname);
+ signal_usr1 = signal_usr2 = false;
int mode = dhcpv6_request(DHCPV6_MSG_SOLICIT);
odhcp6c_signal_process();
int mode = dhcpv6_request(DHCPV6_MSG_SOLICIT);
odhcp6c_signal_process();
do {
int res = dhcpv6_request(mode == DHCPV6_STATELESS ?
DHCPV6_MSG_INFO_REQ : DHCPV6_MSG_REQUEST);
do {
int res = dhcpv6_request(mode == DHCPV6_STATELESS ?
DHCPV6_MSG_INFO_REQ : DHCPV6_MSG_REQUEST);
+ bool signalled = odhcp6c_signal_process();
- odhcp6c_signal_process();
- else if (do_signal > 0) {
bound = true;
syslog(LOG_NOTICE, "entering stateless-mode on %s", ifname);
bound = true;
syslog(LOG_NOTICE, "entering stateless-mode on %s", ifname);
- while (do_signal == 0 || do_signal == SIGUSR1) {
- do_signal = 0;
+ while (!signal_usr2 && !signal_term) {
+ signal_usr1 = false;
script_call("informed");
int res = dhcpv6_poll_reconfigure();
script_call("informed");
int res = dhcpv6_poll_reconfigure();
- if (do_signal == SIGUSR1) {
- do_signal = 0; // Acknowledged
+ if (signal_usr1) {
+ signal_usr1 = false; // Acknowledged
- } else if (do_signal > 0)
+ }
+ if (signal_usr2 || signal_term)
break;
res = dhcpv6_request(DHCPV6_MSG_INFO_REQ);
odhcp6c_signal_process();
break;
res = dhcpv6_request(DHCPV6_MSG_INFO_REQ);
odhcp6c_signal_process();
- if (do_signal == SIGUSR1)
continue;
else if (res < 0)
break;
continue;
else if (res < 0)
break;
bfd_start(ifname, bfd_loss, bfd_interval);
#endif
bfd_start(ifname, bfd_loss, bfd_interval);
#endif
- while (do_signal == 0 || do_signal == SIGUSR1) {
+ while (!signal_usr2 && !signal_term) {
// Renew Cycle
// Wait for T1 to expire or until we get a reconfigure
int res = dhcpv6_poll_reconfigure();
// Renew Cycle
// Wait for T1 to expire or until we get a reconfigure
int res = dhcpv6_poll_reconfigure();
}
// Handle signal, if necessary
}
// Handle signal, if necessary
- if (do_signal == SIGUSR1)
- do_signal = 0; // Acknowledged
- else if (do_signal > 0)
+ if (signal_usr1)
+ signal_usr1 = false; // Acknowledged
+ if (signal_usr2 || signal_term)
break; // Other signal type
// Send renew as T1 expired
break; // Other signal type
// Send renew as T1 expired
bool odhcp6c_signal_process(void)
{
bool odhcp6c_signal_process(void)
{
- if (do_signal == SIGIO) {
- do_signal = 0;
+ while (signal_io) {
+ signal_io = false;
+
bool ra_updated = ra_process();
if (ra_link_up())
bool ra_updated = ra_process();
if (ra_link_up())
if (ra_updated && (bound || allow_slaac_only == 0))
script_call("ra-updated"); // Immediate process urgent events
if (ra_updated && (bound || allow_slaac_only == 0))
script_call("ra-updated"); // Immediate process urgent events
+ return signal_usr1 || signal_usr2 || signal_term;
if (signal == SIGCHLD)
while (waitpid(-1, NULL, WNOHANG) > 0);
else if (signal == SIGUSR1)
if (signal == SIGCHLD)
while (waitpid(-1, NULL, WNOHANG) > 0);
else if (signal == SIGUSR1)
else if (signal == SIGUSR2)
else if (signal == SIGUSR2)
else if (signal == SIGIO)
else if (signal == SIGIO)