private void ReceiveCallback(IAsyncResult ar) { SSUSession session = null; try { EndPoint ep = RemoteEP; var size = MySocket.EndReceiveFrom(ar, ref ep); if (ep.AddressFamily != AddressFamily.InterNetwork && (!SessionLayer.RouterContext.Inst.UseIpV6 || ep.AddressFamily != AddressFamily.InterNetworkV6)) { return; // TODO: Add IPV6 } if (size <= 37) { Logging.LogDebugData($"SSU Recv: {size} bytes [0x{size:X}] from {ep} (hole punch, ignored)"); return; } var sessionendpoint = (IPEndPoint)ep; Logging.LogDebugData($"SSU Recv: {size} bytes [0x{size:X}] from {ep}"); lock ( Sessions ) { if (!Sessions.ContainsKey(sessionendpoint)) { if (IPFilter.IsFiltered(((IPEndPoint)ep).Address)) { Logging.LogTransport($"SSUHost ReceiveCallback: IPAddress {sessionendpoint} is blocked. {size} bytes."); return; } ++IncommingConnectionAttempts; Logging.LogTransport($"SSUHost: incoming connection " + $"from {sessionendpoint} created."); session = new SSUSession( this, Send, (IPEndPoint)ep, MyRouterContext); Sessions[sessionendpoint] = session; Logging.LogTransport($"SSUHost: incoming connection " + $"{session.DebugId} from {sessionendpoint} created."); NeedCpu(session); ConnectionCreated?.Invoke(session); } else { session = Sessions[sessionendpoint]; } } var localbuffer = BufRefLen.Clone(ReceiveBuf, 0, size); #if DEBUG Stopwatch Stopwatch1 = new Stopwatch(); Stopwatch1.Start(); #endif try { session.Receive(localbuffer); } catch (ThreadAbortException taex) { AddFailedSession(session); Logging.Log(taex); } catch (ThreadInterruptedException tiex) { AddFailedSession(session); Logging.Log(tiex); } catch (ChecksumFailureException cfex) { AddFailedSession(session); Logging.Log(cfex); } catch (SignatureCheckFailureException scex) { AddFailedSession(session); Logging.Log(scex); } catch (FailedToConnectException fcex) { AddFailedSession(session); #if LOG_MUCH_TRANSPORT Logging.LogTransport(fcex); #endif if (session != null) { NetDb.Inst.Statistics.FailedToConnect(session.RemoteRouterIdentity.IdentHash); session.RaiseException(fcex); } } #if DEBUG Stopwatch1.Stop(); if (Stopwatch1.ElapsedMilliseconds > SessionCallWarningLevelMilliseconds) { Logging.LogTransport( $"SSUHost ReceiveCallback: WARNING Session {session} used {Stopwatch1.ElapsedMilliseconds}ms cpu."); } #endif } catch (Exception ex) { AddFailedSession(session); Logging.Log(ex); if (session != null && session.RemoteRouterIdentity != null && NetDb.Inst != null) { NetDb.Inst.Statistics.DestinationInformationFaulty(session.RemoteRouterIdentity.IdentHash); session.RaiseException(ex); } } finally { RemoteEP = LocalEP; MySocket.BeginReceiveFrom(ReceiveBuf, 0, ReceiveBuf.Length, SocketFlags.None, ref RemoteEP, new AsyncCallback(ReceiveCallback), MySocket); } }
private void ReceiveCallback(IAsyncResult ar) { SSUSession session = null; try { EndPoint ep = RemoteEP; var size = MySocket.EndReceiveFrom(ar, ref ep); if (ep.AddressFamily != AddressFamily.InterNetwork) { return; // TODO: Add IPV6 } if (size <= 37) { #if LOG_ALL_TRANSPORT DebugUtils.Log(string.Format("SSU Recv: {0} bytes [0x{0:X}] from {1} (hole punch, ignored)", size, ep)); #endif return; } var key = (IPEndPoint)ep; #if LOG_ALL_TRANSPORT DebugUtils.Log(string.Format("SSU Recv: {0} bytes [0x{0:X}] from {1}", size, ep)); #endif lock ( Sessions ) { if (!Sessions.ContainsKey(key)) { if (IPFilter.IsFiltered(((IPEndPoint)ep).Address)) { DebugUtils.LogDebug(() => string.Format("SSUHost ReceiveCallback: IPAddress {0} is blocked. {1} bytes.", key, size)); return; } ++IncommingConnectionAttempts; session = new SSUSession(this, (IPEndPoint)ep, MTUProvider, MyRouterContext); Sessions[key] = session; DebugUtils.LogDebug("SSUHost: incoming connection " + session.DebugId + " from " + key.ToString() + " created."); NeedCpu(session); if (ConnectionCreated != null) { ConnectionCreated(session); } } else { session = Sessions[key]; } } var localbuffer = BufRefLen.Clone(ReceiveBuf, 0, size); #if DEBUG Stopwatch Stopwatch1 = new Stopwatch(); Stopwatch1.Start(); #endif try { session.Receive(localbuffer); } catch (ThreadAbortException taex) { AddFailedSession(session); DebugUtils.Log(taex); } catch (ThreadInterruptedException tiex) { AddFailedSession(session); DebugUtils.Log(tiex); } catch (ChecksumFailureException cfex) { AddFailedSession(session); DebugUtils.Log(cfex); } catch (SignatureCheckFailureException scex) { AddFailedSession(session); DebugUtils.Log(scex); } catch (FailedToConnectException fcex) { AddFailedSession(session); #if LOG_ALL_TRANSPORT DebugUtils.Log(fcex); #endif if (session != null) { NetDb.Inst.Statistics.FailedToConnect(session.RemoteRouterIdentity.IdentHash); session.RaiseException(fcex); } } #if DEBUG Stopwatch1.Stop(); if (Stopwatch1.ElapsedMilliseconds > SessionCallWarningLevelMilliseconds) { DebugUtils.LogDebug(() => string.Format("SSUHost ReceiveCallback: WARNING Session {0} used {1}ms cpu.", session, Stopwatch1.ElapsedMilliseconds)); } #endif } catch (Exception ex) { AddFailedSession(session); DebugUtils.Log(ex); if (session != null && session.RemoteRouterIdentity != null && NetDb.Inst != null) { NetDb.Inst.Statistics.DestinationInformationFaulty(session.RemoteRouterIdentity.IdentHash); session.RaiseException(ex); } } finally { RemoteEP = LocalEP; MySocket.BeginReceiveFrom(ReceiveBuf, 0, ReceiveBuf.Length, SocketFlags.None, ref RemoteEP, new AsyncCallback(ReceiveCallback), MySocket); } }