librats 1.0.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/README.md +145 -331
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +288 -696
  4. package/lib/index.js +407 -44
  5. package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
  6. package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
  7. package/native-src/CMakeLists.txt +404 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +762 -0
  10. package/native-src/src/librats/bindings/rats.h +380 -0
  11. package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
  12. package/native-src/src/librats/bittorrent/bencode.h +176 -0
  13. package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
  14. package/native-src/src/librats/bittorrent/bitfield.h +76 -0
  15. package/native-src/src/librats/bittorrent/byte_io.h +58 -0
  16. package/native-src/src/librats/bittorrent/choker.cpp +25 -0
  17. package/native-src/src/librats/bittorrent/choker.h +46 -0
  18. package/native-src/src/librats/bittorrent/client.cpp +413 -0
  19. package/native-src/src/librats/bittorrent/client.h +227 -0
  20. package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
  21. package/native-src/src/librats/bittorrent/disk_io.h +150 -0
  22. package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
  23. package/native-src/src/librats/bittorrent/extensions.h +94 -0
  24. package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
  25. package/native-src/src/librats/bittorrent/file_storage.h +79 -0
  26. package/native-src/src/librats/bittorrent/log.h +42 -0
  27. package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
  28. package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
  29. package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
  30. package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
  31. package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
  32. package/native-src/src/librats/bittorrent/peer_list.h +75 -0
  33. package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
  34. package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
  35. package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
  36. package/native-src/src/librats/bittorrent/reactor.h +89 -0
  37. package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
  38. package/native-src/src/librats/bittorrent/resume_data.h +41 -0
  39. package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
  40. package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
  41. package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
  42. package/native-src/src/librats/bittorrent/torrent.h +260 -0
  43. package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
  44. package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
  45. package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
  46. package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
  47. package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
  48. package/native-src/src/librats/bittorrent/tracker.h +108 -0
  49. package/native-src/src/librats/bittorrent/types.cpp +206 -0
  50. package/native-src/src/librats/bittorrent/types.h +86 -0
  51. package/native-src/src/librats/core/address.cpp +35 -0
  52. package/native-src/src/librats/core/address.h +78 -0
  53. package/native-src/src/librats/core/bytes.h +69 -0
  54. package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
  55. package/native-src/src/librats/core/chained_send_buffer.h +183 -0
  56. package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
  57. package/native-src/src/librats/core/endpoint_parse.h +31 -0
  58. package/native-src/src/librats/core/event_bus.h +70 -0
  59. package/native-src/src/librats/core/host_endpoint.h +56 -0
  60. package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
  61. package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
  62. package/native-src/src/librats/core/ip_address.cpp +120 -0
  63. package/native-src/src/librats/core/ip_address.h +109 -0
  64. package/native-src/src/librats/core/mpsc_queue.h +47 -0
  65. package/native-src/src/librats/core/notifier.h +74 -0
  66. package/native-src/src/librats/core/receive_buffer.cpp +219 -0
  67. package/native-src/src/librats/core/receive_buffer.h +171 -0
  68. package/native-src/src/librats/core/service_registry.h +58 -0
  69. package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
  70. package/native-src/src/librats/core/socket.h +496 -0
  71. package/native-src/src/librats/core/timer_queue.h +105 -0
  72. package/native-src/src/librats/core/types.cpp +43 -0
  73. package/native-src/src/librats/core/types.h +103 -0
  74. package/native-src/src/librats/core/wakeup_pipe.h +83 -0
  75. package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
  76. package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
  77. package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
  78. package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
  79. package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
  80. package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
  81. package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
  82. package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
  83. package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
  84. package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
  85. package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
  86. package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
  87. package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
  88. package/native-src/src/librats/crypto/hkdf.c +266 -0
  89. package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
  90. package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
  91. package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
  92. package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
  93. package/native-src/src/librats/crypto/poly1305.h +37 -0
  94. package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
  95. package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
  96. package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
  97. package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
  98. package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
  99. package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
  100. package/native-src/src/librats/dht/announce.cpp +37 -0
  101. package/native-src/src/librats/dht/announce.h +41 -0
  102. package/native-src/src/librats/dht/bep42.cpp +109 -0
  103. package/native-src/src/librats/dht/bep42.h +48 -0
  104. package/native-src/src/librats/dht/dht.cpp +501 -0
  105. package/native-src/src/librats/dht/dht.h +119 -0
  106. package/native-src/src/librats/dht/dht_runner.cpp +103 -0
  107. package/native-src/src/librats/dht/dht_runner.h +71 -0
  108. package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
  109. package/native-src/src/librats/dht/dos_blocker.h +47 -0
  110. package/native-src/src/librats/dht/find_peers.cpp +52 -0
  111. package/native-src/src/librats/dht/find_peers.h +73 -0
  112. package/native-src/src/librats/dht/id.h +167 -0
  113. package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
  114. package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
  115. package/native-src/src/librats/dht/log.h +38 -0
  116. package/native-src/src/librats/dht/node.cpp +473 -0
  117. package/native-src/src/librats/dht/node.h +164 -0
  118. package/native-src/src/librats/dht/node_entry.h +81 -0
  119. package/native-src/src/librats/dht/observer.h +72 -0
  120. package/native-src/src/librats/dht/persistence.cpp +90 -0
  121. package/native-src/src/librats/dht/persistence.h +32 -0
  122. package/native-src/src/librats/dht/routing_table.cpp +559 -0
  123. package/native-src/src/librats/dht/routing_table.h +185 -0
  124. package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
  125. package/native-src/src/librats/dht/rpc_manager.h +77 -0
  126. package/native-src/src/librats/dht/storage.cpp +92 -0
  127. package/native-src/src/librats/dht/storage.h +74 -0
  128. package/native-src/src/librats/dht/transport.h +27 -0
  129. package/native-src/src/librats/dht/traversal.cpp +326 -0
  130. package/native-src/src/librats/dht/traversal.h +120 -0
  131. package/native-src/src/librats/dht/udp_transport.cpp +49 -0
  132. package/native-src/src/librats/dht/udp_transport.h +51 -0
  133. package/native-src/src/librats/mdns/log.h +22 -0
  134. package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
  135. package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
  136. package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
  137. package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
  138. package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
  139. package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
  140. package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
  141. package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
  142. package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
  143. package/native-src/src/librats/node/circuit_service.h +84 -0
  144. package/native-src/src/librats/node/config.h +110 -0
  145. package/native-src/src/librats/node/dial_service.h +54 -0
  146. package/native-src/src/librats/node/dialer.cpp +264 -0
  147. package/native-src/src/librats/node/dialer.h +188 -0
  148. package/native-src/src/librats/node/host_events.h +26 -0
  149. package/native-src/src/librats/node/identify.cpp +130 -0
  150. package/native-src/src/librats/node/identify.h +71 -0
  151. package/native-src/src/librats/node/nat_status.cpp +103 -0
  152. package/native-src/src/librats/node/nat_status.h +118 -0
  153. package/native-src/src/librats/node/node.cpp +865 -0
  154. package/native-src/src/librats/node/node.h +344 -0
  155. package/native-src/src/librats/node/node_context.h +33 -0
  156. package/native-src/src/librats/node/peer_network.h +91 -0
  157. package/native-src/src/librats/peer/peer.h +49 -0
  158. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  159. package/native-src/src/librats/peer/peer_book.h +88 -0
  160. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  161. package/native-src/src/librats/peer/peer_id.h +62 -0
  162. package/native-src/src/librats/peer/peer_info.h +37 -0
  163. package/native-src/src/librats/peer/peer_table.cpp +170 -0
  164. package/native-src/src/librats/peer/peer_table.h +148 -0
  165. package/native-src/src/librats/security/handshaker.h +66 -0
  166. package/native-src/src/librats/security/identity.h +43 -0
  167. package/native-src/src/librats/security/noise_security.cpp +122 -0
  168. package/native-src/src/librats/security/noise_security.h +37 -0
  169. package/native-src/src/librats/security/plaintext_security.h +106 -0
  170. package/native-src/src/librats/security/session.h +37 -0
  171. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  172. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  173. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  174. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  176. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  177. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  178. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  179. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  180. package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
  181. package/native-src/src/librats/subsystems/hole_punch.h +290 -0
  182. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  184. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  185. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  186. package/native-src/src/librats/subsystems/message_json.h +88 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  188. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  189. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  190. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  192. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  193. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  194. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  195. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  196. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  197. package/native-src/src/librats/subsystems/relay.cpp +1142 -0
  198. package/native-src/src/librats/subsystems/relay.h +211 -0
  199. package/native-src/src/librats/subsystems/relay_service.h +46 -0
  200. package/native-src/src/librats/transport/connection.cpp +343 -0
  201. package/native-src/src/librats/transport/connection.h +283 -0
  202. package/native-src/src/librats/transport/link.h +96 -0
  203. package/native-src/src/librats/transport/reactor.cpp +588 -0
  204. package/native-src/src/librats/transport/reactor.h +262 -0
  205. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  206. package/native-src/src/librats/transport/relay_link.cpp +208 -0
  207. package/native-src/src/librats/transport/relay_link.h +303 -0
  208. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  209. package/native-src/src/librats/transport/tcp_link.h +43 -0
  210. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  211. package/native-src/src/librats/transport/udp_mux.h +363 -0
  212. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  213. package/native-src/src/librats/transport/udp_packet.h +190 -0
  214. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  215. package/native-src/src/librats/transport/udp_stream.h +614 -0
  216. package/native-src/src/librats/util/features.h.in +51 -0
  217. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  218. package/native-src/src/librats/util/fs.h +136 -0
  219. package/native-src/src/librats/util/json.cpp +1002 -0
  220. package/native-src/src/librats/util/json.h +444 -0
  221. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  222. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  223. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  224. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  225. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  226. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  227. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  228. package/native-src/src/librats/util/rats_export.h +69 -0
  229. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  230. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  231. package/native-src/src/librats/wire/frame.cpp +76 -0
  232. package/native-src/src/librats/wire/frame.h +111 -0
  233. package/native-src/src/librats/wire/message_router.cpp +45 -0
  234. package/native-src/src/librats/wire/message_router.h +47 -0
  235. package/package.json +5 -4
  236. package/scripts/build-librats.js +1 -0
  237. package/scripts/postinstall.js +3 -3
  238. package/scripts/prepare-package.js +4 -4
  239. package/scripts/verify-installation.js +63 -105
  240. package/src/librats_node.cpp +1067 -1323
  241. package/native-src/src/bencode.cpp +0 -485
  242. package/native-src/src/bencode.h +0 -145
  243. package/native-src/src/bittorrent.cpp +0 -14
  244. package/native-src/src/bittorrent.h +0 -74
  245. package/native-src/src/bt_bitfield.cpp +0 -372
  246. package/native-src/src/bt_bitfield.h +0 -316
  247. package/native-src/src/bt_choker.cpp +0 -228
  248. package/native-src/src/bt_choker.h +0 -147
  249. package/native-src/src/bt_client.cpp +0 -1047
  250. package/native-src/src/bt_client.h +0 -445
  251. package/native-src/src/bt_create_torrent.cpp +0 -677
  252. package/native-src/src/bt_create_torrent.h +0 -473
  253. package/native-src/src/bt_extension.cpp +0 -469
  254. package/native-src/src/bt_extension.h +0 -309
  255. package/native-src/src/bt_file_storage.cpp +0 -261
  256. package/native-src/src/bt_file_storage.h +0 -298
  257. package/native-src/src/bt_handshake.cpp +0 -134
  258. package/native-src/src/bt_handshake.h +0 -157
  259. package/native-src/src/bt_messages.cpp +0 -364
  260. package/native-src/src/bt_messages.h +0 -324
  261. package/native-src/src/bt_network.cpp +0 -1007
  262. package/native-src/src/bt_network.h +0 -417
  263. package/native-src/src/bt_peer_connection.cpp +0 -742
  264. package/native-src/src/bt_peer_connection.h +0 -592
  265. package/native-src/src/bt_piece_picker.cpp +0 -786
  266. package/native-src/src/bt_piece_picker.h +0 -473
  267. package/native-src/src/bt_resume_data.cpp +0 -410
  268. package/native-src/src/bt_resume_data.h +0 -249
  269. package/native-src/src/bt_torrent.cpp +0 -2120
  270. package/native-src/src/bt_torrent.h +0 -641
  271. package/native-src/src/bt_torrent_info.cpp +0 -659
  272. package/native-src/src/bt_torrent_info.h +0 -418
  273. package/native-src/src/bt_types.h +0 -621
  274. package/native-src/src/chained_send_buffer.cpp +0 -75
  275. package/native-src/src/chained_send_buffer.h +0 -137
  276. package/native-src/src/crypto/hkdf.c +0 -266
  277. package/native-src/src/crypto/poly1305.h +0 -36
  278. package/native-src/src/dht.cpp +0 -3311
  279. package/native-src/src/dht.h +0 -717
  280. package/native-src/src/disk_io.cpp +0 -632
  281. package/native-src/src/disk_io.h +0 -315
  282. package/native-src/src/file_transfer.cpp +0 -1415
  283. package/native-src/src/file_transfer.h +0 -286
  284. package/native-src/src/fs.h +0 -108
  285. package/native-src/src/gossipsub.cpp +0 -1139
  286. package/native-src/src/gossipsub.h +0 -403
  287. package/native-src/src/ice.cpp +0 -893
  288. package/native-src/src/ice.h +0 -559
  289. package/native-src/src/json.hpp +0 -25526
  290. package/native-src/src/librats.cpp +0 -2378
  291. package/native-src/src/librats.h +0 -2324
  292. package/native-src/src/librats_bittorrent.cpp +0 -601
  293. package/native-src/src/librats_c.cpp +0 -1557
  294. package/native-src/src/librats_c.h +0 -323
  295. package/native-src/src/librats_discovery.cpp +0 -402
  296. package/native-src/src/librats_encryption.cpp +0 -275
  297. package/native-src/src/librats_file_transfer.cpp +0 -144
  298. package/native-src/src/librats_gossipsub.cpp +0 -289
  299. package/native-src/src/librats_ice.cpp +0 -213
  300. package/native-src/src/librats_log_macros.h +0 -36
  301. package/native-src/src/librats_logging.cpp +0 -173
  302. package/native-src/src/librats_mdns.cpp +0 -166
  303. package/native-src/src/librats_persistence.cpp +0 -796
  304. package/native-src/src/librats_portmap.cpp +0 -419
  305. package/native-src/src/librats_reconnection.cpp +0 -218
  306. package/native-src/src/librats_statistic.cpp +0 -105
  307. package/native-src/src/librats_storage.cpp +0 -189
  308. package/native-src/src/rats_export.h +0 -17
  309. package/native-src/src/receive_buffer.cpp +0 -82
  310. package/native-src/src/receive_buffer.h +0 -127
  311. package/native-src/src/socket.h +0 -228
  312. package/native-src/src/threadmanager.cpp +0 -105
  313. package/native-src/src/threadmanager.h +0 -53
  314. package/native-src/src/tracker.cpp +0 -1264
  315. package/native-src/src/tracker.h +0 -319
  316. package/native-src/src/turn.cpp +0 -762
  317. package/native-src/src/turn.h +0 -460
  318. package/native-src/src/wakeup_pipe.h +0 -60
  319. /package/native-src/src/{os.h → librats/util/os.h} +0 -0
