Esempio n. 1
0
        public void ReceiveRequest(G2ReceivedPacket packet)
        {
            SearchReq request = SearchReq.Decode(packet);

            // loopback
            if (Network.Local.Equals(request.Source))
            {
                return;
            }

            if (Core.ServiceBandwidth.ContainsKey(request.Service))
            {
                Core.ServiceBandwidth[request.Service].InPerSec += packet.Root.Data.Length;
            }

            if (packet.ReceivedTcp && request.SearchID != 0)
            {
                // request from blocked node
                if (packet.Tcp.Proxy == ProxyType.ClientBlocked)
                {
                    int proxySearches = 0;
                    lock (Active)
                        foreach (DhtSearch search in Active)
                        {
                            if (search.ProxyTcp == packet.Tcp)
                            {
                                proxySearches++;

                                if (request.EndProxySearch && search.SearchID == request.SearchID)
                                {
                                    search.FinishSearch("Proxied node finished search");
                                    return;
                                }
                            }
                        }

                    if (proxySearches < MAX_SEARCHES)
                    {
                        DhtSearch search = new DhtSearch(this, request.TargetID, "Proxy", request.Service, request.DataType);

                        search.Parameters = request.Parameters;
                        search.ProxyTcp   = packet.Tcp;
                        search.SearchID   = request.SearchID;
                        search.Activate();
                        Active.Add(search);
                        search.Log("Active - Proxy Search");
                    }

                    // continue processing request and send local results
                }

                // request from proxy server
                if (packet.Tcp.Proxy == ProxyType.Server && request.EndProxySearch)
                {
                    lock (Active)
                        foreach (DhtSearch search in Active)
                        {
                            if (search.SearchID == request.SearchID)
                            {
                                if (!search.Finished)
                                {
                                    search.FinishSearch("Server finished search");
                                }
                            }
                        }
                }
            }


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


            // forward to proxied nodes
            foreach (TcpConnect socket in Network.TcpControl.ProxyClients)
            {
                // prevents incoming udp from proxy and being forwarded to same host tcp
                if (socket != packet.Tcp && !(packet.Source.UserID == socket.UserID && packet.Source.ClientID == socket.ClientID))
                {
                    request.FromAddress = packet.Source;

                    socket.SendPacket(request);
                }
            }



            // send ack
            bool sendNoResults = (request.SearchID != 0 || request.Service == Core.DhtServiceID) &&
                                 (packet.ReceivedUdp || packet.Tunneled);

            SearchAck ack = new SearchAck();

            ack.Source   = Network.GetLocalSource();
            ack.SearchID = request.SearchID;
            ack.Service  = request.Service;

            // search for connected proxy
            if (Network.TcpControl.ProxyMap.Values.Any(p => p.UserID == request.TargetID))
            {
                ack.Proxied = true;
            }

            // only send nodes from proxy server routing table
            if (request.Nodes && (packet.ReceivedUdp || packet.Tunneled))
            {
                ack.ContactList = Routing.Find(request.TargetID, 8);
            }


            // dont send an ack if behind a proxy server and no results
            if (!SearchEvent.Contains(request.Service, request.DataType))
            {
                if (sendNoResults)
                {
                    SendAck(packet, request, ack);
                }
            }

            else
            {
                List <byte[]> results = new List <byte[]>();
                SearchEvent[request.Service, request.DataType].Invoke(request.TargetID, request.Parameters, results);

                // if nothing found, still send ack with closer contacts
                if (results == null || results.Count == 0)
                {
                    if (sendNoResults)
                    {
                        SendAck(packet, request, ack);
                    }

                    return;
                }

                // if a direct search
                if (request.SearchID == 0)
                {
                    foreach (byte[] value in results)
                    {
                        Network.Store.Send_StoreReq(packet.Source, packet.Tcp, new DataReq(null, request.TargetID, request.Service, request.DataType, value));
                    }

                    return;
                }

                // else send normal search results
                int totalSize = 0;

                foreach (byte[] data in results)
                {
                    if (data.Length + totalSize > 1200)
                    {
                        SendAck(packet, request, ack);

                        ack.ValueList.Clear();
                        ack.ContactList.Clear(); // dont send twice
                        totalSize = 0;
                    }

                    ack.ValueList.Add(data);
                    totalSize += data.Length;
                }

                if (totalSize > 0)
                {
                    SendAck(packet, request, ack);
                }
            }
        }
