Ejemplo n.º 1
0
        public override void HandleConnectionRequestFrame(AleTunnel theConnection, Frames.AleFrame theFrame)
        {
            var crData = theFrame.UserData as AleConnectionRequest;

            // 停止超时检测计时器。
            theConnection.StopHandshakeTimer();

            // 检查CR协议帧。
            this.CheckCrFrame(crData, theConnection);

            // 检查AU1的正确性。
            this.Context.AuMsgBuilder.CheckAu1Packet(crData.UserData);

            // 发送CC帧。
            this.SendConnectionConfirmFrame(theConnection);

            if (!this.Context.ContainsTunnel(theConnection))
            {
                // 事件通知:接收到一个新的TCP连接。
                var args = new TcpConnectedEventArgs(theConnection.ID,
                                                     this.Context.RsspEP.LocalID, theConnection.LocalEndPoint,
                                                     this.Context.RsspEP.RemoteID, theConnection.RemoteEndPoint);
                this.Context.TunnelEventNotifier.NotifyTcpConnected(args);

                // 增加有效的连接个数。
                theConnection.IsHandShaken = true;
                this.Context.IncreaseValidConnection();

                // 保存TCP连接
                this.Context.AddConnection(theConnection);
            }
        }
Ejemplo n.º 2
0
        protected void CheckCrFrame(AleConnectionRequest crData, AleTunnel theTunnel)
        {
            if (crData.ServiceType == ServiceType.A)
            {
                throw new Exception(string.Format("收到CR帧,请求A类服务,不支持此类型,断开连接。"));
            }

            if (crData.ResponderID != this.Context.RsspEP.LocalID)
            {
                throw new Exception(string.Format("CR帧中的被动方编号({0})与本地编号({1})不一致,断开此连接。",
                                                  crData.ResponderID, this.Context.RsspEP.LocalID));
            }

            if (crData.InitiatorID == this.Context.RsspEP.LocalID)
            {
                throw new Exception(string.Format("CR帧中的主动方编号({0})与本地编号({1})相同,断开此连接。",
                                                  crData.InitiatorID, this.Context.RsspEP.LocalID));
            }

            if (!this.Context.RsspEP.IsClientAcceptable(crData.InitiatorID, theTunnel.RemoteEndPoint))
            {
                throw new Exception(string.Format("CR帧中的主动方编号({0})或终结点({1})不在可接受的范围内,断开此连接。",
                                                  crData.InitiatorID, theTunnel.RemoteEndPoint));
            }
        }
Ejemplo n.º 3
0
        public virtual void HandleDiFrame(AleTunnel theConnection, AleFrame theFrame)
        {
            var diData = theFrame.UserData as AleDisconnect;

            this.Context.Observer.OnAleUserDataArrival(diData.UserData);

            theConnection.Disconnect();
        }
Ejemplo n.º 4
0
        public override void HandleConnectionConfirmFrame(AleTunnel theConnection, Frames.AleFrame theFrame)
        {
            // 停止超时检测计时器。
            theConnection.StopHandshakeTimer();

            // 检查CC帧。
            var ccData = theFrame.UserData as AleConnectionConfirm;

            this.CheckCcFrame(ccData);

            // 如果CC帧中的应答方编号校验通过,则增加一个有效的连接。
            theConnection.IsHandShaken = true;
            this.Context.IncreaseValidConnection();
        }
Ejemplo n.º 5
0
        void IAleTunnelObserver.OnAleFrameArrival(AleTunnel theConnection, AleFrame theFrame)
        {
            try
            {
                // 只处理ConnectionRequest帧。
                if (theFrame.FrameType != AleFrameType.ConnectionRequest)
                {
                    throw new Exception(string.Format("在临时AleTunnel上收到了非CR帧,关闭此连接!本地终结点={0},远程终结点={1}。",
                                                      theConnection.LocalEndPoint, theConnection.RemoteEndPoint));
                }

                // 确认此连接是“AleServerTunnel对象”。
                var tunnel = theConnection as AleServerTunnel;
                if (tunnel == null)
                {
                    throw new Exception(string.Format("在非AleServerTunnel上收到了CR帧!本地终结点={0},远程终结点={1}。",
                                                      theConnection.LocalEndPoint, theConnection.RemoteEndPoint));
                }

                // 处理ALE帧。
                var aleCrData = theFrame.UserData as AleConnectionRequest;
                var key       = this.BuildSaiConnectionID(aleCrData.ResponderID, aleCrData.InitiatorID);

                SaiConnectionServer saiConnection;
                lock (_saiConnectionsLock)
                {
                    saiConnection = this.GetSaiConnection(key) as SaiConnectionServer;
                    if (saiConnection == null)
                    {
                        saiConnection = this.CreateSaiConnectionServer(aleCrData.InitiatorID);

                        this.AddSaiConnection(key, saiConnection);

                        saiConnection.Open();
                    }
                }

                // 交给SaiConnection处理。
                saiConnection.HandleAleConnectionRequestFrame(tunnel, theFrame);

                // 从临时链表中移除。
                _serverTunnels.Remove(tunnel);
            }
            catch (System.Exception ex)
            {
                LogUtility.Error(string.Format("{0}", ex));
                _serverTunnels.Remove(theConnection as AleServerTunnel);
                theConnection.Close();
            }
        }
