예제 #1
0
        void ReceiveAck(G2ReceivedPacket raw, LightClient client, RudpPacket packet)
        {
            // remove acked packet
            foreach (Tuple <uint, RudpPacket> tuple in client.Packets)
            {
                if (tuple.Param2.PeerID == packet.PeerID)
                {
                    client.Packets.Remove(tuple);
                    client.Attempts = 0;
                    break;
                }
            }

            // read ack ident and move to top
            foreach (RudpAddress address in client.Addresses)
            {
                if (address.Ident == packet.Ident)
                {
                    client.Addresses.Remove(address);
                    client.Addresses.AddFirst(address);
                    address.LastAck = Core.TimeNow;
                    break;
                }
            }

            client.NextTry = Core.TimeNow;

            // receieved ack, try to send next packet immediately
            client.TrySend(Network);
        }
예제 #2
0
        public void SendReliable(DhtClient client, uint service, int type, G2Packet packet, bool expedite)
        {
            if (!Clients.ContainsKey(client.RoutingID))
            {
                return;
            }

            RudpPacket comm = CreateRudpPacket(client, service, type, packet, true);

            LightClient target = Clients[client.RoutingID];

            if (expedite)
            {
                target.NextTry = Core.TimeNow;
                target.Packets.AddFirst(new Tuple <uint, RudpPacket>(service, comm));
                target.TrySend(Network);
                return;
            }

            Active[client.RoutingID] = target;

            target.Packets.AddLast(new Tuple <uint, RudpPacket>(service, comm));
            while (target.Packets.Count > 30)
            {
                //crit - log to console? Debug.Assert(false);
                target.Packets.RemoveFirst();
            }

            target.TrySend(Network);
        }
예제 #3
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);
                }
            }
        }
예제 #4
0
        void SendAck(LightClient light, RudpPacket packet, uint service)
        {
            RudpPacket comm = new RudpPacket();

            comm.SenderID     = Network.Local.UserID;
            comm.SenderClient = Network.Local.ClientID;
            comm.TargetID     = light.Client.UserID;
            comm.TargetClient = light.Client.ClientID;
            comm.PacketType   = RudpPacketType.LightAck;
            comm.PeerID       = packet.PeerID; // so remote knows which packet we're acking
            comm.Ident        = packet.Ident;  // so remote knows which address is good
            comm.Sequence     = 0;

            // send ack to first address, addresses moved to front on receive packet
            int sentBytes = LightClient.SendtoAddress(Network, light.Addresses.First.Value, comm);

            Core.ServiceBandwidth[service].OutPerSec += sentBytes;

            // on resend packet from remote we receive it through different proxy, so that address
            // is moved to the front of the list automatically and our ack takes that direction
        }
예제 #5
0
        public void Update(LocationData location)
        {
            DhtClient client = new DhtClient(location.Source);

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

            LightClient light = Clients[client.RoutingID];

            light.AddAddress(Core, new DhtAddress(location.IP, location.Source), false);

            foreach (DhtAddress address in location.Proxies)
            {
                light.AddAddress(Core, address, false);
            }

            foreach (DhtAddress server in location.TunnelServers)
            {
                light.AddAddress(Core, new DhtContact(location.Source, location.IP, location.TunnelClient, server), false);
            }
        }