summaryrefslogtreecommitdiff
path: root/vendor/github.com/docker/go-connections/sockets
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/docker/go-connections/sockets')
-rw-r--r--vendor/github.com/docker/go-connections/sockets/README.md0
-rw-r--r--vendor/github.com/docker/go-connections/sockets/inmem_socket.go81
-rw-r--r--vendor/github.com/docker/go-connections/sockets/proxy.go28
-rw-r--r--vendor/github.com/docker/go-connections/sockets/sockets.go37
-rw-r--r--vendor/github.com/docker/go-connections/sockets/sockets_unix.go39
-rw-r--r--vendor/github.com/docker/go-connections/sockets/sockets_windows.go28
-rw-r--r--vendor/github.com/docker/go-connections/sockets/tcp_socket.go22
-rw-r--r--vendor/github.com/docker/go-connections/sockets/unix_socket.go126
8 files changed, 361 insertions, 0 deletions
diff --git a/vendor/github.com/docker/go-connections/sockets/README.md b/vendor/github.com/docker/go-connections/sockets/README.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/github.com/docker/go-connections/sockets/README.md
diff --git a/vendor/github.com/docker/go-connections/sockets/inmem_socket.go b/vendor/github.com/docker/go-connections/sockets/inmem_socket.go
new file mode 100644
index 0000000..99846ff
--- /dev/null
+++ b/vendor/github.com/docker/go-connections/sockets/inmem_socket.go
@@ -0,0 +1,81 @@
+package sockets
+
+import (
+ "errors"
+ "net"
+ "sync"
+)
+
+var errClosed = errors.New("use of closed network connection")
+
+// InmemSocket implements net.Listener using in-memory only connections.
+type InmemSocket struct {
+ chConn chan net.Conn
+ chClose chan struct{}
+ addr string
+ mu sync.Mutex
+}
+
+// dummyAddr is used to satisfy net.Addr for the in-mem socket
+// it is just stored as a string and returns the string for all calls
+type dummyAddr string
+
+// NewInmemSocket creates an in-memory only net.Listener
+// The addr argument can be any string, but is used to satisfy the `Addr()` part
+// of the net.Listener interface
+func NewInmemSocket(addr string, bufSize int) *InmemSocket {
+ return &InmemSocket{
+ chConn: make(chan net.Conn, bufSize),
+ chClose: make(chan struct{}),
+ addr: addr,
+ }
+}
+
+// Addr returns the socket's addr string to satisfy net.Listener
+func (s *InmemSocket) Addr() net.Addr {
+ return dummyAddr(s.addr)
+}
+
+// Accept implements the Accept method in the Listener interface; it waits for the next call and returns a generic Conn.
+func (s *InmemSocket) Accept() (net.Conn, error) {
+ select {
+ case conn := <-s.chConn:
+ return conn, nil
+ case <-s.chClose:
+ return nil, errClosed
+ }
+}
+
+// Close closes the listener. It will be unavailable for use once closed.
+func (s *InmemSocket) Close() error {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ select {
+ case <-s.chClose:
+ default:
+ close(s.chClose)
+ }
+ return nil
+}
+
+// Dial is used to establish a connection with the in-mem server
+func (s *InmemSocket) Dial(network, addr string) (net.Conn, error) {
+ srvConn, clientConn := net.Pipe()
+ select {
+ case s.chConn <- srvConn:
+ case <-s.chClose:
+ return nil, errClosed
+ }
+
+ return clientConn, nil
+}
+
+// Network returns the addr string, satisfies net.Addr
+func (a dummyAddr) Network() string {
+ return string(a)
+}
+
+// String returns the string form
+func (a dummyAddr) String() string {
+ return string(a)
+}
diff --git a/vendor/github.com/docker/go-connections/sockets/proxy.go b/vendor/github.com/docker/go-connections/sockets/proxy.go
new file mode 100644
index 0000000..c897cb0
--- /dev/null
+++ b/vendor/github.com/docker/go-connections/sockets/proxy.go
@@ -0,0 +1,28 @@
+package sockets
+
+import (
+ "net"
+ "os"
+ "strings"
+)
+
+// GetProxyEnv allows access to the uppercase and the lowercase forms of
+// proxy-related variables. See the Go specification for details on these
+// variables. https://golang.org/pkg/net/http/
+func GetProxyEnv(key string) string {
+ proxyValue := os.Getenv(strings.ToUpper(key))
+ if proxyValue == "" {
+ return os.Getenv(strings.ToLower(key))
+ }
+ return proxyValue
+}
+
+// DialerFromEnvironment was previously used to configure a net.Dialer to route
+// connections through a SOCKS proxy.
+// DEPRECATED: SOCKS proxies are now supported by configuring only
+// http.Transport.Proxy, and no longer require changing http.Transport.Dial.
+// Therefore, only sockets.ConfigureTransport() needs to be called, and any
+// sockets.DialerFromEnvironment() calls can be dropped.
+func DialerFromEnvironment(direct *net.Dialer) (*net.Dialer, error) {
+ return direct, nil
+}
diff --git a/vendor/github.com/docker/go-connections/sockets/sockets.go b/vendor/github.com/docker/go-connections/sockets/sockets.go
new file mode 100644
index 0000000..b0eae23
--- /dev/null
+++ b/vendor/github.com/docker/go-connections/sockets/sockets.go
@@ -0,0 +1,37 @@
+// Package sockets provides helper functions to create and configure Unix or TCP sockets.
+package sockets
+
+import (
+ "errors"
+ "net"
+ "net/http"
+ "time"
+)
+
+const defaultTimeout = 10 * time.Second
+
+// ErrProtocolNotAvailable is returned when a given transport protocol is not provided by the operating system.
+var ErrProtocolNotAvailable = errors.New("protocol not available")
+
+// ConfigureTransport configures the specified [http.Transport] according to the specified proto
+// and addr.
+//
+// If the proto is unix (using a unix socket to communicate) or npipe the compression is disabled.
+// For other protos, compression is enabled. If you want to manually enable/disable compression,
+// make sure you do it _after_ any subsequent calls to ConfigureTransport is made against the same
+// [http.Transport].
+func ConfigureTransport(tr *http.Transport, proto, addr string) error {
+ switch proto {
+ case "unix":
+ return configureUnixTransport(tr, proto, addr)
+ case "npipe":
+ return configureNpipeTransport(tr, proto, addr)
+ default:
+ tr.Proxy = http.ProxyFromEnvironment
+ tr.DisableCompression = false
+ tr.DialContext = (&net.Dialer{
+ Timeout: defaultTimeout,
+ }).DialContext
+ }
+ return nil
+}
diff --git a/vendor/github.com/docker/go-connections/sockets/sockets_unix.go b/vendor/github.com/docker/go-connections/sockets/sockets_unix.go
new file mode 100644
index 0000000..78a34a9
--- /dev/null
+++ b/vendor/github.com/docker/go-connections/sockets/sockets_unix.go
@@ -0,0 +1,39 @@
+//go:build !windows
+
+package sockets
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "net/http"
+ "syscall"
+ "time"
+)
+
+const maxUnixSocketPathSize = len(syscall.RawSockaddrUnix{}.Path)
+
+func configureUnixTransport(tr *http.Transport, proto, addr string) error {
+ if len(addr) > maxUnixSocketPathSize {
+ return fmt.Errorf("unix socket path %q is too long", addr)
+ }
+ // No need for compression in local communications.
+ tr.DisableCompression = true
+ dialer := &net.Dialer{
+ Timeout: defaultTimeout,
+ }
+ tr.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) {
+ return dialer.DialContext(ctx, proto, addr)
+ }
+ return nil
+}
+
+func configureNpipeTransport(tr *http.Transport, proto, addr string) error {
+ return ErrProtocolNotAvailable
+}
+
+// DialPipe connects to a Windows named pipe.
+// This is not supported on other OSes.
+func DialPipe(_ string, _ time.Duration) (net.Conn, error) {
+ return nil, syscall.EAFNOSUPPORT
+}
diff --git a/vendor/github.com/docker/go-connections/sockets/sockets_windows.go b/vendor/github.com/docker/go-connections/sockets/sockets_windows.go
new file mode 100644
index 0000000..7acafc5
--- /dev/null
+++ b/vendor/github.com/docker/go-connections/sockets/sockets_windows.go
@@ -0,0 +1,28 @@
+package sockets
+
+import (
+ "context"
+ "net"
+ "net/http"
+ "time"
+
+ "github.com/Microsoft/go-winio"
+)
+
+func configureUnixTransport(tr *http.Transport, proto, addr string) error {
+ return ErrProtocolNotAvailable
+}
+
+func configureNpipeTransport(tr *http.Transport, proto, addr string) error {
+ // No need for compression in local communications.
+ tr.DisableCompression = true
+ tr.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) {
+ return winio.DialPipeContext(ctx, addr)
+ }
+ return nil
+}
+
+// DialPipe connects to a Windows named pipe.
+func DialPipe(addr string, timeout time.Duration) (net.Conn, error) {
+ return winio.DialPipe(addr, &timeout)
+}
diff --git a/vendor/github.com/docker/go-connections/sockets/tcp_socket.go b/vendor/github.com/docker/go-connections/sockets/tcp_socket.go
new file mode 100644
index 0000000..53cbb6c
--- /dev/null
+++ b/vendor/github.com/docker/go-connections/sockets/tcp_socket.go
@@ -0,0 +1,22 @@
+// Package sockets provides helper functions to create and configure Unix or TCP sockets.
+package sockets
+
+import (
+ "crypto/tls"
+ "net"
+)
+
+// NewTCPSocket creates a TCP socket listener with the specified address and
+// the specified tls configuration. If TLSConfig is set, will encapsulate the
+// TCP listener inside a TLS one.
+func NewTCPSocket(addr string, tlsConfig *tls.Config) (net.Listener, error) {
+ l, err := net.Listen("tcp", addr)
+ if err != nil {
+ return nil, err
+ }
+ if tlsConfig != nil {
+ tlsConfig.NextProtos = []string{"http/1.1"}
+ l = tls.NewListener(l, tlsConfig)
+ }
+ return l, nil
+}
diff --git a/vendor/github.com/docker/go-connections/sockets/unix_socket.go b/vendor/github.com/docker/go-connections/sockets/unix_socket.go
new file mode 100644
index 0000000..b923352
--- /dev/null
+++ b/vendor/github.com/docker/go-connections/sockets/unix_socket.go
@@ -0,0 +1,126 @@
+//go:build !windows
+
+/*
+Package sockets is a simple unix domain socket wrapper.
+
+# Usage
+
+For example:
+
+ import(
+ "fmt"
+ "net"
+ "os"
+ "github.com/docker/go-connections/sockets"
+ )
+
+ func main() {
+ l, err := sockets.NewUnixSocketWithOpts("/path/to/sockets",
+ sockets.WithChown(0,0),sockets.WithChmod(0660))
+ if err != nil {
+ panic(err)
+ }
+ echoStr := "hello"
+
+ go func() {
+ for {
+ conn, err := l.Accept()
+ if err != nil {
+ return
+ }
+ conn.Write([]byte(echoStr))
+ conn.Close()
+ }
+ }()
+
+ conn, err := net.Dial("unix", path)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ buf := make([]byte, 5)
+ if _, err := conn.Read(buf); err != nil {
+ panic(err)
+ } else if string(buf) != echoStr {
+ panic(fmt.Errorf("msg may lost"))
+ }
+ }
+*/
+package sockets
+
+import (
+ "net"
+ "os"
+ "syscall"
+)
+
+// SockOption sets up socket file's creating option
+type SockOption func(string) error
+
+// WithChown modifies the socket file's uid and gid
+func WithChown(uid, gid int) SockOption {
+ return func(path string) error {
+ if err := os.Chown(path, uid, gid); err != nil {
+ return err
+ }
+ return nil
+ }
+}
+
+// WithChmod modifies socket file's access mode.
+func WithChmod(mask os.FileMode) SockOption {
+ return func(path string) error {
+ if err := os.Chmod(path, mask); err != nil {
+ return err
+ }
+ return nil
+ }
+}
+
+// NewUnixSocketWithOpts creates a unix socket with the specified options.
+// By default, socket permissions are 0000 (i.e.: no access for anyone); pass
+// WithChmod() and WithChown() to set the desired ownership and permissions.
+//
+// This function temporarily changes the system's "umask" to 0777 to work around
+// a race condition between creating the socket and setting its permissions. While
+// this should only be for a short duration, it may affect other processes that
+// create files/directories during that period.
+func NewUnixSocketWithOpts(path string, opts ...SockOption) (net.Listener, error) {
+ if err := syscall.Unlink(path); err != nil && !os.IsNotExist(err) {
+ return nil, err
+ }
+
+ // net.Listen does not allow for permissions to be set. As a result, when
+ // specifying custom permissions ("WithChmod()"), there is a short time
+ // between creating the socket and applying the permissions, during which
+ // the socket permissions are Less restrictive than desired.
+ //
+ // To work around this limitation of net.Listen(), we temporarily set the
+ // umask to 0777, which forces the socket to be created with 000 permissions
+ // (i.e.: no access for anyone). After that, WithChmod() must be used to set
+ // the desired permissions.
+ //
+ // We don't use "defer" here, to reset the umask to its original value as soon
+ // as possible. Ideally we'd be able to detect if WithChmod() was passed as
+ // an option, and skip changing umask if default permissions are used.
+ origUmask := syscall.Umask(0o777)
+ l, err := net.Listen("unix", path)
+ syscall.Umask(origUmask)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, op := range opts {
+ if err := op(path); err != nil {
+ _ = l.Close()
+ return nil, err
+ }
+ }
+
+ return l, nil
+}
+
+// NewUnixSocket creates a unix socket with the specified path and group.
+func NewUnixSocket(path string, gid int) (net.Listener, error) {
+ return NewUnixSocketWithOpts(path, WithChown(0, gid), WithChmod(0o660))
+}