fix transparent proxy
This commit is contained in:
@ -8,7 +8,7 @@ import (
|
||||
|
||||
const (
|
||||
defaultTTL = 60 * time.Second
|
||||
defaultReadBufferSize = 1024
|
||||
defaultReadBufferSize = 1500
|
||||
defaultReadQueueSize = 128
|
||||
defaultBacklog = 128
|
||||
)
|
||||
|
66
listener/redirect/tcp/listener.go
Normal file
66
listener/redirect/tcp/listener.go
Normal file
@ -0,0 +1,66 @@
|
||||
package tcp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/go-gost/core/listener"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
metrics "github.com/go-gost/core/metrics/wrapper"
|
||||
"github.com/go-gost/core/registry"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.ListenerRegistry().Register("red", NewListener)
|
||||
registry.ListenerRegistry().Register("redir", NewListener)
|
||||
registry.ListenerRegistry().Register("redirect", NewListener)
|
||||
}
|
||||
|
||||
type redirectListener struct {
|
||||
ln net.Listener
|
||||
logger logger.Logger
|
||||
md metadata
|
||||
options listener.Options
|
||||
}
|
||||
|
||||
func NewListener(opts ...listener.Option) listener.Listener {
|
||||
options := listener.Options{}
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
return &redirectListener{
|
||||
logger: options.Logger,
|
||||
options: options,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *redirectListener) Init(md md.Metadata) (err error) {
|
||||
if err = l.parseMetadata(md); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
lc := net.ListenConfig{}
|
||||
if l.md.tproxy {
|
||||
lc.Control = l.control
|
||||
}
|
||||
ln, err := lc.Listen(context.Background(), "tcp", l.options.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.ln = metrics.WrapListener(l.options.Service, ln)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *redirectListener) Accept() (conn net.Conn, err error) {
|
||||
return l.ln.Accept()
|
||||
}
|
||||
|
||||
func (l *redirectListener) Addr() net.Addr {
|
||||
return l.ln.Addr()
|
||||
}
|
||||
|
||||
func (l *redirectListener) Close() error {
|
||||
return l.ln.Close()
|
||||
}
|
15
listener/redirect/tcp/listener_linux.go
Normal file
15
listener/redirect/tcp/listener_linux.go
Normal file
@ -0,0 +1,15 @@
|
||||
package tcp
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func (l *redirectListener) control(network, address string, c syscall.RawConn) error {
|
||||
return c.Control(func(fd uintptr) {
|
||||
if err := unix.SetsockoptInt(int(fd), unix.SOL_IP, unix.IP_TRANSPARENT, 1); err != nil {
|
||||
l.logger.Errorf("set sockopt: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
12
listener/redirect/tcp/listener_other.go
Normal file
12
listener/redirect/tcp/listener_other.go
Normal file
@ -0,0 +1,12 @@
|
||||
//go:build !linux
|
||||
|
||||
package tcp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (l *redirectListener) control(network, address string, c syscall.RawConn) error {
|
||||
return errors.New("TProxy is not available on non-linux platform")
|
||||
}
|
17
listener/redirect/tcp/metadata.go
Normal file
17
listener/redirect/tcp/metadata.go
Normal file
@ -0,0 +1,17 @@
|
||||
package tcp
|
||||
|
||||
import (
|
||||
mdata "github.com/go-gost/core/metadata"
|
||||
)
|
||||
|
||||
type metadata struct {
|
||||
tproxy bool
|
||||
}
|
||||
|
||||
func (l *redirectListener) parseMetadata(md mdata.Metadata) (err error) {
|
||||
const (
|
||||
tproxy = "tproxy"
|
||||
)
|
||||
l.md.tproxy = mdata.GetBool(md, tproxy)
|
||||
return
|
||||
}
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
const (
|
||||
defaultTTL = 60 * time.Second
|
||||
defaultReadBufferSize = 1024
|
||||
defaultReadBufferSize = 1500
|
||||
)
|
||||
|
||||
type metadata struct {
|
||||
|
Reference in New Issue
Block a user