fix netns for socks5 and relay handler

This commit is contained in:
ginuerzh
2024-06-24 21:18:04 +08:00
parent 2ae0462822
commit f9bfca76ed
12 changed files with 150 additions and 34 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/go-gost/core/listener"
"github.com/go-gost/core/logger"
"github.com/go-gost/relay"
xnet "github.com/go-gost/x/internal/net"
"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"
@ -50,7 +51,10 @@ func (h *relayHandler) bindTCP(ctx context.Context, conn net.Conn, network, addr
Status: relay.StatusOK,
}
ln, err := net.Listen(network, address) // strict mode: if the port already in use, it will return error
lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
ln, err := lc.Listen(ctx, network, address) // strict mode: if the port already in use, it will return error
if err != nil {
log.Error(err)
resp.Status = relay.StatusServiceUnavailable
@ -129,10 +133,10 @@ func (h *relayHandler) bindUDP(ctx context.Context, conn net.Conn, network, addr
Status: relay.StatusOK,
}
var pc net.PacketConn
var err error
bindAddr, _ := net.ResolveUDPAddr(network, address)
pc, err = net.ListenUDP(network, bindAddr)
lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
pc, err := lc.ListenPacket(ctx, network, address)
if err != nil {
log.Error(err)
return err

View File

@ -9,6 +9,7 @@ import (
"github.com/go-gost/core/logger"
"github.com/go-gost/gosocks5"
netpkg "github.com/go-gost/x/internal/net"
xnet "github.com/go-gost/x/internal/net"
)
func (h *socks5Handler) handleBind(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error {
@ -31,7 +32,10 @@ func (h *socks5Handler) handleBind(ctx context.Context, conn net.Conn, network,
}
func (h *socks5Handler) bindLocal(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error {
ln, err := net.Listen(network, address) // strict mode: if the port already in use, it will return error
lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
ln, err := lc.Listen(ctx, network, address) // strict mode: if the port already in use, it will return error
if err != nil {
log.Error(err)
reply := gosocks5.NewReply(gosocks5.Failure, nil)
@ -95,7 +99,7 @@ func (h *socks5Handler) serveBind(ctx context.Context, conn net.Conn, ln net.Lis
defer close(errc)
defer pc1.Close()
errc <- netpkg.Transport(conn, pc1)
errc <- xnet.Transport(conn, pc1)
}()
return errc

View File

@ -8,7 +8,7 @@ import (
"github.com/go-gost/core/logger"
"github.com/go-gost/gosocks5"
netpkg "github.com/go-gost/x/internal/net"
xnet "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/internal/util/mux"
)
@ -31,7 +31,10 @@ func (h *socks5Handler) handleMuxBind(ctx context.Context, conn net.Conn, networ
}
func (h *socks5Handler) muxBindLocal(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error {
ln, err := net.Listen(network, address) // strict mode: if the port already in use, it will return error
lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
ln, err := lc.Listen(ctx, network, address) // strict mode: if the port already in use, it will return error
if err != nil {
log.Error(err)
reply := gosocks5.NewReply(gosocks5.Failure, nil)
@ -125,7 +128,7 @@ func (h *socks5Handler) serveMuxBind(ctx context.Context, conn net.Conn, ln net.
t := time.Now()
log.Debugf("%s <-> %s", c.LocalAddr(), c.RemoteAddr())
netpkg.Transport(sc, c)
xnet.Transport(sc, c)
log.WithFields(map[string]any{"duration": time.Since(t)}).
Debugf("%s >-< %s", c.LocalAddr(), c.RemoteAddr())
}(rc)

View File

@ -11,6 +11,7 @@ import (
"github.com/go-gost/core/logger"
"github.com/go-gost/gosocks5"
ctxvalue "github.com/go-gost/x/ctx"
xnet "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/internal/net/udp"
"github.com/go-gost/x/internal/util/socks"
"github.com/go-gost/x/stats"
@ -29,7 +30,11 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger
return reply.Write(conn)
}
cc, err := net.ListenUDP("udp", nil)
lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
laddr := &net.UDPAddr{IP: conn.LocalAddr().(*net.TCPAddr).IP, Port: 0} // use out-going interface's IP
cc, err := lc.ListenPacket(ctx, "udp", laddr.String())
if err != nil {
log.Error(err)
reply := gosocks5.NewReply(gosocks5.Failure, nil)
@ -41,8 +46,6 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger
saddr := gosocks5.Addr{}
saddr.ParseFrom(cc.LocalAddr().String())
saddr.Type = 0
saddr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String()) // replace the IP to the out-going interface's
reply := gosocks5.NewReply(gosocks5.Succeeded, &saddr)
log.Trace(reply)
if err := reply.Write(conn); err != nil {
@ -70,17 +73,16 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger
return err
}
var lc net.PacketConn = cc
clientID := ctxvalue.ClientIDFromContext(ctx)
if h.options.Observer != nil {
pstats := h.stats.Stats(string(clientID))
pstats.Add(stats.KindTotalConns, 1)
pstats.Add(stats.KindCurrentConns, 1)
defer pstats.Add(stats.KindCurrentConns, -1)
lc = stats_wrapper.WrapPacketConn(lc, pstats)
cc = stats_wrapper.WrapPacketConn(cc, pstats)
}
r := udp.NewRelay(socks.UDPConn(lc, h.md.udpBufferSize), pc).
r := udp.NewRelay(socks.UDPConn(cc, h.md.udpBufferSize), pc).
WithBypass(h.options.Bypass).
WithLogger(log)
r.SetBufferSize(h.md.udpBufferSize)

View File

@ -2,12 +2,14 @@ package v5
import (
"context"
"errors"
"net"
"time"
"github.com/go-gost/core/logger"
"github.com/go-gost/gosocks5"
ctxvalue "github.com/go-gost/x/ctx"
xnet "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/internal/net/udp"
"github.com/go-gost/x/internal/util/socks"
"github.com/go-gost/x/stats"
@ -24,28 +26,52 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network
bindAddr = &net.UDPAddr{}
}
var pc net.PacketConn
// relay mode
if bindAddr.Port == 0 {
// relay mode
if !h.md.enableUDP {
reply := gosocks5.NewReply(gosocks5.NotAllowed, nil)
log.Trace(reply)
log.Error("socks5: UDP relay is disabled")
return reply.Write(conn)
}
} else {
// BIND mode
// obtain a udp connection
c, err := h.router.Dial(ctx, "udp", "") // UDP association
if err != nil {
log.Error(err)
return err
}
defer c.Close()
var ok bool
pc, ok = c.(net.PacketConn)
if !ok {
err := errors.New("socks5: wrong connection type")
log.Error(err)
return err
}
} else { // BIND mode
if !h.md.enableBind {
reply := gosocks5.NewReply(gosocks5.NotAllowed, nil)
log.Trace(reply)
log.Error("socks5: BIND is disabled")
return reply.Write(conn)
}
}
pc, err := net.ListenUDP(network, bindAddr)
if err != nil {
log.Error(err)
return err
lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
var err error
pc, err = lc.ListenPacket(ctx, "udp", bindAddr.String())
if err != nil {
log.Error(err)
reply := gosocks5.NewReply(gosocks5.Failure, nil)
log.Trace(reply)
reply.Write(conn)
return err
}
}
defer pc.Close()