parse real client IP
This commit is contained in:
@@ -2,10 +2,10 @@ package v5
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/common/bufpool"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/gosocks5"
|
||||
)
|
||||
@@ -28,15 +28,14 @@ type udpRelayConn struct {
|
||||
udpConn *net.UDPConn
|
||||
tcpConn net.Conn
|
||||
taddr net.Addr
|
||||
bufferSize int
|
||||
rbuf [math.MaxUint16]byte
|
||||
wbuf [math.MaxInt16]byte
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
func (c *udpRelayConn) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
||||
buf := bufpool.Get(c.bufferSize)
|
||||
defer bufpool.Put(buf)
|
||||
|
||||
nn, err := c.udpConn.Read(buf)
|
||||
buf := c.rbuf[:]
|
||||
nn, err := c.udpConn.Read(buf[:])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -82,8 +81,7 @@ func (c *udpRelayConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||
Data: b,
|
||||
}
|
||||
|
||||
buf := bufpool.Get(c.bufferSize)
|
||||
defer bufpool.Put(buf)
|
||||
buf := c.wbuf[:]
|
||||
|
||||
nn, err := dgram.WriteTo(bytes.NewBuffer(buf[:0]))
|
||||
if err != nil {
|
||||
|
||||
@@ -228,7 +228,6 @@ func (c *socks5Connector) relayUDP(ctx context.Context, conn net.Conn, addr net.
|
||||
udpConn: cc.(*net.UDPConn),
|
||||
tcpConn: conn,
|
||||
taddr: addr,
|
||||
bufferSize: c.md.udpBufferSize,
|
||||
logger: log,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -4,19 +4,14 @@ import (
|
||||
"time"
|
||||
|
||||
mdata "github.com/go-gost/core/metadata"
|
||||
mdutil "github.com/go-gost/x/metadata/util"
|
||||
"github.com/go-gost/x/internal/util/mux"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultUDPBufferSize = 4096
|
||||
mdutil "github.com/go-gost/x/metadata/util"
|
||||
)
|
||||
|
||||
type metadata struct {
|
||||
connectTimeout time.Duration
|
||||
noTLS bool
|
||||
relay string
|
||||
udpBufferSize int
|
||||
udpTimeout time.Duration
|
||||
muxCfg *mux.Config
|
||||
}
|
||||
@@ -25,10 +20,6 @@ func (c *socks5Connector) parseMetadata(md mdata.Metadata) (err error) {
|
||||
c.md.connectTimeout = mdutil.GetDuration(md, "timeout")
|
||||
c.md.noTLS = mdutil.GetBool(md, "notls")
|
||||
c.md.relay = mdutil.GetString(md, "relay")
|
||||
c.md.udpBufferSize = mdutil.GetInt(md, "udp.bufferSize", "udpBufferSize")
|
||||
if c.md.udpBufferSize <= 0 {
|
||||
c.md.udpBufferSize = defaultUDPBufferSize
|
||||
}
|
||||
c.md.udpTimeout = mdutil.GetDuration(md, "udp.timeout")
|
||||
|
||||
c.md.muxCfg = &mux.Config{
|
||||
|
||||
@@ -665,6 +665,11 @@ func (h *httpHandler) dial(ctx context.Context, network, addr string) (conn net.
|
||||
conn, err = h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), network, addr)
|
||||
if ro := ctx_internal.RecorderObjectFromContext(ctx); ro != nil {
|
||||
ro.Route = buf.String()
|
||||
|
||||
if conn != nil {
|
||||
ro.Src = conn.LocalAddr().String()
|
||||
ro.Dst = conn.RemoteAddr().String()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
@@ -49,9 +49,12 @@ type metadata struct {
|
||||
|
||||
func (h *httpHandler) parseMetadata(md mdata.Metadata) error {
|
||||
h.md.readTimeout = mdutil.GetDuration(md, "readTimeout")
|
||||
if h.md.readTimeout <= 0 {
|
||||
if h.md.readTimeout == 0 {
|
||||
h.md.readTimeout = 15 * time.Second
|
||||
}
|
||||
if h.md.readTimeout < 0 {
|
||||
h.md.readTimeout = 0
|
||||
}
|
||||
|
||||
if m := mdutil.GetStringMapString(md, "http.header", "header"); len(m) > 0 {
|
||||
hd := http.Header{}
|
||||
|
||||
@@ -87,6 +87,9 @@ func (h *socks5Handler) bindLocal(ctx context.Context, conn net.Conn, network, a
|
||||
|
||||
// Issue: may not reachable when host has multi-interface
|
||||
socksAddr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String())
|
||||
if h.md.publicAddr != "" {
|
||||
socksAddr.Host = h.md.publicAddr
|
||||
}
|
||||
socksAddr.Type = 0
|
||||
reply := gosocks5.NewReply(gosocks5.Succeeded, &socksAddr)
|
||||
log.Trace(reply)
|
||||
|
||||
@@ -88,6 +88,9 @@ func (h *socks5Handler) muxBindLocal(ctx context.Context, conn net.Conn, network
|
||||
|
||||
// Issue: may not reachable when host has multi-interface
|
||||
socksAddr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String())
|
||||
if h.md.publicAddr != "" {
|
||||
socksAddr.Host = h.md.publicAddr
|
||||
}
|
||||
socksAddr.Type = 0
|
||||
reply := gosocks5.NewReply(gosocks5.Succeeded, &socksAddr)
|
||||
log.Trace(reply)
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
)
|
||||
|
||||
type metadata struct {
|
||||
publicAddr string
|
||||
readTimeout time.Duration
|
||||
noTLS bool
|
||||
enableBind bool
|
||||
@@ -40,6 +41,7 @@ type metadata struct {
|
||||
}
|
||||
|
||||
func (h *socks5Handler) parseMetadata(md mdata.Metadata) (err error) {
|
||||
h.md.publicAddr = mdutil.GetString(md, "socks.publicAddr", "publicAddr")
|
||||
h.md.readTimeout = mdutil.GetDuration(md, "readTimeout")
|
||||
if h.md.readTimeout <= 0 {
|
||||
h.md.readTimeout = 15 * time.Second
|
||||
|
||||
+11
-3
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/go-gost/x/internal/net/udp"
|
||||
"github.com/go-gost/x/internal/util/socks"
|
||||
traffic_wrapper "github.com/go-gost/x/limiter/traffic/wrapper"
|
||||
metrics "github.com/go-gost/x/metrics/wrapper"
|
||||
xstats "github.com/go-gost/x/observer/stats"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
@@ -37,8 +38,8 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, ro *xrecor
|
||||
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())
|
||||
|
||||
cc, err := lc.ListenPacket(ctx, "udp", "")
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
reply := gosocks5.NewReply(gosocks5.Failure, nil)
|
||||
@@ -56,6 +57,12 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, ro *xrecor
|
||||
|
||||
saddr := gosocks5.Addr{}
|
||||
saddr.ParseFrom(cc.LocalAddr().String())
|
||||
|
||||
saddr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String())
|
||||
if v := net.ParseIP(h.md.publicAddr); v != nil {
|
||||
saddr.Host = h.md.publicAddr
|
||||
}
|
||||
saddr.Type = 0
|
||||
reply := gosocks5.NewReply(gosocks5.Succeeded, &saddr)
|
||||
log.Trace(reply)
|
||||
if err := reply.Write(conn); err != nil {
|
||||
@@ -81,7 +88,9 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, ro *xrecor
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
pc = metrics.WrapPacketConn(ro.Service, pc)
|
||||
|
||||
{
|
||||
pStats := xstats.Stats{}
|
||||
cc = stats_wrapper.WrapPacketConn(cc, &pStats)
|
||||
|
||||
@@ -90,7 +99,6 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, ro *xrecor
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
}()
|
||||
|
||||
{
|
||||
clientID := ctxvalue.ClientIDFromContext(ctx)
|
||||
cc = traffic_wrapper.WrapPacketConn(
|
||||
cc,
|
||||
|
||||
@@ -186,10 +186,20 @@ func (h *tunnelHandler) initEntrypoint() (err error) {
|
||||
|
||||
func (h *tunnelHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.HandleOption) (err error) {
|
||||
start := time.Now()
|
||||
|
||||
clientIP := conn.RemoteAddr().String()
|
||||
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
||||
clientIP = string(clientAddr)
|
||||
}
|
||||
if h, _, _ := net.SplitHostPort(clientIP); h != "" {
|
||||
clientIP = h
|
||||
}
|
||||
|
||||
log := h.log.WithFields(map[string]any{
|
||||
"remote": conn.RemoteAddr().String(),
|
||||
"local": conn.LocalAddr().String(),
|
||||
"sid": ctxvalue.SidFromContext(ctx),
|
||||
"client": clientIP,
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
type conn struct {
|
||||
session *wt.Session
|
||||
stream *wt.Stream
|
||||
clientAddr net.Addr
|
||||
}
|
||||
|
||||
func Conn(session *wt.Session, stream *wt.Stream) net.Conn {
|
||||
@@ -19,6 +20,14 @@ func Conn(session *wt.Session, stream *wt.Stream) net.Conn {
|
||||
}
|
||||
}
|
||||
|
||||
func ConnWithClientAddr(session *wt.Session, stream *wt.Stream, clientAddr net.Addr) net.Conn {
|
||||
return &conn{
|
||||
session: session,
|
||||
stream: stream,
|
||||
clientAddr: clientAddr,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *conn) Read(b []byte) (n int, err error) {
|
||||
return c.stream.Read(b)
|
||||
}
|
||||
@@ -39,6 +48,10 @@ func (c *conn) RemoteAddr() net.Addr {
|
||||
return c.session.RemoteAddr()
|
||||
}
|
||||
|
||||
func (c *conn) ClientAddr() net.Addr {
|
||||
return c.clientAddr
|
||||
}
|
||||
|
||||
func (c *conn) SetDeadline(t time.Time) error {
|
||||
return c.stream.SetDeadline(t)
|
||||
}
|
||||
|
||||
@@ -106,6 +106,13 @@ func (c *limitConn) Metadata() metadata.Metadata {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *limitConn) ClientAddr() net.Addr {
|
||||
if sc, ok := c.Conn.(xnet.ClientAddr); ok {
|
||||
return sc.ClientAddr()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type packetConn struct {
|
||||
net.PacketConn
|
||||
limiter traffic.TrafficLimiter
|
||||
|
||||
@@ -4,10 +4,12 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/logger"
|
||||
pb "github.com/go-gost/x/internal/util/grpc/proto"
|
||||
mdata "google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/peer"
|
||||
)
|
||||
|
||||
@@ -28,6 +30,11 @@ func (s *server) Tunnel(srv pb.GostTunel_TunnelServer) error {
|
||||
if p, ok := peer.FromContext(srv.Context()); ok {
|
||||
c.remoteAddr = p.Addr
|
||||
}
|
||||
if md, ok := mdata.FromIncomingContext(srv.Context()); ok {
|
||||
if cip := getClientIP(md); cip != nil {
|
||||
c.clientAddr = &net.IPAddr{IP: cip}
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
case s.cqueue <- c:
|
||||
@@ -41,11 +48,39 @@ func (s *server) Tunnel(srv pb.GostTunel_TunnelServer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getClientIP(md mdata.MD) net.IP {
|
||||
if md == nil {
|
||||
return nil
|
||||
}
|
||||
var cip string
|
||||
// cloudflare CDN
|
||||
if v := md.Get("CF-Connecting-IP"); len(v) > 0 {
|
||||
cip = v[0]
|
||||
}
|
||||
if cip == "" {
|
||||
if v := md.Get("X-Forwarded-For"); len(v) > 0 {
|
||||
ss := strings.Split(v[0], ",")
|
||||
if len(ss) > 0 && ss[0] != "" {
|
||||
cip = ss[0]
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if cip == "" {
|
||||
if v := md.Get("X-Real-Ip"); len(v) > 0 {
|
||||
cip = v[0]
|
||||
}
|
||||
}
|
||||
|
||||
return net.ParseIP(cip)
|
||||
}
|
||||
|
||||
type conn struct {
|
||||
s pb.GostTunel_TunnelServer
|
||||
rb []byte
|
||||
localAddr net.Addr
|
||||
remoteAddr net.Addr
|
||||
clientAddr net.Addr
|
||||
closed chan struct{}
|
||||
}
|
||||
|
||||
@@ -111,6 +146,10 @@ func (c *conn) RemoteAddr() net.Addr {
|
||||
return c.remoteAddr
|
||||
}
|
||||
|
||||
func (c *conn) ClientAddr() net.Addr {
|
||||
return c.clientAddr
|
||||
}
|
||||
|
||||
func (c *conn) SetDeadline(t time.Time) error {
|
||||
return &net.OpError{Op: "set", Net: "grpc", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ type conn struct {
|
||||
w http.ResponseWriter
|
||||
laddr net.Addr
|
||||
raddr net.Addr
|
||||
clientAddr net.Addr
|
||||
closed chan struct{}
|
||||
}
|
||||
|
||||
@@ -44,6 +45,10 @@ func (c *conn) RemoteAddr() net.Addr {
|
||||
return c.raddr
|
||||
}
|
||||
|
||||
func (c *conn) ClientAddr() net.Addr {
|
||||
return c.clientAddr
|
||||
}
|
||||
|
||||
func (c *conn) SetDeadline(t time.Time) error {
|
||||
return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ type conn struct {
|
||||
w io.Writer
|
||||
remoteAddr net.Addr
|
||||
localAddr net.Addr
|
||||
clientAddr net.Addr
|
||||
closed chan struct{}
|
||||
}
|
||||
|
||||
@@ -49,6 +50,10 @@ func (c *conn) RemoteAddr() net.Addr {
|
||||
return c.remoteAddr
|
||||
}
|
||||
|
||||
func (c *conn) ClientAddr() net.Addr {
|
||||
return c.clientAddr
|
||||
}
|
||||
|
||||
func (c *conn) SetDeadline(t time.Time) error {
|
||||
return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
md "github.com/go-gost/core/metadata"
|
||||
admission "github.com/go-gost/x/admission/wrapper"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
xhttp "github.com/go-gost/x/internal/net/http"
|
||||
"github.com/go-gost/x/internal/net/proxyproto"
|
||||
climiter "github.com/go-gost/x/limiter/conn/wrapper"
|
||||
limiter_wrapper "github.com/go-gost/x/limiter/traffic/wrapper"
|
||||
@@ -198,11 +199,18 @@ func (l *h2Listener) upgrade(w http.ResponseWriter, r *http.Request) (*conn, err
|
||||
Port: 0,
|
||||
}
|
||||
}
|
||||
|
||||
var clientAddr net.Addr
|
||||
if clientIP := xhttp.GetClientIP(r); clientIP != nil {
|
||||
clientAddr = &net.IPAddr{IP: clientIP}
|
||||
}
|
||||
|
||||
return &conn{
|
||||
r: r.Body,
|
||||
w: flushWriter{w},
|
||||
localAddr: l.addr,
|
||||
remoteAddr: remoteAddr,
|
||||
clientAddr: clientAddr,
|
||||
closed: make(chan struct{}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
md "github.com/go-gost/core/metadata"
|
||||
admission "github.com/go-gost/x/admission/wrapper"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
xhttp "github.com/go-gost/x/internal/net/http"
|
||||
"github.com/go-gost/x/internal/net/proxyproto"
|
||||
climiter "github.com/go-gost/x/limiter/conn/wrapper"
|
||||
limiter_wrapper "github.com/go-gost/x/limiter/traffic/wrapper"
|
||||
@@ -148,6 +149,11 @@ func (l *http2Listener) handleFunc(w http.ResponseWriter, r *http.Request) {
|
||||
"w": w,
|
||||
}),
|
||||
}
|
||||
|
||||
if clientIP := xhttp.GetClientIP(r); clientIP != nil {
|
||||
conn.clientAddr = &net.IPAddr{IP: clientIP}
|
||||
}
|
||||
|
||||
select {
|
||||
case l.cqueue <- conn:
|
||||
default:
|
||||
|
||||
@@ -3,7 +3,6 @@ package http3
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
mdata "github.com/go-gost/core/metadata"
|
||||
@@ -12,10 +11,9 @@ import (
|
||||
// a dummy HTTP3 server conn used by HTTP3 handler
|
||||
type conn struct {
|
||||
md mdata.Metadata
|
||||
r *http.Request
|
||||
w http.ResponseWriter
|
||||
laddr net.Addr
|
||||
raddr net.Addr
|
||||
clientAddr net.Addr
|
||||
closed chan struct{}
|
||||
}
|
||||
|
||||
@@ -44,6 +42,10 @@ func (c *conn) RemoteAddr() net.Addr {
|
||||
return c.raddr
|
||||
}
|
||||
|
||||
func (c *conn) ClientAddr() net.Addr {
|
||||
return c.clientAddr
|
||||
}
|
||||
|
||||
func (c *conn) SetDeadline(t time.Time) error {
|
||||
return &net.OpError{Op: "set", Net: "http3", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
xhttp "github.com/go-gost/x/internal/net/http"
|
||||
mdx "github.com/go-gost/x/metadata"
|
||||
"github.com/go-gost/x/registry"
|
||||
"github.com/quic-go/quic-go"
|
||||
@@ -134,6 +135,11 @@ func (l *http3Listener) handleFunc(w http.ResponseWriter, r *http.Request) {
|
||||
"w": w,
|
||||
}),
|
||||
}
|
||||
|
||||
if clientIP := xhttp.GetClientIP(r); clientIP != nil {
|
||||
conn.clientAddr = &net.IPAddr{IP: clientIP}
|
||||
}
|
||||
|
||||
select {
|
||||
case l.cqueue <- conn:
|
||||
default:
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
md "github.com/go-gost/core/metadata"
|
||||
admission "github.com/go-gost/x/admission/wrapper"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
xhttp "github.com/go-gost/x/internal/net/http"
|
||||
wt_util "github.com/go-gost/x/internal/util/wt"
|
||||
traffic_limiter "github.com/go-gost/x/limiter/traffic"
|
||||
limiter_wrapper "github.com/go-gost/x/limiter/traffic/wrapper"
|
||||
@@ -153,9 +154,15 @@ func (l *wtListener) Close() (err error) {
|
||||
}
|
||||
|
||||
func (l *wtListener) upgrade(w http.ResponseWriter, r *http.Request) {
|
||||
clientIP := xhttp.GetClientIP(r)
|
||||
cip := ""
|
||||
if clientIP != nil {
|
||||
cip = clientIP.String()
|
||||
}
|
||||
log := l.logger.WithFields(map[string]any{
|
||||
"local": l.addr.String(),
|
||||
"remote": r.RemoteAddr,
|
||||
"client": cip,
|
||||
})
|
||||
if l.logger.IsLevelEnabled(logger.TraceLevel) {
|
||||
dump, _ := httputil.DumpRequest(r, false)
|
||||
@@ -169,10 +176,15 @@ func (l *wtListener) upgrade(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
l.mux(s, log)
|
||||
var clientAddr net.Addr
|
||||
if clientIP != nil {
|
||||
clientAddr = &net.IPAddr{IP: clientIP}
|
||||
}
|
||||
|
||||
l.mux(s, clientAddr, log)
|
||||
}
|
||||
|
||||
func (l *wtListener) mux(s *wt.Session, log logger.Logger) (err error) {
|
||||
func (l *wtListener) mux(s *wt.Session, clientAddr net.Addr, log logger.Logger) (err error) {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
s.CloseWithError(1, err.Error())
|
||||
@@ -190,7 +202,7 @@ func (l *wtListener) mux(s *wt.Session, log logger.Logger) (err error) {
|
||||
}
|
||||
|
||||
select {
|
||||
case l.cqueue <- wt_util.Conn(s, stream):
|
||||
case l.cqueue <- wt_util.ConnWithClientAddr(s, stream, clientAddr):
|
||||
default:
|
||||
stream.Close()
|
||||
l.logger.Warnf("connection queue is full, stream %v discarded", stream.StreamID())
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
md "github.com/go-gost/core/metadata"
|
||||
admission "github.com/go-gost/x/admission/wrapper"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
xhttp "github.com/go-gost/x/internal/net/http"
|
||||
"github.com/go-gost/x/internal/net/proxyproto"
|
||||
"github.com/go-gost/x/internal/util/mux"
|
||||
ws_util "github.com/go-gost/x/internal/util/ws"
|
||||
@@ -162,26 +163,36 @@ func (l *mwsListener) Addr() net.Addr {
|
||||
}
|
||||
|
||||
func (l *mwsListener) upgrade(w http.ResponseWriter, r *http.Request) {
|
||||
clientIP := xhttp.GetClientIP(r)
|
||||
cip := ""
|
||||
if clientIP != nil {
|
||||
cip = clientIP.String()
|
||||
}
|
||||
log := l.logger.WithFields(map[string]any{
|
||||
"local": l.addr.String(),
|
||||
"remote": r.RemoteAddr,
|
||||
"client": cip,
|
||||
})
|
||||
if l.logger.IsLevelEnabled(logger.TraceLevel) {
|
||||
if log.IsLevelEnabled(logger.TraceLevel) {
|
||||
dump, _ := httputil.DumpRequest(r, false)
|
||||
log.Trace(string(dump))
|
||||
}
|
||||
|
||||
conn, err := l.upgrader.Upgrade(w, r, l.md.header)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
l.mux(ws_util.Conn(conn), log)
|
||||
var clientAddr net.Addr
|
||||
if clientIP != nil {
|
||||
clientAddr = &net.IPAddr{IP: clientIP}
|
||||
}
|
||||
|
||||
l.mux(ws_util.Conn(conn), clientAddr, log)
|
||||
}
|
||||
|
||||
func (l *mwsListener) mux(conn net.Conn, log logger.Logger) {
|
||||
func (l *mwsListener) mux(conn net.Conn, clientAddr net.Addr, log logger.Logger) {
|
||||
defer conn.Close()
|
||||
|
||||
session, err := mux.ServerSession(conn, l.md.muxCfg)
|
||||
@@ -199,10 +210,19 @@ func (l *mwsListener) mux(conn net.Conn, log logger.Logger) {
|
||||
}
|
||||
|
||||
select {
|
||||
case l.cqueue <- stream:
|
||||
case l.cqueue <- &connWithClientAddr{Conn: stream, clientAddr: clientAddr}:
|
||||
default:
|
||||
stream.Close()
|
||||
log.Warnf("connection queue is full, client %s discarded", stream.RemoteAddr())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type connWithClientAddr struct {
|
||||
net.Conn
|
||||
clientAddr net.Addr
|
||||
}
|
||||
|
||||
func (c *connWithClientAddr) ClientAddr() net.Addr {
|
||||
return c.clientAddr
|
||||
}
|
||||
|
||||
@@ -159,24 +159,23 @@ func (l *wsListener) Addr() net.Addr {
|
||||
|
||||
func (l *wsListener) upgrade(w http.ResponseWriter, r *http.Request) {
|
||||
clientIP := xhttp.GetClientIP(r)
|
||||
if l.logger.IsLevelEnabled(logger.TraceLevel) {
|
||||
sip := ""
|
||||
cip := ""
|
||||
if clientIP != nil {
|
||||
sip = clientIP.String()
|
||||
cip = clientIP.String()
|
||||
}
|
||||
log := l.logger.WithFields(map[string]any{
|
||||
"local": l.addr.String(),
|
||||
"remote": r.RemoteAddr,
|
||||
"clientIP": sip,
|
||||
"client": cip,
|
||||
})
|
||||
if log.IsLevelEnabled(logger.TraceLevel) {
|
||||
dump, _ := httputil.DumpRequest(r, false)
|
||||
log.Trace(string(dump))
|
||||
}
|
||||
|
||||
conn, err := l.upgrader.Upgrade(w, r, l.md.header)
|
||||
if err != nil {
|
||||
l.logger.Error(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -189,6 +188,6 @@ func (l *wsListener) upgrade(w http.ResponseWriter, r *http.Request) {
|
||||
case l.cqueue <- ws_util.ConnWithClientAddr(conn, clientAddr):
|
||||
default:
|
||||
conn.Close()
|
||||
l.logger.Warnf("connection queue is full, client %s discarded", conn.RemoteAddr())
|
||||
log.Warnf("connection queue is full, client %s discarded", conn.RemoteAddr())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,13 @@ func (c *serverConn) Metadata() metadata.Metadata {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *serverConn) ClientAddr() net.Addr {
|
||||
if sc, ok := c.Conn.(xnet.ClientAddr); ok {
|
||||
return sc.ClientAddr()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type packetConn struct {
|
||||
net.PacketConn
|
||||
service string
|
||||
|
||||
@@ -82,6 +82,13 @@ func (c *conn) Metadata() metadata.Metadata {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *conn) ClientAddr() net.Addr {
|
||||
if sc, ok := c.Conn.(xnet.ClientAddr); ok {
|
||||
return sc.ClientAddr()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type packetConn struct {
|
||||
net.PacketConn
|
||||
stats stats.Stats
|
||||
|
||||
Reference in New Issue
Block a user