Пример #1
0
        public void TrySend(DhtNetwork network)
        {
            // check if stuff in queue
            if (Packets.Count == 0 ||
                Addresses.Count == 0 ||
                network.Core.TimeNow < NextTry)
            {
                return;
            }

            Attempts++;
            if (Attempts >= Addresses.Count * 2) // every address known tried twice
            {
                Attempts = 0;
                Packets.RemoveFirst();
                return;
            }

            RudpAddress target = Addresses.First.Value;

            Addresses.RemoveFirst();
            Addresses.AddLast(target);

            NextTry = network.Core.TimeNow.AddSeconds(3);

            Tuple <uint, RudpPacket> tuple = Packets.First.Value;
            RudpPacket packet = tuple.Param2;

            packet.Ident = target.Ident;

            int sentBytes = SendtoAddress(network, target, packet);

            network.Core.ServiceBandwidth[tuple.Param1].OutPerSec += sentBytes;
        }
Пример #2
0
        public void SendTracked(TrackPacket tracked)
        {
            if (AddressMap.Count == 0)
            {
                return;
            }

            RudpAddress target = tracked.SpecialTarget ? tracked.Target : PrimaryAddress;

            LastSend                    = Core.TimeNow;
            tracked.TimeSent            = Core.TimeNow.Ticks;
            tracked.Target              = target;
            tracked.Packet.SenderID     = Network.Local.UserID;
            tracked.Packet.SenderClient = Network.Local.ClientID;


            if (tracked.Packet.PacketType != RudpPacketType.Syn)
            {
                SendPacket(tracked.Packet, target);
            }

            else
            {
                PrimaryAddress.Reset = true;

                foreach (RudpAddress address in AddressMap.Values)
                {
                    tracked.Packet.Ident = address.Ident;
                    tracked.Target       = address;

                    SendPacket(tracked.Packet, address);
                }
            }
        }
Пример #3
0
        public static int SendtoAddress(DhtNetwork network, RudpAddress target, RudpPacket packet)
        {
            Debug.Assert(packet.Payload != null || packet.PacketType == RudpPacketType.LightAck);

            int sentBytes = 0;

            // same code used in rudpSocket
            if (network.Core.Firewall != FirewallType.Blocked && target.LocalProxy == null)
            {
                sentBytes = network.SendPacket(target.Address, packet);
            }

            else if (target.Address.TunnelClient != null)
            {
                sentBytes = network.SendTunnelPacket(target.Address, packet);
            }

            else
            {
                packet.ToAddress = target.Address;

                TcpConnect proxy = network.TcpControl.GetProxy(target.LocalProxy);

                if (proxy != null)
                {
                    sentBytes = proxy.SendPacket(packet);
                }
                else
                {
                    sentBytes = network.TcpControl.SendRandomProxy(packet);
                }
            }

            return(sentBytes);
        }
Пример #4
0
        public void AddAddress(RudpAddress address)
        {
            if (!AddressMap.ContainsKey(address.GetHashCode()))
            {
                address.Ident = (uint)Core.RndGen.Next();
                AddressMap[address.GetHashCode()] = address;
            }

            if (PrimaryAddress == null)
            {
                PrimaryAddress = address;
            }
        }
Пример #5
0
        public void SendPacket(RudpPacket packet, RudpAddress target)
        {
            Debug.Assert(packet.Payload != null);

            // sending syn  to (tracked target) through (address target) udp / tcp

            /*string log = "Sending " + tracked.Packet.PacketType.ToString();
             * if (tracked.Packet.Ident != 0) log  += ", ID " + tracked.Packet.Ident.ToString();
             * log +=  " to " + Utilities.IDtoBin(tracked.Packet.TargetID).Substring(0, 10);
             * log += " target address " + target.Address.ToString();*/

            int sentBytes = 0;

            // same code used in lightComm
            if (Core.Firewall != FirewallType.Blocked && target.LocalProxy == null)
            {
                sentBytes = Network.SendPacket(target.Address, packet);
            }

            else if (target.Address.TunnelClient != null)
            {
                sentBytes = Network.SendTunnelPacket(target.Address, packet);
            }

            else
            {
                packet.ToAddress = target.Address;

                TcpConnect proxy = Network.TcpControl.GetProxy(target.LocalProxy);

                if (proxy != null)
                {
                    sentBytes = proxy.SendPacket(packet);
                }
                else
                {
                    sentBytes = Network.TcpControl.SendRandomProxy(packet);
                }

                //log += " proxied by local tcp";
            }

            Bandwidth.OutPerSec += sentBytes;

            //Session.Log(log);
        }
Пример #6
0
        void SendPing(RudpAddress address)
        {
            RudpPacket ping = new RudpPacket();

            ping.TargetID     = Session.UserID;
            ping.TargetClient = Session.ClientID;
            ping.PeerID       = RemotePeerID;
            ping.PacketType   = RudpPacketType.Ping;
            ping.Sequence     = 0;
            ping.Payload      = BitConverter.GetBytes(address.Ident);

            //Session.Log("Keep Alive Sent, Seq " + alive.Sequence.ToString() + ", ID " + alive.PeerID.ToString());
            TrackPacket tracked = new TrackPacket(ping);

            tracked.Target        = address;
            tracked.SpecialTarget = true;

            SendTracked(tracked);
        }
Пример #7
0
        private void SetPrimaryAddress(uint ident)
        {
            foreach (RudpAddress address in AddressMap.Values)
            {
                if (address.Ident == ident)
                {
                    address.LastAck = Core.TimeNow;

                    // if primary address needs to be reset, replace with this one
                    // (which would be first/fastest received)
                    if (PrimaryAddress.Reset)
                    {
                        PrimaryAddress.Reset = false;
                        PrimaryAddress       = address;
                    }

                    break;
                }
            }
        }
Пример #8
0
        public void AddAddress(OpCore core, RudpAddress address, bool moveFront)
        {
            Debug.Assert(address.Address.UdpPort != 0);

            foreach (RudpAddress check in Addresses)
            {
                if (check.GetHashCode() == address.GetHashCode())
                {
                    if (moveFront)
                    {
                        Addresses.Remove(check);
                        Addresses.AddFirst(check);
                    }

                    return;
                }
            }

            address.Ident = (uint)core.RndGen.Next();
            Addresses.AddLast(address);
        }
Пример #9
0
        public void SecondTimer()
        {
            int packetLoss = 0;

            if (State == RudpState.Connected)
            {
                //Debug.WriteLine(Core.User.Settings.UserName + ":" + Core.TimeNow.Second + " - Send Window: " + SendWindowSize + ", Packets Sent: " + PacketsCompleted + ", Retransmits: " + ReTransmits); //crit delete
                PacketsCompleted = 0;

                // manage send window
                packetLoss = 0;

                if (InOrderAcks > 0)
                {
                    packetLoss = ReTransmits * 100 / InOrderAcks;
                }

                ReTransmits = 0;
                InOrderAcks = 0;

                //Session.Log("PL: " + packetLoss.ToString() +
                //    ", SW: " + SendWindowSize.ToString() +
                //    ", SQ: " + SendPacketMap.Count.ToString() +
                //    ", SB: " + SendBuffLength.ToString());

                if (packetLoss < 10 && SendWindowSize < MAX_WINDOW_SIZE)
                {
                    SendWindowSize++;
                }
                if (packetLoss > 20 && SendWindowSize > 1)
                {
                    SendWindowSize /= 2;
                }


                // if data waiting to be read
                if (State == RudpState.Connected && RecvBuffLength > 0)
                {
                    Session.OnReceive();
                }


                // dead - 5 secs send ping, 10 secs reset primary addr, 15 secs close

                DateTime lastRecv = PrimaryAddress.LastAck;

                // if nothing received for 15 seconds disconnect
                if (Core.TimeNow > lastRecv.AddSeconds(15))
                {
                    RudpClose(CloseReason.TIMEOUT);
                }

                // re-analyze alternate routes after 10 secs dead, or half min interval
                else if (Core.TimeNow > lastRecv.AddSeconds(10) || Core.TimeNow > NextCheckRoutes)
                {
                    // after connection this should immediately be called to find best route

                    CheckRoutes();

                    NextCheckRoutes = Core.TimeNow.AddSeconds(30);
                }

                // send keep alive if nothing received after 5 secs
                else if (Core.TimeNow > lastRecv.AddSeconds(5))
                {
                    SendPing(PrimaryAddress);
                }
            }

            // prune addressMap to last 6 addresses seen
            while (AddressMap.Count > 6)
            {
                RudpAddress lastSeen = null;

                foreach (RudpAddress address in AddressMap.Values)
                {
                    if (lastSeen == null || address.LastAck < lastSeen.LastAck)
                    {
                        lastSeen = address;
                    }
                }

                AddressMap.Remove(lastSeen.GetHashCode());
            }

            // finishing
            if (State == RudpState.Finishing)
            {
                if (!FinSent)
                {
                    TrySendFin();
                }

                if (FinTimeout > 0)
                {
                    FinTimeout--;
                }

                if (FinTimeout == 0)
                {
                    ChangeState(RudpState.Closed);
                }

                // buffer clear, all packets acked in sequence including fins
                if (FinSent && FinReceived && SendPacketMap.Count == 0)
                {
                    ChangeState(RudpState.Closed);
                }
            }

            // re-send packets in out buffer
            if (State != RudpState.Closed)
            {
                ManageSendWindow();
            }

            // update bandwidth rate used for determining public send buffer
            AvgBytesSent.Next();

            // bandwidth stats
            Bandwidth.NextSecond();
        }
Пример #10
0
        private void SetPrimaryAddress(uint ident)
        {
            foreach (RudpAddress address in AddressMap.Values)
                if (address.Ident == ident)
                {
                    address.LastAck = Core.TimeNow;

                    // if primary address needs to be reset, replace with this one
                    // (which would be first/fastest received)
                    if (PrimaryAddress.Reset)
                    {
                        PrimaryAddress.Reset = false;
                        PrimaryAddress = address;
                    }

                    break;
                }
        }
Пример #11
0
        void SendPing(RudpAddress address)
        {
            RudpPacket ping = new RudpPacket();

            ping.TargetID = Session.UserID;
            ping.TargetClient = Session.ClientID;
            ping.PeerID = RemotePeerID;
            ping.PacketType = RudpPacketType.Ping;
            ping.Sequence = 0;
            ping.Payload = BitConverter.GetBytes(address.Ident);

            //Session.Log("Keep Alive Sent, Seq " + alive.Sequence.ToString() + ", ID " + alive.PeerID.ToString());
            TrackPacket tracked = new TrackPacket(ping);
            tracked.Target = address;
            tracked.SpecialTarget = true;

            SendTracked(tracked);
        }
Пример #12
0
        public void SendPacket(RudpPacket packet, RudpAddress target)
        {
            Debug.Assert(packet.Payload != null);

            // sending syn  to (tracked target) through (address target) udp / tcp

            /*string log = "Sending " + tracked.Packet.PacketType.ToString();
            if (tracked.Packet.Ident != 0) log  += ", ID " + tracked.Packet.Ident.ToString();
            log +=  " to " + Utilities.IDtoBin(tracked.Packet.TargetID).Substring(0, 10);
            log += " target address " + target.Address.ToString();*/

            int sentBytes = 0;

            // same code used in lightComm
            if (Core.Firewall != FirewallType.Blocked && target.LocalProxy == null)
            {
                sentBytes = Network.SendPacket(target.Address, packet);
            }

            else if (target.Address.TunnelClient != null)
                sentBytes = Network.SendTunnelPacket(target.Address, packet);

            else
            {
                packet.ToAddress = target.Address;

                TcpConnect proxy = Network.TcpControl.GetProxy(target.LocalProxy);

                if (proxy != null)
                    sentBytes = proxy.SendPacket(packet);
                else
                    sentBytes = Network.TcpControl.SendRandomProxy(packet);

                //log += " proxied by local tcp";
            }

            Bandwidth.OutPerSec += sentBytes;

            //Session.Log(log);
        }
Пример #13
0
        public void AddAddress(RudpAddress address)
        {
            if (!AddressMap.ContainsKey(address.GetHashCode()))
            {
                address.Ident = (uint) Core.RndGen.Next();
                AddressMap[address.GetHashCode()] = address;
            }

            if (PrimaryAddress == null)
                PrimaryAddress = address;
        }