mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-15 22:10:26 +00:00
Fixes https://github.com/XTLS/Xray-core/pull/6476 --------- Co-authored-by: echoowall <echoowall@gmail.com>
73 lines
1.8 KiB
Go
73 lines
1.8 KiB
Go
package encoding
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/xtls/xray-core/common/errors"
|
|
"github.com/xtls/xray-core/common/net"
|
|
"google.golang.org/grpc/metadata"
|
|
"google.golang.org/grpc/peer"
|
|
)
|
|
|
|
func remoteAddrFromContext(ctx context.Context, trusted []string) net.Addr {
|
|
var remoteAddr net.Addr
|
|
if pr, ok := peer.FromContext(ctx); ok {
|
|
remoteAddr = pr.Addr
|
|
} else {
|
|
remoteAddr = &net.TCPAddr{
|
|
IP: []byte{0, 0, 0, 0},
|
|
Port: 0,
|
|
}
|
|
}
|
|
|
|
md, ok := metadata.FromIncomingContext(ctx)
|
|
if !ok {
|
|
return remoteAddr
|
|
}
|
|
|
|
if forwardedAddr := parseTrustedXForwardedFor(md, trusted, remoteAddr); forwardedAddr != nil && forwardedAddr.Family().IsIP() {
|
|
remoteAddr = &net.TCPAddr{
|
|
IP: forwardedAddr.IP(),
|
|
Port: 0,
|
|
}
|
|
}
|
|
return remoteAddr
|
|
}
|
|
|
|
func parseTrustedXForwardedFor(md metadata.MD, trusted []string, remoteAddr net.Addr) net.Address {
|
|
values := md.Get("X-Forwarded-For")
|
|
if len(values) == 0 || values[0] == "" {
|
|
return nil
|
|
}
|
|
value := values[0]
|
|
for _, t := range trusted {
|
|
if len(md.Get(t)) > 0 {
|
|
if idx := strings.IndexByte(value, ','); idx >= 0 {
|
|
value = value[:idx]
|
|
}
|
|
return net.ParseAddress(value)
|
|
}
|
|
}
|
|
if len(trusted) == 0 {
|
|
errors.LogWarning(context.Background(), `received "X-Forwarded-For" from `, remoteAddr, ` but "sockopt.trustedXForwardedFor" is not configured; ignoring it and using the real remote address`)
|
|
} else {
|
|
errors.LogError(context.Background(), `ignored potentially forged "X-Forwarded-For" from `, remoteAddr, `: `, value)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func localAddrFromContext(ctx context.Context) net.Addr {
|
|
var localAddr net.Addr
|
|
if pr, ok := peer.FromContext(ctx); ok {
|
|
localAddr = pr.LocalAddr
|
|
}
|
|
if localAddr == nil {
|
|
localAddr = &net.TCPAddr{
|
|
IP: []byte{0, 0, 0, 0},
|
|
Port: 0,
|
|
}
|
|
}
|
|
return localAddr
|
|
}
|