Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
strategy:
fail-fast: false
matrix:
go: ["1.18.x", "oldstable", "stable"]
go: ["oldstable", "stable"]
platform: [ubuntu-24.04]
runs-on: ${{ matrix.platform }}
steps:
Expand All @@ -48,7 +48,7 @@ jobs:
strategy:
fail-fast: false
matrix:
go: ["1.18.x", "oldstable", "stable"]
go: ["oldstable", "stable"]
platform: [windows-latest, macos-latest]
runs-on: ${{ matrix.platform }}
steps:
Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
module github.com/docker/go-connections

go 1.18
go 1.23.0

require github.com/Microsoft/go-winio v0.4.21
require (
github.com/Microsoft/go-winio v0.4.21
github.com/moby/moby/api v1.52.0-beta.1.0.20251007000938-19e498ea6522
)

require golang.org/x/sys v0.1.0 // indirect
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
github.com/Microsoft/go-winio v0.4.21 h1:+6mVbXh4wPzUrl1COX9A+ZCvEpYsOBZ6/+kwDnvLyro=
github.com/Microsoft/go-winio v0.4.21/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/moby/moby/api v1.52.0-beta.1.0.20251007000938-19e498ea6522 h1:bLoNdDBj+gro5RVsCOg5rQQ5MZQrrtxUuYMllhCtkaU=
github.com/moby/moby/api v1.52.0-beta.1.0.20251007000938-19e498ea6522/go.mod h1:/ou52HkRydg4+odrUR3vFsGgjIyHvprrpEQEkweL10s=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
Expand All @@ -9,3 +13,5 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
91 changes: 53 additions & 38 deletions nat/nat.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,42 @@ import (
"errors"
"fmt"
"net"
"net/netip"
"strconv"
"strings"

"github.com/moby/moby/api/types/network"
)

// PortBinding represents a binding between a Host IP address and a Host Port
type PortBinding struct {
// HostIP is the host IP Address
HostIP string `json:"HostIp"`
// HostPort is the host port number
HostPort string
}
//
// Deprecated: Use [network.PortBinding] instead.
type PortBinding = network.PortBinding

// PortMap is a collection of PortBinding indexed by Port
type PortMap map[Port][]PortBinding
//
// Deprecated: Use [network.PortMap] instead.
type PortMap = network.PortMap

// PortSet is a collection of structs indexed by Port
type PortSet map[Port]struct{}
//
// Deprecated: Use [network.PortSet] instead.
type PortSet = network.PortSet

// Port is a string containing port number and protocol in the format "80/tcp"
type Port string
//
// Deprecated: Use [network.Port] or [network.PortRange] accordingly instead.
type Port struct {
network.PortRange
}

// NewPort creates a new instance of a Port given a protocol and port number or port range
func NewPort(proto, portOrRange string) (Port, error) {
start, end, err := parsePortRange(portOrRange)
pr, err := network.ParsePortRange(portOrRange + "/" + proto)
if err != nil {
return "", err
return Port{}, err
}
if start == end {
return Port(fmt.Sprintf("%d/%s", start, proto)), nil
}
return Port(fmt.Sprintf("%d-%d/%s", start, end, proto)), nil
return Port{pr}, nil
}

// ParsePort parses the port number string and returns an int
Expand All @@ -59,37 +64,20 @@ func ParsePortRangeToInt(rawPort string) (startPort, endPort int, _ error) {
return parsePortRange(rawPort)
}

// Proto returns the protocol of a Port
func (p Port) Proto() string {
_, proto, _ := strings.Cut(string(p), "/")
if proto == "" {
proto = "tcp"
}
return proto
}

// Port returns the port number of a Port
func (p Port) Port() string {
port, _, _ := strings.Cut(string(p), "/")
return port
return fmt.Sprintf("%d", p.Start())
}

// Int returns the port number of a Port as an int. It assumes [Port]
// is valid, and returns 0 otherwise.
func (p Port) Int() int {
// We don't need to check for an error because we're going to
// assume that any error would have been found, and reported, in [NewPort]
port, _ := parsePortNumber(p.Port())
return port
return int(p.Start())
}

// Range returns the start/end port numbers of a Port range as ints
func (p Port) Range() (int, int, error) {
portRange := p.Port()
if portRange == "" {
return 0, 0, nil
}
return parsePortRange(portRange)
return int(p.Start()), int(p.End()), nil
}

// SplitProtoPort splits a port(range) and protocol, formatted as "<portnum>/[<proto>]"
Expand Down Expand Up @@ -144,13 +132,21 @@ func ParsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding,
}

// PortMapping is a data object mapping a Port to a PortBinding
//
// Deprecated: Use [network.PortMap] instead.
type PortMapping struct {
Port Port
Binding PortBinding
}

func (p *PortMapping) String() string {
return net.JoinHostPort(p.Binding.HostIP, p.Binding.HostPort+":"+string(p.Port))
var host string

if p.Binding.HostIP != netip.IPv4Unspecified() {
host = p.Binding.HostIP.String()
}

return net.JoinHostPort(host, p.Binding.HostPort+":"+p.Port.String())
}

func splitParts(rawport string) (hostIP, hostPort, containerPort string) {
Expand Down Expand Up @@ -228,9 +224,28 @@ func ParsePortSpec(rawPort string) ([]PortMapping, error) {
hPort += "-" + strconv.Itoa(endHostPort)
}
}
port, err := network.ParsePortRange(fmt.Sprintf("%d/%s", startPort+i, proto))
if err != nil {
return nil, err
}

var addr netip.Addr
if strings.Count(ip, ":") >= 2 {
addr = netip.IPv6Unspecified()
} else {
addr = netip.IPv4Unspecified()
}

if ip != "" {
addr, err = netip.ParseAddr(ip)
if err != nil {
return nil, err
}
}

ports = append(ports, PortMapping{
Port: Port(strconv.Itoa(startPort+i) + "/" + proto),
Binding: PortBinding{HostIP: ip, HostPort: hPort},
Port: Port{port},
Binding: PortBinding{HostIP: addr, HostPort: hPort},
})
}
return ports, nil
Expand Down
Loading
Loading