Parse X-Forward-For in HTTP requests

This commit is contained in:
世界 2022-08-23 19:44:40 +08:00
parent e750c747c6
commit 9f6ff54a76
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
14 changed files with 38 additions and 59 deletions

View file

@ -21,11 +21,14 @@ type TLSDialer struct {
} }
func TLSConfig(serverAddress string, options option.OutboundTLSOptions) (*tls.Config, error) { func TLSConfig(serverAddress string, options option.OutboundTLSOptions) (*tls.Config, error) {
if !options.Enabled {
return nil, nil
}
var serverName string var serverName string
if options.ServerName != "" { if options.ServerName != "" {
serverName = options.ServerName serverName = options.ServerName
} else if serverAddress != "" { } else if serverAddress != "" {
if _, err := netip.ParseAddr(serverName); err != nil { if _, err := netip.ParseAddr(serverName); err == nil {
serverName = serverAddress serverName = serverAddress
} }
} }

4
go.mod
View file

@ -19,7 +19,7 @@ require (
github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a
github.com/sagernet/netlink v0.0.0-20220820041223-3cd8365d17ac github.com/sagernet/netlink v0.0.0-20220820041223-3cd8365d17ac
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb
github.com/sagernet/sing v0.0.0-20220822075357-8b9965b73533 github.com/sagernet/sing v0.0.0-20220823075935-c333192241ec
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
github.com/sagernet/sing-tun v0.0.0-20220822073626-d5efb431220d github.com/sagernet/sing-tun v0.0.0-20220822073626-d5efb431220d
@ -29,7 +29,7 @@ require (
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0
go.uber.org/atomic v1.10.0 go.uber.org/atomic v1.10.0
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8
golang.org/x/net v0.0.0-20220812174116-3211cb980234 golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c
golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 golang.org/x/sys v0.0.0-20220818161305-2296e01440c6
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478
google.golang.org/grpc v1.48.0 google.golang.org/grpc v1.48.0

8
go.sum
View file

@ -140,8 +140,8 @@ github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb h1:wc0yQ+SBn4TaTY
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4= github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4=
github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.0.0-20220822075357-8b9965b73533 h1:oOOlmOE6QAGtkYeNyboTm/RzPO8g9mCybg0xveWxvnI= github.com/sagernet/sing v0.0.0-20220823075935-c333192241ec h1:71B48luR/x6uGug+8VN1oUwGuBNgpb7lgb0q9FjgsVw=
github.com/sagernet/sing v0.0.0-20220822075357-8b9965b73533/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ= github.com/sagernet/sing v0.0.0-20220823075935-c333192241ec/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ=
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 h1:XUTocA/Ek0dFxUX+xJCWMPPFZCn2GC/uLrBjTSr1vHY= github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 h1:XUTocA/Ek0dFxUX+xJCWMPPFZCn2GC/uLrBjTSr1vHY=
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666/go.mod h1:eDyH7AJmqBGjZQdQmpZIzlbTREudZuWDExMuGKgjRVM= github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666/go.mod h1:eDyH7AJmqBGjZQdQmpZIzlbTREudZuWDExMuGKgjRVM=
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4=
@ -215,8 +215,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c h1:JVAXQ10yGGVbSyoer5VILysz6YKjdNT2bsvlayjqhes=
golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

View file

@ -63,29 +63,18 @@ func (a *myInboundAdapter) Tag() string {
func (a *myInboundAdapter) Start() error { func (a *myInboundAdapter) Start() error {
var err error var err error
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
if common.Contains(a.network, N.NetworkTCP) { if common.Contains(a.network, N.NetworkTCP) {
var tcpListener *net.TCPListener _, err = a.ListenTCP()
if !a.listenOptions.TCPFastOpen {
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
} else {
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
}
if err != nil { if err != nil {
return err return err
} }
a.tcpListener = tcpListener
go a.loopTCPIn() go a.loopTCPIn()
a.logger.Info("tcp server started at ", tcpListener.Addr())
} }
if common.Contains(a.network, N.NetworkUDP) { if common.Contains(a.network, N.NetworkUDP) {
var udpConn *net.UDPConn _, err = a.ListenUDP()
udpConn, err = net.ListenUDP(M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr())
if err != nil { if err != nil {
return err return err
} }
a.udpConn = udpConn
a.udpAddr = bindAddr
a.packetOutboundClosed = make(chan struct{}) a.packetOutboundClosed = make(chan struct{})
a.packetOutbound = make(chan *myInboundPacket) a.packetOutbound = make(chan *myInboundPacket)
if a.oobPacketHandler != nil { if a.oobPacketHandler != nil {
@ -102,7 +91,6 @@ func (a *myInboundAdapter) Start() error {
} }
go a.loopUDPOut() go a.loopUDPOut()
} }
a.logger.Info("udp server started at ", udpConn.LocalAddr())
} }
if a.setSystemProxy { if a.setSystemProxy {
a.clearSystemProxy, err = settings.SetSystemProxy(a.router, M.SocksaddrFromNet(a.tcpListener.Addr()).Port, a.protocol == C.TypeMixed) a.clearSystemProxy, err = settings.SetSystemProxy(a.router, M.SocksaddrFromNet(a.tcpListener.Addr()).Port, a.protocol == C.TypeMixed)
@ -188,8 +176,7 @@ func (a *myInboundAdapter) loopTCPIn() {
} }
} }
func (a *myInboundAdapter) createMetadata(conn net.Conn) adapter.InboundContext { func (a *myInboundAdapter) createMetadata(conn net.Conn, metadata adapter.InboundContext) adapter.InboundContext {
var metadata adapter.InboundContext
metadata.Inbound = a.tag metadata.Inbound = a.tag
metadata.InboundType = a.protocol metadata.InboundType = a.protocol
metadata.SniffEnabled = a.listenOptions.SniffEnabled metadata.SniffEnabled = a.listenOptions.SniffEnabled
@ -203,7 +190,7 @@ func (a *myInboundAdapter) createMetadata(conn net.Conn) adapter.InboundContext
func (a *myInboundAdapter) injectTCP(conn net.Conn) { func (a *myInboundAdapter) injectTCP(conn net.Conn) {
ctx := log.ContextWithNewID(a.ctx) ctx := log.ContextWithNewID(a.ctx)
metadata := a.createMetadata(conn) metadata := a.createMetadata(conn, adapter.InboundContext{})
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source) a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
hErr := a.connHandler.NewConnection(ctx, conn, metadata) hErr := a.connHandler.NewConnection(ctx, conn, metadata)
if hErr != nil { if hErr != nil {

View file

@ -13,7 +13,6 @@ import (
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/auth" "github.com/sagernet/sing/common/auth"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/protocol/http" "github.com/sagernet/sing/protocol/http"
) )
@ -72,7 +71,7 @@ func (h *HTTP) NewConnection(ctx context.Context, conn net.Conn, metadata adapte
if h.tlsConfig != nil { if h.tlsConfig != nil {
conn = tls.Server(conn, h.tlsConfig.Config()) conn = tls.Server(conn, h.tlsConfig.Config())
} }
return http.HandleConnection(ctx, conn, std_bufio.NewReader(conn), h.authenticator, h.upstreamUserHandler(metadata), M.Metadata{}) return http.HandleConnection(ctx, conn, std_bufio.NewReader(conn), h.authenticator, h.upstreamUserHandler(metadata), adapter.UpstreamMetadata(metadata))
} }
func (a *myInboundAdapter) upstreamUserHandler(metadata adapter.InboundContext) adapter.UpstreamHandlerAdapter { func (a *myInboundAdapter) upstreamUserHandler(metadata adapter.InboundContext) adapter.UpstreamHandlerAdapter {

View file

@ -12,7 +12,6 @@ import (
"github.com/sagernet/sing/common/auth" "github.com/sagernet/sing/common/auth"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/rw"
"github.com/sagernet/sing/protocol/http" "github.com/sagernet/sing/protocol/http"
@ -53,8 +52,8 @@ func (h *Mixed) NewConnection(ctx context.Context, conn net.Conn, metadata adapt
} }
switch headerType { switch headerType {
case socks4.Version, socks5.Version: case socks4.Version, socks5.Version:
return socks.HandleConnection0(ctx, conn, headerType, h.authenticator, h.upstreamUserHandler(metadata), M.Metadata{}) return socks.HandleConnection0(ctx, conn, headerType, h.authenticator, h.upstreamUserHandler(metadata), adapter.UpstreamMetadata(metadata))
} }
reader := std_bufio.NewReader(bufio.NewCachedReader(conn, buf.As([]byte{headerType}))) reader := std_bufio.NewReader(bufio.NewCachedReader(conn, buf.As([]byte{headerType})))
return http.HandleConnection(ctx, conn, reader, h.authenticator, h.upstreamUserHandler(metadata), M.Metadata{}) return http.HandleConnection(ctx, conn, reader, h.authenticator, h.upstreamUserHandler(metadata), adapter.UpstreamMetadata(metadata))
} }

View file

@ -25,6 +25,7 @@ import (
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/rw"
sHttp "github.com/sagernet/sing/protocol/http"
) )
var _ adapter.Inbound = (*Naive)(nil) var _ adapter.Inbound = (*Naive)(nil)
@ -155,7 +156,7 @@ func (n *Naive) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
if hostPort == "" { if hostPort == "" {
hostPort = request.Host hostPort = request.Host
} }
source := M.ParseSocksaddr(request.RemoteAddr) source := sHttp.SourceAddress(request)
destination := M.ParseSocksaddr(hostPort) destination := M.ParseSocksaddr(hostPort)
if hijacker, isHijacker := writer.(http.Hijacker); isHijacker { if hijacker, isHijacker := writer.(http.Hijacker); isHijacker {
@ -170,10 +171,10 @@ func (n *Naive) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
} }
func (n *Naive) newConnection(ctx context.Context, conn net.Conn, source, destination M.Socksaddr) { func (n *Naive) newConnection(ctx context.Context, conn net.Conn, source, destination M.Socksaddr) {
metadata := n.createMetadata(conn) n.routeTCP(ctx, conn, n.createMetadata(conn, adapter.InboundContext{
metadata.Source = source Source: source,
metadata.Destination = destination Destination: destination,
n.routeTCP(ctx, conn, metadata) }))
} }
func (n *Naive) badRequest(ctx context.Context, request *http.Request, err error) { func (n *Naive) badRequest(ctx context.Context, request *http.Request, err error) {

View file

@ -9,7 +9,6 @@ import (
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common/auth" "github.com/sagernet/sing/common/auth"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/protocol/socks" "github.com/sagernet/sing/protocol/socks"
) )
@ -39,5 +38,5 @@ func NewSocks(ctx context.Context, router adapter.Router, logger log.ContextLogg
} }
func (h *Socks) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { func (h *Socks) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
return socks.HandleConnection(ctx, conn, h.authenticator, h.upstreamUserHandler(metadata), M.Metadata{}) return socks.HandleConnection(ctx, conn, h.authenticator, h.upstreamUserHandler(metadata), adapter.UpstreamMetadata(metadata))
} }

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"net" "net"
"net/netip" "net/netip"
"syscall"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/redir" "github.com/sagernet/sing-box/common/redir"
@ -55,7 +56,7 @@ func (t *TProxy) Start() error {
return err return err
} }
if t.tcpListener != nil { if t.tcpListener != nil {
err = control.Conn(t.tcpListener, func(fd uintptr) error { err = control.Conn(common.MustCast[syscall.Conn](t.tcpListener), func(fd uintptr) error {
return redir.TProxy(fd, M.SocksaddrFromNet(t.tcpListener.Addr()).Addr.Is6()) return redir.TProxy(fd, M.SocksaddrFromNet(t.tcpListener.Addr()).Addr.Is6())
}) })
if err != nil { if err != nil {

View file

@ -133,7 +133,7 @@ func (h *Trojan) NewConnection(ctx context.Context, conn net.Conn, metadata adap
} }
func (h *Trojan) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { func (h *Trojan) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
metadata = h.createMetadata(conn) metadata = h.createMetadata(conn, metadata)
return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata)) return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata))
} }

View file

@ -131,7 +131,7 @@ func (h *VMess) NewConnection(ctx context.Context, conn net.Conn, metadata adapt
} }
func (h *VMess) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { func (h *VMess) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
metadata = h.createMetadata(conn) metadata = h.createMetadata(conn, metadata)
return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata)) return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata))
} }

