Exemplo n.º 1
0
        public Peer Connect(Address address, uint channelCount = 0)
        {
            channelCount = channelCount == 0 ? ChannelLimit : channelCount;
            channelCount = Utils.Clamp(channelCount, MINIMUM_CHANNEL_COUNT, ChannelLimit);

            var currentPeer = Array.Find(Peers, (p) => p.State == PeerState.DISCONNECTED);

            if (currentPeer == null)
            {
                return(null);
            }

            currentPeer.ResetChannels();
            currentPeer.ChannelCount = channelCount;
            currentPeer.State        = PeerState.CONNECTING;
            currentPeer.Address      = address;
            currentPeer.SessionID    = _nextSessionID++;

            if (Version.MaxPeerID == 0x7Fu)
            {
                currentPeer.SessionID &= 0xFFu;
            }

            if (OutgoingBandwidth == 0)
            {
                currentPeer.WindowSize = MAXIMUM_WINDOW_SIZE;
            }
            else
            {
                currentPeer.WindowSize = (OutgoingBandwidth / Peer.WINDOW_SIZE_SCALE) * MINIMUM_WINDOW_SIZE;
            }
            currentPeer.WindowSize = Utils.Clamp(currentPeer.WindowSize, MINIMUM_WINDOW_SIZE, MAXIMUM_WINDOW_SIZE);

            var command = new Protocol.Connect
            {
                Flags                      = ProtocolFlag.ACKNOWLEDGE,
                ChannelID                  = 0xFF,
                OutgoingPeerID             = currentPeer.IncomingPeerID,
                MTU                        = currentPeer.MTU,
                WindowSize                 = currentPeer.WindowSize,
                ChannelCount               = channelCount,
                IncomingBandwidth          = IncomingBandwidth,
                OutgoingBandwidth          = OutgoingBandwidth,
                PacketThrottleInterval     = currentPeer.PacketThrottleInterval,
                PacketThrottleAcceleration = currentPeer.PacketThrottleAcceleration,
                PacketThrottleDeceleration = currentPeer.PacketThrottleDeceleration,
                SessionID                  = currentPeer.SessionID,
            };

            currentPeer.QueueOutgoingCommand(command, null, 0, 0);

            return(currentPeer);
        }
Exemplo n.º 2
0
        private int HandleConnect(Address receivedAddress, ref Peer result, Protocol.Connect command)
        {
            uint channelCount = command.ChannelCount;

            if (channelCount < MINIMUM_CHANNEL_COUNT || channelCount > MAXIMUM_CHANNEL_COUNT)
            {
                return(-1);
            }

            foreach (var peer in Peers)
            {
                if (peer.State != PeerState.DISCONNECTED &&
                    peer.Address.Host == receivedAddress.Host &&
                    peer.Address.Port == receivedAddress.Port &&
                    peer.SessionID == command.SessionID)
                {
                    return(-1);
                }
            }

            var currentPeer = Array.Find(Peers, (peer) => peer.State == PeerState.DISCONNECTED);

            if (currentPeer == null)
            {
                return(-1);
            }

            if (channelCount > ChannelLimit)
            {
                channelCount = ChannelLimit;
            }

            currentPeer.ResetChannels();
            currentPeer.ChannelCount               = channelCount;
            currentPeer.State                      = PeerState.ACKNOWLEDGING_CONNECT;
            currentPeer.SessionID                  = command.SessionID;
            currentPeer.Address                    = receivedAddress;
            currentPeer.OutgoingPeerID             = command.OutgoingPeerID;
            currentPeer.IncomingBandwidth          = command.IncomingBandwidth;
            currentPeer.OutgoingBandwidth          = command.OutgoingBandwidth;
            currentPeer.PacketThrottleInterval     = command.PacketThrottleInterval;
            currentPeer.PacketThrottleAcceleration = command.PacketThrottleAcceleration;
            currentPeer.PacketThrottleDeceleration = command.PacketThrottleDeceleration;
            currentPeer.MTU = Utils.Clamp(command.MTU, MINIMUM_MTU, MAXIMUM_MTU);

            if (OutgoingBandwidth == 0 &&
                currentPeer.IncomingBandwidth == 0)
            {
                currentPeer.WindowSize = MAXIMUM_WINDOW_SIZE;
            }
            else if (OutgoingBandwidth == 0 ||
                     currentPeer.IncomingBandwidth == 0)
            {
                currentPeer.WindowSize = (Math.Max(OutgoingBandwidth, currentPeer.IncomingBandwidth) / Peer.WINDOW_SIZE_SCALE) * MINIMUM_WINDOW_SIZE;
            }
            else
            {
                currentPeer.WindowSize = (Math.Min(OutgoingBandwidth, currentPeer.IncomingBandwidth) / Peer.WINDOW_SIZE_SCALE) * MINIMUM_WINDOW_SIZE;
            }

            currentPeer.WindowSize = Utils.Clamp(currentPeer.WindowSize, MINIMUM_WINDOW_SIZE, MAXIMUM_WINDOW_SIZE);

            uint windowSize = IncomingBandwidth == 0 ? MAXIMUM_WINDOW_SIZE : (IncomingBandwidth / Peer.WINDOW_SIZE_SCALE) * MINIMUM_WINDOW_SIZE;

            if (windowSize > command.WindowSize)
            {
                windowSize = command.WindowSize;
            }

            windowSize = Utils.Clamp(windowSize, MINIMUM_WINDOW_SIZE, MAXIMUM_WINDOW_SIZE);

            var verifyCommand = new Protocol.VerifyConnect
            {
                Flags                      = ProtocolFlag.ACKNOWLEDGE,
                ChannelID                  = 0xFF,
                OutgoingPeerID             = currentPeer.IncomingPeerID,
                MTU                        = currentPeer.MTU,
                WindowSize                 = windowSize,
                ChannelCount               = channelCount,
                IncomingBandwidth          = IncomingBandwidth,
                OutgoingBandwidth          = OutgoingBandwidth,
                PacketThrottleInterval     = currentPeer.PacketThrottleInterval,
                PacketThrottleAcceleration = currentPeer.PacketThrottleAcceleration,
                PacketThrottleDeceleration = currentPeer.PacketThrottleDeceleration,
            };

            currentPeer.QueueOutgoingCommand(verifyCommand, null, 0, 0);

            result = currentPeer;
            return(0);
        }