mirror of
https://github.com/containers/podman.git
synced 2025-06-22 09:58:10 +08:00
@ -71,14 +71,44 @@ func createPortBindings(ports []string) ([]specgen.PortMapping, error) {
|
||||
return nil, errors.Errorf("invalid port format - protocol can only be specified once")
|
||||
}
|
||||
|
||||
splitPort := strings.Split(splitProto[0], ":")
|
||||
remainder := splitProto[0]
|
||||
haveV6 := false
|
||||
|
||||
// Check for an IPv6 address in brackets
|
||||
splitV6 := strings.Split(remainder, "]")
|
||||
switch len(splitV6) {
|
||||
case 1:
|
||||
// Do nothing, proceed as before
|
||||
case 2:
|
||||
// We potentially have an IPv6 address
|
||||
haveV6 = true
|
||||
if !strings.HasPrefix(splitV6[0], "[") {
|
||||
return nil, errors.Errorf("invalid port format - IPv6 addresses must be enclosed by []")
|
||||
}
|
||||
if !strings.HasPrefix(splitV6[1], ":") {
|
||||
return nil, errors.Errorf("invalid port format - IPv6 address must be followed by a colon (':')")
|
||||
}
|
||||
ipNoPrefix := strings.TrimPrefix(splitV6[0], "[")
|
||||
hostIP = &ipNoPrefix
|
||||
remainder = strings.TrimPrefix(splitV6[1], ":")
|
||||
default:
|
||||
return nil, errors.Errorf("invalid port format - at most one IPv6 address can be specified in a --publish")
|
||||
}
|
||||
|
||||
splitPort := strings.Split(remainder, ":")
|
||||
switch len(splitPort) {
|
||||
case 1:
|
||||
if haveV6 {
|
||||
return nil, errors.Errorf("invalid port format - must provide host and destination port if specifying an IP")
|
||||
}
|
||||
ctrPort = splitPort[0]
|
||||
case 2:
|
||||
hostPort = &(splitPort[0])
|
||||
ctrPort = splitPort[1]
|
||||
case 3:
|
||||
if haveV6 {
|
||||
return nil, errors.Errorf("invalid port format - when v6 address specified, must be [ipv6]:hostPort:ctrPort")
|
||||
}
|
||||
hostIP = &(splitPort[0])
|
||||
hostPort = &(splitPort[1])
|
||||
ctrPort = splitPort[2]
|
||||
|
@ -36,14 +36,30 @@ func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) {
|
||||
var files []*os.File
|
||||
notifySCTP := false
|
||||
for _, i := range ports {
|
||||
isV6 := net.ParseIP(i.HostIP).To4() == nil
|
||||
if i.HostIP == "" {
|
||||
isV6 = false
|
||||
}
|
||||
switch i.Protocol {
|
||||
case "udp":
|
||||
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort))
|
||||
var (
|
||||
addr *net.UDPAddr
|
||||
err error
|
||||
)
|
||||
if isV6 {
|
||||
addr, err = net.ResolveUDPAddr("udp6", fmt.Sprintf("[%s]:%d", i.HostIP, i.HostPort))
|
||||
} else {
|
||||
addr, err = net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot resolve the UDP address")
|
||||
}
|
||||
|
||||
server, err := net.ListenUDP("udp", addr)
|
||||
proto := "udp4"
|
||||
if isV6 {
|
||||
proto = "udp6"
|
||||
}
|
||||
server, err := net.ListenUDP(proto, addr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot listen on the UDP port")
|
||||
}
|
||||
@ -54,12 +70,24 @@ func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) {
|
||||
files = append(files, f)
|
||||
|
||||
case "tcp":
|
||||
addr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort))
|
||||
var (
|
||||
addr *net.TCPAddr
|
||||
err error
|
||||
)
|
||||
if isV6 {
|
||||
addr, err = net.ResolveTCPAddr("tcp6", fmt.Sprintf("[%s]:%d", i.HostIP, i.HostPort))
|
||||
} else {
|
||||
addr, err = net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot resolve the TCP address")
|
||||
}
|
||||
|
||||
server, err := net.ListenTCP("tcp4", addr)
|
||||
proto := "tcp4"
|
||||
if isV6 {
|
||||
proto = "tcp6"
|
||||
}
|
||||
server, err := net.ListenTCP(proto, addr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot listen on the TCP port")
|
||||
}
|
||||
|
@ -129,6 +129,32 @@ var _ = Describe("Podman run networking", func() {
|
||||
Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("127.0.0.1"))
|
||||
})
|
||||
|
||||
It("podman run -p [::1]:8080:80/udp", func() {
|
||||
name := "testctr"
|
||||
session := podmanTest.Podman([]string{"create", "-t", "-p", "[::1]:8080:80/udp", "--name", name, ALPINE, "/bin/sh"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
inspectOut := podmanTest.InspectContainer(name)
|
||||
Expect(len(inspectOut)).To(Equal(1))
|
||||
Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1))
|
||||
Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(8080)))
|
||||
Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80)))
|
||||
Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("udp"))
|
||||
Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("::1"))
|
||||
})
|
||||
|
||||
It("podman run -p [::1]:8080:80/tcp", func() {
|
||||
name := "testctr"
|
||||
session := podmanTest.Podman([]string{"create", "-t", "-p", "[::1]:8080:80/tcp", "--name", name, ALPINE, "/bin/sh"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
inspectOut := podmanTest.InspectContainer(name)
|
||||
Expect(len(inspectOut)).To(Equal(1))
|
||||
Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1))
|
||||
Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(8080)))
|
||||
Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80)))
|
||||
Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("tcp"))
|
||||
Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("::1"))
|
||||
})
|
||||
|
||||
It("podman run --expose 80 -P", func() {
|
||||
name := "testctr"
|
||||
session := podmanTest.Podman([]string{"create", "-t", "--expose", "80", "-P", "--name", name, ALPINE, "/bin/sh"})
|
||||
|
Reference in New Issue
Block a user