|
@@ -3,17 +3,11 @@ package portmapper
|
|
|
import (
|
|
|
"fmt"
|
|
|
"io"
|
|
|
- "io/ioutil"
|
|
|
"net"
|
|
|
- "os"
|
|
|
- "os/exec"
|
|
|
- "time"
|
|
|
|
|
|
"github.com/ishidawataru/sctp"
|
|
|
)
|
|
|
|
|
|
-var userlandProxyCommandName = "docker-proxy"
|
|
|
-
|
|
|
type userlandProxy interface {
|
|
|
Start() error
|
|
|
Stop() error
|
|
@@ -29,60 +23,6 @@ const (
|
|
|
ipv6 ipVersion = "6"
|
|
|
)
|
|
|
|
|
|
-// proxyCommand wraps an exec.Cmd to run the userland TCP and UDP
|
|
|
-// proxies as separate processes.
|
|
|
-type proxyCommand struct {
|
|
|
- cmd *exec.Cmd
|
|
|
-}
|
|
|
-
|
|
|
-func (p *proxyCommand) Start() error {
|
|
|
- r, w, err := os.Pipe()
|
|
|
- if err != nil {
|
|
|
- return fmt.Errorf("proxy unable to open os.Pipe %s", err)
|
|
|
- }
|
|
|
- defer r.Close()
|
|
|
- p.cmd.ExtraFiles = []*os.File{w}
|
|
|
- if err := p.cmd.Start(); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- w.Close()
|
|
|
-
|
|
|
- errchan := make(chan error, 1)
|
|
|
- go func() {
|
|
|
- buf := make([]byte, 2)
|
|
|
- r.Read(buf)
|
|
|
-
|
|
|
- if string(buf) != "0\n" {
|
|
|
- errStr, err := ioutil.ReadAll(r)
|
|
|
- if err != nil {
|
|
|
- errchan <- fmt.Errorf("Error reading exit status from userland proxy: %v", err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- errchan <- fmt.Errorf("Error starting userland proxy: %s", errStr)
|
|
|
- return
|
|
|
- }
|
|
|
- errchan <- nil
|
|
|
- }()
|
|
|
-
|
|
|
- select {
|
|
|
- case err := <-errchan:
|
|
|
- return err
|
|
|
- case <-time.After(16 * time.Second):
|
|
|
- return fmt.Errorf("Timed out proxy starting the userland proxy")
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (p *proxyCommand) Stop() error {
|
|
|
- if p.cmd.Process != nil {
|
|
|
- if err := p.cmd.Process.Signal(os.Interrupt); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- return p.cmd.Wait()
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
// dummyProxy just listen on some port, it is needed to prevent accidental
|
|
|
// port allocations on bound port, because without userland proxy we using
|
|
|
// iptables rules and not net.Listen
|