/** * If we receive an ACK or RST, we mark the outgoing request or response as acknowledged or * rejected respectively and cancel its retransmission. */ @Override public void receiveEmptyMessage(Exchange exchange, EmptyMessage message) { exchange.setFailedTransmissionCount(0); // TODO: If this is an observe relation, the current response might not // be the one that is being acknowledged. The current response might // already be the next NON notification. if (message.getType() == Type.ACK) { if (exchange.getOrigin() == Origin.LOCAL) { exchange.getCurrentRequest().setAcknowledged(true); } else { exchange.getCurrentResponse().setAcknowledged(true); } } else if (message.getType() == Type.RST) { if (exchange.getOrigin() == Origin.LOCAL) { exchange.getCurrentRequest().setRejected(true); } else { exchange.getCurrentResponse().setRejected(true); } } else { LOGGER.warning("Empty messgae was not ACK nor RST: " + message); } LOGGER.finer("Cancel retransmission"); exchange.setRetransmissionHandle(null); super.receiveEmptyMessage(exchange, message); }
/** * 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. */ @Override public void receiveRequest(Exchange exchange, Request request) { if (request.isDuplicate()) { // Request is a duplicate, so resend ACK, RST or response if (exchange.getCurrentResponse() != null) { LOGGER.fine("Respond with the current response to the duplicate request"); // Do not restart retransmission cycle super.sendResponse(exchange, exchange.getCurrentResponse()); } else if (exchange.getCurrentRequest().isAcknowledged()) { LOGGER.fine( "The duplicate request was acknowledged but no response computed yet. Retransmit ACK"); EmptyMessage ack = EmptyMessage.newACK(request); sendEmptyMessage(exchange, ack); } else if (exchange.getCurrentRequest().isRejected()) { LOGGER.fine("The duplicate request was rejected. Reject again"); EmptyMessage rst = EmptyMessage.newRST(request); sendEmptyMessage(exchange, rst); } else { LOGGER.fine( "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 { // Request is not a duplicate exchange.setCurrentRequest(request); super.receiveRequest(exchange, request); } }