mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-09 06:35:03 +03:00
fix(amneziawg): keep port forwards per inbound and off future relay ports
Attach and BulkAttach copied a client record's forwardedPorts onto the target inbound. A client a node reports keeps the forwards the node chose, so attaching it to one of the master's AmneziaWG inbounds opened listeners of the node's choosing on the master, among them the loopback relay port a later AmneziaWG or TUIC inbound derives from its id; that inbound's traffic then went to the forward and Xray failed to bind. A forward is set per inbound and is no longer carried by an attach, and creating an AmneziaWG or TUIC inbound is refused while a peer forward already holds its relay port.
This commit is contained in:
@@ -157,3 +157,63 @@ func TestAttachRefusesDefaultRouteNextToHeldAddress(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A forward is a listener on the inbound's host; carried over from a node-reported
|
||||
// client, it let the node pick ports on the master, a future relay port among them.
|
||||
func TestAttachDoesNotCarryForwardedPorts(t *testing.T) {
|
||||
attaches := map[string]func(*ClientService, *InboundService, string, int) error{
|
||||
"Attach": func(s *ClientService, inboundSvc *InboundService, email string, ibId int) error {
|
||||
_, err := s.AttachByEmail(inboundSvc, email, []int{ibId})
|
||||
return err
|
||||
},
|
||||
"BulkAttach": func(s *ClientService, inboundSvc *InboundService, email string, ibId int) error {
|
||||
result, _, err := s.BulkAttach(inboundSvc, []string{email}, []int{ibId})
|
||||
if err == nil && len(result.Errors) > 0 {
|
||||
err = errors.New(strings.Join(result.Errors, "; "))
|
||||
}
|
||||
return err
|
||||
},
|
||||
}
|
||||
for name, attach := range attaches {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
setupConflictDB(t)
|
||||
node := 1
|
||||
seedInboundConflict(t, "own", "0.0.0.0", 51830, model.AmneziaWG, ``, awgRelayWindowSettings(t, "own"))
|
||||
seedInboundConflictNode(t, "node", "0.0.0.0", 44301, model.AmneziaWG, ``, `{"clients":[`+
|
||||
`{"email":"forwarder","subId":"s-fwd","enable":true,"publicKey":"QkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkI=","allowedIPs":["10.9.1.2/32"],"forwardedPorts":"8022"}]}`, &node)
|
||||
|
||||
s := &ClientService{}
|
||||
inboundSvc := &InboundService{}
|
||||
var own model.Inbound
|
||||
for _, tag := range []string{"node", "own"} {
|
||||
own = model.Inbound{}
|
||||
if err := database.GetDB().Where("tag = ?", tag).First(&own).Error; err != nil {
|
||||
t.Fatalf("read seeded %s row: %v", tag, err)
|
||||
}
|
||||
clients, err := inboundSvc.GetClients(&own)
|
||||
if err != nil {
|
||||
t.Fatalf("GetClients(%s): %v", tag, err)
|
||||
}
|
||||
if err := s.SyncInbound(nil, own.Id, clients); err != nil {
|
||||
t.Fatalf("SyncInbound(%s): %v", tag, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := attach(s, inboundSvc, "forwarder", own.Id); err != nil {
|
||||
t.Fatalf("attach: %v", err)
|
||||
}
|
||||
if err := database.GetDB().First(&own, own.Id).Error; err != nil {
|
||||
t.Fatalf("reread own inbound: %v", err)
|
||||
}
|
||||
clients, err := inboundSvc.GetClients(&own)
|
||||
if err != nil {
|
||||
t.Fatalf("GetClients(own): %v", err)
|
||||
}
|
||||
for _, c := range clients {
|
||||
if c.Email == "forwarder" && c.ForwardedPorts != "" {
|
||||
t.Fatalf("attach carried forwardedPorts %q onto the master's inbound", c.ForwardedPorts)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user