RouterComponentSystem.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Runtime.InteropServices;
  5. namespace ET
  6. {
  7. [FriendClass(typeof (RouterComponent))]
  8. [FriendClass(typeof (RouterNode))]
  9. public static class RouterComponentSystem
  10. {
  11. [ObjectSystem]
  12. public class RouterComponentAwakeSystem: AwakeSystem<RouterComponent, IPEndPoint, string>
  13. {
  14. public override void Awake(RouterComponent self, IPEndPoint outerAddress, string innerIP)
  15. {
  16. self.OuterSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
  17. self.OuterSocket.Bind(outerAddress);
  18. self.OuterSocket.SendBufferSize = 16 * Kcp.OneM;
  19. self.OuterSocket.ReceiveBufferSize = 16 * Kcp.OneM;
  20. self.InnerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
  21. self.InnerSocket.Bind(new IPEndPoint(IPAddress.Parse(innerIP), 0));
  22. self.InnerSocket.SendBufferSize = 16 * Kcp.OneM;
  23. self.InnerSocket.ReceiveBufferSize = 16 * Kcp.OneM;
  24. if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
  25. {
  26. const uint IOC_IN = 0x80000000;
  27. const uint IOC_VENDOR = 0x18000000;
  28. uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
  29. self.OuterSocket.IOControl((int) SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null);
  30. self.InnerSocket.IOControl((int) SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null);
  31. }
  32. }
  33. }
  34. [ObjectSystem]
  35. public class RouterComponentDestroySystem: DestroySystem<RouterComponent>
  36. {
  37. public override void Destroy(RouterComponent self)
  38. {
  39. self.OuterSocket.Dispose();
  40. self.InnerSocket.Dispose();
  41. self.OuterNodes.Clear();
  42. self.IPEndPoint = null;
  43. }
  44. }
  45. [ObjectSystem]
  46. public class RouterComponentUpdateSystem: UpdateSystem<RouterComponent>
  47. {
  48. public override void Update(RouterComponent self)
  49. {
  50. long timeNow = TimeHelper.ClientNow();
  51. self.RecvOuter(timeNow);
  52. self.RecvInner(timeNow);
  53. // 每秒钟检查一次
  54. if (timeNow - self.LastCheckTime > 1000)
  55. {
  56. self.CheckConnectTimeout(timeNow);
  57. }
  58. }
  59. }
  60. private static IPEndPoint CloneAddress(this RouterComponent self)
  61. {
  62. IPEndPoint ipEndPoint = (IPEndPoint) self.IPEndPoint;
  63. return new IPEndPoint(ipEndPoint.Address, ipEndPoint.Port);
  64. }
  65. // 接收udp消息
  66. private static void RecvOuter(this RouterComponent self, long timeNow)
  67. {
  68. while (self.OuterSocket != null && self.OuterSocket.Available > 0)
  69. {
  70. try
  71. {
  72. int messageLength = self.OuterSocket.ReceiveFrom(self.Cache, ref self.IPEndPoint);
  73. self.RecvOuterHandler(messageLength, timeNow);
  74. }
  75. catch (Exception e)
  76. {
  77. Log.Error(e);
  78. }
  79. }
  80. }
  81. private static void CheckConnectTimeout(this RouterComponent self, long timeNow)
  82. {
  83. // 检查连接过程超时
  84. using (ListComponent<long> listComponent = ListComponent<long>.Create())
  85. {
  86. foreach (var kv in self.ConnectIdNodes)
  87. {
  88. if (timeNow < kv.Value.LastRecvOuterTime + 10 * 1000)
  89. {
  90. continue;
  91. }
  92. listComponent.Add(kv.Value.Id);
  93. }
  94. foreach (long id in listComponent)
  95. {
  96. self.OnError(id, ErrorCore.ERR_KcpRouterConnectFail);
  97. }
  98. }
  99. // 外网消息超时就断开,内网因为会一直重发,没有重连之前内网连接一直存在,会导致router一直收到内网消息
  100. using (ListComponent<long> listComponent = ListComponent<long>.Create())
  101. {
  102. foreach (var kv in self.OuterNodes)
  103. {
  104. // 比session超时应该多10秒钟
  105. if (timeNow < kv.Value.LastRecvOuterTime + ConstValue.SessionTimeoutTime + 10 * 1000)
  106. {
  107. continue;
  108. }
  109. listComponent.Add(kv.Value.Id);
  110. }
  111. foreach (long id in listComponent)
  112. {
  113. self.OnError(id, ErrorCore.ERR_KcpRouterTimeout);
  114. }
  115. }
  116. }
  117. private static void RecvInner(this RouterComponent self, long timeNow)
  118. {
  119. while (self.InnerSocket != null && self.InnerSocket.Available > 0)
  120. {
  121. try
  122. {
  123. int messageLength = self.InnerSocket.ReceiveFrom(self.Cache, ref self.IPEndPoint);
  124. self.RecvInnerHandler(messageLength, timeNow);
  125. }
  126. catch (Exception e)
  127. {
  128. Log.Error(e);
  129. }
  130. }
  131. }
  132. private static void RecvOuterHandler(this RouterComponent self, int messageLength, long timeNow)
  133. {
  134. // 长度小于1,不是正常的消息
  135. if (messageLength < 1)
  136. {
  137. return;
  138. }
  139. // accept
  140. byte flag = self.Cache[0];
  141. switch (flag)
  142. {
  143. case KcpProtocalType.RouterReconnectSYN:
  144. {
  145. if (messageLength < 13)
  146. {
  147. break;
  148. }
  149. uint outerConn = BitConverter.ToUInt32(self.Cache, 1);
  150. uint innerConn = BitConverter.ToUInt32(self.Cache, 5);
  151. uint connectId = BitConverter.ToUInt32(self.Cache, 9);
  152. string realAddress = self.Cache.ToStr(13, messageLength - 13);
  153. RouterNode routerNode;
  154. // RouterAck之后ConnectIdNodes会删除,加入到OuterNodes中来
  155. if (!self.OuterNodes.TryGetValue(outerConn, out routerNode))
  156. {
  157. self.ConnectIdNodes.TryGetValue(connectId, out routerNode);
  158. if (routerNode == null)
  159. {
  160. Log.Info($"router create reconnect: {self.IPEndPoint} {realAddress} {connectId} {outerConn} {innerConn}");
  161. routerNode = self.New(realAddress, connectId, outerConn, innerConn, self.CloneAddress());
  162. // self.OuterNodes 这里不能add,因为还没验证完成,要在RouterAck中加入
  163. }
  164. }
  165. if (routerNode.ConnectId != connectId)
  166. {
  167. Log.Warning($"kcp router router reconnect connectId diff1: {routerNode.SyncIpEndPoint} {(IPEndPoint) self.IPEndPoint}");
  168. break;
  169. }
  170. // 不是自己的,outerConn冲突, 直接break,也就是说这个软路由上有个跟自己outerConn冲突的连接,就不能连接了
  171. // 这个路由连接不上,客户端会换个软路由,所以没关系
  172. if (routerNode.InnerConn != innerConn)
  173. {
  174. Log.Warning($"kcp router router reconnect inner conn diff1: {routerNode.SyncIpEndPoint} {(IPEndPoint) self.IPEndPoint}");
  175. break;
  176. }
  177. if (routerNode.OuterConn != outerConn)
  178. {
  179. Log.Warning($"kcp router router reconnect outer conn diff1: {routerNode.SyncIpEndPoint} {(IPEndPoint) self.IPEndPoint}");
  180. break;
  181. }
  182. // 校验ip,连接过程中ip不能变化
  183. if (!Equals(routerNode.SyncIpEndPoint, self.IPEndPoint))
  184. {
  185. Log.Warning($"kcp router syn ip is diff1: {routerNode.SyncIpEndPoint} {(IPEndPoint) self.IPEndPoint}");
  186. break;
  187. }
  188. // 校验内网地址
  189. if (routerNode.InnerAddress != realAddress)
  190. {
  191. Log.Warning($"router sync error2: {routerNode.OuterConn} {routerNode.InnerAddress} {outerConn} {realAddress}");
  192. break;
  193. }
  194. if (++routerNode.RouterSyncCount > 40)
  195. {
  196. self.OnError(routerNode.Id, ErrorCore.ERR_KcpRouterRouterSyncCountTooMuchTimes);
  197. break;
  198. }
  199. // 转发到内网
  200. self.Cache.WriteTo(0, KcpProtocalType.RouterReconnectSYN);
  201. self.Cache.WriteTo(1, outerConn);
  202. self.Cache.WriteTo(5, innerConn);
  203. self.Cache.WriteTo(9, connectId);
  204. self.InnerSocket.SendTo(self.Cache, 0, 13, SocketFlags.None, routerNode.InnerIpEndPoint);
  205. if (!routerNode.CheckOuterCount(timeNow))
  206. {
  207. self.OnError(routerNode.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
  208. }
  209. break;
  210. }
  211. case KcpProtocalType.RouterSYN:
  212. {
  213. if (messageLength < 13)
  214. {
  215. break;
  216. }
  217. uint outerConn = BitConverter.ToUInt32(self.Cache, 1);
  218. uint innerConn = BitConverter.ToUInt32(self.Cache, 5);
  219. uint connectId = BitConverter.ToUInt32(self.Cache, 9);
  220. string realAddress = self.Cache.ToStr(13, messageLength - 13);
  221. RouterNode routerNode;
  222. self.ConnectIdNodes.TryGetValue(connectId, out routerNode);
  223. if (routerNode == null)
  224. {
  225. outerConn = RandomHelper.RandUInt32();
  226. routerNode = self.New(realAddress, connectId, outerConn, innerConn, self.CloneAddress());
  227. Log.Info($"router create: {realAddress} {connectId} {outerConn} {innerConn} {routerNode.SyncIpEndPoint}");
  228. self.OuterNodes.Add(routerNode.OuterConn, routerNode);
  229. }
  230. if (++routerNode.RouterSyncCount > 40)
  231. {
  232. self.OnError(routerNode.Id, ErrorCore.ERR_KcpRouterRouterSyncCountTooMuchTimes);
  233. break;
  234. }
  235. // 校验ip,连接过程中ip不能变化
  236. if (!Equals(routerNode.SyncIpEndPoint, self.IPEndPoint))
  237. {
  238. Log.Warning($"kcp router syn ip is diff1: {routerNode.SyncIpEndPoint} {self.IPEndPoint}");
  239. break;
  240. }
  241. // 校验内网地址
  242. if (routerNode.InnerAddress != realAddress)
  243. {
  244. Log.Warning($"router sync error2: {routerNode.OuterConn} {routerNode.InnerAddress} {outerConn} {realAddress}");
  245. break;
  246. }
  247. self.Cache.WriteTo(0, KcpProtocalType.RouterACK);
  248. self.Cache.WriteTo(1, routerNode.InnerConn);
  249. self.Cache.WriteTo(5, routerNode.OuterConn);
  250. self.OuterSocket.SendTo(self.Cache, 0, 9, SocketFlags.None, routerNode.SyncIpEndPoint);
  251. if (!routerNode.CheckOuterCount(timeNow))
  252. {
  253. self.OnError(routerNode.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
  254. }
  255. break;
  256. }
  257. case KcpProtocalType.SYN:
  258. {
  259. // 长度!=13,不是accpet消息
  260. if (messageLength != 9)
  261. {
  262. break;
  263. }
  264. uint outerConn = BitConverter.ToUInt32(self.Cache, 1); // remote
  265. uint innerConn = BitConverter.ToUInt32(self.Cache, 5);
  266. if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouter))
  267. {
  268. Log.Warning($"kcp router syn not found outer nodes: {outerConn} {innerConn}");
  269. break;
  270. }
  271. if (++kcpRouter.SyncCount > 40)
  272. {
  273. self.OnError(kcpRouter.Id, ErrorCore.ERR_KcpRouterSyncCountTooMuchTimes);
  274. break;
  275. }
  276. // 校验ip,连接过程中ip不能变化
  277. IPEndPoint ipEndPoint = (IPEndPoint) self.IPEndPoint;
  278. if (!Equals(kcpRouter.SyncIpEndPoint.Address, ipEndPoint.Address))
  279. {
  280. Log.Warning($"kcp router syn ip is diff3: {kcpRouter.SyncIpEndPoint.Address} {ipEndPoint.Address}");
  281. break;
  282. }
  283. kcpRouter.LastRecvOuterTime = timeNow;
  284. kcpRouter.OuterIpEndPoint = self.CloneAddress();
  285. // 转发到内网, 带上客户端的地址
  286. self.Cache.WriteTo(0, KcpProtocalType.SYN);
  287. self.Cache.WriteTo(1, outerConn);
  288. self.Cache.WriteTo(5, innerConn);
  289. byte[] addressBytes = ipEndPoint.ToString().ToByteArray();
  290. Array.Copy(addressBytes, 0, self.Cache, 9, addressBytes.Length);
  291. Log.Info($"kcp router syn: {outerConn} {innerConn} {kcpRouter.InnerIpEndPoint} {kcpRouter.OuterIpEndPoint}");
  292. self.InnerSocket.SendTo(self.Cache, 0, 9 + addressBytes.Length, SocketFlags.None, kcpRouter.InnerIpEndPoint);
  293. if (!kcpRouter.CheckOuterCount(timeNow))
  294. {
  295. self.OnError(kcpRouter.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
  296. }
  297. break;
  298. }
  299. case KcpProtocalType.FIN: // 断开
  300. {
  301. // 长度!=13,不是DisConnect消息
  302. if (messageLength != 13)
  303. {
  304. break;
  305. }
  306. uint outerConn = BitConverter.ToUInt32(self.Cache, 1);
  307. uint innerConn = BitConverter.ToUInt32(self.Cache, 5);
  308. if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouter))
  309. {
  310. Log.Warning($"kcp router outer fin not found outer nodes: {outerConn} {innerConn}");
  311. break;
  312. }
  313. // 比对innerConn
  314. if (kcpRouter.InnerConn != innerConn)
  315. {
  316. Log.Warning($"router node innerConn error: {innerConn} {outerConn} {kcpRouter.Status}");
  317. break;
  318. }
  319. kcpRouter.LastRecvOuterTime = timeNow;
  320. Log.Info($"kcp router outer fin: {outerConn} {innerConn} {kcpRouter.InnerIpEndPoint}");
  321. self.InnerSocket.SendTo(self.Cache, 0, messageLength, SocketFlags.None, kcpRouter.InnerIpEndPoint);
  322. if (!kcpRouter.CheckOuterCount(timeNow))
  323. {
  324. self.OnError(kcpRouter.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
  325. }
  326. break;
  327. }
  328. case KcpProtocalType.MSG:
  329. {
  330. // 长度<9,不是Msg消息
  331. if (messageLength < 9)
  332. {
  333. break;
  334. }
  335. // 处理chanel
  336. uint outerConn = BitConverter.ToUInt32(self.Cache, 1); // remote
  337. uint innerConn = BitConverter.ToUInt32(self.Cache, 5); // local
  338. if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouter))
  339. {
  340. Log.Warning($"kcp router msg not found outer nodes: {outerConn} {innerConn}");
  341. break;
  342. }
  343. if (kcpRouter.Status != RouterStatus.Msg)
  344. {
  345. Log.Warning($"router node status error: {innerConn} {outerConn} {kcpRouter.Status}");
  346. break;
  347. }
  348. // 比对innerConn
  349. if (kcpRouter.InnerConn != innerConn)
  350. {
  351. Log.Warning($"router node innerConn error: {innerConn} {outerConn} {kcpRouter.Status}");
  352. break;
  353. }
  354. // 重连的时候,没有经过syn阶段,可能没有设置OuterIpEndPoint,重连请求Router的Socket跟发送消息的Socket不是同一个,所以udp出来的公网地址可能会变化
  355. if (!Equals(kcpRouter.OuterIpEndPoint, self.IPEndPoint))
  356. {
  357. kcpRouter.OuterIpEndPoint = self.CloneAddress();
  358. }
  359. kcpRouter.LastRecvOuterTime = timeNow;
  360. self.InnerSocket.SendTo(self.Cache, 0, messageLength, SocketFlags.None, kcpRouter.InnerIpEndPoint);
  361. if (!kcpRouter.CheckOuterCount(timeNow))
  362. {
  363. self.OnError(kcpRouter.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
  364. }
  365. break;
  366. }
  367. }
  368. }
  369. private static void RecvInnerHandler(this RouterComponent self, int messageLength, long timeNow)
  370. {
  371. // 长度小于1,不是正常的消息
  372. if (messageLength < 1)
  373. {
  374. return;
  375. }
  376. // accept
  377. byte flag = self.Cache[0];
  378. switch (flag)
  379. {
  380. case KcpProtocalType.RouterReconnectACK:
  381. {
  382. uint innerConn = BitConverter.ToUInt32(self.Cache, 1);
  383. uint outerConn = BitConverter.ToUInt32(self.Cache, 5);
  384. uint connectId = BitConverter.ToUInt32(self.Cache, 9);
  385. if (!self.ConnectIdNodes.TryGetValue(connectId, out RouterNode kcpRouterNode))
  386. {
  387. Log.Warning($"router node error: {innerConn} {connectId}");
  388. break;
  389. }
  390. // 必须校验innerConn,防止伪造
  391. if (innerConn != kcpRouterNode.InnerConn)
  392. {
  393. Log.Warning(
  394. $"router node innerConn error: {innerConn} {kcpRouterNode.InnerConn} {outerConn} {kcpRouterNode.OuterConn} {kcpRouterNode.Status}");
  395. break;
  396. }
  397. // 必须校验outerConn,防止伪造
  398. if (outerConn != kcpRouterNode.OuterConn)
  399. {
  400. Log.Warning(
  401. $"router node outerConn error: {innerConn} {kcpRouterNode.InnerConn} {outerConn} {kcpRouterNode.OuterConn} {kcpRouterNode.Status}");
  402. break;
  403. }
  404. kcpRouterNode.Status = RouterStatus.Msg;
  405. kcpRouterNode.LastRecvInnerTime = timeNow;
  406. // 校验成功才加到outerNodes中, 如果这里有冲突,外网将连接失败,不过几率极小
  407. if (!self.OuterNodes.ContainsKey(outerConn))
  408. {
  409. self.OuterNodes.Add(outerConn, kcpRouterNode);
  410. self.ConnectIdNodes.Remove(connectId);
  411. }
  412. // 转发出去
  413. self.Cache.WriteTo(0, KcpProtocalType.RouterReconnectACK);
  414. self.Cache.WriteTo(1, kcpRouterNode.InnerConn);
  415. self.Cache.WriteTo(5, kcpRouterNode.OuterConn);
  416. Log.Info($"kcp router RouterAck: {outerConn} {innerConn} {kcpRouterNode.SyncIpEndPoint}");
  417. self.OuterSocket.SendTo(self.Cache, 0, 9, SocketFlags.None, kcpRouterNode.SyncIpEndPoint);
  418. break;
  419. }
  420. case KcpProtocalType.ACK:
  421. {
  422. uint innerConn = BitConverter.ToUInt32(self.Cache, 1); // remote
  423. uint outerConn = BitConverter.ToUInt32(self.Cache, 5); // local
  424. if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouterNode))
  425. {
  426. Log.Warning($"kcp router ack not found outer nodes: {outerConn} {innerConn}");
  427. break;
  428. }
  429. kcpRouterNode.Status = RouterStatus.Msg;
  430. kcpRouterNode.InnerConn = innerConn;
  431. kcpRouterNode.LastRecvInnerTime = timeNow;
  432. // 转发出去
  433. Log.Info($"kcp router ack: {outerConn} {innerConn} {kcpRouterNode.OuterIpEndPoint}");
  434. self.OuterSocket.SendTo(self.Cache, 0, messageLength, SocketFlags.None, kcpRouterNode.OuterIpEndPoint);
  435. break;
  436. }
  437. case KcpProtocalType.FIN: // 断开
  438. {
  439. // 长度!=13,不是DisConnect消息
  440. if (messageLength != 13)
  441. {
  442. break;
  443. }
  444. uint innerConn = BitConverter.ToUInt32(self.Cache, 1);
  445. uint outerConn = BitConverter.ToUInt32(self.Cache, 5);
  446. if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouterNode))
  447. {
  448. Log.Warning($"kcp router inner fin not found outer nodes: {outerConn} {innerConn}");
  449. break;
  450. }
  451. // 比对innerConn
  452. if (kcpRouterNode.InnerConn != innerConn)
  453. {
  454. Log.Warning($"router node innerConn error: {innerConn} {outerConn} {kcpRouterNode.Status}");
  455. break;
  456. }
  457. // 重连,这个字段可能为空,需要客户端发送消息上来才能设置
  458. if (kcpRouterNode.OuterIpEndPoint == null)
  459. {
  460. break;
  461. }
  462. kcpRouterNode.LastRecvInnerTime = timeNow;
  463. Log.Info($"kcp router inner fin: {outerConn} {innerConn} {kcpRouterNode.OuterIpEndPoint}");
  464. self.OuterSocket.SendTo(self.Cache, 0, messageLength, SocketFlags.None, kcpRouterNode.OuterIpEndPoint);
  465. break;
  466. }
  467. case KcpProtocalType.MSG:
  468. {
  469. // 长度<9,不是Msg消息
  470. if (messageLength < 9)
  471. {
  472. break;
  473. }
  474. // 处理chanel
  475. uint innerConn = BitConverter.ToUInt32(self.Cache, 1); // remote
  476. uint outerConn = BitConverter.ToUInt32(self.Cache, 5); // local
  477. if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouterNode))
  478. {
  479. Log.Warning($"kcp router inner msg not found outer nodes: {outerConn} {innerConn}");
  480. break;
  481. }
  482. // 比对innerConn
  483. if (kcpRouterNode.InnerConn != innerConn)
  484. {
  485. Log.Warning($"router node innerConn error: {innerConn} {outerConn} {kcpRouterNode.Status}");
  486. break;
  487. }
  488. // 重连,这个字段可能为空,需要客户端发送消息上来才能设置
  489. if (kcpRouterNode.OuterIpEndPoint == null)
  490. {
  491. break;
  492. }
  493. kcpRouterNode.LastRecvInnerTime = timeNow;
  494. self.OuterSocket.SendTo(self.Cache, 0, messageLength, SocketFlags.None, kcpRouterNode.OuterIpEndPoint);
  495. break;
  496. }
  497. }
  498. }
  499. public static RouterNode Get(this RouterComponent self, uint outerConn)
  500. {
  501. RouterNode routerNode = null;
  502. self.OuterNodes.TryGetValue(outerConn, out routerNode);
  503. return routerNode;
  504. }
  505. private static RouterNode New(this RouterComponent self, string innerAddress, uint connectId, uint outerConn, uint innerConn, IPEndPoint syncEndPoint)
  506. {
  507. RouterNode routerNode = self.AddChild<RouterNode>();
  508. routerNode.ConnectId = connectId;
  509. routerNode.OuterConn = outerConn;
  510. routerNode.InnerConn = innerConn;
  511. routerNode.InnerIpEndPoint = NetworkHelper.ToIPEndPoint(innerAddress);
  512. routerNode.SyncIpEndPoint = syncEndPoint;
  513. routerNode.InnerAddress = innerAddress;
  514. routerNode.LastRecvInnerTime = TimeHelper.ClientNow();
  515. self.ConnectIdNodes.Add(connectId, routerNode);
  516. routerNode.Status = RouterStatus.Sync;
  517. Log.Info($"router new: outerConn: {outerConn} innerConn: {innerConn} {syncEndPoint}");
  518. return routerNode;
  519. }
  520. public static void OnError(this RouterComponent self, long id, int error)
  521. {
  522. RouterNode routerNode = self.GetChild<RouterNode>(id);
  523. if (routerNode == null)
  524. {
  525. return;
  526. }
  527. Log.Info($"router node remove: {routerNode.OuterConn} {routerNode.InnerConn} {error}");
  528. self.Remove(id);
  529. }
  530. private static void Remove(this RouterComponent self, long id)
  531. {
  532. RouterNode routerNode = self.GetChild<RouterNode>(id);
  533. if (routerNode == null)
  534. {
  535. return;
  536. }
  537. self.OuterNodes.Remove(routerNode.OuterConn);
  538. RouterNode connectRouterNode;
  539. if (self.ConnectIdNodes.TryGetValue(routerNode.ConnectId, out connectRouterNode))
  540. {
  541. if (connectRouterNode.Id == routerNode.Id)
  542. {
  543. self.ConnectIdNodes.Remove(routerNode.ConnectId);
  544. }
  545. }
  546. Log.Info($"router remove: {routerNode.Id} outerConn: {routerNode.OuterConn} innerConn: {routerNode.InnerConn}");
  547. routerNode.Dispose();
  548. }
  549. }
  550. }