Example #1
0
        ReturnCode Send(SocketSession session, byte[] sendData, bool doNotEncrypt = false)
        {
            if (!doNotEncrypt)
            {
                switch (this.encryptLevel)
                {
                case 1: sendData = Crypto.SimpleXorEncrypt(sendData, session.encryptionKey); break;

                case 2: sendData = Crypto.AESEncrypt(sendData, session.encryptionKey); break;
                }
            }

            var socket = session.socket;

            if (null == socket)
            {
                return(ReturnCode.ERROR_INVALID_SESSIONID);
            }
            else if (false == socket.Connected)
            {
                return(ReturnCode.ERROR_SESSION_CLOSED);
            }

            if (0 == Interlocked.CompareExchange(ref session.isSendAsyncCalled, 1, 0))
            {
                return(_Send(session, socket, sendData));
            }
            else
            {
                session.sendQueue.Enqueue(sendData);
                VerifyMissingSend(session);
            }

            return(ReturnCode.SUCCESS);
        }
Example #2
0
 void VerifyMissingSend(SocketSession session)
 {
     if ((0 == session.isSendAsyncCalled) && (session.sendQueue.Count > 0))
     {
         byte[] emptyData = new byte[0];
         Send(session, emptyData, true);
     }
 }
Example #3
0
 byte[] AESDecrypt(SocketSession session, byte[] data)
 {
     try
     {
         return(Crypto.AESDecrypt(data, session.encryptionKey));
     }
     catch
     {
         return(null);
     }
 }
Example #4
0
 byte[] SimpleXorEncrypt(SocketSession session, byte[] data)
 {
     try
     {
         return(Crypto.SimpleXorEncrypt(data, session.encryptionKey));
     }
     catch
     {
         return(null);
     }
 }
Example #5
0
 bool AssignEncyptionKey(SocketSession session, byte[] data)
 {
     try
     {
         session.encryptionKey = Crypto.RSADecrypt(Encoding.UTF8.GetString(data), this.privateKey);
         return(true);
     }
     catch
     {
         return(false);
     }
 }
Example #6
0
        void OnSendAsyncCompleted(SocketSession session, Socket socket, SocketAsyncEventArgs args)
        {
            var sid = session.id;

            if ((args.SocketError != SocketError.Success) || (0 == args.BytesTransferred))
            {
                this.socketResourceManager.CloseSocket(socket);
                var list = args.BufferList as List <ArraySegment <byte> >;
                this.socketResourceManager.FreeArraySegmentList(list);
                this.socketResourceManager.FreeSocketAsyncEventArgs(args);
                return;
            }

            byte[] qitem;
            if (session.sendQueue.TryPeek(out qitem))
            {
                var nlist = args.BufferList as List <ArraySegment <byte> >;
                nlist.Clear();
                while (session.sendQueue.TryDequeue(out qitem))
                {
                    nlist.Add(new ArraySegment <byte>(BitConverter.GetBytes(qitem.Length)));
                    nlist.Add(new ArraySegment <byte>(qitem));
                }
                args.BufferList = nlist;

                bool asyncResult = true;
                try
                {
                    session.IncPendingCount(this.utcNow);
                    asyncResult = socket.SendAsync(args);
                }
                catch
                {
                    session.DecPendingCount(this.utcNow);
                    this.socketResourceManager.CloseSocket(socket);
                    var list = args.BufferList as List <ArraySegment <byte> >;
                    this.socketResourceManager.FreeArraySegmentList(list);
                    this.socketResourceManager.FreeSocketAsyncEventArgs(args);
                    return;
                }

                if (false == asyncResult)
                {
                    OnSocketIOCompleted(session.socket, args);
                }
            }
            else
            {
                Interlocked.CompareExchange(ref session.isSendAsyncCalled, 0, 1);
                this.socketResourceManager.FreeSocketAsyncEventArgs(args);
                VerifyMissingSend(session);
            }
        }
Example #7
0
        void OnConnectAsyncCompleted(SocketSession session, Socket socket, SocketAsyncEventArgs args)
        {
            var sid = session.id;

            if (args.SocketError != SocketError.Success)
            {
                this.socketResourceManager.CloseSocket(socket);
                this.socketResourceManager.FreeSocketAsyncEventArgs(args);

                this.userCallback(CallbackEventType.CONNECT_FAIL, session, args.SocketError);
                DisposeSocketSession(session);
                return;
            }

            if (this.encryptLevel > 0)
            {
                // wait for public key receive
            }
            else
            {
                this.userCallback(CallbackEventType.CONNECT_SUCCESS, session, null);
                session.isUserCallbackHappen = true;
            }

            if (socket.Connected)
            {
                bool asyncResult = true;
                try
                {
                    session.IncPendingCount(this.utcNow);

                    args.SetBuffer(session.receiveBuffer, 0, session.receiveBuffer.Length);
                    asyncResult = socket.ReceiveAsync(args);
                }
                catch
                {
                    session.DecPendingCount(this.utcNow);
                    this.socketResourceManager.CloseSocket(socket);
                    this.socketResourceManager.FreeSocketAsyncEventArgs(args);
                    return;
                }

                if (false == asyncResult)
                {
                    OnSocketIOCompleted(socket, args);
                }
            }
        }
        public SocketSession AllocSocketSession(Socket socket, SessionType sessionType, int receiveBufferSize = 8192)
        {
            SocketSession session = null;

            if (false == this.socketSessionPool.TryDequeue(out session))
            {
                session = new SocketSession(socket, receiveBufferSize);
            }
            else
            {
                session.Clear();
                session.socket = socket;
            }

            session.sessionType = sessionType;
            session.id          = Interlocked.Increment(ref this.socketSessionID);
            return(session);
        }
