2016-03-04 07:54:59 +06:00
|
|
|
package transocks
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"net/url"
|
2016-08-31 14:56:12 +07:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/cybozu-go/log"
|
2018-11-07 09:52:08 +07:00
|
|
|
"github.com/cybozu-go/well"
|
2016-08-31 14:56:12 +07:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
defaultShutdownTimeout = 1 * time.Minute
|
2016-03-04 07:54:59 +06:00
|
|
|
)
|
|
|
|
|
2016-08-31 14:56:12 +07:00
|
|
|
// Mode is the type of transocks mode.
|
|
|
|
type Mode string
|
|
|
|
|
|
|
|
func (m Mode) String() string {
|
|
|
|
return string(m)
|
|
|
|
}
|
|
|
|
|
2016-03-04 07:54:59 +06:00
|
|
|
const (
|
2016-08-31 14:56:12 +07:00
|
|
|
// ModeNAT is mode constant for NAT.
|
|
|
|
ModeNAT = Mode("nat")
|
2016-03-04 07:54:59 +06:00
|
|
|
)
|
|
|
|
|
|
|
|
// Config keeps configurations for Server.
|
|
|
|
type Config struct {
|
2016-08-31 14:56:12 +07:00
|
|
|
// Addr is the listening address.
|
|
|
|
Addr string
|
2016-03-04 07:54:59 +06:00
|
|
|
|
|
|
|
// ProxyURL is the URL for upstream proxy.
|
|
|
|
//
|
|
|
|
// For SOCKS5, URL looks like "socks5://USER:PASSWORD@HOST:PORT".
|
|
|
|
//
|
|
|
|
// For HTTP proxy, URL looks like "http://USER:PASSWORD@HOST:PORT".
|
|
|
|
// The HTTP proxy must support CONNECT method.
|
|
|
|
ProxyURL *url.URL
|
|
|
|
|
|
|
|
// Mode determines how clients are routed to transocks.
|
2016-08-31 14:56:12 +07:00
|
|
|
// Default is ModeNAT. No other options are available at this point.
|
|
|
|
Mode Mode
|
|
|
|
|
|
|
|
// ShutdownTimeout is the maximum duration the server waits for
|
|
|
|
// all connections to be closed before shutdown.
|
|
|
|
//
|
|
|
|
// Zero duration disables timeout. Default is 1 minute.
|
|
|
|
ShutdownTimeout time.Duration
|
2016-03-04 07:54:59 +06:00
|
|
|
|
|
|
|
// Dialer is the base dialer to connect to the proxy server.
|
|
|
|
// The server uses the default dialer if this is nil.
|
|
|
|
Dialer *net.Dialer
|
2016-08-31 14:56:12 +07:00
|
|
|
|
|
|
|
// Logger can be used to provide a custom logger.
|
|
|
|
// If nil, the default logger is used.
|
|
|
|
Logger *log.Logger
|
|
|
|
|
2018-11-07 09:52:08 +07:00
|
|
|
// Env can be used to specify a well.Environment on which the server runs.
|
2016-08-31 14:56:12 +07:00
|
|
|
// If nil, the server will run on the global environment.
|
2018-11-07 09:52:08 +07:00
|
|
|
Env *well.Environment
|
2016-03-04 07:54:59 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewConfig creates and initializes a new Config.
|
|
|
|
func NewConfig() *Config {
|
|
|
|
c := new(Config)
|
|
|
|
c.Mode = ModeNAT
|
2016-08-31 14:56:12 +07:00
|
|
|
c.ShutdownTimeout = defaultShutdownTimeout
|
2016-03-04 07:54:59 +06:00
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
// validate validates the configuration.
|
|
|
|
// It returns non-nil error if the configuration is not valid.
|
|
|
|
func (c *Config) validate() error {
|
|
|
|
if c.ProxyURL == nil {
|
|
|
|
return errors.New("ProxyURL is nil")
|
|
|
|
}
|
|
|
|
if c.Mode != ModeNAT {
|
|
|
|
return fmt.Errorf("Unknown mode: %s", c.Mode)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|