Ejemplo n.º 1
0
        public override void Update()
        {
            this.Recv();
            
            this.TimerOut();

            foreach (long id in updateChannels)
            {
                KChannel kChannel = this.Get(id);
                if (kChannel == null)
                {
                    continue;
                }

                if (kChannel.Id == 0)
                {
                    continue;
                }

                kChannel.Update();
            }

            this.updateChannels.Clear();
            
            this.RemoveConnectTimeoutChannels();
        }
Ejemplo n.º 2
0
        public override void Update()
        {
            this.TimeNow = (uint)(TimeHelper.ClientNow() - this.StartTime);

            this.Recv();

            this.TimerOut();

            foreach (long id in updateChannels)
            {
                KChannel kChannel = this.GetKChannel(id);
                if (kChannel == null)
                {
                    continue;
                }
                if (kChannel.Id == 0)
                {
                    continue;
                }
                kChannel.Update();
            }
            this.updateChannels.Clear();

            while (this.removedChannels.Count > 0)
            {
                long     id = this.removedChannels.Dequeue();
                KChannel channel;
                if (!this.localConnChannels.TryGetValue(id, out channel))
                {
                    continue;
                }
                this.localConnChannels.Remove(id);
                channel.Dispose();
            }
        }
Ejemplo n.º 3
0
 protected override void Send(long channelId, long actorId, MemoryStream stream)
 {
     KChannel channel = this.Get(channelId);
     if (channel == null)
     {
         return;
     }
     channel.Send(actorId, stream);
 }
Ejemplo n.º 4
0
        public void ChangeAddress(long id, IPEndPoint address)
        {
            KChannel kChannel = this.Get(id);

            if (kChannel == null)
            {
                return;
            }

            Log.Info($"channel change address: {id} {address}");
            kChannel.RemoteAddress = address;
        }
Ejemplo n.º 5
0
 private static int KcpOutput(IntPtr bytes, int len, IntPtr kcp, IntPtr user)
 {
     try
     {
         KChannel kChannel = KChannel.kChannels[(uint) user];
         kChannel.Output(bytes, len);
     }
     catch (Exception e)
     {
         Log.Error(e);
         return len;
     }
     return len;
 }
Ejemplo n.º 6
0
        public override AChannel ConnectChannel(IPEndPoint remoteEndPoint)
        {
            uint     localConn = (uint)RandomHelper.RandomNumber(1000, int.MaxValue);
            KChannel oldChannel;

            if (this.localConnChannels.TryGetValue(localConn, out oldChannel))
            {
                this.localConnChannels.Remove(oldChannel.LocalConn);
                oldChannel.Dispose();
            }

            KChannel channel = new KChannel(localConn, this.socket, remoteEndPoint, this);

            this.localConnChannels[channel.LocalConn] = channel;
            return(channel);
        }
Ejemplo n.º 7
0
        public static void Output(IntPtr bytes, int count, IntPtr user)
        {
            if (Instance == null)
            {
                return;
            }
            AChannel aChannel = Instance.GetChannel((uint)user);

            if (aChannel == null)
            {
                Log.Error($"not found kchannel, {(uint)user}");
                return;
            }

            KChannel kChannel = aChannel as KChannel;

            kChannel.Output(bytes, count);
        }
Ejemplo n.º 8
0
 protected override void Get(long id, IPEndPoint address)
 {
     if (this.idChannels.TryGetValue(id, out KChannel channel))
     {
         return;
     }
     try
     {
         // 低32bit是localConn
         uint localConn = (uint)((ulong) id & uint.MaxValue);
         channel = new KChannel(id, localConn, this.socket, address, this);
         this.idChannels.Add(id, channel);
         this.localConnChannels.Add(channel.LocalConn, channel);
     }
     catch (Exception e)
     {
         Log.Error($"kservice get error: {id}\n{e}");
     }
 }
Ejemplo n.º 9
0
        public void ChangeAddress(long id, IPEndPoint address)
        {
#if NET_THREAD
            this.ThreadSynchronizationContext.Post(() =>
                    {
#endif
                        KChannel kChannel = this.Get(id);
                        if (kChannel == null)
                        {
                            return;
                        }

                        Log.Info($"channel change address: {id} {address}");
                        kChannel.RemoteAddress = address;
#if NET_THREAD
                    }
        );
#endif
        }
