GitHub Action commited on
Commit
34c9342
·
1 Parent(s): bc8a823

Sync from GitHub with Git LFS

Browse files
Files changed (2) hide show
  1. agents/peer_sync.py +66 -65
  2. agents/requirements.txt +2 -1
agents/peer_sync.py CHANGED
@@ -7,6 +7,7 @@ import json
7
  import uuid
8
  import ipaddress
9
  import re
 
10
  from tools.storage import Storage
11
  from datetime import datetime
12
  import select
@@ -60,10 +61,21 @@ def get_listening_ports():
60
  tcp_ports, udp_ports = get_listening_ports()
61
 
62
  # ======================
63
- # LAN Discovery (только local_addresses)
64
  # ======================
65
- def lan_discovery():
 
 
 
 
 
 
 
 
 
 
66
  DISCOVERY_INTERVAL = 30
 
67
  local_addresses = storage.get_config_value("local_addresses", [])
68
  udp_port_set = set()
69
  for a in local_addresses:
@@ -71,55 +83,25 @@ def lan_discovery():
71
  if port:
72
  udp_port_set.add(port)
73
 
74
- while True:
75
- local_ip = get_local_ip()
76
- if not local_ip:
77
- time.sleep(DISCOVERY_INTERVAL)
78
- continue
79
-
80
- net = ipaddress.ip_network(local_ip + '/24', strict=False)
81
- for ip in net.hosts():
82
- if str(ip) == local_ip:
83
- continue
84
- for port in udp_port_set:
85
- try:
86
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
87
- sock.settimeout(0.5)
88
- msg = json.dumps({
89
- "id": my_id,
90
- "name": agent_name,
91
- "addresses": local_addresses
92
- }).encode("utf-8")
93
- sock.sendto(msg, (str(ip), port))
94
- sock.close()
95
- except:
96
- continue
97
- time.sleep(DISCOVERY_INTERVAL)
98
-
99
- def get_local_ip():
100
- try:
101
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
102
- s.connect(("8.8.8.8", 80))
103
- ip = s.getsockname()[0]
104
- s.close()
105
- return ip
106
- except:
107
- return None
108
 
109
- # ======================
110
- # UDP Discovery Listener
111
- # ======================
112
- def udp_discovery_listener():
113
- sockets = []
114
- for _, port in udp_ports:
115
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
116
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
117
- sock.bind(("", port))
118
- sockets.append(sock)
119
 
120
  while True:
121
- for sock in sockets:
 
122
  try:
 
123
  data, addr = sock.recvfrom(2048)
124
  msg = json.loads(data.decode("utf-8"))
125
  peer_id = msg.get("id")
@@ -128,38 +110,59 @@ def udp_discovery_listener():
128
 
129
  name = msg.get("name", "unknown")
130
  addresses = msg.get("addresses", [f"{addr[0]}:{sock.getsockname()[1]}"])
131
-
132
  expanded_addresses = []
 
133
  for a in addresses:
134
  norm = storage.normalize_address(a)
135
  if norm is None:
136
  continue
137
  proto, rest = norm.split("://", 1)
138
-
139
- # --- фильтруем loopback ---
140
  host_port = rest.split(":")[0]
141
- if host_port.startswith("127."):
142
  continue
143
-
144
- if proto == "udp":
145
- expanded_addresses.append(f"udp://{rest}")
146
- expanded_addresses.append(f"tcp://{rest}")
147
- elif proto == "any":
148
  expanded_addresses.append(f"udp://{rest}")
149
  expanded_addresses.append(f"tcp://{rest}")
150
  elif proto == "tcp":
151
  expanded_addresses.append(f"tcp://{rest}")
152
 
153
  if expanded_addresses:
154
- print(f"[UDP Discovery] получен пакет от {addr}, id={peer_id}, "
155
- f"addresses(raw)={addresses}, addresses(expanded)={expanded_addresses}")
156
  storage.add_or_update_peer(peer_id, name, expanded_addresses, "discovery", "online")
 
 
157
  except Exception as e:
158
- print(f"[UDP Discovery] ошибка при обработке пакета: {e}")
159
  continue
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  # ======================
162
- # UDP Discovery Sender (только global_addresses)
163
  # ======================
164
  def udp_discovery_sender():
165
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
@@ -191,7 +194,7 @@ def udp_discovery_sender():
191
  time.sleep(1)
192
 
193
  # ======================
194
- # TCP Listener (для Peer Exchange)
195
  # ======================
196
  def tcp_listener():
197
  sockets = []
@@ -239,7 +242,6 @@ def tcp_listener():
239
  print(f"[TCP Listener] Ошибка при обработке соединения: {e}")
240
  continue
241
 
242
-
243
  # ======================
244
  # Peer Exchange (TCP)
245
  # ======================
@@ -282,11 +284,10 @@ def peer_exchange():
282
  def start_sync():
283
  print("[PeerSync] Запуск фоновой синхронизации")
284
  storage.load_bootstrap()
285
- threading.Thread(target=udp_discovery_listener, daemon=True).start()
286
  threading.Thread(target=udp_discovery_sender, daemon=True).start()
287
  threading.Thread(target=peer_exchange, daemon=True).start()
288
- threading.Thread(target=lan_discovery, daemon=True).start()
289
  threading.Thread(target=tcp_listener, daemon=True).start()
290
 
291
  while True:
292
- time.sleep(60)
 
