fixing coding-style related issues

This commit is contained in:
Dmitri Dolguikh 2017-11-01 11:31:59 -07:00 committed by Dave Anderson
parent 11a8e61c10
commit 8725ede99b
13 changed files with 525 additions and 524 deletions

View File

@ -6,13 +6,13 @@ import (
)
type IdentityAssociation struct {
IpAddress net.IP
ClientId []byte
InterfaceId []byte
IPAddress net.IP
ClientID []byte
InterfaceID []byte
CreatedAt time.Time
}
type AddressPool interface {
ReserveAddresses(clientId []byte, interfaceIds [][]byte) ([]*IdentityAssociation, error)
ReleaseAddresses(clientId []byte, interfaceIds [][]byte)
ReserveAddresses(clientID []byte, interfaceIds [][]byte) ([]*IdentityAssociation, error)
ReleaseAddresses(clientID []byte, interfaceIds [][]byte)
}

View File

@ -11,75 +11,75 @@ import (
)
type BootConfiguration interface {
GetBootUrl(id []byte, clientArchType uint16) ([]byte, error)
GetBootURL(id []byte, clientArchType uint16) ([]byte, error)
GetPreference() []byte
GetRecursiveDns() []net.IP
GetRecursiveDNS() []net.IP
}
type StaticBootConfiguration struct {
HttpBootUrl []byte
IPxeBootUrl []byte
RecursiveDns []net.IP
Preference []byte
UsePreference bool
HTTPBootURL []byte
IPxeBootURL []byte
RecursiveDNS []net.IP
Preference []byte
UsePreference bool
}
func MakeStaticBootConfiguration(httpBootUrl, ipxeBootUrl string, preference uint8, usePreference bool,
func MakeStaticBootConfiguration(httpBootURL, ipxeBootURL string, preference uint8, usePreference bool,
dnsServerAddresses []net.IP) *StaticBootConfiguration {
ret := &StaticBootConfiguration{HttpBootUrl: []byte(httpBootUrl), IPxeBootUrl: []byte(ipxeBootUrl), UsePreference: usePreference}
ret := &StaticBootConfiguration{HTTPBootURL: []byte(httpBootURL), IPxeBootURL: []byte(ipxeBootURL), UsePreference: usePreference}
if usePreference {
ret.Preference = make([]byte, 1)
ret.Preference[0] = byte(preference)
}
ret.RecursiveDns = dnsServerAddresses
ret.RecursiveDNS = dnsServerAddresses
return ret
}
func (bc *StaticBootConfiguration) GetBootUrl(id []byte, clientArchType uint16) ([]byte, error) {
func (bc *StaticBootConfiguration) GetBootURL(id []byte, clientArchType uint16) ([]byte, error) {
if 0x10 == clientArchType {
return bc.HttpBootUrl, nil
return bc.HTTPBootURL, nil
}
return bc.IPxeBootUrl, nil
return bc.IPxeBootURL, nil
}
func (bc *StaticBootConfiguration) GetPreference() []byte {
return bc.Preference
}
func (bc *StaticBootConfiguration) GetRecursiveDns() []net.IP {
return bc.RecursiveDns
func (bc *StaticBootConfiguration) GetRecursiveDNS() []net.IP {
return bc.RecursiveDNS
}
type ApiBootConfiguration struct {
client *http.Client
urlPrefix string
RecursiveDns []net.IP
Preference []byte
UsePreference bool
type APIBootConfiguration struct {
Client *http.Client
URLPrefix string
RecursiveDNS []net.IP
Preference []byte
UsePreference bool
}
func MakeApiBootConfiguration(url string, timeout time.Duration, preference uint8, usePreference bool,
dnsServerAddresses []net.IP) *ApiBootConfiguration {
dnsServerAddresses []net.IP) *APIBootConfiguration {
if !strings.HasSuffix(url, "/") {
url += "/"
}
ret := &ApiBootConfiguration{
client: &http.Client{Timeout: timeout},
urlPrefix: url + "v1",
ret := &APIBootConfiguration{
Client: &http.Client{Timeout: timeout},
URLPrefix: url + "v1",
UsePreference: usePreference,
}
if usePreference {
ret.Preference = make([]byte, 1)
ret.Preference[0] = byte(preference)
}
ret.RecursiveDns = dnsServerAddresses
ret.RecursiveDNS = dnsServerAddresses
return ret
}
func (bc *ApiBootConfiguration) GetBootUrl(id []byte, clientArchType uint16) ([]byte, error) {
reqURL := fmt.Sprintf("%s/boot/%x/%d", bc.urlPrefix, id, clientArchType)
resp, err := bc.client.Get(reqURL)
func (bc *APIBootConfiguration) GetBootURL(id []byte, clientArchType uint16) ([]byte, error) {
reqURL := fmt.Sprintf("%s/boot/%x/%d", bc.URLPrefix, id, clientArchType)
resp, err := bc.Client.Get(reqURL)
if err != nil {
return nil, err
}
@ -96,13 +96,13 @@ func (bc *ApiBootConfiguration) GetBootUrl(id []byte, clientArchType uint16) ([]
return []byte(url), nil
}
func (bc *ApiBootConfiguration) makeURLAbsolute(urlStr string) (string, error) {
func (bc *APIBootConfiguration) makeURLAbsolute(urlStr string) (string, error) {
u, err := url.Parse(urlStr)
if err != nil {
return "", fmt.Errorf("%q is not an URL", urlStr)
}
if !u.IsAbs() {
base, err := url.Parse(bc.urlPrefix)
base, err := url.Parse(bc.URLPrefix)
if err != nil {
return "", err
}
@ -111,10 +111,10 @@ func (bc *ApiBootConfiguration) makeURLAbsolute(urlStr string) (string, error) {
return u.String(), nil
}
func (bc *ApiBootConfiguration) GetPreference() []byte {
func (bc *APIBootConfiguration) GetPreference() []byte {
return bc.Preference
}
func (bc *ApiBootConfiguration) GetRecursiveDns() []net.IP {
return bc.RecursiveDns
func (bc *APIBootConfiguration) GetRecursiveDNS() []net.IP {
return bc.RecursiveDNS
}

View File

@ -8,55 +8,55 @@ import (
)
const (
OptClientId uint16 = 1 // IPMask
OptServerId = 2 // int32
OptIaNa = 3 // IPs
OptIaTa = 4 // IPs
OptIaAddr = 5 // string
OptOro = 6 // uint16
OptPreference = 7 // string
OptElapsedTime = 8 // IP
OptRelayMessage = 9 // IP
OptAuth = 11 // []byte
OptUnicast = 12 // IP
OptStatusCode = 13 // uint32
OptRapidCommit = 14 // byte
OptUserClass = 15 // IP
OptVendorClass = 16 // []byte
OptVendorOpts = 17 // string
OptInterfaceId = 18 // uint16
OptReconfMsg = 19 // uint32
OptReconfAccept = 20 // uint32
OptRecursiveDns = 23 // []byte
OptBootfileUrl = 59
OptBootfileParam = 60 //[][]byte
OptClientArchType = 61 //[][]byte, sent by the client
OptClientID uint16 = 1 // IPMask
OptServerID = 2 // int32
OptIaNa = 3 // IPs
OptIaTa = 4 // IPs
OptIaAddr = 5 // string
OptOro = 6 // uint16
OptPreference = 7 // string
OptElapsedTime = 8 // IP
OptRelayMessage = 9 // IP
OptAuth = 11 // []byte
OptUnicast = 12 // IP
OptStatusCode = 13 // uint32
OptRapidCommit = 14 // byte
OptUserClass = 15 // IP
OptVendorClass = 16 // []byte
OptVendorOpts = 17 // string
OptInterfaceID = 18 // uint16
OptReconfMsg = 19 // uint32
OptReconfAccept = 20 // uint32
OptRecursiveDNS = 23 // []byte
OptBootfileURL = 59
OptBootfileParam = 60 //[][]byte
OptClientArchType = 61 //[][]byte, sent by the Client
// 24? Domain search list
)
type Option struct {
Id uint16
ID uint16
Length uint16
Value []byte
Value []byte
}
func MakeOption(id uint16, value []byte) *Option {
return &Option{ Id: id, Length: uint16(len(value)), Value: value}
return &Option{ ID: id, Length: uint16(len(value)), Value: value}
}
type Options map[uint16][]*Option
func MakeOptions(bs []byte) (Options, error) {
to_ret := make(Options)
ret := make(Options)
for len(bs) > 0 {
o, err := UnmarshalOption(bs)
if err != nil {
return nil, err
}
to_ret[o.Id] = append(to_ret[o.Id], &Option{ Id: o.Id, Length: o.Length, Value: bs[4 : 4+o.Length]})
ret[o.ID] = append(ret[o.ID], &Option{ ID: o.ID, Length: o.Length, Value: bs[4 : 4+o.Length]})
bs = bs[4+o.Length:]
}
return to_ret, nil
return ret, nil
}
func UnmarshalOption(bs []byte) (*Option, error) {
@ -76,18 +76,18 @@ func UnmarshalOption(bs []byte) (*Option, error) {
return nil, fmt.Errorf("option %d claims to have %d bytes of payload, but only has %d bytes", optionId, optionLength, len(bs[4:]))
}
}
return &Option{ Id: optionId, Length: optionLength, Value: bs[4 : 4+optionLength]}, nil
return &Option{ ID: optionId, Length: optionLength, Value: bs[4 : 4+optionLength]}, nil
}
func (o Options) HumanReadable() []string {
to_ret := make([]string, 0, len(o))
for _, multipleOptions := range(o) {
for _, option := range(multipleOptions) {
switch option.Id {
switch option.ID {
case 3:
to_ret = append(to_ret, o.HumanReadableIaNa(*option)...)
default:
to_ret = append(to_ret, fmt.Sprintf("Option: %d | %d | %d | %s\n", option.Id, option.Length, option.Value, option.Value))
to_ret = append(to_ret, fmt.Sprintf("Option: %d | %d | %d | %s\n", option.ID, option.Length, option.Value, option.Value))
}
}
}
@ -127,10 +127,10 @@ func (o Options) HumanReadableIaNa(opt Option) []string {
}
func (o Options) AddOption(option *Option) {
_, present := o[option.Id]; if !present {
o[option.Id] = make([]*Option, 0)
_, present := o[option.ID]; if !present {
o[option.ID] = make([]*Option, 0)
}
o[option.Id] = append(o[option.Id], option)
o[option.ID] = append(o[option.ID], option)
}
func MakeIaNaOption(iaid []byte, t1, t2 uint32, iaOption *Option) *Option {
@ -163,7 +163,7 @@ func MakeDNSServersOption(addresses []net.IP) *Option {
for i, dnsAddress := range addresses {
copy(value[i*16:], dnsAddress)
}
return MakeOption(OptRecursiveDns, value)
return MakeOption(OptRecursiveDNS, value)
}
func (o Options) Marshal() ([]byte, error) {
@ -185,7 +185,7 @@ func (o Options) Marshal() ([]byte, error) {
func (o *Option) Marshal() ([]byte, error) {
buffer := bytes.NewBuffer(make([]byte, 0, o.Length + 2))
err := binary.Write(buffer, binary.BigEndian, o.Id)
err := binary.Write(buffer, binary.BigEndian, o.ID)
if err != nil {
return nil, fmt.Errorf("Error serializing option id: %s", err)
}
@ -201,32 +201,32 @@ func (o *Option) Marshal() ([]byte, error) {
}
func (o Options) UnmarshalOptionRequestOption() map[uint16]bool {
to_ret := make(map[uint16]bool)
ret := make(map[uint16]bool)
_, present := o[OptOro]; if !present {
return to_ret
return ret
}
oro_content := o[OptOro][0].Value
value := o[OptOro][0].Value
for i := 0; i < int(o[OptOro][0].Length)/2; i++ {
to_ret[uint16(binary.BigEndian.Uint16(oro_content[i*2:(i+1)*2]))] = true
ret[uint16(binary.BigEndian.Uint16(value[i*2:(i+1)*2]))] = true
}
return to_ret
return ret
}
func (o Options) HasBootFileUrlOption() bool {
requested_options := o.UnmarshalOptionRequestOption()
_, present := requested_options[OptBootfileUrl]
func (o Options) HasBootFileURLOption() bool {
requestedOptions := o.UnmarshalOptionRequestOption()
_, present := requestedOptions[OptBootfileURL]
return present
}
func (o Options) HasClientId() bool {
_, present := o[OptClientId]
func (o Options) HasClientID() bool {
_, present := o[OptClientID]
return present
}
func (o Options) HasServerId() bool {
_, present := o[OptServerId]
func (o Options) HasServerID() bool {
_, present := o[OptServerID]
return present
}
@ -245,23 +245,23 @@ func (o Options) HasClientArchType() bool {
return present
}
func (o Options) ClientId() []byte {
opt, exists := o[OptClientId]
func (o Options) ClientID() []byte {
opt, exists := o[OptClientID]
if exists {
return opt[0].Value
}
return nil
}
func (o Options) ServerId() []byte {
opt, exists := o[OptServerId]
func (o Options) ServerID() []byte {
opt, exists := o[OptServerID]
if exists {
return opt[0].Value
}
return nil
}
func (o Options) IaNaIds() [][]byte {
func (o Options) IaNaIDs() [][]byte {
options, exists := o[OptIaNa]
ret := make([][]byte, 0)
if exists {
@ -281,8 +281,8 @@ func (o Options) ClientArchType() uint16 {
return 0
}
func (o Options) BootfileUrl() []byte {
opt, exists := o[OptBootfileUrl]
func (o Options) BootFileURL() []byte {
opt, exists := o[OptBootfileURL]
if exists {
return opt[0].Value
}

View File

@ -7,39 +7,39 @@ import (
)
func TestMarshalOption(t *testing.T) {
expectedUrl := []byte("http://blah")
expectedLength := uint16(len(expectedUrl))
opt := &Option{Id: OptBootfileUrl, Length: expectedLength, Value: expectedUrl}
expectedURL := []byte("http://blah")
expectedLength := uint16(len(expectedURL))
opt := &Option{ID: OptBootfileURL, Length: expectedLength, Value: expectedURL}
marshalled, err := opt.Marshal()
if err != nil {
t.Fatalf("Unexpected marshalling failure.")
}
if id := uint16(binary.BigEndian.Uint16(marshalled[0:2])); id != OptBootfileUrl {
t.Fatalf("Expected optionId %d, got: %d", OptBootfileUrl, id)
if id := uint16(binary.BigEndian.Uint16(marshalled[0:2])); id != OptBootfileURL {
t.Fatalf("Expected optionId %d, got: %d", OptBootfileURL, id)
}
if l := uint16(binary.BigEndian.Uint16(marshalled[2:4])); l != expectedLength {
t.Fatalf("Expected length of %d, got: %d", expectedLength, l)
}
if url := marshalled[4:]; string(url) != string(expectedUrl) {
t.Fatalf("Expected %s, got %s", expectedUrl, url)
if url := marshalled[4:]; string(url) != string(expectedURL) {
t.Fatalf("Expected %s, got %s", expectedURL, url)
}
}
func TestMakeIaAddrOption(t *testing.T) {
expectedIp := net.ParseIP("2001:db8:f00f:cafe::99")
expectedIP := net.ParseIP("2001:db8:f00f:cafe::99")
var expectedPreferredLifetime, expectedValidLifetime uint32 = 27000, 43200
iaAddrOption := MakeIaAddrOption(expectedIp, expectedPreferredLifetime, expectedValidLifetime)
iaAddrOption := MakeIaAddrOption(expectedIP, expectedPreferredLifetime, expectedValidLifetime)
if iaAddrOption.Id != OptIaAddr {
t.Fatalf("Expected option id %d, got %d", OptIaAddr, iaAddrOption.Id)
if iaAddrOption.ID != OptIaAddr {
t.Fatalf("Expected option id %d, got %d", OptIaAddr, iaAddrOption.ID)
}
if iaAddrOption.Length != 24 {
t.Fatalf("Expected length 24 bytes, got %d", iaAddrOption.Length)
}
if string(iaAddrOption.Value[0:16]) != string(expectedIp) {
t.Fatalf("Expected address %v, got %v", expectedIp, iaAddrOption.Value[0:16])
if string(iaAddrOption.Value[0:16]) != string(expectedIP) {
t.Fatalf("Expected address %v, got %v", expectedIP, iaAddrOption.Value[0:16])
}
if preferredLifetime := uint32(binary.BigEndian.Uint32(iaAddrOption.Value[16:20])); preferredLifetime != expectedPreferredLifetime {
t.Fatalf("Expected preferred lifetime of %d, got %d", expectedPreferredLifetime, preferredLifetime)
@ -55,16 +55,16 @@ func TestMakeIaNaOption(t *testing.T) {
if err != nil {
t.Fatalf("Unexpected serialization error: %s", err)
}
expectedId := []byte("1234")
expectedID := []byte("1234")
var expectedT1, expectedT2 uint32 = 100, 200
iaNaOption := MakeIaNaOption(expectedId, expectedT1, expectedT2, iaAddrOption)
iaNaOption := MakeIaNaOption(expectedID, expectedT1, expectedT2, iaAddrOption)
if iaNaOption.Id != OptIaNa {
t.Fatalf("Expected optionId %d, got %d", OptIaNa, iaNaOption.Id)
if iaNaOption.ID != OptIaNa {
t.Fatalf("Expected optionId %d, got %d", OptIaNa, iaNaOption.ID)
}
if string(iaNaOption.Value[0:4]) != string(expectedId) {
t.Fatalf("Expected id %s, got %s", expectedId, string(iaNaOption.Value[0:4]))
if string(iaNaOption.Value[0:4]) != string(expectedID) {
t.Fatalf("Expected id %s, got %s", expectedID, string(iaNaOption.Value[0:4]))
}
if t1 := uint32(binary.BigEndian.Uint32(iaNaOption.Value[4:])); t1 != expectedT1 {
t.Fatalf("Expected t1 of %d, got %d", expectedT1, t1)
@ -82,8 +82,8 @@ func TestMakeStatusOption(t *testing.T) {
expectedStatusCode := uint16(2)
noAddrOption := MakeStatusOption(expectedStatusCode, expectedMessage)
if noAddrOption.Id != OptStatusCode {
t.Fatalf("Expected option id %d, got %d", OptStatusCode, noAddrOption.Id)
if noAddrOption.ID != OptStatusCode {
t.Fatalf("Expected option id %d, got %d", OptStatusCode, noAddrOption.ID)
}
if noAddrOption.Length != uint16(2 + len(expectedMessage)) {
t.Fatalf("Expected option length of %d, got %d", 2 + len(expectedMessage), noAddrOption.Length)
@ -108,8 +108,8 @@ func TestMakeDNSServersOption(t *testing.T) {
expectedAddress2 := net.ParseIP("2001:db8:f00f:cafe::9A")
dnsServersOption := MakeDNSServersOption([]net.IP{expectedAddress1, expectedAddress2})
if dnsServersOption.Id != OptRecursiveDns {
t.Fatalf("Expected option id %d, got %d", OptRecursiveDns, dnsServersOption.Id)
if dnsServersOption.ID != OptRecursiveDNS {
t.Fatalf("Expected option id %d, got %d", OptRecursiveDNS, dnsServersOption.ID)
}
if dnsServersOption.Length != 32 {
t.Fatalf("Expected length 32 bytes, got %d", dnsServersOption.Length)

View File

@ -40,15 +40,15 @@ func MakePacket(bs []byte, packetLength int) (*Packet, error) {
}
func (p *Packet) Marshal() ([]byte, error) {
marshalled_options, err := p.Options.Marshal()
marshalledOptions, err := p.Options.Marshal()
if err != nil {
return nil, fmt.Errorf("packet has malformed options section: %s", err)
}
ret := make([]byte, len(marshalled_options) + 4, len(marshalled_options) + 4)
ret := make([]byte, len(marshalledOptions) + 4, len(marshalledOptions) + 4)
ret[0] = byte(p.Type)
copy(ret[1:], p.TransactionID[:])
copy(ret[4:], marshalled_options)
copy(ret[4:], marshalledOptions)
return ret, nil
}
@ -70,13 +70,13 @@ func (p *Packet) ShouldDiscard(serverDuid []byte) error {
func ShouldDiscardSolicit(p *Packet) error {
options := p.Options
if !options.HasBootFileUrlOption() {
if !options.HasBootFileURLOption() {
return fmt.Errorf("'Solicit' packet doesn't have file url option")
}
if !options.HasClientId() {
return fmt.Errorf("'Solicit' packet has no client id option")
if !options.HasClientID() {
return fmt.Errorf("'Solicit' packet has no Client id option")
}
if options.HasServerId() {
if options.HasServerID() {
return fmt.Errorf("'Solicit' packet has server id option")
}
return nil
@ -84,31 +84,31 @@ func ShouldDiscardSolicit(p *Packet) error {
func ShouldDiscardRequest(p *Packet, serverDuid []byte) error {
options := p.Options
if !options.HasBootFileUrlOption() {
if !options.HasBootFileURLOption() {
return fmt.Errorf("'Request' packet doesn't have file url option")
}
if !options.HasClientId() {
return fmt.Errorf("'Request' packet has no client id option")
if !options.HasClientID() {
return fmt.Errorf("'Request' packet has no Client id option")
}
if !options.HasServerId() {
if !options.HasServerID() {
return fmt.Errorf("'Request' packet has no server id option")
}
if bytes.Compare(options.ServerId(), serverDuid) != 0 {
return fmt.Errorf("'Request' packet's server id option (%d) is different from ours (%d)", options.ServerId(), serverDuid)
if bytes.Compare(options.ServerID(), serverDuid) != 0 {
return fmt.Errorf("'Request' packet's server id option (%d) is different from ours (%d)", options.ServerID(), serverDuid)
}
return nil
}
func ShouldDiscardInformationRequest(p *Packet, serverDuid []byte) error {
options := p.Options
if !options.HasBootFileUrlOption() {
if !options.HasBootFileURLOption() {
return fmt.Errorf("'Information-request' packet doesn't have boot file url option")
}
if options.HasIaNa() || options.HasIaTa() {
return fmt.Errorf("'Information-request' packet has an IA option present")
}
if options.HasServerId() && (bytes.Compare(options.ServerId(), serverDuid) != 0) {
return fmt.Errorf("'Information-request' packet's server id option (%d) is different from ours (%d)", options.ServerId(), serverDuid)
if options.HasServerID() && (bytes.Compare(options.ServerID(), serverDuid) != 0) {
return fmt.Errorf("'Information-request' packet's server id option (%d) is different from ours (%d)", options.ServerID(), serverDuid)
}
return nil
}

View File

@ -15,116 +15,117 @@ func MakePacketBuilder(preferredLifetime, validLifetime uint32) *PacketBuilder {
return &PacketBuilder{PreferredLifetime: preferredLifetime, ValidLifetime: validLifetime}
}
func (b *PacketBuilder) BuildResponse(in *Packet, serverDuid []byte, configuration BootConfiguration, addresses AddressPool) (*Packet, error) {
func (b *PacketBuilder) BuildResponse(in *Packet, serverDUID []byte, configuration BootConfiguration, addresses AddressPool) (*Packet, error) {
switch in.Type {
case MsgSolicit:
bootFileUrl, err := configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType())
bootFileURL, err := configuration.GetBootURL(b.ExtractLLAddressOrID(in.Options.ClientID()), in.Options.ClientArchType())
if err != nil {
return nil, err
}
associations, err := addresses.ReserveAddresses(in.Options.ClientId(), in.Options.IaNaIds())
associations, err := addresses.ReserveAddresses(in.Options.ClientID(), in.Options.IaNaIDs())
if err != nil {
return b.MakeMsgAdvertiseWithNoAddrsAvailable(in.TransactionID, serverDuid, in.Options.ClientId(), err), err
return b.MakeMsgAdvertiseWithNoAddrsAvailable(in.TransactionID, serverDUID, in.Options.ClientID(), err), err
}
return b.MakeMsgAdvertise(in.TransactionID, serverDuid, in.Options.ClientId(),
in.Options.ClientArchType(), associations, bootFileUrl, configuration.GetPreference(), configuration.GetRecursiveDns()), nil
return b.MakeMsgAdvertise(in.TransactionID, serverDUID, in.Options.ClientID(),
in.Options.ClientArchType(), associations, bootFileURL, configuration.GetPreference(), configuration.GetRecursiveDNS()), nil
case MsgRequest:
bootFileUrl, err := configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType())
bootFileURL, err := configuration.GetBootURL(b.ExtractLLAddressOrID(in.Options.ClientID()), in.Options.ClientArchType())
if err != nil {
return nil, err
}
associations, err := addresses.ReserveAddresses(in.Options.ClientId(), in.Options.IaNaIds())
return b.MakeMsgReply(in.TransactionID, serverDuid, in.Options.ClientId(),
in.Options.ClientArchType(), associations, iasWithoutAddesses(associations, in.Options.IaNaIds()), bootFileUrl,
configuration.GetRecursiveDns(), err), err
associations, err := addresses.ReserveAddresses(in.Options.ClientID(), in.Options.IaNaIDs())
return b.MakeMsgReply(in.TransactionID, serverDUID, in.Options.ClientID(),
in.Options.ClientArchType(), associations, iasWithoutAddesses(associations, in.Options.IaNaIDs()), bootFileURL,
configuration.GetRecursiveDNS(), err), err
case MsgInformationRequest:
bootFileUrl, err := configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType())
bootFileURL, err := configuration.GetBootURL(b.ExtractLLAddressOrID(in.Options.ClientID()), in.Options.ClientArchType())
if err != nil {
return nil, err
}
return b.MakeMsgInformationRequestReply(in.TransactionID, serverDuid, in.Options.ClientId(),
in.Options.ClientArchType(), bootFileUrl, configuration.GetRecursiveDns()), nil
return b.MakeMsgInformationRequestReply(in.TransactionID, serverDUID, in.Options.ClientID(),
in.Options.ClientArchType(), bootFileURL, configuration.GetRecursiveDNS()), nil
case MsgRelease:
addresses.ReleaseAddresses(in.Options.ClientId(), in.Options.IaNaIds())
return b.MakeMsgReleaseReply(in.TransactionID, serverDuid, in.Options.ClientId()), nil
addresses.ReleaseAddresses(in.Options.ClientID(), in.Options.IaNaIDs())
return b.MakeMsgReleaseReply(in.TransactionID, serverDUID, in.Options.ClientID()), nil
default:
return nil, nil
}
}
func (b *PacketBuilder) MakeMsgAdvertise(transactionId [3]byte, serverDuid, clientId []byte, clientArchType uint16,
associations []*IdentityAssociation, bootFileUrl, preference []byte, dnsServers []net.IP) *Packet {
ret_options := make(Options)
ret_options.AddOption(MakeOption(OptClientId, clientId))
func (b *PacketBuilder) MakeMsgAdvertise(transactionID [3]byte, serverDUID, clientID []byte, clientArchType uint16,
associations []*IdentityAssociation, bootFileURL, preference []byte, dnsServers []net.IP) *Packet {
retOptions := make(Options)
retOptions.AddOption(MakeOption(OptClientID, clientID))
for _, association := range(associations) {
ret_options.AddOption(MakeIaNaOption(association.InterfaceId, b.calculateT1(), b.calculateT2(),
MakeIaAddrOption(association.IpAddress, b.PreferredLifetime, b.ValidLifetime)))
retOptions.AddOption(MakeIaNaOption(association.InterfaceID, b.calculateT1(), b.calculateT2(),
MakeIaAddrOption(association.IPAddress, b.PreferredLifetime, b.ValidLifetime)))
}
ret_options.AddOption(MakeOption(OptServerId, serverDuid))
retOptions.AddOption(MakeOption(OptServerID, serverDUID))
if 0x10 == clientArchType { // HTTPClient
ret_options.AddOption(MakeOption(OptVendorClass, []byte {0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient
retOptions.AddOption(MakeOption(OptVendorClass, []byte {0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient
}
ret_options.AddOption(MakeOption(OptBootfileUrl, bootFileUrl))
if preference != nil {ret_options.AddOption(MakeOption(OptPreference, preference))}
if len(dnsServers) > 0 { ret_options.AddOption(MakeDNSServersOption(dnsServers)) }
retOptions.AddOption(MakeOption(OptBootfileURL, bootFileURL))
if preference != nil {
retOptions.AddOption(MakeOption(OptPreference, preference))}
if len(dnsServers) > 0 { retOptions.AddOption(MakeDNSServersOption(dnsServers)) }
return &Packet{Type: MsgAdvertise, TransactionID: transactionId, Options: ret_options}
return &Packet{Type: MsgAdvertise, TransactionID: transactionID, Options: retOptions}
}
func (b *PacketBuilder) MakeMsgReply(transactionId [3]byte, serverDuid, clientId []byte, clientArchType uint16,
associations []*IdentityAssociation, iasWithoutAddresses [][]byte, bootFileUrl []byte, dnsServers []net.IP, err error) *Packet {
ret_options := make(Options)
ret_options.AddOption(MakeOption(OptClientId, clientId))
func (b *PacketBuilder) MakeMsgReply(transactionID [3]byte, serverDUID, clientID []byte, clientArchType uint16,
associations []*IdentityAssociation, iasWithoutAddresses [][]byte, bootFileURL []byte, dnsServers []net.IP, err error) *Packet {
retOptions := make(Options)
retOptions.AddOption(MakeOption(OptClientID, clientID))
for _, association := range(associations) {
ret_options.AddOption(MakeIaNaOption(association.InterfaceId, b.calculateT1(), b.calculateT2(),
MakeIaAddrOption(association.IpAddress, b.PreferredLifetime, b.ValidLifetime)))
retOptions.AddOption(MakeIaNaOption(association.InterfaceID, b.calculateT1(), b.calculateT2(),
MakeIaAddrOption(association.IPAddress, b.PreferredLifetime, b.ValidLifetime)))
}
for _, ia := range(iasWithoutAddresses) {
ret_options.AddOption(MakeIaNaOption(ia, b.calculateT1(), b.calculateT2(),
retOptions.AddOption(MakeIaNaOption(ia, b.calculateT1(), b.calculateT2(),
MakeStatusOption(2, err.Error())))
}
ret_options.AddOption(MakeOption(OptServerId, serverDuid))
retOptions.AddOption(MakeOption(OptServerID, serverDUID))
if 0x10 == clientArchType { // HTTPClient
ret_options.AddOption(MakeOption(OptVendorClass, []byte {0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient
retOptions.AddOption(MakeOption(OptVendorClass, []byte {0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient
}
ret_options.AddOption(MakeOption(OptBootfileUrl, bootFileUrl))
if len(dnsServers) > 0 { ret_options.AddOption(MakeDNSServersOption(dnsServers)) }
retOptions.AddOption(MakeOption(OptBootfileURL, bootFileURL))
if len(dnsServers) > 0 { retOptions.AddOption(MakeDNSServersOption(dnsServers)) }
return &Packet{Type: MsgReply, TransactionID: transactionId, Options: ret_options}
return &Packet{Type: MsgReply, TransactionID: transactionID, Options: retOptions}
}
func (b *PacketBuilder) MakeMsgInformationRequestReply(transactionId [3]byte, serverDuid, clientId []byte, clientArchType uint16,
bootFileUrl []byte, dnsServers []net.IP) *Packet {
ret_options := make(Options)
ret_options.AddOption(MakeOption(OptClientId, clientId))
ret_options.AddOption(MakeOption(OptServerId, serverDuid))
func (b *PacketBuilder) MakeMsgInformationRequestReply(transactionID [3]byte, serverDUID, clientID []byte, clientArchType uint16,
bootFileURL []byte, dnsServers []net.IP) *Packet {
retOptions := make(Options)
retOptions.AddOption(MakeOption(OptClientID, clientID))
retOptions.AddOption(MakeOption(OptServerID, serverDUID))
if 0x10 == clientArchType { // HTTPClient
ret_options.AddOption(MakeOption(OptVendorClass, []byte {0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient
retOptions.AddOption(MakeOption(OptVendorClass, []byte {0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient
}
ret_options.AddOption(MakeOption(OptBootfileUrl, bootFileUrl))
if len(dnsServers) > 0 { ret_options.AddOption(MakeDNSServersOption(dnsServers)) }
retOptions.AddOption(MakeOption(OptBootfileURL, bootFileURL))
if len(dnsServers) > 0 { retOptions.AddOption(MakeDNSServersOption(dnsServers)) }
return &Packet{Type: MsgReply, TransactionID: transactionId, Options: ret_options}
return &Packet{Type: MsgReply, TransactionID: transactionID, Options: retOptions}
}
func (b *PacketBuilder) MakeMsgReleaseReply(transactionId [3]byte, serverDuid, clientId []byte) *Packet {
ret_options := make(Options)
func (b *PacketBuilder) MakeMsgReleaseReply(transactionID [3]byte, serverDUID, clientID []byte) *Packet {
retOptions := make(Options)
ret_options.AddOption(MakeOption(OptClientId, clientId))
ret_options.AddOption(MakeOption(OptServerId, serverDuid))
retOptions.AddOption(MakeOption(OptClientID, clientID))
retOptions.AddOption(MakeOption(OptServerID, serverDUID))
v := make([]byte, 19, 19)
copy(v[2:], []byte("Release received."))
ret_options.AddOption(MakeOption(OptStatusCode, v))
retOptions.AddOption(MakeOption(OptStatusCode, v))
return &Packet{Type: MsgReply, TransactionID: transactionId, Options: ret_options}
return &Packet{Type: MsgReply, TransactionID: transactionID, Options: retOptions}
}
func (b *PacketBuilder) MakeMsgAdvertiseWithNoAddrsAvailable(transactionId [3]byte, serverDuid, clientId []byte, err error) *Packet {
ret_options := make(Options)
ret_options.AddOption(MakeOption(OptClientId, clientId))
ret_options.AddOption(MakeOption(OptServerId, serverDuid))
ret_options.AddOption(MakeStatusOption(2, err.Error())) // NoAddrAvailable
return &Packet{Type: MsgAdvertise, TransactionID: transactionId, Options: ret_options}
func (b *PacketBuilder) MakeMsgAdvertiseWithNoAddrsAvailable(transactionID [3]byte, serverDUID, clientID []byte, err error) *Packet {
retOptions := make(Options)
retOptions.AddOption(MakeOption(OptClientID, clientID))
retOptions.AddOption(MakeOption(OptServerID, serverDUID))
retOptions.AddOption(MakeStatusOption(2, err.Error())) // NoAddrAvailable
return &Packet{Type: MsgAdvertise, TransactionID: transactionID, Options: retOptions}
}
func (b *PacketBuilder) calculateT1() uint32 {
@ -135,36 +136,36 @@ func (b *PacketBuilder) calculateT2() uint32 {
return (b.PreferredLifetime * 4)/5
}
func (b *PacketBuilder) ExtractLLAddressOrId(optClientId []byte) []byte {
idType := binary.BigEndian.Uint16(optClientId[0:2])
func (b *PacketBuilder) ExtractLLAddressOrID(optClientID []byte) []byte {
idType := binary.BigEndian.Uint16(optClientID[0:2])
switch idType {
case 1:
return optClientId[8:]
return optClientID[8:]
case 3:
return optClientId[4:]
return optClientID[4:]
default:
return optClientId[2:]
return optClientID[2:]
}
}
func iasWithoutAddesses(availableAssociations []*IdentityAssociation, allIas [][]byte) [][]byte {
func iasWithoutAddesses(availableAssociations []*IdentityAssociation, allIAs [][]byte) [][]byte {
ret := make([][]byte, 0)
iasWithAddresses := make(map[uint64]bool)
for _, association := range(availableAssociations) {
iasWithAddresses[calculateIaIdHash(association.InterfaceId)] = true
iasWithAddresses[calculateIAIDHash(association.InterfaceID)] = true
}
for _, ia := range(allIas) {
_, exists := iasWithAddresses[calculateIaIdHash(ia)]; if !exists {
for _, ia := range(allIAs) {
_, exists := iasWithAddresses[calculateIAIDHash(ia)]; if !exists {
ret = append(ret, ia)
}
}
return ret
}
func calculateIaIdHash(interfaceId []byte) uint64 {
func calculateIAIDHash(interfaceID []byte) uint64 {
h := fnv.New64a()
h.Write(interfaceId)
h.Write(interfaceID)
return h.Sum64()
}

View File

@ -8,52 +8,52 @@ import (
)
func TestMakeMsgAdvertise(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
expectedInterfaceId := []byte("id-1")
transactionId := [3]byte{'1', '2', '3'}
expectedIp := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileUrl := []byte("http://bootfileurl")
expectedDnsServerIp := net.ParseIP("2001:db8:f00f:cafe::99")
identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: expectedInterfaceId}
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
expectedInterfaceID := []byte("id-1")
transactionID := [3]byte{'1', '2', '3'}
expectedIP := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileURL := []byte("http://bootfileurl")
expectedDnsServerIP := net.ParseIP("2001:db8:f00f:cafe::99")
identityAssociation := &IdentityAssociation{IPAddress: expectedIP, InterfaceID: expectedInterfaceID}
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgAdvertise(transactionId, expectedServerId, expectedClientId, 0x11,
[]*IdentityAssociation{identityAssociation}, expectedBootFileUrl, nil, []net.IP{expectedDnsServerIp})
msg := builder.MakeMsgAdvertise(transactionID, expectedServerID, expectedClientID, 0x11,
[]*IdentityAssociation{identityAssociation}, expectedBootFileURL, nil, []net.IP{expectedDnsServerIP})
if msg.Type != MsgAdvertise {
t.Fatalf("Expected message type %d, got %d", MsgAdvertise, msg.Type)
}
if transactionId != msg.TransactionID {
t.Fatalf("Expected transaction Id %v, got %v", transactionId, msg.TransactionID)
if transactionID != msg.TransactionID {
t.Fatalf("Expected transaction ID %v, got %v", transactionID, msg.TransactionID)
}
clientIdOption := msg.Options.ClientId()
if clientIdOption == nil {
t.Fatalf("Client Id option should be present")
clientIDOption := msg.Options.ClientID()
if clientIDOption == nil {
t.Fatalf("Client ID option should be present")
}
if string(expectedClientId) != string(clientIdOption) {
t.Fatalf("Expected client id %v, got %v", expectedClientId, clientIdOption)
if string(expectedClientID) != string(clientIDOption) {
t.Fatalf("Expected Client id %v, got %v", expectedClientID, clientIDOption)
}
serverIdOption := msg.Options.ServerId()
if serverIdOption == nil {
t.Fatalf("Server Id option should be present")
serverIDOption := msg.Options.ServerID()
if serverIDOption == nil {
t.Fatalf("Server ID option should be present")
}
if string(expectedServerId) != string(serverIdOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientId, serverIdOption)
if string(expectedServerID) != string(serverIDOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientID, serverIDOption)
}
bootfileUrlOption := msg.Options[OptBootfileUrl][0]
if bootfileUrlOption == nil {
bootfileURLOption := msg.Options[OptBootfileURL][0]
if bootfileURLOption == nil {
t.Fatalf("Bootfile URL option should be present")
}
if string(expectedBootFileUrl) != string(bootfileUrlOption.Value) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileUrl, bootfileUrlOption)
if string(expectedBootFileURL) != string(bootfileURLOption.Value) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileURL, bootfileURLOption)
}
iaNaOption := msg.Options.IaNaIds()
iaNaOption := msg.Options.IaNaIDs()
if len(iaNaOption) == 0 {
t.Fatalf("interface non-temporary association option should be present")
}
@ -63,36 +63,36 @@ func TestMakeMsgAdvertise(t *testing.T) {
t.Fatalf("Preference option shouldn't be set")
}
dnsServersOption := msg.Options[OptRecursiveDns]
dnsServersOption := msg.Options[OptRecursiveDNS]
if dnsServersOption == nil {
t.Fatalf("DNS servers option should be set")
}
if string(dnsServersOption[0].Value) != string(expectedDnsServerIp) {
t.Fatalf("Expected dns server %v, got %v", expectedDnsServerIp, net.IP(dnsServersOption[0].Value))
if string(dnsServersOption[0].Value) != string(expectedDnsServerIP) {
t.Fatalf("Expected dns server %v, got %v", expectedDnsServerIP, net.IP(dnsServersOption[0].Value))
}
}
func TestMakeMsgAdvertiseShouldSkipDnsServersIfNoneConfigured(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
expectedInterfaceId := []byte("id-1")
transactionId := [3]byte{'1', '2', '3'}
expectedIp := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileUrl := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: expectedInterfaceId}
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
expectedInterfaceID := []byte("id-1")
transactionID := [3]byte{'1', '2', '3'}
expectedIP := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileURL := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IPAddress: expectedIP, InterfaceID: expectedInterfaceID}
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgAdvertise(transactionId, expectedServerId, expectedClientId, 0x11,
[]*IdentityAssociation{identityAssociation}, expectedBootFileUrl, nil, []net.IP{})
msg := builder.MakeMsgAdvertise(transactionID, expectedServerID, expectedClientID, 0x11,
[]*IdentityAssociation{identityAssociation}, expectedBootFileURL, nil, []net.IP{})
_, exists := msg.Options[OptRecursiveDns]; if exists {
_, exists := msg.Options[OptRecursiveDNS]; if exists {
t.Fatalf("DNS servers option should not be set")
}
}
func TestShouldSetPreferenceOptionWhenSpecified(t *testing.T) {
identityAssociation := &IdentityAssociation{IpAddress: net.ParseIP("2001:db8:f00f:cafe::1"), InterfaceId: []byte("id-1")}
identityAssociation := &IdentityAssociation{IPAddress: net.ParseIP("2001:db8:f00f:cafe::1"), InterfaceID: []byte("id-1")}
builder := MakePacketBuilder(90, 100)
@ -110,62 +110,62 @@ func TestShouldSetPreferenceOptionWhenSpecified(t *testing.T) {
}
func TestMakeMsgAdvertiseWithHttpClientArch(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedIp := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileUrl := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: []byte("id-1")}
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
expectedIP := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileURL := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IPAddress: expectedIP, InterfaceID: []byte("id-1")}
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgAdvertise(transactionId, expectedServerId, expectedClientId, 0x10,
[]*IdentityAssociation{identityAssociation}, expectedBootFileUrl, nil, []net.IP{})
msg := builder.MakeMsgAdvertise(transactionID, expectedServerID, expectedClientID, 0x10,
[]*IdentityAssociation{identityAssociation}, expectedBootFileURL, nil, []net.IP{})
vendorClassOption := msg.Options[OptVendorClass]
if vendorClassOption == nil {
t.Fatalf("Vendor class option should be present")
}
bootfileUrlOption := msg.Options.BootfileUrl()
if bootfileUrlOption == nil {
bootfileURLOption := msg.Options.BootFileURL()
if bootfileURLOption == nil {
t.Fatalf("Bootfile URL option should be present")
}
if string(expectedBootFileUrl) != string(bootfileUrlOption) {
t.Fatalf("Expected bootfile URL %s, got %s", expectedBootFileUrl, bootfileUrlOption)
if string(expectedBootFileURL) != string(bootfileURLOption) {
t.Fatalf("Expected bootfile URL %s, got %s", expectedBootFileURL, bootfileURLOption)
}
}
func TestMakeNoAddrsAvailable(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
expectedMessage := "Boom!"
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgAdvertiseWithNoAddrsAvailable(transactionId, expectedServerId, expectedClientId, fmt.Errorf(expectedMessage))
msg := builder.MakeMsgAdvertiseWithNoAddrsAvailable(transactionID, expectedServerID, expectedClientID, fmt.Errorf(expectedMessage))
if msg.Type != MsgAdvertise {
t.Fatalf("Expected message type %d, got %d", MsgAdvertise, msg.Type)
}
if transactionId != msg.TransactionID {
t.Fatalf("Expected transaction Id %v, got %v", transactionId, msg.TransactionID)
if transactionID != msg.TransactionID {
t.Fatalf("Expected transaction ID %v, got %v", transactionID, msg.TransactionID)
}
clientIdOption := msg.Options.ClientId()
if clientIdOption == nil {
t.Fatalf("Client Id option should be present")
clientIDOption := msg.Options.ClientID()
if clientIDOption == nil {
t.Fatalf("Client ID option should be present")
}
if string(expectedClientId) != string(clientIdOption) {
t.Fatalf("Expected client id %v, got %v", expectedClientId, clientIdOption)
if string(expectedClientID) != string(clientIDOption) {
t.Fatalf("Expected Client id %v, got %v", expectedClientID, clientIDOption)
}
serverIdOption := msg.Options.ServerId()
if serverIdOption == nil {
t.Fatalf("Server Id option should be present")
serverIDOption := msg.Options.ServerID()
if serverIDOption == nil {
t.Fatalf("Server ID option should be present")
}
if string(expectedServerId) != string(serverIdOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientId, serverIdOption)
if string(expectedServerID) != string(serverIDOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientID, serverIDOption)
}
_, exists := msg.Options[OptStatusCode]; if !exists {
@ -181,54 +181,54 @@ func TestMakeNoAddrsAvailable(t *testing.T) {
}
func TestMakeMsgReply(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedIp := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileUrl := []byte("http://bootfileurl")
expectedDnsServerIp := net.ParseIP("2001:db8:f00f:cafe::99")
identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: []byte("id-1")}
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
expectedIP := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileURL := []byte("http://bootfileurl")
expectedDnsServerIP := net.ParseIP("2001:db8:f00f:cafe::99")
identityAssociation := &IdentityAssociation{IPAddress: expectedIP, InterfaceID: []byte("id-1")}
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgReply(transactionId, expectedServerId, expectedClientId, 0x11,
[]*IdentityAssociation{identityAssociation}, make([][]byte, 0), expectedBootFileUrl, []net.IP{expectedDnsServerIp}, nil)
msg := builder.MakeMsgReply(transactionID, expectedServerID, expectedClientID, 0x11,
[]*IdentityAssociation{identityAssociation}, make([][]byte, 0), expectedBootFileURL, []net.IP{expectedDnsServerIP}, nil)
if msg.Type != MsgReply {
t.Fatalf("Expected message type %d, got %d", MsgAdvertise, msg.Type)
}
if transactionId != msg.TransactionID {
t.Fatalf("Expected transaction Id %v, got %v", transactionId, msg.TransactionID)
if transactionID != msg.TransactionID {
t.Fatalf("Expected transaction ID %v, got %v", transactionID, msg.TransactionID)
}
clientIdOption := msg.Options.ClientId()
if clientIdOption == nil {
t.Fatalf("Client Id option should be present")
clientIDOption := msg.Options.ClientID()
if clientIDOption == nil {
t.Fatalf("Client ID option should be present")
}
if string(expectedClientId) != string(clientIdOption) {
t.Fatalf("Expected client id %v, got %v", expectedClientId, clientIdOption)
if string(expectedClientID) != string(clientIDOption) {
t.Fatalf("Expected Client id %v, got %v", expectedClientID, clientIDOption)
}
if len(expectedClientId) != len(clientIdOption) {
t.Fatalf("Expected client id length of %d, got %d", len(expectedClientId), len(clientIdOption))
if len(expectedClientID) != len(clientIDOption) {
t.Fatalf("Expected Client id length of %d, got %d", len(expectedClientID), len(clientIDOption))
}
serverIdOption := msg.Options.ServerId()
if serverIdOption == nil {
t.Fatalf("Server Id option should be present")
serverIDOption := msg.Options.ServerID()
if serverIDOption == nil {
t.Fatalf("Server ID option should be present")
}
if string(expectedServerId) != string(serverIdOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientId, serverIdOption)
if string(expectedServerID) != string(serverIDOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientID, serverIDOption)
}
if len(expectedServerId) != len(serverIdOption) {
t.Fatalf("Expected server id length of %d, got %d", len(expectedClientId), len(serverIdOption))
if len(expectedServerID) != len(serverIDOption) {
t.Fatalf("Expected server id length of %d, got %d", len(expectedClientID), len(serverIDOption))
}
bootfileUrlOption := msg.Options.BootfileUrl()
if bootfileUrlOption == nil {
bootfileURLOption := msg.Options.BootFileURL()
if bootfileURLOption == nil {
t.Fatalf("Bootfile URL option should be present")
}
if string(expectedBootFileUrl) != string(bootfileUrlOption) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileUrl, bootfileUrlOption)
if string(expectedBootFileURL) != string(bootfileURLOption) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileURL, bootfileURLOption)
}
iaNaOption := msg.Options[OptIaNa]
@ -236,73 +236,73 @@ func TestMakeMsgReply(t *testing.T) {
t.Fatalf("interface non-temporary association option should be present")
}
dnsServersOption := msg.Options[OptRecursiveDns]
dnsServersOption := msg.Options[OptRecursiveDNS]
if dnsServersOption == nil {
t.Fatalf("DNS servers option should be set")
}
if string(dnsServersOption[0].Value) != string(expectedDnsServerIp) {
t.Fatalf("Expected dns server %v, got %v", expectedDnsServerIp, net.IP(dnsServersOption[0].Value))
if string(dnsServersOption[0].Value) != string(expectedDnsServerIP) {
t.Fatalf("Expected dns server %v, got %v", expectedDnsServerIP, net.IP(dnsServersOption[0].Value))
}
}
func TestMakeMsgReplyShouldSkipDnsServersIfNoneWereConfigured(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedIp := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileUrl := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: []byte("id-1")}
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
expectedIP := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileURL := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IPAddress: expectedIP, InterfaceID: []byte("id-1")}
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgReply(transactionId, expectedServerId, expectedClientId, 0x11,
[]*IdentityAssociation{identityAssociation}, make([][]byte, 0), expectedBootFileUrl, []net.IP{}, nil)
msg := builder.MakeMsgReply(transactionID, expectedServerID, expectedClientID, 0x11,
[]*IdentityAssociation{identityAssociation}, make([][]byte, 0), expectedBootFileURL, []net.IP{}, nil)
_, exists := msg.Options[OptRecursiveDns]; if exists {
_, exists := msg.Options[OptRecursiveDNS]; if exists {
t.Fatalf("Dns servers option shouldn't be present")
}
}
func TestMakeMsgReplyWithHttpClientArch(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedIp := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileUrl := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: []byte("id-1")}
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
expectedIP := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileURL := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IPAddress: expectedIP, InterfaceID: []byte("id-1")}
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgReply(transactionId, expectedServerId, expectedClientId, 0x10,
[]*IdentityAssociation{identityAssociation}, make([][]byte, 0), expectedBootFileUrl, []net.IP{}, nil)
msg := builder.MakeMsgReply(transactionID, expectedServerID, expectedClientID, 0x10,
[]*IdentityAssociation{identityAssociation}, make([][]byte, 0), expectedBootFileURL, []net.IP{}, nil)
vendorClassOption := msg.Options[OptVendorClass]
if vendorClassOption == nil {
t.Fatalf("Vendor class option should be present")
}
bootfileUrlOption := msg.Options.BootfileUrl()
if bootfileUrlOption == nil {
bootfileURLOption := msg.Options.BootFileURL()
if bootfileURLOption == nil {
t.Fatalf("Bootfile URL option should be present")
}
if string(expectedBootFileUrl) != string(bootfileUrlOption) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileUrl, bootfileUrlOption)
if string(expectedBootFileURL) != string(bootfileURLOption) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileURL, bootfileURLOption)
}
}
func TestMakeMsgReplyWithNoAddrsAvailable(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedIp := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileUrl := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: []byte("id-1")}
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
expectedIP := net.ParseIP("2001:db8:f00f:cafe::1")
expectedBootFileURL := []byte("http://bootfileurl")
identityAssociation := &IdentityAssociation{IPAddress: expectedIP, InterfaceID: []byte("id-1")}
expectedErrorMessage := "Boom!"
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgReply(transactionId, expectedServerId, expectedClientId, 0x10,
[]*IdentityAssociation{identityAssociation}, [][]byte{[]byte("id-2")}, expectedBootFileUrl, []net.IP{},
msg := builder.MakeMsgReply(transactionID, expectedServerID, expectedClientID, 0x10,
[]*IdentityAssociation{identityAssociation}, [][]byte{[]byte("id-2")}, expectedBootFileURL, []net.IP{},
fmt.Errorf(expectedErrorMessage))
iaNaOption := msg.Options[OptIaNa]
@ -325,16 +325,16 @@ func TestMakeMsgReplyWithNoAddrsAvailable(t *testing.T) {
if err != nil {
t.Fatalf("Failed to unmarshal IaNa options: %s", err)
}
if possiblyIaAddrOption.Id != OptIaAddr {
t.Fatalf("Expected option 5 (ia address), got %d", possiblyIaAddrOption.Id)
if possiblyIaAddrOption.ID != OptIaAddr {
t.Fatalf("Expected option 5 (ia address), got %d", possiblyIaAddrOption.ID)
}
possiblyStatusOption, err := UnmarshalOption(failedIaNaOption[12:])
if err != nil {
t.Fatalf("Failed to unmarshal IaNa options: %s", err)
}
if possiblyStatusOption.Id != OptStatusCode {
t.Fatalf("Expected option 13 (status code), got %d", possiblyStatusOption.Id)
if possiblyStatusOption.ID != OptStatusCode {
t.Fatalf("Expected option 13 (status code), got %d", possiblyStatusOption.ID)
}
if binary.BigEndian.Uint16(possiblyStatusOption.Value[0:2]) != uint16(2) {
t.Fatalf("Expected status code 2, got %d", binary.BigEndian.Uint16(possiblyStatusOption.Value[0:2]))
@ -345,147 +345,147 @@ func TestMakeMsgReplyWithNoAddrsAvailable(t *testing.T) {
}
func TestMakeMsgInformationRequestReply(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedBootFileUrl := []byte("http://bootfileurl")
expectedDnsServerIp := net.ParseIP("2001:db8:f00f:cafe::99")
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
expectedBootFileURL := []byte("http://bootfileurl")
expectedDnsServerIP := net.ParseIP("2001:db8:f00f:cafe::99")
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgInformationRequestReply(transactionId, expectedServerId, expectedClientId, 0x11,
expectedBootFileUrl, []net.IP{expectedDnsServerIp})
msg := builder.MakeMsgInformationRequestReply(transactionID, expectedServerID, expectedClientID, 0x11,
expectedBootFileURL, []net.IP{expectedDnsServerIP})
if msg.Type != MsgReply {
t.Fatalf("Expected message type %d, got %d", MsgAdvertise, msg.Type)
}
if transactionId != msg.TransactionID {
t.Fatalf("Expected transaction Id %v, got %v", transactionId, msg.TransactionID)
if transactionID != msg.TransactionID {
t.Fatalf("Expected transaction ID %v, got %v", transactionID, msg.TransactionID)
}
clientIdOption := msg.Options.ClientId()
if clientIdOption == nil {
t.Fatalf("Client Id option should be present")
clientIDOption := msg.Options.ClientID()
if clientIDOption == nil {
t.Fatalf("Client ID option should be present")
}
if string(expectedClientId) != string(clientIdOption) {
t.Fatalf("Expected client id %v, got %v", expectedClientId, clientIdOption)
if string(expectedClientID) != string(clientIDOption) {
t.Fatalf("Expected Client id %v, got %v", expectedClientID, clientIDOption)
}
if len(expectedClientId) != len(clientIdOption) {
t.Fatalf("Expected client id length of %d, got %d", len(expectedClientId), len(clientIdOption))
if len(expectedClientID) != len(clientIDOption) {
t.Fatalf("Expected Client id length of %d, got %d", len(expectedClientID), len(clientIDOption))
}
serverIdOption := msg.Options.ServerId()
if serverIdOption == nil {
t.Fatalf("Server Id option should be present")
serverIDOption := msg.Options.ServerID()
if serverIDOption == nil {
t.Fatalf("Server ID option should be present")
}
if string(expectedServerId) != string(serverIdOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientId, serverIdOption)
if string(expectedServerID) != string(serverIDOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientID, serverIDOption)
}
if len(expectedServerId) != len(serverIdOption) {
t.Fatalf("Expected server id length of %d, got %d", len(expectedClientId), len(serverIdOption))
if len(expectedServerID) != len(serverIDOption) {
t.Fatalf("Expected server id length of %d, got %d", len(expectedClientID), len(serverIDOption))
}
bootfileUrlOption := msg.Options.BootfileUrl()
if bootfileUrlOption == nil {
bootfileURLOption := msg.Options.BootFileURL()
if bootfileURLOption == nil {
t.Fatalf("Bootfile URL option should be present")
}
if string(expectedBootFileUrl) != string(bootfileUrlOption) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileUrl, bootfileUrlOption)
if string(expectedBootFileURL) != string(bootfileURLOption) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileURL, bootfileURLOption)
}
dnsServersOption := msg.Options[OptRecursiveDns]
dnsServersOption := msg.Options[OptRecursiveDNS]
if dnsServersOption == nil {
t.Fatalf("DNS servers option should be set")
}
if string(dnsServersOption[0].Value) != string(expectedDnsServerIp) {
t.Fatalf("Expected dns server %v, got %v", expectedDnsServerIp, net.IP(dnsServersOption[0].Value))
if string(dnsServersOption[0].Value) != string(expectedDnsServerIP) {
t.Fatalf("Expected dns server %v, got %v", expectedDnsServerIP, net.IP(dnsServersOption[0].Value))
}
}
func TestMakeMsgInformationRequestReplyShouldSkipDnsServersIfNoneWereConfigured(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedBootFileUrl := []byte("http://bootfileurl")
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
expectedBootFileURL := []byte("http://bootfileurl")
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgInformationRequestReply(transactionId, expectedServerId, expectedClientId, 0x11,
expectedBootFileUrl, []net.IP{})
msg := builder.MakeMsgInformationRequestReply(transactionID, expectedServerID, expectedClientID, 0x11,
expectedBootFileURL, []net.IP{})
_, exists := msg.Options[OptRecursiveDns]; if exists {
_, exists := msg.Options[OptRecursiveDNS]; if exists {
t.Fatalf("Dns servers option shouldn't be present")
}
}
func TestMakeMsgInformationRequestReplyWithHttpClientArch(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedBootFileUrl := []byte("http://bootfileurl")
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
expectedBootFileURL := []byte("http://bootfileurl")
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgInformationRequestReply(transactionId, expectedServerId, expectedClientId, 0x10,
expectedBootFileUrl, []net.IP{})
msg := builder.MakeMsgInformationRequestReply(transactionID, expectedServerID, expectedClientID, 0x10,
expectedBootFileURL, []net.IP{})
vendorClassOption := msg.Options[OptVendorClass]
if vendorClassOption == nil {
t.Fatalf("Vendor class option should be present")
}
bootfileUrlOption := msg.Options.BootfileUrl()
if bootfileUrlOption == nil {
bootfileURLOption := msg.Options.BootFileURL()
if bootfileURLOption == nil {
t.Fatalf("Bootfile URL option should be present")
}
if string(expectedBootFileUrl) != string(bootfileUrlOption) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileUrl, bootfileUrlOption)
if string(expectedBootFileURL) != string(bootfileURLOption) {
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileURL, bootfileURLOption)
}
}
func TestMakeMsgReleaseReply(t *testing.T) {
expectedClientId := []byte("clientid")
expectedServerId := []byte("serverid")
transactionId := [3]byte{'1', '2', '3'}
expectedClientID := []byte("clientid")
expectedServerID := []byte("serverid")
transactionID := [3]byte{'1', '2', '3'}
builder := MakePacketBuilder(90, 100)
msg := builder.MakeMsgReleaseReply(transactionId, expectedServerId, expectedClientId)
msg := builder.MakeMsgReleaseReply(transactionID, expectedServerID, expectedClientID)
if msg.Type != MsgReply {
t.Fatalf("Expected message type %d, got %d", MsgAdvertise, msg.Type)
}
if transactionId != msg.TransactionID {
t.Fatalf("Expected transaction Id %v, got %v", transactionId, msg.TransactionID)
if transactionID != msg.TransactionID {
t.Fatalf("Expected transaction ID %v, got %v", transactionID, msg.TransactionID)
}
clientIdOption := msg.Options.ClientId()
if clientIdOption == nil {
t.Fatalf("Client Id option should be present")
clientIDOption := msg.Options.ClientID()
if clientIDOption == nil {
t.Fatalf("Client ID option should be present")
}
if string(expectedClientId) != string(clientIdOption) {
t.Fatalf("Expected client id %v, got %v", expectedClientId, clientIdOption)
if string(expectedClientID) != string(clientIDOption) {
t.Fatalf("Expected Client id %v, got %v", expectedClientID, clientIDOption)
}
if len(expectedClientId) != len(clientIdOption) {
t.Fatalf("Expected client id length of %d, got %d", len(expectedClientId), len(clientIdOption))
if len(expectedClientID) != len(clientIDOption) {
t.Fatalf("Expected Client id length of %d, got %d", len(expectedClientID), len(clientIDOption))
}
serverIdOption := msg.Options.ServerId()
if serverIdOption == nil {
t.Fatalf("Server Id option should be present")
serverIDOption := msg.Options.ServerID()
if serverIDOption == nil {
t.Fatalf("Server ID option should be present")
}
if string(expectedServerId) != string(serverIdOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientId, serverIdOption)
if string(expectedServerID) != string(serverIDOption) {
t.Fatalf("Expected server id %v, got %v", expectedClientID, serverIDOption)
}
if len(expectedServerId) != len(serverIdOption) {
t.Fatalf("Expected server id length of %d, got %d", len(expectedClientId), len(serverIdOption))
if len(expectedServerID) != len(serverIDOption) {
t.Fatalf("Expected server id length of %d, got %d", len(expectedClientID), len(serverIDOption))
}
}
func TestExtractLLAddressOrIdWithDUIDLLT(t *testing.T) {
builder := &PacketBuilder{}
expectedLLAddress := []byte{0xac, 0xbc, 0x32, 0xae, 0x86, 0x37}
llAddress := builder.ExtractLLAddressOrId([]byte{0x0, 0x1, 0x0, 0x1, 0x1, 0x2, 0x3, 0x4, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37})
llAddress := builder.ExtractLLAddressOrID([]byte{0x0, 0x1, 0x0, 0x1, 0x1, 0x2, 0x3, 0x4, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37})
if string(expectedLLAddress) != string(llAddress) {
t.Fatalf("Expected ll address %x, got: %x", expectedLLAddress, llAddress)
}
@ -494,7 +494,7 @@ func TestExtractLLAddressOrIdWithDUIDLLT(t *testing.T) {
func TestExtractLLAddressOrIdWithDUIDEN(t *testing.T) {
builder := &PacketBuilder{}
expectedId := []byte{0x0, 0x1, 0x2, 0x3, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37}
id := builder.ExtractLLAddressOrId([]byte{0x0, 0x2, 0x0, 0x1, 0x2, 0x3, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37})
id := builder.ExtractLLAddressOrID([]byte{0x0, 0x2, 0x0, 0x1, 0x2, 0x3, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37})
if string(expectedId) != string(id) {
t.Fatalf("Expected id %x, got: %x", expectedId, id)
}
@ -503,7 +503,7 @@ func TestExtractLLAddressOrIdWithDUIDEN(t *testing.T) {
func TestExtractLLAddressOrIdWithDUIDLL(t *testing.T) {
builder := &PacketBuilder{}
expectedLLAddress := []byte{0xac, 0xbc, 0x32, 0xae, 0x86, 0x37}
llAddress := builder.ExtractLLAddressOrId([]byte{0x0, 0x3, 0x0, 0x1, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37})
llAddress := builder.ExtractLLAddressOrID([]byte{0x0, 0x3, 0x0, 0x1, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37})
if string(expectedLLAddress) != string(llAddress) {
t.Fatalf("Expected ll address %x, got: %x", expectedLLAddress, llAddress)
}

View File

@ -6,9 +6,9 @@ import (
)
func TestShouldDiscardSolicitWithoutBootfileUrlOption(t *testing.T) {
clientId := []byte("clientid")
clientID := []byte("clientid")
options := make(Options)
options.AddOption(&Option{Id: OptClientId, Length: uint16(len(clientId)), Value: clientId})
options.AddOption(&Option{ID: OptClientID, Length: uint16(len(clientID)), Value: clientID})
solicit := &Packet{Type: MsgSolicit, TransactionID: [3]byte{'1', '2', '3'}, Options: options}
if err := ShouldDiscardSolicit(solicit); err == nil {
@ -18,7 +18,7 @@ func TestShouldDiscardSolicitWithoutBootfileUrlOption(t *testing.T) {
func TestShouldDiscardSolicitWithoutClientIdOption(t *testing.T) {
options := make(Options)
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileUrl}))
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileURL}))
solicit := &Packet{Type: MsgSolicit, TransactionID: [3]byte{'1', '2', '3'}, Options: options}
if err := ShouldDiscardSolicit(solicit); err == nil {
@ -27,12 +27,12 @@ func TestShouldDiscardSolicitWithoutClientIdOption(t *testing.T) {
}
func TestShouldDiscardSolicitWithServerIdOption(t *testing.T) {
serverId := []byte("serverid")
clientId := []byte("clientid")
serverID := []byte("serverid")
clientID := []byte("clientid")
options := make(Options)
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileUrl}))
options.AddOption(&Option{Id: OptClientId, Length: uint16(len(clientId)), Value: clientId})
options.AddOption(&Option{Id: OptServerId, Length: uint16(len(serverId)), Value: serverId})
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileURL}))
options.AddOption(&Option{ID: OptClientID, Length: uint16(len(clientID)), Value: clientID})
options.AddOption(&Option{ID: OptServerID, Length: uint16(len(serverID)), Value: serverID})
solicit := &Packet{Type: MsgSolicit, TransactionID: [3]byte{'1', '2', '3'}, Options: options}
if err := ShouldDiscardSolicit(solicit); err == nil {
@ -41,35 +41,35 @@ func TestShouldDiscardSolicitWithServerIdOption(t *testing.T) {
}
func TestShouldDiscardRequestWithoutBootfileUrlOption(t *testing.T) {
serverId := []byte("serverid")
clientId := []byte("clientid")
serverID := []byte("serverid")
clientID := []byte("clientid")
options := make(Options)
options.AddOption(&Option{Id: OptClientId, Length: uint16(len(clientId)), Value: clientId})
options.AddOption(&Option{Id: OptServerId, Length: uint16(len(serverId)), Value: serverId})
options.AddOption(&Option{ID: OptClientID, Length: uint16(len(clientID)), Value: clientID})
options.AddOption(&Option{ID: OptServerID, Length: uint16(len(serverID)), Value: serverID})
request := &Packet{Type: MsgRequest, TransactionID: [3]byte{'1', '2', '3'}, Options: options}
if err := ShouldDiscardRequest(request, serverId); err == nil {
if err := ShouldDiscardRequest(request, serverID); err == nil {
t.Fatalf("Should discard request packet without bootfile url option, but didn't")
}
}
func TestShouldDiscardRequestWithoutClientIdOption(t *testing.T) {
serverId := []byte("serverid")
serverID := []byte("serverid")
options := make(Options)
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileUrl}))
options.AddOption(&Option{Id: OptServerId, Length: uint16(len(serverId)), Value: serverId})
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileURL}))
options.AddOption(&Option{ID: OptServerID, Length: uint16(len(serverID)), Value: serverID})
request := &Packet{Type: MsgRequest, TransactionID: [3]byte{'1', '2', '3'}, Options: options}
if err := ShouldDiscardRequest(request, serverId); err == nil {
if err := ShouldDiscardRequest(request, serverID); err == nil {
t.Fatalf("Should discard request packet without client id option, but didn't")
}
}
func TestShouldDiscardRequestWithoutServerIdOption(t *testing.T) {
clientId := []byte("clientid")
clientID := []byte("clientid")
options := make(Options)
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileUrl}))
options.AddOption(&Option{Id: OptClientId, Length: uint16(len(clientId)), Value: clientId})
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileURL}))
options.AddOption(&Option{ID: OptClientID, Length: uint16(len(clientID)), Value: clientID})
request := &Packet{Type: MsgRequest, TransactionID: [3]byte{'1', '2', '3'}, Options: options}
if err := ShouldDiscardRequest(request, []byte("serverid")); err == nil {
@ -78,12 +78,12 @@ func TestShouldDiscardRequestWithoutServerIdOption(t *testing.T) {
}
func TestShouldDiscardRequestWithWrongServerId(t *testing.T) {
clientId := []byte("clientid")
serverId := []byte("serverid")
clientID := []byte("clientid")
serverID := []byte("serverid")
options := make(Options)
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileUrl}))
options.AddOption(&Option{Id: OptClientId, Length: uint16(len(clientId)), Value: clientId})
options.AddOption(&Option{Id: OptServerId, Length: uint16(len(serverId)), Value: serverId})
options.AddOption(MakeOptionRequestOptions([]uint16{OptBootfileURL}))
options.AddOption(&Option{ID: OptClientID, Length: uint16(len(clientID)), Value: clientID})
options.AddOption(&Option{ID: OptServerID, Length: uint16(len(serverID)), Value: serverID})
request := &Packet{Type: MsgRequest, TransactionID: [3]byte{'1', '2', '3'}, Options: options}
if err := ShouldDiscardRequest(request, []byte("wrongid")); err == nil {
@ -97,6 +97,6 @@ func MakeOptionRequestOptions(options []uint16) *Option {
binary.BigEndian.PutUint16(value[i*2:], option)
}
return &Option{Id: OptOro, Length: uint16(len(options)*2), Value: value}
return &Option{ID: OptOro, Length: uint16(len(options)*2), Value: value}
}

View File

@ -26,9 +26,9 @@ func (f *Fifo) Push(v interface{}) {
}
func (f *Fifo) Shift() interface{} {
var to_ret interface{}
to_ret, f.q = f.q[0], f.q[1:]
return to_ret
var ret interface{}
ret, f.q = f.q[0], f.q[1:]
return ret
}
func (f *Fifo) Size() int {
@ -54,37 +54,37 @@ type RandomAddressPool struct {
}
func NewRandomAddressPool(poolStartAddress net.IP, poolSize uint64, validLifetime uint32) *RandomAddressPool {
to_ret := &RandomAddressPool{}
to_ret.validLifetime = validLifetime
to_ret.poolStartAddress = big.NewInt(0)
to_ret.poolStartAddress.SetBytes(poolStartAddress)
to_ret.poolSize = poolSize
to_ret.identityAssociations = make(map[uint64]*IdentityAssociation)
to_ret.usedIps = make(map[uint64]struct{})
to_ret.identityAssociationExpirations = newFifo()
to_ret.timeNow = func() time.Time { return time.Now() }
ret := &RandomAddressPool{}
ret.validLifetime = validLifetime
ret.poolStartAddress = big.NewInt(0)
ret.poolStartAddress.SetBytes(poolStartAddress)
ret.poolSize = poolSize
ret.identityAssociations = make(map[uint64]*IdentityAssociation)
ret.usedIps = make(map[uint64]struct{})
ret.identityAssociationExpirations = newFifo()
ret.timeNow = func() time.Time { return time.Now() }
ticker := time.NewTicker(time.Second * 10).C
go func() {
for {
<- ticker
to_ret.ExpireIdentityAssociations()
ret.ExpireIdentityAssociations()
}
}()
return to_ret
return ret
}
func (p *RandomAddressPool) ReserveAddresses(clientId []byte, interfaceIds [][]byte) ([]*IdentityAssociation, error) {
func (p *RandomAddressPool) ReserveAddresses(clientID []byte, interfaceIDs [][]byte) ([]*IdentityAssociation, error) {
p.lock.Lock()
defer p.lock.Unlock()
ret := make([]*IdentityAssociation, 0, len(interfaceIds))
ret := make([]*IdentityAssociation, 0, len(interfaceIDs))
rng := rand.New(rand.NewSource(p.timeNow().UnixNano()))
for _, interfaceId := range (interfaceIds) {
clientIdHash := p.calculateIaIdHash(clientId, interfaceId)
association, exists := p.identityAssociations[clientIdHash];
for _, interfaceID := range (interfaceIDs) {
clientIDHash := p.calculateIAIDHash(clientID, interfaceID)
association, exists := p.identityAssociations[clientIDHash];
if exists {
ret = append(ret, association)
@ -101,11 +101,11 @@ func (p *RandomAddressPool) ReserveAddresses(clientId []byte, interfaceIds [][]b
_, exists := p.usedIps[newIp.Uint64()];
if !exists {
timeNow := p.timeNow()
association := &IdentityAssociation{ClientId: clientId,
InterfaceId: interfaceId,
IpAddress: newIp.Bytes(),
association := &IdentityAssociation{ClientID: clientID,
InterfaceID: interfaceID,
IPAddress: newIp.Bytes(),
CreatedAt: timeNow}
p.identityAssociations[clientIdHash] = association
p.identityAssociations[clientIDHash] = association
p.usedIps[newIp.Uint64()] = struct{}{}
p.identityAssociationExpirations.Push(&AssociationExpiration{expiresAt: p.calculateAssociationExpiration(timeNow), ia: association})
ret = append(ret, association)
@ -117,17 +117,17 @@ func (p *RandomAddressPool) ReserveAddresses(clientId []byte, interfaceIds [][]b
return ret, nil
}
func (p *RandomAddressPool) ReleaseAddresses(clientId []byte, interfaceIds [][]byte) {
func (p *RandomAddressPool) ReleaseAddresses(clientID []byte, interfaceIDs [][]byte) {
p.lock.Lock()
defer p.lock.Unlock()
for _, interfaceId := range(interfaceIds) {
association, exists := p.identityAssociations[p.calculateIaIdHash(clientId, interfaceId)]
for _, interfaceId := range(interfaceIDs) {
association, exists := p.identityAssociations[p.calculateIAIDHash(clientID, interfaceId)]
if !exists {
continue
}
delete(p.usedIps, big.NewInt(0).SetBytes(association.IpAddress).Uint64())
delete(p.identityAssociations, p.calculateIaIdHash(clientId, interfaceId))
delete(p.usedIps, big.NewInt(0).SetBytes(association.IPAddress).Uint64())
delete(p.identityAssociations, p.calculateIAIDHash(clientID, interfaceId))
}
}
@ -140,8 +140,8 @@ func (p *RandomAddressPool) ExpireIdentityAssociations() {
expiration := p.identityAssociationExpirations.Peek().(*AssociationExpiration)
if p.timeNow().Before(expiration.expiresAt) { break }
p.identityAssociationExpirations.Shift()
delete(p.identityAssociations, p.calculateIaIdHash(expiration.ia.ClientId, expiration.ia.InterfaceId))
delete(p.usedIps, big.NewInt(0).SetBytes(expiration.ia.IpAddress).Uint64())
delete(p.identityAssociations, p.calculateIAIDHash(expiration.ia.ClientID, expiration.ia.InterfaceID))
delete(p.usedIps, big.NewInt(0).SetBytes(expiration.ia.IPAddress).Uint64())
}
}
@ -149,10 +149,10 @@ func (p *RandomAddressPool) calculateAssociationExpiration(now time.Time) time.T
return now.Add(time.Duration(p.validLifetime)*time.Second)
}
func (p *RandomAddressPool) calculateIaIdHash(clientId, interfaceId []byte) uint64 {
func (p *RandomAddressPool) calculateIAIDHash(clientID, interfaceID []byte) uint64 {
h := fnv.New64a()
h.Write(clientId)
h.Write(interfaceId)
h.Write(clientID)
h.Write(interfaceID)
return h.Sum64()
}

View File

@ -7,42 +7,42 @@ import (
)
func TestReserveAddress(t *testing.T) {
expectedIp1 := net.ParseIP("2001:db8:f00f:cafe::1")
expectedIp2 := net.ParseIP("2001:db8:f00f:cafe::2")
expectedClientId := []byte("client-id")
expectedIaId1 := []byte("interface-id-1")
expectedIaId2 := []byte("interface-id-2")
expectedIP1 := net.ParseIP("2001:db8:f00f:cafe::1")
expectedIP2 := net.ParseIP("2001:db8:f00f:cafe::2")
expectedClientID := []byte("Client-id")
expectedIAID1 := []byte("interface-id-1")
expectedIAID2 := []byte("interface-id-2")
expectedTime := time.Now()
expectedMaxLifetime := uint32(100)
pool := NewRandomAddressPool(expectedIp1, 2, expectedMaxLifetime)
pool := NewRandomAddressPool(expectedIP1, 2, expectedMaxLifetime)
pool.timeNow = func() time.Time { return expectedTime }
ias, _ := pool.ReserveAddresses(expectedClientId, [][]byte{expectedIaId1, expectedIaId2})
ias, _ := pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID1, expectedIAID2})
if len(ias) != 2 {
t.Fatalf("Expected 2 identity associations but received %d", len(ias))
}
if string(ias[0].IpAddress) != string(expectedIp1) && string(ias[0].IpAddress) != string(expectedIp2) {
t.Fatalf("Unexpected ip address: %v", ias[0].IpAddress)
if string(ias[0].IPAddress) != string(expectedIP1) && string(ias[0].IPAddress) != string(expectedIP2) {
t.Fatalf("Unexpected ip address: %v", ias[0].IPAddress)
}
if string(ias[0].ClientId) != string(expectedClientId) {
t.Fatalf("Expected client id: %v, but got: %v", expectedClientId, ias[0].ClientId)
if string(ias[0].ClientID) != string(expectedClientID) {
t.Fatalf("Expected Client id: %v, but got: %v", expectedClientID, ias[0].ClientID)
}
if string(ias[0].InterfaceId) != string(expectedIaId1) {
t.Fatalf("Expected interface id: %v, but got: %v", expectedIaId1, ias[0].InterfaceId)
if string(ias[0].InterfaceID) != string(expectedIAID1) {
t.Fatalf("Expected interface id: %v, but got: %v", expectedIAID1, ias[0].InterfaceID)
}
if ias[0].CreatedAt != expectedTime {
t.Fatalf("Expected creation time: %v, but got: %v", expectedTime, ias[0].CreatedAt)
}
if string(ias[1].IpAddress) != string(expectedIp1) && string(ias[1].IpAddress) != string(expectedIp2) {
t.Fatalf("Unexpected ip address: %v", ias[0].IpAddress)
if string(ias[1].IPAddress) != string(expectedIP1) && string(ias[1].IPAddress) != string(expectedIP2) {
t.Fatalf("Unexpected ip address: %v", ias[0].IPAddress)
}
if string(ias[1].ClientId) != string(expectedClientId) {
t.Fatalf("Expected client id: %v, but got: %v", expectedClientId, ias[1].ClientId)
if string(ias[1].ClientID) != string(expectedClientID) {
t.Fatalf("Expected Client id: %v, but got: %v", expectedClientID, ias[1].ClientID)
}
if string(ias[1].InterfaceId) != string(expectedIaId2) {
t.Fatalf("Expected interface id: %v, but got: %v", expectedIaId2, ias[1].InterfaceId)
if string(ias[1].InterfaceID) != string(expectedIAID2) {
t.Fatalf("Expected interface id: %v, but got: %v", expectedIAID2, ias[1].InterfaceID)
}
if ias[1].CreatedAt != expectedTime {
t.Fatalf("Expected creation time: %v, but got: %v", expectedTime, ias[1].CreatedAt)
@ -50,35 +50,35 @@ func TestReserveAddress(t *testing.T) {
}
func TestReserveAddressUpdatesAddressPool(t *testing.T) {
expectedClientId := []byte("client-id")
expectedIaId := []byte("interface-id")
expectedClientID := []byte("Client-id")
expectedIAID := []byte("interface-id")
expectedTime := time.Now()
expectedMaxLifetime := uint32(100)
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
pool.timeNow = func() time.Time { return expectedTime }
pool.ReserveAddresses(expectedClientId, [][]byte{expectedIaId})
expectedIdx := pool.calculateIaIdHash(expectedClientId, expectedIaId)
pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
expectedIdx := pool.calculateIAIDHash(expectedClientID, expectedIAID)
a, exists := pool.identityAssociations[expectedIdx]
if !exists {
t.Fatalf("Expected to find identity association at %d but didn't", expectedIdx)
}
if string(a.ClientId) != string(expectedClientId) || string(a.InterfaceId) != string(expectedIaId) {
t.Fatalf("Expected ia association with client id %x and ia id %x, but got %x %x respectively",
expectedClientId, expectedIaId, a.ClientId, a.InterfaceId)
if string(a.ClientID) != string(expectedClientID) || string(a.InterfaceID) != string(expectedIAID) {
t.Fatalf("Expected ia association with Client id %x and ia id %x, but got %x %x respectively",
expectedClientID, expectedIAID, a.ClientID, a.InterfaceID)
}
}
func TestReserveAddressKeepsTrackOfUsedAddresses(t *testing.T) {
expectedClientId := []byte("client-id")
expectedIaId := []byte("interface-id")
expectedClientID := []byte("Client-id")
expectedIAID := []byte("interface-id")
expectedTime := time.Now()
expectedMaxLifetime := uint32(100)
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
pool.timeNow = func() time.Time { return expectedTime }
pool.ReserveAddresses(expectedClientId, [][]byte{expectedIaId})
pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
_, exists := pool.usedIps[0x01]; if !exists {
t.Fatal("'2001:db8:f00f:cafe::1' should be marked as in use")
@ -86,14 +86,14 @@ func TestReserveAddressKeepsTrackOfUsedAddresses(t *testing.T) {
}
func TestReserveAddressKeepsTrackOfAssociationExpiration(t *testing.T) {
expectedClientId := []byte("client-id")
expectedIaId := []byte("interface-id")
expectedClientID := []byte("Client-id")
expectedIAID := []byte("interface-id")
expectedTime := time.Now()
expectedMaxLifetime := uint32(100)
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
pool.timeNow = func() time.Time { return expectedTime }
pool.ReserveAddresses(expectedClientId, [][]byte{expectedIaId})
pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
expiration := pool.identityAssociationExpirations.Peek().(*AssociationExpiration)
if expiration == nil {
@ -106,15 +106,15 @@ func TestReserveAddressKeepsTrackOfAssociationExpiration(t *testing.T) {
}
func TestReserveAddressReturnsExistingAssociation(t *testing.T) {
expectedClientId := []byte("client-id")
expectedIaId := []byte("interface-id")
expectedClientID := []byte("Client-id")
expectedIAID := []byte("interface-id")
expectedTime := time.Now()
expectedMaxLifetime := uint32(100)
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
pool.timeNow = func() time.Time { return expectedTime }
firstAssociation, _ := pool.ReserveAddresses(expectedClientId, [][]byte{expectedIaId})
secondAssociation, _ := pool.ReserveAddresses(expectedClientId, [][]byte{expectedIaId})
firstAssociation, _ := pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
secondAssociation, _ := pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
if len(firstAssociation) < 1 {
t.Fatalf("No associations returned from the first call to ReserveAddresses")
@ -122,24 +122,24 @@ func TestReserveAddressReturnsExistingAssociation(t *testing.T) {
if len(secondAssociation) < 1 {
t.Fatalf("No associations returned from the second call to ReserveAddresses")
}
if string(firstAssociation[0].IpAddress) != string(secondAssociation[0].IpAddress) {
if string(firstAssociation[0].IPAddress) != string(secondAssociation[0].IPAddress) {
t.Fatal("Expected return of the same ip address on both invocations")
}
}
func TestReleaseAddress(t *testing.T) {
expectedClientId := []byte("client-id")
expectedIaId := []byte("interface-id")
expectedClientID := []byte("Client-id")
expectedIAID := []byte("interface-id")
expectedTime := time.Now()
expectedMaxLifetime := uint32(100)
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
pool.timeNow = func() time.Time { return expectedTime }
a, _ := pool.ReserveAddresses(expectedClientId, [][]byte{expectedIaId})
a, _ := pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
pool.ReleaseAddresses(expectedClientId, [][]byte{expectedIaId})
pool.ReleaseAddresses(expectedClientID, [][]byte{expectedIAID})
_, exists := pool.identityAssociations[pool.calculateIaIdHash(expectedClientId, expectedIaId)]; if exists {
t.Fatalf("identity association for %v should've been removed, but is still available", a[0].IpAddress)
_, exists := pool.identityAssociations[pool.calculateIAIDHash(expectedClientID, expectedIAID)]; if exists {
t.Fatalf("identity association for %v should've been removed, but is still available", a[0].IPAddress)
}
}

View File

@ -18,11 +18,11 @@ var bootIPv6Cmd = &cobra.Command{
if err != nil {
fatalf("Error reading flag: %s", err)
}
ipxeUrl, err := cmd.Flags().GetString("ipxe-url")
ipxeURL, err := cmd.Flags().GetString("ipxe-url")
if err != nil {
fatalf("Error reading flag: %s", err)
}
httpBootUrl, err := cmd.Flags().GetString("httpboot-url")
httpBootURL, err := cmd.Flags().GetString("httpboot-url")
if err != nil {
fatalf("Error reading flag: %s", err)
}
@ -40,10 +40,10 @@ var bootIPv6Cmd = &cobra.Command{
fatalf("Please specify address to bind to")
} else {
}
if ipxeUrl == "" {
if ipxeURL == "" {
fatalf("Please specify ipxe config file url")
}
if httpBootUrl == "" {
if httpBootURL == "" {
fatalf("Please specify httpboot url")
}
@ -62,7 +62,7 @@ var bootIPv6Cmd = &cobra.Command{
dnsServerAddresses = append(dnsServerAddresses, net.ParseIP(dnsServerAddress))
}
}
s.BootConfig = dhcp6.MakeStaticBootConfiguration(httpBootUrl, ipxeUrl, preference,
s.BootConfig = dhcp6.MakeStaticBootConfiguration(httpBootURL, ipxeURL, preference,
cmd.Flags().Changed("preference"), dnsServerAddresses)
addressPoolStart, err := cmd.Flags().GetString("address-pool-start")

View File

@ -20,7 +20,7 @@ var ipv6ApiCmd = &cobra.Command{
if err != nil {
fatalf("Error reading flag: %s", err)
}
apiUrl, err := cmd.Flags().GetString("api-request-url")
apiURL, err := cmd.Flags().GetString("api-request-url")
if err != nil {
fatalf("Error reading flag: %s", err)
}
@ -41,7 +41,7 @@ var ipv6ApiCmd = &cobra.Command{
fatalf("Please specify address to bind to")
} else {
}
if apiUrl == "" {
if apiURL == "" {
fatalf("Please specify ipxe config file url")
}
s.Address = addr
@ -59,7 +59,7 @@ var ipv6ApiCmd = &cobra.Command{
dnsServerAddresses = append(dnsServerAddresses, net.ParseIP(dnsServerAddress))
}
}
s.BootConfig = dhcp6.MakeApiBootConfiguration(apiUrl, apiTimeout, preference,
s.BootConfig = dhcp6.MakeApiBootConfiguration(apiURL, apiTimeout, preference,
cmd.Flags().Changed("preference"), dnsServerAddresses)
addressPoolStart, err := cmd.Flags().GetString("address-pool-start")
@ -81,7 +81,7 @@ var ipv6ApiCmd = &cobra.Command{
},
}
func serverv6ApiConfigFlags(cmd *cobra.Command) {
func serverv6APIConfigFlags(cmd *cobra.Command) {
cmd.Flags().StringP("listen-addr", "", "", "IPv6 address to listen on")
cmd.Flags().StringP("api-request-url", "", "", "Ipv6-specific API server url")
cmd.Flags().Duration("api-request-timeout", 5*time.Second, "Timeout for request to the API server")
@ -95,6 +95,6 @@ func serverv6ApiConfigFlags(cmd *cobra.Command) {
func init() {
rootCmd.AddCommand(ipv6ApiCmd)
serverv6ApiConfigFlags(ipv6ApiCmd)
serverv6APIConfigFlags(ipv6ApiCmd)
}

View File

@ -34,13 +34,13 @@ func (s *ServerV6) serveDHCP(conn *dhcp6.Conn) error {
continue
}
marshalled_response, err := response.Marshal()
marshalledResponse, err := response.Marshal()
if err != nil {
s.log("dhcpv6", fmt.Sprintf("Error marshalling response: %s", response.Type, response.TransactionID, err))
continue
}
if err := conn.SendDHCP(src, marshalled_response); err != nil {
if err := conn.SendDHCP(src, marshalledResponse); err != nil {
s.log("dhcpv6", fmt.Sprintf("Error sending reply (%d) (%d): %s", response.Type, response.TransactionID, err))
continue
}