示例#1
0
        void Receive_Ping(G2ReceivedPacket packet)
        {
            Core.ServiceBandwidth[Core.DhtServiceID].InPerSec += packet.Root.Data.Length;

            Ping ping = Ping.Decode(packet);

            bool lanIP       = Utilities.IsLocalIP(packet.Source.IP);
            bool validSource = (!lanIP || LanMode && lanIP);

            // set local IP
            SetLocalIP(ping.RemoteIP, packet);


            // check loop back
            if (ping.Source != null && Local.Equals(ping.Source))
            {
                if (packet.ReceivedTcp)
                {
                    packet.Tcp.CleanClose("Loopback connection");
                }

                return;
            }

            // dont send back pong if received tunneled and no longer need to use lookup proxies
            // remote would only send tunneled ping if UseGlobalProxies published info on network
            // let our lookup address expire from remote's routing table
            if (packet.Tunneled && !UseLookupProxies)
            {
                return;
            }

            // setup pong reply
            Pong pong = new Pong();

            if (ping.Source != null)
            {
                pong.Source = GetLocalSource();
            }

            if (ping.RemoteIP != null)
            {
                pong.RemoteIP = packet.Source.IP;
            }

            if (!IsLookup && Core.Context.SignedUpdate != null && Core.Context.SignedUpdate.Loaded)
            {
                pong.Version = Core.Context.SignedUpdate.SequentialVersion;
            }


            int sentBytes = 0;

            // received tcp
            if (packet.ReceivedTcp)
            {
                if (ping.Source == null)
                {
                    packet.Tcp.SendPacket(pong);
                    return;
                }

                if (validSource)
                {
                    if (ping.Source.Firewall == FirewallType.Open)
                    {
                        Routing.Add(new DhtContact(ping.Source, packet.Source.IP));
                    }

                    // received incoming tcp means we are not firewalled
                    if (!packet.Tcp.Outbound)
                    {
                        // done here to prevent setting open for loopback tcp connection
                        Core.SetFirewallType(FirewallType.Open);
                        pong.Source.Firewall = FirewallType.Open;
                    }
                }

                // check if already connected
                if (packet.Tcp.Proxy == ProxyType.Unset && TcpControl.GetProxy(ping.Source) != null)
                {
                    packet.Tcp.CleanClose("Dupelicate Connection");
                    return;
                }

                packet.Tcp.UserID   = ping.Source.UserID;
                packet.Tcp.ClientID = ping.Source.ClientID;
                packet.Tcp.TcpPort  = ping.Source.TcpPort;
                packet.Tcp.UdpPort  = ping.Source.UdpPort;

                // if inbound connection, to our open host, and haven't checked fw yet
                if (!packet.Tcp.Outbound &&
                    ping.Source.Firewall != FirewallType.Open &&
                    !packet.Tcp.CheckedFirewall)
                {
                    TcpControl.MakeOutbound(packet.Source, ping.Source.TcpPort, "check firewall");
                    packet.Tcp.CheckedFirewall = true;
                }

                pong.Direct = true;
                sentBytes   = packet.Tcp.SendPacket(pong);

                // dont send close if proxies maxxed yet, because their id might be closer than current proxies
            }

            // ping received udp or tunneled
            else
            {
                if (validSource)
                {
                    // received udp traffic, we must be behind a NAT at least
                    if (Core.Firewall == FirewallType.Blocked && !packet.Tunneled)
                    {
                        Core.SetFirewallType(FirewallType.NAT);
                    }

                    Routing.TryAdd(packet, ping.Source);
                }

                // if received over lan, the port isn't set
                if (packet.Source.UdpPort == 0)
                {
                    packet.Source.UdpPort = ping.Source.UdpPort;
                }

                // send pong
                sentBytes = SendPacket(packet.Source, pong);
            }

            Core.ServiceBandwidth[Core.DhtServiceID].OutPerSec += sentBytes;
        }