uint64_t current_milli_time = 0;
if (!retx->is_retransmit) {
+ // Initial delay handling
if (retx->max_delay) {
if (retx->delay_msec == 0) {
+ // Initial delay before starting the transaction
retx->delay_msec = (dhcpv6_rand_delay((10000 * retx->max_delay) / 2) + (1000 * retx->max_delay) / 2);
dhcpv6_set_state_timeout(retx->delay_msec);
+ // Add current time to calculate absolute time
retx->delay_msec += odhcp6c_get_milli_time();
return 1;
} else {
+ // Wait until delay expires
current_milli_time = odhcp6c_get_milli_time();
if (current_milli_time < retx->delay_msec) {
+ // Still waiting
dhcpv6_set_state_timeout(retx->delay_msec - current_milli_time);
return 1;
}
odhcp6c_random(retx->tr_id, sizeof(retx->tr_id));
}
+ // Record start time
retx->start = odhcp6c_get_milli_time();
retx->round_start = retx->start;
+ // Reset retransmission timeout initial value
retx->rto = 0;
}
while (req_msg_type == DHCPV6_MSG_SOLICIT && delay <= 0)
delay = dhcpv6_rand_delay(retx->init_timeo * 1000);
+ // First timeout
retx->rto = (retx->init_timeo * 1000 + delay);
} else {
+ // Exponential back-off with randomization to avoid synchronization
retx->rto = (2 * retx->rto + dhcpv6_rand_delay(retx->rto));
}
if (retx->max_timeo && (retx->rto >= retx->max_timeo * 1000)) {
+ // Cap to max timeout if set and exceeded
retx->rto = retx->max_timeo * 1000 +
dhcpv6_rand_delay(retx->max_timeo * 1000);
}
len = retx->reply_ret;
}
+ // Clamp round end (Round Trip Time) to 1s max wait after receiving a valid response (in milliseconds)
if (len > 0 && retx->round_end - retx->round_start > 1000)
retx->round_end = 1000 + retx->round_start;
dhcpv6_next_state();
}
} else {
+ // This sets the response polling timeout (round_end - round_start) in milliseconds
dhcpv6_set_state_timeout(retx->round_end - retx->round_start);
}
// retransmission strategy
struct dhcpv6_retx {
- uint8_t max_delay;
+ uint8_t max_delay; // Delay before starting transaction
uint8_t init_timeo;
uint16_t max_timeo;
- uint8_t max_rc;
+ uint8_t max_rc; // Max Retry Count
char name[8];
reply_handler *handler_reply;
int(*handler_finish)(void);
bool is_retransmit;
- uint64_t timeout;
- uint8_t rc;
- uint64_t start;
- uint8_t tr_id[3];
- int64_t rto;
- uint64_t round_start;
- uint64_t round_end;
- int reply_ret;
- uint64_t delay_msec;
+ uint64_t timeout; // Maximum duration (in seconds) for the entire DHCPv6 transaction. Varies based on the message type
+ uint8_t rc; // Retry Count
+ uint64_t start; // Transaction start time (in milliseconds)
+ uint8_t tr_id[3]; // Transaction ID
+ int64_t rto; // Retransmission TimeOut
+ uint64_t round_start; // the (RTT) time when a request was sent (in milliseconds)
+ uint64_t round_end; // the (RTT) time when a response was expected to arrive (in milliseconds)
+ int reply_ret; // Reply handler return value
+ uint64_t delay_msec; // Delay before starting the transaction
};
#define DHCPV6_OPT_HDR_SIZE 4