AUTH-2394 added socks5 proxy
This commit is contained in:
		
							parent
							
								
									710f66b0bb
								
							
						
					
					
						commit
						a37da2b165
					
				|  | @ -11,9 +11,7 @@ import ( | |||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/cloudflare/cloudflared/cmd/cloudflared/token" | ||||
| 	cloudflaredWebsocket "github.com/cloudflare/cloudflared/websocket" | ||||
| 	"github.com/gorilla/websocket" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
| 
 | ||||
| type StartOptions struct { | ||||
|  | @ -21,6 +19,15 @@ type StartOptions struct { | |||
| 	Headers   http.Header | ||||
| } | ||||
| 
 | ||||
| // Connection wraps up all the needed functions to forward over the tunnel
 | ||||
| type Connection interface { | ||||
| 	// ServeStream is used to forward data from the client to the edge
 | ||||
| 	ServeStream(*StartOptions, io.ReadWriter) error | ||||
| 
 | ||||
| 	// StartServer is used to listen for incoming connections from the edge to the origin
 | ||||
| 	StartServer(net.Listener, string, <-chan struct{}) error | ||||
| } | ||||
| 
 | ||||
| // StdinoutStream is empty struct for wrapping stdin/stdout
 | ||||
| // into a single ReadWriter
 | ||||
| type StdinoutStream struct { | ||||
|  | @ -44,29 +51,27 @@ func closeRespBody(resp *http.Response) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StartClient will copy the data from stdin/stdout over a WebSocket connection
 | ||||
| // to the edge (originURL)
 | ||||
| func StartClient(logger *logrus.Logger, stream io.ReadWriter, options *StartOptions) error { | ||||
| 	return serveStream(logger, stream, options) | ||||
| } | ||||
| 
 | ||||
| // StartServer will setup a listener on a specified address/port and then
 | ||||
| // StartForwarder will setup a listener on a specified address/port and then
 | ||||
| // forward connections to the origin by calling `Serve()`.
 | ||||
| func StartServer(logger *logrus.Logger, address string, shutdownC <-chan struct{}, options *StartOptions) error { | ||||
| func StartForwarder(conn Connection, address string, shutdownC <-chan struct{}, options *StartOptions) error { | ||||
| 	listener, err := net.Listen("tcp", address) | ||||
| 	if err != nil { | ||||
| 		logger.WithError(err).Error("failed to start forwarding server") | ||||
| 		return err | ||||
| 		return errors.Wrap(err, "failed to start forwarding server") | ||||
| 	} | ||||
| 	logger.Info("Started listening on ", address) | ||||
| 	return Serve(logger, listener, shutdownC, options) | ||||
| 	return Serve(conn, listener, shutdownC, options) | ||||
| } | ||||
| 
 | ||||
| // StartClient will copy the data from stdin/stdout over a WebSocket connection
 | ||||
| // to the edge (originURL)
 | ||||
| func StartClient(conn Connection, stream io.ReadWriter, options *StartOptions) error { | ||||
| 	return serveStream(conn, stream, options) | ||||
| } | ||||
| 
 | ||||
| // Serve accepts incoming connections on the specified net.Listener.
 | ||||
| // Each connection is handled in a new goroutine: its data is copied over a
 | ||||
| // WebSocket connection to the edge (originURL).
 | ||||
| // `Serve` always closes `listener`.
 | ||||
| func Serve(logger *logrus.Logger, listener net.Listener, shutdownC <-chan struct{}, options *StartOptions) error { | ||||
| func Serve(remoteConn Connection, listener net.Listener, shutdownC <-chan struct{}, options *StartOptions) error { | ||||
| 	defer listener.Close() | ||||
| 	for { | ||||
| 		select { | ||||
|  | @ -77,53 +82,20 @@ func Serve(logger *logrus.Logger, listener net.Listener, shutdownC <-chan struct | |||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			go serveConnection(logger, conn, options) | ||||
| 			go serveConnection(remoteConn, conn, options) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // serveConnection handles connections for the Serve() call
 | ||||
| func serveConnection(logger *logrus.Logger, c net.Conn, options *StartOptions) { | ||||
| func serveConnection(remoteConn Connection, c net.Conn, options *StartOptions) { | ||||
| 	defer c.Close() | ||||
| 	serveStream(logger, c, options) | ||||
| 	serveStream(remoteConn, c, options) | ||||
| } | ||||
| 
 | ||||
| // serveStream will serve the data over the WebSocket stream
 | ||||
| func serveStream(logger *logrus.Logger, conn io.ReadWriter, options *StartOptions) error { | ||||
| 	wsConn, err := createWebsocketStream(options) | ||||
| 	if err != nil { | ||||
| 		logger.WithError(err).Errorf("failed to connect to %s\n", options.OriginURL) | ||||
| 		return err | ||||
| 	} | ||||
| 	defer wsConn.Close() | ||||
| 
 | ||||
| 	cloudflaredWebsocket.Stream(wsConn, conn) | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // createWebsocketStream will create a WebSocket connection to stream data over
 | ||||
| // It also handles redirects from Access and will present that flow if
 | ||||
| // the token is not present on the request
 | ||||
| func createWebsocketStream(options *StartOptions) (*cloudflaredWebsocket.Conn, error) { | ||||
| 	req, err := http.NewRequest(http.MethodGet, options.OriginURL, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	req.Header = options.Headers | ||||
| 
 | ||||
| 	wsConn, resp, err := cloudflaredWebsocket.ClientConnect(req, nil) | ||||
| 	defer closeRespBody(resp) | ||||
| 	if err != nil && IsAccessResponse(resp) { | ||||
| 		wsConn, err = createAccessAuthenticatedStream(options) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} else if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return &cloudflaredWebsocket.Conn{Conn: wsConn}, nil | ||||
| func serveStream(remoteConn Connection, conn io.ReadWriter, options *StartOptions) error { | ||||
| 	return remoteConn.ServeStream(options, conn) | ||||
| } | ||||
| 
 | ||||
| // IsAccessResponse checks the http Response to see if the url location
 | ||||
|  | @ -144,49 +116,7 @@ func IsAccessResponse(resp *http.Response) bool { | |||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // createAccessAuthenticatedStream will try load a token from storage and make
 | ||||
| // a connection with the token set on the request. If it still get redirect,
 | ||||
| // this probably means the token in storage is invalid (expired/revoked). If that
 | ||||
| // happens it deletes the token and runs the connection again, so the user can
 | ||||
| // login again and generate a new one.
 | ||||
| func createAccessAuthenticatedStream(options *StartOptions) (*websocket.Conn, error) { | ||||
| 	wsConn, resp, err := createAccessWebSocketStream(options) | ||||
| 	defer closeRespBody(resp) | ||||
| 	if err == nil { | ||||
| 		return wsConn, nil | ||||
| 	} | ||||
| 
 | ||||
| 	if !IsAccessResponse(resp) { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// Access Token is invalid for some reason. Go through regen flow
 | ||||
| 	originReq, err := http.NewRequest(http.MethodGet, options.OriginURL, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := token.RemoveTokenIfExists(originReq.URL); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	wsConn, resp, err = createAccessWebSocketStream(options) | ||||
| 	defer closeRespBody(resp) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return wsConn, nil | ||||
| } | ||||
| 
 | ||||
| // createAccessWebSocketStream builds an Access request and makes a connection
 | ||||
| func createAccessWebSocketStream(options *StartOptions) (*websocket.Conn, *http.Response, error) { | ||||
| 	req, err := BuildAccessRequest(options) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 	return cloudflaredWebsocket.ClientConnect(req, nil) | ||||
| } | ||||
| 
 | ||||
| // buildAccessRequest builds an HTTP request with the Access token set
 | ||||
| // BuildAccessRequest builds an HTTP request with the Access token set
 | ||||
| func BuildAccessRequest(options *StartOptions) (*http.Request, error) { | ||||
| 	req, err := http.NewRequest(http.MethodGet, options.OriginURL, nil) | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -44,6 +44,7 @@ func (s *testStreamer) Write(p []byte) (int, error) { | |||
| func TestStartClient(t *testing.T) { | ||||
| 	message := "Good morning Austin! Time for another sunny day in the great state of Texas." | ||||
| 	logger := logrus.New() | ||||
| 	wsConn := NewWSConnection(logger, false) | ||||
| 	ts := newTestWebSocketServer() | ||||
| 	defer ts.Close() | ||||
| 
 | ||||
|  | @ -52,7 +53,7 @@ func TestStartClient(t *testing.T) { | |||
| 		OriginURL: "http://" + ts.Listener.Addr().String(), | ||||
| 		Headers:   nil, | ||||
| 	} | ||||
| 	err := StartClient(logger, buf, options) | ||||
| 	err := StartClient(wsConn, buf, options) | ||||
| 	assert.NoError(t, err) | ||||
| 	buf.Write([]byte(message)) | ||||
| 
 | ||||
|  | @ -69,6 +70,7 @@ func TestStartServer(t *testing.T) { | |||
| 	message := "Good morning Austin! Time for another sunny day in the great state of Texas." | ||||
| 	logger := logrus.New() | ||||
| 	shutdownC := make(chan struct{}) | ||||
| 	wsConn := NewWSConnection(logger, false) | ||||
| 	ts := newTestWebSocketServer() | ||||
| 	defer ts.Close() | ||||
| 	options := &StartOptions{ | ||||
|  | @ -77,7 +79,7 @@ func TestStartServer(t *testing.T) { | |||
| 	} | ||||
| 
 | ||||
| 	go func() { | ||||
| 		err := Serve(logger, listener, shutdownC, options) | ||||
| 		err := Serve(wsConn, listener, shutdownC, options) | ||||
| 		if err != nil { | ||||
| 			t.Fatalf("Error running server: %v", err) | ||||
| 		} | ||||
|  |  | |||
|  | @ -0,0 +1,137 @@ | |||
| package carrier | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 
 | ||||
| 	"github.com/cloudflare/cloudflared/cmd/cloudflared/token" | ||||
| 	"github.com/cloudflare/cloudflared/socks" | ||||
| 	cfwebsocket "github.com/cloudflare/cloudflared/websocket" | ||||
| 	"github.com/gorilla/websocket" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| // Websocket is used to carry data via WS binary frames over the tunnel from client to the origin
 | ||||
| // This implements the functions for glider proxy (sock5) and the carrier interface
 | ||||
| type Websocket struct { | ||||
| 	logger  *logrus.Logger | ||||
| 	isSocks bool | ||||
| } | ||||
| 
 | ||||
| type wsdialer struct { | ||||
| 	conn *cfwebsocket.Conn | ||||
| } | ||||
| 
 | ||||
| func (d *wsdialer) Dial(address string) (io.ReadWriteCloser, *socks.AddrSpec, error) { | ||||
| 	local, ok := d.conn.LocalAddr().(*net.TCPAddr) | ||||
| 	if !ok { | ||||
| 		return nil, nil, fmt.Errorf("not a tcp connection") | ||||
| 	} | ||||
| 
 | ||||
| 	addr := socks.AddrSpec{IP: local.IP, Port: local.Port} | ||||
| 	return d.conn, &addr, nil | ||||
| } | ||||
| 
 | ||||
| // NewWSConnection returns a new connection object
 | ||||
| func NewWSConnection(logger *logrus.Logger, isSocks bool) Connection { | ||||
| 	return &Websocket{ | ||||
| 		logger:  logger, | ||||
| 		isSocks: isSocks, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ServeStream will create a Websocket client stream connection to the edge
 | ||||
| // it blocks and writes the raw data from conn over the tunnel
 | ||||
| func (ws *Websocket) ServeStream(options *StartOptions, conn io.ReadWriter) error { | ||||
| 	wsConn, err := createWebsocketStream(options) | ||||
| 	if err != nil { | ||||
| 		ws.logger.WithError(err).Errorf("failed to connect to %s", options.OriginURL) | ||||
| 		return err | ||||
| 	} | ||||
| 	defer wsConn.Close() | ||||
| 
 | ||||
| 	if ws.isSocks { | ||||
| 		dialer := &wsdialer{conn: wsConn} | ||||
| 		requestHandler := socks.NewRequestHandler(dialer) | ||||
| 		socksServer := socks.NewConnectionHandler(requestHandler) | ||||
| 
 | ||||
| 		socksServer.Serve(conn) | ||||
| 	} else { | ||||
| 		cfwebsocket.Stream(wsConn, conn) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // StartServer creates a Websocket server to listen for connections.
 | ||||
| // This is used on the origin (tunnel) side to take data from the muxer and send it to the origin
 | ||||
| func (ws *Websocket) StartServer(listener net.Listener, remote string, shutdownC <-chan struct{}) error { | ||||
| 	return cfwebsocket.StartProxyServer(ws.logger, listener, remote, shutdownC, cfwebsocket.DefaultStreamHandler) | ||||
| } | ||||
| 
 | ||||
| // createWebsocketStream will create a WebSocket connection to stream data over
 | ||||
| // It also handles redirects from Access and will present that flow if
 | ||||
| // the token is not present on the request
 | ||||
| func createWebsocketStream(options *StartOptions) (*cfwebsocket.Conn, error) { | ||||
| 	req, err := http.NewRequest(http.MethodGet, options.OriginURL, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	req.Header = options.Headers | ||||
| 
 | ||||
| 	wsConn, resp, err := cfwebsocket.ClientConnect(req, nil) | ||||
| 	defer closeRespBody(resp) | ||||
| 	if err != nil && IsAccessResponse(resp) { | ||||
| 		wsConn, err = createAccessAuthenticatedStream(options) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} else if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return &cfwebsocket.Conn{Conn: wsConn}, nil | ||||
| } | ||||
| 
 | ||||
| // createAccessAuthenticatedStream will try load a token from storage and make
 | ||||
| // a connection with the token set on the request. If it still get redirect,
 | ||||
| // this probably means the token in storage is invalid (expired/revoked). If that
 | ||||
| // happens it deletes the token and runs the connection again, so the user can
 | ||||
| // login again and generate a new one.
 | ||||
| func createAccessAuthenticatedStream(options *StartOptions) (*websocket.Conn, error) { | ||||
| 	wsConn, resp, err := createAccessWebSocketStream(options) | ||||
| 	defer closeRespBody(resp) | ||||
| 	if err == nil { | ||||
| 		return wsConn, nil | ||||
| 	} | ||||
| 
 | ||||
| 	if !IsAccessResponse(resp) { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// Access Token is invalid for some reason. Go through regen flow
 | ||||
| 	originReq, err := http.NewRequest(http.MethodGet, options.OriginURL, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := token.RemoveTokenIfExists(originReq.URL); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	wsConn, resp, err = createAccessWebSocketStream(options) | ||||
| 	defer closeRespBody(resp) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return wsConn, nil | ||||
| } | ||||
| 
 | ||||
| // createAccessWebSocketStream builds an Access request and makes a connection
 | ||||
| func createAccessWebSocketStream(options *StartOptions) (*websocket.Conn, *http.Response, error) { | ||||
| 	req, err := BuildAccessRequest(options) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 	return cfwebsocket.ClientConnect(req, nil) | ||||
| } | ||||
|  | @ -44,6 +44,9 @@ func ssh(c *cli.Context) error { | |||
| 		Headers:   headers, | ||||
| 	} | ||||
| 
 | ||||
| 	// we could add a cmd line variable for this bool if we want the SOCK5 server to be on the client side
 | ||||
| 	wsConn := carrier.NewWSConnection(logger, false) | ||||
| 
 | ||||
| 	if c.NArg() > 0 || c.IsSet(sshURLFlag) { | ||||
| 		localForwarder, err := config.ValidateUrl(c) | ||||
| 		if err != nil { | ||||
|  | @ -55,10 +58,12 @@ func ssh(c *cli.Context) error { | |||
| 			logger.WithError(err).Error("Error validating origin URL") | ||||
| 			return errors.Wrap(err, "error validating origin URL") | ||||
| 		} | ||||
| 		return carrier.StartServer(logger, forwarder.Host, shutdownC, options) | ||||
| 
 | ||||
| 		logger.Infof("Start Websocket listener on: %s", forwarder.Host) | ||||
| 		return carrier.StartForwarder(wsConn, forwarder.Host, shutdownC, options) | ||||
| 	} | ||||
| 
 | ||||
| 	return carrier.StartClient(logger, &carrier.StdinoutStream{}, options) | ||||
| 	return carrier.StartClient(wsConn, &carrier.StdinoutStream{}, options) | ||||
| } | ||||
| 
 | ||||
| func buildRequestHeaders(values []string) http.Header { | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ import ( | |||
| 	"github.com/cloudflare/cloudflared/metrics" | ||||
| 	"github.com/cloudflare/cloudflared/origin" | ||||
| 	"github.com/cloudflare/cloudflared/signal" | ||||
| 	"github.com/cloudflare/cloudflared/socks" | ||||
| 	"github.com/cloudflare/cloudflared/sshlog" | ||||
| 	"github.com/cloudflare/cloudflared/sshserver" | ||||
| 	"github.com/cloudflare/cloudflared/supervisor" | ||||
|  | @ -77,6 +78,9 @@ const ( | |||
| 	// hostKeyPath is the path of the dir to save SSH host keys too
 | ||||
| 	hostKeyPath = "host-key-path" | ||||
| 
 | ||||
| 	// socks5Flag is to enable the socks server to deframe
 | ||||
| 	socks5Flag = "socks5" | ||||
| 
 | ||||
| 	noIntentMsg = "The --intent argument is required. Cloudflared looks up an Intent to determine what configuration to use (i.e. which tunnels to start). If you don't have any Intents yet, you can use a placeholder Intent Label for now. Then, when you make an Intent with that label, cloudflared will get notified and open the tunnels you specified in that Intent." | ||||
| ) | ||||
| 
 | ||||
|  | @ -390,7 +394,18 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan | |||
| 		wg.Add(1) | ||||
| 		go func() { | ||||
| 			defer wg.Done() | ||||
| 			errC <- websocket.StartProxyServer(logger, listener, host, shutdownC) | ||||
| 			streamHandler := websocket.DefaultStreamHandler | ||||
| 			if c.IsSet(socks5Flag) { | ||||
| 				logger.Info("SOCKS5 server started") | ||||
| 				streamHandler = func(wsConn *websocket.Conn, remoteConn net.Conn) { | ||||
| 					dialer := socks.NewConnDialer(remoteConn) | ||||
| 					requestHandler := socks.NewRequestHandler(dialer) | ||||
| 					socksServer := socks.NewConnectionHandler(requestHandler) | ||||
| 
 | ||||
| 					socksServer.Serve(wsConn) | ||||
| 				} | ||||
| 			} | ||||
| 			errC <- websocket.StartProxyServer(logger, listener, host, shutdownC, streamHandler) | ||||
| 		}() | ||||
| 		c.Set("url", "http://"+listener.Addr().String()) | ||||
| 	} | ||||
|  | @ -1074,6 +1089,13 @@ func tunnelFlags(shouldHide bool) []cli.Flag { | |||
| 			Hidden:  true, | ||||
| 			Value:   false, | ||||
| 		}), | ||||
| 		altsrc.NewBoolFlag(&cli.BoolFlag{ | ||||
| 			Name:    socks5Flag, | ||||
| 			Usage:   "specify if this tunnel is running as a SOCK5 Server", | ||||
| 			EnvVars: []string{"TUNNEL_SOCKS"}, | ||||
| 			Value:   false, | ||||
| 			Hidden:  false, | ||||
| 		}), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										11
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										11
									
								
								go.mod
								
								
								
								
							|  | @ -25,14 +25,15 @@ require ( | |||
| 	github.com/gliderlabs/ssh v0.0.0-20191009160644-63518b5243e0 | ||||
| 	github.com/go-sql-driver/mysql v1.4.1 | ||||
| 	github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 | ||||
| 	github.com/google/certificate-transparency-go v1.1.0 // indirect | ||||
| 	github.com/google/uuid v1.1.1 | ||||
| 	github.com/gorilla/mux v1.7.3 | ||||
| 	github.com/gorilla/websocket v1.4.0 | ||||
| 	github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect | ||||
| 	github.com/jmoiron/sqlx v1.2.0 | ||||
| 	github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect | ||||
| 	github.com/kr/pretty v0.1.0 // indirect | ||||
| 	github.com/kshvakov/clickhouse v1.3.11 | ||||
| 	github.com/kylelemons/godebug v1.1.0 // indirect | ||||
| 	github.com/lib/pq v1.2.0 | ||||
| 	github.com/mattn/go-colorable v0.1.4 | ||||
| 	github.com/mattn/go-isatty v0.0.10 // indirect | ||||
|  | @ -54,11 +55,15 @@ require ( | |||
| 	github.com/tinylib/msgp v1.1.0 // indirect | ||||
| 	github.com/xo/dburl v0.0.0-20191005012637-293c3298d6c0 | ||||
| 	golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 | ||||
| 	golang.org/x/net v0.0.0-20191007182048-72f939374954 | ||||
| 	golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 | ||||
| 	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect | ||||
| 	golang.org/x/sync v0.0.0-20190423024810-112230192c58 | ||||
| 	golang.org/x/sys v0.0.0-20191008105621-543471e840be | ||||
| 	golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2 | ||||
| 	golang.org/x/text v0.3.2 // indirect | ||||
| 	google.golang.org/appengine v1.5.0 // indirect | ||||
| 	google.golang.org/genproto v0.0.0-20191007204434-a023cd5227bd // indirect | ||||
| 	google.golang.org/grpc v1.24.0 // indirect | ||||
| 	gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect | ||||
| 	gopkg.in/coreos/go-oidc.v2 v2.1.0 | ||||
| 	gopkg.in/square/go-jose.v2 v2.4.0 // indirect | ||||
| 	gopkg.in/urfave/cli.v2 v2.0.0-20180128181224-d604b6ffeee8 | ||||
|  |  | |||
							
								
								
									
										238
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										238
									
								
								go.sum
								
								
								
								
							|  | @ -1,28 +1,19 @@ | |||
| cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||||
| cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||||
| cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= | ||||
| contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw= | ||||
| contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA= | ||||
| github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= | ||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
| github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= | ||||
| github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= | ||||
| github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= | ||||
| github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= | ||||
| github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= | ||||
| github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | ||||
| github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= | ||||
| github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= | ||||
| github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= | ||||
| github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= | ||||
| github.com/aws/aws-sdk-go v1.25.8 h1:n7I+HUUXjun2CsX7JK+1hpRIkZrlKhd3nayeb+Xmavs= | ||||
| github.com/aws/aws-sdk-go v1.25.8/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= | ||||
| github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= | ||||
| github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | ||||
| github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= | ||||
| github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk= | ||||
| github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= | ||||
| github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | ||||
| github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261 h1:6/yVvBsKeAw05IUj4AzvrxaCnDjN4nUqKjW9+w5wixg= | ||||
| github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= | ||||
| github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= | ||||
|  | @ -34,26 +25,15 @@ github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY | |||
| github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= | ||||
| github.com/coredns/coredns v1.2.0 h1:YEI38K2BJYzL/SxO2tZFD727T/C68DqVWkBQjT0sWPU= | ||||
| github.com/coredns/coredns v1.2.0/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0= | ||||
| github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= | ||||
| github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= | ||||
| github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= | ||||
| github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= | ||||
| github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73 h1:7CNPV0LWRCa1FNmqg700pbXhzvmoaXKyfxWRkjRym7Q= | ||||
| github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= | ||||
| github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||
| github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||
| github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | ||||
| github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a h1:W8b4lQ4tFF21aspRGoBuCNV6V2fFJBF+pm1J6OY8Lys= | ||||
| github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | ||||
| github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | ||||
| github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= | ||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0 h1:epsH3lb7KVbXHYk7LYGN5EiE0MxcevHU85CKITJ0wUY= | ||||
| github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | ||||
| github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= | ||||
| github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= | ||||
| github.com/equinox-io/equinox v1.2.0 h1:bBS7Ou+Y7Jwgmy8TWSYxEh85WctuFn7FPlgbUzX4DBA= | ||||
| github.com/equinox-io/equinox v1.2.0/go.mod h1:6s3HJB0PYUNgs0mxmI8fHdfVl3TQ25ieA/PVfr+eyVo= | ||||
| github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= | ||||
|  | @ -66,178 +46,80 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojt | |||
| github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= | ||||
| github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= | ||||
| github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= | ||||
| github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | ||||
| github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= | ||||
| github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= | ||||
| github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | ||||
| github.com/getsentry/raven-go v0.0.0-20180517221441-ed7bcb39ff10 h1:YO10pIIBftO/kkTFdWhctH96grJ7qiy7bMdiZcIvPKs= | ||||
| github.com/getsentry/raven-go v0.0.0-20180517221441-ed7bcb39ff10/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= | ||||
| github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | ||||
| github.com/gliderlabs/ssh v0.0.0-20191009160644-63518b5243e0 h1:gF8ngtda767ddth2SH0YSAhswhz6qUkvyI9EZFYCWJA= | ||||
| github.com/gliderlabs/ssh v0.0.0-20191009160644-63518b5243e0/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= | ||||
| github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= | ||||
| github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= | ||||
| github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= | ||||
| github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= | ||||
| github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= | ||||
| github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= | ||||
| github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= | ||||
| github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= | ||||
| github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= | ||||
| github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= | ||||
| github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= | ||||
| github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= | ||||
| github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= | ||||
| github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= | ||||
| github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= | ||||
| github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= | ||||
| github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= | ||||
| github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= | ||||
| github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= | ||||
| github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= | ||||
| github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= | ||||
| github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= | ||||
| github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||||
| github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4= | ||||
| github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU= | ||||
| github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= | ||||
| github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= | ||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= | ||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||||
| github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||
| github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||
| github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||
| github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||
| github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= | ||||
| github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= | ||||
| github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= | ||||
| github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= | ||||
| github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= | ||||
| github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM= | ||||
| github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= | ||||
| github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= | ||||
| github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= | ||||
| github.com/golangci/golangci-lint v1.17.2-0.20190910081718-bad04bb7378f/go.mod h1:kaqo8l0OZKYPtjNmG4z4HrWLgcYNIJ9B9q3LWri9uLg= | ||||
| github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU= | ||||
| github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= | ||||
| github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= | ||||
| github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= | ||||
| github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= | ||||
| github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= | ||||
| github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= | ||||
| github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= | ||||
| github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/certificate-transparency-go v1.1.0 h1:10MlrYzh5wfkToxWI4yJzffsxLfxcEDlOATMx/V9Kzw= | ||||
| github.com/google/certificate-transparency-go v1.1.0/go.mod h1:i+Q7XY+ArBveOUT36jiHGfuSK1fHICIg6sUkRxPAbCs= | ||||
| github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||||
| github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= | ||||
| github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= | ||||
| github.com/google/monologue v0.0.0-20190606152607-4b11a32b5934/go.mod h1:6NTfaQoUpg5QmPsCUWLR3ig33FHrKXhTtWzF0DVdmuk= | ||||
| github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= | ||||
| github.com/google/trillian v1.2.2-0.20190612132142-05461f4df60a/go.mod h1:YPmUVn5NGwgnDUgqlVyFGMTgaWlnSvH7W5p+NdOG8UA= | ||||
| github.com/google/trillian-examples v0.0.0-20190603134952-4e75ba15216c/go.mod h1:WgL3XZ3pA8/9cm7yxqWrZE6iZkESB2ItGxy5Fo6k2lk= | ||||
| github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= | ||||
| github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||
| github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= | ||||
| github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= | ||||
| github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= | ||||
| github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= | ||||
| github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | ||||
| github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= | ||||
| github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | ||||
| github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= | ||||
| github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= | ||||
| github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= | ||||
| github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= | ||||
| github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= | ||||
| github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= | ||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= | ||||
| github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= | ||||
| github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | ||||
| github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | ||||
| github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= | ||||
| github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= | ||||
| github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= | ||||
| github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= | ||||
| github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= | ||||
| github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= | ||||
| github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= | ||||
| github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | ||||
| github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM= | ||||
| github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||||
| github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= | ||||
| github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= | ||||
| github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= | ||||
| github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= | ||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= | ||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||
| github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= | ||||
| github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= | ||||
| github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||||
| github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||||
| github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= | ||||
| github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||
| github.com/kshvakov/clickhouse v1.3.11 h1:dtzTJY0fCA+MWkLyuKZaNPkmSwdX4gh8+Klic9NB1Lw= | ||||
| github.com/kshvakov/clickhouse v1.3.11/go.mod h1:/SVBAcqF3u7rxQ9sTWCZwf8jzzvxiZGeQvtmSF2BBEc= | ||||
| github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= | ||||
| github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= | ||||
| github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= | ||||
| github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= | ||||
| github.com/letsencrypt/pkcs11key v2.0.1-0.20170608213348-396559074696+incompatible/go.mod h1:iGYXKqDXt0cpBthCHdr9ZdsQwyGlYFh/+8xa4WzIQ34= | ||||
| github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||
| github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||
| github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= | ||||
| github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||
| github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= | ||||
| github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= | ||||
| github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= | ||||
| github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= | ||||
| github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= | ||||
| github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= | ||||
| github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= | ||||
| github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | ||||
| github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= | ||||
| github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= | ||||
| github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= | ||||
| github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | ||||
| github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | ||||
| github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= | ||||
| github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | ||||
| github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | ||||
| github.com/mholt/caddy v0.0.0-20180807230124-d3b731e9255b h1:/BbY4n99iMazlr2igipph+hj0MwlZIWpcsP8Iy+na+s= | ||||
| github.com/mholt/caddy v0.0.0-20180807230124-d3b731e9255b/go.mod h1:Wb1PlT4DAYSqOEd03MsqkdkXnTxA8v9pKjdpxbqM1kY= | ||||
| github.com/miekg/dns v1.1.8 h1:1QYRAKU3lN5cRfLCkPU08hwvLJFhvjP6MqNMmQz6ZVI= | ||||
| github.com/miekg/dns v1.1.8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= | ||||
| github.com/miekg/dns v1.1.27 h1:aEH/kqUzUxGJ/UHcEKdJY+ugH6WEzsEBBSPa8zuy1aM= | ||||
| github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= | ||||
| github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= | ||||
| github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | ||||
| github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= | ||||
| github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | ||||
| github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= | ||||
| github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | ||||
| github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | ||||
| github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= | ||||
| github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= | ||||
| github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | ||||
| github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= | ||||
| github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= | ||||
| github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= | ||||
| github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= | ||||
| github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= | ||||
| github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= | ||||
| github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= | ||||
| github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= | ||||
| github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= | ||||
| github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= | ||||
| github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= | ||||
| github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= | ||||
|  | @ -257,199 +139,95 @@ github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLy | |||
| github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= | ||||
| github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= | ||||
| github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= | ||||
| github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= | ||||
| github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= | ||||
| github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= | ||||
| github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= | ||||
| github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= | ||||
| github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= | ||||
| github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= | ||||
| github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= | ||||
| github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= | ||||
| github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= | ||||
| github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= | ||||
| github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= | ||||
| github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= | ||||
| github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= | ||||
| github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= | ||||
| github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= | ||||
| github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= | ||||
| github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= | ||||
| github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= | ||||
| github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= | ||||
| github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= | ||||
| github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= | ||||
| github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= | ||||
| github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= | ||||
| github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= | ||||
| github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||
| github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||
| github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= | ||||
| github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||
| github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
| github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= | ||||
| github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU= | ||||
| github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= | ||||
| github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | ||||
| github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= | ||||
| github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= | ||||
| github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= | ||||
| github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= | ||||
| github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= | ||||
| github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= | ||||
| github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= | ||||
| github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= | ||||
| github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= | ||||
| github.com/xo/dburl v0.0.0-20191005012637-293c3298d6c0 h1:6DtWz8hNS4qbq0OCRPhdBMG9E2qKTSDKlwnP3dmZvuA= | ||||
| github.com/xo/dburl v0.0.0-20191005012637-293c3298d6c0/go.mod h1:A47W3pdWONaZmXuLZgfKLAVgUY0qvfTRM5vVDKS40S4= | ||||
| github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= | ||||
| go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= | ||||
| go.etcd.io/etcd v3.3.13+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI= | ||||
| go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= | ||||
| go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= | ||||
| go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | ||||
| go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= | ||||
| go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= | ||||
| golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5hzyggAkLLlCUjqfRxd8Q4= | ||||
| golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= | ||||
| golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||||
| golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
| golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | ||||
| golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
| golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||||
| golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||||
| golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= | ||||
| golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20191007182048-72f939374954 h1:JGZucVF/L/TotR719NbujzadOZ2AgnYlqphQGHDCKaU= | ||||
| golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA= | ||||
| golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= | ||||
| golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||||
| golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= | ||||
| golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= | ||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU= | ||||
| golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2 h1:nq114VpM8lsSlP+lyUbANecYHYiFcSNFtqcBlxRV+gA= | ||||
| golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= | ||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
| golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= | ||||
| golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | ||||
| golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | ||||
| golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | ||||
| golang.org/x/tools v0.0.0-20190909030654-5b82db07426d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= | ||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= | ||||
| google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= | ||||
| google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= | ||||
| google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= | ||||
| google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= | ||||
| google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | ||||
| google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= | ||||
| google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | ||||
| google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | ||||
| google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | ||||
| google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | ||||
| google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | ||||
| google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | ||||
| google.golang.org/genproto v0.0.0-20190605220351-eb0b1bdb6ae6/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= | ||||
| google.golang.org/genproto v0.0.0-20191007204434-a023cd5227bd h1:84VQPzup3IpKLxuIAZjHMhVjJ8fZ4/i3yUnj3k6fUdw= | ||||
| google.golang.org/genproto v0.0.0-20191007204434-a023cd5227bd/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= | ||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | ||||
| google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | ||||
| google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | ||||
| google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= | ||||
| google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= | ||||
| gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= | ||||
| gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= | ||||
| gopkg.in/coreos/go-oidc.v2 v2.1.0 h1:E8PjVFdj/SLDKB0hvb70KTbMbYVHjqztiQdSkIg8E+I= | ||||
| gopkg.in/coreos/go-oidc.v2 v2.1.0/go.mod h1:fYaTe2FS96wZZwR17YTDHwG+Mw6fmyqJNxN2eNCGPCI= | ||||
| gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | ||||
| gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= | ||||
| gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= | ||||
| gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= | ||||
| gopkg.in/square/go-jose.v2 v2.4.0 h1:0kXPskUMGAXXWJlP05ktEMOV0vmzFQUWw6d+aZJQU8A= | ||||
| gopkg.in/square/go-jose.v2 v2.4.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | ||||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | ||||
| gopkg.in/urfave/cli.v2 v2.0.0-20180128181224-d604b6ffeee8 h1:/pLAskKF+d5SawboKd8GB8ew4ClHDbt2c3K9EBFeRGU= | ||||
| gopkg.in/urfave/cli.v2 v2.0.0-20180128181224-d604b6ffeee8/go.mod h1:cKXr3E0k4aosgycml1b5z33BVV6hai1Kh7uDgFOkbcs= | ||||
| gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= | ||||
| gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= | ||||
| gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= | ||||
| mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= | ||||
| mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= | ||||
| sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= | ||||
| zombiezen.com/go/capnproto2 v0.0.0-20180616160808-7cfd211c19c7 h1:CZoOFlTPbKfAShKYrMuUfYbnXexFT1rYRUX1SPnrdE4= | ||||
| zombiezen.com/go/capnproto2 v0.0.0-20180616160808-7cfd211c19c7/go.mod h1:TMGa8HWGJkXiq4nHe9Zu/JgRF5oUtg4XizFC+Vexbec= | ||||
|  |  | |||
|  | @ -660,6 +660,7 @@ func (h *TunnelHandler) serveWebsocket(stream *h2mux.MuxedStream, req *http.Requ | |||
| 	// Copy to/from stream to the undelying connection. Use the underlying
 | ||||
| 	// connection because cloudflared doesn't operate on the message themselves
 | ||||
| 	websocket.Stream(conn.UnderlyingConn(), stream) | ||||
| 
 | ||||
| 	return response, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -105,7 +105,7 @@ func NewWebSocketService(tlsConfig *tls.Config, url *url.URL) (OriginService, er | |||
| 	} | ||||
| 	shutdownC := make(chan struct{}) | ||||
| 	go func() { | ||||
| 		websocket.StartProxyServer(log.CreateLogger(), listener, url.String(), shutdownC) | ||||
| 		websocket.StartProxyServer(log.CreateLogger(), listener, url.String(), shutdownC, websocket.DefaultStreamHandler) | ||||
| 	}() | ||||
| 	return &WebsocketService{ | ||||
| 		tlsConfig: tlsConfig, | ||||
|  |  | |||
|  | @ -0,0 +1,77 @@ | |||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	// NoAuth means no authentication is used when connecting
 | ||||
| 	NoAuth = uint8(0) | ||||
| 
 | ||||
| 	// UserPassAuth means a user/password is used when connecting
 | ||||
| 	UserPassAuth = uint8(2) | ||||
| 
 | ||||
| 	noAcceptable    = uint8(255) | ||||
| 	userAuthVersion = uint8(1) | ||||
| 	authSuccess     = uint8(0) | ||||
| 	authFailure     = uint8(1) | ||||
| ) | ||||
| 
 | ||||
| // AuthHandler handles socks authenication requests
 | ||||
| type AuthHandler interface { | ||||
| 	Handle(io.Reader, io.Writer) error | ||||
| 	Register(uint8, Authenticator) | ||||
| } | ||||
| 
 | ||||
| // StandardAuthHandler loads the default authenticators
 | ||||
| type StandardAuthHandler struct { | ||||
| 	authenticators map[uint8]Authenticator | ||||
| } | ||||
| 
 | ||||
| // NewAuthHandler creates a default auth handler
 | ||||
| func NewAuthHandler() AuthHandler { | ||||
| 	defaults := make(map[uint8]Authenticator) | ||||
| 	defaults[NoAuth] = NewNoAuthAuthenticator() | ||||
| 	return &StandardAuthHandler{ | ||||
| 		authenticators: defaults, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Register adds/replaces an Authenticator to use when handling Authentication requests
 | ||||
| func (h *StandardAuthHandler) Register(method uint8, a Authenticator) { | ||||
| 	h.authenticators[method] = a | ||||
| } | ||||
| 
 | ||||
| // Handle gets the methods from the SOCKS5 client and authenicates with the first supported method
 | ||||
| func (h *StandardAuthHandler) Handle(bufConn io.Reader, conn io.Writer) error { | ||||
| 	methods, err := readMethods(bufConn) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("Failed to read auth methods: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// first supported method is used
 | ||||
| 	for _, method := range methods { | ||||
| 		authenticator := h.authenticators[method] | ||||
| 		if authenticator != nil { | ||||
| 			return authenticator.Handle(bufConn, conn) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// failed to authenticate. No supported authentication type found
 | ||||
| 	conn.Write([]byte{socks5Version, noAcceptable}) | ||||
| 	return fmt.Errorf("unknown authentication type") | ||||
| } | ||||
| 
 | ||||
| // readMethods is used to read the number and type of methods
 | ||||
| func readMethods(r io.Reader) ([]byte, error) { | ||||
| 	header := []byte{0} | ||||
| 	if _, err := r.Read(header); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	numMethods := int(header[0]) | ||||
| 	methods := make([]byte, numMethods) | ||||
| 	_, err := io.ReadAtLeast(r, methods, numMethods) | ||||
| 	return methods, err | ||||
| } | ||||
|  | @ -0,0 +1,87 @@ | |||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| ) | ||||
| 
 | ||||
| // Authenticator is the connection passed in as a reader/writer to support different authentication types
 | ||||
| type Authenticator interface { | ||||
| 	Handle(io.Reader, io.Writer) error | ||||
| } | ||||
| 
 | ||||
| // NoAuthAuthenticator is used to handle the No Authentication mode
 | ||||
| type NoAuthAuthenticator struct{} | ||||
| 
 | ||||
| // NewNoAuthAuthenticator creates a authless Authenticator
 | ||||
| func NewNoAuthAuthenticator() Authenticator { | ||||
| 	return &NoAuthAuthenticator{} | ||||
| } | ||||
| 
 | ||||
| // Handle writes back the version and NoAuth
 | ||||
| func (a *NoAuthAuthenticator) Handle(reader io.Reader, writer io.Writer) error { | ||||
| 	_, err := writer.Write([]byte{socks5Version, NoAuth}) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| // UserPassAuthAuthenticator is used to handle the user/password mode
 | ||||
| type UserPassAuthAuthenticator struct { | ||||
| 	IsValid func(string, string) bool | ||||
| } | ||||
| 
 | ||||
| // NewUserPassAuthAuthenticator creates a new username/password validator Authenticator
 | ||||
| func NewUserPassAuthAuthenticator(isValid func(string, string) bool) Authenticator { | ||||
| 	return &UserPassAuthAuthenticator{ | ||||
| 		IsValid: isValid, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Handle writes back the version and NoAuth
 | ||||
| func (a *UserPassAuthAuthenticator) Handle(reader io.Reader, writer io.Writer) error { | ||||
| 	if _, err := writer.Write([]byte{socks5Version, UserPassAuth}); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the version and username length
 | ||||
| 	header := []byte{0, 0} | ||||
| 	if _, err := io.ReadAtLeast(reader, header, 2); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Ensure compatibility. Someone call E-harmony
 | ||||
| 	if header[0] != userAuthVersion { | ||||
| 		return fmt.Errorf("Unsupported auth version: %v", header[0]) | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the user name
 | ||||
| 	userLen := int(header[1]) | ||||
| 	user := make([]byte, userLen) | ||||
| 	if _, err := io.ReadAtLeast(reader, user, userLen); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the password length
 | ||||
| 	if _, err := reader.Read(header[:1]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the password
 | ||||
| 	passLen := int(header[0]) | ||||
| 	pass := make([]byte, passLen) | ||||
| 	if _, err := io.ReadAtLeast(reader, pass, passLen); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Verify the password
 | ||||
| 	if a.IsValid(string(user), string(pass)) { | ||||
| 		_, err := writer.Write([]byte{userAuthVersion, authSuccess}) | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// password failed. Write back failure
 | ||||
| 	if _, err := writer.Write([]byte{userAuthVersion, authFailure}); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return fmt.Errorf("User authentication failed") | ||||
| } | ||||
|  | @ -0,0 +1,57 @@ | |||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| ) | ||||
| 
 | ||||
| // ConnectionHandler is the Serve method to handle connections
 | ||||
| // from a local TCP listener of the standard library (net.Listener)
 | ||||
| type ConnectionHandler interface { | ||||
| 	Serve(io.ReadWriter) error | ||||
| } | ||||
| 
 | ||||
| // StandardConnectionHandler is the base implementation of handling SOCKS5 requests
 | ||||
| type StandardConnectionHandler struct { | ||||
| 	requestHandler RequestHandler | ||||
| 	authHandler    AuthHandler | ||||
| } | ||||
| 
 | ||||
| // NewConnectionHandler creates a standard SOCKS5 connection handler
 | ||||
| // This process connections from a generic TCP listener from the standard library
 | ||||
| func NewConnectionHandler(requestHandler RequestHandler) ConnectionHandler { | ||||
| 	return &StandardConnectionHandler{ | ||||
| 		requestHandler: requestHandler, | ||||
| 		authHandler:    NewAuthHandler(), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Serve process new connection created after calling `Accept()` in the standard library
 | ||||
| func (h *StandardConnectionHandler) Serve(c io.ReadWriter) error { | ||||
| 	bufConn := bufio.NewReader(c) | ||||
| 
 | ||||
| 	// read the version byte
 | ||||
| 	version := []byte{0} | ||||
| 	if _, err := bufConn.Read(version); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// ensure compatibility
 | ||||
| 	if version[0] != socks5Version { | ||||
| 		return fmt.Errorf("Unsupported SOCKS version: %v", version) | ||||
| 	} | ||||
| 
 | ||||
| 	// handle auth
 | ||||
| 	if err := h.authHandler.Handle(bufConn, c); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// process command/request
 | ||||
| 	req, err := NewRequest(bufConn) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return h.requestHandler.Handle(req, c) | ||||
| } | ||||
|  | @ -0,0 +1,88 @@ | |||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"io/ioutil" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"golang.org/x/net/proxy" | ||||
| ) | ||||
| 
 | ||||
| type successResponse struct { | ||||
| 	Status string `json:"status"` | ||||
| } | ||||
| 
 | ||||
| func sendSocksRequest(t *testing.T) []byte { | ||||
| 	dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:8086", nil, proxy.Direct) | ||||
| 	assert.NoError(t, err) | ||||
| 
 | ||||
| 	httpTransport := &http.Transport{} | ||||
| 	httpClient := &http.Client{Transport: httpTransport} | ||||
| 	// set our socks5 as the dialer
 | ||||
| 	httpTransport.Dial = dialer.Dial | ||||
| 
 | ||||
| 	req, err := http.NewRequest("GET", "http://127.0.0.1:8085", nil) | ||||
| 	assert.NoError(t, err) | ||||
| 
 | ||||
| 	resp, err := httpClient.Do(req) | ||||
| 	assert.NoError(t, err) | ||||
| 	defer resp.Body.Close() | ||||
| 
 | ||||
| 	b, err := ioutil.ReadAll(resp.Body) | ||||
| 	assert.NoError(t, err) | ||||
| 
 | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| func startTestServer(t *testing.T, httpHandler func(w http.ResponseWriter, r *http.Request)) { | ||||
| 	// create a socks server
 | ||||
| 	requestHandler := NewRequestHandler(NewNetDialer()) | ||||
| 	socksServer := NewConnectionHandler(requestHandler) | ||||
| 	listener, err := net.Listen("tcp", ":8086") | ||||
| 	assert.NoError(t, err) | ||||
| 
 | ||||
| 	go func() { | ||||
| 		defer listener.Close() | ||||
| 		for { | ||||
| 			conn, _ := listener.Accept() | ||||
| 			go socksServer.Serve(conn) | ||||
| 		} | ||||
| 	}() | ||||
| 
 | ||||
| 	// create an http server
 | ||||
| 	mux := http.NewServeMux() | ||||
| 	mux.HandleFunc("/", httpHandler) | ||||
| 
 | ||||
| 	// start the servers
 | ||||
| 	go http.ListenAndServe(":8085", mux) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func respondWithJSON(w http.ResponseWriter, v interface{}, status int) { | ||||
| 	data, _ := json.Marshal(v) | ||||
| 
 | ||||
| 	w.Header().Set("Content-Type", "application/json") | ||||
| 	w.WriteHeader(status) | ||||
| 	w.Write(data) | ||||
| } | ||||
| 
 | ||||
| func OkJSONResponseHandler(w http.ResponseWriter, r *http.Request) { | ||||
| 	resp := successResponse{ | ||||
| 		Status: "ok", | ||||
| 	} | ||||
| 	respondWithJSON(w, resp, http.StatusOK) | ||||
| } | ||||
| 
 | ||||
| func TestSocksConnection(t *testing.T) { | ||||
| 	startTestServer(t, OkJSONResponseHandler) | ||||
| 	b := sendSocksRequest(t) | ||||
| 	assert.True(t, len(b) > 0, "no data returned!") | ||||
| 
 | ||||
| 	var resp successResponse | ||||
| 	json.Unmarshal(b, &resp) | ||||
| 
 | ||||
| 	assert.True(t, resp.Status == "ok", "response didn't return ok") | ||||
| } | ||||
|  | @ -0,0 +1,57 @@ | |||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net" | ||||
| ) | ||||
| 
 | ||||
| // Dialer is used to provided the transport of the proxy
 | ||||
| type Dialer interface { | ||||
| 	Dial(string) (io.ReadWriteCloser, *AddrSpec, error) | ||||
| } | ||||
| 
 | ||||
| // NetDialer is a standard TCP dialer
 | ||||
| type NetDialer struct { | ||||
| } | ||||
| 
 | ||||
| // NewNetDialer creates a new dialer
 | ||||
| func NewNetDialer() Dialer { | ||||
| 	return &NetDialer{} | ||||
| } | ||||
| 
 | ||||
| // Dial is a base TCP dialer
 | ||||
| func (d *NetDialer) Dial(address string) (io.ReadWriteCloser, *AddrSpec, error) { | ||||
| 	c, err := net.Dial("tcp", address) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	local := c.LocalAddr().(*net.TCPAddr) | ||||
| 	addr := AddrSpec{IP: local.IP, Port: local.Port} | ||||
| 
 | ||||
| 	return c, &addr, nil | ||||
| } | ||||
| 
 | ||||
| // ConnDialer is like NetDialer but with an existing TCP dialer already created
 | ||||
| type ConnDialer struct { | ||||
| 	conn net.Conn | ||||
| } | ||||
| 
 | ||||
| // NewConnDialer creates a new dialer with a already created net.conn (TCP expected)
 | ||||
| func NewConnDialer(conn net.Conn) Dialer { | ||||
| 	return &ConnDialer{ | ||||
| 		conn: conn, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Dial is a TCP dialer but already created
 | ||||
| func (d *ConnDialer) Dial(address string) (io.ReadWriteCloser, *AddrSpec, error) { | ||||
| 	local, ok := d.conn.LocalAddr().(*net.TCPAddr) | ||||
| 	if !ok { | ||||
| 		return nil, nil, fmt.Errorf("not a tcp connection") | ||||
| 	} | ||||
| 
 | ||||
| 	addr := AddrSpec{IP: local.IP, Port: local.Port} | ||||
| 	return d.conn, &addr, nil | ||||
| } | ||||
|  | @ -0,0 +1,195 @@ | |||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"strconv" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	// version
 | ||||
| 	socks5Version = uint8(5) | ||||
| 
 | ||||
| 	// commands https://tools.ietf.org/html/rfc1928#section-4
 | ||||
| 	connectCommand   = uint8(1) | ||||
| 	bindCommand      = uint8(2) | ||||
| 	associateCommand = uint8(3) | ||||
| 
 | ||||
| 	// address types
 | ||||
| 	ipv4Address = uint8(1) | ||||
| 	fqdnAddress = uint8(3) | ||||
| 	ipv6Address = uint8(4) | ||||
| ) | ||||
| 
 | ||||
| // https://tools.ietf.org/html/rfc1928#section-6
 | ||||
| const ( | ||||
| 	successReply uint8 = iota | ||||
| 	serverFailure | ||||
| 	ruleFailure | ||||
| 	networkUnreachable | ||||
| 	hostUnreachable | ||||
| 	connectionRefused | ||||
| 	ttlExpired | ||||
| 	commandNotSupported | ||||
| 	addrTypeNotSupported | ||||
| ) | ||||
| 
 | ||||
| // AddrSpec is used to return the target IPv4, IPv6, or a FQDN
 | ||||
| type AddrSpec struct { | ||||
| 	FQDN string | ||||
| 	IP   net.IP | ||||
| 	Port int | ||||
| } | ||||
| 
 | ||||
| // String gives a host version of the Address
 | ||||
| func (a *AddrSpec) String() string { | ||||
| 	if a.FQDN != "" { | ||||
| 		return fmt.Sprintf("%s (%s):%d", a.FQDN, a.IP, a.Port) | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s:%d", a.IP, a.Port) | ||||
| } | ||||
| 
 | ||||
| // Address returns a string suitable to dial; prefer returning IP-based
 | ||||
| // address, fallback to FQDN
 | ||||
| func (a AddrSpec) Address() string { | ||||
| 	if len(a.IP) != 0 { | ||||
| 		return net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port)) | ||||
| 	} | ||||
| 	return net.JoinHostPort(a.FQDN, strconv.Itoa(a.Port)) | ||||
| } | ||||
| 
 | ||||
| // Request is a SOCKS5 command with supporting field of the connection
 | ||||
| type Request struct { | ||||
| 	// Protocol version
 | ||||
| 	Version uint8 | ||||
| 	// Requested command
 | ||||
| 	Command uint8 | ||||
| 	// AddrSpec of the destination
 | ||||
| 	DestAddr *AddrSpec | ||||
| 	// reading from the connection
 | ||||
| 	bufConn io.Reader | ||||
| } | ||||
| 
 | ||||
| // NewRequest creates a new request from the connection data stream
 | ||||
| func NewRequest(bufConn io.Reader) (*Request, error) { | ||||
| 	// Read the version byte
 | ||||
| 	header := []byte{0, 0, 0} | ||||
| 	if _, err := io.ReadAtLeast(bufConn, header, 3); err != nil { | ||||
| 		return nil, fmt.Errorf("Failed to get command version: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// ensure compatibility
 | ||||
| 	if header[0] != socks5Version { | ||||
| 		return nil, fmt.Errorf("Unsupported command version: %v", header[0]) | ||||
| 	} | ||||
| 
 | ||||
| 	// Read in the destination address
 | ||||
| 	dest, err := readAddrSpec(bufConn) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return &Request{ | ||||
| 		Version:  socks5Version, | ||||
| 		Command:  header[1], | ||||
| 		DestAddr: dest, | ||||
| 		bufConn:  bufConn, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func sendReply(w io.Writer, resp uint8, addr *AddrSpec) error { | ||||
| 	var addrType uint8 | ||||
| 	var addrBody []byte | ||||
| 	var addrPort uint16 | ||||
| 	switch { | ||||
| 	case addr == nil: | ||||
| 		addrType = ipv4Address | ||||
| 		addrBody = []byte{0, 0, 0, 0} | ||||
| 		addrPort = 0 | ||||
| 
 | ||||
| 	case addr.FQDN != "": | ||||
| 		addrType = fqdnAddress | ||||
| 		addrBody = append([]byte{byte(len(addr.FQDN))}, addr.FQDN...) | ||||
| 		addrPort = uint16(addr.Port) | ||||
| 
 | ||||
| 	case addr.IP.To4() != nil: | ||||
| 		addrType = ipv4Address | ||||
| 		addrBody = []byte(addr.IP.To4()) | ||||
| 		addrPort = uint16(addr.Port) | ||||
| 
 | ||||
| 	case addr.IP.To16() != nil: | ||||
| 		addrType = ipv6Address | ||||
| 		addrBody = []byte(addr.IP.To16()) | ||||
| 		addrPort = uint16(addr.Port) | ||||
| 
 | ||||
| 	default: | ||||
| 		return fmt.Errorf("Failed to format address: %v", addr) | ||||
| 	} | ||||
| 
 | ||||
| 	// Format the message
 | ||||
| 	msg := make([]byte, 6+len(addrBody)) | ||||
| 	msg[0] = socks5Version | ||||
| 	msg[1] = resp | ||||
| 	msg[2] = 0 // Reserved
 | ||||
| 	msg[3] = addrType | ||||
| 	copy(msg[4:], addrBody) | ||||
| 	msg[4+len(addrBody)] = byte(addrPort >> 8) | ||||
| 	msg[4+len(addrBody)+1] = byte(addrPort & 0xff) | ||||
| 
 | ||||
| 	// Send the message
 | ||||
| 	_, err := w.Write(msg) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| // readAddrSpec is used to read AddrSpec.
 | ||||
| // Expects an address type byte, followed by the address and port
 | ||||
| func readAddrSpec(r io.Reader) (*AddrSpec, error) { | ||||
| 	d := &AddrSpec{} | ||||
| 
 | ||||
| 	// Get the address type
 | ||||
| 	addrType := []byte{0} | ||||
| 	if _, err := r.Read(addrType); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// Handle on a per type basis
 | ||||
| 	switch addrType[0] { | ||||
| 	case ipv4Address: | ||||
| 		addr := make([]byte, 4) | ||||
| 		if _, err := io.ReadAtLeast(r, addr, len(addr)); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		d.IP = net.IP(addr) | ||||
| 
 | ||||
| 	case ipv6Address: | ||||
| 		addr := make([]byte, 16) | ||||
| 		if _, err := io.ReadAtLeast(r, addr, len(addr)); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		d.IP = net.IP(addr) | ||||
| 
 | ||||
| 	case fqdnAddress: | ||||
| 		if _, err := r.Read(addrType); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		addrLen := int(addrType[0]) | ||||
| 		fqdn := make([]byte, addrLen) | ||||
| 		if _, err := io.ReadAtLeast(r, fqdn, addrLen); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		d.FQDN = string(fqdn) | ||||
| 
 | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("Unrecognized address type") | ||||
| 	} | ||||
| 
 | ||||
| 	// Read the port
 | ||||
| 	port := []byte{0, 0} | ||||
| 	if _, err := io.ReadAtLeast(r, port, 2); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	d.Port = (int(port[0]) << 8) | int(port[1]) | ||||
| 
 | ||||
| 	return d, nil | ||||
| } | ||||
|  | @ -0,0 +1,106 @@ | |||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| // RequestHandler is the functions needed to handle a SOCKS5 command
 | ||||
| type RequestHandler interface { | ||||
| 	Handle(*Request, io.ReadWriter) error | ||||
| } | ||||
| 
 | ||||
| // StandardRequestHandler implements the base socks5 command processing
 | ||||
| type StandardRequestHandler struct { | ||||
| 	dialer Dialer | ||||
| } | ||||
| 
 | ||||
| // NewRequestHandler creates a standard SOCKS5 request handler
 | ||||
| // This handles the SOCKS5 commands and proxies them to their destination
 | ||||
| func NewRequestHandler(dialer Dialer) RequestHandler { | ||||
| 	return &StandardRequestHandler{ | ||||
| 		dialer: dialer, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Handle processes and responds to socks5 commands
 | ||||
| func (h *StandardRequestHandler) Handle(req *Request, conn io.ReadWriter) error { | ||||
| 	switch req.Command { | ||||
| 	case connectCommand: | ||||
| 		return h.handleConnect(conn, req) | ||||
| 	case bindCommand: | ||||
| 		return h.handleBind(conn, req) | ||||
| 	case associateCommand: | ||||
| 		return h.handleAssociate(conn, req) | ||||
| 	default: | ||||
| 		if err := sendReply(conn, commandNotSupported, nil); err != nil { | ||||
| 			return fmt.Errorf("Failed to send reply: %v", err) | ||||
| 		} | ||||
| 		return fmt.Errorf("Unsupported command: %v", req.Command) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // handleConnect is used to handle a connect command
 | ||||
| func (h *StandardRequestHandler) handleConnect(conn io.ReadWriter, req *Request) error { | ||||
| 	target, localAddr, err := h.dialer.Dial(req.DestAddr.Address()) | ||||
| 	if err != nil { | ||||
| 		msg := err.Error() | ||||
| 		resp := hostUnreachable | ||||
| 		if strings.Contains(msg, "refused") { | ||||
| 			resp = connectionRefused | ||||
| 		} else if strings.Contains(msg, "network is unreachable") { | ||||
| 			resp = networkUnreachable | ||||
| 		} | ||||
| 		if err := sendReply(conn, resp, nil); err != nil { | ||||
| 			return fmt.Errorf("Failed to send reply: %v", err) | ||||
| 		} | ||||
| 		return fmt.Errorf("Connect to %v failed: %v", req.DestAddr, err) | ||||
| 	} | ||||
| 	defer target.Close() | ||||
| 
 | ||||
| 	// Send success
 | ||||
| 	if err := sendReply(conn, successReply, localAddr); err != nil { | ||||
| 		return fmt.Errorf("Failed to send reply: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Start proxying
 | ||||
| 	proxyDone := make(chan error, 2) | ||||
| 
 | ||||
| 	go func() { | ||||
| 		_, e := io.Copy(target, req.bufConn) | ||||
| 		proxyDone <- e | ||||
| 	}() | ||||
| 
 | ||||
| 	go func() { | ||||
| 		_, e := io.Copy(conn, target) | ||||
| 		proxyDone <- e | ||||
| 	}() | ||||
| 
 | ||||
| 	// Wait for both
 | ||||
| 	for i := 0; i < 2; i++ { | ||||
| 		e := <-proxyDone | ||||
| 		if e != nil { | ||||
| 			return e | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // handleBind is used to handle a bind command
 | ||||
| // TODO: Support bind command
 | ||||
| func (h *StandardRequestHandler) handleBind(conn io.ReadWriter, req *Request) error { | ||||
| 	if err := sendReply(conn, commandNotSupported, nil); err != nil { | ||||
| 		return fmt.Errorf("Failed to send reply: %v", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // handleAssociate is used to handle a connect command
 | ||||
| // TODO: Support associate command
 | ||||
| func (h *StandardRequestHandler) handleAssociate(conn io.ReadWriter, req *Request) error { | ||||
| 	if err := sendReply(conn, commandNotSupported, nil); err != nil { | ||||
| 		return fmt.Errorf("Failed to send reply: %v", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | @ -0,0 +1,28 @@ | |||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestUnsupportedBind(t *testing.T) { | ||||
| 	req := createRequest(t, socks5Version, bindCommand, "2001:db8::68", 1337, false) | ||||
| 	var b bytes.Buffer | ||||
| 
 | ||||
| 	requestHandler := NewRequestHandler(NewNetDialer()) | ||||
| 	err := requestHandler.Handle(req, &b) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.True(t, b.Bytes()[1] == commandNotSupported, "expected a response") | ||||
| } | ||||
| 
 | ||||
| func TestUnsupportedAssociate(t *testing.T) { | ||||
| 	req := createRequest(t, socks5Version, associateCommand, "127.0.0.1", 1337, false) | ||||
| 	var b bytes.Buffer | ||||
| 
 | ||||
| 	requestHandler := NewRequestHandler(NewNetDialer()) | ||||
| 	err := requestHandler.Handle(req, &b) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.True(t, b.Bytes()[1] == commandNotSupported, "expected a response") | ||||
| } | ||||
|  | @ -0,0 +1,69 @@ | |||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"net" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func createRequestData(version, command uint8, ip net.IP, port uint16) []byte { | ||||
| 	// set the command
 | ||||
| 	b := []byte{version, command, 0} | ||||
| 
 | ||||
| 	// append the ip
 | ||||
| 	if len(ip) == net.IPv4len { | ||||
| 		b = append(b, 1) | ||||
| 		b = append(b, ip.To4()...) | ||||
| 	} else { | ||||
| 		b = append(b, 4) | ||||
| 		b = append(b, ip.To16()...) | ||||
| 	} | ||||
| 
 | ||||
| 	// append the port
 | ||||
| 	p := []byte{0, 0} | ||||
| 	binary.BigEndian.PutUint16(p, port) | ||||
| 	b = append(b, p...) | ||||
| 
 | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| func createRequest(t *testing.T, version, command uint8, ipStr string, port uint16, shouldFail bool) *Request { | ||||
| 	ip := net.ParseIP(ipStr) | ||||
| 	data := createRequestData(version, command, ip, port) | ||||
| 	reader := bytes.NewReader(data) | ||||
| 	req, err := NewRequest(reader) | ||||
| 	if shouldFail { | ||||
| 		assert.Error(t, err) | ||||
| 		return nil | ||||
| 	} | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.True(t, req.Version == socks5Version, "version doesn't match expectation: %v", req.Version) | ||||
| 	assert.True(t, req.Command == command, "command doesn't match expectation: %v", req.Command) | ||||
| 	assert.True(t, req.DestAddr.Port == int(port), "port doesn't match expectation: %v", req.DestAddr.Port) | ||||
| 	assert.True(t, req.DestAddr.IP.String() == ipStr, "ip doesn't match expectation: %v", req.DestAddr.IP.String()) | ||||
| 
 | ||||
| 	return req | ||||
| } | ||||
| 
 | ||||
| func TestValidConnectRequest(t *testing.T) { | ||||
| 	createRequest(t, socks5Version, connectCommand, "127.0.0.1", 1337, false) | ||||
| } | ||||
| 
 | ||||
| func TestValidBindRequest(t *testing.T) { | ||||
| 	createRequest(t, socks5Version, bindCommand, "2001:db8::68", 1337, false) | ||||
| } | ||||
| 
 | ||||
| func TestValidAssociateRequest(t *testing.T) { | ||||
| 	createRequest(t, socks5Version, associateCommand, "127.0.0.1", 1234, false) | ||||
| } | ||||
| 
 | ||||
| func TestInValidVersionRequest(t *testing.T) { | ||||
| 	createRequest(t, 4, connectCommand, "127.0.0.1", 1337, true) | ||||
| } | ||||
| 
 | ||||
| func TestInValidIPRequest(t *testing.T) { | ||||
| 	createRequest(t, 4, connectCommand, "127.0.01", 1337, true) | ||||
| } | ||||
|  | @ -17,6 +17,7 @@ type pipe struct { | |||
| 	mu       sync.Mutex | ||||
| 	c        sync.Cond     // c.L lazily initialized to &p.mu
 | ||||
| 	b        pipeBuffer    // nil when done reading
 | ||||
| 	unread   int           // bytes unread when done
 | ||||
| 	err      error         // read error once empty. non-nil means closed.
 | ||||
| 	breakErr error         // immediate read error (caller doesn't see rest of b)
 | ||||
| 	donec    chan struct{} // closed on error
 | ||||
|  | @ -33,7 +34,7 @@ func (p *pipe) Len() int { | |||
| 	p.mu.Lock() | ||||
| 	defer p.mu.Unlock() | ||||
| 	if p.b == nil { | ||||
| 		return 0 | ||||
| 		return p.unread | ||||
| 	} | ||||
| 	return p.b.Len() | ||||
| } | ||||
|  | @ -80,6 +81,7 @@ func (p *pipe) Write(d []byte) (n int, err error) { | |||
| 		return 0, errClosedPipeWrite | ||||
| 	} | ||||
| 	if p.breakErr != nil { | ||||
| 		p.unread += len(d) | ||||
| 		return len(d), nil // discard when there is no reader
 | ||||
| 	} | ||||
| 	return p.b.Write(d) | ||||
|  | @ -117,6 +119,9 @@ func (p *pipe) closeWithError(dst *error, err error, fn func()) { | |||
| 	} | ||||
| 	p.readFn = fn | ||||
| 	if dst == &p.breakErr { | ||||
| 		if p.b != nil { | ||||
| 			p.unread += p.b.Len() | ||||
| 		} | ||||
| 		p.b = nil | ||||
| 	} | ||||
| 	*dst = err | ||||
|  |  | |||
|  | @ -2415,7 +2415,11 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { | |||
| 			clen = strconv.Itoa(len(p)) | ||||
| 		} | ||||
| 		_, hasContentType := rws.snapHeader["Content-Type"] | ||||
| 		if !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 { | ||||
| 		// If the Content-Encoding is non-blank, we shouldn't
 | ||||
| 		// sniff the body. See Issue golang.org/issue/31753.
 | ||||
| 		ce := rws.snapHeader.Get("Content-Encoding") | ||||
| 		hasCE := len(ce) > 0 | ||||
| 		if !hasCE && !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 { | ||||
| 			ctype = http.DetectContentType(p) | ||||
| 		} | ||||
| 		var date string | ||||
|  |  | |||
|  | @ -603,7 +603,7 @@ func (t *Transport) expectContinueTimeout() time.Duration { | |||
| } | ||||
| 
 | ||||
| func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { | ||||
| 	return t.newClientConn(c, false) | ||||
| 	return t.newClientConn(c, t.disableKeepAlives()) | ||||
| } | ||||
| 
 | ||||
| func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { | ||||
|  | @ -1478,7 +1478,29 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail | |||
| 				if vv[0] == "" { | ||||
| 					continue | ||||
| 				} | ||||
| 
 | ||||
| 			} else if strings.EqualFold(k, "cookie") { | ||||
| 				// Per 8.1.2.5 To allow for better compression efficiency, the
 | ||||
| 				// Cookie header field MAY be split into separate header fields,
 | ||||
| 				// each with one or more cookie-pairs.
 | ||||
| 				for _, v := range vv { | ||||
| 					for { | ||||
| 						p := strings.IndexByte(v, ';') | ||||
| 						if p < 0 { | ||||
| 							break | ||||
| 						} | ||||
| 						f("cookie", v[:p]) | ||||
| 						p++ | ||||
| 						// strip space after semicolon if any.
 | ||||
| 						for p+1 <= len(v) && v[p] == ' ' { | ||||
| 							p++ | ||||
| 						} | ||||
| 						v = v[p:] | ||||
| 					} | ||||
| 					if len(v) > 0 { | ||||
| 						f("cookie", v) | ||||
| 					} | ||||
| 				} | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			for _, v := range vv { | ||||
|  |  | |||
|  | @ -0,0 +1,168 @@ | |||
| // Copyright 2018 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	noDeadline   = time.Time{} | ||||
| 	aLongTimeAgo = time.Unix(1, 0) | ||||
| ) | ||||
| 
 | ||||
| func (d *Dialer) connect(ctx context.Context, c net.Conn, address string) (_ net.Addr, ctxErr error) { | ||||
| 	host, port, err := splitHostPort(address) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() { | ||||
| 		c.SetDeadline(deadline) | ||||
| 		defer c.SetDeadline(noDeadline) | ||||
| 	} | ||||
| 	if ctx != context.Background() { | ||||
| 		errCh := make(chan error, 1) | ||||
| 		done := make(chan struct{}) | ||||
| 		defer func() { | ||||
| 			close(done) | ||||
| 			if ctxErr == nil { | ||||
| 				ctxErr = <-errCh | ||||
| 			} | ||||
| 		}() | ||||
| 		go func() { | ||||
| 			select { | ||||
| 			case <-ctx.Done(): | ||||
| 				c.SetDeadline(aLongTimeAgo) | ||||
| 				errCh <- ctx.Err() | ||||
| 			case <-done: | ||||
| 				errCh <- nil | ||||
| 			} | ||||
| 		}() | ||||
| 	} | ||||
| 
 | ||||
| 	b := make([]byte, 0, 6+len(host)) // the size here is just an estimate
 | ||||
| 	b = append(b, Version5) | ||||
| 	if len(d.AuthMethods) == 0 || d.Authenticate == nil { | ||||
| 		b = append(b, 1, byte(AuthMethodNotRequired)) | ||||
| 	} else { | ||||
| 		ams := d.AuthMethods | ||||
| 		if len(ams) > 255 { | ||||
| 			return nil, errors.New("too many authentication methods") | ||||
| 		} | ||||
| 		b = append(b, byte(len(ams))) | ||||
| 		for _, am := range ams { | ||||
| 			b = append(b, byte(am)) | ||||
| 		} | ||||
| 	} | ||||
| 	if _, ctxErr = c.Write(b); ctxErr != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if _, ctxErr = io.ReadFull(c, b[:2]); ctxErr != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if b[0] != Version5 { | ||||
| 		return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0]))) | ||||
| 	} | ||||
| 	am := AuthMethod(b[1]) | ||||
| 	if am == AuthMethodNoAcceptableMethods { | ||||
| 		return nil, errors.New("no acceptable authentication methods") | ||||
| 	} | ||||
| 	if d.Authenticate != nil { | ||||
| 		if ctxErr = d.Authenticate(ctx, c, am); ctxErr != nil { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	b = b[:0] | ||||
| 	b = append(b, Version5, byte(d.cmd), 0) | ||||
| 	if ip := net.ParseIP(host); ip != nil { | ||||
| 		if ip4 := ip.To4(); ip4 != nil { | ||||
| 			b = append(b, AddrTypeIPv4) | ||||
| 			b = append(b, ip4...) | ||||
| 		} else if ip6 := ip.To16(); ip6 != nil { | ||||
| 			b = append(b, AddrTypeIPv6) | ||||
| 			b = append(b, ip6...) | ||||
| 		} else { | ||||
| 			return nil, errors.New("unknown address type") | ||||
| 		} | ||||
| 	} else { | ||||
| 		if len(host) > 255 { | ||||
| 			return nil, errors.New("FQDN too long") | ||||
| 		} | ||||
| 		b = append(b, AddrTypeFQDN) | ||||
| 		b = append(b, byte(len(host))) | ||||
| 		b = append(b, host...) | ||||
| 	} | ||||
| 	b = append(b, byte(port>>8), byte(port)) | ||||
| 	if _, ctxErr = c.Write(b); ctxErr != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if _, ctxErr = io.ReadFull(c, b[:4]); ctxErr != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if b[0] != Version5 { | ||||
| 		return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0]))) | ||||
| 	} | ||||
| 	if cmdErr := Reply(b[1]); cmdErr != StatusSucceeded { | ||||
| 		return nil, errors.New("unknown error " + cmdErr.String()) | ||||
| 	} | ||||
| 	if b[2] != 0 { | ||||
| 		return nil, errors.New("non-zero reserved field") | ||||
| 	} | ||||
| 	l := 2 | ||||
| 	var a Addr | ||||
| 	switch b[3] { | ||||
| 	case AddrTypeIPv4: | ||||
| 		l += net.IPv4len | ||||
| 		a.IP = make(net.IP, net.IPv4len) | ||||
| 	case AddrTypeIPv6: | ||||
| 		l += net.IPv6len | ||||
| 		a.IP = make(net.IP, net.IPv6len) | ||||
| 	case AddrTypeFQDN: | ||||
| 		if _, err := io.ReadFull(c, b[:1]); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		l += int(b[0]) | ||||
| 	default: | ||||
| 		return nil, errors.New("unknown address type " + strconv.Itoa(int(b[3]))) | ||||
| 	} | ||||
| 	if cap(b) < l { | ||||
| 		b = make([]byte, l) | ||||
| 	} else { | ||||
| 		b = b[:l] | ||||
| 	} | ||||
| 	if _, ctxErr = io.ReadFull(c, b); ctxErr != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if a.IP != nil { | ||||
| 		copy(a.IP, b) | ||||
| 	} else { | ||||
| 		a.Name = string(b[:len(b)-2]) | ||||
| 	} | ||||
| 	a.Port = int(b[len(b)-2])<<8 | int(b[len(b)-1]) | ||||
| 	return &a, nil | ||||
| } | ||||
| 
 | ||||
| func splitHostPort(address string) (string, int, error) { | ||||
| 	host, port, err := net.SplitHostPort(address) | ||||
| 	if err != nil { | ||||
| 		return "", 0, err | ||||
| 	} | ||||
| 	portnum, err := strconv.Atoi(port) | ||||
| 	if err != nil { | ||||
| 		return "", 0, err | ||||
| 	} | ||||
| 	if 1 > portnum || portnum > 0xffff { | ||||
| 		return "", 0, errors.New("port number out of range " + port) | ||||
| 	} | ||||
| 	return host, portnum, nil | ||||
| } | ||||
|  | @ -0,0 +1,317 @@ | |||
| // Copyright 2018 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| // Package socks provides a SOCKS version 5 client implementation.
 | ||||
| //
 | ||||
| // SOCKS protocol version 5 is defined in RFC 1928.
 | ||||
| // Username/Password authentication for SOCKS version 5 is defined in
 | ||||
| // RFC 1929.
 | ||||
| package socks | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"strconv" | ||||
| ) | ||||
| 
 | ||||
| // A Command represents a SOCKS command.
 | ||||
| type Command int | ||||
| 
 | ||||
| func (cmd Command) String() string { | ||||
| 	switch cmd { | ||||
| 	case CmdConnect: | ||||
| 		return "socks connect" | ||||
| 	case cmdBind: | ||||
| 		return "socks bind" | ||||
| 	default: | ||||
| 		return "socks " + strconv.Itoa(int(cmd)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // An AuthMethod represents a SOCKS authentication method.
 | ||||
| type AuthMethod int | ||||
| 
 | ||||
| // A Reply represents a SOCKS command reply code.
 | ||||
| type Reply int | ||||
| 
 | ||||
| func (code Reply) String() string { | ||||
| 	switch code { | ||||
| 	case StatusSucceeded: | ||||
| 		return "succeeded" | ||||
| 	case 0x01: | ||||
| 		return "general SOCKS server failure" | ||||
| 	case 0x02: | ||||
| 		return "connection not allowed by ruleset" | ||||
| 	case 0x03: | ||||
| 		return "network unreachable" | ||||
| 	case 0x04: | ||||
| 		return "host unreachable" | ||||
| 	case 0x05: | ||||
| 		return "connection refused" | ||||
| 	case 0x06: | ||||
| 		return "TTL expired" | ||||
| 	case 0x07: | ||||
| 		return "command not supported" | ||||
| 	case 0x08: | ||||
| 		return "address type not supported" | ||||
| 	default: | ||||
| 		return "unknown code: " + strconv.Itoa(int(code)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Wire protocol constants.
 | ||||
| const ( | ||||
| 	Version5 = 0x05 | ||||
| 
 | ||||
| 	AddrTypeIPv4 = 0x01 | ||||
| 	AddrTypeFQDN = 0x03 | ||||
| 	AddrTypeIPv6 = 0x04 | ||||
| 
 | ||||
| 	CmdConnect Command = 0x01 // establishes an active-open forward proxy connection
 | ||||
| 	cmdBind    Command = 0x02 // establishes a passive-open forward proxy connection
 | ||||
| 
 | ||||
| 	AuthMethodNotRequired         AuthMethod = 0x00 // no authentication required
 | ||||
| 	AuthMethodUsernamePassword    AuthMethod = 0x02 // use username/password
 | ||||
| 	AuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authentication methods
 | ||||
| 
 | ||||
| 	StatusSucceeded Reply = 0x00 | ||||
| ) | ||||
| 
 | ||||
| // An Addr represents a SOCKS-specific address.
 | ||||
| // Either Name or IP is used exclusively.
 | ||||
| type Addr struct { | ||||
| 	Name string // fully-qualified domain name
 | ||||
| 	IP   net.IP | ||||
| 	Port int | ||||
| } | ||||
| 
 | ||||
| func (a *Addr) Network() string { return "socks" } | ||||
| 
 | ||||
| func (a *Addr) String() string { | ||||
| 	if a == nil { | ||||
| 		return "<nil>" | ||||
| 	} | ||||
| 	port := strconv.Itoa(a.Port) | ||||
| 	if a.IP == nil { | ||||
| 		return net.JoinHostPort(a.Name, port) | ||||
| 	} | ||||
| 	return net.JoinHostPort(a.IP.String(), port) | ||||
| } | ||||
| 
 | ||||
| // A Conn represents a forward proxy connection.
 | ||||
| type Conn struct { | ||||
| 	net.Conn | ||||
| 
 | ||||
| 	boundAddr net.Addr | ||||
| } | ||||
| 
 | ||||
| // BoundAddr returns the address assigned by the proxy server for
 | ||||
| // connecting to the command target address from the proxy server.
 | ||||
| func (c *Conn) BoundAddr() net.Addr { | ||||
| 	if c == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return c.boundAddr | ||||
| } | ||||
| 
 | ||||
| // A Dialer holds SOCKS-specific options.
 | ||||
| type Dialer struct { | ||||
| 	cmd          Command // either CmdConnect or cmdBind
 | ||||
| 	proxyNetwork string  // network between a proxy server and a client
 | ||||
| 	proxyAddress string  // proxy server address
 | ||||
| 
 | ||||
| 	// ProxyDial specifies the optional dial function for
 | ||||
| 	// establishing the transport connection.
 | ||||
| 	ProxyDial func(context.Context, string, string) (net.Conn, error) | ||||
| 
 | ||||
| 	// AuthMethods specifies the list of request authentication
 | ||||
| 	// methods.
 | ||||
| 	// If empty, SOCKS client requests only AuthMethodNotRequired.
 | ||||
| 	AuthMethods []AuthMethod | ||||
| 
 | ||||
| 	// Authenticate specifies the optional authentication
 | ||||
| 	// function. It must be non-nil when AuthMethods is not empty.
 | ||||
| 	// It must return an error when the authentication is failed.
 | ||||
| 	Authenticate func(context.Context, io.ReadWriter, AuthMethod) error | ||||
| } | ||||
| 
 | ||||
| // DialContext connects to the provided address on the provided
 | ||||
| // network.
 | ||||
| //
 | ||||
| // The returned error value may be a net.OpError. When the Op field of
 | ||||
| // net.OpError contains "socks", the Source field contains a proxy
 | ||||
| // server address and the Addr field contains a command target
 | ||||
| // address.
 | ||||
| //
 | ||||
| // See func Dial of the net package of standard library for a
 | ||||
| // description of the network and address parameters.
 | ||||
| func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { | ||||
| 	if err := d.validateTarget(network, address); err != nil { | ||||
| 		proxy, dst, _ := d.pathAddrs(address) | ||||
| 		return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err} | ||||
| 	} | ||||
| 	if ctx == nil { | ||||
| 		proxy, dst, _ := d.pathAddrs(address) | ||||
| 		return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")} | ||||
| 	} | ||||
| 	var err error | ||||
| 	var c net.Conn | ||||
| 	if d.ProxyDial != nil { | ||||
| 		c, err = d.ProxyDial(ctx, d.proxyNetwork, d.proxyAddress) | ||||
| 	} else { | ||||
| 		var dd net.Dialer | ||||
| 		c, err = dd.DialContext(ctx, d.proxyNetwork, d.proxyAddress) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		proxy, dst, _ := d.pathAddrs(address) | ||||
| 		return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err} | ||||
| 	} | ||||
| 	a, err := d.connect(ctx, c, address) | ||||
| 	if err != nil { | ||||
| 		c.Close() | ||||
| 		proxy, dst, _ := d.pathAddrs(address) | ||||
| 		return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err} | ||||
| 	} | ||||
| 	return &Conn{Conn: c, boundAddr: a}, nil | ||||
| } | ||||
| 
 | ||||
| // DialWithConn initiates a connection from SOCKS server to the target
 | ||||
| // network and address using the connection c that is already
 | ||||
| // connected to the SOCKS server.
 | ||||
| //
 | ||||
| // It returns the connection's local address assigned by the SOCKS
 | ||||
| // server.
 | ||||
| func (d *Dialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) { | ||||
| 	if err := d.validateTarget(network, address); err != nil { | ||||
| 		proxy, dst, _ := d.pathAddrs(address) | ||||
| 		return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err} | ||||
| 	} | ||||
| 	if ctx == nil { | ||||
| 		proxy, dst, _ := d.pathAddrs(address) | ||||
| 		return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")} | ||||
| 	} | ||||
| 	a, err := d.connect(ctx, c, address) | ||||
| 	if err != nil { | ||||
| 		proxy, dst, _ := d.pathAddrs(address) | ||||
| 		return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err} | ||||
| 	} | ||||
| 	return a, nil | ||||
| } | ||||
| 
 | ||||
| // Dial connects to the provided address on the provided network.
 | ||||
| //
 | ||||
| // Unlike DialContext, it returns a raw transport connection instead
 | ||||
| // of a forward proxy connection.
 | ||||
| //
 | ||||
| // Deprecated: Use DialContext or DialWithConn instead.
 | ||||
| func (d *Dialer) Dial(network, address string) (net.Conn, error) { | ||||
| 	if err := d.validateTarget(network, address); err != nil { | ||||
| 		proxy, dst, _ := d.pathAddrs(address) | ||||
| 		return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err} | ||||
| 	} | ||||
| 	var err error | ||||
| 	var c net.Conn | ||||
| 	if d.ProxyDial != nil { | ||||
| 		c, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress) | ||||
| 	} else { | ||||
| 		c, err = net.Dial(d.proxyNetwork, d.proxyAddress) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		proxy, dst, _ := d.pathAddrs(address) | ||||
| 		return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err} | ||||
| 	} | ||||
| 	if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil { | ||||
| 		c.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return c, nil | ||||
| } | ||||
| 
 | ||||
| func (d *Dialer) validateTarget(network, address string) error { | ||||
| 	switch network { | ||||
| 	case "tcp", "tcp6", "tcp4": | ||||
| 	default: | ||||
| 		return errors.New("network not implemented") | ||||
| 	} | ||||
| 	switch d.cmd { | ||||
| 	case CmdConnect, cmdBind: | ||||
| 	default: | ||||
| 		return errors.New("command not implemented") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (d *Dialer) pathAddrs(address string) (proxy, dst net.Addr, err error) { | ||||
| 	for i, s := range []string{d.proxyAddress, address} { | ||||
| 		host, port, err := splitHostPort(s) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, err | ||||
| 		} | ||||
| 		a := &Addr{Port: port} | ||||
| 		a.IP = net.ParseIP(host) | ||||
| 		if a.IP == nil { | ||||
| 			a.Name = host | ||||
| 		} | ||||
| 		if i == 0 { | ||||
| 			proxy = a | ||||
| 		} else { | ||||
| 			dst = a | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // NewDialer returns a new Dialer that dials through the provided
 | ||||
| // proxy server's network and address.
 | ||||
| func NewDialer(network, address string) *Dialer { | ||||
| 	return &Dialer{proxyNetwork: network, proxyAddress: address, cmd: CmdConnect} | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
| 	authUsernamePasswordVersion = 0x01 | ||||
| 	authStatusSucceeded         = 0x00 | ||||
| ) | ||||
| 
 | ||||
| // UsernamePassword are the credentials for the username/password
 | ||||
| // authentication method.
 | ||||
| type UsernamePassword struct { | ||||
| 	Username string | ||||
| 	Password string | ||||
| } | ||||
| 
 | ||||
| // Authenticate authenticates a pair of username and password with the
 | ||||
| // proxy server.
 | ||||
| func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth AuthMethod) error { | ||||
| 	switch auth { | ||||
| 	case AuthMethodNotRequired: | ||||
| 		return nil | ||||
| 	case AuthMethodUsernamePassword: | ||||
| 		if len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) == 0 || len(up.Password) > 255 { | ||||
| 			return errors.New("invalid username/password") | ||||
| 		} | ||||
| 		b := []byte{authUsernamePasswordVersion} | ||||
| 		b = append(b, byte(len(up.Username))) | ||||
| 		b = append(b, up.Username...) | ||||
| 		b = append(b, byte(len(up.Password))) | ||||
| 		b = append(b, up.Password...) | ||||
| 		// TODO(mikio): handle IO deadlines and cancelation if
 | ||||
| 		// necessary
 | ||||
| 		if _, err := rw.Write(b); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if _, err := io.ReadFull(rw, b[:2]); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if b[0] != authUsernamePasswordVersion { | ||||
| 			return errors.New("invalid username/password version") | ||||
| 		} | ||||
| 		if b[1] != authStatusSucceeded { | ||||
| 			return errors.New("username/password authentication failed") | ||||
| 		} | ||||
| 		return nil | ||||
| 	} | ||||
| 	return errors.New("unsupported authentication method " + strconv.Itoa(int(auth))) | ||||
| } | ||||
|  | @ -0,0 +1,54 @@ | |||
| // Copyright 2019 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package proxy | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"net" | ||||
| ) | ||||
| 
 | ||||
| // A ContextDialer dials using a context.
 | ||||
| type ContextDialer interface { | ||||
| 	DialContext(ctx context.Context, network, address string) (net.Conn, error) | ||||
| } | ||||
| 
 | ||||
| // Dial works like DialContext on net.Dialer but using a dialer returned by FromEnvironment.
 | ||||
| //
 | ||||
| // The passed ctx is only used for returning the Conn, not the lifetime of the Conn.
 | ||||
| //
 | ||||
| // Custom dialers (registered via RegisterDialerType) that do not implement ContextDialer
 | ||||
| // can leak a goroutine for as long as it takes the underlying Dialer implementation to timeout.
 | ||||
| //
 | ||||
| // A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
 | ||||
| func Dial(ctx context.Context, network, address string) (net.Conn, error) { | ||||
| 	d := FromEnvironment() | ||||
| 	if xd, ok := d.(ContextDialer); ok { | ||||
| 		return xd.DialContext(ctx, network, address) | ||||
| 	} | ||||
| 	return dialContext(ctx, d, network, address) | ||||
| } | ||||
| 
 | ||||
| // WARNING: this can leak a goroutine for as long as the underlying Dialer implementation takes to timeout
 | ||||
| // A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
 | ||||
| func dialContext(ctx context.Context, d Dialer, network, address string) (net.Conn, error) { | ||||
| 	var ( | ||||
| 		conn net.Conn | ||||
| 		done = make(chan struct{}, 1) | ||||
| 		err  error | ||||
| 	) | ||||
| 	go func() { | ||||
| 		conn, err = d.Dial(network, address) | ||||
| 		close(done) | ||||
| 		if conn != nil && ctx.Err() != nil { | ||||
| 			conn.Close() | ||||
| 		} | ||||
| 	}() | ||||
| 	select { | ||||
| 	case <-ctx.Done(): | ||||
| 		err = ctx.Err() | ||||
| 	case <-done: | ||||
| 	} | ||||
| 	return conn, err | ||||
| } | ||||
|  | @ -0,0 +1,31 @@ | |||
| // Copyright 2011 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package proxy | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"net" | ||||
| ) | ||||
| 
 | ||||
| type direct struct{} | ||||
| 
 | ||||
| // Direct implements Dialer by making network connections directly using net.Dial or net.DialContext.
 | ||||
| var Direct = direct{} | ||||
| 
 | ||||
| var ( | ||||
| 	_ Dialer        = Direct | ||||
| 	_ ContextDialer = Direct | ||||
| ) | ||||
| 
 | ||||
| // Dial directly invokes net.Dial with the supplied parameters.
 | ||||
| func (direct) Dial(network, addr string) (net.Conn, error) { | ||||
| 	return net.Dial(network, addr) | ||||
| } | ||||
| 
 | ||||
| // DialContext instantiates a net.Dialer and invokes its DialContext receiver with the supplied parameters.
 | ||||
| func (direct) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { | ||||
| 	var d net.Dialer | ||||
| 	return d.DialContext(ctx, network, addr) | ||||
| } | ||||
|  | @ -0,0 +1,155 @@ | |||
| // Copyright 2011 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package proxy | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"net" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| // A PerHost directs connections to a default Dialer unless the host name
 | ||||
| // requested matches one of a number of exceptions.
 | ||||
| type PerHost struct { | ||||
| 	def, bypass Dialer | ||||
| 
 | ||||
| 	bypassNetworks []*net.IPNet | ||||
| 	bypassIPs      []net.IP | ||||
| 	bypassZones    []string | ||||
| 	bypassHosts    []string | ||||
| } | ||||
| 
 | ||||
| // NewPerHost returns a PerHost Dialer that directs connections to either
 | ||||
| // defaultDialer or bypass, depending on whether the connection matches one of
 | ||||
| // the configured rules.
 | ||||
| func NewPerHost(defaultDialer, bypass Dialer) *PerHost { | ||||
| 	return &PerHost{ | ||||
| 		def:    defaultDialer, | ||||
| 		bypass: bypass, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Dial connects to the address addr on the given network through either
 | ||||
| // defaultDialer or bypass.
 | ||||
| func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) { | ||||
| 	host, _, err := net.SplitHostPort(addr) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return p.dialerForRequest(host).Dial(network, addr) | ||||
| } | ||||
| 
 | ||||
| // DialContext connects to the address addr on the given network through either
 | ||||
| // defaultDialer or bypass.
 | ||||
| func (p *PerHost) DialContext(ctx context.Context, network, addr string) (c net.Conn, err error) { | ||||
| 	host, _, err := net.SplitHostPort(addr) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	d := p.dialerForRequest(host) | ||||
| 	if x, ok := d.(ContextDialer); ok { | ||||
| 		return x.DialContext(ctx, network, addr) | ||||
| 	} | ||||
| 	return dialContext(ctx, d, network, addr) | ||||
| } | ||||
| 
 | ||||
| func (p *PerHost) dialerForRequest(host string) Dialer { | ||||
| 	if ip := net.ParseIP(host); ip != nil { | ||||
| 		for _, net := range p.bypassNetworks { | ||||
| 			if net.Contains(ip) { | ||||
| 				return p.bypass | ||||
| 			} | ||||
| 		} | ||||
| 		for _, bypassIP := range p.bypassIPs { | ||||
| 			if bypassIP.Equal(ip) { | ||||
| 				return p.bypass | ||||
| 			} | ||||
| 		} | ||||
| 		return p.def | ||||
| 	} | ||||
| 
 | ||||
| 	for _, zone := range p.bypassZones { | ||||
| 		if strings.HasSuffix(host, zone) { | ||||
| 			return p.bypass | ||||
| 		} | ||||
| 		if host == zone[1:] { | ||||
| 			// For a zone ".example.com", we match "example.com"
 | ||||
| 			// too.
 | ||||
| 			return p.bypass | ||||
| 		} | ||||
| 	} | ||||
| 	for _, bypassHost := range p.bypassHosts { | ||||
| 		if bypassHost == host { | ||||
| 			return p.bypass | ||||
| 		} | ||||
| 	} | ||||
| 	return p.def | ||||
| } | ||||
| 
 | ||||
| // AddFromString parses a string that contains comma-separated values
 | ||||
| // specifying hosts that should use the bypass proxy. Each value is either an
 | ||||
| // IP address, a CIDR range, a zone (*.example.com) or a host name
 | ||||
| // (localhost). A best effort is made to parse the string and errors are
 | ||||
| // ignored.
 | ||||
| func (p *PerHost) AddFromString(s string) { | ||||
| 	hosts := strings.Split(s, ",") | ||||
| 	for _, host := range hosts { | ||||
| 		host = strings.TrimSpace(host) | ||||
| 		if len(host) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 		if strings.Contains(host, "/") { | ||||
| 			// We assume that it's a CIDR address like 127.0.0.0/8
 | ||||
| 			if _, net, err := net.ParseCIDR(host); err == nil { | ||||
| 				p.AddNetwork(net) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
| 		if ip := net.ParseIP(host); ip != nil { | ||||
| 			p.AddIP(ip) | ||||
| 			continue | ||||
| 		} | ||||
| 		if strings.HasPrefix(host, "*.") { | ||||
| 			p.AddZone(host[1:]) | ||||
| 			continue | ||||
| 		} | ||||
| 		p.AddHost(host) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // AddIP specifies an IP address that will use the bypass proxy. Note that
 | ||||
| // this will only take effect if a literal IP address is dialed. A connection
 | ||||
| // to a named host will never match an IP.
 | ||||
| func (p *PerHost) AddIP(ip net.IP) { | ||||
| 	p.bypassIPs = append(p.bypassIPs, ip) | ||||
| } | ||||
| 
 | ||||
| // AddNetwork specifies an IP range that will use the bypass proxy. Note that
 | ||||
| // this will only take effect if a literal IP address is dialed. A connection
 | ||||
| // to a named host will never match.
 | ||||
| func (p *PerHost) AddNetwork(net *net.IPNet) { | ||||
| 	p.bypassNetworks = append(p.bypassNetworks, net) | ||||
| } | ||||
| 
 | ||||
| // AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
 | ||||
| // "example.com" matches "example.com" and all of its subdomains.
 | ||||
| func (p *PerHost) AddZone(zone string) { | ||||
| 	if strings.HasSuffix(zone, ".") { | ||||
| 		zone = zone[:len(zone)-1] | ||||
| 	} | ||||
| 	if !strings.HasPrefix(zone, ".") { | ||||
| 		zone = "." + zone | ||||
| 	} | ||||
| 	p.bypassZones = append(p.bypassZones, zone) | ||||
| } | ||||
| 
 | ||||
| // AddHost specifies a host name that will use the bypass proxy.
 | ||||
| func (p *PerHost) AddHost(host string) { | ||||
| 	if strings.HasSuffix(host, ".") { | ||||
| 		host = host[:len(host)-1] | ||||
| 	} | ||||
| 	p.bypassHosts = append(p.bypassHosts, host) | ||||
| } | ||||
|  | @ -0,0 +1,149 @@ | |||
| // Copyright 2011 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| // Package proxy provides support for a variety of protocols to proxy network
 | ||||
| // data.
 | ||||
| package proxy // import "golang.org/x/net/proxy"
 | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"net" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| 	"sync" | ||||
| ) | ||||
| 
 | ||||
| // A Dialer is a means to establish a connection.
 | ||||
| // Custom dialers should also implement ContextDialer.
 | ||||
| type Dialer interface { | ||||
| 	// Dial connects to the given address via the proxy.
 | ||||
| 	Dial(network, addr string) (c net.Conn, err error) | ||||
| } | ||||
| 
 | ||||
| // Auth contains authentication parameters that specific Dialers may require.
 | ||||
| type Auth struct { | ||||
| 	User, Password string | ||||
| } | ||||
| 
 | ||||
| // FromEnvironment returns the dialer specified by the proxy-related
 | ||||
| // variables in the environment and makes underlying connections
 | ||||
| // directly.
 | ||||
| func FromEnvironment() Dialer { | ||||
| 	return FromEnvironmentUsing(Direct) | ||||
| } | ||||
| 
 | ||||
| // FromEnvironmentUsing returns the dialer specify by the proxy-related
 | ||||
| // variables in the environment and makes underlying connections
 | ||||
| // using the provided forwarding Dialer (for instance, a *net.Dialer
 | ||||
| // with desired configuration).
 | ||||
| func FromEnvironmentUsing(forward Dialer) Dialer { | ||||
| 	allProxy := allProxyEnv.Get() | ||||
| 	if len(allProxy) == 0 { | ||||
| 		return forward | ||||
| 	} | ||||
| 
 | ||||
| 	proxyURL, err := url.Parse(allProxy) | ||||
| 	if err != nil { | ||||
| 		return forward | ||||
| 	} | ||||
| 	proxy, err := FromURL(proxyURL, forward) | ||||
| 	if err != nil { | ||||
| 		return forward | ||||
| 	} | ||||
| 
 | ||||
| 	noProxy := noProxyEnv.Get() | ||||
| 	if len(noProxy) == 0 { | ||||
| 		return proxy | ||||
| 	} | ||||
| 
 | ||||
| 	perHost := NewPerHost(proxy, forward) | ||||
| 	perHost.AddFromString(noProxy) | ||||
| 	return perHost | ||||
| } | ||||
| 
 | ||||
| // proxySchemes is a map from URL schemes to a function that creates a Dialer
 | ||||
| // from a URL with such a scheme.
 | ||||
| var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error) | ||||
| 
 | ||||
| // RegisterDialerType takes a URL scheme and a function to generate Dialers from
 | ||||
| // a URL with that scheme and a forwarding Dialer. Registered schemes are used
 | ||||
| // by FromURL.
 | ||||
| func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) { | ||||
| 	if proxySchemes == nil { | ||||
| 		proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error)) | ||||
| 	} | ||||
| 	proxySchemes[scheme] = f | ||||
| } | ||||
| 
 | ||||
| // FromURL returns a Dialer given a URL specification and an underlying
 | ||||
| // Dialer for it to make network requests.
 | ||||
| func FromURL(u *url.URL, forward Dialer) (Dialer, error) { | ||||
| 	var auth *Auth | ||||
| 	if u.User != nil { | ||||
| 		auth = new(Auth) | ||||
| 		auth.User = u.User.Username() | ||||
| 		if p, ok := u.User.Password(); ok { | ||||
| 			auth.Password = p | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	switch u.Scheme { | ||||
| 	case "socks5", "socks5h": | ||||
| 		addr := u.Hostname() | ||||
| 		port := u.Port() | ||||
| 		if port == "" { | ||||
| 			port = "1080" | ||||
| 		} | ||||
| 		return SOCKS5("tcp", net.JoinHostPort(addr, port), auth, forward) | ||||
| 	} | ||||
| 
 | ||||
| 	// If the scheme doesn't match any of the built-in schemes, see if it
 | ||||
| 	// was registered by another package.
 | ||||
| 	if proxySchemes != nil { | ||||
| 		if f, ok := proxySchemes[u.Scheme]; ok { | ||||
| 			return f(u, forward) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, errors.New("proxy: unknown scheme: " + u.Scheme) | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
| 	allProxyEnv = &envOnce{ | ||||
| 		names: []string{"ALL_PROXY", "all_proxy"}, | ||||
| 	} | ||||
| 	noProxyEnv = &envOnce{ | ||||
| 		names: []string{"NO_PROXY", "no_proxy"}, | ||||
| 	} | ||||
| ) | ||||
| 
 | ||||
| // envOnce looks up an environment variable (optionally by multiple
 | ||||
| // names) once. It mitigates expensive lookups on some platforms
 | ||||
| // (e.g. Windows).
 | ||||
| // (Borrowed from net/http/transport.go)
 | ||||
| type envOnce struct { | ||||
| 	names []string | ||||
| 	once  sync.Once | ||||
| 	val   string | ||||
| } | ||||
| 
 | ||||
| func (e *envOnce) Get() string { | ||||
| 	e.once.Do(e.init) | ||||
| 	return e.val | ||||
| } | ||||
| 
 | ||||
| func (e *envOnce) init() { | ||||
| 	for _, n := range e.names { | ||||
| 		e.val = os.Getenv(n) | ||||
| 		if e.val != "" { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // reset is used by tests
 | ||||
| func (e *envOnce) reset() { | ||||
| 	e.once = sync.Once{} | ||||
| 	e.val = "" | ||||
| } | ||||
|  | @ -0,0 +1,42 @@ | |||
| // Copyright 2011 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package proxy | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"net" | ||||
| 
 | ||||
| 	"golang.org/x/net/internal/socks" | ||||
| ) | ||||
| 
 | ||||
| // SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given
 | ||||
| // address with an optional username and password.
 | ||||
| // See RFC 1928 and RFC 1929.
 | ||||
| func SOCKS5(network, address string, auth *Auth, forward Dialer) (Dialer, error) { | ||||
| 	d := socks.NewDialer(network, address) | ||||
| 	if forward != nil { | ||||
| 		if f, ok := forward.(ContextDialer); ok { | ||||
| 			d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) { | ||||
| 				return f.DialContext(ctx, network, address) | ||||
| 			} | ||||
| 		} else { | ||||
| 			d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) { | ||||
| 				return dialContext(ctx, forward, network, address) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if auth != nil { | ||||
| 		up := socks.UsernamePassword{ | ||||
| 			Username: auth.User, | ||||
| 			Password: auth.Password, | ||||
| 		} | ||||
| 		d.AuthMethods = []socks.AuthMethod{ | ||||
| 			socks.AuthMethodNotRequired, | ||||
| 			socks.AuthMethodUsernamePassword, | ||||
| 		} | ||||
| 		d.Authenticate = up.Authenticate | ||||
| 	} | ||||
| 	return d, nil | ||||
| } | ||||
|  | @ -0,0 +1,16 @@ | |||
| // Copyright 2019 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package unix | ||||
| 
 | ||||
| // Round the length of a raw sockaddr up to align it properly.
 | ||||
| func cmsgAlignOf(salen int) int { | ||||
| 	salign := SizeofPtr | ||||
| 	if SizeofPtr == 8 && !supportsABI(_dragonflyABIChangeVersion) { | ||||
| 		// 64-bit Dragonfly before the September 2019 ABI changes still requires
 | ||||
| 		// 32-bit aligned access to network subsystem.
 | ||||
| 		salign = 4 | ||||
| 	} | ||||
| 	return (salen + salign - 1) & ^(salign - 1) | ||||
| } | ||||
|  | @ -17,7 +17,7 @@ func UnixCredentials(ucred *Ucred) []byte { | |||
| 	h.Level = SOL_SOCKET | ||||
| 	h.Type = SCM_CREDENTIALS | ||||
| 	h.SetLen(CmsgLen(SizeofUcred)) | ||||
| 	*((*Ucred)(cmsgData(h))) = *ucred | ||||
| 	*(*Ucred)(h.data(0)) = *ucred | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,35 +9,9 @@ | |||
| package unix | ||||
| 
 | ||||
| import ( | ||||
| 	"runtime" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| // Round the length of a raw sockaddr up to align it properly.
 | ||||
| func cmsgAlignOf(salen int) int { | ||||
| 	salign := SizeofPtr | ||||
| 
 | ||||
| 	switch runtime.GOOS { | ||||
| 	case "aix": | ||||
| 		// There is no alignment on AIX.
 | ||||
| 		salign = 1 | ||||
| 	case "darwin", "dragonfly", "solaris", "illumos": | ||||
| 		// NOTE: It seems like 64-bit Darwin, DragonFly BSD,
 | ||||
| 		// illumos, and Solaris kernels still require 32-bit
 | ||||
| 		// aligned access to network subsystem.
 | ||||
| 		if SizeofPtr == 8 { | ||||
| 			salign = 4 | ||||
| 		} | ||||
| 	case "netbsd", "openbsd": | ||||
| 		// NetBSD and OpenBSD armv7 require 64-bit alignment.
 | ||||
| 		if runtime.GOARCH == "arm" { | ||||
| 			salign = 8 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return (salen + salign - 1) & ^(salign - 1) | ||||
| } | ||||
| 
 | ||||
| // CmsgLen returns the value to store in the Len field of the Cmsghdr
 | ||||
| // structure, taking into account any necessary alignment.
 | ||||
| func CmsgLen(datalen int) int { | ||||
|  | @ -50,8 +24,8 @@ func CmsgSpace(datalen int) int { | |||
| 	return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen) | ||||
| } | ||||
| 
 | ||||
| func cmsgData(h *Cmsghdr) unsafe.Pointer { | ||||
| 	return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr))) | ||||
| func (h *Cmsghdr) data(offset uintptr) unsafe.Pointer { | ||||
| 	return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)) + offset) | ||||
| } | ||||
| 
 | ||||
| // SocketControlMessage represents a socket control message.
 | ||||
|  | @ -94,10 +68,8 @@ func UnixRights(fds ...int) []byte { | |||
| 	h.Level = SOL_SOCKET | ||||
| 	h.Type = SCM_RIGHTS | ||||
| 	h.SetLen(CmsgLen(datalen)) | ||||
| 	data := cmsgData(h) | ||||
| 	for _, fd := range fds { | ||||
| 		*(*int32)(data) = int32(fd) | ||||
| 		data = unsafe.Pointer(uintptr(data) + 4) | ||||
| 	for i, fd := range fds { | ||||
| 		*(*int32)(h.data(4 * uintptr(i))) = int32(fd) | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,38 @@ | |||
| // Copyright 2019 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| // +build aix darwin freebsd linux netbsd openbsd solaris
 | ||||
| 
 | ||||
| package unix | ||||
| 
 | ||||
| import ( | ||||
| 	"runtime" | ||||
| ) | ||||
| 
 | ||||
| // Round the length of a raw sockaddr up to align it properly.
 | ||||
| func cmsgAlignOf(salen int) int { | ||||
| 	salign := SizeofPtr | ||||
| 
 | ||||
| 	// dragonfly needs to check ABI version at runtime, see cmsgAlignOf in
 | ||||
| 	// sockcmsg_dragonfly.go
 | ||||
| 	switch runtime.GOOS { | ||||
| 	case "aix": | ||||
| 		// There is no alignment on AIX.
 | ||||
| 		salign = 1 | ||||
| 	case "darwin", "illumos", "solaris": | ||||
| 		// NOTE: It seems like 64-bit Darwin, Illumos and Solaris
 | ||||
| 		// kernels still require 32-bit aligned access to network
 | ||||
| 		// subsystem.
 | ||||
| 		if SizeofPtr == 8 { | ||||
| 			salign = 4 | ||||
| 		} | ||||
| 	case "netbsd", "openbsd": | ||||
| 		// NetBSD and OpenBSD armv7 require 64-bit alignment.
 | ||||
| 		if runtime.GOARCH == "arm" { | ||||
| 			salign = 8 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return (salen + salign - 1) & ^(salign - 1) | ||||
| } | ||||
|  | @ -237,7 +237,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | ||||
| 		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | ||||
| 		sa.Name = string(bytes) | ||||
| 		return sa, nil | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,9 +12,25 @@ | |||
| 
 | ||||
| package unix | ||||
| 
 | ||||
| import "unsafe" | ||||
| import ( | ||||
| 	"sync" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| //sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
 | ||||
| // See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h
 | ||||
| var ( | ||||
| 	osreldateOnce sync.Once | ||||
| 	osreldate     uint32 | ||||
| ) | ||||
| 
 | ||||
| // First __DragonFly_version after September 2019 ABI changes
 | ||||
| // http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html
 | ||||
| const _dragonflyABIChangeVersion = 500705 | ||||
| 
 | ||||
| func supportsABI(ver uint32) bool { | ||||
| 	osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") }) | ||||
| 	return osreldate >= ver | ||||
| } | ||||
| 
 | ||||
| // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
 | ||||
| type SockaddrDatalink struct { | ||||
|  |  | |||
|  | @ -884,7 +884,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
| 		for n < len(pp.Path) && pp.Path[n] != 0 { | ||||
| 			n++ | ||||
| 		} | ||||
| 		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | ||||
| 		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | ||||
| 		sa.Name = string(bytes) | ||||
| 		return sa, nil | ||||
| 
 | ||||
|  |  | |||
|  | @ -391,7 +391,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
| 		for n < len(pp.Path) && pp.Path[n] != 0 { | ||||
| 			n++ | ||||
| 		} | ||||
| 		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | ||||
| 		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | ||||
| 		sa.Name = string(bytes) | ||||
| 		return sa, nil | ||||
| 
 | ||||
|  |  | |||
|  | @ -599,22 +599,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2484,6 +2468,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -600,22 +600,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2497,6 +2481,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -603,22 +603,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2475,6 +2459,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -601,22 +601,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2476,6 +2460,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -602,22 +602,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2481,6 +2465,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -601,22 +601,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2478,6 +2462,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -601,22 +601,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2478,6 +2462,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -602,22 +602,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2481,6 +2465,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -602,22 +602,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2486,6 +2470,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -602,22 +602,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2486,6 +2470,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -601,22 +601,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2504,6 +2488,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -600,22 +600,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2500,6 +2484,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -604,22 +604,6 @@ const ( | |||
| 	RTN_THROW               = 0x9 | ||||
| 	RTN_NAT                 = 0xa | ||||
| 	RTN_XRESOLVE            = 0xb | ||||
| 	RTNLGRP_NONE            = 0x0 | ||||
| 	RTNLGRP_LINK            = 0x1 | ||||
| 	RTNLGRP_NOTIFY          = 0x2 | ||||
| 	RTNLGRP_NEIGH           = 0x3 | ||||
| 	RTNLGRP_TC              = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR     = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE     = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE      = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE       = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR     = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE     = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE      = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO     = 0xc | ||||
| 	RTNLGRP_IPV6_PREFIX     = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE       = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT      = 0x14 | ||||
| 	SizeofNlMsghdr          = 0x10 | ||||
| 	SizeofNlMsgerr          = 0x14 | ||||
| 	SizeofRtGenmsg          = 0x1 | ||||
|  | @ -2481,6 +2465,42 @@ const ( | |||
| 	BPF_FD_TYPE_URETPROBE               = 0x5 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RTNLGRP_NONE          = 0x0 | ||||
| 	RTNLGRP_LINK          = 0x1 | ||||
| 	RTNLGRP_NOTIFY        = 0x2 | ||||
| 	RTNLGRP_NEIGH         = 0x3 | ||||
| 	RTNLGRP_TC            = 0x4 | ||||
| 	RTNLGRP_IPV4_IFADDR   = 0x5 | ||||
| 	RTNLGRP_IPV4_MROUTE   = 0x6 | ||||
| 	RTNLGRP_IPV4_ROUTE    = 0x7 | ||||
| 	RTNLGRP_IPV4_RULE     = 0x8 | ||||
| 	RTNLGRP_IPV6_IFADDR   = 0x9 | ||||
| 	RTNLGRP_IPV6_MROUTE   = 0xa | ||||
| 	RTNLGRP_IPV6_ROUTE    = 0xb | ||||
| 	RTNLGRP_IPV6_IFINFO   = 0xc | ||||
| 	RTNLGRP_DECnet_IFADDR = 0xd | ||||
| 	RTNLGRP_NOP2          = 0xe | ||||
| 	RTNLGRP_DECnet_ROUTE  = 0xf | ||||
| 	RTNLGRP_DECnet_RULE   = 0x10 | ||||
| 	RTNLGRP_NOP4          = 0x11 | ||||
| 	RTNLGRP_IPV6_PREFIX   = 0x12 | ||||
| 	RTNLGRP_IPV6_RULE     = 0x13 | ||||
| 	RTNLGRP_ND_USEROPT    = 0x14 | ||||
| 	RTNLGRP_PHONET_IFADDR = 0x15 | ||||
| 	RTNLGRP_PHONET_ROUTE  = 0x16 | ||||
| 	RTNLGRP_DCB           = 0x17 | ||||
| 	RTNLGRP_IPV4_NETCONF  = 0x18 | ||||
| 	RTNLGRP_IPV6_NETCONF  = 0x19 | ||||
| 	RTNLGRP_MDB           = 0x1a | ||||
| 	RTNLGRP_MPLS_ROUTE    = 0x1b | ||||
| 	RTNLGRP_NSID          = 0x1c | ||||
| 	RTNLGRP_MPLS_NETCONF  = 0x1d | ||||
| 	RTNLGRP_IPV4_MROUTE_R = 0x1e | ||||
| 	RTNLGRP_IPV6_MROUTE_R = 0x1f | ||||
| 	RTNLGRP_NEXTHOP       = 0x20 | ||||
| ) | ||||
| 
 | ||||
| type CapUserHeader struct { | ||||
| 	Version uint32 | ||||
| 	Pid     int32 | ||||
|  |  | |||
|  | @ -229,13 +229,15 @@ func LookupSID(system, account string) (sid *SID, domain string, accType uint32, | |||
| 
 | ||||
| // String converts SID to a string format suitable for display, storage, or transmission.
 | ||||
| func (sid *SID) String() string { | ||||
| 	// From https://docs.microsoft.com/en-us/windows/win32/secbiomet/general-constants
 | ||||
| 	const SecurityMaxSidSize = 68 | ||||
| 	var s *uint16 | ||||
| 	e := ConvertSidToStringSid(sid, &s) | ||||
| 	if e != nil { | ||||
| 		return "" | ||||
| 	} | ||||
| 	defer LocalFree((Handle)(unsafe.Pointer(s))) | ||||
| 	return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(s))[:]) | ||||
| 	return UTF16ToString((*[SecurityMaxSidSize]uint16)(unsafe.Pointer(s))[:]) | ||||
| } | ||||
| 
 | ||||
| // Len returns the length, in bytes, of a valid security identifier SID.
 | ||||
|  |  | |||
|  | @ -290,6 +290,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { | |||
| //sys	FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) = FindNextVolumeMountPointW
 | ||||
| //sys	FindVolumeClose(findVolume Handle) (err error)
 | ||||
| //sys	FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error)
 | ||||
| //sys	GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = GetDiskFreeSpaceExW
 | ||||
| //sys	GetDriveType(rootPathName *uint16) (driveType uint32) = GetDriveTypeW
 | ||||
| //sys	GetLogicalDrives() (drivesBitMask uint32, err error) [failretval==0]
 | ||||
| //sys	GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) [failretval==0] = GetLogicalDriveStringsW
 | ||||
|  | @ -856,7 +857,7 @@ func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { | |||
| 		for n < len(pp.Path) && pp.Path[n] != 0 { | ||||
| 			n++ | ||||
| 		} | ||||
| 		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | ||||
| 		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | ||||
| 		sa.Name = string(bytes) | ||||
| 		return sa, nil | ||||
| 
 | ||||
|  |  | |||
|  | @ -224,6 +224,7 @@ var ( | |||
| 	procFindNextVolumeMountPointW                            = modkernel32.NewProc("FindNextVolumeMountPointW") | ||||
| 	procFindVolumeClose                                      = modkernel32.NewProc("FindVolumeClose") | ||||
| 	procFindVolumeMountPointClose                            = modkernel32.NewProc("FindVolumeMountPointClose") | ||||
| 	procGetDiskFreeSpaceExW                                  = modkernel32.NewProc("GetDiskFreeSpaceExW") | ||||
| 	procGetDriveTypeW                                        = modkernel32.NewProc("GetDriveTypeW") | ||||
| 	procGetLogicalDrives                                     = modkernel32.NewProc("GetLogicalDrives") | ||||
| 	procGetLogicalDriveStringsW                              = modkernel32.NewProc("GetLogicalDriveStringsW") | ||||
|  | @ -2503,6 +2504,18 @@ func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { | |||
| 	return | ||||
| } | ||||
| 
 | ||||
| func GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = errnoErr(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func GetDriveType(rootPathName *uint16) (driveType uint32) { | ||||
| 	r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) | ||||
| 	driveType = uint32(r0) | ||||
|  |  | |||
|  | @ -212,7 +212,7 @@ golang.org/x/crypto/poly1305 | |||
| golang.org/x/crypto/salsa20/salsa | ||||
| golang.org/x/crypto/ssh | ||||
| golang.org/x/crypto/ssh/terminal | ||||
| # golang.org/x/net v0.0.0-20191007182048-72f939374954 | ||||
| # golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 | ||||
| golang.org/x/net/bpf | ||||
| golang.org/x/net/context | ||||
| golang.org/x/net/context/ctxhttp | ||||
|  | @ -222,9 +222,11 @@ golang.org/x/net/http2/hpack | |||
| golang.org/x/net/idna | ||||
| golang.org/x/net/internal/iana | ||||
| golang.org/x/net/internal/socket | ||||
| golang.org/x/net/internal/socks | ||||
| golang.org/x/net/internal/timeseries | ||||
| golang.org/x/net/ipv4 | ||||
| golang.org/x/net/ipv6 | ||||
| golang.org/x/net/proxy | ||||
| golang.org/x/net/trace | ||||
| golang.org/x/net/websocket | ||||
| # golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 | ||||
|  | @ -232,7 +234,7 @@ golang.org/x/oauth2 | |||
| golang.org/x/oauth2/internal | ||||
| # golang.org/x/sync v0.0.0-20190423024810-112230192c58 | ||||
| golang.org/x/sync/errgroup | ||||
| # golang.org/x/sys v0.0.0-20191008105621-543471e840be | ||||
| # golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2 | ||||
| golang.org/x/sys/cpu | ||||
| golang.org/x/sys/unix | ||||
| golang.org/x/sys/windows | ||||
|  |  | |||
|  | @ -116,10 +116,15 @@ func Stream(conn, backendConn io.ReadWriter) { | |||
| 	<-proxyDone | ||||
| } | ||||
| 
 | ||||
| // DefaultStreamHandler is provided to the the standard websocket to origin stream
 | ||||
| // This exist to allow SOCKS to deframe data before it gets to the origin
 | ||||
| func DefaultStreamHandler(wsConn *Conn, remoteConn net.Conn) { | ||||
| 	Stream(wsConn, remoteConn) | ||||
| } | ||||
| 
 | ||||
| // StartProxyServer will start a websocket server that will decode
 | ||||
| // the websocket data and write the resulting data to the provided
 | ||||
| // address
 | ||||
| func StartProxyServer(logger *logrus.Logger, listener net.Listener, remote string, shutdownC <-chan struct{}) error { | ||||
| func StartProxyServer(logger *logrus.Logger, listener net.Listener, remote string, shutdownC <-chan struct{}, streamHandler func(wsConn *Conn, remoteConn net.Conn)) error { | ||||
| 	upgrader := websocket.Upgrader{ | ||||
| 		ReadBufferSize:  1024, | ||||
| 		WriteBufferSize: 1024, | ||||
|  | @ -165,7 +170,7 @@ func StartProxyServer(logger *logrus.Logger, listener net.Listener, remote strin | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		Stream(&Conn{conn}, stream) | ||||
| 		streamHandler(&Conn{conn}, stream) | ||||
| 	}) | ||||
| 
 | ||||
| 	return httpServer.Serve(listener) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue