From e1843be1c89af4026d40d793b971caab4538fd23 Mon Sep 17 00:00:00 2001 From: amir-devman Date: Wed, 19 Jul 2023 23:16:29 +0000 Subject: [PATCH] fix(ip-restriction): protect usrIpRstrct from concurrent access --- proxy/trojan/server.go | 6 ++++++ proxy/vless/inbound/inbound.go | 6 ++++++ proxy/vmess/inbound/inbound.go | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/proxy/trojan/server.go b/proxy/trojan/server.go index f952cdf9..da800fbb 100644 --- a/proxy/trojan/server.go +++ b/proxy/trojan/server.go @@ -5,6 +5,7 @@ import ( "io" "strconv" "strings" + "sync" "time" "github.com/xtls/xray-core/common" @@ -35,6 +36,8 @@ func init() { // Server is an inbound connection handler that handles messages in trojan protocol. type Server struct { + sync.Mutex + policyManager policy.Manager validator *Validator fallbacks map[string]map[string]map[string]*Fallback // or nil @@ -225,12 +228,15 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con addr := conn.RemoteAddr().(*net.TCPAddr) uniqueIps := make(map[string]bool) + + s.Lock() // Iterate through the connections and find unique used IP addresses withing last 30 seconds. for _, conn := range *usrIpRstrct { if conn.User == user.Email && !conn.IpAddress.Equal(addr.IP) && ((time.Now().Unix() - conn.Time) < 30) { uniqueIps[conn.IpAddress.String()] = true } } + s.Unlock() if (len(uniqueIps) >= int(user.IpLimit)) { return newError("User ", user, " has exceeded their allowed IPs.").AtWarning() diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 9f4bed30..708176ca 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -10,6 +10,7 @@ import ( "reflect" "strconv" "strings" + "sync" "syscall" "time" "unsafe" @@ -53,6 +54,8 @@ func init() { // Handler is an inbound connection handler that handles messages in VLess protocol. type Handler struct { + sync.Mutex + inboundHandlerManager feature_inbound.Manager policyManager policy.Manager validator *vless.Validator @@ -451,12 +454,15 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s addr := connection.RemoteAddr().(*net.TCPAddr) uniqueIps := make(map[string]bool) + + h.Lock() // Iterate through the connections and find unique used IP addresses withing last 30 seconds. for _, conn := range *usrIpRstrct { if conn.User == request.User.Email && !conn.IpAddress.Equal(addr.IP) && ((time.Now().Unix() - conn.Time) < 30) { uniqueIps[conn.IpAddress.String()] = true } } + h.Unlock() if (len(uniqueIps) >= int(request.User.IpLimit)) { return newError("User ", request.User.Email, " has exceeded their allowed IPs.").AtWarning() diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index e39d1a89..b014be88 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -97,6 +97,8 @@ func (v *userByEmail) Remove(email string) bool { // Handler is an inbound connection handler that handles messages in VMess protocol. type Handler struct { + sync.Mutex + policyManager policy.Manager inboundHandlerManager feature_inbound.Manager clients *vmess.TimedUserValidator @@ -268,12 +270,14 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s addr := connection.RemoteAddr().(*net.TCPAddr) uniqueIps := make(map[string]bool) + h.Lock() // Iterate through the connections and find unique used IP addresses withing last 30 seconds. for _, conn := range *usrIpRstrct { if conn.User == request.User.Email && !conn.IpAddress.Equal(addr.IP) && ((time.Now().Unix() - conn.Time) < 30) { uniqueIps[conn.IpAddress.String()] = true } } + h.Unlock() if (len(uniqueIps) >= int(request.User.IpLimit)) { return newError("User ", request.User.Email, " has exceeded their allowed IPs.").AtWarning()