Skip to content

Commit

Permalink
client6: new async DHCPv6 client like #250.
Browse files Browse the repository at this point in the history
- Race-condition-averse.
- Supports multiple concurrent requests.
- Tested.
- Requires a fully compatible net.PacketConn.

Signed-off-by: Christopher Koch <[email protected]>
  • Loading branch information
hugelgupf authored and insomniacslk committed Apr 4, 2019
1 parent b40bd52 commit 175868d
Show file tree
Hide file tree
Showing 11 changed files with 734 additions and 132 deletions.
6 changes: 5 additions & 1 deletion dhcpv6/client6/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,11 @@ func (c *Client) sendReceive(ifname string, packet dhcpv6.DHCPv6, expectedType d
// an error if any. The modifiers will be applied to the Solicit before sending
// it, see modifiers.go
func (c *Client) Solicit(ifname string, modifiers ...dhcpv6.Modifier) (dhcpv6.DHCPv6, dhcpv6.DHCPv6, error) {
solicit, err := dhcpv6.NewSolicitForInterface(ifname)
iface, err := net.InterfaceByName(ifname)
if err != nil {
return nil, nil, err
}
solicit, err := dhcpv6.NewSolicit(iface.HardwareAddr)
if err != nil {
return nil, nil, err
}
Expand Down
9 changes: 7 additions & 2 deletions dhcpv6/dhcpv6.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ type DHCPv6 interface {
String() string
Summary() string
IsRelay() bool

// GetInnerMessage returns the innermost encapsulated DHCPv6 message.
//
// If it is already a message, it will be returned. If it is a relay
// message, the encapsulated message will be recursively extracted.
GetInnerMessage() (*Message, error)

GetOption(code OptionCode) []Option
Expand Down Expand Up @@ -108,11 +113,11 @@ func DecapsulateRelay(l DHCPv6) (DHCPv6, error) {
}
opt := l.GetOneOption(OptionRelayMsg)
if opt == nil {
return nil, fmt.Errorf("No OptRelayMsg found")
return nil, fmt.Errorf("malformed Relay message: no OptRelayMsg found")
}
relayOpt := opt.(*OptRelayMsg)
if relayOpt.RelayMessage() == nil {
return nil, fmt.Errorf("Relay message cannot be nil")
return nil, fmt.Errorf("malformed Relay message: encapsulated message is empty")
}
return relayOpt.RelayMessage(), nil
}
Expand Down
10 changes: 3 additions & 7 deletions dhcpv6/dhcpv6message.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,14 @@ func NewSolicitWithCID(duid Duid, modifiers ...Modifier) (*Message, error) {
return m, nil
}

// NewSolicitForInterface creates a new SOLICIT message with DUID-LLT, using the
// NewSolicit creates a new SOLICIT message with DUID-LLT, using the
// given network interface's hardware address and current time
func NewSolicitForInterface(ifname string, modifiers ...Modifier) (*Message, error) {
iface, err := net.InterfaceByName(ifname)
if err != nil {
return nil, err
}
func NewSolicit(ifaceHWAddr net.HardwareAddr, modifiers ...Modifier) (*Message, error) {
duid := Duid{
Type: DUID_LLT,
HwType: iana.HWTypeEthernet,
Time: GetTime(),
LinkLayerAddr: iface.HardwareAddr,
LinkLayerAddr: ifaceHWAddr,
}
return NewSolicitWithCID(duid, modifiers...)
}
Expand Down
5 changes: 5 additions & 0 deletions dhcpv6/modifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ func WithDomainSearchList(searchlist ...string) Modifier {
}
}

// WithRapidCommit adds the rapid commit option to a message.
func WithRapidCommit(d DHCPv6) {
d.UpdateOption(&OptionGeneric{OptionCode: OptionRapidCommit})
}

// WithRequestedOptions adds requested options to the packet
func WithRequestedOptions(optionCodes ...OptionCode) Modifier {
return func(d DHCPv6) {
Expand Down
Loading

0 comments on commit 175868d

Please sign in to comment.