Example #9
0
        void OnReceiveAsyncCompleted(SocketSession session, Socket socket, SocketAsyncEventArgs args)
        {
            var sid = session.id;

            if ((args.SocketError != SocketError.Success) || (0 == args.BytesTransferred))
            {
                this.socketResourceManager.CloseSocket(socket);
                this.socketResourceManager.FreeSocketAsyncEventArgs(args);
                return;
            }

            session.IncPendingCount(this.utcNow); // to prevent disconnect while receive data processing
            var ret = ProcessReceivedData(session, socket, args);

            session.DecPendingCount(this.utcNow);

            if (false == ret)
            {
                this.socketResourceManager.CloseSocket(socket);
                this.socketResourceManager.FreeSocketAsyncEventArgs(args);
                return;
            }

            bool asyncResult = true;

            try
            {
                session.IncPendingCount(this.utcNow);
                asyncResult = socket.ReceiveAsync(args);
            }
            catch
            {
                session.DecPendingCount(this.utcNow);
                this.socketResourceManager.CloseSocket(socket);
                this.socketResourceManager.FreeSocketAsyncEventArgs(args);
                return;
            }

            if (false == asyncResult)
            {
                OnSocketIOCompleted(socket, args);
            }
        }
Example #10
0
        void OnSocketIOCompleted(object sender, SocketAsyncEventArgs args)
        {
            var           socket  = sender as Socket;
            SocketSession session = null;

            if (args.UserToken != null)
            {
                session = args.UserToken as SocketSession;
                session.DecPendingCount(this.utcNow);
            }
            else if (args.LastOperation != SocketAsyncOperation.Accept)
            {
                var list = args.BufferList as List <ArraySegment <byte> >;
                if (null != list)
                {
                    this.socketResourceManager.FreeArraySegmentList(list);
                }

                this.socketResourceManager.FreeSocketAsyncEventArgs(args);
                return;
            }

            switch (args.LastOperation)
            {
            case SocketAsyncOperation.Accept:
                OnAcceptAsyncCompleted(socket, args);
                break;

            case SocketAsyncOperation.Connect:
                OnConnectAsyncCompleted(session, socket, args);
                break;

            case SocketAsyncOperation.Send:
                OnSendAsyncCompleted(session, socket, args);
                break;

            case SocketAsyncOperation.Receive:
                OnReceiveAsyncCompleted(session, socket, args);
                break;
            }
        }
Example #11
0
        ReturnCode _Send(SocketSession session, Socket socket, byte[] sendData)
        {
            var sid  = session.id;
            var args = this.socketResourceManager.AllocSocketAsyncEventArgs(OnSocketIOCompleted);

            args.UserToken = session;

            var list = this.socketResourceManager.AllocArraySegmentList();

            list.Add(new ArraySegment <byte>(BitConverter.GetBytes(sendData.Length)));
            list.Add(new ArraySegment <byte>(sendData));
            args.BufferList = list;

            bool asyncResult = true;

            try
            {
                session.IncPendingCount(this.utcNow);
                asyncResult = socket.SendAsync(args);
            }
            catch
            {
                session.DecPendingCount(this.utcNow);
                this.socketResourceManager.CloseSocket(socket);
                this.socketResourceManager.FreeSocketAsyncEventArgs(args);
                this.socketResourceManager.FreeArraySegmentList(list);
                return(ReturnCode.ERROR_SESSION_CLOSED);
            }

            if (false == asyncResult)
            {
                OnSocketIOCompleted(socket, args);
            }

            return(ReturnCode.SUCCESS);
        }
Example #12
0
 void DisposeSocketSession(SocketSession session)
 {
     RemoveFromSocketSessionDic(session);
     this.socketResourceManager.FreeSocketSession(session);
 }