Ejemplo n.º 10
0
        private void Recv()
        {
            if (this.socket == null)
            {
                return;
            }

            while (socket != null && this.socket.Available > 0)
            {
                int messageLength = this.socket.ReceiveFrom(this.cache, ref this.ipEndPoint);

                // 长度小于1,不是正常的消息
                if (messageLength < 1)
                {
                    continue;
                }

                // accept
                byte flag = this.cache[0];
                    
                // conn从100开始,如果为1,2,3则是特殊包
                uint remoteConn = 0;
                uint localConn = 0;
                
                try
                {
                    KChannel kChannel = null;
                    switch (flag)
                    {
#if NOT_CLIENT
                        case KcpProtocalType.SYN: // accept
                        {
                            // 长度!=5,不是SYN消息
                            if (messageLength < 9)
                            {
                                break;
                            }

                            string realAddress = null;
                            remoteConn = BitConverter.ToUInt32(this.cache, 1);
                            if (messageLength > 9)
                            {
                                realAddress = this.cache.ToStr(9, messageLength - 9);
                            }

                            remoteConn = BitConverter.ToUInt32(this.cache, 1);
                            localConn = BitConverter.ToUInt32(this.cache, 5);

                            this.waitConnectChannels.TryGetValue(remoteConn, out kChannel);
                            if (kChannel == null)
                            {
                                localConn = CreateRandomLocalConn(this.random);
                                // 已存在同样的localConn,则不处理,等待下次sync
                                if (this.localConnChannels.ContainsKey(localConn))
                                {
                                    break;
                                }
                                long id = this.CreateAcceptChannelId(localConn);
                                if (this.idChannels.ContainsKey(id))
                                {
                                    break;
                                }

                                kChannel = new KChannel(id, localConn, remoteConn, this.socket, this.CloneAddress(), this);
                                this.idChannels.Add(kChannel.Id, kChannel);
                                this.waitConnectChannels.Add(kChannel.RemoteConn, kChannel); // 连接上了或者超时后会删除
                                this.localConnChannels.Add(kChannel.LocalConn, kChannel);

                                kChannel.RealAddress = realAddress;

                                IPEndPoint realEndPoint = kChannel.RealAddress == null? kChannel.RemoteAddress : NetworkHelper.ToIPEndPoint(kChannel.RealAddress);
                                this.OnAccept(kChannel.Id, realEndPoint);
                            }

                            if (kChannel.RemoteConn != remoteConn)
                            {
                                break;
                            }

                            // 地址跟上次的不一致则跳过
                            if (kChannel.RealAddress != realAddress)
                            {
                                Log.Error($"kchannel syn address diff: {kChannel.Id} {kChannel.RealAddress} {realAddress}");
                                break;
                            }

                            try
                            {
                                byte[] buffer = this.cache;
                                buffer.WriteTo(0, KcpProtocalType.ACK);
                                buffer.WriteTo(1, kChannel.LocalConn);
                                buffer.WriteTo(5, kChannel.RemoteConn);
                                Log.Info($"kservice syn: {kChannel.Id} {remoteConn} {localConn}");
                                this.socket.SendTo(buffer, 0, 9, SocketFlags.None, kChannel.RemoteAddress);
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                                kChannel.OnError(ErrorCode.ERR_SocketCantSend);
                            }

                            break;
                        }
#endif
                        case KcpProtocalType.ACK: // connect返回
                            // 长度!=9,不是connect消息
                            if (messageLength != 9)
                            {
                                break;
                            }

                            remoteConn = BitConverter.ToUInt32(this.cache, 1);
                            localConn = BitConverter.ToUInt32(this.cache, 5);
                            kChannel = this.GetByLocalConn(localConn);
                            if (kChannel != null)
                            {
                                Log.Info($"kservice ack: {kChannel.Id} {remoteConn} {localConn}");
                                kChannel.RemoteConn = remoteConn;
                                kChannel.HandleConnnect();
                            }

                            break;
                        case KcpProtocalType.FIN: // 断开
                            // 长度!=13,不是DisConnect消息
                            if (messageLength != 13)
                            {
                                break;
                            }

                            remoteConn = BitConverter.ToUInt32(this.cache, 1);
                            localConn = BitConverter.ToUInt32(this.cache, 5);
                            int error = BitConverter.ToInt32(this.cache, 9);

                            // 处理chanel
                            kChannel = this.GetByLocalConn(localConn);
                            if (kChannel == null)
                            {
                                break;
                            }
                            
                            // 校验remoteConn,防止第三方攻击
                            if (kChannel.RemoteConn != remoteConn)
                            {
                                break;
                            }
                            
                            Log.Info($"kservice recv fin: {kChannel.Id} {localConn} {remoteConn} {error}");
                            kChannel.OnError(ErrorCode.ERR_PeerDisconnect);

                            break;
                        case KcpProtocalType.MSG: // 断开
                            // 长度<9,不是Msg消息
                            if (messageLength < 9)
                            {
                                break;
                            }
                            
                            // 处理chanel
                            remoteConn = BitConverter.ToUInt32(this.cache, 1);
                            localConn = BitConverter.ToUInt32(this.cache, 5);

                            kChannel = this.GetByLocalConn(localConn);
                            if (kChannel == null)
                            {
                                // 通知对方断开
                                this.Disconnect(localConn, remoteConn, ErrorCode.ERR_KcpNotFoundChannel, (IPEndPoint) this.ipEndPoint, 1);
                                break;
                            }
                            
                            // 校验remoteConn,防止第三方攻击
                            if (kChannel.RemoteConn != remoteConn)
                            {
                                break;
                            }
                            
                            kChannel.HandleRecv(this.cache, 5, messageLength - 5);
                            break;
                    }
                }
                catch (Exception e)
                {
                    Log.Error($"kservice error: {flag} {remoteConn} {localConn}\n{e}");
                }
            }
        }
