@@ -64,7 +64,9 @@ pub struct Client {
6464///
6565/// To provide memory for the dynamic IP address, configure your
6666/// `Interface` with one of `ip_addrs` and the `ipv4_gateway` being
67- /// `Ipv4Address::UNSPECIFIED`.
67+ /// `Ipv4Address::UNSPECIFIED`. You must also assign this `0.0.0.0/0`
68+ /// while the client's state is `Discovering`. Hence, the `poll()`
69+ /// method returns a corresponding `Config` struct in this case.
6870///
6971/// You must call `dhcp_client.poll()` after `iface.poll()` to send
7072/// and receive DHCP packets.
@@ -135,12 +137,18 @@ impl Client {
135137 None
136138 } ;
137139
138- // Send requests
139- if udp_socket. can_send ( ) && now >= self . next_egress {
140- self . egress ( iface, & mut * udp_socket, now) ?;
140+ if config. is_some ( ) {
141+ // Return a new config immediately so that addresses can
142+ // be configured that are required by egress().
143+ Ok ( config)
144+ } else {
145+ // Send requests
146+ if udp_socket. can_send ( ) && now >= self . next_egress {
147+ self . egress ( iface, & mut * udp_socket, now)
148+ } else {
149+ Ok ( None )
150+ }
141151 }
142-
143- Ok ( config)
144152 }
145153
146154 fn ingress < DeviceT : for < ' d > Device < ' d > >
@@ -227,7 +235,7 @@ impl Client {
227235 config
228236 }
229237
230- fn egress < DeviceT : for < ' d > Device < ' d > > ( & mut self , iface : & mut Interface < DeviceT > , udp_socket : & mut UdpSocket , now : Instant ) -> Result < ( ) > {
238+ fn egress < DeviceT : for < ' d > Device < ' d > > ( & mut self , iface : & mut Interface < DeviceT > , udp_socket : & mut UdpSocket , now : Instant ) -> Result < Option < Config > > {
231239 // Reset after maximum amount of retries
232240 let retries_exceeded = match self . state {
233241 ClientState :: Requesting ( ref mut r_state) if r_state. retry >= REQUEST_RETRIES => {
@@ -242,6 +250,14 @@ impl Client {
242250 } ;
243251 if retries_exceeded {
244252 self . reset ( now) ;
253+ // Return a config now so that user code assigns the
254+ // 0.0.0.0/0 address, which will be used sending a DHCP
255+ // discovery packet in the next call to egress().
256+ return Ok ( Some ( Config {
257+ address : Some ( Ipv4Cidr :: new ( Ipv4Address :: UNSPECIFIED , 0 ) ) ,
258+ router : None ,
259+ dns_servers : [ None ; 3 ] ,
260+ } ) ) ;
245261 }
246262
247263 // Prepare sending next packet
@@ -265,6 +281,11 @@ impl Client {
265281 parameter_request_list : None ,
266282 dns_servers : None ,
267283 } ;
284+ let mut send_packet = |endpoint, dhcp_repr| {
285+ send_packet ( udp_socket, & endpoint, dhcp_repr)
286+ . map ( |( ) | None )
287+ } ;
288+
268289
269290 match self . state {
270291 ClientState :: Discovering => {
@@ -275,7 +296,7 @@ impl Client {
275296 port : UDP_SERVER_PORT ,
276297 } ;
277298 net_trace ! ( "DHCP send discover to {}: {:?}" , endpoint, dhcp_repr) ;
278- send_packet ( udp_socket , & endpoint, & dhcp_repr)
299+ send_packet ( endpoint, & dhcp_repr)
279300 }
280301 ClientState :: Requesting ( ref mut r_state) => {
281302 r_state. retry += 1 ;
@@ -296,7 +317,7 @@ impl Client {
296317 dhcp_repr. server_identifier = Some ( r_state. server_identifier ) ;
297318 dhcp_repr. parameter_request_list = Some ( PARAMETER_REQUEST_LIST ) ;
298319 net_trace ! ( "DHCP send request to {} = {:?}" , endpoint, dhcp_repr) ;
299- send_packet ( udp_socket , & endpoint, & dhcp_repr)
320+ send_packet ( endpoint, & dhcp_repr)
300321 }
301322 ClientState :: Renew ( ref mut p_state) => {
302323 p_state. retry += 1 ;
@@ -310,7 +331,7 @@ impl Client {
310331 dhcp_repr. message_type = DhcpMessageType :: Request ;
311332 dhcp_repr. client_ip = client_ip;
312333 net_trace ! ( "DHCP send renew to {}: {:?}" , endpoint, dhcp_repr) ;
313- send_packet ( udp_socket , & endpoint, & dhcp_repr)
334+ send_packet ( endpoint, & dhcp_repr)
314335 }
315336 }
316337 }
@@ -319,6 +340,9 @@ impl Client {
319340 ///
320341 /// Use this to speed up acquisition of an address in a new
321342 /// network if a link was down and it is now back up.
343+ ///
344+ /// You *must* configure a `0.0.0.0` address on your interface
345+ /// before the next call to `poll()`!
322346 pub fn reset ( & mut self , now : Instant ) {
323347 net_trace ! ( "DHCP reset" ) ;
324348 self . state = ClientState :: Discovering ;
0 commit comments