func (c *client) Renew(id ID, ack *dhcp.Packet) (*dhcp.Packet, error) { c.Lock() defer c.Unlock() log.Debugf("renewing IP %s", ack.YourIP()) cl, err := c.newClient(ack) if err != nil { return nil, err } defer cl.Close() p := dhcp4.Packet(ack.Packet) var newack dhcp4.Packet err = withRetry(func() error { var err error newack, err = c.renew(id, p, cl) return err }) if err != nil { return nil, err } return dhcp.NewPacket([]byte(newack)), nil }
func (c *client) request(id ID, cl *dhcp4client.Client) (bool, *dhcp.Packet, error) { dp, err := c.discoverPacket(id, cl) if err != nil { return false, nil, err } dp.PadToMinSize() if err = cl.SendPacket(*dp); err != nil { return false, nil, err } var op dhcp4.Packet for { op, err = cl.GetOffer(dp) if err != nil { return false, nil, err } if isCompletePacket(dhcp.NewPacket([]byte(op))) { break } } rp, err := c.requestPacket(id, cl, &op) if err != nil { return false, nil, err } rp.PadToMinSize() if err = cl.SendPacket(*rp); err != nil { return false, nil, err } ack, err := cl.GetAcknowledgement(rp) if err != nil { return false, nil, err } opts := ack.ParseOptions() if dhcp4.MessageType(opts[dhcp4.OptionDHCPMessageType][0]) == dhcp4.NAK { return false, nil, fmt.Errorf("Got NAK from DHCP server") } return true, dhcp.NewPacket([]byte(ack)), nil }
func (c *client) LastAck() *dhcp.Packet { defer trace.End(trace.Begin("")) if c.ack == nil { return nil } return dhcp.NewPacket(c.ack) }
func (c *client) newClient() (*dhcp4client.Client, error) { defer trace.End(trace.Begin("")) ack := dhcp.NewPacket(c.ack) conn, err := dhcp4client.NewInetSock(dhcp4client.SetRemoteAddr(net.UDPAddr{IP: ack.ServerIP(), Port: 67})) if err != nil { return nil, err } cl, err := dhcp4client.New(dhcp4client.Connection(conn), dhcp4client.Timeout(c.timeout)) if err != nil { return nil, err } return cl, nil }