7
  import uuid
8
  import ipaddress
9
  import re
10
+ import netifaces
11
  from tools.storage import Storage
12
  from datetime import datetime
13
  import select
 
61
  tcp_ports, udp_ports = get_listening_ports()
62
 
63
  # ======================
64
+ # Получение всех локальных IP
65
  # ======================
66
+ def get_all_local_ips():
67
+ ips = []
68
+ for iface in netifaces.interfaces():
69
+ for addr in netifaces.ifaddresses(iface).get(netifaces.AF_INET, []):
70
+ ips.append(addr['addr'])
71
+ return ips
72
+
73
+ # ======================
74
+ # Объединённый UDP/LAN Discovery
75
+ # ======================
76
+ def udp_lan_discovery():
77
  DISCOVERY_INTERVAL = 30
78
+
79
  local_addresses = storage.get_config_value("local_addresses", [])
80
  udp_port_set = set()
81
  for a in local_addresses:
 
83
  if port:
84
  udp_port_set.add(port)
85
 
86
+ # Сокеты для приёма
87
+ listen_sockets = []
88
+ for port in udp_port_set:
89
+ try:
90
+ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
91
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
92
+ sock.bind(("", port))
93
+ listen_sockets.append(sock)
94
+ except Exception as e:
95
+ print(f"[UDP/LAN Discovery] Не удалось создать сокет на порту {port}: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
+ send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
98
+ send_sock.settimeout(0.5)
 
 
 
 
 
 
 
 
99
 
100
  while True:
101
+ # ------------------ Приём ------------------
102
+ for sock in listen_sockets:
103
  try:
104
+ sock.settimeout(0.1)
105
  data, addr = sock.recvfrom(2048)
106
  msg = json.loads(data.decode("utf-8"))
107
  peer_id = msg.get("id")
 
110
 
111
  name = msg.get("name", "unknown")
112
  addresses = msg.get("addresses", [f"{addr[0]}:{sock.getsockname()[1]}"])
 
113
  expanded_addresses = []
114
+
115
  for a in addresses:
116
  norm = storage.normalize_address(a)
117
  if norm is None:
118
  continue
119
  proto, rest = norm.split("://", 1)
 
 
120
  host_port = rest.split(":")[0]
121
+ if host_port.startswith("127.") or host_port.startswith("0."):
122
  continue
123
+ if proto in ["udp", "any"]:
 
 
 
 
124
  expanded_addresses.append(f"udp://{rest}")
125
  expanded_addresses.append(f"tcp://{rest}")
126
  elif proto == "tcp":
127
  expanded_addresses.append(f"tcp://{rest}")
128
 
129
  if expanded_addresses:
130
+ print(f"[UDP/LAN Discovery] получен пакет от {addr} через {sock.getsockname()}, "
131
+ f"id={peer_id}, addresses={expanded_addresses}")
132
  storage.add_or_update_peer(peer_id, name, expanded_addresses, "discovery", "online")
133
+ except socket.timeout:
134
+ continue
135
  except Exception as e:
136
+ print(f"[UDP/LAN Discovery] ошибка при обработке пакета: {e}")
137
  continue
138
 
139
+ # ------------------ Отправка ------------------
140
+ local_ips = get_all_local_ips()
141
+ msg_data = json.dumps({
142
+ "id": my_id,
143
+ "name": agent_name,
144
+ "addresses": local_addresses
145
+ }).encode("utf-8")
146
+
147
+ for local_ip in local_ips:
148
+ try:
149
+ net = ipaddress.ip_network(local_ip + '/24', strict=False)
150
+ except Exception:
151
+ continue
152
+ for ip in net.hosts():
153
+ ip_str = str(ip)
154
+ if ip_str == local_ip or ip_str.startswith("127.") or ip_str.startswith("0."):
155
+ continue
156
+ for port in udp_port_set:
157
+ try:
158
+ send_sock.sendto(msg_data, (ip_str, port))
159
+ except Exception:
160
+ continue
161
+
162
+ time.sleep(DISCOVERY_INTERVAL)
163
+
164
  # ======================
165
+ # UDP Discovery Sender (для global_addresses)
166
  # ======================
167
  def udp_discovery_sender():
168
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
 
194
  time.sleep(1)
195
 
196
  # ======================
197
+ # TCP Listener (Peer Exchange)
198
  # ======================
199
  def tcp_listener():
200
  sockets = []
 
242
  print(f"[TCP Listener] Ошибка при обработке соединения: {e}")
243
  continue
244
 
 
245
  # ======================
246
  # Peer Exchange (TCP)
247
  # ======================
 
284
  def start_sync():
285
  print("[PeerSync] Запуск фоновой синхронизации")
286
  storage.load_bootstrap()
287
+ threading.Thread(target=udp_lan_discovery, daemon=True).start()
288
  threading.Thread(target=udp_discovery_sender, daemon=True).start()
289
  threading.Thread(target=peer_exchange, daemon=True).start()
 
290
  threading.Thread(target=tcp_listener, daemon=True).start()
291
 
292
  while True:
293
+ time.sleep(60)
agents/requirements.txt CHANGED
@@ -13,4 +13,5 @@ python-multipart
13
  passlib[bcrypt]
14
  werkzeug
15
  itsdangerous
16
- bleach
 
 
13
  passlib[bcrypt]
14
  werkzeug
15
  itsdangerous
16
+ bleach
17
+ netifaces