Exemplo n.º 1
0
        private void Receive_Patch(DhtAddress source, byte[] data)
        {
            // invoke patch
            G2Header root = new G2Header(data);

            if (G2Protocol.ReadPacket(root))
            {
                if (root.Name == StorePacket.Patch)
                {
                    PatchPacket packet = PatchPacket.Decode(root);

                    if (packet == null)
                    {
                        return;
                    }

                    foreach (PatchTag patch in packet.PatchData)
                    {
                        if (PatchEvent.Contains(patch.Service, patch.DataType))
                        {
                            PatchEvent[patch.Service, patch.DataType].Invoke(source, patch.Tag);
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
 void InvokeTags(ulong user, ServiceData data)
 {
     foreach (PatchTag tag in data.Tags)
     {
         if (TagReceived.Contains(tag.Service, tag.DataType))
         {
             TagReceived[tag.Service, tag.DataType].Invoke(user, tag.Tag);
         }
     }
 }
Exemplo n.º 3
0
        public void Receive_StoreReq(G2ReceivedPacket packet)
        {
            StoreReq store = StoreReq.Decode(packet);

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

            if (store.Source.Firewall == FirewallType.Open)
            {
                // dont need to add to routing if nat/blocked because eventual routing ping by server will auto add
                Network.Routing.Add(new DhtContact(store.Source, packet.Source.IP));
            }


            // forward to proxied nodes - only replicate data to blocked nodes on operation network
            if (!Network.IsLookup)
            {
                // when we go offline it will be these nodes that update their next proxy with stored info
                foreach (TcpConnect socket in Network.TcpControl.ProxyClients)
                {
                    if (packet.Tcp != socket)
                    {
                        if (packet.ReceivedUdp)
                        {
                            store.FromAddress = packet.Source;
                        }

                        socket.SendPacket(store);
                    }
                }
            }

            // pass to components
            DataReq data = new DataReq(packet.Source, store.Key, store.Service, store.DataType, store.Data);

            if (packet.ReceivedTcp && packet.Tcp.Proxy == ProxyType.Server)
            {
                data.LocalProxy = new DhtClient(packet.Tcp);
            }

            if (data.Service == 0)
            {
                Receive_Patch(packet.Source, store.Data);
            }

            else if (StoreEvent.Contains(store.Service, store.DataType))
            {
                StoreEvent[store.Service, store.DataType].Invoke(data);
            }
        }
Exemplo n.º 4
0
        /*public void SendUnreliable(RudpAddress address, uint service, int type, G2Packet packet)
         * {
         *  // insecure, rudp provides this same method which is more secure, if a rudp connection is already established
         *
         *  RudpPacket wrap = CreateRudpPacket(address.Address, service, type, packet, false);
         *
         *  int sentBytes = LightClient.SendtoAddress(Core.Network, address, wrap);
         *
         *  Core.ServiceBandwidth[service].OutPerSec += sentBytes;
         * }*/

        public void ReceivePacket(G2ReceivedPacket raw, RudpPacket packet)
        {
            DhtClient client = new DhtClient(packet.SenderID, packet.SenderClient);

            if (!Clients.ContainsKey(client.RoutingID))
            {
                Clients[client.RoutingID] = new LightClient(client);
            }

            LightClient light = Clients[client.RoutingID];

            light.LastSeen = Core.TimeNow;

            // either direct, or node's proxy
            light.AddAddress(Core, new RudpAddress(raw.Source), true);

            if (raw.ReceivedTcp) // add this second so sending ack through tcp proxy is perferred
            {
                light.AddAddress(Core, new RudpAddress(raw.Source, raw.Tcp), true);
            }


            if (packet.PacketType == RudpPacketType.LightAck)
            {
                ReceiveAck(raw, light, packet);
            }

            else if (packet.PacketType == RudpPacketType.Light)
            {
                RudpLight info = new RudpLight(packet.Payload);

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

                if (Data.Contains(info.Service, info.Type))
                {
                    Data[info.Service, info.Type].Invoke(client, info.Data);
                }

                if (packet.Sequence == 1) // reliable packet
                {
                    SendAck(light, packet, info.Service);
                }
            }
        }
Exemplo n.º 5
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);
                }
            }
        }
Exemplo n.º 6
0
        private void Process_LocationData(DataReq data, SignedData signed, LocationData location)
        {
            Core.IndexKey(location.UserID, ref location.Key);

            Debug.Assert(location.UserID == location.Source.UserID);
            if (location.UserID != location.Source.UserID)
            {
                return;
            }


            ClientInfo client = GetLocationInfo(location.UserID, location.Source.ClientID);

            // check location version
            if (client != null)
            {
                if (location.Version == client.Data.Version)
                {
                    return;
                }

                else if (location.Version < client.Data.Version)
                {
                    if (data != null && data.Source != null)
                    {
                        Network.Store.Send_StoreReq(data.Source, data.LocalProxy, new DataReq(null, client.Data.UserID, ServiceID, 0, client.SignedData));
                    }

                    return;
                }
            }

            Core.IndexName(location.UserID, location.Name);

            // notify components of new versions (usually just localsync service signed up for this)
            DhtAddress address = new DhtAddress(location.IP, location.Source);

            foreach (PatchTag tag in location.Tags)
            {
                if (TagReceived.Contains(tag.Service, tag.DataType))
                {
                    TagReceived[tag.Service, tag.DataType].Invoke(address, location.UserID, tag.Tag);
                }
            }


            // add location
            if (client == null)
            {
                // if too many clients, and not us, return
                if (location.UserID != Core.UserID && ActiveClientCount(location.UserID) > MaxClientsperUser)
                {
                    return;
                }

                client = new ClientInfo(location);

                Clients.SafeAdd(client.RoutingID, client);

                // dont need to worry about remote caching old locs indefinitely because if a loc is cached remotely
                // that means the remote is being continuall pinged, or else the loc would expire
                // if we're still interested in loc after a min, it will be pinged locally
            }

            client.Data       = location;
            client.SignedData = signed.Encode(Network.Protocol);

            if (client.Data.UserID == Core.UserID && client.Data.Source.ClientID == Network.Local.ClientID)
            {
                LocalClient = client;
            }


            AddRoutingData(location);

            // only get down here if loc was new version in first place (recently published)
            // with live comm trickle down this prevents highers from being direct ping flooded to find their
            // online status
            client.LastSeen = Core.TimeNow;

            SignalUpdate(client, true);
        }