Esempio n. 2
0
        public void SecondTimer()
        {
            // get active search count
            int searchCount = 0;

            lock (Active)
                foreach (DhtSearch search in Active)
                {
                    if (search.ProxyTcp == null || search.ProxyTcp.Proxy == ProxyType.Server)
                    {
                        searchCount++;
                    }
                }


            // if pending searches
            if (Network.Responsive) // only move from pending to active if network responsive
            {
                while (searchCount < MAX_SEARCHES && Pending.Count > 0)
                {
                    DhtSearch move = Pending[0];
                    searchCount++; // do here to get out of loop

                    if (move.Activate())
                    {
                        move.Log("Active");
                        Active.Add(move);
                        Pending.Remove(move);
                    }
                }
            }

            // pulse active searches
            List <DhtSearch> removeList = new List <DhtSearch>();

            lock (Active)
                foreach (DhtSearch search in Active)
                {
                    if (search.Finished)
                    {
                        removeList.Add(search);
                    }
                    else
                    {
                        search.SecondTimer();
                    }
                }

            // remove finished searches
            foreach (DhtSearch search in removeList)
            {
                if (Active.Contains(search))
                {
                    lock (Active)
                        Active.Remove(search);
                }

                if (Pending.Contains(search))
                {
                    lock (Pending)
                        Pending.Remove(search);
                }

                string log = "Finished";

                if (search.FoundValues.Count > 0)
                {
                    log += ", " + search.FoundValues.Count.ToString() + " Values Found";
                }

                if (search.FinishReason != null)
                {
                    log += ", " + search.FinishReason;
                }

                search.Log(log);
            }
        }
Esempio n. 3
0
        public void ReceiveRequest(G2ReceivedPacket packet)
        {
            SearchReq request = SearchReq.Decode(packet);

            // loopback
            if (Network.Local.Equals(request.Source))
                return;

            if (Core.ServiceBandwidth.ContainsKey(request.Service))
                Core.ServiceBandwidth[request.Service].InPerSec += packet.Root.Data.Length;

            if (packet.ReceivedTcp && request.SearchID != 0)
            {
                // request from blocked node
                if (packet.Tcp.Proxy == ProxyType.ClientBlocked)
                {
                    int proxySearches = 0;
                    lock (Active)
                        foreach (DhtSearch search in Active)
                            if (search.ProxyTcp == packet.Tcp)
                            {
                                proxySearches++;

                                if (request.EndProxySearch && search.SearchID == request.SearchID)
                                {
                                    search.FinishSearch("Proxied node finished search");
                                    return;
                                }
                            }

                    if (proxySearches < MAX_SEARCHES)
                    {
                        DhtSearch search = new DhtSearch(this, request.TargetID, "Proxy", request.Service, request.DataType);

                        search.Parameters = request.Parameters;
                        search.ProxyTcp = packet.Tcp;
                        search.SearchID = request.SearchID;
                        search.Activate();
                        Active.Add(search);
                        search.Log("Active - Proxy Search");
                    }

                    // continue processing request and send local results
                }

                // request from proxy server
                if (packet.Tcp.Proxy == ProxyType.Server && request.EndProxySearch)
                {
                    lock (Active)
                        foreach (DhtSearch search in Active)
                            if (search.SearchID == request.SearchID)
                                if( !search.Finished )
                                    search.FinishSearch("Server finished search");
                }
            }

            if (request.Source.Firewall == FirewallType.Open)
                Routing.Add(new DhtContact(request.Source, packet.Source.IP));

            // forward to proxied nodes
            foreach (TcpConnect socket in Network.TcpControl.ProxyClients)
                // prevents incoming udp from proxy and being forwarded to same host tcp
                if(socket != packet.Tcp && !(packet.Source.UserID == socket.UserID && packet.Source.ClientID == socket.ClientID))
                {
                    request.FromAddress = packet.Source;

                    socket.SendPacket(request);
                }

            // send ack
            bool sendNoResults = (request.SearchID != 0 || request.Service == Core.DhtServiceID) &&
                                 (packet.ReceivedUdp || packet.Tunneled);

            SearchAck ack = new SearchAck();
            ack.Source = Network.GetLocalSource();
            ack.SearchID = request.SearchID;
            ack.Service = request.Service;

            // search for connected proxy
            if (Network.TcpControl.ProxyMap.Values.Any(p => p.UserID == request.TargetID))
                ack.Proxied = true;

            // only send nodes from proxy server routing table
            if (request.Nodes && (packet.ReceivedUdp || packet.Tunneled))
                ack.ContactList = Routing.Find(request.TargetID, 8);

            // dont send an ack if behind a proxy server and no results
            if (!SearchEvent.Contains(request.Service, request.DataType))
            {
                if (sendNoResults)
                    SendAck(packet, request, ack);
            }

            else
            {

                List<byte[]> results = new List<byte[]>();
                SearchEvent[request.Service, request.DataType].Invoke(request.TargetID, request.Parameters, results);

                // if nothing found, still send ack with closer contacts
                if (results == null || results.Count == 0)
                {
                    if (sendNoResults)
                        SendAck(packet, request, ack);

                    return;
                }

                // if a direct search
                if (request.SearchID == 0)
                {
                    foreach(byte[] value in results)
                        Network.Store.Send_StoreReq(packet.Source, packet.Tcp, new DataReq(null, request.TargetID, request.Service, request.DataType, value));

                    return;
                }

                // else send normal search results
                int totalSize = 0;

                foreach (byte[] data in results)
                {
                    if (data.Length + totalSize > 1200)
                    {
                        SendAck(packet, request, ack);

                        ack.ValueList.Clear();
                        ack.ContactList.Clear(); // dont send twice
                        totalSize = 0;
                    }

                    ack.ValueList.Add(data);
                    totalSize += data.Length;
                }

                if(totalSize > 0)
                    SendAck(packet, request, ack);
            }
        }