Skip to content

Commit

Permalink
Merge pull request #20 from stapelberg/timeout
Browse files Browse the repository at this point in the history
Read timeout accounts for total time to receive relevant packet (2)
  • Loading branch information
d2g authored Jun 22, 2018
2 parents e612998 + 45101b2 commit 2cd8a27
Showing 1 changed file with 33 additions and 2 deletions.
35 changes: 33 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package dhcp4client

import (
"bytes"
"fmt"
"hash/fnv"
"math/rand"
"net"
"sync"
"syscall"
"time"

"github.com/d2g/dhcp4"
Expand Down Expand Up @@ -142,13 +144,32 @@ func (c *Client) SendDiscoverPacket() (dhcp4.Packet, error) {
return discoveryPacket, c.SendPacket(discoveryPacket)
}

// TimeoutError records a timeout when waiting for a DHCP packet.
type TimeoutError struct {
Timeout time.Duration
}

func (te *TimeoutError) Error() string {
return fmt.Sprintf("no DHCP packet received within %v", te.Timeout)
}

//Retreive Offer...
//Wait for the offer for a specific Discovery Packet.
func (c *Client) GetOffer(discoverPacket *dhcp4.Packet) (dhcp4.Packet, error) {
start := time.Now()

for {
c.connection.SetReadTimeout(c.timeout)
timeout := c.timeout - time.Since(start)
if timeout < 0 {
return dhcp4.Packet{}, &TimeoutError{Timeout: c.timeout}
}

c.connection.SetReadTimeout(timeout)
readBuffer, source, err := c.connection.ReadFrom()
if err != nil {
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EAGAIN {
return dhcp4.Packet{}, &TimeoutError{Timeout: c.timeout}
}
return dhcp4.Packet{}, err
}

Expand Down Expand Up @@ -186,10 +207,20 @@ func (c *Client) SendRequest(offerPacket *dhcp4.Packet) (dhcp4.Packet, error) {
//Retreive Acknowledgement
//Wait for the offer for a specific Request Packet.
func (c *Client) GetAcknowledgement(requestPacket *dhcp4.Packet) (dhcp4.Packet, error) {
start := time.Now()

for {
c.connection.SetReadTimeout(c.timeout)
timeout := c.timeout - time.Since(start)
if timeout < 0 {
return dhcp4.Packet{}, &TimeoutError{Timeout: c.timeout}
}

c.connection.SetReadTimeout(timeout)
readBuffer, source, err := c.connection.ReadFrom()
if err != nil {
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EAGAIN {
return dhcp4.Packet{}, &TimeoutError{Timeout: c.timeout}
}
return dhcp4.Packet{}, err
}

Expand Down

0 comments on commit 2cd8a27

Please sign in to comment.