Fix parseIP error when parseIP before get AddressFamily

Signed-off-by: Tom Zhao <zlwangel@gmail.com>
This commit is contained in:
Tom Zhao 2019-08-15 16:44:31 +08:00
parent 65ade31ba1
commit 7ab62b791f
2 changed files with 145 additions and 123 deletions

View File

@ -133,49 +133,67 @@ func TestService(t *testing.T) {
for _, protocol := range protocols { for _, protocol := range protocols {
for _, schedMethod := range schedMethods { for _, schedMethod := range schedMethods {
testDatas := []struct {
s := Service{ AddressFamily uint16
AddressFamily: nl.FAMILY_V4, IP string
SchedName: schedMethod, Netmask uint32
}{
{
AddressFamily: nl.FAMILY_V4,
IP: "1.2.3.4",
Netmask: 0xFFFFFFFF,
}, {
AddressFamily: nl.FAMILY_V6,
IP: "2001:db8:3c4d:15::1a00",
Netmask: 128,
},
} }
for _, td := range testDatas {
switch protocol { s := Service{
case "FWM": AddressFamily: td.AddressFamily,
s.FWMark = 1234 SchedName: schedMethod,
case "TCP":
s.Protocol = unix.IPPROTO_TCP
s.Port = 80
s.Address = net.ParseIP("1.2.3.4")
s.Netmask = 0xFFFFFFFF
case "UDP":
s.Protocol = unix.IPPROTO_UDP
s.Port = 53
s.Address = net.ParseIP("2.3.4.5")
}
err := i.NewService(&s)
assert.NilError(t, err)
checkService(t, i, &s, true)
for _, updateSchedMethod := range schedMethods {
if updateSchedMethod == schedMethod {
continue
} }
s.SchedName = updateSchedMethod switch protocol {
err = i.UpdateService(&s) case "FWM":
s.FWMark = 1234
s.Netmask = td.Netmask
case "TCP":
s.Protocol = unix.IPPROTO_TCP
s.Port = 80
s.Address = net.ParseIP(td.IP)
s.Netmask = td.Netmask
case "UDP":
s.Protocol = unix.IPPROTO_UDP
s.Port = 53
s.Address = net.ParseIP(td.IP)
s.Netmask = td.Netmask
}
err := i.NewService(&s)
assert.NilError(t, err) assert.NilError(t, err)
checkService(t, i, &s, true) checkService(t, i, &s, true)
for _, updateSchedMethod := range schedMethods {
if updateSchedMethod == schedMethod {
continue
}
scopy, err := i.GetService(&s) s.SchedName = updateSchedMethod
err = i.UpdateService(&s)
assert.NilError(t, err)
checkService(t, i, &s, true)
scopy, err := i.GetService(&s)
assert.NilError(t, err)
assert.Check(t, is.Equal((*scopy).Address.String(), s.Address.String()))
assert.Check(t, is.Equal((*scopy).Port, s.Port))
assert.Check(t, is.Equal((*scopy).Protocol, s.Protocol))
}
err = i.DelService(&s)
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal((*scopy).Address.String(), s.Address.String())) checkService(t, i, &s, false)
assert.Check(t, is.Equal((*scopy).Port, s.Port))
assert.Check(t, is.Equal((*scopy).Protocol, s.Protocol))
} }
err = i.DelService(&s)
assert.NilError(t, err)
checkService(t, i, &s, false)
} }
} }
@ -251,95 +269,85 @@ func TestDestination(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
for _, protocol := range protocols { for _, protocol := range protocols {
testDatas := []struct {
s := Service{ AddressFamily uint16
AddressFamily: nl.FAMILY_V4, IP string
SchedName: RoundRobin, Netmask uint32
Destinations []string
}{
{
AddressFamily: nl.FAMILY_V4,
IP: "1.2.3.4",
Netmask: 0xFFFFFFFF,
Destinations: []string{"10.1.1.2", "10.1.1.3", "10.1.1.4"},
}, {
AddressFamily: nl.FAMILY_V6,
IP: "2001:db8:3c4d:15::1a00",
Netmask: 128,
Destinations: []string{"2001:db8:3c4d:15::1a2b", "2001:db8:3c4d:15::1a2c", "2001:db8:3c4d:15::1a2d"},
},
} }
for _, td := range testDatas {
switch protocol { s := Service{
case "FWM": AddressFamily: td.AddressFamily,
s.FWMark = 1234 SchedName: RoundRobin,
case "TCP":
s.Protocol = unix.IPPROTO_TCP
s.Port = 80
s.Address = net.ParseIP("1.2.3.4")
s.Netmask = 0xFFFFFFFF
case "UDP":
s.Protocol = unix.IPPROTO_UDP
s.Port = 53
s.Address = net.ParseIP("2.3.4.5")
}
err := i.NewService(&s)
assert.NilError(t, err)
checkService(t, i, &s, true)
s.SchedName = ""
for _, fwdMethod := range fwdMethods {
d1 := Destination{
AddressFamily: nl.FAMILY_V4,
Address: net.ParseIP("10.1.1.2"),
Port: 5000,
Weight: 1,
ConnectionFlags: fwdMethod,
} }
err := i.NewDestination(&s, &d1) switch protocol {
assert.NilError(t, err) case "FWM":
checkDestination(t, i, &s, &d1, true) s.FWMark = 1234
d2 := Destination{ s.Netmask = td.Netmask
AddressFamily: nl.FAMILY_V4, case "TCP":
Address: net.ParseIP("10.1.1.3"), s.Protocol = unix.IPPROTO_TCP
Port: 5000, s.Port = 80
Weight: 1, s.Address = net.ParseIP(td.IP)
ConnectionFlags: fwdMethod, s.Netmask = td.Netmask
case "UDP":
s.Protocol = unix.IPPROTO_UDP
s.Port = 53
s.Address = net.ParseIP(td.IP)
s.Netmask = td.Netmask
} }
err = i.NewDestination(&s, &d2) err := i.NewService(&s)
assert.NilError(t, err) assert.NilError(t, err)
checkDestination(t, i, &s, &d2, true) checkService(t, i, &s, true)
d3 := Destination{ s.SchedName = ""
AddressFamily: nl.FAMILY_V4, for _, fwdMethod := range fwdMethods {
Address: net.ParseIP("10.1.1.4"), destinations := make([]Destination, 0)
Port: 5000, for _, ip := range td.Destinations {
Weight: 1, d := Destination{
ConnectionFlags: fwdMethod, AddressFamily: td.AddressFamily,
} Address: net.ParseIP(ip),
Port: 5000,
err = i.NewDestination(&s, &d3) Weight: 1,
assert.NilError(t, err) ConnectionFlags: fwdMethod,
checkDestination(t, i, &s, &d3, true) }
destinations = append(destinations, d)
for _, updateFwdMethod := range fwdMethods { err := i.NewDestination(&s, &d)
if updateFwdMethod == fwdMethod { assert.NilError(t, err)
continue checkDestination(t, i, &s, &d, true)
} }
d1.ConnectionFlags = updateFwdMethod
err = i.UpdateDestination(&s, &d1)
assert.NilError(t, err)
checkDestination(t, i, &s, &d1, true)
d2.ConnectionFlags = updateFwdMethod for _, updateFwdMethod := range fwdMethods {
err = i.UpdateDestination(&s, &d2) if updateFwdMethod == fwdMethod {
assert.NilError(t, err) continue
checkDestination(t, i, &s, &d2, true) }
for _, d := range destinations {
d3.ConnectionFlags = updateFwdMethod d.ConnectionFlags = updateFwdMethod
err = i.UpdateDestination(&s, &d3) err = i.UpdateDestination(&s, &d)
assert.NilError(t, err) assert.NilError(t, err)
checkDestination(t, i, &s, &d3, true) checkDestination(t, i, &s, &d, true)
}
}
for _, d := range destinations {
err = i.DelDestination(&s, &d)
assert.NilError(t, err)
checkDestination(t, i, &s, &d, false)
}
} }
err = i.DelDestination(&s, &d1)
assert.NilError(t, err)
err = i.DelDestination(&s, &d2)
assert.NilError(t, err)
err = i.DelDestination(&s, &d3)
assert.NilError(t, err)
checkDestination(t, i, &s, &d3, false)
} }
} }
} }

