add port range support for service
This commit is contained in:
105
chain/route.go
105
chain/route.go
@ -2,6 +2,8 @@ package chain
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
@ -10,9 +12,86 @@ import (
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/core/metrics"
|
||||
"github.com/go-gost/core/selector"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
"github.com/go-gost/x/internal/net/dialer"
|
||||
"github.com/go-gost/x/internal/net/udp"
|
||||
xmetrics "github.com/go-gost/x/metrics"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrEmptyRoute = errors.New("empty route")
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultRoute chain.Route = &defaultRoute{}
|
||||
)
|
||||
|
||||
// defaultRoute is a Route without nodes.
|
||||
type defaultRoute struct{}
|
||||
|
||||
func (*defaultRoute) Dial(ctx context.Context, network, address string, opts ...chain.DialOption) (net.Conn, error) {
|
||||
var options chain.DialOptions
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
netd := dialer.Dialer{
|
||||
Interface: options.Interface,
|
||||
Netns: options.Netns,
|
||||
Logger: options.Logger,
|
||||
}
|
||||
if options.SockOpts != nil {
|
||||
netd.Mark = options.SockOpts.Mark
|
||||
}
|
||||
|
||||
return netd.Dial(ctx, network, address)
|
||||
}
|
||||
|
||||
func (*defaultRoute) Bind(ctx context.Context, network, address string, opts ...chain.BindOption) (net.Listener, error) {
|
||||
var options chain.BindOptions
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
addr, err := net.ResolveTCPAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return net.ListenTCP(network, addr)
|
||||
case "udp", "udp4", "udp6":
|
||||
addr, err := net.ResolveUDPAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn, err := net.ListenUDP(network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logger := logger.Default().WithFields(map[string]any{
|
||||
"network": network,
|
||||
"address": address,
|
||||
})
|
||||
ln := udp.NewListener(conn, &udp.ListenConfig{
|
||||
Backlog: options.Backlog,
|
||||
ReadQueueSize: options.UDPDataQueueSize,
|
||||
ReadBufferSize: options.UDPDataBufferSize,
|
||||
TTL: options.UDPConnTTL,
|
||||
KeepAlive: true,
|
||||
Logger: logger,
|
||||
})
|
||||
return ln, err
|
||||
default:
|
||||
err := fmt.Errorf("network %s unsupported", network)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (r *defaultRoute) Nodes() []*chain.Node {
|
||||
return nil
|
||||
}
|
||||
|
||||
type RouteOptions struct {
|
||||
Chain chain.Chainer
|
||||
}
|
||||
@ -25,12 +104,12 @@ func ChainRouteOption(c chain.Chainer) RouteOption {
|
||||
}
|
||||
}
|
||||
|
||||
type route struct {
|
||||
type chainRoute struct {
|
||||
nodes []*chain.Node
|
||||
options RouteOptions
|
||||
}
|
||||
|
||||
func NewRoute(opts ...RouteOption) *route {
|
||||
func NewRoute(opts ...RouteOption) *chainRoute {
|
||||
var options RouteOptions
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
@ -38,18 +117,18 @@ func NewRoute(opts ...RouteOption) *route {
|
||||
}
|
||||
}
|
||||
|
||||
return &route{
|
||||
return &chainRoute{
|
||||
options: options,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *route) addNode(nodes ...*chain.Node) {
|
||||
func (r *chainRoute) addNode(nodes ...*chain.Node) {
|
||||
r.nodes = append(r.nodes, nodes...)
|
||||
}
|
||||
|
||||
func (r *route) Dial(ctx context.Context, network, address string, opts ...chain.DialOption) (net.Conn, error) {
|
||||
func (r *chainRoute) Dial(ctx context.Context, network, address string, opts ...chain.DialOption) (net.Conn, error) {
|
||||
if len(r.Nodes()) == 0 {
|
||||
return chain.DefaultRoute.Dial(ctx, network, address, opts...)
|
||||
return DefaultRoute.Dial(ctx, network, address, opts...)
|
||||
}
|
||||
|
||||
var options chain.DialOptions
|
||||
@ -73,9 +152,9 @@ func (r *route) Dial(ctx context.Context, network, address string, opts ...chain
|
||||
return cc, nil
|
||||
}
|
||||
|
||||
func (r *route) Bind(ctx context.Context, network, address string, opts ...chain.BindOption) (net.Listener, error) {
|
||||
func (r *chainRoute) Bind(ctx context.Context, network, address string, opts ...chain.BindOption) (net.Listener, error) {
|
||||
if len(r.Nodes()) == 0 {
|
||||
return chain.DefaultRoute.Bind(ctx, network, address, opts...)
|
||||
return DefaultRoute.Bind(ctx, network, address, opts...)
|
||||
}
|
||||
|
||||
var options chain.BindOptions
|
||||
@ -106,7 +185,7 @@ func (r *route) Bind(ctx context.Context, network, address string, opts ...chain
|
||||
return ln, nil
|
||||
}
|
||||
|
||||
func (r *route) connect(ctx context.Context, logger logger.Logger) (conn net.Conn, err error) {
|
||||
func (r *chainRoute) connect(ctx context.Context, logger logger.Logger) (conn net.Conn, err error) {
|
||||
network := "ip"
|
||||
node := r.nodes[0]
|
||||
|
||||
@ -138,7 +217,7 @@ func (r *route) connect(ctx context.Context, logger logger.Logger) (conn net.Con
|
||||
}
|
||||
}()
|
||||
|
||||
addr, err := chain.Resolve(ctx, network, node.Addr, node.Options().Resolver, node.Options().HostMapper, logger)
|
||||
addr, err := xnet.Resolve(ctx, network, node.Addr, node.Options().Resolver, node.Options().HostMapper, logger)
|
||||
marker := node.Marker()
|
||||
if err != nil {
|
||||
if marker != nil {
|
||||
@ -182,7 +261,7 @@ func (r *route) connect(ctx context.Context, logger logger.Logger) (conn net.Con
|
||||
preNode := node
|
||||
for _, node := range r.nodes[1:] {
|
||||
marker := node.Marker()
|
||||
addr, err = chain.Resolve(ctx, network, node.Addr, node.Options().Resolver, node.Options().HostMapper, logger)
|
||||
addr, err = xnet.Resolve(ctx, network, node.Addr, node.Options().Resolver, node.Options().HostMapper, logger)
|
||||
if err != nil {
|
||||
cn.Close()
|
||||
if marker != nil {
|
||||
@ -218,14 +297,14 @@ func (r *route) connect(ctx context.Context, logger logger.Logger) (conn net.Con
|
||||
return
|
||||
}
|
||||
|
||||
func (r *route) getNode(index int) *chain.Node {
|
||||
func (r *chainRoute) getNode(index int) *chain.Node {
|
||||
if r == nil || len(r.Nodes()) == 0 || index < 0 || index >= len(r.Nodes()) {
|
||||
return nil
|
||||
}
|
||||
return r.nodes[index]
|
||||
}
|
||||
|
||||
func (r *route) Nodes() []*chain.Node {
|
||||
func (r *chainRoute) Nodes() []*chain.Node {
|
||||
if r != nil {
|
||||
return r.nodes
|
||||
}
|
||||
|
205
chain/router.go
Normal file
205
chain/router.go
Normal file
@ -0,0 +1,205 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/core/recorder"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
)
|
||||
|
||||
type Router struct {
|
||||
options chain.RouterOptions
|
||||
}
|
||||
|
||||
func NewRouter(opts ...chain.RouterOption) *Router {
|
||||
r := &Router{}
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
opt(&r.options)
|
||||
}
|
||||
}
|
||||
if r.options.Timeout == 0 {
|
||||
r.options.Timeout = 15 * time.Second
|
||||
}
|
||||
|
||||
if r.options.Logger == nil {
|
||||
r.options.Logger = logger.Default().WithFields(map[string]any{"kind": "router"})
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Router) Options() *chain.RouterOptions {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
return &r.options
|
||||
}
|
||||
|
||||
func (r *Router) Dial(ctx context.Context, network, address string) (conn net.Conn, err error) {
|
||||
if r.options.Timeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, r.options.Timeout)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
host := address
|
||||
if h, _, _ := net.SplitHostPort(address); h != "" {
|
||||
host = h
|
||||
}
|
||||
r.record(ctx, recorder.RecorderServiceRouterDialAddress, []byte(host))
|
||||
|
||||
conn, err = r.dial(ctx, network, address)
|
||||
if err != nil {
|
||||
r.record(ctx, recorder.RecorderServiceRouterDialAddressError, []byte(host))
|
||||
return
|
||||
}
|
||||
|
||||
if network == "udp" || network == "udp4" || network == "udp6" {
|
||||
if _, ok := conn.(net.PacketConn); !ok {
|
||||
return &packetConn{conn}, nil
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Router) record(ctx context.Context, name string, data []byte) error {
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, rec := range r.options.Recorders {
|
||||
if rec.Record == name {
|
||||
err := rec.Recorder.Record(ctx, data)
|
||||
if err != nil {
|
||||
r.options.Logger.Errorf("record %s: %v", name, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Router) dial(ctx context.Context, network, address string) (conn net.Conn, err error) {
|
||||
count := r.options.Retries + 1
|
||||
if count <= 0 {
|
||||
count = 1
|
||||
}
|
||||
r.options.Logger.Debugf("dial %s/%s", address, network)
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
var ipAddr string
|
||||
ipAddr, err = xnet.Resolve(ctx, "ip", address, r.options.Resolver, r.options.HostMapper, r.options.Logger)
|
||||
if err != nil {
|
||||
r.options.Logger.Error(err)
|
||||
break
|
||||
}
|
||||
|
||||
var route chain.Route
|
||||
if r.options.Chain != nil {
|
||||
route = r.options.Chain.Route(ctx, network, ipAddr, chain.WithHostRouteOption(address))
|
||||
}
|
||||
|
||||
if r.options.Logger.IsLevelEnabled(logger.DebugLevel) {
|
||||
buf := bytes.Buffer{}
|
||||
for _, node := range routePath(route) {
|
||||
fmt.Fprintf(&buf, "%s@%s > ", node.Name, node.Addr)
|
||||
}
|
||||
fmt.Fprintf(&buf, "%s", ipAddr)
|
||||
r.options.Logger.Debugf("route(retry=%d) %s", i, buf.String())
|
||||
}
|
||||
|
||||
if route == nil {
|
||||
route = DefaultRoute
|
||||
}
|
||||
conn, err = route.Dial(ctx, network, ipAddr,
|
||||
chain.InterfaceDialOption(r.options.IfceName),
|
||||
chain.NetnsDialOption(r.options.Netns),
|
||||
chain.SockOptsDialOption(r.options.SockOpts),
|
||||
chain.LoggerDialOption(r.options.Logger),
|
||||
)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
r.options.Logger.Errorf("route(retry=%d) %s", i, err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Router) Bind(ctx context.Context, network, address string, opts ...chain.BindOption) (ln net.Listener, err error) {
|
||||
if r.options.Timeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, r.options.Timeout)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
count := r.options.Retries + 1
|
||||
if count <= 0 {
|
||||
count = 1
|
||||
}
|
||||
r.options.Logger.Debugf("bind on %s/%s", address, network)
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
var route chain.Route
|
||||
if r.options.Chain != nil {
|
||||
route = r.options.Chain.Route(ctx, network, address)
|
||||
if route == nil || len(route.Nodes()) == 0 {
|
||||
err = ErrEmptyRoute
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if r.options.Logger.IsLevelEnabled(logger.DebugLevel) {
|
||||
buf := bytes.Buffer{}
|
||||
for _, node := range routePath(route) {
|
||||
fmt.Fprintf(&buf, "%s@%s > ", node.Name, node.Addr)
|
||||
}
|
||||
fmt.Fprintf(&buf, "%s", address)
|
||||
r.options.Logger.Debugf("route(retry=%d) %s", i, buf.String())
|
||||
}
|
||||
|
||||
if route == nil {
|
||||
route = DefaultRoute
|
||||
}
|
||||
ln, err = route.Bind(ctx, network, address, opts...)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
r.options.Logger.Errorf("route(retry=%d) %s", i, err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func routePath(route chain.Route) (path []*chain.Node) {
|
||||
if route == nil {
|
||||
return
|
||||
}
|
||||
for _, node := range route.Nodes() {
|
||||
if tr := node.Options().Transport; tr != nil {
|
||||
path = append(path, routePath(tr.Options().Route)...)
|
||||
}
|
||||
path = append(path, node)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type packetConn struct {
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (c *packetConn) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
||||
n, err = c.Read(b)
|
||||
addr = c.Conn.RemoteAddr()
|
||||
return
|
||||
}
|
||||
|
||||
func (c *packetConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||
return c.Write(b)
|
||||
}
|
106
chain/transport.go
Normal file
106
chain/transport.go
Normal file
@ -0,0 +1,106 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/connector"
|
||||
"github.com/go-gost/core/dialer"
|
||||
net_dialer "github.com/go-gost/x/internal/net/dialer"
|
||||
)
|
||||
|
||||
type Transport struct {
|
||||
dialer dialer.Dialer
|
||||
connector connector.Connector
|
||||
options chain.TransportOptions
|
||||
}
|
||||
|
||||
func NewTransport(d dialer.Dialer, c connector.Connector, opts ...chain.TransportOption) *Transport {
|
||||
tr := &Transport{
|
||||
dialer: d,
|
||||
connector: c,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
opt(&tr.options)
|
||||
}
|
||||
}
|
||||
|
||||
return tr
|
||||
}
|
||||
|
||||
func (tr *Transport) Dial(ctx context.Context, addr string) (net.Conn, error) {
|
||||
netd := &net_dialer.Dialer{
|
||||
Interface: tr.options.IfceName,
|
||||
Netns: tr.options.Netns,
|
||||
}
|
||||
if tr.options.SockOpts != nil {
|
||||
netd.Mark = tr.options.SockOpts.Mark
|
||||
}
|
||||
if tr.options.Route != nil && len(tr.options.Route.Nodes()) > 0 {
|
||||
netd.DialFunc = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return tr.options.Route.Dial(ctx, network, addr)
|
||||
}
|
||||
}
|
||||
opts := []dialer.DialOption{
|
||||
dialer.HostDialOption(tr.options.Addr),
|
||||
dialer.NetDialerDialOption(netd),
|
||||
}
|
||||
return tr.dialer.Dial(ctx, addr, opts...)
|
||||
}
|
||||
|
||||
func (tr *Transport) Handshake(ctx context.Context, conn net.Conn) (net.Conn, error) {
|
||||
var err error
|
||||
if hs, ok := tr.dialer.(dialer.Handshaker); ok {
|
||||
conn, err = hs.Handshake(ctx, conn,
|
||||
dialer.AddrHandshakeOption(tr.options.Addr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if hs, ok := tr.connector.(connector.Handshaker); ok {
|
||||
return hs.Handshake(ctx, conn)
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func (tr *Transport) Connect(ctx context.Context, conn net.Conn, network, address string) (net.Conn, error) {
|
||||
netd := &net_dialer.Dialer{
|
||||
Interface: tr.options.IfceName,
|
||||
Netns: tr.options.Netns,
|
||||
}
|
||||
if tr.options.SockOpts != nil {
|
||||
netd.Mark = tr.options.SockOpts.Mark
|
||||
}
|
||||
return tr.connector.Connect(ctx, conn, network, address,
|
||||
connector.DialerConnectOption(netd),
|
||||
)
|
||||
}
|
||||
|
||||
func (tr *Transport) Bind(ctx context.Context, conn net.Conn, network, address string, opts ...connector.BindOption) (net.Listener, error) {
|
||||
if binder, ok := tr.connector.(connector.Binder); ok {
|
||||
return binder.Bind(ctx, conn, network, address, opts...)
|
||||
}
|
||||
return nil, connector.ErrBindUnsupported
|
||||
}
|
||||
|
||||
func (tr *Transport) Multiplex() bool {
|
||||
if mux, ok := tr.dialer.(dialer.Multiplexer); ok {
|
||||
return mux.Multiplex()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (tr *Transport) Options() *chain.TransportOptions {
|
||||
if tr != nil {
|
||||
return &tr.options
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tr *Transport) Copy() chain.Transporter {
|
||||
tr2 := &Transport{}
|
||||
*tr2 = *tr
|
||||
return tr
|
||||
}
|
677
config/cmd/cmd.go
Normal file
677
config/cmd/cmd.go
Normal file
@ -0,0 +1,677 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
mdutil "github.com/go-gost/core/metadata/util"
|
||||
"github.com/go-gost/x/config"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
"github.com/go-gost/x/limiter/conn"
|
||||
"github.com/go-gost/x/limiter/traffic"
|
||||
mdx "github.com/go-gost/x/metadata"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidCmd = errors.New("invalid cmd")
|
||||
ErrInvalidNode = errors.New("invalid node")
|
||||
)
|
||||
|
||||
func BuildConfigFromCmd(serviceList, nodeList []string) (*config.Config, error) {
|
||||
namePrefix := ""
|
||||
cfg := &config.Config{}
|
||||
|
||||
var chain *config.ChainConfig
|
||||
if len(nodeList) > 0 {
|
||||
chain = &config.ChainConfig{
|
||||
Name: fmt.Sprintf("%schain-0", namePrefix),
|
||||
}
|
||||
cfg.Chains = append(cfg.Chains, chain)
|
||||
}
|
||||
|
||||
for i, node := range nodeList {
|
||||
url, err := Norm(node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeConfig, err := buildNodeConfig(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nodeConfig.Name = fmt.Sprintf("%snode-0", namePrefix)
|
||||
|
||||
var nodes []*config.NodeConfig
|
||||
for _, host := range strings.Split(nodeConfig.Addr, ",") {
|
||||
if host == "" {
|
||||
continue
|
||||
}
|
||||
nodeCfg := &config.NodeConfig{}
|
||||
*nodeCfg = *nodeConfig
|
||||
nodeCfg.Name = fmt.Sprintf("%snode-%d", namePrefix, len(nodes))
|
||||
nodeCfg.Addr = host
|
||||
nodes = append(nodes, nodeCfg)
|
||||
}
|
||||
|
||||
m := map[string]any{}
|
||||
for k, v := range url.Query() {
|
||||
if len(v) > 0 {
|
||||
m[k] = v[0]
|
||||
}
|
||||
}
|
||||
md := mdx.NewMetadata(m)
|
||||
|
||||
hopConfig := &config.HopConfig{
|
||||
Name: fmt.Sprintf("%shop-%d", namePrefix, i),
|
||||
Selector: parseSelector(m),
|
||||
Nodes: nodes,
|
||||
Metadata: m,
|
||||
}
|
||||
|
||||
if v := mdutil.GetString(md, "bypass"); v != "" {
|
||||
bypassCfg := &config.BypassConfig{
|
||||
Name: fmt.Sprintf("%sbypass-%d", namePrefix, len(cfg.Bypasses)),
|
||||
}
|
||||
if v[0] == '~' {
|
||||
bypassCfg.Whitelist = true
|
||||
v = v[1:]
|
||||
}
|
||||
for _, s := range strings.Split(v, ",") {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
bypassCfg.Matchers = append(bypassCfg.Matchers, s)
|
||||
}
|
||||
hopConfig.Bypass = bypassCfg.Name
|
||||
cfg.Bypasses = append(cfg.Bypasses, bypassCfg)
|
||||
delete(m, "bypass")
|
||||
}
|
||||
if v := mdutil.GetString(md, "resolver"); v != "" {
|
||||
resolverCfg := &config.ResolverConfig{
|
||||
Name: fmt.Sprintf("%sresolver-%d", namePrefix, len(cfg.Resolvers)),
|
||||
}
|
||||
for _, rs := range strings.Split(v, ",") {
|
||||
if rs == "" {
|
||||
continue
|
||||
}
|
||||
resolverCfg.Nameservers = append(
|
||||
resolverCfg.Nameservers,
|
||||
&config.NameserverConfig{
|
||||
Addr: rs,
|
||||
},
|
||||
)
|
||||
}
|
||||
hopConfig.Resolver = resolverCfg.Name
|
||||
cfg.Resolvers = append(cfg.Resolvers, resolverCfg)
|
||||
delete(m, "resolver")
|
||||
}
|
||||
if v := mdutil.GetString(md, "hosts"); v != "" {
|
||||
hostsCfg := &config.HostsConfig{
|
||||
Name: fmt.Sprintf("%shosts-%d", namePrefix, len(cfg.Hosts)),
|
||||
}
|
||||
for _, s := range strings.Split(v, ",") {
|
||||
ss := strings.SplitN(s, ":", 2)
|
||||
if len(ss) != 2 {
|
||||
continue
|
||||
}
|
||||
hostsCfg.Mappings = append(
|
||||
hostsCfg.Mappings,
|
||||
&config.HostMappingConfig{
|
||||
Hostname: ss[0],
|
||||
IP: ss[1],
|
||||
},
|
||||
)
|
||||
}
|
||||
hopConfig.Hosts = hostsCfg.Name
|
||||
cfg.Hosts = append(cfg.Hosts, hostsCfg)
|
||||
delete(m, "hosts")
|
||||
}
|
||||
|
||||
if v := mdutil.GetString(md, "interface"); v != "" {
|
||||
hopConfig.Interface = v
|
||||
delete(m, "interface")
|
||||
}
|
||||
if v := mdutil.GetInt(md, "so_mark"); v > 0 {
|
||||
hopConfig.SockOpts = &config.SockOptsConfig{
|
||||
Mark: v,
|
||||
}
|
||||
delete(m, "so_mark")
|
||||
}
|
||||
|
||||
chain.Hops = append(chain.Hops, hopConfig)
|
||||
}
|
||||
|
||||
var services []*config.ServiceConfig
|
||||
for _, svc := range serviceList {
|
||||
svc = strings.TrimSpace(svc)
|
||||
if svc == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if svc[0] == ':' || !strings.Contains(svc, "://") {
|
||||
svc = "auto://" + svc
|
||||
}
|
||||
|
||||
host, svc := cutHost(svc)
|
||||
|
||||
url, err := Norm(svc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
url.Host = host
|
||||
|
||||
svcs, err := buildServiceConfig(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
services = append(services, svcs...)
|
||||
}
|
||||
|
||||
for i, service := range services {
|
||||
service.Name = fmt.Sprintf("%sservice-%d", namePrefix, i)
|
||||
if chain != nil {
|
||||
if service.Listener.Type == "rtcp" || service.Listener.Type == "rudp" {
|
||||
service.Listener.Chain = chain.Name
|
||||
} else {
|
||||
service.Handler.Chain = chain.Name
|
||||
}
|
||||
}
|
||||
cfg.Services = append(cfg.Services, service)
|
||||
|
||||
mh := service.Handler.Metadata
|
||||
md := mdx.NewMetadata(mh)
|
||||
if v := mdutil.GetInt(md, "retries"); v > 0 {
|
||||
service.Handler.Retries = v
|
||||
delete(mh, "retries")
|
||||
}
|
||||
if v := mdutil.GetString(md, "admission"); v != "" {
|
||||
admCfg := &config.AdmissionConfig{
|
||||
Name: fmt.Sprintf("%sadmission-%d", namePrefix, len(cfg.Admissions)),
|
||||
}
|
||||
if v[0] == '~' {
|
||||
admCfg.Whitelist = true
|
||||
v = v[1:]
|
||||
}
|
||||
for _, s := range strings.Split(v, ",") {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
admCfg.Matchers = append(admCfg.Matchers, s)
|
||||
}
|
||||
service.Admission = admCfg.Name
|
||||
cfg.Admissions = append(cfg.Admissions, admCfg)
|
||||
delete(mh, "admission")
|
||||
}
|
||||
if v := mdutil.GetString(md, "bypass"); v != "" {
|
||||
bypassCfg := &config.BypassConfig{
|
||||
Name: fmt.Sprintf("%sbypass-%d", namePrefix, len(cfg.Bypasses)),
|
||||
}
|
||||
if v[0] == '~' {
|
||||
bypassCfg.Whitelist = true
|
||||
v = v[1:]
|
||||
}
|
||||
for _, s := range strings.Split(v, ",") {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
bypassCfg.Matchers = append(bypassCfg.Matchers, s)
|
||||
}
|
||||
service.Bypass = bypassCfg.Name
|
||||
cfg.Bypasses = append(cfg.Bypasses, bypassCfg)
|
||||
delete(mh, "bypass")
|
||||
}
|
||||
if v := mdutil.GetString(md, "resolver"); v != "" {
|
||||
resolverCfg := &config.ResolverConfig{
|
||||
Name: fmt.Sprintf("%sresolver-%d", namePrefix, len(cfg.Resolvers)),
|
||||
}
|
||||
for _, rs := range strings.Split(v, ",") {
|
||||
if rs == "" {
|
||||
continue
|
||||
}
|
||||
resolverCfg.Nameservers = append(
|
||||
resolverCfg.Nameservers,
|
||||
&config.NameserverConfig{
|
||||
Addr: rs,
|
||||
Prefer: mdutil.GetString(md, "prefer"),
|
||||
},
|
||||
)
|
||||
}
|
||||
service.Resolver = resolverCfg.Name
|
||||
cfg.Resolvers = append(cfg.Resolvers, resolverCfg)
|
||||
delete(mh, "resolver")
|
||||
}
|
||||
if v := mdutil.GetString(md, "hosts"); v != "" {
|
||||
hostsCfg := &config.HostsConfig{
|
||||
Name: fmt.Sprintf("%shosts-%d", namePrefix, len(cfg.Hosts)),
|
||||
}
|
||||
for _, s := range strings.Split(v, ",") {
|
||||
ss := strings.SplitN(s, ":", 2)
|
||||
if len(ss) != 2 {
|
||||
continue
|
||||
}
|
||||
hostsCfg.Mappings = append(
|
||||
hostsCfg.Mappings,
|
||||
&config.HostMappingConfig{
|
||||
Hostname: ss[0],
|
||||
IP: ss[1],
|
||||
},
|
||||
)
|
||||
}
|
||||
service.Hosts = hostsCfg.Name
|
||||
cfg.Hosts = append(cfg.Hosts, hostsCfg)
|
||||
delete(mh, "hosts")
|
||||
}
|
||||
|
||||
in := mdutil.GetString(md, "limiter.in")
|
||||
out := mdutil.GetString(md, "limiter.out")
|
||||
cin := mdutil.GetString(md, "limiter.conn.in")
|
||||
cout := mdutil.GetString(md, "limiter.conn.out")
|
||||
if in != "" || cin != "" || out != "" || cout != "" {
|
||||
limiter := &config.LimiterConfig{
|
||||
Name: fmt.Sprintf("%slimiter-%d", namePrefix, len(cfg.Limiters)),
|
||||
}
|
||||
if in != "" || out != "" {
|
||||
limiter.Limits = append(limiter.Limits,
|
||||
fmt.Sprintf("%s %s %s", traffic.GlobalLimitKey, in, out))
|
||||
}
|
||||
if cin != "" || cout != "" {
|
||||
limiter.Limits = append(limiter.Limits,
|
||||
fmt.Sprintf("%s %s %s", traffic.ConnLimitKey, cin, cout))
|
||||
}
|
||||
service.Limiter = limiter.Name
|
||||
cfg.Limiters = append(cfg.Limiters, limiter)
|
||||
delete(mh, "limiter.in")
|
||||
delete(mh, "limiter.out")
|
||||
delete(mh, "limiter.conn.in")
|
||||
delete(mh, "limiter.conn.out")
|
||||
}
|
||||
|
||||
if climit := mdutil.GetInt(md, "climiter"); climit > 0 {
|
||||
limiter := &config.LimiterConfig{
|
||||
Name: fmt.Sprintf("%sclimiter-%d", namePrefix, len(cfg.CLimiters)),
|
||||
Limits: []string{fmt.Sprintf("%s %d", conn.GlobalLimitKey, climit)},
|
||||
}
|
||||
service.CLimiter = limiter.Name
|
||||
cfg.CLimiters = append(cfg.CLimiters, limiter)
|
||||
delete(mh, "climiter")
|
||||
}
|
||||
|
||||
if rlimit := mdutil.GetFloat(md, "rlimiter"); rlimit > 0 {
|
||||
limiter := &config.LimiterConfig{
|
||||
Name: fmt.Sprintf("%srlimiter-%d", namePrefix, len(cfg.RLimiters)),
|
||||
Limits: []string{fmt.Sprintf("%s %s", conn.GlobalLimitKey, strconv.FormatFloat(rlimit, 'f', -1, 64))},
|
||||
}
|
||||
service.RLimiter = limiter.Name
|
||||
cfg.RLimiters = append(cfg.RLimiters, limiter)
|
||||
delete(mh, "rlimiter")
|
||||
}
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func cutHost(s string) (host, remain string) {
|
||||
if s == "" {
|
||||
return
|
||||
}
|
||||
|
||||
n := strings.IndexByte(s, ':')
|
||||
start := n + 3
|
||||
end := strings.IndexAny(s[start:], "/?")
|
||||
if end < 0 {
|
||||
end = len(s)
|
||||
} else {
|
||||
end += start
|
||||
}
|
||||
host = s[start:end]
|
||||
remain = s[:start] + s[end:]
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func buildServiceConfig(url *url.URL) ([]*config.ServiceConfig, error) {
|
||||
namePrefix := ""
|
||||
if v := os.Getenv("_GOST_ID"); v != "" {
|
||||
namePrefix = fmt.Sprintf("go-%s@", v)
|
||||
}
|
||||
|
||||
var handler, listener string
|
||||
schemes := strings.Split(url.Scheme, "+")
|
||||
if len(schemes) == 1 {
|
||||
handler = schemes[0]
|
||||
listener = schemes[0]
|
||||
}
|
||||
if len(schemes) == 2 {
|
||||
handler = schemes[0]
|
||||
listener = schemes[1]
|
||||
}
|
||||
|
||||
addrs := xnet.AddrPortRange(url.Host).Addrs()
|
||||
if len(addrs) == 0 {
|
||||
addrs = append(addrs, url.Host)
|
||||
}
|
||||
|
||||
var services []*config.ServiceConfig
|
||||
for _, addr := range addrs {
|
||||
services = append(services, &config.ServiceConfig{
|
||||
Addr: addr,
|
||||
})
|
||||
}
|
||||
|
||||
if h := registry.HandlerRegistry().Get(handler); h == nil {
|
||||
handler = "auto"
|
||||
}
|
||||
if ln := registry.ListenerRegistry().Get(listener); ln == nil {
|
||||
listener = "tcp"
|
||||
if handler == "ssu" {
|
||||
listener = "udp"
|
||||
}
|
||||
}
|
||||
|
||||
var nodes []*config.ForwardNodeConfig
|
||||
// forward mode
|
||||
if remotes := strings.Trim(url.EscapedPath(), "/"); remotes != "" {
|
||||
i := 0
|
||||
for _, addr := range strings.Split(remotes, ",") {
|
||||
addrs := xnet.AddrPortRange(addr).Addrs()
|
||||
if len(addrs) == 0 {
|
||||
addrs = append(addrs, addr)
|
||||
}
|
||||
for _, adr := range addrs {
|
||||
nodes = append(nodes, &config.ForwardNodeConfig{
|
||||
Name: fmt.Sprintf("%starget-%d", namePrefix, i),
|
||||
Addr: adr,
|
||||
})
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
if handler != "relay" {
|
||||
if listener == "tcp" || listener == "udp" ||
|
||||
listener == "rtcp" || listener == "rudp" ||
|
||||
listener == "tun" || listener == "tap" ||
|
||||
listener == "dns" || listener == "unix" ||
|
||||
listener == "serial" {
|
||||
handler = listener
|
||||
} else {
|
||||
handler = "forward"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(nodes) > 0 {
|
||||
if len(services) == 1 {
|
||||
services[0].Forwarder = &config.ForwarderConfig{
|
||||
Nodes: nodes,
|
||||
}
|
||||
} else {
|
||||
for i, svc := range services {
|
||||
if len(nodes) == 1 {
|
||||
svc.Forwarder = &config.ForwarderConfig{
|
||||
Nodes: nodes,
|
||||
}
|
||||
} else {
|
||||
if i < len(nodes) {
|
||||
svc.Forwarder = &config.ForwarderConfig{
|
||||
Nodes: []*config.ForwardNodeConfig{nodes[i]},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var auth *config.AuthConfig
|
||||
if url.User != nil {
|
||||
auth = &config.AuthConfig{
|
||||
Username: url.User.Username(),
|
||||
}
|
||||
auth.Password, _ = url.User.Password()
|
||||
}
|
||||
|
||||
m := map[string]any{}
|
||||
for k, v := range url.Query() {
|
||||
if len(v) > 0 {
|
||||
m[k] = v[0]
|
||||
}
|
||||
}
|
||||
md := mdx.NewMetadata(m)
|
||||
|
||||
if sa := mdutil.GetString(md, "auth"); sa != "" {
|
||||
au, err := parseAuthFromCmd(sa)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
auth = au
|
||||
}
|
||||
delete(m, "auth")
|
||||
|
||||
tlsConfig := &config.TLSConfig{
|
||||
CertFile: mdutil.GetString(md, "tls.certFile", "certFile", "cert"),
|
||||
KeyFile: mdutil.GetString(md, "tls.keyFile", "keyFile", "key"),
|
||||
CAFile: mdutil.GetString(md, "tls.caFile", "caFile", "ca"),
|
||||
}
|
||||
|
||||
delete(m, "tls.certFile")
|
||||
delete(m, "certFile")
|
||||
delete(m, "cert")
|
||||
delete(m, "tls.keyFile")
|
||||
delete(m, "keyFile")
|
||||
delete(m, "key")
|
||||
delete(m, "tls.caFile")
|
||||
delete(m, "caFile")
|
||||
delete(m, "ca")
|
||||
|
||||
if tlsConfig.CertFile == "" {
|
||||
tlsConfig = nil
|
||||
}
|
||||
|
||||
if v := mdutil.GetString(md, "dns"); v != "" {
|
||||
md.Set("dns", strings.Split(v, ","))
|
||||
}
|
||||
|
||||
selector := parseSelector(m)
|
||||
handlerCfg := &config.HandlerConfig{
|
||||
Type: handler,
|
||||
Auth: auth,
|
||||
Metadata: m,
|
||||
}
|
||||
listenerCfg := &config.ListenerConfig{
|
||||
Type: listener,
|
||||
TLS: tlsConfig,
|
||||
Metadata: m,
|
||||
}
|
||||
if listenerCfg.Type == "ssh" || listenerCfg.Type == "sshd" {
|
||||
handlerCfg.Auth = nil
|
||||
listenerCfg.Auth = auth
|
||||
}
|
||||
|
||||
for _, svc := range services {
|
||||
if svc.Forwarder != nil {
|
||||
svc.Forwarder.Selector = selector
|
||||
}
|
||||
svc.Handler = handlerCfg
|
||||
svc.Listener = listenerCfg
|
||||
svc.Metadata = m
|
||||
}
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func buildNodeConfig(url *url.URL) (*config.NodeConfig, error) {
|
||||
var connector, dialer string
|
||||
schemes := strings.Split(url.Scheme, "+")
|
||||
if len(schemes) == 1 {
|
||||
connector = schemes[0]
|
||||
dialer = schemes[0]
|
||||
}
|
||||
if len(schemes) == 2 {
|
||||
connector = schemes[0]
|
||||
dialer = schemes[1]
|
||||
}
|
||||
|
||||
m := map[string]any{}
|
||||
for k, v := range url.Query() {
|
||||
if len(v) > 0 {
|
||||
m[k] = v[0]
|
||||
}
|
||||
}
|
||||
md := mdx.NewMetadata(m)
|
||||
|
||||
node := &config.NodeConfig{
|
||||
Addr: url.Host,
|
||||
Metadata: m,
|
||||
}
|
||||
|
||||
if c := registry.ConnectorRegistry().Get(connector); c == nil {
|
||||
connector = "http"
|
||||
}
|
||||
if d := registry.DialerRegistry().Get(dialer); d == nil {
|
||||
dialer = "tcp"
|
||||
if connector == "ssu" {
|
||||
dialer = "udp"
|
||||
}
|
||||
}
|
||||
|
||||
var auth *config.AuthConfig
|
||||
if url.User != nil {
|
||||
auth = &config.AuthConfig{
|
||||
Username: url.User.Username(),
|
||||
}
|
||||
auth.Password, _ = url.User.Password()
|
||||
}
|
||||
|
||||
if sauth := mdutil.GetString(md, "auth"); sauth != "" && auth == nil {
|
||||
au, err := parseAuthFromCmd(sauth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
auth = au
|
||||
}
|
||||
delete(m, "auth")
|
||||
|
||||
tlsConfig := &config.TLSConfig{
|
||||
CertFile: mdutil.GetString(md, "tls.certFile", "certFile", "cert"),
|
||||
KeyFile: mdutil.GetString(md, "tls.keyFile", "keyFile", "key"),
|
||||
CAFile: mdutil.GetString(md, "tls.caFile", "caFile", "ca"),
|
||||
Secure: mdutil.GetBool(md, "tls.secure", "secure"),
|
||||
ServerName: mdutil.GetString(md, "tls.servername", "servername"),
|
||||
}
|
||||
if tlsConfig.ServerName == "" {
|
||||
tlsConfig.ServerName = url.Hostname()
|
||||
}
|
||||
|
||||
delete(m, "tls.certFile")
|
||||
delete(m, "certFile")
|
||||
delete(m, "cert")
|
||||
delete(m, "tls.keyFile")
|
||||
delete(m, "keyFile")
|
||||
delete(m, "key")
|
||||
delete(m, "tls.caFile")
|
||||
delete(m, "caFile")
|
||||
delete(m, "ca")
|
||||
delete(m, "tls.secure")
|
||||
delete(m, "secure")
|
||||
delete(m, "tls.servername")
|
||||
delete(m, "serverName")
|
||||
|
||||
if !tlsConfig.Secure && tlsConfig.CertFile == "" && tlsConfig.CAFile == "" && tlsConfig.ServerName == "" {
|
||||
tlsConfig = nil
|
||||
}
|
||||
|
||||
node.Connector = &config.ConnectorConfig{
|
||||
Type: connector,
|
||||
Auth: auth,
|
||||
Metadata: m,
|
||||
}
|
||||
node.Dialer = &config.DialerConfig{
|
||||
Type: dialer,
|
||||
TLS: tlsConfig,
|
||||
Metadata: m,
|
||||
}
|
||||
|
||||
if node.Dialer.Type == "ssh" || node.Dialer.Type == "sshd" {
|
||||
node.Connector.Auth = nil
|
||||
node.Dialer.Auth = auth
|
||||
}
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func Norm(s string) (*url.URL, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return nil, ErrInvalidCmd
|
||||
}
|
||||
|
||||
if s[0] == ':' || !strings.Contains(s, "://") {
|
||||
s = "auto://" + 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
|
||||
}
|
||||
|
||||
func parseSelector(m map[string]any) *config.SelectorConfig {
|
||||
md := mdx.NewMetadata(m)
|
||||
strategy := mdutil.GetString(md, "strategy")
|
||||
maxFails := mdutil.GetInt(md, "maxFails", "max_fails")
|
||||
failTimeout := mdutil.GetDuration(md, "failTimeout", "fail_timeout")
|
||||
if strategy == "" && maxFails <= 0 && failTimeout <= 0 {
|
||||
return nil
|
||||
}
|
||||
if strategy == "" {
|
||||
strategy = "round"
|
||||
}
|
||||
if maxFails <= 0 {
|
||||
maxFails = 1
|
||||
}
|
||||
if failTimeout <= 0 {
|
||||
failTimeout = 30 * time.Second
|
||||
}
|
||||
|
||||
delete(m, "strategy")
|
||||
delete(m, "maxFails")
|
||||
delete(m, "max_fails")
|
||||
delete(m, "failTimeout")
|
||||
delete(m, "fail_timeout")
|
||||
|
||||
return &config.SelectorConfig{
|
||||
Strategy: strategy,
|
||||
MaxFails: maxFails,
|
||||
FailTimeout: failTimeout,
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import (
|
||||
"github.com/go-gost/core/metadata"
|
||||
mdutil "github.com/go-gost/core/metadata/util"
|
||||
xauth "github.com/go-gost/x/auth"
|
||||
xchain "github.com/go-gost/x/chain"
|
||||
"github.com/go-gost/x/config"
|
||||
"github.com/go-gost/x/config/parsing"
|
||||
auth_parser "github.com/go-gost/x/config/parsing/auth"
|
||||
@ -139,7 +140,7 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
|
||||
}
|
||||
}
|
||||
|
||||
tr := chain.NewTransport(d, cr,
|
||||
tr := xchain.NewTransport(d, cr,
|
||||
chain.AddrTransportOption(cfg.Addr),
|
||||
chain.InterfaceTransportOption(cfg.Interface),
|
||||
chain.NetnsTransportOption(cfg.Netns),
|
||||
|
@ -28,7 +28,6 @@ import (
|
||||
hop_parser "github.com/go-gost/x/config/parsing/hop"
|
||||
logger_parser "github.com/go-gost/x/config/parsing/logger"
|
||||
selector_parser "github.com/go-gost/x/config/parsing/selector"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
"github.com/go-gost/x/metadata"
|
||||
"github.com/go-gost/x/registry"
|
||||
@ -151,7 +150,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
|
||||
|
||||
listenOpts := []listener.Option{
|
||||
listener.AddrOption(cfg.Addr),
|
||||
listener.RouterOption(chain.NewRouter(routerOpts...)),
|
||||
listener.RouterOption(xchain.NewRouter(routerOpts...)),
|
||||
listener.AutherOption(auther),
|
||||
listener.AuthOption(auth_parser.Info(cfg.Listener.Auth)),
|
||||
listener.TLSConfigOption(tlsConfig),
|
||||
@ -271,7 +270,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
|
||||
var h handler.Handler
|
||||
if rf := registry.HandlerRegistry().Get(cfg.Handler.Type); rf != nil {
|
||||
h = rf(
|
||||
handler.RouterOption(chain.NewRouter(routerOpts...)),
|
||||
handler.RouterOption(xchain.NewRouter(routerOpts...)),
|
||||
handler.AutherOption(auther),
|
||||
handler.AuthOption(auth_parser.Info(cfg.Handler.Auth)),
|
||||
handler.BypassOption(bypass.BypassGroup(bypass_parser.List(cfg.Bypass, cfg.Bypasses...)...)),
|
||||
@ -339,15 +338,8 @@ func parseForwarder(cfg *config.ForwarderConfig, log logger.Logger) (hop.Hop, er
|
||||
Selector: cfg.Selector,
|
||||
}
|
||||
for _, node := range cfg.Nodes {
|
||||
if node != nil {
|
||||
addrs := xnet.AddrPortRange(node.Addr).Addrs()
|
||||
if len(addrs) == 0 {
|
||||
addrs = append(addrs, node.Addr)
|
||||
}
|
||||
for i, addr := range addrs {
|
||||
name := node.Name
|
||||
if i > 0 {
|
||||
name = fmt.Sprintf("%s-%d", node.Name, i)
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
filter := node.Filter
|
||||
@ -371,8 +363,8 @@ func parseForwarder(cfg *config.ForwarderConfig, log logger.Logger) (hop.Hop, er
|
||||
}
|
||||
}
|
||||
hc.Nodes = append(hc.Nodes, &config.NodeConfig{
|
||||
Name: name,
|
||||
Addr: addr,
|
||||
Name: node.Name,
|
||||
Addr: node.Addr,
|
||||
Network: node.Network,
|
||||
Bypass: node.Bypass,
|
||||
Bypasses: node.Bypasses,
|
||||
@ -382,8 +374,6 @@ func parseForwarder(cfg *config.ForwarderConfig, log logger.Logger) (hop.Hop, er
|
||||
Metadata: node.Metadata,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return hop_parser.ParseHop(&hc, log)
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ func (c *directConnector) Connect(ctx context.Context, _ net.Conn, network, addr
|
||||
opt(&cOpts)
|
||||
}
|
||||
|
||||
conn, err := cOpts.NetDialer.Dial(ctx, network, address)
|
||||
conn, err := cOpts.Dialer.Dial(ctx, network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ import (
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-gost/core/common/net/udp"
|
||||
"github.com/go-gost/core/connector"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/relay"
|
||||
"github.com/go-gost/x/internal/net/udp"
|
||||
"github.com/go-gost/x/internal/util/mux"
|
||||
relay_util "github.com/go-gost/x/internal/util/relay"
|
||||
)
|
||||
|
@ -5,10 +5,10 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/go-gost/core/common/net/udp"
|
||||
"github.com/go-gost/core/connector"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/gosocks5"
|
||||
"github.com/go-gost/x/internal/net/udp"
|
||||
"github.com/go-gost/x/internal/util/mux"
|
||||
"github.com/go-gost/x/internal/util/socks"
|
||||
)
|
||||
|
@ -211,7 +211,7 @@ func (c *socks5Connector) relayUDP(ctx context.Context, conn net.Conn, addr net.
|
||||
|
||||
log.Debugf("bind on: %v", reply.Addr)
|
||||
|
||||
cc, err := opts.NetDialer.Dial(ctx, "udp", reply.Addr.String())
|
||||
cc, err := opts.Dialer.Dial(ctx, "udp", reply.Addr.String())
|
||||
if err != nil {
|
||||
c.options.Logger.Error(err)
|
||||
return nil, err
|
||||
|
@ -45,7 +45,7 @@ func (d *dtlsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err := options.NetDialer.Dial(ctx, "udp", addr)
|
||||
conn, err := options.Dialer.Dial(ctx, "udp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -71,14 +71,13 @@ func (d *grpcDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO
|
||||
grpcOpts := []grpc.DialOption{
|
||||
// grpc.WithBlock(),
|
||||
grpc.WithContextDialer(func(c context.Context, s string) (net.Conn, error) {
|
||||
return options.NetDialer.Dial(c, "tcp", s)
|
||||
return options.Dialer.Dial(c, "tcp", s)
|
||||
}),
|
||||
grpc.WithAuthority(host),
|
||||
grpc.WithConnectParams(grpc.ConnectParams{
|
||||
Backoff: backoff.DefaultConfig,
|
||||
MinConnectTimeout: d.md.minConnectTimeout,
|
||||
}),
|
||||
grpc.FailOnNonTempDialError(true),
|
||||
}
|
||||
if !d.md.insecure {
|
||||
grpcOpts = append(grpcOpts, grpc.WithTransportCredentials(credentials.NewTLS(d.options.TLSConfig)))
|
||||
@ -94,7 +93,7 @@ func (d *grpcDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO
|
||||
}))
|
||||
}
|
||||
|
||||
cc, err := grpc.DialContext(ctx, addr, grpcOpts...)
|
||||
cc, err := grpc.NewClient(addr, grpcOpts...)
|
||||
if err != nil {
|
||||
d.options.Logger.Error(err)
|
||||
return nil, err
|
||||
|
@ -7,10 +7,10 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
net_dialer "github.com/go-gost/core/common/net/dialer"
|
||||
"github.com/go-gost/core/dialer"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
net_dialer "github.com/go-gost/x/internal/net/dialer"
|
||||
mdx "github.com/go-gost/x/metadata"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@ -72,7 +72,7 @@ func (d *http2Dialer) Dial(ctx context.Context, address string, opts ...dialer.D
|
||||
|
||||
{
|
||||
// Check whether the connection is established properly
|
||||
netd := options.NetDialer
|
||||
netd := options.Dialer
|
||||
if netd == nil {
|
||||
netd = net_dialer.DefaultNetDialer
|
||||
}
|
||||
@ -87,7 +87,7 @@ func (d *http2Dialer) Dial(ctx context.Context, address string, opts ...dialer.D
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: d.options.TLSConfig,
|
||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
netd := options.NetDialer
|
||||
netd := options.Dialer
|
||||
if netd == nil {
|
||||
netd = net_dialer.DefaultNetDialer
|
||||
}
|
||||
|
@ -94,14 +94,14 @@ func (d *h2Dialer) Dial(ctx context.Context, address string, opts ...dialer.Dial
|
||||
client.Transport = &http2.Transport{
|
||||
AllowHTTP: true,
|
||||
DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
|
||||
return options.NetDialer.Dial(ctx, network, addr)
|
||||
return options.Dialer.Dial(ctx, network, addr)
|
||||
},
|
||||
}
|
||||
} else {
|
||||
client.Transport = &http.Transport{
|
||||
TLSClientConfig: d.options.TLSConfig,
|
||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return options.NetDialer.Dial(ctx, network, addr)
|
||||
return options.Dialer.Dial(ctx, network, addr)
|
||||
},
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
|
@ -79,7 +79,7 @@ func (d *http3Dialer) Dial(ctx context.Context, addr string, opts ...dialer.Dial
|
||||
return nil, err
|
||||
}
|
||||
|
||||
udpConn, err := options.NetDialer.Dial(ctx, "udp", "")
|
||||
udpConn, err := options.Dialer.Dial(ctx, "udp", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ func (d *wtDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOpt
|
||||
return nil, err
|
||||
}
|
||||
|
||||
udpConn, err := options.NetDialer.Dial(ctx, "udp", "")
|
||||
udpConn, err := options.Dialer.Dial(ctx, "udp", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ func (d *kcpDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp
|
||||
PacketConn: pc,
|
||||
}
|
||||
} else {
|
||||
c, err := options.NetDialer.Dial(ctx, "udp", "")
|
||||
c, err := options.Dialer.Dial(ctx, "udp", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ func (d *mtcpDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err = options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err = options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func (d *mtlsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err = options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err = options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ func (d *mwsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err = options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err = options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ func (d *obfsHTTPDialer) Dial(ctx context.Context, addr string, opts ...dialer.D
|
||||
opt(options)
|
||||
}
|
||||
|
||||
conn, err := options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err := options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
d.logger.Error(err)
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func (d *obfsTLSDialer) Dial(ctx context.Context, addr string, opts ...dialer.Di
|
||||
opt(options)
|
||||
}
|
||||
|
||||
conn, err := options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err := options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
d.logger.Error(err)
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func (d *phtDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp
|
||||
tr := &http.Transport{
|
||||
// Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: func(ctx context.Context, network, adr string) (net.Conn, error) {
|
||||
return options.NetDialer.Dial(ctx, network, addr)
|
||||
return options.Dialer.Dial(ctx, network, addr)
|
||||
},
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
|
@ -67,7 +67,7 @@ func (d *quicDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO
|
||||
opt(options)
|
||||
}
|
||||
|
||||
c, err := options.NetDialer.Dial(ctx, "udp", "")
|
||||
c, err := options.Dialer.Dial(ctx, "udp", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ func (d *sshDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err = options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err = options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ func (d *sshdDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err = options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err = options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func (d *tcpDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err := options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err := options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
d.logger.Error(err)
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ func (d *tlsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err := options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err := options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
d.logger.Error(err)
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func (d *udpDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
c, err := options.NetDialer.Dial(ctx, "udp", addr)
|
||||
c, err := options.Dialer.Dial(ctx, "udp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func (d *wgDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOpt
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err := options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err := options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
d.logger.Error(err)
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ func (d *wsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOpt
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
conn, err := options.NetDialer.Dial(ctx, "tcp", addr)
|
||||
conn, err := options.Dialer.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
d.options.Logger.Error(err)
|
||||
}
|
||||
|
20
go.mod
20
go.mod
@ -9,7 +9,7 @@ require (
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
|
||||
github.com/gin-contrib/cors v1.6.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-gost/core v0.0.0-20240704150322-30cc92870515
|
||||
github.com/go-gost/core v0.0.0-20240708142821-48d070d34568
|
||||
github.com/go-gost/gosocks4 v0.0.1
|
||||
github.com/go-gost/gosocks5 v0.4.2
|
||||
github.com/go-gost/plugin v0.0.0-20240103125338-9c84e29cb81a
|
||||
@ -20,7 +20,7 @@ require (
|
||||
github.com/golang/snappy v0.0.4
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/miekg/dns v1.1.57
|
||||
github.com/miekg/dns v1.1.61
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pion/dtls/v2 v2.2.6
|
||||
@ -41,12 +41,12 @@ require (
|
||||
github.com/xtaci/tcpraw v1.2.25
|
||||
github.com/yl2chen/cidranger v1.0.2
|
||||
github.com/zalando/go-keyring v0.2.4
|
||||
golang.org/x/crypto v0.24.0
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/sys v0.21.0
|
||||
golang.org/x/crypto v0.25.0
|
||||
golang.org/x/net v0.27.0
|
||||
golang.org/x/sys v0.22.0
|
||||
golang.org/x/time v0.5.0
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478
|
||||
google.golang.org/grpc v1.64.0
|
||||
google.golang.org/grpc v1.65.0
|
||||
google.golang.org/protobuf v1.34.2
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
@ -57,7 +57,7 @@ require (
|
||||
github.com/alessio/shellescape v1.4.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.11.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||
github.com/coreos/go-iptables v0.5.0 // indirect
|
||||
@ -111,11 +111,11 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.7.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/mod v0.19.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
golang.org/x/tools v0.23.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240610135401-a8a62080eff3 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
)
|
||||
|
44
go.sum
44
go.sum
@ -15,8 +15,8 @@ github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ
|
||||
github.com/bytedance/sonic v1.11.2 h1:ywfwo0a/3j9HR8wsYGWsIWl2mvRsI950HyoxiBERw5A=
|
||||
github.com/bytedance/sonic v1.11.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||
@ -53,8 +53,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-gost/core v0.0.0-20240704150322-30cc92870515 h1:i/zcDZtz00hcmRosvJgXmgJsdc4bC32PAvt2+8MUOEg=
|
||||
github.com/go-gost/core v0.0.0-20240704150322-30cc92870515/go.mod h1:QmVAZIXIYBsX44Vehwug5RFnG2K3/Hz/uu/Y4QVhAY0=
|
||||
github.com/go-gost/core v0.0.0-20240708142821-48d070d34568 h1:OJ+FzmBMy9RnWdECxGw6FKHRmN346Q/iVmDUSCBIthk=
|
||||
github.com/go-gost/core v0.0.0-20240708142821-48d070d34568/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A=
|
||||
github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s=
|
||||
github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc=
|
||||
github.com/go-gost/gosocks5 v0.4.2 h1:IianxHTkACPqCwiOAT3MHoMdSUl+SEPSRu1ikawC1Pc=
|
||||
@ -133,8 +133,8 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
|
||||
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
|
||||
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
|
||||
github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
|
||||
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/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
@ -271,8 +271,8 @@ golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM=
|
||||
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
||||
@ -282,8 +282,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -295,8 +295,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
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=
|
||||
@ -317,15 +317,15 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
@ -343,8 +343,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -356,14 +356,14 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
||||
google.golang.org/appengine v1.4.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-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240610135401-a8a62080eff3 h1:9Xyg6I9IWQZhRVfCWjKK+l6kI0jHcPesVlMnT//aHNo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240610135401-a8a62080eff3/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
||||
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
|
||||
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
||||
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -34,7 +34,6 @@ type dnsHandler struct {
|
||||
hop hop.Hop
|
||||
exchangers map[string]exchanger.Exchanger
|
||||
cache *resolver_util.Cache
|
||||
router *chain.Router
|
||||
hostMapper hosts.HostMapper
|
||||
md metadata
|
||||
options handler.Options
|
||||
@ -60,11 +59,7 @@ func (h *dnsHandler) Init(md md.Metadata) (err error) {
|
||||
|
||||
h.cache = resolver_util.NewCache().WithLogger(log)
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(log))
|
||||
}
|
||||
h.hostMapper = h.router.Options().HostMapper
|
||||
h.hostMapper = h.options.Router.Options().HostMapper
|
||||
|
||||
if h.hop == nil {
|
||||
var nodes []*chain.Node
|
||||
@ -88,7 +83,7 @@ func (h *dnsHandler) Init(md md.Metadata) (err error) {
|
||||
}
|
||||
ex, err := exchanger.NewExchanger(
|
||||
addr,
|
||||
exchanger.RouterOption(h.router),
|
||||
exchanger.RouterOption(h.options.Router),
|
||||
exchanger.TimeoutOption(h.md.timeout),
|
||||
exchanger.LoggerOption(log),
|
||||
)
|
||||
@ -102,7 +97,7 @@ func (h *dnsHandler) Init(md md.Metadata) (err error) {
|
||||
if len(h.exchangers) == 0 {
|
||||
ex, err := exchanger.NewExchanger(
|
||||
defaultNameserver,
|
||||
exchanger.RouterOption(h.router),
|
||||
exchanger.RouterOption(h.options.Router),
|
||||
exchanger.TimeoutOption(h.md.timeout),
|
||||
exchanger.LoggerOption(log),
|
||||
)
|
||||
|
@ -37,7 +37,6 @@ func init() {
|
||||
|
||||
type forwardHandler struct {
|
||||
hop hop.Hop
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -58,11 +57,6 @@ func (h *forwardHandler) Init(md md.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -157,7 +151,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
||||
|
||||
log.Debugf("%s >> %s", conn.RemoteAddr(), addr)
|
||||
|
||||
cc, err := h.router.Dial(ctx, network, addr)
|
||||
cc, err := h.options.Router.Dial(ctx, network, addr)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
// TODO: the router itself may be failed due to the failed node in the router,
|
||||
@ -277,7 +271,7 @@ func (h *forwardHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, remot
|
||||
}
|
||||
}
|
||||
|
||||
cc, err = h.router.Dial(ctx, "tcp", target.Addr)
|
||||
cc, err = h.options.Router.Dial(ctx, "tcp", target.Addr)
|
||||
if err != nil {
|
||||
// TODO: the router itself may be failed due to the failed node in the router,
|
||||
// the dead marker may be a wrong operation.
|
||||
|
@ -38,7 +38,6 @@ func init() {
|
||||
|
||||
type forwardHandler struct {
|
||||
hop hop.Hop
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -59,11 +58,6 @@ func (h *forwardHandler) Init(md mdata.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -156,7 +150,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
||||
|
||||
log.Debugf("%s >> %s", conn.RemoteAddr(), target.Addr)
|
||||
|
||||
cc, err := h.router.Dial(ctx, network, target.Addr)
|
||||
cc, err := h.options.Router.Dial(ctx, network, target.Addr)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
// TODO: the router itself may be failed due to the failed node in the router,
|
||||
@ -277,7 +271,7 @@ func (h *forwardHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, remot
|
||||
}
|
||||
}
|
||||
|
||||
cc, err = h.router.Dial(ctx, "tcp", target.Addr)
|
||||
cc, err = h.options.Router.Dial(ctx, "tcp", target.Addr)
|
||||
if err != nil {
|
||||
// TODO: the router itself may be failed due to the failed node in the router,
|
||||
// the dead marker may be a wrong operation.
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
traffic "github.com/go-gost/core/limiter/traffic"
|
||||
"github.com/go-gost/core/logger"
|
||||
@ -37,7 +36,6 @@ func init() {
|
||||
}
|
||||
|
||||
type httpHandler struct {
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
stats *stats_util.HandlerStats
|
||||
@ -61,11 +59,6 @@ func (h *httpHandler) Init(md md.Metadata) error {
|
||||
return err
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
h.cancel = cancel
|
||||
|
||||
@ -215,7 +208,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
|
||||
ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: addr})
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, network, addr)
|
||||
cc, err := h.options.Router.Dial(ctx, network, addr)
|
||||
if err != nil {
|
||||
resp.StatusCode = http.StatusServiceUnavailable
|
||||
|
||||
|
@ -51,7 +51,7 @@ func (h *httpHandler) handleUDP(ctx context.Context, conn net.Conn, log logger.L
|
||||
}
|
||||
|
||||
// obtain a udp connection
|
||||
c, err := h.router.Dial(ctx, "udp", "") // UDP association
|
||||
c, err := h.options.Router.Dial(ctx, "udp", "") // UDP association
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/limiter/traffic"
|
||||
"github.com/go-gost/core/logger"
|
||||
@ -38,7 +37,6 @@ func init() {
|
||||
}
|
||||
|
||||
type http2Handler struct {
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
stats *stats_util.HandlerStats
|
||||
@ -62,11 +60,6 @@ func (h *http2Handler) Init(md md.Metadata) error {
|
||||
return err
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
h.cancel = cancel
|
||||
|
||||
@ -188,7 +181,7 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
|
||||
ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: addr})
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, "tcp", addr)
|
||||
cc, err := h.options.Router.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
|
@ -24,7 +24,6 @@ func init() {
|
||||
|
||||
type http3Handler struct {
|
||||
hop hop.Hop
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -45,11 +44,6 @@ func (h *http3Handler) Init(md md.Metadata) error {
|
||||
return err
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -147,7 +141,7 @@ func (h *http3Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
conn, err := h.router.Dial(ctx, network, target.Addr)
|
||||
conn, err := h.options.Router.Dial(ctx, network, target.Addr)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
// TODO: the router itself may be failed due to the failed node in the router,
|
||||
|
@ -15,7 +15,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/bypass"
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
@ -32,7 +31,6 @@ func init() {
|
||||
}
|
||||
|
||||
type redirectHandler struct {
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -53,11 +51,6 @@ func (h *redirectHandler) Init(md md.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -129,7 +122,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
|
||||
return nil
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, dstAddr.Network(), dstAddr.String())
|
||||
cc, err := h.options.Router.Dial(ctx, dstAddr.Network(), dstAddr.String())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
@ -170,13 +163,13 @@ func (h *redirectHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, radd
|
||||
return nil
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, "tcp", host)
|
||||
cc, err := h.options.Router.Dial(ctx, "tcp", host)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
if cc == nil {
|
||||
cc, err = h.router.Dial(ctx, "tcp", dstAddr.String())
|
||||
cc, err = h.options.Router.Dial(ctx, "tcp", dstAddr.String())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
@ -245,14 +238,14 @@ func (h *redirectHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, rad
|
||||
return nil
|
||||
}
|
||||
|
||||
cc, err = h.router.Dial(ctx, "tcp", host)
|
||||
cc, err = h.options.Router.Dial(ctx, "tcp", host)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
if cc == nil {
|
||||
cc, err = h.router.Dial(ctx, "tcp", dstAddr.String())
|
||||
cc, err = h.options.Router.Dial(ctx, "tcp", dstAddr.String())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
netpkg "github.com/go-gost/x/internal/net"
|
||||
@ -18,7 +17,6 @@ func init() {
|
||||
}
|
||||
|
||||
type redirectHandler struct {
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -39,11 +37,6 @@ func (h *redirectHandler) Init(md md.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -80,7 +73,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
|
||||
return nil
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, dstAddr.Network(), dstAddr.String())
|
||||
cc, err := h.options.Router.Dial(ctx, dstAddr.Network(), dstAddr.String())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
|
@ -66,7 +66,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network
|
||||
case "serial":
|
||||
cc, err = serial.OpenPort(serial.ParseConfigFromAddr(address))
|
||||
default:
|
||||
cc, err = h.router.Dial(ctx, network, address)
|
||||
cc, err = h.options.Router.Dial(ctx, network, address)
|
||||
}
|
||||
if err != nil {
|
||||
resp.Status = relay.StatusNetworkUnreachable
|
||||
|
@ -38,7 +38,7 @@ func (h *relayHandler) handleForward(ctx context.Context, conn net.Conn, network
|
||||
|
||||
log.Debugf("%s >> %s", conn.RemoteAddr(), target.Addr)
|
||||
|
||||
cc, err := h.router.Dial(ctx, network, target.Addr)
|
||||
cc, err := h.options.Router.Dial(ctx, network, target.Addr)
|
||||
if err != nil {
|
||||
// TODO: the router itself may be failed due to the failed node in the router,
|
||||
// the dead marker may be a wrong operation.
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/hop"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
@ -30,7 +29,6 @@ func init() {
|
||||
|
||||
type relayHandler struct {
|
||||
hop hop.Hop
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
stats *stats_util.HandlerStats
|
||||
@ -54,11 +52,6 @@ func (h *relayHandler) Init(md md.Metadata) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
h.cancel = cancel
|
||||
|
||||
|
@ -25,7 +25,6 @@ func init() {
|
||||
|
||||
type serialHandler struct {
|
||||
hop hop.Hop
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
recorder recorder.RecorderObject
|
||||
@ -47,11 +46,7 @@ func (h *serialHandler) Init(md md.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
if opts := h.router.Options(); opts != nil {
|
||||
if opts := h.options.Router.Options(); opts != nil {
|
||||
for _, ro := range opts.Recorders {
|
||||
if ro.Record == xrecorder.RecorderServiceHandlerSerial {
|
||||
h.recorder = ro
|
||||
@ -97,7 +92,7 @@ func (h *serialHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl
|
||||
return h.forwardSerial(ctx, conn, target, log)
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, "tcp", "@")
|
||||
cc, err := h.options.Router.Dial(ctx, "tcp", "@")
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
@ -121,8 +116,8 @@ func (h *serialHandler) forwardSerial(ctx context.Context, conn net.Conn, target
|
||||
cfg := serial.ParseConfigFromAddr(conn.LocalAddr().String())
|
||||
cfg.Name = target.Addr
|
||||
|
||||
if opts := h.router.Options(); opts != nil && opts.Chain != nil {
|
||||
port, err = h.router.Dial(ctx, "serial", serial.AddrFromConfig(cfg))
|
||||
if opts := h.options.Router.Options(); opts != nil && opts.Chain != nil {
|
||||
port, err = h.options.Router.Dial(ctx, "serial", serial.AddrFromConfig(cfg))
|
||||
} else {
|
||||
cfg.ReadTimeout = h.md.timeout
|
||||
port, err = serial.OpenPort(cfg)
|
||||
|
@ -16,7 +16,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/bypass"
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
@ -32,7 +31,6 @@ func init() {
|
||||
}
|
||||
|
||||
type sniHandler struct {
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -55,11 +53,6 @@ func (h *sniHandler) Init(md md.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -128,7 +121,7 @@ func (h *sniHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, raddr net
|
||||
ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: host})
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, "tcp", host)
|
||||
cc, err := h.options.Router.Dial(ctx, "tcp", host)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
@ -196,7 +189,7 @@ func (h *sniHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, raddr ne
|
||||
ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: host})
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, "tcp", host)
|
||||
cc, err := h.options.Router.Dial(ctx, "tcp", host)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/limiter/traffic"
|
||||
"github.com/go-gost/core/logger"
|
||||
@ -32,7 +31,6 @@ func init() {
|
||||
}
|
||||
|
||||
type socks4Handler struct {
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
stats *stats_util.HandlerStats
|
||||
@ -56,11 +54,6 @@ func (h *socks4Handler) Init(md md.Metadata) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
h.cancel = cancel
|
||||
|
||||
@ -154,7 +147,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g
|
||||
ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: addr})
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, "tcp", addr)
|
||||
cc, err := h.options.Router.Dial(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
resp := gosocks4.NewReply(gosocks4.Failed, nil)
|
||||
log.Trace(resp)
|
||||
|
@ -35,7 +35,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ
|
||||
ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: address})
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, network, address)
|
||||
cc, err := h.options.Router.Dial(ctx, network, address)
|
||||
if err != nil {
|
||||
resp := gosocks5.NewReply(gosocks5.NetUnreachable, nil)
|
||||
log.Trace(resp)
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/gosocks5"
|
||||
@ -27,7 +26,6 @@ func init() {
|
||||
|
||||
type socks5Handler struct {
|
||||
selector gosocks5.Selector
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
stats *stats_util.HandlerStats
|
||||
@ -51,11 +49,6 @@ func (h *socks5Handler) Init(md md.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
h.selector = &serverSelector{
|
||||
Authenticator: h.options.Auther,
|
||||
TLSConfig: h.options.TLSConfig,
|
||||
|
@ -59,7 +59,7 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger
|
||||
log.Debugf("bind on %s OK", cc.LocalAddr())
|
||||
|
||||
// obtain a udp connection
|
||||
c, err := h.router.Dial(ctx, "udp", "") // UDP association
|
||||
c, err := h.options.Router.Dial(ctx, "udp", "") // UDP association
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
|
@ -37,7 +37,7 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network
|
||||
}
|
||||
|
||||
// obtain a udp connection
|
||||
c, err := h.router.Dial(ctx, "udp", "") // UDP association
|
||||
c, err := h.options.Router.Dial(ctx, "udp", "") // UDP association
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/gosocks5"
|
||||
@ -23,7 +22,6 @@ func init() {
|
||||
|
||||
type ssHandler struct {
|
||||
cipher core.Cipher
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -52,11 +50,6 @@ func (h *ssHandler) Init(md md.Metadata) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -111,7 +104,7 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H
|
||||
ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: addr.String()})
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, "tcp", addr.String())
|
||||
cc, err := h.options.Router.Dial(ctx, "tcp", addr.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/common/bufpool"
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/logger"
|
||||
@ -23,7 +22,6 @@ func init() {
|
||||
|
||||
type ssuHandler struct {
|
||||
cipher core.Cipher
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -53,11 +51,6 @@ func (h *ssuHandler) Init(md md.Metadata) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -97,7 +90,7 @@ func (h *ssuHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
|
||||
}
|
||||
|
||||
// obtain a udp connection
|
||||
c, err := h.router.Dial(ctx, "udp", "") // UDP association
|
||||
c, err := h.options.Router.Dial(ctx, "udp", "") // UDP association
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
@ -29,7 +28,6 @@ func init() {
|
||||
}
|
||||
|
||||
type forwardHandler struct {
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -50,11 +48,6 @@ func (h *forwardHandler) Init(md md.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -97,7 +90,7 @@ func (h *forwardHandler) handleDirectForward(ctx context.Context, conn *sshd_uti
|
||||
return nil
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, "tcp", targetAddr)
|
||||
cc, err := h.options.Router.Dial(ctx, "tcp", targetAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ type tapHandler struct {
|
||||
routes sync.Map
|
||||
exit chan struct{}
|
||||
cipher core.Cipher
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -64,11 +63,6 @@ func (h *tapHandler) Init(md md.Metadata) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -135,7 +129,7 @@ func (h *tapHandler) handleLoop(ctx context.Context, conn net.Conn, addr net.Add
|
||||
var pc net.PacketConn
|
||||
|
||||
if addr != nil {
|
||||
cc, err := h.router.Dial(ctx, addr.Network(), "")
|
||||
cc, err := h.options.Router.Dial(ctx, addr.Network(), "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func (h *tunHandler) handleClient(ctx context.Context, conn net.Conn, raddr stri
|
||||
|
||||
for {
|
||||
err := func() error {
|
||||
cc, err := h.router.Dial(ctx, "udp", raddr)
|
||||
cc, err := h.options.Router.Dial(ctx, "udp", raddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ func init() {
|
||||
type tunHandler struct {
|
||||
hop hop.Hop
|
||||
routes sync.Map
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -50,11 +49,6 @@ func (h *tunHandler) Init(md md.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/hop"
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/hop"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
@ -22,7 +22,6 @@ func init() {
|
||||
|
||||
type unixHandler struct {
|
||||
hop hop.Hop
|
||||
router *chain.Router
|
||||
md metadata
|
||||
options handler.Options
|
||||
}
|
||||
@ -43,11 +42,6 @@ func (h *unixHandler) Init(md md.Metadata) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
h.router = h.options.Router
|
||||
if h.router == nil {
|
||||
h.router = chain.NewRouter(chain.LoggerRouterOption(h.options.Logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -80,7 +74,7 @@ func (h *unixHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
|
||||
return h.forwardUnix(ctx, conn, target, log)
|
||||
}
|
||||
|
||||
cc, err := h.router.Dial(ctx, "tcp", "@")
|
||||
cc, err := h.options.Router.Dial(ctx, "tcp", "@")
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
@ -101,8 +95,8 @@ func (h *unixHandler) forwardUnix(ctx context.Context, conn net.Conn, target *ch
|
||||
log.Debugf("%s >> %s", conn.LocalAddr(), target.Addr)
|
||||
var cc io.ReadWriteCloser
|
||||
|
||||
if opts := h.router.Options(); opts != nil && opts.Chain != nil {
|
||||
cc, err = h.router.Dial(ctx, "unix", target.Addr)
|
||||
if opts := h.options.Router.Options(); opts != nil && opts.Chain != nil {
|
||||
cc, err = h.options.Router.Dial(ctx, "unix", target.Addr)
|
||||
} else {
|
||||
cc, err = (&net.Dialer{}).DialContext(ctx, "unix", target.Addr)
|
||||
}
|
||||
|
@ -7,6 +7,84 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ParseInterfaceAddr(ifceName, network string) (ifce string, addr []net.Addr, err error) {
|
||||
if ifceName == "" {
|
||||
addr = append(addr, nil)
|
||||
return
|
||||
}
|
||||
|
||||
ip := net.ParseIP(ifceName)
|
||||
if ip == nil {
|
||||
var ife *net.Interface
|
||||
ife, err = net.InterfaceByName(ifceName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var addrs []net.Addr
|
||||
addrs, err = ife.Addrs()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(addrs) == 0 {
|
||||
err = fmt.Errorf("addr not found for interface %s", ifceName)
|
||||
return
|
||||
}
|
||||
ifce = ifceName
|
||||
for _, addr_ := range addrs {
|
||||
if ipNet, ok := addr_.(*net.IPNet); ok {
|
||||
addr = append(addr, ipToAddr(ipNet.IP, network))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ifce, err = findInterfaceByIP(ip)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
addr = []net.Addr{ipToAddr(ip, network)}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ipToAddr(ip net.IP, network string) (addr net.Addr) {
|
||||
port := 0
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
addr = &net.TCPAddr{IP: ip, Port: port}
|
||||
return
|
||||
case "udp", "udp4", "udp6":
|
||||
addr = &net.UDPAddr{IP: ip, Port: port}
|
||||
return
|
||||
default:
|
||||
addr = &net.IPAddr{IP: ip}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func findInterfaceByIP(ip net.IP) (string, error) {
|
||||
ifces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, ifce := range ifces {
|
||||
addrs, _ := ifce.Addrs()
|
||||
if len(addrs) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
ipAddr, _ := addr.(*net.IPNet)
|
||||
if ipAddr == nil {
|
||||
continue
|
||||
}
|
||||
// logger.Default().Infof("%s-%s", ipAddr, ip)
|
||||
if ipAddr.IP.Equal(ip) {
|
||||
return ifce.Name, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// AddrPortRange is the network address with port range supported.
|
||||
// e.g. 192.168.1.1:0-65535
|
||||
type AddrPortRange string
|
||||
|
176
internal/net/dialer/dialer.go
Normal file
176
internal/net/dialer/dialer.go
Normal file
@ -0,0 +1,176 @@
|
||||
package dialer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/logger"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultTimeout = 10 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultNetDialer = &Dialer{}
|
||||
)
|
||||
|
||||
type Dialer struct {
|
||||
Interface string
|
||||
Netns string
|
||||
Mark int
|
||||
DialFunc func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
Logger logger.Logger
|
||||
}
|
||||
|
||||
func (d *Dialer) Dial(ctx context.Context, network, addr string) (conn net.Conn, err error) {
|
||||
if d == nil {
|
||||
d = DefaultNetDialer
|
||||
}
|
||||
|
||||
log := d.Logger
|
||||
if log == nil {
|
||||
log = logger.Default()
|
||||
}
|
||||
|
||||
if d.Netns != "" {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
originNs, err := netns.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("netns.Get(): %v", err)
|
||||
}
|
||||
defer netns.Set(originNs)
|
||||
|
||||
var ns netns.NsHandle
|
||||
if strings.HasPrefix(d.Netns, "/") {
|
||||
ns, err = netns.GetFromPath(d.Netns)
|
||||
} else {
|
||||
ns, err = netns.GetFromName(d.Netns)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("netns.Get(%s): %v", d.Netns, err)
|
||||
}
|
||||
defer ns.Close()
|
||||
|
||||
if err := netns.Set(ns); err != nil {
|
||||
return nil, fmt.Errorf("netns.Set(%s): %v", d.Netns, err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.DialFunc != nil {
|
||||
return d.DialFunc(ctx, network, addr)
|
||||
}
|
||||
|
||||
switch network {
|
||||
case "unix":
|
||||
netd := net.Dialer{}
|
||||
return netd.DialContext(ctx, network, addr)
|
||||
default:
|
||||
}
|
||||
|
||||
ifces := strings.Split(d.Interface, ",")
|
||||
for _, ifce := range ifces {
|
||||
strict := strings.HasSuffix(ifce, "!")
|
||||
ifce = strings.TrimSuffix(ifce, "!")
|
||||
var ifceName string
|
||||
var ifAddrs []net.Addr
|
||||
ifceName, ifAddrs, err = xnet.ParseInterfaceAddr(ifce, network)
|
||||
if err != nil && strict {
|
||||
return
|
||||
}
|
||||
|
||||
for _, ifAddr := range ifAddrs {
|
||||
conn, err = d.dialOnce(ctx, network, addr, ifceName, ifAddr, log)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
log.Debugf("dial %s %v@%s failed: %s", network, ifAddr, ifceName, err)
|
||||
|
||||
if strict &&
|
||||
!strings.Contains(err.Error(), "no suitable address found") &&
|
||||
!strings.Contains(err.Error(), "mismatched local address type") {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Dialer) dialOnce(ctx context.Context, network, addr, ifceName string, ifAddr net.Addr, log logger.Logger) (net.Conn, error) {
|
||||
if ifceName != "" {
|
||||
log.Debugf("interface: %s %v/%s", ifceName, ifAddr, network)
|
||||
}
|
||||
|
||||
switch network {
|
||||
case "udp", "udp4", "udp6":
|
||||
if addr == "" {
|
||||
var laddr *net.UDPAddr
|
||||
if ifAddr != nil {
|
||||
laddr, _ = ifAddr.(*net.UDPAddr)
|
||||
}
|
||||
|
||||
c, err := net.ListenUDP(network, laddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sc, err := c.SyscallConn()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
err = sc.Control(func(fd uintptr) {
|
||||
if ifceName != "" {
|
||||
if err := bindDevice(fd, ifceName); err != nil {
|
||||
log.Warnf("bind device: %v", err)
|
||||
}
|
||||
}
|
||||
if d.Mark != 0 {
|
||||
if err := setMark(fd, d.Mark); err != nil {
|
||||
log.Warnf("set mark: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
default:
|
||||
return nil, fmt.Errorf("dial: unsupported network %s", network)
|
||||
}
|
||||
netd := net.Dialer{
|
||||
LocalAddr: ifAddr,
|
||||
Control: func(network, address string, c syscall.RawConn) error {
|
||||
return c.Control(func(fd uintptr) {
|
||||
if ifceName != "" {
|
||||
if err := bindDevice(fd, ifceName); err != nil {
|
||||
log.Warnf("bind device: %v", err)
|
||||
}
|
||||
}
|
||||
if d.Mark != 0 {
|
||||
if err := setMark(fd, d.Mark); err != nil {
|
||||
log.Warnf("set mark: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
if d.Netns != "" {
|
||||
// https://github.com/golang/go/issues/44922#issuecomment-796645858
|
||||
netd.FallbackDelay = -1
|
||||
}
|
||||
|
||||
return netd.DialContext(ctx, network, addr)
|
||||
}
|
19
internal/net/dialer/dialer_linux.go
Normal file
19
internal/net/dialer/dialer_linux.go
Normal file
@ -0,0 +1,19 @@
|
||||
package dialer
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func bindDevice(fd uintptr, ifceName string) error {
|
||||
if ifceName == "" {
|
||||
return nil
|
||||
}
|
||||
return unix.BindToDevice(int(fd), ifceName)
|
||||
}
|
||||
|
||||
func setMark(fd uintptr, mark int) error {
|
||||
if mark == 0 {
|
||||
return nil
|
||||
}
|
||||
return unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_MARK, mark)
|
||||
}
|
11
internal/net/dialer/dialer_other.go
Normal file
11
internal/net/dialer/dialer_other.go
Normal file
@ -0,0 +1,11 @@
|
||||
//go:build !linux
|
||||
|
||||
package dialer
|
||||
|
||||
func bindDevice(fd uintptr, ifceName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setMark(fd uintptr, mark int) error {
|
||||
return nil
|
||||
}
|
44
internal/net/resovle.go
Normal file
44
internal/net/resovle.go
Normal file
@ -0,0 +1,44 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/go-gost/core/hosts"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/core/resolver"
|
||||
)
|
||||
|
||||
func Resolve(ctx context.Context, network, addr string, r resolver.Resolver, hosts hosts.HostMapper, log logger.Logger) (string, error) {
|
||||
if addr == "" {
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
host, port, _ := net.SplitHostPort(addr)
|
||||
if host == "" {
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
if hosts != nil {
|
||||
if ips, _ := hosts.Lookup(ctx, network, host); len(ips) > 0 {
|
||||
log.Debugf("hit host mapper: %s -> %s", host, ips)
|
||||
return net.JoinHostPort(ips[0].String(), port), nil
|
||||
}
|
||||
}
|
||||
|
||||
if r != nil {
|
||||
ips, err := r.Resolve(ctx, network, host)
|
||||
if err != nil {
|
||||
if err == resolver.ErrInvalid {
|
||||
return addr, nil
|
||||
}
|
||||
log.Error(err)
|
||||
}
|
||||
if len(ips) == 0 {
|
||||
return "", fmt.Errorf("resolver: domain %s does not exist", host)
|
||||
}
|
||||
return net.JoinHostPort(ips[0].String(), port), nil
|
||||
}
|
||||
return addr, nil
|
||||
}
|
232
internal/net/udp/listener.go
Normal file
232
internal/net/udp/listener.go
Normal file
@ -0,0 +1,232 @@
|
||||
package udp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/common/bufpool"
|
||||
"github.com/go-gost/core/logger"
|
||||
)
|
||||
|
||||
type ListenConfig struct {
|
||||
Addr net.Addr
|
||||
Backlog int
|
||||
ReadQueueSize int
|
||||
ReadBufferSize int
|
||||
TTL time.Duration
|
||||
KeepAlive bool
|
||||
Logger logger.Logger
|
||||
}
|
||||
type listener struct {
|
||||
conn net.PacketConn
|
||||
cqueue chan net.Conn
|
||||
connPool *connPool
|
||||
// mux sync.Mutex
|
||||
closed chan struct{}
|
||||
errChan chan error
|
||||
config *ListenConfig
|
||||
}
|
||||
|
||||
func NewListener(conn net.PacketConn, cfg *ListenConfig) net.Listener {
|
||||
if cfg == nil {
|
||||
cfg = &ListenConfig{}
|
||||
}
|
||||
|
||||
ln := &listener{
|
||||
conn: conn,
|
||||
cqueue: make(chan net.Conn, cfg.Backlog),
|
||||
closed: make(chan struct{}),
|
||||
errChan: make(chan error, 1),
|
||||
config: cfg,
|
||||
}
|
||||
if cfg.KeepAlive {
|
||||
ln.connPool = newConnPool(cfg.TTL).WithLogger(cfg.Logger)
|
||||
}
|
||||
go ln.listenLoop()
|
||||
|
||||
return ln
|
||||
}
|
||||
|
||||
func (ln *listener) Accept() (conn net.Conn, err error) {
|
||||
select {
|
||||
case conn = <-ln.cqueue:
|
||||
return
|
||||
case <-ln.closed:
|
||||
return nil, net.ErrClosed
|
||||
case err = <-ln.errChan:
|
||||
if err == nil {
|
||||
err = net.ErrClosed
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (ln *listener) listenLoop() {
|
||||
for {
|
||||
select {
|
||||
case <-ln.closed:
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
b := bufpool.Get(ln.config.ReadBufferSize)
|
||||
|
||||
n, raddr, err := ln.conn.ReadFrom(b)
|
||||
if err != nil {
|
||||
ln.errChan <- err
|
||||
close(ln.errChan)
|
||||
return
|
||||
}
|
||||
|
||||
c := ln.getConn(raddr)
|
||||
if c == nil {
|
||||
bufpool.Put(b)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := c.WriteQueue(b[:n]); err != nil {
|
||||
ln.config.Logger.Warn("data discarded: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ln *listener) Addr() net.Addr {
|
||||
if ln.config.Addr != nil {
|
||||
return ln.config.Addr
|
||||
}
|
||||
return ln.conn.LocalAddr()
|
||||
}
|
||||
|
||||
func (ln *listener) Close() error {
|
||||
select {
|
||||
case <-ln.closed:
|
||||
default:
|
||||
close(ln.closed)
|
||||
ln.conn.Close()
|
||||
ln.connPool.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ln *listener) getConn(raddr net.Addr) *conn {
|
||||
// ln.mux.Lock()
|
||||
// defer ln.mux.Unlock()
|
||||
|
||||
c, ok := ln.connPool.Get(raddr.String())
|
||||
if ok {
|
||||
return c
|
||||
}
|
||||
|
||||
c = newConn(ln.conn, ln.Addr(), raddr, ln.config.ReadQueueSize, ln.config.KeepAlive)
|
||||
select {
|
||||
case ln.cqueue <- c:
|
||||
ln.connPool.Set(raddr.String(), c)
|
||||
return c
|
||||
default:
|
||||
c.Close()
|
||||
ln.config.Logger.Warnf("connection queue is full, client %s discarded", raddr)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// conn is a server side connection for UDP client peer, it implements net.Conn and net.PacketConn.
|
||||
type conn struct {
|
||||
net.PacketConn
|
||||
localAddr net.Addr
|
||||
remoteAddr net.Addr
|
||||
rc chan []byte // data receive queue
|
||||
idle int32 // indicate the connection is idle
|
||||
closed chan struct{}
|
||||
closeMutex sync.Mutex
|
||||
keepAlive bool
|
||||
}
|
||||
|
||||
func newConn(c net.PacketConn, laddr, remoteAddr net.Addr, queueSize int, keepAlive bool) *conn {
|
||||
return &conn{
|
||||
PacketConn: c,
|
||||
localAddr: laddr,
|
||||
remoteAddr: remoteAddr,
|
||||
rc: make(chan []byte, queueSize),
|
||||
closed: make(chan struct{}),
|
||||
keepAlive: keepAlive,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *conn) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
||||
select {
|
||||
case bb := <-c.rc:
|
||||
n = copy(b, bb)
|
||||
c.SetIdle(false)
|
||||
bufpool.Put(bb)
|
||||
|
||||
case <-c.closed:
|
||||
err = net.ErrClosed
|
||||
return
|
||||
}
|
||||
|
||||
addr = c.remoteAddr
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *conn) Read(b []byte) (n int, err error) {
|
||||
n, _, err = c.ReadFrom(b)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *conn) Write(b []byte) (n int, err error) {
|
||||
n, err = c.WriteTo(b, c.remoteAddr)
|
||||
if !c.keepAlive {
|
||||
c.Close()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *conn) Close() error {
|
||||
c.closeMutex.Lock()
|
||||
defer c.closeMutex.Unlock()
|
||||
|
||||
select {
|
||||
case <-c.closed:
|
||||
default:
|
||||
close(c.closed)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *conn) LocalAddr() net.Addr {
|
||||
return c.localAddr
|
||||
}
|
||||
|
||||
func (c *conn) RemoteAddr() net.Addr {
|
||||
return c.remoteAddr
|
||||
}
|
||||
|
||||
func (c *conn) IsIdle() bool {
|
||||
return atomic.LoadInt32(&c.idle) > 0
|
||||
}
|
||||
|
||||
func (c *conn) SetIdle(idle bool) {
|
||||
v := int32(0)
|
||||
if idle {
|
||||
v = 1
|
||||
}
|
||||
atomic.StoreInt32(&c.idle, v)
|
||||
}
|
||||
|
||||
func (c *conn) WriteQueue(b []byte) error {
|
||||
select {
|
||||
case c.rc <- b:
|
||||
return nil
|
||||
|
||||
case <-c.closed:
|
||||
return net.ErrClosed
|
||||
|
||||
default:
|
||||
return errors.New("recv queue is full")
|
||||
}
|
||||
}
|
115
internal/net/udp/pool.go
Normal file
115
internal/net/udp/pool.go
Normal file
@ -0,0 +1,115 @@
|
||||
package udp
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/logger"
|
||||
)
|
||||
|
||||
type connPool struct {
|
||||
m sync.Map
|
||||
ttl time.Duration
|
||||
closed chan struct{}
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
func newConnPool(ttl time.Duration) *connPool {
|
||||
p := &connPool{
|
||||
ttl: ttl,
|
||||
closed: make(chan struct{}),
|
||||
}
|
||||
go p.idleCheck()
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *connPool) WithLogger(logger logger.Logger) *connPool {
|
||||
p.logger = logger
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *connPool) Get(key any) (c *conn, ok bool) {
|
||||
if p == nil {
|
||||
return
|
||||
}
|
||||
|
||||
v, ok := p.m.Load(key)
|
||||
if ok {
|
||||
c, ok = v.(*conn)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (p *connPool) Set(key any, c *conn) {
|
||||
if p == nil {
|
||||
return
|
||||
}
|
||||
|
||||
p.m.Store(key, c)
|
||||
}
|
||||
|
||||
func (p *connPool) Delete(key any) {
|
||||
if p == nil {
|
||||
return
|
||||
}
|
||||
p.m.Delete(key)
|
||||
}
|
||||
|
||||
func (p *connPool) Close() {
|
||||
if p == nil {
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-p.closed:
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
close(p.closed)
|
||||
|
||||
p.m.Range(func(k, v any) bool {
|
||||
if c, ok := v.(*conn); ok && c != nil {
|
||||
c.Close()
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (p *connPool) idleCheck() {
|
||||
ticker := time.NewTicker(p.ttl)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
size := 0
|
||||
idles := 0
|
||||
p.m.Range(func(key, value any) bool {
|
||||
c, ok := value.(*conn)
|
||||
if !ok || c == nil {
|
||||
p.Delete(key)
|
||||
return true
|
||||
}
|
||||
size++
|
||||
|
||||
if c.IsIdle() {
|
||||
idles++
|
||||
p.Delete(key)
|
||||
c.Close()
|
||||
return true
|
||||
}
|
||||
|
||||
c.SetIdle(true)
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
if idles > 0 {
|
||||
p.logger.Debugf("connection pool: size=%d, idle=%d", size, idles)
|
||||
}
|
||||
case <-p.closed:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
@ -3,12 +3,12 @@ package ftcp
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/go-gost/core/common/net/udp"
|
||||
"github.com/go-gost/core/listener"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
admission "github.com/go-gost/x/admission/wrapper"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
"github.com/go-gost/x/internal/net/udp"
|
||||
limiter "github.com/go-gost/x/limiter/traffic/wrapper"
|
||||
metrics "github.com/go-gost/x/metrics/wrapper"
|
||||
stats "github.com/go-gost/x/observer/stats/wrapper"
|
||||
|
@ -108,7 +108,7 @@ func (l *redirectListener) accept() (conn net.Conn, err error) {
|
||||
// Out-of-band data is also read in so that the original destination
|
||||
// address can be identified and parsed.
|
||||
func readFromUDP(conn *net.UDPConn, b []byte) (n int, remoteAddr *net.UDPAddr, dstAddr *net.UDPAddr, err error) {
|
||||
oob := bufpool.Get(1024)
|
||||
oob := bufpool.Get(8192)
|
||||
defer bufpool.Put(oob)
|
||||
|
||||
n, oobn, _, remoteAddr, err := conn.ReadMsgUDP(b, oob)
|
||||
@ -118,14 +118,14 @@ func readFromUDP(conn *net.UDPConn, b []byte) (n int, remoteAddr *net.UDPAddr, d
|
||||
|
||||
msgs, err := unix.ParseSocketControlMessage(oob[:oobn])
|
||||
if err != nil {
|
||||
return 0, nil, nil, fmt.Errorf("parsing socket control message: %s", err)
|
||||
return 0, nil, nil, fmt.Errorf("parsing socket control message: %v", err)
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
if msg.Header.Level == unix.SOL_IP && msg.Header.Type == unix.IP_RECVORIGDSTADDR {
|
||||
originalDstRaw := &unix.RawSockaddrInet4{}
|
||||
if err = binary.Read(bytes.NewReader(msg.Data), binary.LittleEndian, originalDstRaw); err != nil {
|
||||
return 0, nil, nil, fmt.Errorf("reading original destination address: %s", err)
|
||||
return 0, nil, nil, fmt.Errorf("reading original destination address: %v", err)
|
||||
}
|
||||
|
||||
switch originalDstRaw.Family {
|
||||
@ -154,7 +154,7 @@ func readFromUDP(conn *net.UDPConn, b []byte) (n int, remoteAddr *net.UDPAddr, d
|
||||
}
|
||||
|
||||
if dstAddr == nil {
|
||||
return 0, nil, nil, fmt.Errorf("unable to obtain original destination: %s", err)
|
||||
return 0, nil, nil, fmt.Errorf("unable to obtain original destination: %v", err)
|
||||
}
|
||||
|
||||
return
|
||||
@ -166,50 +166,50 @@ func readFromUDP(conn *net.UDPConn, b []byte) (n int, remoteAddr *net.UDPAddr, d
|
||||
func dialUDP(network string, laddr *net.UDPAddr, raddr *net.UDPAddr) (net.Conn, error) {
|
||||
remoteSocketAddress, err := udpAddrToSocketAddr(raddr)
|
||||
if err != nil {
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("build destination socket address: %s", err)}
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("build destination socket address: %v", err)}
|
||||
}
|
||||
|
||||
localSocketAddress, err := udpAddrToSocketAddr(laddr)
|
||||
if err != nil {
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("build local socket address: %s", err)}
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("build local socket address: %v", err)}
|
||||
}
|
||||
|
||||
fileDescriptor, err := unix.Socket(udpAddrFamily(network, laddr, raddr), unix.SOCK_DGRAM, 0)
|
||||
if err != nil {
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket open: %s", err)}
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket open: %v", err)}
|
||||
}
|
||||
|
||||
if err = unix.SetsockoptInt(fileDescriptor, unix.SOL_IP, unix.IP_TRANSPARENT, 1); err != nil {
|
||||
unix.Close(fileDescriptor)
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: IP_TRANSPARENT: %s", err)}
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: IP_TRANSPARENT: %v", err)}
|
||||
}
|
||||
|
||||
if err = unix.SetsockoptInt(fileDescriptor, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil {
|
||||
unix.Close(fileDescriptor)
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_REUSEADDR: %s", err)}
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_REUSEADDR: %v", err)}
|
||||
}
|
||||
if err = unix.SetsockoptInt(fileDescriptor, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {
|
||||
unix.Close(fileDescriptor)
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_REUSEPORT: %s", err)}
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_REUSEPORT: %v", err)}
|
||||
}
|
||||
|
||||
if err = unix.Bind(fileDescriptor, localSocketAddress); err != nil {
|
||||
unix.Close(fileDescriptor)
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket bind %v: %s", laddr, err)}
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket bind %v: %v", laddr, err)}
|
||||
}
|
||||
|
||||
if err = unix.Connect(fileDescriptor, remoteSocketAddress); err != nil {
|
||||
unix.Close(fileDescriptor)
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket connect: %s", err)}
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket connect: %v", err)}
|
||||
}
|
||||
|
||||
fdFile := os.NewFile(uintptr(fileDescriptor), fmt.Sprintf("net-udp-dial-%s", raddr.String()))
|
||||
fdFile := os.NewFile(uintptr(fileDescriptor), fmt.Sprintf("net-udp-dial-%v", raddr.String()))
|
||||
defer fdFile.Close()
|
||||
|
||||
remoteConn, err := net.FileConn(fdFile)
|
||||
if err != nil {
|
||||
unix.Close(fileDescriptor)
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("convert file descriptor to connection: %s", err)}
|
||||
return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("convert file descriptor to connection: %v", err)}
|
||||
}
|
||||
|
||||
return remoteConn, nil
|
||||
|
@ -25,7 +25,6 @@ func init() {
|
||||
type rtcpListener struct {
|
||||
laddr net.Addr
|
||||
ln net.Listener
|
||||
router *chain.Router
|
||||
logger logger.Logger
|
||||
closed chan struct{}
|
||||
options listener.Options
|
||||
@ -60,11 +59,6 @@ func (l *rtcpListener) Init(md md.Metadata) (err error) {
|
||||
l.laddr = &bindAddr{addr: l.options.Addr}
|
||||
}
|
||||
|
||||
l.router = l.options.Router
|
||||
if l.router == nil {
|
||||
l.router = chain.NewRouter(chain.LoggerRouterOption(l.logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -77,7 +71,7 @@ func (l *rtcpListener) Accept() (conn net.Conn, err error) {
|
||||
|
||||
ln := l.getListener()
|
||||
if ln == nil {
|
||||
ln, err = l.router.Bind(
|
||||
ln, err = l.options.Router.Bind(
|
||||
context.Background(), "tcp", l.laddr.String(),
|
||||
chain.MuxBindOption(true),
|
||||
)
|
||||
|
@ -24,7 +24,6 @@ func init() {
|
||||
type rudpListener struct {
|
||||
laddr net.Addr
|
||||
ln net.Listener
|
||||
router *chain.Router
|
||||
closed chan struct{}
|
||||
logger logger.Logger
|
||||
md metadata
|
||||
@ -60,11 +59,6 @@ func (l *rudpListener) Init(md md.Metadata) (err error) {
|
||||
l.laddr = &bindAddr{addr: l.options.Addr}
|
||||
}
|
||||
|
||||
l.router = l.options.Router
|
||||
if l.router == nil {
|
||||
l.router = chain.NewRouter(chain.LoggerRouterOption(l.logger))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -77,7 +71,7 @@ func (l *rudpListener) Accept() (conn net.Conn, err error) {
|
||||
|
||||
ln := l.getListener()
|
||||
if ln == nil {
|
||||
ln, err = l.router.Bind(
|
||||
ln, err = l.options.Router.Bind(
|
||||
context.Background(), "udp", l.laddr.String(),
|
||||
chain.BacklogBindOption(l.md.backlog),
|
||||
chain.UDPConnTTLBindOption(l.md.ttl),
|
||||
|
@ -3,12 +3,12 @@ package udp
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/go-gost/core/common/net/udp"
|
||||
"github.com/go-gost/core/listener"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
admission "github.com/go-gost/x/admission/wrapper"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
"github.com/go-gost/x/internal/net/udp"
|
||||
limiter "github.com/go-gost/x/limiter/traffic/wrapper"
|
||||
metrics "github.com/go-gost/x/metrics/wrapper"
|
||||
stats "github.com/go-gost/x/observer/stats/wrapper"
|
||||
|
@ -14,11 +14,12 @@ import (
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/logger"
|
||||
xchain "github.com/go-gost/x/chain"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
router *chain.Router
|
||||
router chain.Router
|
||||
tlsConfig *tls.Config
|
||||
timeout time.Duration
|
||||
logger logger.Logger
|
||||
@ -28,7 +29,7 @@ type Options struct {
|
||||
type Option func(opts *Options)
|
||||
|
||||
// RouterOption sets the router for Exchanger.
|
||||
func RouterOption(router *chain.Router) Option {
|
||||
func RouterOption(router chain.Router) Option {
|
||||
return func(opts *Options) {
|
||||
opts.router = router
|
||||
}
|
||||
@ -65,7 +66,7 @@ type exchanger struct {
|
||||
network string
|
||||
addr string
|
||||
rawAddr string
|
||||
router *chain.Router
|
||||
router chain.Router
|
||||
client *http.Client
|
||||
options Options
|
||||
}
|
||||
@ -102,7 +103,7 @@ func NewExchanger(addr string, opts ...Option) (Exchanger, error) {
|
||||
ex.addr = net.JoinHostPort(ex.addr, "53")
|
||||
}
|
||||
if ex.router == nil {
|
||||
ex.router = chain.NewRouter(chain.LoggerRouterOption(options.logger))
|
||||
ex.router = xchain.NewRouter(chain.LoggerRouterOption(options.logger))
|
||||
}
|
||||
|
||||
switch ex.network {
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/core/resolver"
|
||||
xchain "github.com/go-gost/x/chain"
|
||||
resolver_util "github.com/go-gost/x/internal/util/resolver"
|
||||
"github.com/go-gost/x/resolver/exchanger"
|
||||
"github.com/miekg/dns"
|
||||
@ -67,7 +68,7 @@ func NewResolver(nameservers []NameServer, opts ...Option) (resolver.Resolver, e
|
||||
ex, err := exchanger.NewExchanger(
|
||||
addr,
|
||||
exchanger.RouterOption(
|
||||
chain.NewRouter(
|
||||
xchain.NewRouter(
|
||||
chain.ChainRouterOption(server.Chain),
|
||||
chain.LoggerRouterOption(options.logger),
|
||||
),
|
||||
@ -165,7 +166,7 @@ func (r *localResolver) resolveAsync(ctx context.Context, server *NameServer, ho
|
||||
return
|
||||
}
|
||||
|
||||
func (r *localResolver) lookupCache(ctx context.Context, server *NameServer, host string) (ips []net.IP, ttl time.Duration, ok bool) {
|
||||
func (r *localResolver) lookupCache(_ context.Context, server *NameServer, host string) (ips []net.IP, ttl time.Duration, ok bool) {
|
||||
lookup := func(t uint16, host string) (ips []net.IP, ttl time.Duration, ok bool) {
|
||||
mq := dns.Msg{}
|
||||
mq.SetQuestion(dns.Fqdn(host), t)
|
||||
|
Reference in New Issue
Block a user