Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        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);
            }
        }