This means we can vendor libnetwork without special casing, and
it is built the same way as the other external binaries.
Signed-off-by: Justin Cormack <justin.cormack@docker.com>
| ... | ... |
@@ -222,10 +222,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ |
| 222 | 222 |
hello-world:latest@sha256:8be990ef2aeb16dbcb9271ddfe2610fa6658d13f6dfb8bc72074cc1ca36966a7 |
| 223 | 223 |
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is) |
| 224 | 224 |
|
| 225 |
-# Install tomlv, runc, containerd and grimes |
|
| 225 |
+# Install tomlv, runc, containerd, grimes, docker-proxy |
|
| 226 | 226 |
# Please edit hack/dockerfile/install-binaries.sh to update them. |
| 227 | 227 |
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh |
| 228 |
-RUN /tmp/install-binaries.sh tomlv runc containerd grimes |
|
| 228 |
+RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy |
|
| 229 | 229 |
|
| 230 | 230 |
# Wrap all commands in the "docker-in-docker" script to allow nested containers |
| 231 | 231 |
ENTRYPOINT ["hack/dind"] |
| ... | ... |
@@ -165,10 +165,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ |
| 165 | 165 |
aarch64/hello-world:latest@sha256:65a4a158587b307bb02db4de41b836addb0c35175bdc801367b1ac1ddeb9afda |
| 166 | 166 |
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is) |
| 167 | 167 |
|
| 168 |
-# Install tomlv, runc, containerd and grimes |
|
| 168 |
+# Install tomlv, runc, containerd, grimes, docker-proxy |
|
| 169 | 169 |
# Please edit hack/dockerfile/install-binaries.sh to update them. |
| 170 | 170 |
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh |
| 171 |
-RUN /tmp/install-binaries.sh tomlv runc containerd grimes |
|
| 171 |
+RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy |
|
| 172 | 172 |
|
| 173 | 173 |
# Wrap all commands in the "docker-in-docker" script to allow nested containers |
| 174 | 174 |
ENTRYPOINT ["hack/dind"] |
| ... | ... |
@@ -164,10 +164,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ |
| 164 | 164 |
armhf/hello-world:latest@sha256:161dcecea0225975b2ad5f768058212c1e0d39e8211098666ffa1ac74cfb7791 |
| 165 | 165 |
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is) |
| 166 | 166 |
|
| 167 |
-# Install tomlv, runc, containerd and grimes |
|
| 167 |
+# Install tomlv, runc, containerd, grimes, docker-proxy |
|
| 168 | 168 |
# Please edit hack/dockerfile/install-binaries.sh to update them. |
| 169 | 169 |
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh |
| 170 |
-RUN /tmp/install-binaries.sh tomlv runc containerd grimes |
|
| 170 |
+RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy |
|
| 171 | 171 |
|
| 172 | 172 |
ENTRYPOINT ["hack/dind"] |
| 173 | 173 |
|
| ... | ... |
@@ -183,10 +183,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ |
| 183 | 183 |
ppc64le/hello-world:latest@sha256:186a40a9a02ca26df0b6c8acdfb8ac2f3ae6678996a838f977e57fac9d963974 |
| 184 | 184 |
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is) |
| 185 | 185 |
|
| 186 |
-# Install tomlv, runc, containerd and grimes |
|
| 186 |
+# Install tomlv, runc, containerd, grimes, docker-proxy |
|
| 187 | 187 |
# Please edit hack/dockerfile/install-binaries.sh to update them. |
| 188 | 188 |
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh |
| 189 |
-RUN /tmp/install-binaries.sh tomlv runc containerd grimes |
|
| 189 |
+RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy |
|
| 190 | 190 |
|
| 191 | 191 |
# Wrap all commands in the "docker-in-docker" script to allow nested containers |
| 192 | 192 |
ENTRYPOINT ["hack/dind"] |
| ... | ... |
@@ -175,10 +175,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ |
| 175 | 175 |
s390x/hello-world:latest@sha256:780d80b3a7677c3788c0d5cd9168281320c8d4a6d9183892d8ee5cdd610f5699 |
| 176 | 176 |
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is) |
| 177 | 177 |
|
| 178 |
-# Install tomlv, runc, containerd and grimes |
|
| 178 |
+# Install tomlv, runc, containerd, grimes, docker-proxy |
|
| 179 | 179 |
# Please edit hack/dockerfile/install-binaries.sh to update them. |
| 180 | 180 |
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh |
| 181 |
-RUN /tmp/install-binaries.sh tomlv runc containerd grimes |
|
| 181 |
+RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy |
|
| 182 | 182 |
|
| 183 | 183 |
# Wrap all commands in the "docker-in-docker" script to allow nested containers |
| 184 | 184 |
ENTRYPOINT ["hack/dind"] |
| ... | ... |
@@ -56,10 +56,10 @@ ENV PATH /go/bin:/usr/local/go/bin:$PATH |
| 56 | 56 |
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor |
| 57 | 57 |
ENV CGO_LDFLAGS -L/lib |
| 58 | 58 |
|
| 59 |
-# Install runc, containerd and grimes |
|
| 59 |
+# Install runc, containerd, grimes and docker-proxy |
|
| 60 | 60 |
# Please edit hack/dockerfile/install-binaries.sh to update them. |
| 61 | 61 |
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh |
| 62 |
-RUN /tmp/install-binaries.sh runc containerd grimes |
|
| 62 |
+RUN /tmp/install-binaries.sh runc containerd grimes proxy |
|
| 63 | 63 |
|
| 64 | 64 |
ENV AUTO_GOPATH 1 |
| 65 | 65 |
WORKDIR /usr/src/docker |
| ... | ... |
@@ -124,9 +124,6 @@ clean() {
|
| 124 | 124 |
findArgs+=( -path "vendor/src/$import" ) |
| 125 | 125 |
done |
| 126 | 126 |
|
| 127 |
- # The docker proxy command is built from libnetwork |
|
| 128 |
- findArgs+=( -or -path vendor/src/github.com/docker/libnetwork/cmd/proxy ) |
|
| 129 |
- |
|
| 130 | 127 |
local IFS=$'\n' |
| 131 | 128 |
local prune=( $($find vendor -depth -type d -not '(' "${findArgs[@]}" ')') )
|
| 132 | 129 |
unset IFS |
| ... | ... |
@@ -6,6 +6,7 @@ TOMLV_COMMIT=9baf8a8a9f2ed20a8e54160840c492f937eeaf9a |
| 6 | 6 |
RUNC_COMMIT=02f8fa7863dd3f82909a73e2061897828460d52f |
| 7 | 7 |
CONTAINERD_COMMIT=52ef1ceb4b660c42cf4ea9013180a5663968d4c7 |
| 8 | 8 |
GRIMES_COMMIT=74341e923bdf06cfb6b70cf54089c4d3ac87ec2d |
| 9 |
+LIBNETWORK_COMMIT=0f534354b813003a754606689722fe253101bc4e |
|
| 9 | 10 |
|
| 10 | 11 |
export GOPATH="$(mktemp -d)" |
| 11 | 12 |
|
| ... | ... |
@@ -66,8 +67,16 @@ do |
| 66 | 66 |
cp init /usr/local/bin/docker-init |
| 67 | 67 |
;; |
| 68 | 68 |
|
| 69 |
+ proxy) |
|
| 70 |
+ echo "Install docker-proxy version $LIBNETWORK_COMMIT" |
|
| 71 |
+ git clone https://github.com/docker/libnetwork.git "$GOPATH/src/github.com/docker/libnetwork" |
|
| 72 |
+ cd "$GOPATH/src/github.com/docker/libnetwork" |
|
| 73 |
+ git checkout -q "$LIBNETWORK_COMMIT" |
|
| 74 |
+ CGO_ENABLED=0 go build -v -o /usr/local/bin/docker-proxy github.com/docker/libnetwork/cmd/proxy |
|
| 75 |
+ ;; |
|
| 76 |
+ |
|
| 69 | 77 |
*) |
| 70 |
- echo echo "Usage: $0 [tomlv|runc|containerd|grimes]" |
|
| 78 |
+ echo echo "Usage: $0 [tomlv|runc|containerd|grimes|proxy]" |
|
| 71 | 79 |
exit 1 |
| 72 | 80 |
|
| 73 | 81 |
esac |
| ... | ... |
@@ -263,7 +263,7 @@ copy_binaries() {
|
| 263 | 263 |
if [ "$(go env GOOS)/$(go env GOARCH)" == "$(go env GOHOSTOS)/$(go env GOHOSTARCH)" ]; then |
| 264 | 264 |
if [ -x /usr/local/bin/docker-runc ]; then |
| 265 | 265 |
echo "Copying nested executables into $dir" |
| 266 |
- for file in containerd containerd-shim containerd-ctr runc init; do |
|
| 266 |
+ for file in containerd containerd-shim containerd-ctr runc init proxy; do |
|
| 267 | 267 |
cp `which "docker-$file"` "$dir/" |
| 268 | 268 |
if [ "$2" == "hash" ]; then |
| 269 | 269 |
hash_files "$dir/docker-$file" |
| ... | ... |
@@ -24,11 +24,12 @@ override_dh_auto_install: |
| 24 | 24 |
mkdir -p debian/docker-engine/usr/bin |
| 25 | 25 |
cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-client/docker)" debian/docker-engine/usr/bin/docker |
| 26 | 26 |
cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-daemon/dockerd)" debian/docker-engine/usr/bin/dockerd |
| 27 |
- cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-daemon/docker-proxy)" debian/docker-engine/usr/bin/docker-proxy |
|
| 27 |
+ cp -aT /usr/local/bin/docker-proxy debian/docker-engine/usr/bin/docker-proxy |
|
| 28 | 28 |
cp -aT /usr/local/bin/docker-containerd debian/docker-engine/usr/bin/docker-containerd |
| 29 | 29 |
cp -aT /usr/local/bin/docker-containerd-shim debian/docker-engine/usr/bin/docker-containerd-shim |
| 30 | 30 |
cp -aT /usr/local/bin/docker-containerd-ctr debian/docker-engine/usr/bin/docker-containerd-ctr |
| 31 | 31 |
cp -aT /usr/local/bin/docker-runc debian/docker-engine/usr/bin/docker-runc |
| 32 |
+ cp -aT /usr/local/bin/docker-init debian/docker-engine/usr/bin/docker-init |
|
| 32 | 33 |
mkdir -p debian/docker-engine/usr/lib/docker |
| 33 | 34 |
|
| 34 | 35 |
override_dh_installinit: |
| ... | ... |
@@ -126,7 +126,9 @@ export DOCKER_GITCOMMIT=%{_gitcommit}
|
| 126 | 126 |
install -d $RPM_BUILD_ROOT/%{_bindir}
|
| 127 | 127 |
install -p -m 755 bundles/%{_origversion}/dynbinary-client/docker-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker
|
| 128 | 128 |
install -p -m 755 bundles/%{_origversion}/dynbinary-daemon/dockerd-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/dockerd
|
| 129 |
-install -p -m 755 bundles/%{_origversion}/dynbinary-daemon/docker-proxy-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker-proxy
|
|
| 129 |
+ |
|
| 130 |
+# install proxy |
|
| 131 |
+install -p -m 755 /usr/local/bin/docker-proxy $RPM_BUILD_ROOT/%{_bindir}/docker-proxy
|
|
| 130 | 132 |
|
| 131 | 133 |
# install containerd |
| 132 | 134 |
install -p -m 755 /usr/local/bin/docker-containerd $RPM_BUILD_ROOT/%{_bindir}/docker-containerd
|
| ... | ... |
@@ -136,6 +138,9 @@ install -p -m 755 /usr/local/bin/docker-containerd-ctr $RPM_BUILD_ROOT/%{_bindir
|
| 136 | 136 |
# install runc |
| 137 | 137 |
install -p -m 755 /usr/local/bin/docker-runc $RPM_BUILD_ROOT/%{_bindir}/docker-runc
|
| 138 | 138 |
|
| 139 |
+# install grimes |
|
| 140 |
+install -p -m 755 /usr/local/bin/docker-init $RPM_BUILD_ROOT/%{_bindir}/docker-init
|
|
| 141 |
+ |
|
| 139 | 142 |
# install udev rules |
| 140 | 143 |
install -d $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d
|
| 141 | 144 |
install -p -m 644 contrib/udev/80-docker.rules $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d/80-docker.rules
|
| ... | ... |
@@ -9,8 +9,5 @@ set -e |
| 9 | 9 |
export BINARY_SHORT_NAME="$DOCKER_DAEMON_BINARY_NAME" |
| 10 | 10 |
export SOURCE_PATH='./cmd/dockerd' |
| 11 | 11 |
source "${MAKEDIR}/.binary"
|
| 12 |
- export BINARY_SHORT_NAME="$DOCKER_PROXY_BINARY_NAME" |
|
| 13 |
- export SOURCE_PATH='./vendor/src/github.com/docker/libnetwork/cmd/proxy' |
|
| 14 |
- source "${MAKEDIR}/.binary"
|
|
| 15 | 12 |
copy_binaries "$DEST" 'hash' |
| 16 | 13 |
) |
| ... | ... |
@@ -73,8 +73,8 @@ set -e |
| 73 | 73 |
EOF |
| 74 | 74 |
|
| 75 | 75 |
cat >> "$DEST/$version/Dockerfile.build" <<-EOF |
| 76 |
- # Install runc and containerd |
|
| 77 |
- RUN ./hack/dockerfile/install-binaries.sh runc-dynamic containerd-dynamic |
|
| 76 |
+ # Install runc, containerd, proxy and grimes |
|
| 77 |
+ RUN ./hack/dockerfile/install-binaries.sh runc-dynamic containerd-dynamic proxy grimes |
|
| 78 | 78 |
EOF |
| 79 | 79 |
|
| 80 | 80 |
if [ "$DOCKER_EXPERIMENTAL" ]; then |
| ... | ... |
@@ -93,8 +93,8 @@ set -e |
| 93 | 93 |
EOF |
| 94 | 94 |
|
| 95 | 95 |
cat >> "$DEST/$version/Dockerfile.build" <<-EOF |
| 96 |
- # Install runc and containerd |
|
| 97 |
- RUN ./hack/dockerfile/install-binaries.sh runc-dynamic containerd-dynamic |
|
| 96 |
+ # Install runc, containerd, proxy and grimes |
|
| 97 |
+ RUN ./hack/dockerfile/install-binaries.sh runc-dynamic containerd-dynamic proxy grimes |
|
| 98 | 98 |
EOF |
| 99 | 99 |
|
| 100 | 100 |
if [ "$DOCKER_EXPERIMENTAL" ]; then |
| ... | ... |
@@ -9,8 +9,4 @@ set -e |
| 9 | 9 |
export BUILDFLAGS=( "${BUILDFLAGS[@]/netgo /}" ) # disable netgo, since we don't need it for a dynamic binary
|
| 10 | 10 |
export BUILDFLAGS=( "${BUILDFLAGS[@]/static_build /}" ) # we're not building a "static" binary here
|
| 11 | 11 |
source "${MAKEDIR}/.binary"
|
| 12 |
- export BINARY_SHORT_NAME='docker-proxy' |
|
| 13 |
- export SOURCE_PATH='./vendor/src/github.com/docker/libnetwork/cmd/proxy' |
|
| 14 |
- export LDFLAGS_STATIC_DOCKER='-linkmode=external' |
|
| 15 |
- source "${MAKEDIR}/.binary"
|
|
| 16 | 12 |
) |
| 17 | 13 |
deleted file mode 100644 |
| ... | ... |
@@ -1,67 +0,0 @@ |
| 1 |
-package main |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "flag" |
|
| 5 |
- "fmt" |
|
| 6 |
- "log" |
|
| 7 |
- "net" |
|
| 8 |
- "os" |
|
| 9 |
- "os/signal" |
|
| 10 |
- "syscall" |
|
| 11 |
-) |
|
| 12 |
- |
|
| 13 |
-func main() {
|
|
| 14 |
- f := os.NewFile(3, "signal-parent") |
|
| 15 |
- host, container := parseHostContainerAddrs() |
|
| 16 |
- |
|
| 17 |
- p, err := NewProxy(host, container) |
|
| 18 |
- if err != nil {
|
|
| 19 |
- fmt.Fprintf(f, "1\n%s", err) |
|
| 20 |
- f.Close() |
|
| 21 |
- os.Exit(1) |
|
| 22 |
- } |
|
| 23 |
- go handleStopSignals(p) |
|
| 24 |
- fmt.Fprint(f, "0\n") |
|
| 25 |
- f.Close() |
|
| 26 |
- |
|
| 27 |
- // Run will block until the proxy stops |
|
| 28 |
- p.Run() |
|
| 29 |
-} |
|
| 30 |
- |
|
| 31 |
-// parseHostContainerAddrs parses the flags passed on reexec to create the TCP or UDP |
|
| 32 |
-// net.Addrs to map the host and container ports |
|
| 33 |
-func parseHostContainerAddrs() (host net.Addr, container net.Addr) {
|
|
| 34 |
- var ( |
|
| 35 |
- proto = flag.String("proto", "tcp", "proxy protocol")
|
|
| 36 |
- hostIP = flag.String("host-ip", "", "host ip")
|
|
| 37 |
- hostPort = flag.Int("host-port", -1, "host port")
|
|
| 38 |
- containerIP = flag.String("container-ip", "", "container ip")
|
|
| 39 |
- containerPort = flag.Int("container-port", -1, "container port")
|
|
| 40 |
- ) |
|
| 41 |
- |
|
| 42 |
- flag.Parse() |
|
| 43 |
- |
|
| 44 |
- switch *proto {
|
|
| 45 |
- case "tcp": |
|
| 46 |
- host = &net.TCPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
|
|
| 47 |
- container = &net.TCPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
|
|
| 48 |
- case "udp": |
|
| 49 |
- host = &net.UDPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
|
|
| 50 |
- container = &net.UDPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
|
|
| 51 |
- default: |
|
| 52 |
- log.Fatalf("unsupported protocol %s", *proto)
|
|
| 53 |
- } |
|
| 54 |
- |
|
| 55 |
- return host, container |
|
| 56 |
-} |
|
| 57 |
- |
|
| 58 |
-func handleStopSignals(p Proxy) {
|
|
| 59 |
- s := make(chan os.Signal, 10) |
|
| 60 |
- signal.Notify(s, os.Interrupt, syscall.SIGTERM) |
|
| 61 |
- |
|
| 62 |
- for range s {
|
|
| 63 |
- p.Close() |
|
| 64 |
- |
|
| 65 |
- os.Exit(0) |
|
| 66 |
- } |
|
| 67 |
-} |
| 68 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,37 +0,0 @@ |
| 1 |
-// docker-proxy provides a network Proxy interface and implementations for TCP |
|
| 2 |
-// and UDP. |
|
| 3 |
-package main |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "fmt" |
|
| 7 |
- "net" |
|
| 8 |
-) |
|
| 9 |
- |
|
| 10 |
-// Proxy defines the behavior of a proxy. It forwards traffic back and forth |
|
| 11 |
-// between two endpoints : the frontend and the backend. |
|
| 12 |
-// It can be used to do software port-mapping between two addresses. |
|
| 13 |
-// e.g. forward all traffic between the frontend (host) 127.0.0.1:3000 |
|
| 14 |
-// to the backend (container) at 172.17.42.108:4000. |
|
| 15 |
-type Proxy interface {
|
|
| 16 |
- // Run starts forwarding traffic back and forth between the front |
|
| 17 |
- // and back-end addresses. |
|
| 18 |
- Run() |
|
| 19 |
- // Close stops forwarding traffic and close both ends of the Proxy. |
|
| 20 |
- Close() |
|
| 21 |
- // FrontendAddr returns the address on which the proxy is listening. |
|
| 22 |
- FrontendAddr() net.Addr |
|
| 23 |
- // BackendAddr returns the proxied address. |
|
| 24 |
- BackendAddr() net.Addr |
|
| 25 |
-} |
|
| 26 |
- |
|
| 27 |
-// NewProxy creates a Proxy according to the specified frontendAddr and backendAddr. |
|
| 28 |
-func NewProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) {
|
|
| 29 |
- switch frontendAddr.(type) {
|
|
| 30 |
- case *net.UDPAddr: |
|
| 31 |
- return NewUDPProxy(frontendAddr.(*net.UDPAddr), backendAddr.(*net.UDPAddr)) |
|
| 32 |
- case *net.TCPAddr: |
|
| 33 |
- return NewTCPProxy(frontendAddr.(*net.TCPAddr), backendAddr.(*net.TCPAddr)) |
|
| 34 |
- default: |
|
| 35 |
- panic(fmt.Errorf("Unsupported protocol"))
|
|
| 36 |
- } |
|
| 37 |
-} |
| 38 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,31 +0,0 @@ |
| 1 |
-package main |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "net" |
|
| 5 |
-) |
|
| 6 |
- |
|
| 7 |
-// StubProxy is a proxy that is a stub (does nothing). |
|
| 8 |
-type StubProxy struct {
|
|
| 9 |
- frontendAddr net.Addr |
|
| 10 |
- backendAddr net.Addr |
|
| 11 |
-} |
|
| 12 |
- |
|
| 13 |
-// Run does nothing. |
|
| 14 |
-func (p *StubProxy) Run() {}
|
|
| 15 |
- |
|
| 16 |
-// Close does nothing. |
|
| 17 |
-func (p *StubProxy) Close() {}
|
|
| 18 |
- |
|
| 19 |
-// FrontendAddr returns the frontend address. |
|
| 20 |
-func (p *StubProxy) FrontendAddr() net.Addr { return p.frontendAddr }
|
|
| 21 |
- |
|
| 22 |
-// BackendAddr returns the backend address. |
|
| 23 |
-func (p *StubProxy) BackendAddr() net.Addr { return p.backendAddr }
|
|
| 24 |
- |
|
| 25 |
-// NewStubProxy creates a new StubProxy |
|
| 26 |
-func NewStubProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) {
|
|
| 27 |
- return &StubProxy{
|
|
| 28 |
- frontendAddr: frontendAddr, |
|
| 29 |
- backendAddr: backendAddr, |
|
| 30 |
- }, nil |
|
| 31 |
-} |
| 32 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,95 +0,0 @@ |
| 1 |
-package main |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "io" |
|
| 5 |
- "log" |
|
| 6 |
- "net" |
|
| 7 |
- "sync" |
|
| 8 |
- "syscall" |
|
| 9 |
-) |
|
| 10 |
- |
|
| 11 |
-// TCPProxy is a proxy for TCP connections. It implements the Proxy interface to |
|
| 12 |
-// handle TCP traffic forwarding between the frontend and backend addresses. |
|
| 13 |
-type TCPProxy struct {
|
|
| 14 |
- listener *net.TCPListener |
|
| 15 |
- frontendAddr *net.TCPAddr |
|
| 16 |
- backendAddr *net.TCPAddr |
|
| 17 |
-} |
|
| 18 |
- |
|
| 19 |
-// NewTCPProxy creates a new TCPProxy. |
|
| 20 |
-func NewTCPProxy(frontendAddr, backendAddr *net.TCPAddr) (*TCPProxy, error) {
|
|
| 21 |
- listener, err := net.ListenTCP("tcp", frontendAddr)
|
|
| 22 |
- if err != nil {
|
|
| 23 |
- return nil, err |
|
| 24 |
- } |
|
| 25 |
- // If the port in frontendAddr was 0 then ListenTCP will have a picked |
|
| 26 |
- // a port to listen on, hence the call to Addr to get that actual port: |
|
| 27 |
- return &TCPProxy{
|
|
| 28 |
- listener: listener, |
|
| 29 |
- frontendAddr: listener.Addr().(*net.TCPAddr), |
|
| 30 |
- backendAddr: backendAddr, |
|
| 31 |
- }, nil |
|
| 32 |
-} |
|
| 33 |
- |
|
| 34 |
-func (proxy *TCPProxy) clientLoop(client *net.TCPConn, quit chan bool) {
|
|
| 35 |
- backend, err := net.DialTCP("tcp", nil, proxy.backendAddr)
|
|
| 36 |
- if err != nil {
|
|
| 37 |
- log.Printf("Can't forward traffic to backend tcp/%v: %s\n", proxy.backendAddr, err)
|
|
| 38 |
- client.Close() |
|
| 39 |
- return |
|
| 40 |
- } |
|
| 41 |
- |
|
| 42 |
- var wg sync.WaitGroup |
|
| 43 |
- var broker = func(to, from *net.TCPConn) {
|
|
| 44 |
- if _, err := io.Copy(to, from); err != nil {
|
|
| 45 |
- // If the socket we are writing to is shutdown with |
|
| 46 |
- // SHUT_WR, forward it to the other end of the pipe: |
|
| 47 |
- if err, ok := err.(*net.OpError); ok && err.Err == syscall.EPIPE {
|
|
| 48 |
- from.CloseWrite() |
|
| 49 |
- } |
|
| 50 |
- } |
|
| 51 |
- to.CloseRead() |
|
| 52 |
- wg.Done() |
|
| 53 |
- } |
|
| 54 |
- |
|
| 55 |
- wg.Add(2) |
|
| 56 |
- go broker(client, backend) |
|
| 57 |
- go broker(backend, client) |
|
| 58 |
- |
|
| 59 |
- finish := make(chan struct{})
|
|
| 60 |
- go func() {
|
|
| 61 |
- wg.Wait() |
|
| 62 |
- close(finish) |
|
| 63 |
- }() |
|
| 64 |
- |
|
| 65 |
- select {
|
|
| 66 |
- case <-quit: |
|
| 67 |
- case <-finish: |
|
| 68 |
- } |
|
| 69 |
- client.Close() |
|
| 70 |
- backend.Close() |
|
| 71 |
- <-finish |
|
| 72 |
-} |
|
| 73 |
- |
|
| 74 |
-// Run starts forwarding the traffic using TCP. |
|
| 75 |
-func (proxy *TCPProxy) Run() {
|
|
| 76 |
- quit := make(chan bool) |
|
| 77 |
- defer close(quit) |
|
| 78 |
- for {
|
|
| 79 |
- client, err := proxy.listener.Accept() |
|
| 80 |
- if err != nil {
|
|
| 81 |
- log.Printf("Stopping proxy on tcp/%v for tcp/%v (%s)", proxy.frontendAddr, proxy.backendAddr, err)
|
|
| 82 |
- return |
|
| 83 |
- } |
|
| 84 |
- go proxy.clientLoop(client.(*net.TCPConn), quit) |
|
| 85 |
- } |
|
| 86 |
-} |
|
| 87 |
- |
|
| 88 |
-// Close stops forwarding the traffic. |
|
| 89 |
-func (proxy *TCPProxy) Close() { proxy.listener.Close() }
|
|
| 90 |
- |
|
| 91 |
-// FrontendAddr returns the TCP address on which the proxy is listening. |
|
| 92 |
-func (proxy *TCPProxy) FrontendAddr() net.Addr { return proxy.frontendAddr }
|
|
| 93 |
- |
|
| 94 |
-// BackendAddr returns the TCP proxied address. |
|
| 95 |
-func (proxy *TCPProxy) BackendAddr() net.Addr { return proxy.backendAddr }
|
| 96 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,168 +0,0 @@ |
| 1 |
-package main |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "encoding/binary" |
|
| 5 |
- "log" |
|
| 6 |
- "net" |
|
| 7 |
- "strings" |
|
| 8 |
- "sync" |
|
| 9 |
- "syscall" |
|
| 10 |
- "time" |
|
| 11 |
-) |
|
| 12 |
- |
|
| 13 |
-const ( |
|
| 14 |
- // UDPConnTrackTimeout is the timeout used for UDP connection tracking |
|
| 15 |
- UDPConnTrackTimeout = 90 * time.Second |
|
| 16 |
- // UDPBufSize is the buffer size for the UDP proxy |
|
| 17 |
- UDPBufSize = 65507 |
|
| 18 |
-) |
|
| 19 |
- |
|
| 20 |
-// A net.Addr where the IP is split into two fields so you can use it as a key |
|
| 21 |
-// in a map: |
|
| 22 |
-type connTrackKey struct {
|
|
| 23 |
- IPHigh uint64 |
|
| 24 |
- IPLow uint64 |
|
| 25 |
- Port int |
|
| 26 |
-} |
|
| 27 |
- |
|
| 28 |
-func newConnTrackKey(addr *net.UDPAddr) *connTrackKey {
|
|
| 29 |
- if len(addr.IP) == net.IPv4len {
|
|
| 30 |
- return &connTrackKey{
|
|
| 31 |
- IPHigh: 0, |
|
| 32 |
- IPLow: uint64(binary.BigEndian.Uint32(addr.IP)), |
|
| 33 |
- Port: addr.Port, |
|
| 34 |
- } |
|
| 35 |
- } |
|
| 36 |
- return &connTrackKey{
|
|
| 37 |
- IPHigh: binary.BigEndian.Uint64(addr.IP[:8]), |
|
| 38 |
- IPLow: binary.BigEndian.Uint64(addr.IP[8:]), |
|
| 39 |
- Port: addr.Port, |
|
| 40 |
- } |
|
| 41 |
-} |
|
| 42 |
- |
|
| 43 |
-type connTrackMap map[connTrackKey]*net.UDPConn |
|
| 44 |
- |
|
| 45 |
-// UDPProxy is proxy for which handles UDP datagrams. It implements the Proxy |
|
| 46 |
-// interface to handle UDP traffic forwarding between the frontend and backend |
|
| 47 |
-// addresses. |
|
| 48 |
-type UDPProxy struct {
|
|
| 49 |
- listener *net.UDPConn |
|
| 50 |
- frontendAddr *net.UDPAddr |
|
| 51 |
- backendAddr *net.UDPAddr |
|
| 52 |
- connTrackTable connTrackMap |
|
| 53 |
- connTrackLock sync.Mutex |
|
| 54 |
-} |
|
| 55 |
- |
|
| 56 |
-// NewUDPProxy creates a new UDPProxy. |
|
| 57 |
-func NewUDPProxy(frontendAddr, backendAddr *net.UDPAddr) (*UDPProxy, error) {
|
|
| 58 |
- listener, err := net.ListenUDP("udp", frontendAddr)
|
|
| 59 |
- if err != nil {
|
|
| 60 |
- return nil, err |
|
| 61 |
- } |
|
| 62 |
- return &UDPProxy{
|
|
| 63 |
- listener: listener, |
|
| 64 |
- frontendAddr: listener.LocalAddr().(*net.UDPAddr), |
|
| 65 |
- backendAddr: backendAddr, |
|
| 66 |
- connTrackTable: make(connTrackMap), |
|
| 67 |
- }, nil |
|
| 68 |
-} |
|
| 69 |
- |
|
| 70 |
-func (proxy *UDPProxy) replyLoop(proxyConn *net.UDPConn, clientAddr *net.UDPAddr, clientKey *connTrackKey) {
|
|
| 71 |
- defer func() {
|
|
| 72 |
- proxy.connTrackLock.Lock() |
|
| 73 |
- delete(proxy.connTrackTable, *clientKey) |
|
| 74 |
- proxy.connTrackLock.Unlock() |
|
| 75 |
- proxyConn.Close() |
|
| 76 |
- }() |
|
| 77 |
- |
|
| 78 |
- readBuf := make([]byte, UDPBufSize) |
|
| 79 |
- for {
|
|
| 80 |
- proxyConn.SetReadDeadline(time.Now().Add(UDPConnTrackTimeout)) |
|
| 81 |
- again: |
|
| 82 |
- read, err := proxyConn.Read(readBuf) |
|
| 83 |
- if err != nil {
|
|
| 84 |
- if err, ok := err.(*net.OpError); ok && err.Err == syscall.ECONNREFUSED {
|
|
| 85 |
- // This will happen if the last write failed |
|
| 86 |
- // (e.g: nothing is actually listening on the |
|
| 87 |
- // proxied port on the container), ignore it |
|
| 88 |
- // and continue until UDPConnTrackTimeout |
|
| 89 |
- // expires: |
|
| 90 |
- goto again |
|
| 91 |
- } |
|
| 92 |
- return |
|
| 93 |
- } |
|
| 94 |
- for i := 0; i != read; {
|
|
| 95 |
- written, err := proxy.listener.WriteToUDP(readBuf[i:read], clientAddr) |
|
| 96 |
- if err != nil {
|
|
| 97 |
- return |
|
| 98 |
- } |
|
| 99 |
- i += written |
|
| 100 |
- } |
|
| 101 |
- } |
|
| 102 |
-} |
|
| 103 |
- |
|
| 104 |
-// Run starts forwarding the traffic using UDP. |
|
| 105 |
-func (proxy *UDPProxy) Run() {
|
|
| 106 |
- readBuf := make([]byte, UDPBufSize) |
|
| 107 |
- for {
|
|
| 108 |
- read, from, err := proxy.listener.ReadFromUDP(readBuf) |
|
| 109 |
- if err != nil {
|
|
| 110 |
- // NOTE: Apparently ReadFrom doesn't return |
|
| 111 |
- // ECONNREFUSED like Read do (see comment in |
|
| 112 |
- // UDPProxy.replyLoop) |
|
| 113 |
- if !isClosedError(err) {
|
|
| 114 |
- log.Printf("Stopping proxy on udp/%v for udp/%v (%s)", proxy.frontendAddr, proxy.backendAddr, err)
|
|
| 115 |
- } |
|
| 116 |
- break |
|
| 117 |
- } |
|
| 118 |
- |
|
| 119 |
- fromKey := newConnTrackKey(from) |
|
| 120 |
- proxy.connTrackLock.Lock() |
|
| 121 |
- proxyConn, hit := proxy.connTrackTable[*fromKey] |
|
| 122 |
- if !hit {
|
|
| 123 |
- proxyConn, err = net.DialUDP("udp", nil, proxy.backendAddr)
|
|
| 124 |
- if err != nil {
|
|
| 125 |
- log.Printf("Can't proxy a datagram to udp/%s: %s\n", proxy.backendAddr, err)
|
|
| 126 |
- proxy.connTrackLock.Unlock() |
|
| 127 |
- continue |
|
| 128 |
- } |
|
| 129 |
- proxy.connTrackTable[*fromKey] = proxyConn |
|
| 130 |
- go proxy.replyLoop(proxyConn, from, fromKey) |
|
| 131 |
- } |
|
| 132 |
- proxy.connTrackLock.Unlock() |
|
| 133 |
- for i := 0; i != read; {
|
|
| 134 |
- written, err := proxyConn.Write(readBuf[i:read]) |
|
| 135 |
- if err != nil {
|
|
| 136 |
- log.Printf("Can't proxy a datagram to udp/%s: %s\n", proxy.backendAddr, err)
|
|
| 137 |
- break |
|
| 138 |
- } |
|
| 139 |
- i += written |
|
| 140 |
- } |
|
| 141 |
- } |
|
| 142 |
-} |
|
| 143 |
- |
|
| 144 |
-// Close stops forwarding the traffic. |
|
| 145 |
-func (proxy *UDPProxy) Close() {
|
|
| 146 |
- proxy.listener.Close() |
|
| 147 |
- proxy.connTrackLock.Lock() |
|
| 148 |
- defer proxy.connTrackLock.Unlock() |
|
| 149 |
- for _, conn := range proxy.connTrackTable {
|
|
| 150 |
- conn.Close() |
|
| 151 |
- } |
|
| 152 |
-} |
|
| 153 |
- |
|
| 154 |
-// FrontendAddr returns the UDP address on which the proxy is listening. |
|
| 155 |
-func (proxy *UDPProxy) FrontendAddr() net.Addr { return proxy.frontendAddr }
|
|
| 156 |
- |
|
| 157 |
-// BackendAddr returns the proxied UDP address. |
|
| 158 |
-func (proxy *UDPProxy) BackendAddr() net.Addr { return proxy.backendAddr }
|
|
| 159 |
- |
|
| 160 |
-func isClosedError(err error) bool {
|
|
| 161 |
- /* This comparison is ugly, but unfortunately, net.go doesn't export errClosing. |
|
| 162 |
- * See: |
|
| 163 |
- * http://golang.org/src/pkg/net/net.go |
|
| 164 |
- * https://code.google.com/p/go/issues/detail?id=4337 |
|
| 165 |
- * https://groups.google.com/forum/#!msg/golang-nuts/0_aaCvBmOcM/SptmDyX1XJMJ |
|
| 166 |
- */ |
|
| 167 |
- return strings.HasSuffix(err.Error(), "use of closed network connection") |
|
| 168 |
-} |