Ejemplo n.º 6
0
        void IAleTunnelObserver.OnTcpDisconnected(AleTunnel theConnection, string reason)
        {
            try
            {
                // 进入此函数表示客户端连接后没有发送任何数据就关闭(可能是客户端主动关闭,也可能是在规定时间里没有发送CR帧而被服务器关闭)。

                _serverTunnels.Remove(theConnection as AleServerTunnel);
                theConnection.Close();
            }
            catch (System.Exception ex)
            {
                LogUtility.Error(ex.ToString());
            }
        }
Ejemplo n.º 7
0
        protected void SendConnectionConfirmFrame(AleTunnel theConnection)
        {
            var au2Packet = this.Context.AuMsgBuilder.BuildAu2Packet();

            var ccData = new AleConnectionConfirm(this.Context.RsspEP.LocalID, au2Packet);

            // 构建AleFrame。
            ushort seqNo   = 0;
            var    appType = this.Context.RsspEP.ApplicatinType;
            var    ccFrame = new AleFrame(appType, seqNo, theConnection.IsNormal, ccData);

            // 发送。
            var bytes = ccFrame.GetBytes();

            theConnection.Send(bytes);

            LogUtility.Info(string.Format("{0}: Send CC frame via tcp connection(LEP = {1}, REP={2}).",
                                          this.Context.RsspEP.ID, theConnection.LocalEndPoint, theConnection.RemoteEndPoint));
        }
Ejemplo n.º 8
0
        public override void HandleConnectionRequestFrame(AleTunnel theConnection, AleFrame theFrame)
        {
            var crData = theFrame.UserData as AleConnectionRequest;

            // 停止握手计时器。
            theConnection.StopHandshakeTimer();

            // 复位序号。
            this.Context.SeqNoManager.Initlialize();

            // 检查CR协议帧。
            this.CheckCrFrame(crData, theConnection);

            // 更新服务类型。
            this.Context.RsspEP.ServiceType = crData.ServiceType;

            // 将CR帧中的AU1提交到MASL(主要更新RandomB)。
            this.Context.Observer.OnAleUserDataArrival(crData.UserData);

            // 发送CC帧。
            this.SendConnectionConfirmFrame(theConnection);

            // 更新序号管理器的发送序号与确认序号。
            this.Context.SeqNoManager.GetAndUpdateSendSeq();
            this.Context.SeqNoManager.UpdateAckSeq(theFrame.SequenceNo);

            if (!this.Context.ContainsTunnel(theConnection))
            {
                // 接收到一个新的TCP连接。
                var args = new TcpConnectedEventArgs(theConnection.ID,
                                                     this.Context.RsspEP.LocalID, theConnection.LocalEndPoint,
                                                     this.Context.RsspEP.RemoteID, theConnection.RemoteEndPoint);
                this.Context.TunnelEventNotifier.NotifyTcpConnected(args);

                // 增加有效的连接个数。
                theConnection.IsHandShaken = true;
                this.Context.IncreaseValidConnection();

                // 保存TCP连接
                this.Context.AddConnection(theConnection);
            }
        }
Ejemplo n.º 9
0
        public override void HandleConnectionConfirmFrame(AleTunnel theConnection, AleFrame theFrame)
        {
            // 复位序号。
            this.Context.SeqNoManager.Initlialize();

            // 停止超时检测计时器。
            theConnection.StopHandshakeTimer();

            // 检查CC帧。
            var ccData = theFrame.UserData as AleConnectionConfirm;

            this.CheckCcFrame(ccData);

            // 如果CC帧中的应答方编号校验通过,则增加一个有效的连接。
            theConnection.IsHandShaken = true;
            this.Context.IncreaseValidConnection();

            // 更新序号管理器的发送序号与确认序号。
            this.Context.SeqNoManager.GetAndUpdateSendSeq();
            this.Context.SeqNoManager.UpdateAckSeq(theFrame.SequenceNo);

            // 将CC帧中的AU2提交到MASL。
            this.Context.Observer.OnAleUserDataArrival(ccData.UserData);
        }
Ejemplo n.º 10
0
        public override void HandleDataTransmissionFrame(AleTunnel theConnection, Frames.AleFrame theFrame)
        {
            var aleData = theFrame.UserData as AleDataTransmission;

            this.Context.Observer.OnAleUserDataArrival(aleData.UserData);
        }
Ejemplo n.º 11
0
 public virtual void HandleDataTransmissionFrame(AleTunnel theConnection, AleFrame theFrame)
 {
     LogUtility.Error(string.Format("{0}: {1}.{2} not implement!",
                                    this.Context.RsspEP.ID, this.GetType().Name,
                                    new StackFrame(0).GetMethod().Name.Split('.').Last()));
 }