View file

@ -4,7 +4,6 @@ import (
"strings" "strings"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/domain" "github.com/sagernet/sing/common/domain"
) )
@ -16,8 +15,6 @@ type DomainItem struct {
} }
func NewDomainItem(domains []string, domainSuffixes []string) *DomainItem { func NewDomainItem(domains []string, domainSuffixes []string) *DomainItem {
domains = common.Uniq(domains)
domainSuffixes = common.Uniq(domainSuffixes)
var description string var description string
if dLen := len(domains); dLen > 0 { if dLen := len(domains); dLen > 0 {
if dLen == 1 { if dLen == 1 {

View file

@ -15,6 +15,7 @@ import (
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
sHttp "github.com/sagernet/sing/protocol/http"
) )
var _ adapter.V2RayServerTransport = (*Server)(nil) var _ adapter.V2RayServerTransport = (*Server)(nil)
@ -92,7 +93,8 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
if f, ok := writer.(http.Flusher); ok { if f, ok := writer.(http.Flusher); ok {
f.Flush() f.Flush()
} }
var metadata M.Metadata
metadata.Source = sHttp.SourceAddress(request)
if h, ok := writer.(http.Hijacker); ok { if h, ok := writer.(http.Hijacker); ok {
conn, _, err := h.Hijack() conn, _, err := h.Hijack()
if err != nil { if err != nil {
@ -100,7 +102,7 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
s.badRequest(request, E.Cause(err, "hijack conn")) s.badRequest(request, E.Cause(err, "hijack conn"))
return return
} }
s.handler.NewConnection(request.Context(), conn, M.Metadata{}) s.handler.NewConnection(request.Context(), conn, metadata)
} else { } else {
conn := &ServerHTTPConn{ conn := &ServerHTTPConn{
HTTPConn{ HTTPConn{
@ -109,7 +111,7 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
}, },
writer.(http.Flusher), writer.(http.Flusher),
} }
s.handler.NewConnection(request.Context(), conn, M.Metadata{}) s.handler.NewConnection(request.Context(), conn, metadata)
} }
} }

View file

@ -6,7 +6,6 @@ import (
"encoding/base64" "encoding/base64"
"net" "net"
"net/http" "net/http"
"net/netip"
"os" "os"
"strings" "strings"
@ -19,6 +18,7 @@ import (
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
sHttp "github.com/sagernet/sing/protocol/http"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
@ -101,25 +101,16 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
s.badRequest(request, E.Cause(err, "upgrade websocket connection")) s.badRequest(request, E.Cause(err, "upgrade websocket connection"))
return return
} }
var remoteAddr net.Addr var metadata M.Metadata
forwardFrom := request.Header.Get("X-Forwarded-For") metadata.Source = sHttp.SourceAddress(request)
if forwardFrom != "" {
for _, from := range strings.Split(forwardFrom, ",") {
originAddr, err := netip.ParseAddr(from)
if err == nil {
remoteAddr = M.SocksaddrFrom(originAddr, 0).TCPAddr()
break
}
}
}
conn = &WebsocketConn{ conn = &WebsocketConn{
Conn: wsConn, Conn: wsConn,
remoteAddr: remoteAddr, remoteAddr: metadata.Source.TCPAddr(),
} }
if len(earlyData) > 0 { if len(earlyData) > 0 {
conn = bufio.NewCachedConn(conn, buf.As(earlyData)) conn = bufio.NewCachedConn(conn, buf.As(earlyData))
} }
s.handler.NewConnection(request.Context(), conn, M.Metadata{}) s.handler.NewConnection(request.Context(), conn, metadata)
} }
func (s *Server) badRequest(request *http.Request, err error) { func (s *Server) badRequest(request *http.Request, err error) {