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 _, schedMethod := range schedMethods {
s := Service{
AddressFamily: nl.FAMILY_V4,
SchedName: schedMethod,
testDatas := []struct {
AddressFamily uint16
IP string
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,
},
}
switch protocol {
case "FWM":
s.FWMark = 1234
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
for _, td := range testDatas {
s := Service{
AddressFamily: td.AddressFamily,
SchedName: schedMethod,
}
s.SchedName = updateSchedMethod
err = i.UpdateService(&s)
switch protocol {
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)
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.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))
checkService(t, i, &s, false)
}
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)
for _, protocol := range protocols {
s := Service{
AddressFamily: nl.FAMILY_V4,
SchedName: RoundRobin,
testDatas := []struct {
AddressFamily uint16
IP string
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"},
},
}
switch protocol {
case "FWM":
s.FWMark = 1234
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,
for _, td := range testDatas {
s := Service{
AddressFamily: td.AddressFamily,
SchedName: RoundRobin,
}
err := i.NewDestination(&s, &d1)
assert.NilError(t, err)
checkDestination(t, i, &s, &d1, true)
d2 := Destination{
AddressFamily: nl.FAMILY_V4,
Address: net.ParseIP("10.1.1.3"),
Port: 5000,
Weight: 1,
ConnectionFlags: fwdMethod,
switch protocol {
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.NewDestination(&s, &d2)
err := i.NewService(&s)
assert.NilError(t, err)
checkDestination(t, i, &s, &d2, true)
checkService(t, i, &s, true)
d3 := Destination{
AddressFamily: nl.FAMILY_V4,
Address: net.ParseIP("10.1.1.4"),
Port: 5000,
Weight: 1,
ConnectionFlags: fwdMethod,
}
err = i.NewDestination(&s, &d3)
assert.NilError(t, err)
checkDestination(t, i, &s, &d3, true)
for _, updateFwdMethod := range fwdMethods {
if updateFwdMethod == fwdMethod {
continue
s.SchedName = ""
for _, fwdMethod := range fwdMethods {
destinations := make([]Destination, 0)
for _, ip := range td.Destinations {
d := Destination{
AddressFamily: td.AddressFamily,
Address: net.ParseIP(ip),
Port: 5000,
Weight: 1,
ConnectionFlags: fwdMethod,
}
destinations = append(destinations, d)
err := i.NewDestination(&s, &d)
assert.NilError(t, err)
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
err = i.UpdateDestination(&s, &d2)
assert.NilError(t, err)
checkDestination(t, i, &s, &d2, true)
d3.ConnectionFlags = updateFwdMethod
err = i.UpdateDestination(&s, &d3)
assert.NilError(t, err)
checkDestination(t, i, &s, &d3, true)
for _, updateFwdMethod := range fwdMethods {
if updateFwdMethod == fwdMethod {
continue
}
for _, d := range destinations {
d.ConnectionFlags = updateFwdMethod
err = i.UpdateDestination(&s, &d)
assert.NilError(t, err)
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) {
var s Service
var addressBytes []byte
for _, attr := range attrs {
@ -327,11 +328,7 @@ func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {
case ipvsSvcAttrProtocol:
s.Protocol = native.Uint16(attr.Value)
case ipvsSvcAttrAddress:
ip, err := parseIP(attr.Value, s.AddressFamily)
if err != nil {
return nil, err
}
s.Address = ip
addressBytes = attr.Value
case ipvsSvcAttrPort:
s.Port = binary.BigEndian.Uint16(attr.Value)
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
}
@ -416,6 +423,7 @@ func (i *Handle) doCmdWithoutAttr(cmd uint8) ([][]byte, error) {
func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error) {
var d Destination
var addressBytes []byte
for _, attr := range attrs {
@ -426,11 +434,7 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error)
case ipvsDestAttrAddressFamily:
d.AddressFamily = native.Uint16(attr.Value)
case ipvsDestAttrAddress:
ip, err := parseIP(attr.Value, d.AddressFamily)
if err != nil {
return nil, err
}
d.Address = ip
addressBytes = attr.Value
case ipvsDestAttrPort:
d.Port = binary.BigEndian.Uint16(attr.Value)
case ipvsDestAttrForwardingMethod:
@ -453,6 +457,16 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error)
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
}