/** * 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); }
@Override public void run() { /* * Do not retransmit a message if it has been acknowledged, * rejected, canceled or already been retransmitted for the maximum * number of times. */ try { int failedCount = exchange.getFailedTransmissionCount() + 1; exchange.setFailedTransmissionCount(failedCount); if (message.isAcknowledged()) { LOGGER.finest( "Timeout: message already acknowledged, cancel retransmission of " + message); return; } else if (message.isRejected()) { LOGGER.finest("Timeout: message already rejected, cancel retransmission of " + message); return; } else if (message.isCanceled()) { LOGGER.finest("Timeout: canceled (MID=" + message.getMID() + "), do not retransmit"); return; } else if (failedCount <= max_retransmit) { LOGGER.finer( "Timeout: retransmit message, failed: " + failedCount + ", message: " + message); // Trigger MessageObservers message.retransmitting(); // MessageObserver might have canceled if (!message.isCanceled()) retransmit(); } else { LOGGER.info( "Timeout: retransmission limit reached, exchange failed, message: " + message); exchange.setTimedOut(); message.setTimedOut(true); } } catch (Exception e) { e.printStackTrace(); } }
/** * 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. */ @Override public void receiveResponse(Exchange exchange, Response response) { exchange.setFailedTransmissionCount(0); exchange.getCurrentRequest().setAcknowledged(true); LOGGER.finest("Cancel any retransmission"); exchange.setRetransmissionHandle(null); if (response.getType() == Type.CON && !exchange.getRequest().isCanceled()) { LOGGER.finer("Response is confirmable, send ACK"); EmptyMessage ack = EmptyMessage.newACK(response); sendEmptyMessage(exchange, ack); } if (response.isDuplicate()) { LOGGER.fine("Response is duplicate, ignore it"); } else { super.receiveResponse(exchange, response); } }