fix transparent proxy

This commit is contained in:
ginuerzh
2022-03-29 23:02:32 +08:00
parent 6a6367b8d1
commit 303f46f843
20 changed files with 493 additions and 68 deletions

View File

@ -8,7 +8,7 @@ import (
const (
defaultTTL = 60 * time.Second
defaultReadBufferSize = 1024
defaultReadBufferSize = 1500
defaultReadQueueSize = 128
defaultBacklog = 128
)

View 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()
}

View 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)
}
})
}

View 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")
}

View 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
}

View File

@ -8,7 +8,7 @@ import (
const (
defaultTTL = 60 * time.Second
defaultReadBufferSize = 1024
defaultReadBufferSize = 1500
)
type metadata struct {