Пример #1
0
 public static bool AddResponse(Message pRespMsg)
 {
     try
     {
         Thread vReqThread = null;
         for (int t = 0; t <= 3; t++)
         {
             if (vResponseSessions.TryAdd(pRespMsg.SessionID, pRespMsg))
             {
                 //Message StoreMsg = (Message)vResponseSessions[pRespMsg.SessionID];
                 //StackLog.Write2ErrorLog("ResponseWaiter.AddReponse", StoreMsg.ToString());
                 //if (StoreMsg.avps.Count == 0)
                 //    StackLog.Write2ErrorLog("ResponseWaiter.AddResponse", "Response Msg has no AVP's for Session:" + StoreMsg.SessionID);
                 for (int tq = 0; tq <= 3; tq++)
                 {
                     if (vRequestSessions.TryRemove(pRespMsg.SessionID, out vReqThread))
                     {
                         //interrupting sessionid:
                         Common.StackLog.Write2TraceLog("ResponseWaiter.AddResponse() ", " Interrupting Session (ID: " + pRespMsg.SessionID + ") Thread: " + vReqThread.Name + " (" + vReqThread.ThreadState.ToString() + ")..\r\n");
                         vReqThread.Interrupt();
                         break;
                     }
                 }
                 return(true);
             }
         }
         return(false);
     }
     catch (Exception ex)
     {
         StackLog.Write2ErrorLog("ResponseWaiter.AddResponse", "Exception :" + ex.Message);
         return(false);
     }
 }