Ejemplo n.º 11
0
        public void Recv()
        {
            if (this.socket == null)
            {
                return;
            }

            while (socket != null && this.socket.Available > 0)
            {
                int messageLength = 0;
                try
                {
                    messageLength = this.socket.ReceiveFrom(this.cache, ref this.ipEndPoint);
                }
                catch (Exception e)
                {
                    Log.Error(e);
                    continue;
                }

                // 长度小于1,不是正常的消息
                if (messageLength < 1)
                {
                    continue;
                }
                // accept
                byte flag = this.cache[0];

                // conn从1000开始,如果为1,2,3则是特殊包
                uint     remoteConn = 0;
                uint     localConn  = 0;
                KChannel kChannel   = null;
                switch (flag)
                {
                case KcpProtocalType.SYN:                          // accept
                    // 长度!=5,不是accpet消息
                    if (messageLength != 5)
                    {
                        break;
                    }

                    IPEndPoint acceptIpEndPoint = (IPEndPoint)this.ipEndPoint;
                    this.ipEndPoint = new IPEndPoint(0, 0);

                    remoteConn = BitConverter.ToUInt32(this.cache, 1);

                    // 如果已经收到连接,则忽略
                    if (this.waitConnectChannels.TryGetValue(remoteConn, out kChannel))
                    {
                        break;
                    }

                    localConn = ++this.IdGenerater;
                    kChannel  = new KChannel(localConn, remoteConn, this.socket, acceptIpEndPoint, this);
                    this.localConnChannels[kChannel.LocalConn] = kChannel;
                    this.waitConnectChannels[remoteConn]       = kChannel;

                    this.OnAccept(kChannel);

                    break;

                case KcpProtocalType.ACK:                          // connect返回
                    // 长度!=9,不是connect消息
                    if (messageLength != 9)
                    {
                        break;
                    }
                    remoteConn = BitConverter.ToUInt32(this.cache, 1);
                    localConn  = BitConverter.ToUInt32(this.cache, 5);

                    kChannel = this.GetKChannel(localConn);
                    if (kChannel != null)
                    {
                        kChannel.HandleConnnect(remoteConn);
                    }
                    break;

                case KcpProtocalType.FIN:                          // 断开
                    // 长度!=13,不是DisConnect消息
                    if (messageLength != 13)
                    {
                        break;
                    }

                    remoteConn = BitConverter.ToUInt32(this.cache, 1);
                    localConn  = BitConverter.ToUInt32(this.cache, 5);

                    // 处理chanel
                    kChannel = this.GetKChannel(localConn);
                    if (kChannel != null)
                    {
                        // 校验remoteConn,防止第三方攻击
                        if (kChannel.RemoteConn == remoteConn)
                        {
                            kChannel.Disconnect(ErrorCode.ERR_PeerDisconnect);
                        }
                    }
                    break;

                case KcpProtocalType.MSG:                          // 断开
                    // 长度<9,不是Msg消息
                    if (messageLength < 9)
                    {
                        break;
                    }
                    // 处理chanel
                    remoteConn = BitConverter.ToUInt32(this.cache, 1);
                    localConn  = BitConverter.ToUInt32(this.cache, 5);

                    this.waitConnectChannels.Remove(remoteConn);

                    kChannel = this.GetKChannel(localConn);
                    if (kChannel != null)
                    {
                        // 校验remoteConn,防止第三方攻击
                        if (kChannel.RemoteConn == remoteConn)
                        {
                            kChannel.HandleRecv(this.cache, 5, messageLength - 5);
                        }
                    }
                    break;
                }
            }
        }