Merge pull request #187 from mrjana/cross

Move network types to types package
This commit is contained in:
Madhu Venugopal 2015-05-20 14:03:52 -07:00
commit e2bdf92d6b
16 changed files with 263 additions and 387 deletions

View File

@ -16,6 +16,7 @@ import (
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
)
const (
@ -275,15 +276,15 @@ func TestGetNetworksAndEndpoints(t *testing.T) {
ec1 := endpointCreate{
Name: "ep1",
NetworkID: string(nid),
ExposedPorts: []netutils.TransportPort{
netutils.TransportPort{Proto: netutils.TCP, Port: uint16(5000)},
netutils.TransportPort{Proto: netutils.UDP, Port: uint16(400)},
netutils.TransportPort{Proto: netutils.TCP, Port: uint16(600)},
ExposedPorts: []types.TransportPort{
types.TransportPort{Proto: types.TCP, Port: uint16(5000)},
types.TransportPort{Proto: types.UDP, Port: uint16(400)},
types.TransportPort{Proto: types.TCP, Port: uint16(600)},
},
PortMapping: []netutils.PortBinding{
netutils.PortBinding{Proto: netutils.TCP, Port: uint16(230), HostPort: uint16(23000)},
netutils.PortBinding{Proto: netutils.UDP, Port: uint16(200), HostPort: uint16(22000)},
netutils.PortBinding{Proto: netutils.TCP, Port: uint16(120), HostPort: uint16(12000)},
PortMapping: []types.PortBinding{
types.PortBinding{Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)},
types.PortBinding{Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)},
types.PortBinding{Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)},
},
}
b1, err := json.Marshal(ec1)

View File

@ -1,6 +1,6 @@
package api
import "github.com/docker/libnetwork/netutils"
import "github.com/docker/libnetwork/types"
/***********
Resources
@ -36,8 +36,8 @@ type networkCreate struct {
type endpointCreate struct {
Name string
NetworkID string
ExposedPorts []netutils.TransportPort
PortMapping []netutils.PortBinding
ExposedPorts []types.TransportPort
PortMapping []types.PortBinding
}
// endpointJoin represents the expected body of the "join endpoint" or "leave endpoint" http request messages

View File

@ -5,8 +5,8 @@ import (
"github.com/docker/libnetwork"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
)
func main() {
@ -58,7 +58,7 @@ func main() {
epInfo, err := ep.DriverInfo()
mapData, ok := epInfo[netlabel.PortMap]
if ok {
portMapping, ok := mapData.([]netutils.PortBinding)
portMapping, ok := mapData.([]types.PortBinding)
if ok {
fmt.Printf("Current port mapping for endpoint %s: %v", ep.Name(), portMapping)
}

View File

@ -57,8 +57,8 @@ type NetworkConfiguration struct {
// EndpointConfiguration represents the user specified configuration for the sandbox endpoint
type EndpointConfiguration struct {
MacAddress net.HardwareAddr
PortBindings []netutils.PortBinding
ExposedPorts []netutils.TransportPort
PortBindings []types.PortBinding
ExposedPorts []types.TransportPort
}
// ContainerConfiguration represents the user specified configuration for a container
@ -73,7 +73,7 @@ type bridgeEndpoint struct {
macAddress net.HardwareAddr
config *EndpointConfiguration // User specified parameters
containerConfig *ContainerConfiguration
portMapping []netutils.PortBinding // Operation port bindings
portMapping []types.PortBinding // Operation port bindings
}
type bridgeNetwork struct {
@ -672,7 +672,7 @@ func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{},
if ep.portMapping != nil {
// Return a copy of the operational data
pmc := make([]netutils.PortBinding, 0, len(ep.portMapping))
pmc := make([]types.PortBinding, 0, len(ep.portMapping))
for _, pm := range ep.portMapping {
pmc = append(pmc, pm.GetCopy())
}
@ -861,7 +861,7 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*EndpointConfigurat
}
if opt, ok := epOptions[netlabel.PortMap]; ok {
if bs, ok := opt.([]netutils.PortBinding); ok {
if bs, ok := opt.([]types.PortBinding); ok {
ec.PortBindings = bs
} else {
return nil, ErrInvalidEndpointConfig
@ -869,7 +869,7 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*EndpointConfigurat
}
if opt, ok := epOptions[netlabel.ExposedPorts]; ok {
if ports, ok := opt.([]netutils.TransportPort); ok {
if ports, ok := opt.([]types.TransportPort); ok {
ec.ExposedPorts = ports
} else {
return nil, ErrInvalidEndpointConfig

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/libnetwork/iptables"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
)
@ -202,7 +203,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
if !ok {
t.Fatalf("Endpoint operational data does not contain port mapping data")
}
pm, ok := pmd.([]netutils.PortBinding)
pm, ok := pmd.([]types.PortBinding)
if !ok {
t.Fatalf("Unexpected format for port mapping in endpoint operational data")
}
@ -261,19 +262,19 @@ func TestCreateLinkWithOptions(t *testing.T) {
}
}
func getExposedPorts() []netutils.TransportPort {
return []netutils.TransportPort{
netutils.TransportPort{Proto: netutils.TCP, Port: uint16(5000)},
netutils.TransportPort{Proto: netutils.UDP, Port: uint16(400)},
netutils.TransportPort{Proto: netutils.TCP, Port: uint16(600)},
func getExposedPorts() []types.TransportPort {
return []types.TransportPort{
types.TransportPort{Proto: types.TCP, Port: uint16(5000)},
types.TransportPort{Proto: types.UDP, Port: uint16(400)},
types.TransportPort{Proto: types.TCP, Port: uint16(600)},
}
}
func getPortMapping() []netutils.PortBinding {
return []netutils.PortBinding{
netutils.PortBinding{Proto: netutils.TCP, Port: uint16(230), HostPort: uint16(23000)},
netutils.PortBinding{Proto: netutils.UDP, Port: uint16(200), HostPort: uint16(22000)},
netutils.PortBinding{Proto: netutils.TCP, Port: uint16(120), HostPort: uint16(12000)},
func getPortMapping() []types.PortBinding {
return []types.PortBinding{
types.PortBinding{Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)},
types.PortBinding{Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)},
types.PortBinding{Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)},
}
}

View File

@ -6,13 +6,13 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/iptables"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/types"
)
type link struct {
parentIP string
childIP string
ports []netutils.TransportPort
ports []types.TransportPort
bridge string
}
@ -20,7 +20,7 @@ func (l *link) String() string {
return fmt.Sprintf("%s <-> %s [%v] on %s", l.parentIP, l.childIP, l.ports, l.bridge)
}
func newLink(parentIP, childIP string, ports []netutils.TransportPort, bridge string) *link {
func newLink(parentIP, childIP string, ports []types.TransportPort, bridge string) *link {
return &link{
childIP: childIP,
parentIP: parentIP,
@ -45,7 +45,7 @@ func (l *link) Disable() {
// that returns typed errors
}
func linkContainers(action, parentIP, childIP string, ports []netutils.TransportPort, bridge string,
func linkContainers(action, parentIP, childIP string, ports []types.TransportPort, bridge string,
ignoreErrors bool) error {
var nfAction iptables.Action

View File

@ -3,14 +3,14 @@ package bridge
import (
"testing"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/types"
)
func getPorts() []netutils.TransportPort {
return []netutils.TransportPort{
netutils.TransportPort{Proto: netutils.TCP, Port: uint16(5000)},
netutils.TransportPort{Proto: netutils.UDP, Port: uint16(400)},
netutils.TransportPort{Proto: netutils.TCP, Port: uint16(600)},
func getPorts() []types.TransportPort {
return []types.TransportPort{
types.TransportPort{Proto: types.TCP, Port: uint16(5000)},
types.TransportPort{Proto: types.UDP, Port: uint16(400)},
types.TransportPort{Proto: types.TCP, Port: uint16(600)},
}
}

View File

@ -7,15 +7,15 @@ import (
"net"
"github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/sandbox"
"github.com/docker/libnetwork/types"
)
var (
defaultBindingIP = net.IPv4(0, 0, 0, 0)
)
func allocatePorts(epConfig *EndpointConfiguration, intf *sandbox.Interface, reqDefBindIP net.IP, ulPxyEnabled bool) ([]netutils.PortBinding, error) {
func allocatePorts(epConfig *EndpointConfiguration, intf *sandbox.Interface, reqDefBindIP net.IP, ulPxyEnabled bool) ([]types.PortBinding, error) {
if epConfig == nil || epConfig.PortBindings == nil {
return nil, nil
}
@ -28,8 +28,8 @@ func allocatePorts(epConfig *EndpointConfiguration, intf *sandbox.Interface, req
return allocatePortsInternal(epConfig.PortBindings, intf.Address.IP, defHostIP, ulPxyEnabled)
}
func allocatePortsInternal(bindings []netutils.PortBinding, containerIP, defHostIP net.IP, ulPxyEnabled bool) ([]netutils.PortBinding, error) {
bs := make([]netutils.PortBinding, 0, len(bindings))
func allocatePortsInternal(bindings []types.PortBinding, containerIP, defHostIP net.IP, ulPxyEnabled bool) ([]types.PortBinding, error) {
bs := make([]types.PortBinding, 0, len(bindings))
for _, c := range bindings {
b := c.GetCopy()
if err := allocatePort(&b, containerIP, defHostIP, ulPxyEnabled); err != nil {
@ -44,7 +44,7 @@ func allocatePortsInternal(bindings []netutils.PortBinding, containerIP, defHost
return bs, nil
}
func allocatePort(bnd *netutils.PortBinding, containerIP, defHostIP net.IP, ulPxyEnabled bool) error {
func allocatePort(bnd *types.PortBinding, containerIP, defHostIP net.IP, ulPxyEnabled bool) error {
var (
host net.Addr
err error
@ -98,7 +98,7 @@ func releasePorts(ep *bridgeEndpoint) error {
return releasePortsInternal(ep.portMapping)
}
func releasePortsInternal(bindings []netutils.PortBinding) error {
func releasePortsInternal(bindings []types.PortBinding) error {
var errorBuf bytes.Buffer
// Attempt to release all port bindings, do not stop on failure
@ -114,7 +114,7 @@ func releasePortsInternal(bindings []netutils.PortBinding) error {
return nil
}
func releasePort(bnd netutils.PortBinding) error {
func releasePort(bnd types.PortBinding) error {
// Construct the host side transport address
host, err := bnd.HostAddr()
if err != nil {

View File

@ -7,6 +7,7 @@ import (
"github.com/docker/docker/pkg/reexec"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/types"
)
func TestMain(m *testing.M) {
@ -20,9 +21,9 @@ func TestPortMappingConfig(t *testing.T) {
defer netutils.SetupTestNetNS(t)()
d := newDriver()
binding1 := netutils.PortBinding{Proto: netutils.UDP, Port: uint16(400), HostPort: uint16(54000)}
binding2 := netutils.PortBinding{Proto: netutils.TCP, Port: uint16(500), HostPort: uint16(65000)}
portBindings := []netutils.PortBinding{binding1, binding2}
binding1 := types.PortBinding{Proto: types.UDP, Port: uint16(400), HostPort: uint16(54000)}
binding2 := types.PortBinding{Proto: types.TCP, Port: uint16(500), HostPort: uint16(65000)}
portBindings := []types.PortBinding{binding1, binding2}
epOptions := make(map[string]interface{})
epOptions[netlabel.PortMap] = portBindings

View File

@ -12,7 +12,6 @@ import (
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/libnetwork/etchosts"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/resolvconf"
"github.com/docker/libnetwork/sandbox"
"github.com/docker/libnetwork/types"
@ -106,7 +105,7 @@ type endpoint struct {
iFaces []*endpointInterface
joinInfo *endpointJoinInfo
container *containerInfo
exposedPorts []netutils.TransportPort
exposedPorts []types.TransportPort
generic map[string]interface{}
joinLeaveDone chan struct{}
sync.Mutex
@ -697,10 +696,10 @@ func JoinOptionUseDefaultSandbox() EndpointOption {
// CreateOptionExposedPorts function returns an option setter for the container exposed
// ports option to be passed to network.CreateEndpoint() method.
func CreateOptionExposedPorts(exposedPorts []netutils.TransportPort) EndpointOption {
func CreateOptionExposedPorts(exposedPorts []types.TransportPort) EndpointOption {
return func(ep *endpoint) {
// Defensive copy
eps := make([]netutils.TransportPort, len(exposedPorts))
eps := make([]types.TransportPort, len(exposedPorts))
copy(eps, exposedPorts)
// Store endpoint label and in generic because driver needs it
ep.exposedPorts = eps
@ -710,10 +709,10 @@ func CreateOptionExposedPorts(exposedPorts []netutils.TransportPort) EndpointOpt
// CreateOptionPortMapping function returns an option setter for the mapping
// ports option to be passed to network.CreateEndpoint() method.
func CreateOptionPortMapping(portBindings []netutils.PortBinding) EndpointOption {
func CreateOptionPortMapping(portBindings []types.PortBinding) EndpointOption {
return func(ep *endpoint) {
// Store a copy of the bindings as generic data to pass to the driver
pbs := make([]netutils.PortBinding, len(portBindings))
pbs := make([]types.PortBinding, len(portBindings))
copy(pbs, portBindings)
ep.generic[netlabel.PortMap] = pbs
}

View File

@ -4,7 +4,7 @@ import (
"net"
"github.com/docker/libnetwork/driverapi"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/types"
)
// EndpointInfo provides an interface to retrieve network resources bound to the endpoint.
@ -105,10 +105,10 @@ func (ep *endpoint) AddInterface(id int, mac net.HardwareAddr, ipv4 net.IPNet, i
iface := &endpointInterface{
id: id,
addr: *netutils.GetIPNetCopy(&ipv4),
addrv6: *netutils.GetIPNetCopy(&ipv6),
addr: *types.GetIPNetCopy(&ipv4),
addrv6: *types.GetIPNetCopy(&ipv6),
}
iface.mac = netutils.GetMacCopy(mac)
iface.mac = types.GetMacCopy(mac)
ep.iFaces = append(ep.iFaces, iface)
return nil
@ -119,15 +119,15 @@ func (i *endpointInterface) ID() int {
}
func (i *endpointInterface) MacAddress() net.HardwareAddr {
return netutils.GetMacCopy(i.mac)
return types.GetMacCopy(i.mac)
}
func (i *endpointInterface) Address() net.IPNet {
return (*netutils.GetIPNetCopy(&i.addr))
return (*types.GetIPNetCopy(&i.addr))
}
func (i *endpointInterface) AddressIPv6() net.IPNet {
return (*netutils.GetIPNetCopy(&i.addrv6))
return (*types.GetIPNetCopy(&i.addrv6))
}
func (i *endpointInterface) SetNames(srcName string, dstName string) error {
@ -168,7 +168,7 @@ func (ep *endpoint) Gateway() net.IP {
return net.IP{}
}
return netutils.GetIPCopy(ep.joinInfo.gw)
return types.GetIPCopy(ep.joinInfo.gw)
}
func (ep *endpoint) GatewayIPv6() net.IP {
@ -179,14 +179,14 @@ func (ep *endpoint) GatewayIPv6() net.IP {
return net.IP{}
}
return netutils.GetIPCopy(ep.joinInfo.gw6)
return types.GetIPCopy(ep.joinInfo.gw6)
}
func (ep *endpoint) SetGateway(gw net.IP) error {
ep.Lock()
defer ep.Unlock()
ep.joinInfo.gw = netutils.GetIPCopy(gw)
ep.joinInfo.gw = types.GetIPCopy(gw)
return nil
}
@ -194,7 +194,7 @@ func (ep *endpoint) SetGatewayIPv6(gw6 net.IP) error {
ep.Lock()
defer ep.Unlock()
ep.joinInfo.gw6 = netutils.GetIPCopy(gw6)
ep.joinInfo.gw6 = types.GetIPCopy(gw6)
return nil
}

View File

@ -22,6 +22,7 @@ import (
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netns"
)
@ -65,11 +66,11 @@ func getEmptyGenericOption() map[string]interface{} {
return genericOption
}
func getPortMapping() []netutils.PortBinding {
return []netutils.PortBinding{
netutils.PortBinding{Proto: netutils.TCP, Port: uint16(230), HostPort: uint16(23000)},
netutils.PortBinding{Proto: netutils.UDP, Port: uint16(200), HostPort: uint16(22000)},
netutils.PortBinding{Proto: netutils.TCP, Port: uint16(120), HostPort: uint16(12000)},
func getPortMapping() []types.PortBinding {
return []types.PortBinding{
types.PortBinding{Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)},
types.PortBinding{Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)},
types.PortBinding{Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)},
}
}
@ -245,7 +246,7 @@ func TestBridge(t *testing.T) {
if !ok {
t.Fatalf("Could not find expected info in endpoint data")
}
pm, ok := pmd.([]netutils.PortBinding)
pm, ok := pmd.([]types.PortBinding)
if !ok {
t.Fatalf("Unexpected format for port mapping in endpoint operational data")
}

View File

@ -3,14 +3,12 @@
package netutils
import (
"bytes"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"net"
"strings"
"github.com/vishvananda/netlink"
)
@ -26,144 +24,6 @@ var (
networkGetRoutesFct = netlink.RouteList
)
// ErrInvalidProtocolBinding is returned when the port binding protocol is not valid.
type ErrInvalidProtocolBinding string
func (ipb ErrInvalidProtocolBinding) Error() string {
return fmt.Sprintf("invalid transport protocol: %s", string(ipb))
}
// TransportPort represent a local Layer 4 endpoint
type TransportPort struct {
Proto Protocol
Port uint16
}
// GetCopy returns a copy of this TransportPort structure instance
func (t *TransportPort) GetCopy() TransportPort {
return TransportPort{Proto: t.Proto, Port: t.Port}
}
// PortBinding represent a port binding between the container an the host
type PortBinding struct {
Proto Protocol
IP net.IP
Port uint16
HostIP net.IP
HostPort uint16
}
// HostAddr returns the host side transport address
func (p PortBinding) HostAddr() (net.Addr, error) {
switch p.Proto {
case UDP:
return &net.UDPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
case TCP:
return &net.TCPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
default:
return nil, ErrInvalidProtocolBinding(p.Proto.String())
}
}
// ContainerAddr returns the container side transport address
func (p PortBinding) ContainerAddr() (net.Addr, error) {
switch p.Proto {
case UDP:
return &net.UDPAddr{IP: p.IP, Port: int(p.Port)}, nil
case TCP:
return &net.TCPAddr{IP: p.IP, Port: int(p.Port)}, nil
default:
return nil, ErrInvalidProtocolBinding(p.Proto.String())
}
}
// GetCopy returns a copy of this PortBinding structure instance
func (p *PortBinding) GetCopy() PortBinding {
return PortBinding{
Proto: p.Proto,
IP: GetIPCopy(p.IP),
Port: p.Port,
HostIP: GetIPCopy(p.HostIP),
HostPort: p.HostPort,
}
}
// Equal checks if this instance of PortBinding is equal to the passed one
func (p *PortBinding) Equal(o *PortBinding) bool {
if p == o {
return true
}
if o == nil {
return false
}
if p.Proto != o.Proto || p.Port != o.Port || p.HostPort != o.HostPort {
return false
}
if p.IP != nil {
if !p.IP.Equal(o.IP) {
return false
}
} else {
if o.IP != nil {
return false
}
}
if p.HostIP != nil {
if !p.HostIP.Equal(o.HostIP) {
return false
}
} else {
if o.HostIP != nil {
return false
}
}
return true
}
const (
// ICMP is for the ICMP ip protocol
ICMP = 1
// TCP is for the TCP ip protocol
TCP = 6
// UDP is for the UDP ip protocol
UDP = 17
)
// Protocol represents a IP protocol number
type Protocol uint8
func (p Protocol) String() string {
switch p {
case ICMP:
return "icmp"
case TCP:
return "tcp"
case UDP:
return "udp"
default:
return fmt.Sprintf("%d", p)
}
}
// ParseProtocol returns the respective Protocol type for the passed string
func ParseProtocol(s string) Protocol {
switch strings.ToLower(s) {
case "icmp":
return ICMP
case "udp":
return UDP
case "tcp":
return TCP
default:
return 0
}
}
// CheckNameserverOverlaps checks whether the passed network overlaps with any of the nameservers
func CheckNameserverOverlaps(nameservers []string, toCheck *net.IPNet) error {
if len(nameservers) > 0 {
@ -287,38 +147,3 @@ func GenerateRandomName(prefix string, size int) (string, error) {
}
return prefix + hex.EncodeToString(id)[:size], nil
}
// GetMacCopy returns a copy of the passed MAC address
func GetMacCopy(from net.HardwareAddr) net.HardwareAddr {
to := make(net.HardwareAddr, len(from))
copy(to, from)
return to
}
// GetIPCopy returns a copy of the passed IP address
func GetIPCopy(from net.IP) net.IP {
to := make(net.IP, len(from))
copy(to, from)
return to
}
// GetIPNetCopy returns a copy of the passed IP Network
func GetIPNetCopy(from *net.IPNet) *net.IPNet {
if from == nil {
return nil
}
bm := make(net.IPMask, len(from.Mask))
copy(bm, from.Mask)
return &net.IPNet{IP: GetIPCopy(from.IP), Mask: bm}
}
// CompareIPNet returns equal if the two IP Networks are equal
func CompareIPNet(a, b *net.IPNet) bool {
if a == b {
return true
}
if a == nil || b == nil {
return false
}
return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask)
}

View File

@ -209,135 +209,3 @@ func TestUtilGenerateRandomMAC(t *testing.T) {
t.Fatalf("mac1 %s should not equal mac2 %s", mac1, mac2)
}
}
func TestCompareIPNet(t *testing.T) {
if CompareIPNet(nil, nil) == false {
t.Fatalf("Failed to detect two nil net.IPNets are equal")
}
_, net1, _ := net.ParseCIDR("192.168.30.22/24")
if CompareIPNet(net1, net1) == false {
t.Fatalf("Failed to detect same net.IPNet pointers equality")
}
_, net2, _ := net.ParseCIDR("192.168.30.22/24")
if CompareIPNet(net1, net2) == false {
t.Fatalf("Failed to detect same net.IPNet object equality")
}
_, net3, _ := net.ParseCIDR("192.168.30.33/24")
if CompareIPNet(net1, net3) == false {
t.Fatalf("Failed to detect semantically equivalent net.IPNets")
}
_, net3, _ = net.ParseCIDR("192.168.31.33/24")
if CompareIPNet(net2, net3) == true {
t.Fatalf("Failed to detect different net.IPNets")
}
}
func TestIPCopyFunctions(t *testing.T) {
ip := net.ParseIP("172.28.30.134")
cp := GetIPCopy(ip)
if !ip.Equal(cp) {
t.Fatalf("Failed to return a copy of net.IP")
}
if &ip == &cp {
t.Fatalf("Failed to return a true copy of net.IP")
}
}
func TestNetIPCopyFunctions(t *testing.T) {
_, net, _ := net.ParseCIDR("192.168.30.23/24")
cp := GetIPNetCopy(net)
if CompareIPNet(net, cp) == false {
t.Fatalf("Failed to return a copy of net.IPNet")
}
if net == cp {
t.Fatalf("Failed to return a true copy of net.IPNet")
}
}
func TestPortBindingEqual(t *testing.T) {
pb1 := &PortBinding{
Proto: TCP,
IP: net.ParseIP("172.17.0.1"),
Port: 80,
HostIP: net.ParseIP("192.168.100.1"),
HostPort: 8080,
}
pb2 := &PortBinding{
Proto: UDP,
IP: net.ParseIP("172.17.0.1"),
Port: 22,
HostIP: net.ParseIP("192.168.100.1"),
HostPort: 2222,
}
if !pb1.Equal(pb1) {
t.Fatalf("PortBinding.Equal() returned false negative")
}
if pb1.Equal(nil) {
t.Fatalf("PortBinding.Equal() returned false negative")
}
if pb1.Equal(pb2) {
t.Fatalf("PortBinding.Equal() returned false positive")
}
if pb1.Equal(pb2) != pb2.Equal(pb1) {
t.Fatalf("PortBinding.Equal() failed commutative check")
}
}
func TestPortBindingGetCopy(t *testing.T) {
pb := &PortBinding{
Proto: TCP,
IP: net.ParseIP("172.17.0.1"),
Port: 80,
HostIP: net.ParseIP("192.168.100.1"),
HostPort: 8080,
}
cp := pb.GetCopy()
if !pb.Equal(&cp) {
t.Fatalf("Failed to return a copy of PortBinding")
}
if pb == &cp {
t.Fatalf("Failed to return a true copy of PortBinding")
}
}
func TestPortBindingContainerAddr(t *testing.T) {
pb := PortBinding{
Proto: TCP,
IP: net.ParseIP("172.17.0.1"),
Port: 80,
HostIP: net.ParseIP("192.168.100.1"),
HostPort: 8080,
}
container, err := pb.ContainerAddr()
if err != nil {
t.Fatal(err)
}
switch netAddr := container.(type) {
case *net.TCPAddr:
if !pb.IP.Equal(netAddr.IP) {
t.Fatalf("PortBinding.ContainerAddr() Failed to return a ContainerAddr")
}
if int(pb.Port) != netAddr.Port {
t.Fatalf("PortBinding.ContainerAddr() Failed to return a ContainerAddr")
}
case *net.UDPAddr:
t.Fatalf("PortBinding.ContainerAddr() Failed to check correct proto")
}
}

View File

@ -3,7 +3,7 @@ package sandbox
import (
"net"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/types"
)
// Sandbox represents a network sandbox, identified by a specific key. It
@ -77,8 +77,8 @@ func (i *Interface) GetCopy() *Interface {
return &Interface{
SrcName: i.SrcName,
DstName: i.DstName,
Address: netutils.GetIPNetCopy(i.Address),
AddressIPv6: netutils.GetIPNetCopy(i.AddressIPv6),
Address: types.GetIPNetCopy(i.Address),
AddressIPv6: types.GetIPNetCopy(i.AddressIPv6),
}
}
@ -96,11 +96,11 @@ func (i *Interface) Equal(o *Interface) bool {
return false
}
if !netutils.CompareIPNet(i.Address, o.Address) {
if !types.CompareIPNet(i.Address, o.Address) {
return false
}
if !netutils.CompareIPNet(i.AddressIPv6, o.AddressIPv6) {
if !types.CompareIPNet(i.AddressIPv6, o.AddressIPv6) {
return false
}
@ -113,8 +113,8 @@ func (s *Info) GetCopy() *Info {
for i, iface := range s.Interfaces {
list[i] = iface.GetCopy()
}
gw := netutils.GetIPCopy(s.Gateway)
gw6 := netutils.GetIPCopy(s.GatewayIPv6)
gw := types.GetIPCopy(s.Gateway)
gw6 := types.GetIPCopy(s.GatewayIPv6)
return &Info{Interfaces: list, Gateway: gw, GatewayIPv6: gw6}
}

View File

@ -1,5 +1,185 @@
// Package types contains types that are common across libnetwork project
package types
import (
"bytes"
"fmt"
"net"
"strings"
)
// UUID represents a globally unique ID of various resources like network and endpoint
type UUID string
// ErrInvalidProtocolBinding is returned when the port binding protocol is not valid.
type ErrInvalidProtocolBinding string
func (ipb ErrInvalidProtocolBinding) Error() string {
return fmt.Sprintf("invalid transport protocol: %s", string(ipb))
}
// TransportPort represent a local Layer 4 endpoint
type TransportPort struct {
Proto Protocol
Port uint16
}
// GetCopy returns a copy of this TransportPort structure instance
func (t *TransportPort) GetCopy() TransportPort {
return TransportPort{Proto: t.Proto, Port: t.Port}
}
// PortBinding represent a port binding between the container an the host
type PortBinding struct {
Proto Protocol
IP net.IP
Port uint16
HostIP net.IP
HostPort uint16
}
// HostAddr returns the host side transport address
func (p PortBinding) HostAddr() (net.Addr, error) {
switch p.Proto {
case UDP:
return &net.UDPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
case TCP:
return &net.TCPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
default:
return nil, ErrInvalidProtocolBinding(p.Proto.String())
}
}
// ContainerAddr returns the container side transport address
func (p PortBinding) ContainerAddr() (net.Addr, error) {
switch p.Proto {
case UDP:
return &net.UDPAddr{IP: p.IP, Port: int(p.Port)}, nil
case TCP:
return &net.TCPAddr{IP: p.IP, Port: int(p.Port)}, nil
default:
return nil, ErrInvalidProtocolBinding(p.Proto.String())
}
}
// GetCopy returns a copy of this PortBinding structure instance
func (p *PortBinding) GetCopy() PortBinding {
return PortBinding{
Proto: p.Proto,
IP: GetIPCopy(p.IP),
Port: p.Port,
HostIP: GetIPCopy(p.HostIP),
HostPort: p.HostPort,
}
}
// Equal checks if this instance of PortBinding is equal to the passed one
func (p *PortBinding) Equal(o *PortBinding) bool {
if p == o {
return true
}
if o == nil {
return false
}
if p.Proto != o.Proto || p.Port != o.Port || p.HostPort != o.HostPort {
return false
}
if p.IP != nil {
if !p.IP.Equal(o.IP) {
return false
}
} else {
if o.IP != nil {
return false
}
}
if p.HostIP != nil {
if !p.HostIP.Equal(o.HostIP) {
return false
}
} else {
if o.HostIP != nil {
return false
}
}
return true
}
const (
// ICMP is for the ICMP ip protocol
ICMP = 1
// TCP is for the TCP ip protocol
TCP = 6
// UDP is for the UDP ip protocol
UDP = 17
)
// Protocol represents a IP protocol number
type Protocol uint8
func (p Protocol) String() string {
switch p {
case ICMP:
return "icmp"
case TCP:
return "tcp"
case UDP:
return "udp"
default:
return fmt.Sprintf("%d", p)
}
}
// ParseProtocol returns the respective Protocol type for the passed string
func ParseProtocol(s string) Protocol {
switch strings.ToLower(s) {
case "icmp":
return ICMP
case "udp":
return UDP
case "tcp":
return TCP
default:
return 0
}
}
// GetMacCopy returns a copy of the passed MAC address
func GetMacCopy(from net.HardwareAddr) net.HardwareAddr {
to := make(net.HardwareAddr, len(from))
copy(to, from)
return to
}
// GetIPCopy returns a copy of the passed IP address
func GetIPCopy(from net.IP) net.IP {
to := make(net.IP, len(from))
copy(to, from)
return to
}
// GetIPNetCopy returns a copy of the passed IP Network
func GetIPNetCopy(from *net.IPNet) *net.IPNet {
if from == nil {
return nil
}
bm := make(net.IPMask, len(from.Mask))
copy(bm, from.Mask)
return &net.IPNet{IP: GetIPCopy(from.IP), Mask: bm}
}
// CompareIPNet returns equal if the two IP Networks are equal
func CompareIPNet(a, b *net.IPNet) bool {
if a == b {
return true
}
if a == nil || b == nil {
return false
}
return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask)
}