Пример #2
0
 public static Message GetResponse(string pReqKey)
 {
     try
     {
         Message vRespMsg     = null;
         bool    vRespRemoved = false;
         for (int t = 0; t <= 3; t++)
         {
             if (vResponseSessions.ContainsKey(pReqKey))
             {
                 //for (int t = 0; t <= 3; t++)
                 //{
                 if (vResponseSessions.TryRemove(pReqKey, out vRespMsg))
                 {
                     vRespRemoved = true;
                     break;
                 }
                 //}
             }
             else
             {
                 StackLog.Write2ErrorLog("ResponseWaiter.GetResponse", "Response Key not found for SessionID:" + pReqKey);
             }
         }
         if (!vRespRemoved)
         {
             StackLog.Write2ErrorLog("ResponseWaiter.GetResponse", "Unable to remove Response for SessionID:" + pReqKey);
         }
         return(vRespMsg);
     }
     catch (Exception ex)
     {
         StackLog.Write2ErrorLog("ResponseWaiter.GetResponse", "Exception :" + ex.Message);
         return(null);
     }
 }
        private void ReceiveCallback(IAsyncResult result)
        {
            int         bytesRead;
            StateObject state  = (StateObject)result.AsyncState;
            Socket      client = state.workSocket;

            try
            {
                // Retrieve the state object and the client socket
                try
                {
                    bytesRead = client.EndReceive(result);
                }
                catch (Exception e)
                {
                    //An error has occured when reading
                    Common.StackLog.Write2ErrorLog("ReceiveCallBack", "Error:" + e.Message + " Stack:" + e.StackTrace);
                    Thread t = new Thread(new ParameterizedThreadStart(Reconnect));
                    t.Start(stackContext);
                    return;
                }
                if (bytesRead == 0)
                {
                    //The connection has been closed.
                    //Reconnect
                    Common.StackLog.Write2ErrorLog("ReceiveCallBack", "Zero Bytes Read");
                    Thread t = new Thread(new ParameterizedThreadStart(Reconnect));
                    t.Start(stackContext);
                    return;
                }

                /// Begin processing Diameter messages , If new data is too large for buffer, reset the buffer and store new data
                //StackLog.Write2TraceLog("ReceiveCallBack", "INIT:Bytesread=" + bytesRead + "\r\nINIT:mLen=" + mLen + "\r\nINIT:mPos=" + mPos);
                if (mLen + bytesRead > MAX_BUFF_SIZE)
                {
                    //StackLog.Write2ErrorLog("ReceiveCallBack", "RESET:mLen=" + mLen + "\r\nRESET:Bytesread=" + bytesRead);

                    if (mLen - mPos > 0)
                    {
                        byte[] tmpBuffer = new byte[mLen - mPos];
                        Array.Copy(responseBuffer, mPos, tmpBuffer, 0, mLen - mPos);
                        responseBuffer = new byte[MAX_BUFF_SIZE];
                        Array.Copy(tmpBuffer, 0, responseBuffer, 0, tmpBuffer.Length);
                        mLen = tmpBuffer.Length;
                        mPos = 0;
                    }
                    else
                    {
                        responseBuffer = new byte[MAX_BUFF_SIZE];
                        mPos           = 0;
                        mLen           = 0;
                    }
                }

                //Append new data into existing Message Buffer
                try
                {
                    //StackLog.Write2ErrorLog("ReceiveCallBack", "Copying Array: mLen: " + mLen + ", Bytesread: " + bytesRead + ", mPos: " + mPos + ", SrcArray len: " + state.buffer.Length + ", DstArray len: " + responseBuffer.Length);
                    Array.Copy(state.buffer, 0, responseBuffer, mLen, bytesRead);
                    mLen = mLen + bytesRead;
                    //StackLog.Write2ErrorLog("ReceiveCallBack", "Array Copied: mLen: " + mLen + ", Bytesread: " + bytesRead + ", mPos: " + mPos + ", SrcArray len: " + state.buffer.Length + ", DstArray len: " + responseBuffer.Length);
                }
                catch (Exception ex)
                {
                    StackLog.Write2ErrorLog("ReceiveCallBack", " Length Error: " + ex.Message + " \nmLen: " + mLen + ", Bytesread: " + bytesRead + ", mPos: " + mPos + ", SrcArray len: " + state.buffer.Length + ", DstArray len: " + responseBuffer.Length);
                    //return;
                    throw ex;
                }

                processData();

                if (client.Connected)
                {
                    //Then start reading from the network again after Parsing recieved Message.
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    StackLog.Write2ErrorLog("ReceiveCallBack", " Socket disconnected, Reconnect Again!");
                    Thread t = new Thread(new ParameterizedThreadStart(Reconnect));
                    t.Start(stackContext);
                }
            }
            catch (Exception e)
            {
                //Then start reading from the network again.
                //state.workSocket.Connect(state.workSocket.RemoteEndPoint);
                Common.StackLog.Write2ErrorLog("ReceiveCallBack", " ReceiveCallback Error:" + e.Message + " Stack:" + e.StackTrace);

                if (client.Connected)
                {
                    //Then start reading from the network again after Parsing recieved Message.
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    StackLog.Write2ErrorLog("ReceiveCallBack", " Exception Socket disconnected, Reconnect Again!");
                    Thread t = new Thread(new ParameterizedThreadStart(Reconnect));
                    t.Start(stackContext);
                }
            }
        }
        /// <summary>
        /// Send Message to the Diameter Peer
        /// </summary>
        /// <param name="MessageBytes"></param>
        /// <param name="TransportType"></param>
        /// <param name="remotePeer"></param>
        public Message SendMessage(Message diameterRequest, Peer destPeer)
        {
            try
            {
                byte[] mgsBytesToSend = diameterRequest.GetBytes();

                //Connect if not connected
                if (stackContext.peers[0].PeerConnection == null || !stackContext.peers[0].PeerConnection.Connected)
                {
                    if (diameterRequest.CommandCode != DiameterMessageCode.CAPABILITY_EXCHANGE)
                    {
                        Common.StackLog.Write2ErrorLog("Transport::SendMessage", "Connection Broken, calling Connect()");
                    }

                    //Connect Diameter Socket
                    Connect();
                }


                Thread pWaiterThread;

                //Just Copy to localThreadWaiter Variable.
                pWaiterThread = Thread.CurrentThread;

                //CCRWaiter vRespWaiter = null;
                //if Message is a CCR message, we need to wait for a response, so add Session to CCRSession
                if (diameterRequest.CommandCode == DiameterMessageCode.CREDIT_CONTROL)
                {
                    ResponseWaiter.AddRequest(diameterRequest.SessionID, pWaiterThread);
                }
                //CER Never Contains a Session ID
                else if (diameterRequest.CommandCode == DiameterMessageCode.CAPABILITY_EXCHANGE)
                {
                    ResponseWaiter.AddRequest("CEX", pWaiterThread);
                    diameterRequest.SessionID = "CEX";
                }
                else
                {
                    StackLog.Write2TraceLog("Transport.SendMessage() ", "UnHandled Message Type:" + diameterRequest.CommandCode);
                    return(null);
                }
                //Record Time
                TimeSpan STime = new TimeSpan(DateTime.Now.Ticks);
                ///////////////////////////////Send Message to the Remote Peer ////////////////////////////////

                //StackLog.Write2TraceLog("\r\nSendMessage", diameterRequest.ToString());
                msgLogger.Write2MessageLog(diameterRequest.ToString());

                Common.StackLog.Write2TraceLog("Transport::SendMessage() ", " Sending Message " + DiameterMessageCode.GetMessageName(diameterRequest.CommandCode, true) + " (" + diameterRequest.SessionID + ") ..");

                destPeer.PeerConnection.GetStream().Write(mgsBytesToSend, 0, mgsBytesToSend.Length);

                //Wait for Response;
                Common.StackLog.Write2TraceLog("Transport::SendMessage() ", " Message Sent, Waiting For Diameter Message Response of Session: " + diameterRequest.SessionID);
                bool isInterrupted = false;
                try
                {
                    //Sleep for 3 Seconds Maximum until interrupted.
                    for (int i = 0; i <= stackContext.CCATimeout * 10; i++)
                    {
                        Thread.Sleep(100);
                    }
                }
                catch (ThreadInterruptedException ex)
                {
                    isInterrupted = true;
                    //StackLog.Write2ErrorLog("SendMessage", "Thread Intrupted for for Response for the Session: " + diameterRequest.SessionID);
                }

                if (isInterrupted)
                {
                    Common.StackLog.Write2TraceLog("Transport.SendMessage() ", " Waiter Thread Response Interrupted for Session: " + diameterRequest.SessionID);
                }
                else
                {
                    Common.StackLog.Write2TraceLog("Transport.SendMessage() ", " Waiter Thread Response Timedout for Session: " + diameterRequest.SessionID);
                }

                //After Thread intrruption get the response here.
                //CEX Dont have any session ID so validate here.
                Message diameterResponse;
                if (ResponseWaiter.ContainsResponse(diameterRequest.SessionID))
                {
                    diameterResponse = ResponseWaiter.GetResponse(diameterRequest.SessionID);
                }
                else
                {
                    Common.StackLog.Write2ErrorLog("Transport::SendMessage", "Response message not available for " + DiameterMessageCode.GetMessageName(diameterRequest.CommandCode, true) + " " + diameterRequest.SessionID);
                    return(null);
                }
                //Check the Recieved Response
                if (diameterResponse != null)
                {
                    Common.StackLog.Write2TraceLog("Transport.SendMessage() ", "Response Message " + DiameterMessageCode.GetMessageName(diameterResponse.CommandCode, false) + " of Request Session: " + diameterRequest.SessionID + " with Response of:" + diameterResponse.SessionID.ToString() + " Received..\r\n");

                    /*if (diameterResponse.avps.Count == 0)
                     * {
                     *  StackLog.Write2ErrorLog("SendMessage", "Response Msg has no AVP's for Session:" + diameterResponse.SessionID);
                     *  StackLog.Write2ErrorLog("SendMessage", diameterResponse.ToString());
                     * }*/
                    ////Log Recieved Message
                    //StackLog.Write2MessageLog(diameterResponse.ToString());
                    msgLogger.Write2MessageLog(diameterResponse.ToString());
                    TimeSpan ETime = new TimeSpan(DateTime.Now.Ticks);
                    diameterResponse.ExecTime = ETime.Subtract(STime).Milliseconds;
                    //diameterResponse.PrintMessage();
                }
                else
                {
                    Common.StackLog.Write2ErrorLog("Transport::SendMessage", "Unable to Receive Response message for " + DiameterMessageCode.GetMessageName(diameterRequest.CommandCode, true) + " " + diameterRequest.SessionID);
                    //Common.StackLog.Write2ErrorLog("Transport::SendMessage", diameterRequest.ToString());
                }

                return(diameterResponse);
            }
            catch (Exception exp)
            {
                StackLog.Write2ErrorLog("DiameterTransport:SendMessage()", "Error:" + exp.Message + " Stack:" + exp.StackTrace.ToString());
                //throw exp;
                return(null);
            }
        }
        private void processData()
        {
            //Common.StackLog.Write2TraceLog("Transport.processData", "Starting processData Thread");
            Message msg = null;

            //while (!DiameterAAAStack.isStopping)
            //{
            while (true)
            {
                try
                {
                    int msgBufLen = mLen - mPos;
                    if (msgBufLen <= 0)
                    {
                        //StackLog.Write2TraceLog("ReceiveCallBack", "buffer processed");
                        try
                        {
                            Thread.Sleep(10);
                        }
                        catch (ThreadInterruptedException)
                        {
                        }
                        break;
                    }

                    //StackLog.Write2TraceLog("ReceiveCallBack", "NEW:msgBufLen=" + msgBufLen);

                    byte[] msgBuffer = new byte[msgBufLen];

                    Array.Copy(responseBuffer, mPos, msgBuffer, 0, msgBufLen);

                    try
                    {
                        msg = new Message(stackContext, msgBuffer);
                    }
                    catch (Exception ex)
                    {
                        //Common.StackLog.Write2ErrorLog("Transport.processData", "Error: " + ex.Message + ", Stack: " + ex.StackTrace);
                        if (ex.Message.Equals("Invalid Protocol Version"))
                        {
                            StackLog.Write2ErrorLog("ReceiveCallBack", "Invalid Protocol Version mPos=" + mPos + ", mLen=" + mLen + ", mBufLen=" + msgBufLen);
                            mPos = mPos + 1;
                            continue;
                        }
                        if (ex.Message.Equals("Invalid Message Length"))
                        {
                            break;
                        }
                        else
                        {
                            throw ex;
                        }
                    }

                    //Set unprocessed message offset
                    mPos = mPos + msg.MessageLength;
                    //ProcessReceivedMsg
                    ProcessreceivedMsg(msg);
                }
                catch (Exception ex)
                {
                    Common.StackLog.Write2ErrorLog("Transport.processData", "Error: " + ex.Message + ", Stack: " + ex.StackTrace);
                    break;
                }
            }
            //}
            //Common.StackLog.Write2TraceLog("Transport.processData", "processData Thread Stopped");
        }