dhcp6: use updated DHCPv6 stuff

This commit is contained in:
Christopher Koch 2019-03-01 09:48:56 -08:00 committed by Michael Stapelberg
parent 7b1fcc9017
commit 33348e1f0d

View File

@ -62,7 +62,7 @@ type Client struct {
raddr *net.UDPAddr raddr *net.UDPAddr
timeNow func() time.Time timeNow func() time.Time
duid *dhcpv6.Duid duid *dhcpv6.Duid
advertise dhcpv6.DHCPv6 advertise *dhcpv6.Message
cfg Config cfg Config
err error err error
@ -159,7 +159,7 @@ func (c *Client) Close() error {
const maxUDPReceivedPacketSize = 8192 // arbitrary size. Theoretically could be up to 65kb const maxUDPReceivedPacketSize = 8192 // arbitrary size. Theoretically could be up to 65kb
func (c *Client) sendReceive(packet dhcpv6.DHCPv6, expectedType dhcpv6.MessageType) (dhcpv6.DHCPv6, error) { func (c *Client) sendReceive(packet *dhcpv6.Message, expectedType dhcpv6.MessageType) (*dhcpv6.Message, error) {
if packet == nil { if packet == nil {
return nil, fmt.Errorf("Packet to send cannot be nil") return nil, fmt.Errorf("Packet to send cannot be nil")
} }
@ -185,46 +185,36 @@ func (c *Client) sendReceive(packet dhcpv6.DHCPv6, expectedType dhcpv6.MessageTy
// wait for a reply // wait for a reply
c.Conn.SetReadDeadline(time.Now().Add(c.ReadTimeout)) c.Conn.SetReadDeadline(time.Now().Add(c.ReadTimeout))
var ( var (
adv dhcpv6.DHCPv6 adv *dhcpv6.Message
isMessage bool
) )
msg, ok := packet.(*dhcpv6.DHCPv6Message)
if ok {
isMessage = true
}
for { for {
buf := make([]byte, maxUDPReceivedPacketSize) buf := make([]byte, maxUDPReceivedPacketSize)
n, _, err := c.Conn.ReadFrom(buf) n, _, err := c.Conn.ReadFrom(buf)
if err != nil { if err != nil {
return nil, err return nil, err
} }
adv, err = dhcpv6.FromBytes(buf[:n]) adv, err = dhcpv6.MessageFromBytes(buf[:n])
if err != nil { if err != nil {
log.Printf("non-DHCP: %v", err) log.Printf("non-DHCP: %v", err)
// skip non-DHCP packets // skip non-DHCP packets
continue continue
} }
if recvMsg, ok := adv.(*dhcpv6.DHCPv6Message); ok && isMessage { if packet.TransactionID != adv.TransactionID {
// if a regular message, check the transaction ID first log.Printf("different XID: got %v, want %v", adv.TransactionID, packet.TransactionID)
// XXX should this unpack relay messages and check the XID of the
// inner packet too?
if msg.TransactionID() != recvMsg.TransactionID() {
log.Printf("different XID: got %v, want %v", recvMsg.TransactionID(), msg.TransactionID())
// different XID, we don't want this packet for sure // different XID, we don't want this packet for sure
continue continue
} }
}
if expectedType == dhcpv6.MessageTypeNone { if expectedType == dhcpv6.MessageTypeNone {
// just take whatever arrived // just take whatever arrived
break break
} else if adv.Type() == expectedType { } else if adv.MessageType == expectedType {
break break
} }
} }
return adv, nil return adv, nil
} }
func (c *Client) solicit(solicit dhcpv6.DHCPv6) (dhcpv6.DHCPv6, dhcpv6.DHCPv6, error) { func (c *Client) solicit(solicit *dhcpv6.Message) (*dhcpv6.Message, *dhcpv6.Message, error) {
var err error var err error
if solicit == nil { if solicit == nil {
solicit, err = dhcpv6.NewSolicitForInterface(c.interfaceName, dhcpv6.WithClientID(*c.duid)) solicit, err = dhcpv6.NewSolicitForInterface(c.interfaceName, dhcpv6.WithClientID(*c.duid))
@ -235,7 +225,7 @@ func (c *Client) solicit(solicit dhcpv6.DHCPv6) (dhcpv6.DHCPv6, dhcpv6.DHCPv6, e
if len(c.transactionIDs) > 0 { if len(c.transactionIDs) > 0 {
id := c.transactionIDs[0] id := c.transactionIDs[0]
c.transactionIDs = c.transactionIDs[1:] c.transactionIDs = c.transactionIDs[1:]
solicit.(*dhcpv6.DHCPv6Message).SetTransactionID(id) solicit.TransactionID = id
} }
iapd := []byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} iapd := []byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
opt, err := dhcpv6.ParseOptIAForPrefixDelegation(iapd) opt, err := dhcpv6.ParseOptIAForPrefixDelegation(iapd)
@ -247,8 +237,7 @@ func (c *Client) solicit(solicit dhcpv6.DHCPv6) (dhcpv6.DHCPv6, dhcpv6.DHCPv6, e
return solicit, advertise, err return solicit, advertise, err
} }
func (c *Client) request(advertise dhcpv6.DHCPv6) (dhcpv6.DHCPv6, dhcpv6.DHCPv6, error) { func (c *Client) request(advertise *dhcpv6.Message) (*dhcpv6.Message, *dhcpv6.Message, error) {
request, err := dhcpv6.NewRequestFromAdvertise(advertise, dhcpv6.WithClientID(*c.duid)) request, err := dhcpv6.NewRequestFromAdvertise(advertise, dhcpv6.WithClientID(*c.duid))
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -260,7 +249,7 @@ func (c *Client) request(advertise dhcpv6.DHCPv6) (dhcpv6.DHCPv6, dhcpv6.DHCPv6,
if len(c.transactionIDs) > 0 { if len(c.transactionIDs) > 0 {
id := c.transactionIDs[0] id := c.transactionIDs[0]
c.transactionIDs = c.transactionIDs[1:] c.transactionIDs = c.transactionIDs[1:]
request.(*dhcpv6.DHCPv6Message).SetTransactionID(id) request.TransactionID = id
} }
reply, err := c.sendReceive(request, dhcpv6.MessageTypeNone) reply, err := c.sendReceive(request, dhcpv6.MessageTypeNone)
return request, reply, err return request, reply, err
@ -281,7 +270,7 @@ func (c *Client) ObtainOrRenew() bool {
return true return true
} }
var newCfg Config var newCfg Config
for _, opt := range reply.Options() { for _, opt := range reply.Options {
switch o := opt.(type) { switch o := opt.(type) {
case *dhcpv6.OptIAForPrefixDelegation: case *dhcpv6.OptIAForPrefixDelegation:
t1 := c.timeNow().Add(time.Duration(o.T1) * time.Second) t1 := c.timeNow().Add(time.Duration(o.T1) * time.Second)
@ -306,17 +295,17 @@ func (c *Client) ObtainOrRenew() bool {
return true return true
} }
func (c *Client) Release() (release dhcpv6.DHCPv6, reply dhcpv6.DHCPv6, err error) { func (c *Client) Release() (release *dhcpv6.Message, reply *dhcpv6.Message, err error) {
release, err = dhcpv6.NewRequestFromAdvertise(c.advertise, dhcpv6.WithClientID(*c.duid)) release, err = dhcpv6.NewRequestFromAdvertise(c.advertise, dhcpv6.WithClientID(*c.duid))
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
release.(*dhcpv6.DHCPv6Message).SetMessage(dhcpv6.MessageTypeRelease) release.MessageType = dhcpv6.MessageTypeRelease
if len(c.transactionIDs) > 0 { if len(c.transactionIDs) > 0 {
id := c.transactionIDs[0] id := c.transactionIDs[0]
c.transactionIDs = c.transactionIDs[1:] c.transactionIDs = c.transactionIDs[1:]
release.(*dhcpv6.DHCPv6Message).SetTransactionID(id) release.TransactionID = id
} }
reply, err = c.sendReceive(release, dhcpv6.MessageTypeNone) reply, err = c.sendReceive(release, dhcpv6.MessageTypeNone)
return release, reply, err return release, reply, err