Skip to content

Commit

Permalink
fix(ip-restriction): protect usrIpRstrct from concurrent access
Browse files Browse the repository at this point in the history
  • Loading branch information
amir-devman committed Jul 19, 2023
1 parent 6a0ff0e commit e1843be
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 0 deletions.
6 changes: 6 additions & 0 deletions proxy/trojan/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"strconv"
"strings"
"sync"
"time"

"github.com/xtls/xray-core/common"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
6 changes: 6 additions & 0 deletions proxy/vless/inbound/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"reflect"
"strconv"
"strings"
"sync"
"syscall"
"time"
"unsafe"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
4 changes: 4 additions & 0 deletions proxy/vmess/inbound/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit e1843be

Please sign in to comment.