@@ -1,762 +0,0 @@
1
- /**
2
- * @file turn.cpp
3
- * @brief TURN (Traversal Using Relays around NAT) Client Implementation
4
- *
5
- * Implements RFC 5766 - TURN protocol for NAT traversal via relay.
6
- */
7
-
8
- #include "turn.h"
9
- #include "logger.h"
10
- #include "network_utils.h"
11
- #include <cstring>
12
- #include <algorithm>
13
-
14
- namespace librats {
15
-
16
- // ============================================================================
17
- // Logging Macros
18
- // ============================================================================
19
-
20
- #define LOG_TURN_DEBUG(msg) LOG_DEBUG("turn", msg)
21
- #define LOG_TURN_INFO(msg) LOG_INFO("turn", msg)
22
- #define LOG_TURN_WARN(msg) LOG_WARN("turn", msg)
23
- #define LOG_TURN_ERROR(msg) LOG_ERROR("turn", msg)
24
-
25
- // ============================================================================
26
- // TurnClient Implementation
27
- // ============================================================================
28
-
29
- TurnClient::TurnClient() = default;
30
-
31
- TurnClient::TurnClient(const TurnClientConfig& config) : config_(config) {}
32
-
33
- TurnClient::~TurnClient() {
34
- close();
35
- }
36
-
37
- TurnClient::TurnClient(TurnClient&& other) noexcept
38
- : config_(std::move(other.config_)),
39
- socket_(other.socket_),
40
- stun_client_(std::move(other.stun_client_)),
41
- state_(other.state_),
42
- allocation_(std::move(other.allocation_)),
43
- nonce_(std::move(other.nonce_)),
44
- realm_(std::move(other.realm_)),
45
- permissions_(std::move(other.permissions_)),
46
- channels_(std::move(other.channels_)),
47
- peer_to_channel_(std::move(other.peer_to_channel_)),
48
- next_channel_(other.next_channel_),
49
- data_callback_(std::move(other.data_callback_)),
50
- state_callback_(std::move(other.state_callback_)) {
51
- other.socket_ = INVALID_SOCKET_VALUE;
52
- other.state_ = TurnAllocationState::None;
53
- }
54
-
55
- TurnClient& TurnClient::operator=(TurnClient&& other) noexcept {
56
- if (this != &other) {
57
- close();
58
- config_ = std::move(other.config_);
59
- socket_ = other.socket_;
60
- stun_client_ = std::move(other.stun_client_);
61
- state_ = other.state_;
62
- allocation_ = std::move(other.allocation_);
63
- nonce_ = std::move(other.nonce_);
64
- realm_ = std::move(other.realm_);
65
- permissions_ = std::move(other.permissions_);
66
- channels_ = std::move(other.channels_);
67
- peer_to_channel_ = std::move(other.peer_to_channel_);
68
- next_channel_ = other.next_channel_;
69
- data_callback_ = std::move(other.data_callback_);
70
- state_callback_ = std::move(other.state_callback_);
71
- other.socket_ = INVALID_SOCKET_VALUE;
72
- other.state_ = TurnAllocationState::None;
73
- }
74
- return *this;
75
- }
76
-
77
- void TurnClient::set_config(const TurnClientConfig& config) {
78
- config_ = config;
79
- }
80
-
81
- void TurnClient::close() {
82
- stop_refresh_thread();
83
-
84
- if (is_allocated()) {
85
- release();
86
- }
87
-
88
- if (is_valid_socket(socket_)) {
89
- close_socket(socket_);
90
- socket_ = INVALID_SOCKET_VALUE;
91
- }
92
-
93
- set_state(TurnAllocationState::None);
94
- }
95
-
96
- bool TurnClient::ensure_socket() {
97
- if (is_valid_socket(socket_)) {
98
- return true;
99
- }
100
-
101
- socket_ = create_udp_socket(0);
102
- if (!is_valid_socket(socket_)) {
103
- LOG_TURN_ERROR("Failed to create UDP socket");
104
- return false;
105
- }
106
-
107
- return true;
108
- }
109
-
110
- std::vector<uint8_t> TurnClient::compute_message_integrity_key() const {
111
- std::string effective_realm = realm_.empty() ? config_.realm : realm_;
112
- return stun_compute_long_term_key(config_.username, effective_realm, config_.password);
113
- }
114
-
115
- void TurnClient::set_state(TurnAllocationState new_state) {
116
- if (state_ != new_state) {
117
- state_ = new_state;
118
- if (state_callback_) {
119
- state_callback_(new_state);
120
- }
121
- }
122
- }
123
-
124
- std::string TurnClient::peer_key(const StunMappedAddress& peer) const {
125
- return peer.address + ":" + std::to_string(peer.port);
126
- }
127
-
128
- // ============================================================================
129
- // Allocation Management
130
- // ============================================================================
131
-
132
- TurnResult TurnClient::allocate() {
133
- LOG_TURN_INFO("Requesting TURN allocation from " << config_.server << ":" << config_.port);
134
-
135
- if (!ensure_socket()) {
136
- return TurnResult::Error("Failed to create socket");
137
- }
138
-
139
- set_state(TurnAllocationState::Allocating);
140
-
141
- // First request without credentials to get nonce and realm
142
- auto result = send_allocate_request(false);
143
-
144
- if (!result.success && result.error) {
145
- if (result.error->code == StunErrorCode::Unauthorized) {
146
- // Expected - server sends 401 with nonce and realm
147
- // Retry with credentials
148
- LOG_TURN_DEBUG("Got 401 response, retrying with credentials");
149
- result = send_allocate_request(true);
150
- }
151
- }
152
-
153
- if (result.success) {
154
- set_state(TurnAllocationState::Allocated);
155
- LOG_TURN_INFO("TURN allocation successful: " << allocation_.relay_address.to_string());
156
-
157
- if (config_.auto_refresh) {
158
- start_refresh_thread();
159
- }
160
- } else {
161
- set_state(TurnAllocationState::Failed);
162
- LOG_TURN_ERROR("TURN allocation failed: " << result.error_message);
163
- }
164
-
165
- return result;
166
- }
167
-
168
- TurnResult TurnClient::send_allocate_request(bool with_credentials) {
169
- StunMessage request(StunMessageType::AllocateRequest);
170
- request.add_requested_transport(TURN_TRANSPORT_UDP);
171
- request.add_lifetime(config_.requested_lifetime);
172
-
173
- if (!config_.software.empty()) {
174
- request.add_software(config_.software);
175
- }
176
-
177
- if (with_credentials && !config_.username.empty()) {
178
- request.add_username(config_.username);
179
- std::string effective_realm = realm_.empty() ? config_.realm : realm_;
180
- if (!effective_realm.empty()) {
181
- request.add_realm(effective_realm);
182
- }
183
- if (!nonce_.empty()) {
184
- request.add_nonce(nonce_);
185
- }
186
- }
187
-
188
- std::vector<uint8_t> data;
189
- if (with_credentials && !config_.password.empty()) {
190
- auto key = compute_message_integrity_key();
191
- data = request.serialize_with_integrity(std::string(key.begin(), key.end()));
192
- } else {
193
- data = request.serialize();
194
- }
195
-
196
- auto response = stun_client_.send_request(socket_, request, config_.server,
197
- config_.port, config_.timeout_ms);
198
-
199
- if (!response) {
200
- return TurnResult::Error("Request timed out");
201
- }
202
-
203
- // Extract nonce and realm from any response
204
- if (auto new_nonce = response->get_nonce()) {
205
- nonce_ = *new_nonce;
206
- }
207
- if (auto new_realm = response->get_realm()) {
208
- realm_ = *new_realm;
209
- }
210
-
211
- if (response->is_error_response()) {
212
- auto error = response->get_error();
213
- if (error) {
214
- return TurnResult::Error(error->code, error->reason);
215
- }
216
- return TurnResult::Error("Unknown error");
217
- }
218
-
219
- if (response->is_success_response()) {
220
- // Parse allocation response
221
- auto relay_addr = response->get_xor_relayed_address();
222
- auto mapped_addr = response->get_xor_mapped_address();
223
- auto lifetime = response->get_lifetime();
224
-
225
- if (!relay_addr || !lifetime) {
226
- return TurnResult::Error("Invalid allocation response");
227
- }
228
-
229
- allocation_.relay_address = *relay_addr;
230
- if (mapped_addr) {
231
- allocation_.mapped_address = *mapped_addr;
232
- }
233
- allocation_.lifetime = *lifetime;
234
- allocation_.allocated_at = std::chrono::steady_clock::now();
235
- allocation_.expires_at = allocation_.allocated_at +
236
- std::chrono::seconds(allocation_.lifetime);
237
-
238
- return TurnResult::Success();
239
- }
240
-
241
- return TurnResult::Error("Unexpected response type");
242
- }
243
-
244
- TurnResult TurnClient::refresh(uint32_t lifetime) {
245
- if (!is_allocated()) {
246
- return TurnResult::Error("No active allocation");
247
- }
248
-
249
- LOG_TURN_DEBUG("Refreshing TURN allocation");
250
- set_state(TurnAllocationState::Refreshing);
251
-
252
- auto result = send_refresh_request(lifetime == 0 ? config_.requested_lifetime : lifetime);
253
-
254
- if (result.success) {
255
- set_state(TurnAllocationState::Allocated);
256
- } else {
257
- set_state(TurnAllocationState::Failed);
258
- }
259
-
260
- return result;
261
- }
262
-
263
- TurnResult TurnClient::send_refresh_request(uint32_t lifetime) {
264
- StunMessage request(StunMessageType::RefreshRequest);
265
- request.add_lifetime(lifetime);
266
- request.add_username(config_.username);
267
-
268
- std::string effective_realm = realm_.empty() ? config_.realm : realm_;
269
- if (!effective_realm.empty()) {
270
- request.add_realm(effective_realm);
271
- }
272
- if (!nonce_.empty()) {
273
- request.add_nonce(nonce_);
274
- }
275
-
276
- auto key = compute_message_integrity_key();
277
- auto data = request.serialize_with_integrity(std::string(key.begin(), key.end()));
278
-
279
- auto response = stun_client_.send_request(socket_, request, config_.server,
280
- config_.port, config_.timeout_ms);
281
-
282
- if (!response) {
283
- return TurnResult::Error("Refresh request timed out");
284
- }
285
-
286
- // Update nonce if changed
287
- if (auto new_nonce = response->get_nonce()) {
288
- nonce_ = *new_nonce;
289
- }
290
-
291
- if (response->is_error_response()) {
292
- auto error = response->get_error();
293
- if (error) {
294
- if (error->code == StunErrorCode::StaleNonce) {
295
- // Retry with new nonce
296
- return send_refresh_request(lifetime);
297
- }
298
- return TurnResult::Error(error->code, error->reason);
299
- }
300
- return TurnResult::Error("Unknown error");
301
- }
302
-
303
- if (response->is_success_response()) {
304
- auto new_lifetime = response->get_lifetime();
305
- if (new_lifetime) {
306
- allocation_.lifetime = *new_lifetime;
307
- allocation_.expires_at = std::chrono::steady_clock::now() +
308
- std::chrono::seconds(allocation_.lifetime);
309
- LOG_TURN_DEBUG("Allocation refreshed, new lifetime: " << allocation_.lifetime);
310
- }
311
- return TurnResult::Success();
312
- }
313
-
314
- return TurnResult::Error("Unexpected response type");
315
- }
316
-
317
- TurnResult TurnClient::release() {
318
- if (!is_allocated()) {
319
- return TurnResult::Success(); // Already released
320
- }
321
-
322
- LOG_TURN_INFO("Releasing TURN allocation");
323
- stop_refresh_thread();
324
-
325
- auto result = send_refresh_request(0); // Lifetime 0 = release
326
-
327
- allocation_ = TurnAllocation();
328
- set_state(TurnAllocationState::None);
329
-
330
- return result;
331
- }
332
-
333
- // ============================================================================
334
- // Permission Management
335
- // ============================================================================
336
-
337
- TurnResult TurnClient::create_permission(const std::string& peer_address) {
338
- StunMappedAddress peer(StunAddressFamily::IPv4, peer_address, 0);
339
- return create_permission(peer);
340
- }
341
-
342
- TurnResult TurnClient::create_permission(const StunMappedAddress& peer) {
343
- return create_permissions({peer.address});
344
- }
345
-
346
- TurnResult TurnClient::create_permissions(const std::vector<std::string>& peer_addresses) {
347
- if (!is_allocated()) {
348
- return TurnResult::Error("No active allocation");
349
- }
350
-
351
- std::vector<StunMappedAddress> peers;
352
- for (const auto& addr : peer_addresses) {
353
- peers.emplace_back(StunAddressFamily::IPv4, addr, 0);
354
- }
355
-
356
- return send_create_permission_request(peers);
357
- }
358
-
359
- TurnResult TurnClient::send_create_permission_request(const std::vector<StunMappedAddress>& peers) {
360
- StunMessage request(StunMessageType::CreatePermissionRequest);
361
-
362
- for (const auto& peer : peers) {
363
- request.add_xor_peer_address(peer);
364
- }
365
-
366
- request.add_username(config_.username);
367
- std::string effective_realm = realm_.empty() ? config_.realm : realm_;
368
- if (!effective_realm.empty()) {
369
- request.add_realm(effective_realm);
370
- }
371
- if (!nonce_.empty()) {
372
- request.add_nonce(nonce_);
373
- }
374
-
375
- auto key = compute_message_integrity_key();
376
- auto data = request.serialize_with_integrity(std::string(key.begin(), key.end()));
377
-
378
- auto response = stun_client_.send_request(socket_, request, config_.server,
379
- config_.port, config_.timeout_ms);
380
-
381
- if (!response) {
382
- return TurnResult::Error("CreatePermission request timed out");
383
- }
384
-
385
- if (auto new_nonce = response->get_nonce()) {
386
- nonce_ = *new_nonce;
387
- }
388
-
389
- if (response->is_error_response()) {
390
- auto error = response->get_error();
391
- if (error) {
392
- if (error->code == StunErrorCode::StaleNonce) {
393
- return send_create_permission_request(peers);
394
- }
395
- return TurnResult::Error(error->code, error->reason);
396
- }
397
- return TurnResult::Error("Unknown error");
398
- }
399
-
400
- if (response->is_success_response()) {
401
- std::lock_guard<std::mutex> lock(mutex_);
402
- auto expires_at = std::chrono::steady_clock::now() + std::chrono::minutes(5);
403
-
404
- for (const auto& peer : peers) {
405
- TurnPermission perm;
406
- perm.peer_address = peer.address;
407
- perm.expires_at = expires_at;
408
- permissions_[peer.address] = perm;
409
- }
410
-
411
- LOG_TURN_DEBUG("Created permissions for " << peers.size() << " peers");
412
- return TurnResult::Success();
413
- }
414
-
415
- return TurnResult::Error("Unexpected response type");
416
- }
417
-
418
- bool TurnClient::has_permission(const std::string& peer_address) const {
419
- std::lock_guard<std::mutex> lock(mutex_);
420
- auto it = permissions_.find(peer_address);
421
- if (it == permissions_.end()) return false;
422
- return !it->second.is_expired();
423
- }
424
-
425
- // ============================================================================
426
- // Channel Binding
427
- // ============================================================================
428
-
429
- uint16_t TurnClient::bind_channel(const StunMappedAddress& peer) {
430
- if (!is_allocated()) {
431
- return 0;
432
- }
433
-
434
- std::string key = peer_key(peer);
435
-
436
- {
437
- std::lock_guard<std::mutex> lock(mutex_);
438
- auto it = peer_to_channel_.find(key);
439
- if (it != peer_to_channel_.end()) {
440
- auto& binding = channels_[it->second];
441
- if (!binding.is_expired()) {
442
- return it->second; // Already bound
443
- }
444
- }
445
- }
446
-
447
- uint16_t channel;
448
- {
449
- std::lock_guard<std::mutex> lock(mutex_);
450
- channel = next_channel_++;
451
- if (next_channel_ > TURN_CHANNEL_MAX) {
452
- next_channel_ = TURN_CHANNEL_MIN;
453
- }
454
- }
455
-
456
- auto result = send_channel_bind_request(channel, peer);
457
- if (!result.success) {
458
- LOG_TURN_ERROR("Channel binding failed: " << result.error_message);
459
- return 0;
460
- }
461
-
462
- {
463
- std::lock_guard<std::mutex> lock(mutex_);
464
- TurnChannelBinding binding;
465
- binding.channel_number = channel;
466
- binding.peer_address = peer;
467
- binding.expires_at = std::chrono::steady_clock::now() + std::chrono::minutes(10);
468
-
469
- channels_[channel] = binding;
470
- peer_to_channel_[key] = channel;
471
- }
472
-
473
- LOG_TURN_DEBUG("Bound channel " << channel << " to " << peer.to_string());
474
- return channel;
475
- }
476
-
477
- TurnResult TurnClient::send_channel_bind_request(uint16_t channel, const StunMappedAddress& peer) {
478
- StunMessage request(StunMessageType::ChannelBindRequest);
479
- request.add_channel_number(channel);
480
- request.add_xor_peer_address(peer);
481
-
482
- request.add_username(config_.username);
483
- std::string effective_realm = realm_.empty() ? config_.realm : realm_;
484
- if (!effective_realm.empty()) {
485
- request.add_realm(effective_realm);
486
- }
487
- if (!nonce_.empty()) {
488
- request.add_nonce(nonce_);
489
- }
490
-
491
- auto key = compute_message_integrity_key();
492
- auto data = request.serialize_with_integrity(std::string(key.begin(), key.end()));
493
-
494
- auto response = stun_client_.send_request(socket_, request, config_.server,
495
- config_.port, config_.timeout_ms);
496
-
497
- if (!response) {
498
- return TurnResult::Error("ChannelBind request timed out");
499
- }
500
-
501
- if (auto new_nonce = response->get_nonce()) {
502
- nonce_ = *new_nonce;
503
- }
504
-
505
- if (response->is_error_response()) {
506
- auto error = response->get_error();
507
- if (error) {
508
- if (error->code == StunErrorCode::StaleNonce) {
509
- return send_channel_bind_request(channel, peer);
510
- }
511
- return TurnResult::Error(error->code, error->reason);
512
- }
513
- return TurnResult::Error("Unknown error");
514
- }
515
-
516
- if (response->is_success_response()) {
517
- return TurnResult::Success();
518
- }
519
-
520
- return TurnResult::Error("Unexpected response type");
521
- }
522
-
523
- uint16_t TurnClient::get_channel(const StunMappedAddress& peer) const {
524
- std::lock_guard<std::mutex> lock(mutex_);
525
- std::string key = peer_key(peer);
526
- auto it = peer_to_channel_.find(key);
527
- if (it == peer_to_channel_.end()) return 0;
528
-
529
- auto ch_it = channels_.find(it->second);
530
- if (ch_it == channels_.end() || ch_it->second.is_expired()) return 0;
531
-
532
- return it->second;
533
- }
534
-
535
- std::optional<StunMappedAddress> TurnClient::get_channel_peer(uint16_t channel) const {
536
- std::lock_guard<std::mutex> lock(mutex_);
537
- auto it = channels_.find(channel);
538
- if (it == channels_.end() || it->second.is_expired()) {
539
- return std::nullopt;
540
- }
541
- return it->second.peer_address;
542
- }
543
-
544
- TurnResult TurnClient::refresh_channel(uint16_t channel) {
545
- std::optional<StunMappedAddress> peer;
546
- {
547
- std::lock_guard<std::mutex> lock(mutex_);
548
- auto it = channels_.find(channel);
549
- if (it != channels_.end()) {
550
- peer = it->second.peer_address;
551
- }
552
- }
553
-
554
- if (!peer) {
555
- return TurnResult::Error("Channel not found");
556
- }
557
-
558
- auto result = send_channel_bind_request(channel, *peer);
559
- if (result.success) {
560
- std::lock_guard<std::mutex> lock(mutex_);
561
- auto it = channels_.find(channel);
562
- if (it != channels_.end()) {
563
- it->second.expires_at = std::chrono::steady_clock::now() + std::chrono::minutes(10);
564
- }
565
- }
566
-
567
- return result;
568
- }
569
-
570
- // ============================================================================
571
- // Data Transfer
572
- // ============================================================================
573
-
574
- bool TurnClient::send_data(const StunMappedAddress& peer, const std::vector<uint8_t>& data) {
575
- uint16_t channel = get_channel(peer);
576
- if (channel != 0) {
577
- return send_channel_data(channel, data);
578
- }
579
- return send_indication(peer, data);
580
- }
581
-
582
- bool TurnClient::send_indication(const StunMappedAddress& peer, const std::vector<uint8_t>& data) {
583
- if (!is_allocated()) {
584
- return false;
585
- }
586
-
587
- // Ensure permission exists
588
- if (!has_permission(peer.address)) {
589
- auto result = create_permission(peer);
590
- if (!result.success) {
591
- LOG_TURN_ERROR("Failed to create permission for " << peer.address);
592
- return false;
593
- }
594
- }
595
-
596
- StunMessage indication;
597
- indication.type = StunMessageType::SendIndication;
598
- indication.generate_transaction_id();
599
- indication.add_xor_peer_address(peer);
600
- indication.add_data(data);
601
-
602
- auto msg_data = indication.serialize();
603
- int sent = send_udp_data(socket_, msg_data, config_.server, config_.port);
604
-
605
- return sent > 0;
606
- }
607
-
608
- bool TurnClient::send_channel_data(uint16_t channel, const std::vector<uint8_t>& data) {
609
- if (!is_allocated()) {
610
- return false;
611
- }
612
-
613
- // Channel data format: 2-byte channel + 2-byte length + data (padded to 4 bytes)
614
- std::vector<uint8_t> msg;
615
- msg.reserve(TURN_CHANNEL_HEADER_SIZE + data.size() + 3);
616
-
617
- msg.push_back(static_cast<uint8_t>(channel >> 8));
618
- msg.push_back(static_cast<uint8_t>(channel));
619
- msg.push_back(static_cast<uint8_t>(data.size() >> 8));
620
- msg.push_back(static_cast<uint8_t>(data.size()));
621
- msg.insert(msg.end(), data.begin(), data.end());
622
-
623
- // Pad to 4-byte boundary
624
- while (msg.size() % 4 != 0) {
625
- msg.push_back(0);
626
- }
627
-
628
- int sent = send_udp_data(socket_, msg, config_.server, config_.port);
629
- return sent > 0;
630
- }
631
-
632
- std::optional<std::pair<StunMappedAddress, std::vector<uint8_t>>> TurnClient::receive_data(int timeout_ms) {
633
- if (!is_valid_socket(socket_)) {
634
- return std::nullopt;
635
- }
636
-
637
- Peer sender;
638
- auto data = receive_udp_data(socket_, STUN_MAX_MESSAGE_SIZE, sender, timeout_ms);
639
-
640
- if (data.empty()) {
641
- return std::nullopt;
642
- }
643
-
644
- // Check if it's a STUN message (Data indication)
645
- if (StunMessage::is_stun_message(data)) {
646
- auto msg = StunMessage::deserialize(data);
647
- if (msg && msg->type == StunMessageType::DataIndication) {
648
- auto peer_addr = msg->get_xor_peer_address();
649
- auto payload = msg->get_data();
650
-
651
- if (peer_addr && payload) {
652
- return std::make_pair(*peer_addr, *payload);
653
- }
654
- }
655
- return std::nullopt;
656
- }
657
-
658
- // Check if it's channel data
659
- if (data.size() >= TURN_CHANNEL_HEADER_SIZE) {
660
- uint16_t channel = (static_cast<uint16_t>(data[0]) << 8) | data[1];
661
-
662
- if (channel >= TURN_CHANNEL_MIN && channel <= TURN_CHANNEL_MAX) {
663
- uint16_t length = (static_cast<uint16_t>(data[2]) << 8) | data[3];
664
-
665
- if (data.size() >= TURN_CHANNEL_HEADER_SIZE + length) {
666
- auto peer = get_channel_peer(channel);
667
- if (peer) {
668
- std::vector<uint8_t> payload(data.begin() + TURN_CHANNEL_HEADER_SIZE,
669
- data.begin() + TURN_CHANNEL_HEADER_SIZE + length);
670
- return std::make_pair(*peer, payload);
671
- }
672
- }
673
- }
674
- }
675
-
676
- return std::nullopt;
677
- }
678
-
679
- void TurnClient::set_data_callback(TurnDataCallback callback) {
680
- data_callback_ = std::move(callback);
681
- }
682
-
683
- void TurnClient::set_state_callback(TurnStateCallback callback) {
684
- state_callback_ = std::move(callback);
685
- }
686
-
687
- void TurnClient::process_incoming() {
688
- auto result = receive_data(0); // Non-blocking
689
- if (result && data_callback_) {
690
- data_callback_(result->first, result->second);
691
- }
692
- }
693
-
694
- // ============================================================================
695
- // Refresh Thread
696
- // ============================================================================
697
-
698
- void TurnClient::start_refresh_thread() {
699
- if (refresh_running_) return;
700
-
701
- refresh_running_ = true;
702
- refresh_thread_ = std::thread(&TurnClient::refresh_loop, this);
703
- }
704
-
705
- void TurnClient::stop_refresh_thread() {
706
- refresh_running_ = false;
707
- if (refresh_thread_.joinable()) {
708
- refresh_thread_.join();
709
- }
710
- }
711
-
712
- void TurnClient::refresh_loop() {
713
- LOG_TURN_DEBUG("Refresh thread started");
714
-
715
- while (refresh_running_) {
716
- // Sleep for a bit
717
- for (int i = 0; i < 10 && refresh_running_; i++) {
718
- std::this_thread::sleep_for(std::chrono::seconds(1));
719
- }
720
-
721
- if (!refresh_running_) break;
722
-
723
- // Check if allocation needs refresh (refresh at 80% of lifetime)
724
- if (is_allocated()) {
725
- auto remaining = allocation_.remaining_lifetime();
726
- auto threshold = allocation_.lifetime * 0.2; // Refresh when 20% remaining
727
-
728
- if (remaining <= threshold) {
729
- LOG_TURN_DEBUG("Allocation lifetime low (" << remaining << "s), refreshing");
730
- refresh();
731
- }
732
- }
733
-
734
- // Refresh permissions and channels
735
- {
736
- std::lock_guard<std::mutex> lock(mutex_);
737
-
738
- // Clean up expired permissions
739
- for (auto it = permissions_.begin(); it != permissions_.end();) {
740
- if (it->second.is_expired()) {
741
- it = permissions_.erase(it);
742
- } else {
743
- ++it;
744
- }
745
- }
746
-
747
- // Clean up expired channels
748
- for (auto it = channels_.begin(); it != channels_.end();) {
749
- if (it->second.is_expired()) {
750
- peer_to_channel_.erase(peer_key(it->second.peer_address));
751
- it = channels_.erase(it);
752
- } else {
753
- ++it;
754
- }
755
- }
756
- }
757
- }
758
-
759
- LOG_TURN_DEBUG("Refresh thread stopped");
760
- }
761
-
762
- } // namespace librats