Example #13
0
        bool ProcessReceivedData(SocketSession session, Socket socket, SocketAsyncEventArgs args)
        {
            var dataSize = session.receiveBufferStoredDataSize + args.BytesTransferred;
            var readPos  = 0;
            var sid      = session.id;

            long readCount = long.MaxValue;

            if (session.readCount < 10)
            {
                readCount = Interlocked.Increment(ref session.readCount);
            }

            while (dataSize >= 4)
            {
                if (!socket.Connected)
                {
                    return(false);
                }

                var packetSize = BitConverter.ToInt32(session.receiveBuffer, readPos);
                if (packetSize < 0)
                {
                    // wrong packet size
                    Console.WriteLine("wrong packet size!!!");
                    return(false);
                }

                dataSize -= 4;
                readPos  += 4;

                if (dataSize >= packetSize)
                {
                    if (packetSize > 0)
                    {
                        var seg = new ArraySegment <byte>(session.receiveBuffer, readPos, packetSize);

                        if (this.encryptLevel > 0)
                        {
                            switch (session.sessionType)
                            {
                            case SessionType.ACCEPTED_SESSION:
                                switch (readCount)
                                {
                                case 1:         // peer encryption key received. decrypt & store
                                    if (!AssignEncyptionKey(session, seg.ToArray <byte>()))
                                    {
                                        return(false);
                                    }

                                    Send(session, Encoding.UTF8.GetBytes(this.encryptionKeyExchangeSuccess), true);
                                    this.userCallback(CallbackEventType.ACCEPT_SUCCESS, session.userTokenNum, sid);
                                    session.isUserCallbackHappen = true;
                                    break;

                                default:
                                    // decrypt with session.encrytionKey and callback
                                    switch (this.encryptLevel)
                                    {
                                    case 1:
                                        var sxe = SimpleXorEncrypt(session, seg.ToArray <byte>());
                                        if (sxe == null)
                                        {
                                            return(false);
                                        }
                                        this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, sxe);
                                        break;

                                    case 2:
                                        var aee = AESDecrypt(session, seg.ToArray <byte>());
                                        if (aee == null)
                                        {
                                            return(false);
                                        }
                                        this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, aee);
                                        break;
                                    }
                                    break;
                                }
                                break;

                            case SessionType.CONNECTED_SESSION:
                                switch (readCount)
                                {
                                case 1:         // public key received. send my encryption key
                                    session.encryptionKey = Crypto.CreateRandomString32(0);
                                    string ecdata = string.Empty;
                                    try
                                    {
                                        ecdata = Crypto.RSAEncrypt(session.encryptionKey, Encoding.UTF8.GetString(seg.ToArray <byte>()));
                                    }
                                    catch
                                    {
                                        return(false);
                                    }
                                    Send(session, Encoding.UTF8.GetBytes(ecdata), true);
                                    break;

                                case 2:         // connection established
                                    if (!Encoding.UTF8.GetString(seg.ToArray <byte>()).Equals(this.encryptionKeyExchangeSuccess))
                                    {
                                        return(false);
                                    }
                                    this.userCallback(CallbackEventType.CONNECT_SUCCESS, session, null);
                                    session.isUserCallbackHappen = true;
                                    break;

                                default:
                                    // decrypt with session.encrytionKey and callback
                                    switch (this.encryptLevel)
                                    {
                                    case 1:
                                        var sxe = SimpleXorEncrypt(session, seg.ToArray <byte>());
                                        if (sxe == null)
                                        {
                                            return(false);
                                        }
                                        this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, sxe);
                                        break;

                                    case 2:
                                        var aee = AESDecrypt(session, seg.ToArray <byte>());
                                        if (aee == null)
                                        {
                                            return(false);
                                        }
                                        this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, aee);
                                        break;
                                    }
                                    break;
                                }
                                break;
                            }
                        }
                        else
                        {
                            this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, seg.ToArray <byte>());
                        }
                    }

                    dataSize -= packetSize;
                    readPos  += packetSize;
                }
                else
                {
                    dataSize += 4;
                    readPos  -= 4;
                    break;
                }
            }

            session.receiveBufferStoredDataSize = dataSize;
            if (dataSize > 0)
            {
                Buffer.BlockCopy(session.receiveBuffer, readPos, session.receiveBuffer, 0, dataSize);
                args.SetBuffer(session.receiveBuffer, dataSize, session.receiveBuffer.Length - dataSize);
            }
            else
            {
                args.SetBuffer(session.receiveBuffer, 0, session.receiveBuffer.Length);
            }

            return(true);
        }
Example #14
0
        void RemoveFromSocketSessionDic(SocketSession session)
        {
            SocketSession ss;

            this.socketSessionIdDic.TryRemove(session.id, out ss);
        }
Example #15
0
 void AddToSocketSessionDic(SocketSession session)
 {
     this.socketSessionIdDic.TryAdd(session.id, session);
 }
Example #16
0
 public ReturnCode CloseSession(SocketSession session)
 {
     this.socketResourceManager.CloseSocket(session.socket);
     return(ReturnCode.SUCCESS);
 }
 public void FreeSocketSession(SocketSession session)
 {
     session.id = 0;
     this.socketSessionPool.Enqueue(session);
 }
Example #18
0
 public ReturnCode Send(SocketSession session, byte[] sendData)
 {
     return(Send(session, sendData, doNotEncrypt: false));
 }