add tls config option

This commit is contained in:
ginuerzh 2022-01-05 00:02:55 +08:00
parent c428b37a36
commit 3b48c4acfb
43 changed files with 395 additions and 496 deletions

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/base64"
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
@ -115,21 +116,46 @@ func buildServiceConfig(url *url.URL) (*config.ServiceConfig, error) {
} }
} }
var auths []*config.AuthConfig
if url.User != nil {
auth := &config.AuthConfig{
Username: url.User.Username(),
}
auth.Password, _ = url.User.Password()
auths = append(auths, auth)
}
md := make(map[string]interface{}) md := make(map[string]interface{})
for k, v := range url.Query() { for k, v := range url.Query() {
if len(v) > 0 { if len(v) > 0 {
md[k] = v[0] md[k] = v[0]
} }
} }
if sauth := md["auth"]; sauth != nil {
var auths []config.AuthConfig if sa, _ := sauth.(string); sa != "" {
if url.User != nil { au, err := parseAuthFromCmd(sa)
auth := config.AuthConfig{ if err != nil {
Username: url.User.Username(), return nil, err
}
auths = append(auths, au)
} }
auth.Password, _ = url.User.Password()
auths = append(auths, auth)
} }
delete(md, "auth")
var tlsConfig *config.TLSConfig
if certs := md["cert"]; certs != nil {
cert, _ := certs.(string)
key, _ := md["key"].(string)
ca, _ := md["ca"].(string)
tlsConfig = &config.TLSConfig{
Cert: cert,
Key: key,
CA: ca,
}
}
delete(md, "cert")
delete(md, "key")
delete(md, "ca")
svc.Handler = &config.HandlerConfig{ svc.Handler = &config.HandlerConfig{
Type: handler, Type: handler,
@ -138,6 +164,7 @@ func buildServiceConfig(url *url.URL) (*config.ServiceConfig, error) {
} }
svc.Listener = &config.ListenerConfig{ svc.Listener = &config.ListenerConfig{
Type: listener, Type: listener,
TLS: tlsConfig,
Metadata: md, Metadata: md,
} }
@ -170,14 +197,6 @@ func buildNodeConfig(url *url.URL) (*config.NodeConfig, error) {
} }
} }
md := make(map[string]interface{})
for k, v := range url.Query() {
if len(v) > 0 {
md[k] = v[0]
}
}
md["serverName"] = url.Host
var auth *config.AuthConfig var auth *config.AuthConfig
if url.User != nil { if url.User != nil {
auth = &config.AuthConfig{ auth = &config.AuthConfig{
@ -186,6 +205,46 @@ func buildNodeConfig(url *url.URL) (*config.NodeConfig, error) {
auth.Password, _ = url.User.Password() auth.Password, _ = url.User.Password()
} }
md := make(map[string]interface{})
for k, v := range url.Query() {
if len(v) > 0 {
md[k] = v[0]
}
}
md["serverName"] = url.Host
if sauth := md["auth"]; sauth != nil && auth == nil {
if sa, _ := sauth.(string); sa != "" {
au, err := parseAuthFromCmd(sa)
if err != nil {
return nil, err
}
auth = au
}
}
delete(md, "auth")
var tlsConfig *config.TLSConfig
if certs := md["cert"]; certs != nil {
cert, _ := certs.(string)
key, _ := md["key"].(string)
ca, _ := md["ca"].(string)
secure, _ := md["secure"].(bool)
serverName, _ := md["serverName"].(string)
tlsConfig = &config.TLSConfig{
Cert: cert,
Key: key,
CA: ca,
Secure: secure,
ServerName: serverName,
}
}
delete(md, "cert")
delete(md, "key")
delete(md, "ca")
delete(md, "secure")
delete(md, "serverName")
node.Connector = &config.ConnectorConfig{ node.Connector = &config.ConnectorConfig{
Type: connector, Type: connector,
Auth: auth, Auth: auth,
@ -193,6 +252,7 @@ func buildNodeConfig(url *url.URL) (*config.NodeConfig, error) {
} }
node.Dialer = &config.DialerConfig{ node.Dialer = &config.DialerConfig{
Type: dialer, Type: dialer,
TLS: tlsConfig,
Metadata: md, Metadata: md,
} }
@ -209,5 +269,32 @@ func normCmd(s string) (*url.URL, error) {
s = "auto://" + s s = "auto://" + s
} }
return url.Parse(s) url, err := url.Parse(s)
if err != nil {
return nil, err
}
if url.Scheme == "https" {
url.Scheme = "http+tls"
}
return url, nil
}
func parseAuthFromCmd(sa string) (*config.AuthConfig, error) {
v, err := base64.StdEncoding.DecodeString(sa)
if err != nil {
return nil, err
}
cs := string(v)
n := strings.IndexByte(cs, ':')
if n < 0 {
return &config.AuthConfig{
Username: cs,
}, nil
}
return &config.AuthConfig{
Username: cs[:n],
Password: cs[n+1:],
}, nil
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"crypto/tls"
"io" "io"
"net" "net"
"net/url" "net/url"
@ -68,9 +69,23 @@ func buildService(cfg *config.Config) (services []*service.Service) {
listenerLogger := serviceLogger.WithFields(map[string]interface{}{ listenerLogger := serviceLogger.WithFields(map[string]interface{}{
"kind": "listener", "kind": "listener",
}) })
var tlsConfig *tls.Config
var err error
tlsCfg := svc.Listener.TLS
if tlsCfg == nil {
tlsCfg = &config.TLSConfig{}
}
tlsConfig, err = loadServerTLSConfig(tlsCfg)
if err != nil {
log.Fatal(err)
}
ln := registry.GetListener(svc.Listener.Type)( ln := registry.GetListener(svc.Listener.Type)(
listener.AddrOption(svc.Addr), listener.AddrOption(svc.Addr),
listener.AuthsOption(authsFromConfig(svc.Listener.Auths...)...), listener.AuthsOption(authsFromConfig(svc.Listener.Auths...)...),
listener.TLSConfigOption(tlsConfig),
listener.LoggerOption(listenerLogger), listener.LoggerOption(listenerLogger),
) )
@ -89,6 +104,16 @@ func buildService(cfg *config.Config) (services []*service.Service) {
"kind": "handler", "kind": "handler",
}) })
tlsConfig = nil
tlsCfg = svc.Handler.TLS
if tlsCfg == nil {
tlsCfg = &config.TLSConfig{}
}
tlsConfig, err = loadServerTLSConfig(tlsCfg)
if err != nil {
log.Fatal(err)
}
h := registry.GetHandler(svc.Handler.Type)( h := registry.GetHandler(svc.Handler.Type)(
handler.RetriesOption(svc.Handler.Retries), handler.RetriesOption(svc.Handler.Retries),
handler.ChainOption(chains[svc.Handler.Chain]), handler.ChainOption(chains[svc.Handler.Chain]),
@ -96,6 +121,7 @@ func buildService(cfg *config.Config) (services []*service.Service) {
handler.HostsOption(hosts[svc.Handler.Hosts]), handler.HostsOption(hosts[svc.Handler.Hosts]),
handler.BypassOption(bypasses[svc.Handler.Bypass]), handler.BypassOption(bypasses[svc.Handler.Bypass]),
handler.AuthsOption(authsFromConfig(svc.Handler.Auths...)...), handler.AuthsOption(authsFromConfig(svc.Handler.Auths...)...),
handler.TLSConfigOption(tlsConfig),
handler.LoggerOption(handlerLogger), handler.LoggerOption(handlerLogger),
) )
@ -148,16 +174,29 @@ func chainFromConfig(cfg *config.ChainConfig) *chain.Chain {
"kind": "connector", "kind": "connector",
}) })
var connectorUser *url.Userinfo var user *url.Userinfo
if auth := v.Connector.Auth; auth != nil && auth.Username != "" { if auth := v.Connector.Auth; auth != nil && auth.Username != "" {
if auth.Password == "" { if auth.Password == "" {
connectorUser = url.User(auth.Username) user = url.User(auth.Username)
} else { } else {
connectorUser = url.UserPassword(auth.Username, auth.Password) user = url.UserPassword(auth.Username, auth.Password)
} }
} }
var tlsConfig *tls.Config
var err error
tlsCfg := v.Connector.TLS
if tlsCfg == nil {
tlsCfg = &config.TLSConfig{}
}
tlsConfig, err = loadClientTLSConfig(tlsCfg)
if err != nil {
log.Fatal(err)
}
cr := registry.GetConnector(v.Connector.Type)( cr := registry.GetConnector(v.Connector.Type)(
connector.UserOption(connectorUser), connector.UserOption(user),
connector.TLSConfigOption(tlsConfig),
connector.LoggerOption(connectorLogger), connector.LoggerOption(connectorLogger),
) )
@ -172,16 +211,28 @@ func chainFromConfig(cfg *config.ChainConfig) *chain.Chain {
"kind": "dialer", "kind": "dialer",
}) })
var dialerUser *url.Userinfo user = nil
if auth := v.Dialer.Auth; auth != nil && auth.Username != "" { if auth := v.Dialer.Auth; auth != nil && auth.Username != "" {
if auth.Password == "" { if auth.Password == "" {
dialerUser = url.User(auth.Username) user = url.User(auth.Username)
} else { } else {
dialerUser = url.UserPassword(auth.Username, auth.Password) user = url.UserPassword(auth.Username, auth.Password)
} }
} }
tlsConfig = nil
tlsCfg = v.Dialer.TLS
if tlsCfg == nil {
tlsCfg = &config.TLSConfig{}
}
tlsConfig, err = loadClientTLSConfig(tlsCfg)
if err != nil {
log.Fatal(err)
}
d := registry.GetDialer(v.Dialer.Type)( d := registry.GetDialer(v.Dialer.Type)(
dialer.UserOption(dialerUser), dialer.UserOption(user),
dialer.TLSConfigOption(tlsConfig),
dialer.LoggerOption(dialerLogger), dialer.LoggerOption(dialerLogger),
) )
@ -328,11 +379,11 @@ func hostsFromConfig(cfg *config.HostsConfig) hostspkg.HostMapper {
return hosts return hosts
} }
func authsFromConfig(cfgs ...config.AuthConfig) []*url.Userinfo { func authsFromConfig(cfgs ...*config.AuthConfig) []*url.Userinfo {
var auths []*url.Userinfo var auths []*url.Userinfo
for _, cfg := range cfgs { for _, cfg := range cfgs {
if cfg.Username == "" { if cfg == nil || cfg.Username == "" {
continue continue
} }
auths = append(auths, url.UserPassword(cfg.Username, cfg.Password)) auths = append(auths, url.UserPassword(cfg.Username, cfg.Password))

View File

@ -14,6 +14,14 @@ import (
"github.com/go-gost/gost/pkg/config" "github.com/go-gost/gost/pkg/config"
) )
func loadServerTLSConfig(cfg *config.TLSConfig) (*tls.Config, error) {
return tls_util.LoadServerConfig(cfg.Cert, cfg.Key, cfg.CA)
}
func loadClientTLSConfig(cfg *config.TLSConfig) (*tls.Config, error) {
return tls_util.LoadClientConfig(cfg.Cert, cfg.Key, cfg.CA, cfg.Secure, cfg.ServerName)
}
func buildDefaultTLSConfig(cfg *config.TLSConfig) { func buildDefaultTLSConfig(cfg *config.TLSConfig) {
if cfg == nil { if cfg == nil {
cfg = &config.TLSConfig{ cfg = &config.TLSConfig{

View File

@ -283,9 +283,9 @@ bypasses:
# http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml # http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
- 224.0.0.0/4 # RFC5771: Multicast/Reserved - 224.0.0.0/4 # RFC5771: Multicast/Reserved
# tls: tls:
# cert: "cert.pem" cert: "cert.pem"
# key: "key.pem" key: "key.pem"
# ca: "root.ca" # ca: "root.ca"
resolvers: resolvers:

View File

@ -31,9 +31,11 @@ type ProfilingConfig struct {
} }
type TLSConfig struct { type TLSConfig struct {
Cert string Cert string
Key string Key string
CA string CA string `yaml:",omitempty"`
Secure bool `yaml:",omitempty"`
ServerName string `yaml:",omitempty"`
} }
type AuthConfig struct { type AuthConfig struct {
@ -82,7 +84,8 @@ type HostsConfig struct {
type ListenerConfig struct { type ListenerConfig struct {
Type string Type string
Chain string `yaml:",omitempty"` Chain string `yaml:",omitempty"`
Auths []AuthConfig `yaml:",omitempty"` Auths []*AuthConfig `yaml:",omitempty"`
TLS *TLSConfig `yaml:",omitempty"`
Metadata map[string]interface{} `yaml:",omitempty"` Metadata map[string]interface{} `yaml:",omitempty"`
} }
@ -93,7 +96,8 @@ type HandlerConfig struct {
Bypass string `yaml:",omitempty"` Bypass string `yaml:",omitempty"`
Resolver string `yaml:",omitempty"` Resolver string `yaml:",omitempty"`
Hosts string `yaml:",omitempty"` Hosts string `yaml:",omitempty"`
Auths []AuthConfig `yaml:",omitempty"` Auths []*AuthConfig `yaml:",omitempty"`
TLS *TLSConfig `yaml:",omitempty"`
Metadata map[string]interface{} `yaml:",omitempty"` Metadata map[string]interface{} `yaml:",omitempty"`
} }
@ -105,12 +109,14 @@ type ForwarderConfig struct {
type DialerConfig struct { type DialerConfig struct {
Type string Type string
Auth *AuthConfig `yaml:",omitempty"` Auth *AuthConfig `yaml:",omitempty"`
TLS *TLSConfig `yaml:",omitempty"`
Metadata map[string]interface{} `yaml:",omitempty"` Metadata map[string]interface{} `yaml:",omitempty"`
} }
type ConnectorConfig struct { type ConnectorConfig struct {
Type string Type string
Auth *AuthConfig `yaml:",omitempty"` Auth *AuthConfig `yaml:",omitempty"`
TLS *TLSConfig `yaml:",omitempty"`
Metadata map[string]interface{} `yaml:",omitempty"` Metadata map[string]interface{} `yaml:",omitempty"`
} }

View File

@ -1,6 +1,7 @@
package connector package connector
import ( import (
"crypto/tls"
"net/url" "net/url"
"time" "time"
@ -8,8 +9,9 @@ import (
) )
type Options struct { type Options struct {
User *url.Userinfo User *url.Userinfo
Logger logger.Logger TLSConfig *tls.Config
Logger logger.Logger
} }
type Option func(opts *Options) type Option func(opts *Options)
@ -20,6 +22,12 @@ func UserOption(user *url.Userinfo) Option {
} }
} }
func TLSConfigOption(tlsConfig *tls.Config) Option {
return func(opts *Options) {
opts.TLSConfig = tlsConfig
}
}
func LoggerOption(logger logger.Logger) Option { func LoggerOption(logger logger.Logger) Option {
return func(opts *Options) { return func(opts *Options) {
opts.Logger = logger opts.Logger = logger

View File

@ -53,7 +53,7 @@ func (c *socks5Connector) Init(md md.Metadata) (err error) {
}, },
logger: c.logger, logger: c.logger,
User: c.options.User, User: c.options.User,
TLSConfig: c.md.tlsConfig, TLSConfig: c.options.TLSConfig,
} }
if !c.md.noTLS { if !c.md.noTLS {
selector.methods = append(selector.methods, socks.MethodTLS) selector.methods = append(selector.methods, socks.MethodTLS)

View File

@ -1,7 +1,6 @@
package v5 package v5
import ( import (
"crypto/tls"
"time" "time"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
@ -9,7 +8,6 @@ import (
type metadata struct { type metadata struct {
connectTimeout time.Duration connectTimeout time.Duration
tlsConfig *tls.Config
noTLS bool noTLS bool
} }

View File

@ -19,21 +19,23 @@ func init() {
} }
type http2Dialer struct { type http2Dialer struct {
md metadata
clients map[string]*http.Client clients map[string]*http.Client
clientMutex sync.Mutex clientMutex sync.Mutex
logger logger.Logger logger logger.Logger
md metadata
options dialer.Options
} }
func NewDialer(opts ...dialer.Option) dialer.Dialer { func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &http2Dialer{ return &http2Dialer{
clients: make(map[string]*http.Client), clients: make(map[string]*http.Client),
logger: options.Logger, logger: options.Logger,
options: options,
} }
} }
@ -69,7 +71,7 @@ func (d *http2Dialer) Dial(ctx context.Context, address string, opts ...dialer.D
if !ok { if !ok {
client = &http.Client{ client = &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: d.md.tlsConfig, TLSClientConfig: d.options.TLSConfig,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return d.dial(ctx, network, addr, options) return d.dial(ctx, network, addr, options)
}, },

View File

@ -27,33 +27,36 @@ func init() {
type h2Dialer struct { type h2Dialer struct {
clients map[string]*http.Client clients map[string]*http.Client
clientMutex sync.Mutex clientMutex sync.Mutex
h2c bool
logger logger.Logger logger logger.Logger
md metadata md metadata
h2c bool options dialer.Options
} }
func NewDialer(opts ...dialer.Option) dialer.Dialer { func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &h2Dialer{ return &h2Dialer{
h2c: true,
clients: make(map[string]*http.Client), clients: make(map[string]*http.Client),
logger: options.Logger, logger: options.Logger,
h2c: true, options: options,
} }
} }
func NewTLSDialer(opts ...dialer.Option) dialer.Dialer { func NewTLSDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &h2Dialer{ return &h2Dialer{
clients: make(map[string]*http.Client), clients: make(map[string]*http.Client),
logger: options.Logger, logger: options.Logger,
options: options,
} }
} }
@ -95,7 +98,7 @@ func (d *h2Dialer) Dial(ctx context.Context, address string, opts ...dialer.Dial
} }
} else { } else {
client.Transport = &http.Transport{ client.Transport = &http.Transport{
TLSClientConfig: d.md.tlsConfig, TLSClientConfig: d.options.TLSConfig,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return d.dial(ctx, network, addr, options) return d.dial(ctx, network, addr, options)
}, },

View File

@ -1,42 +1,21 @@
package h2 package h2
import ( import (
"crypto/tls"
"net"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
type metadata struct { type metadata struct {
path string host string
host string path string
tlsConfig *tls.Config
} }
func (d *h2Dialer) parseMetadata(md mdata.Metadata) (err error) { func (d *h2Dialer) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
certFile = "certFile" host = "host"
keyFile = "keyFile" path = "path"
caFile = "caFile"
secure = "secure"
serverName = "serverName"
path = "path"
)
d.md.host = mdata.GetString(md, serverName)
sn, _, _ := net.SplitHostPort(d.md.host)
if sn == "" {
sn = "localhost"
}
d.md.tlsConfig, err = tls_util.LoadClientConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
mdata.GetBool(md, secure),
sn,
) )
d.md.host = mdata.GetString(md, host)
d.md.path = mdata.GetString(md, path) d.md.path = mdata.GetString(md, path)
return return

View File

@ -1,37 +1,12 @@
package http2 package http2
import ( import (
"crypto/tls"
"net"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
type metadata struct { type metadata struct {
tlsConfig *tls.Config
} }
func (d *http2Dialer) parseMetadata(md mdata.Metadata) (err error) { func (d *http2Dialer) parseMetadata(md mdata.Metadata) (err error) {
const (
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
secure = "secure"
serverName = "serverName"
)
sn, _, _ := net.SplitHostPort(mdata.GetString(md, serverName))
if sn == "" {
sn = "localhost"
}
d.md.tlsConfig, err = tls_util.LoadClientConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
mdata.GetBool(md, secure),
sn,
)
return return
} }

View File

@ -2,6 +2,7 @@ package dialer
import ( import (
"context" "context"
"crypto/tls"
"net" "net"
"net/url" "net/url"
@ -9,8 +10,9 @@ import (
) )
type Options struct { type Options struct {
User *url.Userinfo User *url.Userinfo
Logger logger.Logger TLSConfig *tls.Config
Logger logger.Logger
} }
type Option func(opts *Options) type Option func(opts *Options)
@ -21,6 +23,12 @@ func UserOption(user *url.Userinfo) Option {
} }
} }
func TLSConfigOption(tlsConfig *tls.Config) Option {
return func(opts *Options) {
opts.TLSConfig = tlsConfig
}
}
func LoggerOption(logger logger.Logger) Option { func LoggerOption(logger logger.Logger) Option {
return func(opts *Options) { return func(opts *Options) {
opts.Logger = logger opts.Logger = logger

View File

@ -24,17 +24,19 @@ type quicDialer struct {
sessionMutex sync.Mutex sessionMutex sync.Mutex
logger logger.Logger logger logger.Logger
md metadata md metadata
options dialer.Options
} }
func NewDialer(opts ...dialer.Option) dialer.Dialer { func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &quicDialer{ return &quicDialer{
sessions: make(map[string]*quicSession), sessions: make(map[string]*quicSession),
logger: options.Logger, logger: options.Logger,
options: options,
} }
} }
@ -141,7 +143,7 @@ func (d *quicDialer) initSession(ctx context.Context, addr string, conn net.Conn
}, },
} }
tlsCfg := d.md.tlsConfig tlsCfg := d.options.TLSConfig
tlsCfg.NextProtos = []string{"http/3", "quic/v1"} tlsCfg.NextProtos = []string{"http/3", "quic/v1"}
session, err := quic.DialContext(ctx, pc, udpAddr, addr, tlsCfg, quicConfig) session, err := quic.DialContext(ctx, pc, udpAddr, addr, tlsCfg, quicConfig)

View File

@ -1,11 +1,8 @@
package quic package quic
import ( import (
"crypto/tls"
"net"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -15,7 +12,6 @@ type metadata struct {
handshakeTimeout time.Duration handshakeTimeout time.Duration
cipherKey []byte cipherKey []byte
tlsConfig *tls.Config
} }
func (d *quicDialer) parseMetadata(md mdata.Metadata) (err error) { func (d *quicDialer) parseMetadata(md mdata.Metadata) (err error) {
@ -24,12 +20,6 @@ func (d *quicDialer) parseMetadata(md mdata.Metadata) (err error) {
handshakeTimeout = "handshakeTimeout" handshakeTimeout = "handshakeTimeout"
maxIdleTimeout = "maxIdleTimeout" maxIdleTimeout = "maxIdleTimeout"
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
secure = "secure"
serverName = "serverName"
cipherKey = "cipherKey" cipherKey = "cipherKey"
) )
@ -39,18 +29,6 @@ func (d *quicDialer) parseMetadata(md mdata.Metadata) (err error) {
d.md.cipherKey = []byte(key) d.md.cipherKey = []byte(key)
} }
sn, _, _ := net.SplitHostPort(mdata.GetString(md, serverName))
if sn == "" {
sn = "localhost"
}
d.md.tlsConfig, err = tls_util.LoadClientConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
mdata.GetBool(md, secure),
sn,
)
d.md.keepAlive = mdata.GetBool(md, keepAlive) d.md.keepAlive = mdata.GetBool(md, keepAlive)
d.md.handshakeTimeout = mdata.GetDuration(md, handshakeTimeout) d.md.handshakeTimeout = mdata.GetDuration(md, handshakeTimeout)
d.md.maxIdleTimeout = mdata.GetDuration(md, maxIdleTimeout) d.md.maxIdleTimeout = mdata.GetDuration(md, maxIdleTimeout)

View File

@ -17,18 +17,20 @@ func init() {
} }
type tlsDialer struct { type tlsDialer struct {
md metadata md metadata
logger logger.Logger logger logger.Logger
options dialer.Options
} }
func NewDialer(opts ...dialer.Option) dialer.Dialer { func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &tlsDialer{ return &tlsDialer{
logger: options.Logger, logger: options.Logger,
options: options,
} }
} }
@ -57,7 +59,7 @@ func (d *tlsDialer) Handshake(ctx context.Context, conn net.Conn, options ...dia
defer conn.SetDeadline(time.Time{}) defer conn.SetDeadline(time.Time{})
} }
tlsConn := tls.Client(conn, d.md.tlsConfig) tlsConn := tls.Client(conn, d.options.TLSConfig)
if err := tlsConn.HandshakeContext(ctx); err != nil { if err := tlsConn.HandshakeContext(ctx); err != nil {
conn.Close() conn.Close()
return nil, err return nil, err

View File

@ -1,42 +1,20 @@
package tls package tls
import ( import (
"crypto/tls"
"net"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
type metadata struct { type metadata struct {
tlsConfig *tls.Config
handshakeTimeout time.Duration handshakeTimeout time.Duration
} }
func (d *tlsDialer) parseMetadata(md mdata.Metadata) (err error) { func (d *tlsDialer) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
secure = "secure"
serverName = "serverName"
handshakeTimeout = "handshakeTimeout" handshakeTimeout = "handshakeTimeout"
) )
sn, _, _ := net.SplitHostPort(mdata.GetString(md, serverName))
if sn == "" {
sn = "localhost"
}
d.md.tlsConfig, err = tls_util.LoadClientConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
mdata.GetBool(md, secure),
sn,
)
d.md.handshakeTimeout = mdata.GetDuration(md, handshakeTimeout) d.md.handshakeTimeout = mdata.GetDuration(md, handshakeTimeout)
return return

View File

@ -24,17 +24,19 @@ type mtlsDialer struct {
sessionMutex sync.Mutex sessionMutex sync.Mutex
logger logger.Logger logger logger.Logger
md metadata md metadata
options dialer.Options
} }
func NewDialer(opts ...dialer.Option) dialer.Dialer { func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &mtlsDialer{ return &mtlsDialer{
sessions: make(map[string]*muxSession), sessions: make(map[string]*muxSession),
logger: options.Logger, logger: options.Logger,
options: options,
} }
} }
@ -149,7 +151,7 @@ func (d *mtlsDialer) dial(ctx context.Context, network, addr string, opts *diale
} }
func (d *mtlsDialer) initSession(ctx context.Context, conn net.Conn) (*muxSession, error) { func (d *mtlsDialer) initSession(ctx context.Context, conn net.Conn) (*muxSession, error) {
tlsConn := tls.Client(conn, d.md.tlsConfig) tlsConn := tls.Client(conn, d.options.TLSConfig)
if err := tlsConn.HandshakeContext(ctx); err != nil { if err := tlsConn.HandshakeContext(ctx); err != nil {
return nil, err return nil, err
} }

View File

@ -1,16 +1,12 @@
package mux package mux
import ( import (
"crypto/tls"
"net"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
type metadata struct { type metadata struct {
tlsConfig *tls.Config
handshakeTimeout time.Duration handshakeTimeout time.Duration
muxKeepAliveDisabled bool muxKeepAliveDisabled bool
@ -23,12 +19,6 @@ type metadata struct {
func (d *mtlsDialer) parseMetadata(md mdata.Metadata) (err error) { func (d *mtlsDialer) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
secure = "secure"
serverName = "serverName"
handshakeTimeout = "handshakeTimeout" handshakeTimeout = "handshakeTimeout"
muxKeepAliveDisabled = "muxKeepAliveDisabled" muxKeepAliveDisabled = "muxKeepAliveDisabled"
@ -39,17 +29,6 @@ func (d *mtlsDialer) parseMetadata(md mdata.Metadata) (err error) {
muxMaxStreamBuffer = "muxMaxStreamBuffer" muxMaxStreamBuffer = "muxMaxStreamBuffer"
) )
sn, _, _ := net.SplitHostPort(mdata.GetString(md, serverName))
if sn == "" {
sn = "localhost"
}
d.md.tlsConfig, err = tls_util.LoadClientConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
mdata.GetBool(md, secure),
sn,
)
d.md.handshakeTimeout = mdata.GetDuration(md, handshakeTimeout) d.md.handshakeTimeout = mdata.GetDuration(md, handshakeTimeout)
d.md.muxKeepAliveDisabled = mdata.GetBool(md, muxKeepAliveDisabled) d.md.muxKeepAliveDisabled = mdata.GetBool(md, muxKeepAliveDisabled)

View File

@ -23,28 +23,31 @@ type wsDialer struct {
tlsEnabled bool tlsEnabled bool
logger logger.Logger logger logger.Logger
md metadata md metadata
options dialer.Options
} }
func NewDialer(opts ...dialer.Option) dialer.Dialer { func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &wsDialer{ return &wsDialer{
logger: options.Logger, logger: options.Logger,
options: options,
} }
} }
func NewTLSDialer(opts ...dialer.Option) dialer.Dialer { func NewTLSDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &wsDialer{ return &wsDialer{
tlsEnabled: true, tlsEnabled: true,
logger: options.Logger, logger: options.Logger,
options: options,
} }
} }
@ -96,7 +99,7 @@ func (d *wsDialer) Handshake(ctx context.Context, conn net.Conn, options ...dial
url := url.URL{Scheme: "ws", Host: host, Path: d.md.path} url := url.URL{Scheme: "ws", Host: host, Path: d.md.path}
if d.tlsEnabled { if d.tlsEnabled {
url.Scheme = "wss" url.Scheme = "wss"
dialer.TLSClientConfig = d.md.tlsConfig dialer.TLSClientConfig = d.options.TLSConfig
} }
c, resp, err := dialer.Dial(url.String(), d.md.header) c, resp, err := dialer.Dial(url.String(), d.md.header)

View File

@ -1,12 +1,9 @@
package ws package ws
import ( import (
"crypto/tls"
"net"
"net/http" "net/http"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -15,9 +12,8 @@ const (
) )
type metadata struct { type metadata struct {
path string host string
host string path string
tlsConfig *tls.Config
handshakeTimeout time.Duration handshakeTimeout time.Duration
readHeaderTimeout time.Duration readHeaderTimeout time.Duration
@ -30,14 +26,8 @@ type metadata struct {
func (d *wsDialer) parseMetadata(md mdata.Metadata) (err error) { func (d *wsDialer) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
path = "path"
host = "host" host = "host"
path = "path"
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
secure = "secure"
serverName = "serverName"
handshakeTimeout = "handshakeTimeout" handshakeTimeout = "handshakeTimeout"
readHeaderTimeout = "readHeaderTimeout" readHeaderTimeout = "readHeaderTimeout"
@ -48,25 +38,13 @@ func (d *wsDialer) parseMetadata(md mdata.Metadata) (err error) {
header = "header" header = "header"
) )
d.md.host = mdata.GetString(md, host)
d.md.path = mdata.GetString(md, path) d.md.path = mdata.GetString(md, path)
if d.md.path == "" { if d.md.path == "" {
d.md.path = defaultPath d.md.path = defaultPath
} }
d.md.host = mdata.GetString(md, host)
sn, _, _ := net.SplitHostPort(mdata.GetString(md, serverName))
if sn == "" {
sn = "localhost"
}
d.md.tlsConfig, err = tls_util.LoadClientConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
mdata.GetBool(md, secure),
sn,
)
d.md.handshakeTimeout = mdata.GetDuration(md, handshakeTimeout) d.md.handshakeTimeout = mdata.GetDuration(md, handshakeTimeout)
d.md.readHeaderTimeout = mdata.GetDuration(md, readHeaderTimeout) d.md.readHeaderTimeout = mdata.GetDuration(md, readHeaderTimeout)
d.md.readBufferSize = mdata.GetInt(md, readBufferSize) d.md.readBufferSize = mdata.GetInt(md, readBufferSize)

View File

@ -25,33 +25,36 @@ func init() {
type mwsDialer struct { type mwsDialer struct {
sessions map[string]*muxSession sessions map[string]*muxSession
sessionMutex sync.Mutex sessionMutex sync.Mutex
tlsEnabled bool
logger logger.Logger logger logger.Logger
md metadata md metadata
tlsEnabled bool options dialer.Options
} }
func NewDialer(opts ...dialer.Option) dialer.Dialer { func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &mwsDialer{ return &mwsDialer{
sessions: make(map[string]*muxSession), sessions: make(map[string]*muxSession),
logger: options.Logger, logger: options.Logger,
options: options,
} }
} }
func NewTLSDialer(opts ...dialer.Option) dialer.Dialer { func NewTLSDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{} options := dialer.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &mwsDialer{ return &mwsDialer{
tlsEnabled: true,
sessions: make(map[string]*muxSession), sessions: make(map[string]*muxSession),
logger: options.Logger, logger: options.Logger,
tlsEnabled: true, options: options,
} }
} }
func (d *mwsDialer) Init(md md.Metadata) (err error) { func (d *mwsDialer) Init(md md.Metadata) (err error) {
@ -182,7 +185,7 @@ func (d *mwsDialer) initSession(ctx context.Context, host string, conn net.Conn)
url := url.URL{Scheme: "ws", Host: host, Path: d.md.path} url := url.URL{Scheme: "ws", Host: host, Path: d.md.path}
if d.tlsEnabled { if d.tlsEnabled {
url.Scheme = "wss" url.Scheme = "wss"
dialer.TLSClientConfig = d.md.tlsConfig dialer.TLSClientConfig = d.options.TLSConfig
} }
c, resp, err := dialer.Dial(url.String(), d.md.header) c, resp, err := dialer.Dial(url.String(), d.md.header)

View File

@ -1,12 +1,9 @@
package mux package mux
import ( import (
"crypto/tls"
"net"
"net/http" "net/http"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -15,9 +12,8 @@ const (
) )
type metadata struct { type metadata struct {
path string host string
host string path string
tlsConfig *tls.Config
handshakeTimeout time.Duration handshakeTimeout time.Duration
readHeaderTimeout time.Duration readHeaderTimeout time.Duration
@ -37,14 +33,8 @@ type metadata struct {
func (d *mwsDialer) parseMetadata(md mdata.Metadata) (err error) { func (d *mwsDialer) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
path = "path"
host = "host" host = "host"
path = "path"
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
secure = "secure"
serverName = "serverName"
handshakeTimeout = "handshakeTimeout" handshakeTimeout = "handshakeTimeout"
readHeaderTimeout = "readHeaderTimeout" readHeaderTimeout = "readHeaderTimeout"
@ -62,25 +52,13 @@ func (d *mwsDialer) parseMetadata(md mdata.Metadata) (err error) {
muxMaxStreamBuffer = "muxMaxStreamBuffer" muxMaxStreamBuffer = "muxMaxStreamBuffer"
) )
d.md.host = mdata.GetString(md, host)
d.md.path = mdata.GetString(md, path) d.md.path = mdata.GetString(md, path)
if d.md.path == "" { if d.md.path == "" {
d.md.path = defaultPath d.md.path = defaultPath
} }
d.md.host = mdata.GetString(md, host)
sn, _, _ := net.SplitHostPort(mdata.GetString(md, serverName))
if sn == "" {
sn = "localhost"
}
d.md.tlsConfig, err = tls_util.LoadClientConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
mdata.GetBool(md, secure),
sn,
)
d.md.muxKeepAliveDisabled = mdata.GetBool(md, muxKeepAliveDisabled) d.md.muxKeepAliveDisabled = mdata.GetBool(md, muxKeepAliveDisabled)
d.md.muxKeepAliveInterval = mdata.GetDuration(md, muxKeepAliveInterval) d.md.muxKeepAliveInterval = mdata.GetDuration(md, muxKeepAliveInterval)
d.md.muxKeepAliveTimeout = mdata.GetDuration(md, muxKeepAliveTimeout) d.md.muxKeepAliveTimeout = mdata.GetDuration(md, muxKeepAliveTimeout)

View File

@ -1,6 +1,7 @@
package handler package handler
import ( import (
"crypto/tls"
"net/url" "net/url"
"github.com/go-gost/gost/pkg/bypass" "github.com/go-gost/gost/pkg/bypass"
@ -11,13 +12,14 @@ import (
) )
type Options struct { type Options struct {
Retries int Retries int
Chain *chain.Chain Chain *chain.Chain
Resolver resolver.Resolver Resolver resolver.Resolver
Hosts hosts.HostMapper Hosts hosts.HostMapper
Bypass bypass.Bypass Bypass bypass.Bypass
Auths []*url.Userinfo Auths []*url.Userinfo
Logger logger.Logger TLSConfig *tls.Config
Logger logger.Logger
} }
type Option func(opts *Options) type Option func(opts *Options)
@ -58,6 +60,12 @@ func AuthsOption(auths ...*url.Userinfo) Option {
} }
} }
func TLSConfigOption(tlsConfig *tls.Config) Option {
return func(opts *Options) {
opts.TLSConfig = tlsConfig
}
}
func LoggerOption(logger logger.Logger) Option { func LoggerOption(logger logger.Logger) Option {
return func(opts *Options) { return func(opts *Options) {
opts.Logger = logger opts.Logger = logger

View File

@ -55,7 +55,7 @@ func (h *socks5Handler) Init(md md.Metadata) (err error) {
h.selector = &serverSelector{ h.selector = &serverSelector{
Authenticator: auth_util.AuthFromUsers(h.options.Auths...), Authenticator: auth_util.AuthFromUsers(h.options.Auths...),
TLSConfig: h.md.tlsConfig, TLSConfig: h.options.TLSConfig,
logger: h.logger, logger: h.logger,
noTLS: h.md.noTLS, noTLS: h.md.noTLS,
} }

View File

@ -1,16 +1,13 @@
package v5 package v5
import ( import (
"crypto/tls"
"math" "math"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
type metadata struct { type metadata struct {
tlsConfig *tls.Config
timeout time.Duration timeout time.Duration
readTimeout time.Duration readTimeout time.Duration
noTLS bool noTLS bool
@ -22,9 +19,6 @@ type metadata struct {
func (h *socks5Handler) parseMetadata(md mdata.Metadata) (err error) { func (h *socks5Handler) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
readTimeout = "readTimeout" readTimeout = "readTimeout"
timeout = "timeout" timeout = "timeout"
noTLS = "notls" noTLS = "notls"
@ -34,15 +28,6 @@ func (h *socks5Handler) parseMetadata(md mdata.Metadata) (err error) {
compatibilityMode = "comp" compatibilityMode = "comp"
) )
h.md.tlsConfig, err = tls_util.LoadServerConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
)
if err != nil {
return
}
h.md.readTimeout = mdata.GetDuration(md, readTimeout) h.md.readTimeout = mdata.GetDuration(md, readTimeout)
h.md.timeout = mdata.GetDuration(md, timeout) h.md.timeout = mdata.GetDuration(md, timeout)
h.md.noTLS = mdata.GetBool(md, noTLS) h.md.noTLS = mdata.GetBool(md, noTLS)

View File

@ -21,23 +21,23 @@ func init() {
} }
type dnsListener struct { type dnsListener struct {
saddr string
addr net.Addr addr net.Addr
server Server server Server
cqueue chan net.Conn cqueue chan net.Conn
errChan chan error errChan chan error
logger logger.Logger logger logger.Logger
md metadata md metadata
options listener.Options
} }
func NewListener(opts ...listener.Option) listener.Listener { func NewListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &dnsListener{ return &dnsListener{
saddr: options.Addr, logger: options.Logger,
logger: options.Logger, options: options,
} }
} }
@ -46,7 +46,7 @@ func (l *dnsListener) Init(md md.Metadata) (err error) {
return return
} }
l.addr, err = net.ResolveTCPAddr("tcp", l.saddr) l.addr, err = net.ResolveTCPAddr("tcp", l.options.Addr)
if err != nil { if err != nil {
return err return err
} }
@ -55,7 +55,7 @@ func (l *dnsListener) Init(md md.Metadata) (err error) {
case "tcp": case "tcp":
l.server = &dns.Server{ l.server = &dns.Server{
Net: "tcp", Net: "tcp",
Addr: l.saddr, Addr: l.options.Addr,
Handler: l, Handler: l,
ReadTimeout: l.md.readTimeout, ReadTimeout: l.md.readTimeout,
WriteTimeout: l.md.writeTimeout, WriteTimeout: l.md.writeTimeout,
@ -63,16 +63,16 @@ func (l *dnsListener) Init(md md.Metadata) (err error) {
case "tls": case "tls":
l.server = &dns.Server{ l.server = &dns.Server{
Net: "tcp-tls", Net: "tcp-tls",
Addr: l.saddr, Addr: l.options.Addr,
Handler: l, Handler: l,
TLSConfig: l.md.tlsConfig, TLSConfig: l.options.TLSConfig,
ReadTimeout: l.md.readTimeout, ReadTimeout: l.md.readTimeout,
WriteTimeout: l.md.writeTimeout, WriteTimeout: l.md.writeTimeout,
} }
case "https": case "https":
l.server = &dohServer{ l.server = &dohServer{
addr: l.saddr, addr: l.options.Addr,
tlsConfig: l.md.tlsConfig, tlsConfig: l.options.TLSConfig,
server: &http.Server{ server: &http.Server{
Handler: l, Handler: l,
ReadTimeout: l.md.readTimeout, ReadTimeout: l.md.readTimeout,
@ -80,10 +80,10 @@ func (l *dnsListener) Init(md md.Metadata) (err error) {
}, },
} }
default: default:
l.addr, err = net.ResolveUDPAddr("udp", l.saddr) l.addr, err = net.ResolveUDPAddr("udp", l.options.Addr)
l.server = &dns.Server{ l.server = &dns.Server{
Net: "udp", Net: "udp",
Addr: l.saddr, Addr: l.options.Addr,
Handler: l, Handler: l,
UDPSize: l.md.readBufferSize, UDPSize: l.md.readBufferSize,
ReadTimeout: l.md.readTimeout, ReadTimeout: l.md.readTimeout,

View File

@ -1,10 +1,8 @@
package dns package dns
import ( import (
"crypto/tls"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -17,7 +15,6 @@ type metadata struct {
readBufferSize int readBufferSize int
readTimeout time.Duration readTimeout time.Duration
writeTimeout time.Duration writeTimeout time.Duration
tlsConfig *tls.Config
backlog int backlog int
} }
@ -26,24 +23,12 @@ func (l *dnsListener) parseMetadata(md mdata.Metadata) (err error) {
mode = "mode" mode = "mode"
readBufferSize = "readBufferSize" readBufferSize = "readBufferSize"
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
backlog = "backlog" backlog = "backlog"
) )
l.md.mode = mdata.GetString(md, mode) l.md.mode = mdata.GetString(md, mode)
l.md.readBufferSize = mdata.GetInt(md, readBufferSize) l.md.readBufferSize = mdata.GetInt(md, readBufferSize)
l.md.tlsConfig, err = tls_util.LoadServerConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
)
if err != nil {
return
}
l.md.backlog = mdata.GetInt(md, backlog) l.md.backlog = mdata.GetInt(md, backlog)
if l.md.backlog <= 0 { if l.md.backlog <= 0 {
l.md.backlog = defaultBacklog l.md.backlog = defaultBacklog

View File

@ -22,35 +22,35 @@ func init() {
type h2Listener struct { type h2Listener struct {
server *http.Server server *http.Server
saddr string
addr net.Addr addr net.Addr
cqueue chan net.Conn cqueue chan net.Conn
errChan chan error errChan chan error
logger logger.Logger logger logger.Logger
md metadata md metadata
h2c bool h2c bool
options listener.Options
} }
func NewListener(opts ...listener.Option) listener.Listener { func NewListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &h2Listener{ return &h2Listener{
saddr: options.Addr, h2c: true,
logger: options.Logger, logger: options.Logger,
h2c: true, options: options,
} }
} }
func NewTLSListener(opts ...listener.Option) listener.Listener { func NewTLSListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &h2Listener{ return &h2Listener{
saddr: options.Addr, logger: options.Logger,
logger: options.Logger, options: options,
} }
} }
@ -60,10 +60,10 @@ func (l *h2Listener) Init(md md.Metadata) (err error) {
} }
l.server = &http.Server{ l.server = &http.Server{
Addr: l.saddr, Addr: l.options.Addr,
} }
ln, err := net.Listen("tcp", l.saddr) ln, err := net.Listen("tcp", l.options.Addr)
if err != nil { if err != nil {
return err return err
} }
@ -74,12 +74,12 @@ func (l *h2Listener) Init(md md.Metadata) (err error) {
http.HandlerFunc(l.handleFunc), &http2.Server{}) http.HandlerFunc(l.handleFunc), &http2.Server{})
} else { } else {
l.server.Handler = http.HandlerFunc(l.handleFunc) l.server.Handler = http.HandlerFunc(l.handleFunc)
l.server.TLSConfig = l.md.tlsConfig l.server.TLSConfig = l.options.TLSConfig
if err := http2.ConfigureServer(l.server, nil); err != nil { if err := http2.ConfigureServer(l.server, nil); err != nil {
ln.Close() ln.Close()
return err return err
} }
ln = tls.NewListener(ln, l.md.tlsConfig) ln = tls.NewListener(ln, l.options.TLSConfig)
} }
l.cqueue = make(chan net.Conn, l.md.backlog) l.cqueue = make(chan net.Conn, l.md.backlog)

View File

@ -1,9 +1,6 @@
package h2 package h2
import ( import (
"crypto/tls"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -12,29 +9,16 @@ const (
) )
type metadata struct { type metadata struct {
path string path string
tlsConfig *tls.Config backlog int
backlog int
} }
func (l *h2Listener) parseMetadata(md mdata.Metadata) (err error) { func (l *h2Listener) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
path = "path" path = "path"
certFile = "certFile" backlog = "backlog"
keyFile = "keyFile"
caFile = "caFile"
backlog = "backlog"
) )
l.md.tlsConfig, err = tls_util.LoadServerConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
)
if err != nil {
return
}
l.md.backlog = mdata.GetInt(md, backlog) l.md.backlog = mdata.GetInt(md, backlog)
if l.md.backlog <= 0 { if l.md.backlog <= 0 {
l.md.backlog = defaultBacklog l.md.backlog = defaultBacklog

View File

@ -20,22 +20,22 @@ func init() {
type http2Listener struct { type http2Listener struct {
server *http.Server server *http.Server
saddr string
addr net.Addr addr net.Addr
cqueue chan net.Conn cqueue chan net.Conn
errChan chan error errChan chan error
logger logger.Logger logger logger.Logger
md metadata md metadata
options listener.Options
} }
func NewListener(opts ...listener.Option) listener.Listener { func NewListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &http2Listener{ return &http2Listener{
saddr: options.Addr, logger: options.Logger,
logger: options.Logger, options: options,
} }
} }
@ -45,15 +45,15 @@ func (l *http2Listener) Init(md md.Metadata) (err error) {
} }
l.server = &http.Server{ l.server = &http.Server{
Addr: l.saddr, Addr: l.options.Addr,
Handler: http.HandlerFunc(l.handleFunc), Handler: http.HandlerFunc(l.handleFunc),
TLSConfig: l.md.tlsConfig, TLSConfig: l.options.TLSConfig,
} }
if err := http2.ConfigureServer(l.server, nil); err != nil { if err := http2.ConfigureServer(l.server, nil); err != nil {
return err return err
} }
ln, err := net.Listen("tcp", l.saddr) ln, err := net.Listen("tcp", l.options.Addr)
if err != nil { if err != nil {
return err return err
} }
@ -63,7 +63,7 @@ func (l *http2Listener) Init(md md.Metadata) (err error) {
&util.TCPKeepAliveListener{ &util.TCPKeepAliveListener{
TCPListener: ln.(*net.TCPListener), TCPListener: ln.(*net.TCPListener),
}, },
l.md.tlsConfig, l.options.TLSConfig,
) )
l.cqueue = make(chan net.Conn, l.md.backlog) l.cqueue = make(chan net.Conn, l.md.backlog)

View File

@ -1,11 +1,9 @@
package http2 package http2
import ( import (
"crypto/tls"
"net/http" "net/http"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -15,7 +13,6 @@ const (
type metadata struct { type metadata struct {
path string path string
tlsConfig *tls.Config
handshakeTimeout time.Duration handshakeTimeout time.Duration
readHeaderTimeout time.Duration readHeaderTimeout time.Duration
readBufferSize int readBufferSize int
@ -28,9 +25,6 @@ type metadata struct {
func (l *http2Listener) parseMetadata(md mdata.Metadata) (err error) { func (l *http2Listener) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
path = "path" path = "path"
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
handshakeTimeout = "handshakeTimeout" handshakeTimeout = "handshakeTimeout"
readHeaderTimeout = "readHeaderTimeout" readHeaderTimeout = "readHeaderTimeout"
readBufferSize = "readBufferSize" readBufferSize = "readBufferSize"
@ -38,15 +32,6 @@ func (l *http2Listener) parseMetadata(md mdata.Metadata) (err error) {
backlog = "backlog" backlog = "backlog"
) )
l.md.tlsConfig, err = tls_util.LoadServerConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
)
if err != nil {
return
}
l.md.backlog = mdata.GetInt(md, backlog) l.md.backlog = mdata.GetInt(md, backlog)
if l.md.backlog <= 0 { if l.md.backlog <= 0 {
l.md.backlog = defaultBacklog l.md.backlog = defaultBacklog

View File

@ -1,15 +1,17 @@
package listener package listener
import ( import (
"crypto/tls"
"net/url" "net/url"
"github.com/go-gost/gost/pkg/logger" "github.com/go-gost/gost/pkg/logger"
) )
type Options struct { type Options struct {
Addr string Addr string
Auths []*url.Userinfo Auths []*url.Userinfo
Logger logger.Logger TLSConfig *tls.Config
Logger logger.Logger
} }
type Option func(opts *Options) type Option func(opts *Options)
@ -26,6 +28,12 @@ func AuthsOption(auths ...*url.Userinfo) Option {
} }
} }
func TLSConfigOption(tlsConfig *tls.Config) Option {
return func(opts *Options) {
opts.TLSConfig = tlsConfig
}
}
func LoggerOption(logger logger.Logger) Option { func LoggerOption(logger logger.Logger) Option {
return func(opts *Options) { return func(opts *Options) {
opts.Logger = logger opts.Logger = logger

View File

@ -17,22 +17,22 @@ func init() {
} }
type quicListener struct { type quicListener struct {
addr string
ln quic.Listener ln quic.Listener
cqueue chan net.Conn cqueue chan net.Conn
errChan chan error errChan chan error
logger logger.Logger logger logger.Logger
md metadata md metadata
options listener.Options
} }
func NewListener(opts ...listener.Option) listener.Listener { func NewListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &quicListener{ return &quicListener{
addr: options.Addr, logger: options.Logger,
logger: options.Logger, options: options,
} }
} }
@ -41,7 +41,7 @@ func (l *quicListener) Init(md md.Metadata) (err error) {
return return
} }
laddr, err := net.ResolveUDPAddr("udp", l.addr) laddr, err := net.ResolveUDPAddr("udp", l.options.Addr)
if err != nil { if err != nil {
return return
} }
@ -67,7 +67,7 @@ func (l *quicListener) Init(md md.Metadata) (err error) {
}, },
} }
tlsCfg := l.md.tlsConfig tlsCfg := l.options.TLSConfig
tlsCfg.NextProtos = []string{"http/3", "quic/v1"} tlsCfg.NextProtos = []string{"http/3", "quic/v1"}
ln, err := quic.Listen(conn, tlsCfg, config) ln, err := quic.Listen(conn, tlsCfg, config)

View File

@ -1,10 +1,8 @@
package quic package quic
import ( import (
"crypto/tls"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -17,7 +15,6 @@ type metadata struct {
handshakeTimeout time.Duration handshakeTimeout time.Duration
maxIdleTimeout time.Duration maxIdleTimeout time.Duration
tlsConfig *tls.Config
cipherKey []byte cipherKey []byte
backlog int backlog int
} }
@ -28,23 +25,10 @@ func (l *quicListener) parseMetadata(md mdata.Metadata) (err error) {
handshakeTimeout = "handshakeTimeout" handshakeTimeout = "handshakeTimeout"
maxIdleTimeout = "maxIdleTimeout" maxIdleTimeout = "maxIdleTimeout"
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
backlog = "backlog" backlog = "backlog"
cipherKey = "cipherKey" cipherKey = "cipherKey"
) )
l.md.tlsConfig, err = tls_util.LoadServerConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
)
if err != nil {
return
}
l.md.backlog = mdata.GetInt(md, backlog) l.md.backlog = mdata.GetInt(md, backlog)
if l.md.backlog <= 0 { if l.md.backlog <= 0 {
l.md.backlog = defaultBacklog l.md.backlog = defaultBacklog

View File

@ -15,20 +15,20 @@ func init() {
} }
type tlsListener struct { type tlsListener struct {
addr string
net.Listener net.Listener
logger logger.Logger logger logger.Logger
md metadata md metadata
options listener.Options
} }
func NewListener(opts ...listener.Option) listener.Listener { func NewListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &tlsListener{ return &tlsListener{
addr: options.Addr, logger: options.Logger,
logger: options.Logger, options: options,
} }
} }
@ -37,12 +37,12 @@ func (l *tlsListener) Init(md md.Metadata) (err error) {
return return
} }
ln, err := net.Listen("tcp", l.addr) ln, err := net.Listen("tcp", l.options.Addr)
if err != nil { if err != nil {
return return
} }
l.Listener = tls.NewListener(ln, l.md.tlsConfig) l.Listener = tls.NewListener(ln, l.options.TLSConfig)
return return
} }

View File

@ -1,31 +1,12 @@
package tls package tls
import ( import (
"crypto/tls"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
type metadata struct { type metadata struct {
tlsConfig *tls.Config
} }
func (l *tlsListener) parseMetadata(md mdata.Metadata) (err error) { func (l *tlsListener) parseMetadata(md mdata.Metadata) (err error) {
const (
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
)
l.md.tlsConfig, err = tls_util.LoadServerConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
)
if err != nil {
return
}
return return
} }

View File

@ -16,22 +16,22 @@ func init() {
} }
type mtlsListener struct { type mtlsListener struct {
addr string
net.Listener net.Listener
cqueue chan net.Conn cqueue chan net.Conn
errChan chan error errChan chan error
logger logger.Logger logger logger.Logger
md metadata md metadata
options listener.Options
} }
func NewListener(opts ...listener.Option) listener.Listener { func NewListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &mtlsListener{ return &mtlsListener{
addr: options.Addr, logger: options.Logger,
logger: options.Logger, options: options,
} }
} }
@ -40,11 +40,11 @@ func (l *mtlsListener) Init(md md.Metadata) (err error) {
return return
} }
ln, err := net.Listen("tcp", l.addr) ln, err := net.Listen("tcp", l.options.Addr)
if err != nil { if err != nil {
return return
} }
l.Listener = tls.NewListener(ln, l.md.tlsConfig) l.Listener = tls.NewListener(ln, l.options.TLSConfig)
l.cqueue = make(chan net.Conn, l.md.backlog) l.cqueue = make(chan net.Conn, l.md.backlog)
l.errChan = make(chan error, 1) l.errChan = make(chan error, 1)

View File

@ -1,10 +1,8 @@
package mux package mux
import ( import (
"crypto/tls"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -13,8 +11,6 @@ const (
) )
type metadata struct { type metadata struct {
tlsConfig *tls.Config
muxKeepAliveDisabled bool muxKeepAliveDisabled bool
muxKeepAliveInterval time.Duration muxKeepAliveInterval time.Duration
muxKeepAliveTimeout time.Duration muxKeepAliveTimeout time.Duration
@ -27,10 +23,6 @@ type metadata struct {
func (l *mtlsListener) parseMetadata(md mdata.Metadata) (err error) { func (l *mtlsListener) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
backlog = "backlog" backlog = "backlog"
muxKeepAliveDisabled = "muxKeepAliveDisabled" muxKeepAliveDisabled = "muxKeepAliveDisabled"
@ -41,15 +33,6 @@ func (l *mtlsListener) parseMetadata(md mdata.Metadata) (err error) {
muxMaxStreamBuffer = "muxMaxStreamBuffer" muxMaxStreamBuffer = "muxMaxStreamBuffer"
) )
l.md.tlsConfig, err = tls_util.LoadServerConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
)
if err != nil {
return
}
l.md.backlog = mdata.GetInt(md, backlog) l.md.backlog = mdata.GetInt(md, backlog)
if l.md.backlog <= 0 { if l.md.backlog <= 0 {
l.md.backlog = defaultBacklog l.md.backlog = defaultBacklog

View File

@ -20,7 +20,6 @@ func init() {
} }
type wsListener struct { type wsListener struct {
saddr string
addr net.Addr addr net.Addr
upgrader *websocket.Upgrader upgrader *websocket.Upgrader
srv *http.Server srv *http.Server
@ -29,28 +28,29 @@ type wsListener struct {
errChan chan error errChan chan error
logger logger.Logger logger logger.Logger
md metadata md metadata
options listener.Options
} }
func NewListener(opts ...listener.Option) listener.Listener { func NewListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &wsListener{ return &wsListener{
saddr: options.Addr, logger: options.Logger,
logger: options.Logger, options: options,
} }
} }
func NewTLSListener(opts ...listener.Option) listener.Listener { func NewTLSListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &wsListener{ return &wsListener{
saddr: options.Addr,
logger: options.Logger,
tlsEnabled: true, tlsEnabled: true,
logger: options.Logger,
options: options,
} }
} }
@ -70,7 +70,7 @@ func (l *wsListener) Init(md md.Metadata) (err error) {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.Handle(l.md.path, http.HandlerFunc(l.upgrade)) mux.Handle(l.md.path, http.HandlerFunc(l.upgrade))
l.srv = &http.Server{ l.srv = &http.Server{
Addr: l.saddr, Addr: l.options.Addr,
Handler: mux, Handler: mux,
ReadHeaderTimeout: l.md.readHeaderTimeout, ReadHeaderTimeout: l.md.readHeaderTimeout,
} }
@ -78,12 +78,12 @@ func (l *wsListener) Init(md md.Metadata) (err error) {
l.cqueue = make(chan net.Conn, l.md.backlog) l.cqueue = make(chan net.Conn, l.md.backlog)
l.errChan = make(chan error, 1) l.errChan = make(chan error, 1)
ln, err := net.Listen("tcp", l.saddr) ln, err := net.Listen("tcp", l.options.Addr)
if err != nil { if err != nil {
return return
} }
if l.tlsEnabled { if l.tlsEnabled {
ln = tls.NewListener(ln, l.md.tlsConfig) ln = tls.NewListener(ln, l.options.TLSConfig)
} }
l.addr = ln.Addr() l.addr = ln.Addr()

View File

@ -1,11 +1,9 @@
package ws package ws
import ( import (
"crypto/tls"
"net/http" "net/http"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -15,9 +13,8 @@ const (
) )
type metadata struct { type metadata struct {
path string path string
backlog int backlog int
tlsConfig *tls.Config
handshakeTimeout time.Duration handshakeTimeout time.Duration
readHeaderTimeout time.Duration readHeaderTimeout time.Duration
@ -30,10 +27,6 @@ type metadata struct {
func (l *wsListener) parseMetadata(md mdata.Metadata) (err error) { func (l *wsListener) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
path = "path" path = "path"
backlog = "backlog" backlog = "backlog"
@ -46,15 +39,6 @@ func (l *wsListener) parseMetadata(md mdata.Metadata) (err error) {
header = "header" header = "header"
) )
l.md.tlsConfig, err = tls_util.LoadServerConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
)
if err != nil {
return
}
l.md.path = mdata.GetString(md, path) l.md.path = mdata.GetString(md, path)
if l.md.path == "" { if l.md.path == "" {
l.md.path = defaultPath l.md.path = defaultPath

View File

@ -21,37 +21,37 @@ func init() {
} }
type mwsListener struct { type mwsListener struct {
saddr string
addr net.Addr addr net.Addr
upgrader *websocket.Upgrader upgrader *websocket.Upgrader
srv *http.Server srv *http.Server
cqueue chan net.Conn cqueue chan net.Conn
errChan chan error errChan chan error
tlsEnabled bool
logger logger.Logger logger logger.Logger
md metadata md metadata
tlsEnabled bool options listener.Options
} }
func NewListener(opts ...listener.Option) listener.Listener { func NewListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &mwsListener{ return &mwsListener{
saddr: options.Addr, logger: options.Logger,
logger: options.Logger, options: options,
} }
} }
func NewTLSListener(opts ...listener.Option) listener.Listener { func NewTLSListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{} options := listener.Options{}
for _, opt := range opts { for _, opt := range opts {
opt(options) opt(&options)
} }
return &mwsListener{ return &mwsListener{
saddr: options.Addr,
logger: options.Logger,
tlsEnabled: true, tlsEnabled: true,
logger: options.Logger,
options: options,
} }
} }
@ -75,7 +75,7 @@ func (l *mwsListener) Init(md md.Metadata) (err error) {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.Handle(path, http.HandlerFunc(l.upgrade)) mux.Handle(path, http.HandlerFunc(l.upgrade))
l.srv = &http.Server{ l.srv = &http.Server{
Addr: l.saddr, Addr: l.options.Addr,
Handler: mux, Handler: mux,
ReadHeaderTimeout: l.md.readHeaderTimeout, ReadHeaderTimeout: l.md.readHeaderTimeout,
} }
@ -83,12 +83,12 @@ func (l *mwsListener) Init(md md.Metadata) (err error) {
l.cqueue = make(chan net.Conn, l.md.backlog) l.cqueue = make(chan net.Conn, l.md.backlog)
l.errChan = make(chan error, 1) l.errChan = make(chan error, 1)
ln, err := net.Listen("tcp", l.saddr) ln, err := net.Listen("tcp", l.options.Addr)
if err != nil { if err != nil {
return return
} }
if l.tlsEnabled { if l.tlsEnabled {
ln = tls.NewListener(ln, l.md.tlsConfig) ln = tls.NewListener(ln, l.options.TLSConfig)
} }
l.addr = ln.Addr() l.addr = ln.Addr()

View File

@ -1,11 +1,9 @@
package mux package mux
import ( import (
"crypto/tls"
"net/http" "net/http"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls"
mdata "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
@ -15,10 +13,9 @@ const (
) )
type metadata struct { type metadata struct {
path string path string
backlog int backlog int
tlsConfig *tls.Config header http.Header
header http.Header
handshakeTimeout time.Duration handshakeTimeout time.Duration
readHeaderTimeout time.Duration readHeaderTimeout time.Duration
@ -40,10 +37,6 @@ func (l *mwsListener) parseMetadata(md mdata.Metadata) (err error) {
backlog = "backlog" backlog = "backlog"
header = "header" header = "header"
certFile = "certFile"
keyFile = "keyFile"
caFile = "caFile"
handshakeTimeout = "handshakeTimeout" handshakeTimeout = "handshakeTimeout"
readHeaderTimeout = "readHeaderTimeout" readHeaderTimeout = "readHeaderTimeout"
readBufferSize = "readBufferSize" readBufferSize = "readBufferSize"
@ -58,15 +51,6 @@ func (l *mwsListener) parseMetadata(md mdata.Metadata) (err error) {
muxMaxStreamBuffer = "muxMaxStreamBuffer" muxMaxStreamBuffer = "muxMaxStreamBuffer"
) )
l.md.tlsConfig, err = tls_util.LoadServerConfig(
mdata.GetString(md, certFile),
mdata.GetString(md, keyFile),
mdata.GetString(md, caFile),
)
if err != nil {
return
}
l.md.path = mdata.GetString(md, path) l.md.path = mdata.GetString(md, path)
if l.md.path == "" { if l.md.path == "" {
l.md.path = defaultPath l.md.path = defaultPath