View File

@ -315,6 +315,7 @@ func assembleStats(msg []byte) (SvcStats, error) {
func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) { func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {
var s Service var s Service
var addressBytes []byte
for _, attr := range attrs { for _, attr := range attrs {
@ -327,11 +328,7 @@ func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {
case ipvsSvcAttrProtocol: case ipvsSvcAttrProtocol:
s.Protocol = native.Uint16(attr.Value) s.Protocol = native.Uint16(attr.Value)
case ipvsSvcAttrAddress: case ipvsSvcAttrAddress:
ip, err := parseIP(attr.Value, s.AddressFamily) addressBytes = attr.Value
if err != nil {
return nil, err
}
s.Address = ip
case ipvsSvcAttrPort: case ipvsSvcAttrPort:
s.Port = binary.BigEndian.Uint16(attr.Value) s.Port = binary.BigEndian.Uint16(attr.Value)
case ipvsSvcAttrFWMark: case ipvsSvcAttrFWMark:
@ -353,6 +350,16 @@ func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {
} }
} }
// parse Address after parse AddressFamily incase of parseIP error
if addressBytes != nil {
ip, err := parseIP(addressBytes, s.AddressFamily)
if err != nil {
return nil, err
}
s.Address = ip
}
return &s, nil return &s, nil
} }
@ -416,6 +423,7 @@ func (i *Handle) doCmdWithoutAttr(cmd uint8) ([][]byte, error) {
func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error) { func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error) {
var d Destination var d Destination
var addressBytes []byte
for _, attr := range attrs { for _, attr := range attrs {
@ -426,11 +434,7 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error)
case ipvsDestAttrAddressFamily: case ipvsDestAttrAddressFamily:
d.AddressFamily = native.Uint16(attr.Value) d.AddressFamily = native.Uint16(attr.Value)
case ipvsDestAttrAddress: case ipvsDestAttrAddress:
ip, err := parseIP(attr.Value, d.AddressFamily) addressBytes = attr.Value
if err != nil {
return nil, err
}
d.Address = ip
case ipvsDestAttrPort: case ipvsDestAttrPort:
d.Port = binary.BigEndian.Uint16(attr.Value) d.Port = binary.BigEndian.Uint16(attr.Value)
case ipvsDestAttrForwardingMethod: case ipvsDestAttrForwardingMethod:
@ -453,6 +457,16 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error)
d.Stats = DstStats(stats) d.Stats = DstStats(stats)
} }
} }
// parse Address after parse AddressFamily incase of parseIP error
if addressBytes != nil {
ip, err := parseIP(addressBytes, d.AddressFamily)
if err != nil {
return nil, err
}
d.Address = ip
}
return &d, nil return &d, nil
} }