github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/moby/integration/container/nat_test.go (about)

     1  package container // import "github.com/docker/docker/integration/container"
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  	"net"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/docker/docker/api/types"
    15  	"github.com/docker/docker/integration/internal/container"
    16  	"github.com/docker/go-connections/nat"
    17  	"gotest.tools/v3/assert"
    18  	is "gotest.tools/v3/assert/cmp"
    19  	"gotest.tools/v3/poll"
    20  	"gotest.tools/v3/skip"
    21  )
    22  
    23  func TestNetworkNat(t *testing.T) {
    24  	skip.If(t, testEnv.OSType == "windows", "FIXME")
    25  	skip.If(t, testEnv.IsRemoteDaemon)
    26  
    27  	defer setupTest(t)()
    28  
    29  	msg := "it works"
    30  	startServerContainer(t, msg, 8080)
    31  
    32  	endpoint := getExternalAddress(t)
    33  	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", endpoint.String(), 8080))
    34  	assert.NilError(t, err)
    35  	defer conn.Close()
    36  
    37  	data, err := ioutil.ReadAll(conn)
    38  	assert.NilError(t, err)
    39  	assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data))))
    40  }
    41  
    42  func TestNetworkLocalhostTCPNat(t *testing.T) {
    43  	skip.If(t, testEnv.IsRemoteDaemon)
    44  
    45  	defer setupTest(t)()
    46  
    47  	msg := "hi yall"
    48  	startServerContainer(t, msg, 8081)
    49  
    50  	conn, err := net.Dial("tcp", "localhost:8081")
    51  	assert.NilError(t, err)
    52  	defer conn.Close()
    53  
    54  	data, err := ioutil.ReadAll(conn)
    55  	assert.NilError(t, err)
    56  	assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data))))
    57  }
    58  
    59  func TestNetworkLoopbackNat(t *testing.T) {
    60  	skip.If(t, testEnv.OSType == "windows", "FIXME")
    61  	skip.If(t, testEnv.IsRemoteDaemon)
    62  
    63  	defer setupTest(t)()
    64  
    65  	msg := "it works"
    66  	serverContainerID := startServerContainer(t, msg, 8080)
    67  
    68  	endpoint := getExternalAddress(t)
    69  
    70  	client := testEnv.APIClient()
    71  	ctx := context.Background()
    72  
    73  	cID := container.Run(ctx, t, client, container.WithCmd("sh", "-c", fmt.Sprintf("stty raw && nc -w 1 %s 8080", endpoint.String())), container.WithTty(true), container.WithNetworkMode("container:"+serverContainerID))
    74  
    75  	poll.WaitOn(t, container.IsStopped(ctx, client, cID), poll.WithDelay(100*time.Millisecond))
    76  
    77  	body, err := client.ContainerLogs(ctx, cID, types.ContainerLogsOptions{
    78  		ShowStdout: true,
    79  	})
    80  	assert.NilError(t, err)
    81  	defer body.Close()
    82  
    83  	var b bytes.Buffer
    84  	_, err = io.Copy(&b, body)
    85  	assert.NilError(t, err)
    86  
    87  	assert.Check(t, is.Equal(msg, strings.TrimSpace(b.String())))
    88  }
    89  
    90  func startServerContainer(t *testing.T, msg string, port int) string {
    91  	t.Helper()
    92  	client := testEnv.APIClient()
    93  	ctx := context.Background()
    94  
    95  	cID := container.Run(ctx, t, client, container.WithName("server-"+t.Name()), container.WithCmd("sh", "-c", fmt.Sprintf("echo %q | nc -lp %d", msg, port)), container.WithExposedPorts(fmt.Sprintf("%d/tcp", port)), func(c *container.TestContainerConfig) {
    96  		c.HostConfig.PortBindings = nat.PortMap{
    97  			nat.Port(fmt.Sprintf("%d/tcp", port)): []nat.PortBinding{
    98  				{
    99  					HostPort: fmt.Sprintf("%d", port),
   100  				},
   101  			},
   102  		}
   103  	})
   104  
   105  	poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
   106  
   107  	return cID
   108  }
   109  
   110  func getExternalAddress(t *testing.T) net.IP {
   111  	t.Helper()
   112  	iface, err := net.InterfaceByName("eth0")
   113  	skip.If(t, err != nil, "Test not running with `make test-integration`. Interface eth0 not found: %s", err)
   114  
   115  	ifaceAddrs, err := iface.Addrs()
   116  	assert.NilError(t, err)
   117  	assert.Check(t, 0 != len(ifaceAddrs))
   118  
   119  	ifaceIP, _, err := net.ParseCIDR(ifaceAddrs[0].String())
   120  	assert.NilError(t, err)
   121  
   122  	return ifaceIP
   123  }