/// <summary>
        /// When we receive a Confirmable response, we acknowledge it and it also
        /// counts as acknowledgment for the request. If the response is a duplicate,
        /// we stop it here and do not forward it to the upper layer.
        /// </summary>
        public override void ReceiveResponse(INextLayer nextLayer, Exchange exchange, Response response)
        {
            TransmissionContext ctx = (TransmissionContext)exchange.Remove(TransmissionContextKey);

            if (ctx != null)
            {
                exchange.CurrentRequest.IsAcknowledged = true;
                ctx.Cancel();
            }

            if (response.Type == MessageType.CON && !exchange.Request.IsCancelled)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Response is confirmable, send ACK.");
                }
                EmptyMessage ack = EmptyMessage.NewACK(response);
                SendEmptyMessage(nextLayer, exchange, ack);
            }

            if (response.Duplicate)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Response is duplicate, ignore it.");
                }
            }
            else
            {
                base.ReceiveResponse(nextLayer, exchange, response);
            }
        }
 /// <summary>
 /// When we receive a duplicate of a request, we stop it here and do not
 /// forward it to the upper layer. If the server has already sent a response,
 /// we send it again. If the request has only been acknowledged (but the ACK
 /// has gone lost or not reached the client yet), we resent the ACK. If the
 /// request has neither been responded, acknowledged or rejected yet, the
 /// server has not yet decided what to do with the request and we cannot do
 /// anything.
 /// </summary>
 public override void ReceiveRequest(INextLayer nextLayer, Exchange exchange, Request request)
 {
     if (request.Duplicate)
     {
         // Request is a duplicate, so resend ACK, RST or response
         if (exchange.CurrentResponse != null)
         {
             if (log.IsDebugEnabled)
             {
                 log.Debug("Respond with the current response to the duplicate request");
             }
             base.SendResponse(nextLayer, exchange, exchange.CurrentResponse);
         }
         else if (exchange.CurrentRequest != null)
         {
             if (exchange.CurrentRequest.IsAcknowledged)
             {
                 if (log.IsDebugEnabled)
                 {
                     log.Debug("The duplicate request was acknowledged but no response computed yet. Retransmit ACK.");
                 }
                 EmptyMessage ack = EmptyMessage.NewACK(request);
                 SendEmptyMessage(nextLayer, exchange, ack);
             }
             else if (exchange.CurrentRequest.IsRejected)
             {
                 if (log.IsDebugEnabled)
                 {
                     log.Debug("The duplicate request was rejected. Reject again.");
                 }
                 EmptyMessage rst = EmptyMessage.NewRST(request);
                 SendEmptyMessage(nextLayer, exchange, rst);
             }
             else
             {
                 if (log.IsDebugEnabled)
                 {
                     log.Debug("The server has not yet decided what to do with the request. We ignore the duplicate.");
                 }
                 // The server has not yet decided, whether to acknowledge or
                 // reject the request. We know for sure that the server has
                 // received the request though and can drop this duplicate here.
             }
         }
         else
         {
             // Lost the current request. The server has not yet decided what to do.
         }
     }
     else
     {
         // Request is not a duplicate
         exchange.CurrentRequest = request;
         base.ReceiveRequest(nextLayer, exchange, request);
     }
 }
Exemple #3
0
 /// <summary>
 /// Accept this exchange and therefore the request. Only if the request's
 /// type was a <code>CON</code> and the request has not been acknowledged
 /// yet, it sends an ACK to the client.
 /// </summary>
 public virtual void SendAccept()
 {
     System.Diagnostics.Debug.Assert(_origin == Origin.Remote);
     if (_request.Type == MessageType.CON && !_request.IsAcknowledged)
     {
         _request.IsAcknowledged = true;
         EmptyMessage ack = EmptyMessage.NewACK(_request);
         _endpoint.SendEmptyMessage(this, ack);
     }
 }