浏览代码

dhcp: retry REQUEST slower and with exponential backoff. Fixes #464

Dario Nieuwenhuis 4 年之前
父节点
当前提交
1c33438445
共有 2 个文件被更改,包括 34 次插入4 次删除
  1. 6 4
      src/socket/dhcpv4.rs
  2. 28 0
      src/time.rs

+ 6 - 4
src/socket/dhcpv4.rs

@@ -11,8 +11,10 @@ use super::{PollAt, Socket};
 
 const DISCOVER_TIMEOUT: Duration = Duration::from_secs(10);
 
-const REQUEST_TIMEOUT: Duration = Duration::from_secs(1);
-const REQUEST_RETRIES: u16 = 15;
+// timeout doubles every 2 tries.
+// total time 5 + 5 + 10 + 10 + 20 = 50s
+const REQUEST_TIMEOUT: Duration = Duration::from_secs(5);
+const REQUEST_RETRIES: u16 = 5;
 
 const MIN_RENEW_TIMEOUT: Duration = Duration::from_secs(60);
 
@@ -348,8 +350,8 @@ impl Dhcpv4Socket {
                 ipv4_repr.payload_len = udp_repr.header_len() + dhcp_repr.buffer_len();
                 emit((ipv4_repr, udp_repr, dhcp_repr))?;
 
-                // Exponential backoff
-                state.retry_at = now + REQUEST_TIMEOUT;
+                // Exponential backoff: Double every 2 retries.
+                state.retry_at = now + (REQUEST_TIMEOUT << (state.retry as u32 / 2));
                 state.retry += 1;
 
                 self.transaction_id = next_transaction_id;

+ 28 - 0
src/time.rs

@@ -232,6 +232,34 @@ impl ops::DivAssign<u32> for Duration {
     }
 }
 
+impl ops::Shl<u32> for Duration {
+    type Output = Duration;
+    
+    fn shl(self, rhs: u32) -> Duration {
+        Duration::from_millis(self.millis << rhs)
+    }
+}
+
+impl ops::ShlAssign<u32> for Duration {
+    fn shl_assign(&mut self, rhs: u32) {
+        self.millis <<= rhs;
+    }
+}
+
+impl ops::Shr<u32> for Duration {
+    type Output = Duration;
+    
+    fn shr(self, rhs: u32) -> Duration {
+        Duration::from_millis(self.millis >> rhs)
+    }
+}
+
+impl ops::ShrAssign<u32> for Duration {
+    fn shr_assign(&mut self, rhs: u32) {
+        self.millis >>= rhs;
+    }
+}
+
 impl From<::core::time::Duration> for Duration {
     fn from(other: ::core::time::Duration) -> Duration {
         Duration::from_millis(