mirror of
https://github.com/arduino/Arduino.git
synced 2025-03-15 12:29:26 +01:00
Ethernet: fixed wrong handling of timeouts in DHCP
The signed math doesn't handle correctly cases where the lease time is set to infinity (0xFFFFFFFF). Fixes #2571 Fixes #2601 Fixes #2642 Fixes #985
This commit is contained in:
parent
50dff341f2
commit
a33c93b194
@ -124,7 +124,7 @@ int DhcpClass::request_DHCP_lease(){
|
|||||||
_dhcpUdpSocket.stop();
|
_dhcpUdpSocket.stop();
|
||||||
_dhcpTransactionId++;
|
_dhcpTransactionId++;
|
||||||
|
|
||||||
_secTimeout = millis() + 1000;
|
_lastCheckLeaseMillis = millis();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,45 +392,41 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
|
|||||||
4/DHCP_CHECK_REBIND_OK: rebind success
|
4/DHCP_CHECK_REBIND_OK: rebind success
|
||||||
*/
|
*/
|
||||||
int DhcpClass::checkLease(){
|
int DhcpClass::checkLease(){
|
||||||
//this uses a signed / unsigned trick to deal with millis overflow
|
int rc = DHCP_CHECK_NONE;
|
||||||
|
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
signed long snow = (long)now;
|
unsigned long elapsed = now - _lastCheckLeaseMillis;
|
||||||
int rc=DHCP_CHECK_NONE;
|
|
||||||
|
|
||||||
signed long factor;
|
// if more then one sec passed, reduce the counters accordingly
|
||||||
//calc how many ms past the timeout we are
|
if (elapsed >= 1000) {
|
||||||
factor = snow - (long)_secTimeout;
|
// set the new timestamps
|
||||||
//if on or passed the timeout, reduce the counters
|
_lastCheckLeaseMillis = now - (elapsed % 1000);
|
||||||
if ( factor >= 0 ){
|
elapsed = elapsed / 1000;
|
||||||
//next timeout should be now plus 1000 ms minus parts of second in factor
|
|
||||||
_secTimeout = snow + 1000 - factor % 1000;
|
|
||||||
//how many seconds late are we, minimum 1
|
|
||||||
factor = factor / 1000 +1;
|
|
||||||
|
|
||||||
//reduce the counters by that mouch
|
// decrease the counters by elapsed seconds
|
||||||
//if we can assume that the cycle time (factor) is fairly constant
|
// we assume that the cycle time (elapsed) is fairly constant
|
||||||
//and if the remainder is less than cycle time * 2
|
// if the remainder is less than cycle time * 2
|
||||||
//do it early instead of late
|
// do it early instead of late
|
||||||
if(_renewInSec < factor*2 )
|
if (_renewInSec < elapsed * 2)
|
||||||
_renewInSec = 0;
|
_renewInSec = 0;
|
||||||
else
|
else
|
||||||
_renewInSec -= factor;
|
_renewInSec -= elapsed;
|
||||||
|
|
||||||
if(_rebindInSec < factor*2 )
|
if (_rebindInSec < elapsed * 2)
|
||||||
_rebindInSec = 0;
|
_rebindInSec = 0;
|
||||||
else
|
else
|
||||||
_rebindInSec -= factor;
|
_rebindInSec -= elapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if we have a lease but should renew, do it
|
// if we have a lease but should renew, do it
|
||||||
if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){
|
if (_renewInSec == 0 &&_dhcp_state == STATE_DHCP_LEASED) {
|
||||||
_dhcp_state = STATE_DHCP_REREQUEST;
|
_dhcp_state = STATE_DHCP_REREQUEST;
|
||||||
rc = 1 + request_DHCP_lease();
|
rc = 1 + request_DHCP_lease();
|
||||||
}
|
}
|
||||||
|
|
||||||
//if we have a lease or is renewing but should bind, do it
|
// if we have a lease or is renewing but should bind, do it
|
||||||
if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){
|
if (_rebindInSec == 0 && (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START)) {
|
||||||
//this should basically restart completely
|
// this should basically restart completely
|
||||||
_dhcp_state = STATE_DHCP_START;
|
_dhcp_state = STATE_DHCP_START;
|
||||||
reset_DHCP_lease();
|
reset_DHCP_lease();
|
||||||
rc = 3 + request_DHCP_lease();
|
rc = 3 + request_DHCP_lease();
|
||||||
|
@ -148,11 +148,11 @@ private:
|
|||||||
uint8_t _dhcpDnsServerIp[4];
|
uint8_t _dhcpDnsServerIp[4];
|
||||||
uint32_t _dhcpLeaseTime;
|
uint32_t _dhcpLeaseTime;
|
||||||
uint32_t _dhcpT1, _dhcpT2;
|
uint32_t _dhcpT1, _dhcpT2;
|
||||||
signed long _renewInSec;
|
unsigned long _renewInSec;
|
||||||
signed long _rebindInSec;
|
unsigned long _rebindInSec;
|
||||||
unsigned long _timeout;
|
unsigned long _timeout;
|
||||||
unsigned long _responseTimeout;
|
unsigned long _responseTimeout;
|
||||||
unsigned long _secTimeout;
|
unsigned long _lastCheckLeaseMillis;
|
||||||
uint8_t _dhcp_state;
|
uint8_t _dhcp_state;
|
||||||
EthernetUDP _dhcpUdpSocket;
|
EthernetUDP _dhcpUdpSocket;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user