1
0

socks_bridge.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package amneziawgnet
  2. import (
  3. "encoding/json"
  4. "sync/atomic"
  5. )
  6. // bridgedPort is the port the last generated socks bridge dials; 0 before any.
  7. var bridgedPort atomic.Int64
  8. // BuildSocksBridge swaps an "amneziawg" outbound for its loopback socks
  9. // form, preserving sibling keys; false = unbridgeable, fail loudly upstream.
  10. func BuildSocksBridge(raw []byte) ([]byte, bool) {
  11. var ob map[string]any
  12. if err := json.Unmarshal(raw, &ob); err != nil {
  13. return nil, false
  14. }
  15. tag, _ := ob["tag"].(string)
  16. if tag == "" {
  17. return nil, false
  18. }
  19. port := EgressPort()
  20. settings := map[string]any{
  21. "address": "127.0.0.1",
  22. "port": port,
  23. "user": tag,
  24. "pass": SocksPassword(),
  25. }
  26. bs, err := json.Marshal(settings)
  27. if err != nil {
  28. return nil, false
  29. }
  30. ob["protocol"] = "socks"
  31. ob["settings"] = json.RawMessage(bs)
  32. out, err := json.Marshal(ob)
  33. if err != nil {
  34. return nil, false
  35. }
  36. bridgedPort.Store(int64(port))
  37. return out, true
  38. }
  39. // BridgesStale reports that the egress listener holds another port than the last
  40. // generated socks bridge dials, so Xray has to regenerate its config.
  41. func BridgesStale() bool {
  42. bound, listening := GetEgressServer().boundPort()
  43. bridged := int(bridgedPort.Load())
  44. return listening && bridged != 0 && bridged != bound
  45. }