From e88d8dbeae2aebd2d816f16a21891764163afcd4 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Fri, 30 Jul 2021 14:33:08 +0200 Subject: fix rootless port forwarding with network dis-/connect The rootlessport forwarder requires a child IP to be set. This must be a valid ip in the container network namespace. The problem is that after a network disconnect and connect the eth0 ip changed. Therefore the packages are dropped since the source ip does no longer exists in the netns. One solution is to set the child IP to 127.0.0.1, however this is a security problem. [1] To fix this we have to recreate the ports after network connect and disconnect. To make this work the rootlessport process exposes a socket where podman network connect/disconnect connect to and send to new child IP to rootlessport. The rootlessport process will remove all ports and recreate them with the new correct child IP. Also bump rootlesskit to v0.14.3 to fix a race with RemovePort(). Fixes #10052 [1] https://nvd.nist.gov/vuln/detail/CVE-2021-20199 Signed-off-by: Paul Holzinger --- docs/source/markdown/podman-network-connect.1.md | 2 - .../source/markdown/podman-network-disconnect.1.md | 5 +- docs/source/markdown/podman-network-reload.1.md | 2 - go.mod | 2 +- go.sum | 8 +- libpod/networking_linux.go | 35 ++++++++- libpod/networking_slirp4netns.go | 91 ++++++++++++++++------ pkg/rootlessport/rootlessport_linux.go | 79 +++++++++++++++++-- test/system/500-networking.bats | 85 ++++++++++++++++++++ .../rootlesskit/pkg/port/builtin/parent/parent.go | 10 ++- .../rootlesskit/pkg/port/builtin/parent/tcp/tcp.go | 7 +- .../rootlesskit/pkg/port/builtin/parent/udp/udp.go | 3 +- vendor/modules.txt | 2 +- 13 files changed, 284 insertions(+), 47 deletions(-) diff --git a/docs/source/markdown/podman-network-connect.1.md b/docs/source/markdown/podman-network-connect.1.md index cff4336d6..47a54bd33 100644 --- a/docs/source/markdown/podman-network-connect.1.md +++ b/docs/source/markdown/podman-network-connect.1.md @@ -10,8 +10,6 @@ podman\-network\-connect - Connect a container to a network Connects a container to a network. A container can be connected to a network by name or by ID. Once connected, the container can communicate with other containers in the same network. -This command is not available for rootless users. - ## OPTIONS #### **--alias** Add network-scoped alias for the container. If the network is using the `dnsname` CNI plugin, these aliases diff --git a/docs/source/markdown/podman-network-disconnect.1.md b/docs/source/markdown/podman-network-disconnect.1.md index 8b7125282..a13aa6088 100644 --- a/docs/source/markdown/podman-network-disconnect.1.md +++ b/docs/source/markdown/podman-network-disconnect.1.md @@ -7,9 +7,10 @@ podman\-network\-disconnect - Disconnect a container from a network **podman network disconnect** [*options*] network container ## DESCRIPTION -Disconnects a container from a network. +Disconnects a container from a network. A container can be disconnected from a network by name or by ID. +If all networks are disconnected from the container, it will behave like a container created with `--network=none` +and it will longer have network connectivity until a network is connected again. -This command is not available for rootless users. ## OPTIONS #### **--force**, **-f** diff --git a/docs/source/markdown/podman-network-reload.1.md b/docs/source/markdown/podman-network-reload.1.md index 1d9f34f2e..593265df6 100644 --- a/docs/source/markdown/podman-network-reload.1.md +++ b/docs/source/markdown/podman-network-reload.1.md @@ -13,8 +13,6 @@ Rootfull Podman relies on iptables rules in order to provide network connectivit this happens for example with `firewall-cmd --reload`, the container loses network connectivity. This command restores the network connectivity. -This command is not available for rootless users since rootless containers are not affected by such connectivity problems. - ## OPTIONS #### **--all**, **-a** diff --git a/go.mod b/go.mod index 623226c48..02d7a89d7 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/opencontainers/selinux v1.8.2 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 - github.com/rootless-containers/rootlesskit v0.14.2 + github.com/rootless-containers/rootlesskit v0.14.3 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 34ecb7f9c..f2c1ad631 100644 --- a/go.sum +++ b/go.sum @@ -403,7 +403,7 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6 github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -555,7 +555,6 @@ github.com/insomniacslk/dhcp v0.0.0-20210120172423-cc9239ac6294/go.mod h1:TKl4jN github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee h1:PAXLXk1heNZ5yokbMBpVLZQxo43wCZxRwl00mX+dd44= github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= -github.com/jamescun/tuntap v0.0.0-20190712092105-cb1fb277045c/go.mod h1:zzwpsgcYhzzIP5WyF8g9ivCv38cY9uAV9Gu0m3lThhE= github.com/jinzhu/copier v0.3.2 h1:QdBOCbaouLDYaIPFfi1bKv5F5tPpeTwXe4sD0jqtz5w= github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -812,8 +811,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rootless-containers/rootlesskit v0.14.2 h1:jmsSyNyRG0QdWc3usppt5jEy5qOheeUsIINcymPrOFg= -github.com/rootless-containers/rootlesskit v0.14.2/go.mod h1:nV3TpRISvwhZQSwo0nmQQnxjCxXr3mvrMi0oASLvzcg= +github.com/rootless-containers/rootlesskit v0.14.3 h1:mS6lkZgT1McqUoZ9wjUIbYq7bWfd9aZGUgZgg8B55Sk= +github.com/rootless-containers/rootlesskit v0.14.3/go.mod h1:Ai3detLzryb/4EkzXmNfh8aByUcBXp/qqkQusJs1SO8= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -839,6 +838,7 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 0f3e03e06..8e9b5997c 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -1214,7 +1214,29 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro } } c.state.NetworkStatus = tmpNetworkStatus - return c.save() + err = c.save() + if err != nil { + return err + } + + // OCICNI will set the loopback adpter down on teardown so we should set it up again + err = c.state.NetNS.Do(func(_ ns.NetNS) error { + link, err := netlink.LinkByName("lo") + if err != nil { + return err + } + err = netlink.LinkSetUp(link) + return err + }) + if err != nil { + logrus.Warnf("failed to set loopback adpter up in the container: %v", err) + } + // Reload ports when there are still connected networks, maybe we removed the network interface with the child ip. + // Reloading without connected networks does not make sense, so we can skip this step. + if rootless.IsRootless() && len(tmpNetworkStatus) > 0 { + return c.reloadRootlessRLKPortMapping() + } + return nil } // ConnectNetwork connects a container to a given network @@ -1306,7 +1328,16 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e networkStatus[index] = networkResults[0] c.state.NetworkStatus = networkStatus } - return c.save() + err = c.save() + if err != nil { + return err + } + // The first network needs a port reload to set the correct child ip for the rootlessport process. + // Adding a second network does not require a port reload because the child ip is still valid. + if rootless.IsRootless() && len(networks) == 0 { + return c.reloadRootlessRLKPortMapping() + } + return nil } // DisconnectContainerFromNetwork removes a container from its CNI network diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go index 410b377ec..5858364ff 100644 --- a/libpod/networking_slirp4netns.go +++ b/libpod/networking_slirp4netns.go @@ -17,6 +17,7 @@ import ( "time" "github.com/containers/podman/v3/pkg/errorhandling" + "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/rootlessport" "github.com/containers/podman/v3/pkg/servicereaper" "github.com/pkg/errors" @@ -466,29 +467,16 @@ func (r *Runtime) setupRootlessPortMappingViaRLK(ctr *Container, netnsPath strin } } - slirp4netnsIP, err := GetSlirp4netnsIP(ctr.slirp4netnsSubnet) - if err != nil { - return errors.Wrapf(err, "failed to get slirp4ns ip") - } - childIP := slirp4netnsIP.String() -outer: - for _, r := range ctr.state.NetworkStatus { - for _, i := range r.IPs { - ipv4 := i.Address.IP.To4() - if ipv4 != nil { - childIP = ipv4.String() - break outer - } - } - } - + childIP := getRootlessPortChildIP(ctr) cfg := rootlessport.Config{ - Mappings: ctr.config.PortMappings, - NetNSPath: netnsPath, - ExitFD: 3, - ReadyFD: 4, - TmpDir: ctr.runtime.config.Engine.TmpDir, - ChildIP: childIP, + Mappings: ctr.config.PortMappings, + NetNSPath: netnsPath, + ExitFD: 3, + ReadyFD: 4, + TmpDir: ctr.runtime.config.Engine.TmpDir, + ChildIP: childIP, + ContainerID: ctr.config.ID, + RootlessCNI: ctr.config.NetMode.IsBridge() && rootless.IsRootless(), } cfgJSON, err := json.Marshal(cfg) if err != nil { @@ -617,3 +605,62 @@ func (r *Runtime) setupRootlessPortMappingViaSlirp(ctr *Container, cmd *exec.Cmd logrus.Debug("slirp4netns port-forwarding setup via add_hostfwd is ready") return nil } + +func getRootlessPortChildIP(c *Container) string { + if c.config.NetMode.IsSlirp4netns() { + slirp4netnsIP, err := GetSlirp4netnsIP(c.slirp4netnsSubnet) + if err != nil { + return "" + } + return slirp4netnsIP.String() + } + + for _, r := range c.state.NetworkStatus { + for _, i := range r.IPs { + ipv4 := i.Address.IP.To4() + if ipv4 != nil { + return ipv4.String() + } + } + } + return "" +} + +// reloadRootlessRLKPortMapping will trigger a reload for the port mappings in the rootlessport process. +// This should only be called by network connect/disconnect and only as rootless. +func (c *Container) reloadRootlessRLKPortMapping() error { + childIP := getRootlessPortChildIP(c) + logrus.Debugf("reloading rootless ports for container %s, childIP is %s", c.config.ID, childIP) + + var conn net.Conn + var err error + // try three times to connect to the socket, maybe it is not ready yet + for i := 0; i < 3; i++ { + conn, err = net.Dial("unix", filepath.Join(c.runtime.config.Engine.TmpDir, "rp", c.config.ID)) + if err == nil { + break + } + time.Sleep(250 * time.Millisecond) + } + if err != nil { + // This is not a hard error for backwards compatibility. A container started + // with an old version did not created the rootlessport socket. + logrus.Warnf("Could not reload rootless port mappings, port forwarding may no longer work correctly: %v", err) + return nil + } + defer conn.Close() + enc := json.NewEncoder(conn) + err = enc.Encode(childIP) + if err != nil { + return errors.Wrap(err, "port reloading failed") + } + b, err := ioutil.ReadAll(conn) + if err != nil { + return errors.Wrap(err, "port reloading failed") + } + data := string(b) + if data != "OK" { + return errors.Errorf("port reloading failed: %s", data) + } + return nil +} diff --git a/pkg/rootlessport/rootlessport_linux.go b/pkg/rootlessport/rootlessport_linux.go index 7cb54a7c3..ede216bfe 100644 --- a/pkg/rootlessport/rootlessport_linux.go +++ b/pkg/rootlessport/rootlessport_linux.go @@ -17,9 +17,11 @@ import ( "fmt" "io" "io/ioutil" + "net" "os" "os/exec" "os/signal" + "path/filepath" "github.com/containernetworking/plugins/pkg/ns" "github.com/containers/storage/pkg/reexec" @@ -43,12 +45,14 @@ const ( // Config needs to be provided to the process via stdin as a JSON string. // stdin needs to be closed after the message has been written. type Config struct { - Mappings []ocicni.PortMapping - NetNSPath string - ExitFD int - ReadyFD int - TmpDir string - ChildIP string + Mappings []ocicni.PortMapping + NetNSPath string + ExitFD int + ReadyFD int + TmpDir string + ChildIP string + ContainerID string + RootlessCNI bool } func init() { @@ -126,6 +130,12 @@ func parent() error { } }() + socketDir := filepath.Join(cfg.TmpDir, "rp") + err = os.MkdirAll(socketDir, 0700) + if err != nil { + return err + } + // create the parent driver stateDir, err := ioutil.TempDir(cfg.TmpDir, "rootlessport") if err != nil { @@ -231,6 +241,16 @@ outer: return err } + // we only need to have a socket to reload ports when we run under rootless cni + if cfg.RootlessCNI { + socket, err := net.Listen("unix", filepath.Join(socketDir, cfg.ContainerID)) + if err != nil { + return err + } + defer socket.Close() + go serve(socket, driver) + } + // write and close ReadyFD (convention is same as slirp4netns --ready-fd) logrus.Info("ready") if _, err := readyW.Write([]byte("1")); err != nil { @@ -248,6 +268,53 @@ outer: return nil } +func serve(listener net.Listener, pm rkport.Manager) { + for { + conn, err := listener.Accept() + if err != nil { + // we cannot log this error, stderr is already closed + continue + } + ctx := context.TODO() + err = handler(ctx, conn, pm) + if err != nil { + conn.Write([]byte(err.Error())) + } else { + conn.Write([]byte("OK")) + } + conn.Close() + } +} + +func handler(ctx context.Context, conn io.Reader, pm rkport.Manager) error { + var childIP string + dec := json.NewDecoder(conn) + err := dec.Decode(&childIP) + if err != nil { + return errors.Wrap(err, "rootless port failed to decode ports") + } + portStatus, err := pm.ListPorts(ctx) + if err != nil { + return errors.Wrap(err, "rootless port failed to list ports") + } + for _, status := range portStatus { + err = pm.RemovePort(ctx, status.ID) + if err != nil { + return errors.Wrap(err, "rootless port failed to remove port") + } + } + // add the ports with the new child IP + for _, status := range portStatus { + // set the new child IP + status.Spec.ChildIP = childIP + _, err = pm.AddPort(ctx, status.Spec) + if err != nil { + return errors.Wrap(err, "rootless port failed to add port") + } + } + return nil +} + func exposePorts(pm rkport.Manager, portMappings []ocicni.PortMapping, childIP string) error { ctx := context.TODO() for _, i := range portMappings { diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index 495c7948b..6ffee7eaf 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -390,4 +390,89 @@ load helpers run_podman network rm -f $netname } +# Test for https://github.com/containers/podman/issues/10052 +@test "podman network connect/disconnect with port forwarding" { + random_1=$(random_string 30) + HOST_PORT=12345 + SERVER=http://127.0.0.1:$HOST_PORT + + # Create a test file with random content + INDEX1=$PODMAN_TMPDIR/hello.txt + echo $random_1 > $INDEX1 + + local netname=testnet-$(random_string 10) + run_podman network create $netname + is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" + + local netname2=testnet2-$(random_string 10) + run_podman network create $netname2 + is "$output" ".*/cni/net.d/$netname2.conflist" "output of 'network create'" + + # First, run a container in background to ensure that the rootless cni ns + # is not destroyed after network disconnect. + run_podman run -d --network $netname $IMAGE top + background_cid=$output + + # Run a httpd container on first network with exposed port + run_podman run -d -p "$HOST_PORT:80" \ + --network $netname \ + -v $INDEX1:/var/www/index.txt:Z \ + -w /var/www \ + $IMAGE /bin/busybox-extras httpd -f -p 80 + cid=$output + + # Verify http contents: curl from localhost + run curl --max-time 3 -s $SERVER/index.txt + is "$output" "$random_1" "curl 127.0.0.1:/index.txt" + + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" + ip="$output" + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" + mac="$output" + + run_podman network disconnect $netname $cid + + # check that we cannot curl (timeout after 3 sec) + run curl --max-time 3 -s $SERVER/index.txt + if [ "$status" -eq 0 ]; then + die "curl did not fail, it should have timed out or failed with non zero exit code" + fi + + run_podman network connect $netname $cid + + # curl should work again + run curl --max-time 3 -s $SERVER/index.txt + is "$output" "$random_1" "curl 127.0.0.1:/index.txt should work again" + + # check that we have a new ip and mac + # if the ip is still the same this whole test turns into a nop + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" + if [[ "$output" == "$ip" ]]; then + die "IP address did not change after podman network disconnect/connect" + fi + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" + if [[ "$output" == "$mac" ]]; then + die "MAC address did not change after podman network disconnect/connect" + fi + + # connect a second network + run_podman network connect $netname2 $cid + + # curl should work + run curl --max-time 3 -s $SERVER/index.txt + is "$output" "$random_1" "curl 127.0.0.1:/index.txt should work" + + # disconnect the first network + run_podman network disconnect $netname $cid + + # curl should still work + run curl --max-time 3 -s $SERVER/index.txt + is "$output" "$random_1" "curl 127.0.0.1:/index.txt should still work" + + # cleanup + run_podman stop -t 0 $cid $background_cid + run_podman rm -f $cid $background_cid + run_podman network rm -f $netname $netname2 +} + # vim: filetype=sh diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/parent.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/parent.go index 2895a8f07..abd2c5e2c 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/parent.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/parent.go @@ -12,6 +12,7 @@ import ( "strings" "sync" "syscall" + "time" "github.com/pkg/errors" @@ -140,8 +141,13 @@ func (d *driver) AddPort(ctx context.Context, spec port.Spec) (*port.Status, err } routineStopCh := make(chan struct{}) routineStop := func() error { - close(routineStopCh) - return nil // FIXME + routineStopCh <- struct{}{} + select { + case <-routineStopCh: + case <-time.After(5 * time.Second): + return errors.New("stop timeout after 5 seconds") + } + return nil } switch spec.Proto { case "tcp", "tcp4", "tcp6": diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp/tcp.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp/tcp.go index 7a7a167f1..dcc1068f0 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp/tcp.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp/tcp.go @@ -12,7 +12,7 @@ import ( "github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg" ) -func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, logWriter io.Writer) error { +func Run(socketPath string, spec port.Spec, stopCh chan struct{}, logWriter io.Writer) error { ln, err := net.Listen(spec.Proto, net.JoinHostPort(spec.ParentIP, strconv.Itoa(spec.ParentPort))) if err != nil { fmt.Fprintf(logWriter, "listen: %v\n", err) @@ -31,7 +31,10 @@ func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, logWriter io } }() go func() { - defer ln.Close() + defer func() { + ln.Close() + close(stopCh) + }() for { select { case c, ok := <-newConns: diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go index 0080dd22c..f20721bcc 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go @@ -13,7 +13,7 @@ import ( "github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udpproxy" ) -func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, logWriter io.Writer) error { +func Run(socketPath string, spec port.Spec, stopCh chan struct{}, logWriter io.Writer) error { addr, err := net.ResolveUDPAddr(spec.Proto, net.JoinHostPort(spec.ParentIP, strconv.Itoa(spec.ParentPort))) if err != nil { return err @@ -51,6 +51,7 @@ func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, logWriter io case <-stopCh: // udpp.Close closes ln as well udpp.Close() + close(stopCh) return } } diff --git a/vendor/modules.txt b/vendor/modules.txt index c89582328..ee4f9f25e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -558,7 +558,7 @@ github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util # github.com/rivo/uniseg v0.2.0 github.com/rivo/uniseg -# github.com/rootless-containers/rootlesskit v0.14.2 +# github.com/rootless-containers/rootlesskit v0.14.3 github.com/rootless-containers/rootlesskit/pkg/api github.com/rootless-containers/rootlesskit/pkg/msgutil github.com/rootless-containers/rootlesskit/pkg/port -- cgit v1.2.3-54-g00ecf