private KeyToken(byte[] token, byte[] address, int port) { if (token == null) { throw new NullPointerException("token bytes must not be null"); } else if (address == null) { throw new NullPointerException("address must not be null"); } else if (port < 0 || port > MAX_PORT_NO) { throw new IllegalArgumentException("port must be a 16 bit unsigned int"); } this.token = Arrays.copyOf(token, token.length); this.address = address; this.port = port; this.hash = createHash(); }
@Override public Exchange receiveResponse(final Response response, final CorrelationContext responseContext) { final Exchange.KeyToken idByToken = Exchange.KeyToken.fromInboundMessage(response); Exchange exchange = exchangeStore.get(idByToken); if (exchange == null) { // There is no exchange with the given token - ignore response return null; } else if (isResponseRelatedToRequest(exchange, responseContext)) { return exchange; } else { LOGGER.log(Level.INFO, "Ignoring potentially forged response for token {0} with non-matching correlation context", idByToken); return null; } }
KeyToken idByToken = KeyToken.fromInboundMessage(response); LOGGER.log(Level.FINER, "received response {0}", response); Exchange exchange = exchangeStore.get(idByToken);
KeyToken idByToken = new KeyToken(response.getToken());
exchange.getOrigin()}); } else { KeyToken idByToken = KeyToken.fromOutboundMessage(originRequest); exchangeStore.remove(idByToken, exchange); if (!originRequest.isObserve()) {
exchange.getOrigin()}); } else { KeyToken idByToken = new KeyToken(originRequest.getToken()); exchangesByToken.remove(idByToken, exchange); LOGGER.log(Level.FINER, "Exchange [{0}, origin: {1}] completed", new Object[]{ idByToken, exchange.getOrigin() });
exchange.getOrigin()}); } else { KeyToken idByToken = KeyToken.fromOutboundMessage(originRequest); exchangeStore.remove(idByToken, exchange); if(!originRequest.isObserve()) {
private void registerWithToken(final Exchange exchange) { Request request = exchange.getCurrentRequest(); KeyToken idByToken; if (request.getToken() == null) { idByToken = tokenProvider.getUnusedToken(request); request.setToken(idByToken.getToken()); } else { idByToken = KeyToken.fromOutboundMessage(request); // ongoing requests may reuse token if (!(exchange.getFailedTransmissionCount() > 0 || request.getOptions().hasBlock1() || request.getOptions().hasBlock2() || request.getOptions().hasObserve()) && tokenProvider.isTokenInUse(idByToken)) { LOGGER.log(Level.WARNING, "Manual token overrides existing open request: {0}", idByToken); } } exchangesByToken.put(idByToken, exchange); }
/** * Creates a new key for a token and an endpoint address. * * @param token the token. * @param address the endpoint's address. * @param port the endpoint's port. * @return the key. * @throws NullPointerException if token or address is {@code null} * @throws IllegalArgumentException if port < 0 or port > 65535. */ public static KeyToken fromValues(byte[] token, byte[] address, int port) { return new KeyToken(token, address, port); }
/** * Creates a new key for an inbound CoAP message. * <p> * The key will be scoped to the message's source endpoint. * * @param msg the message. * @return the key. */ public static KeyToken fromInboundMessage(final Message msg) { return new KeyToken(msg.getToken(), msg.getSource().getAddress(), msg.getSourcePort()); }
@Test public void testReceiveResponseForObserveDoesNotReleaseToken() { // GIVEN a request without token sent UdpMatcher matcher = newMatcher(false); Exchange exchange = sendObserveRequest(matcher); // WHEN observe request gets completed exchange.completeCurrentRequest(); // THEN assert that token got not released KeyToken keyToken = KeyToken.fromOutboundMessage(exchange.getCurrentRequest()); assertThat(tokenProvider.isTokenInUse(keyToken), is(true)); }
/** * Creates a new key for an outbound CoAP message. * <p> * The key will be scoped to the message's destination endpoint. * * @param msg the message. * @return the key. */ public static KeyToken fromOutboundMessage(final Message msg) { return new KeyToken(msg.getToken(), msg.getDestination().getAddress(), msg.getDestinationPort()); }
private KeyToken createUnusedToken(final Message message) { byte[] address = message.getDestination().getAddress(); byte[] token = new byte[tokenSizeLimit]; KeyToken result; // TODO what to do when there are no more unused tokens left? do { rng.nextBytes(token); result = KeyToken.fromValues(token, address, message.getDestinationPort()); } while (!usedTokens.add(result)); return result; } }
@Test public void testReceiveResponseReleasesToken() { // GIVEN a request without token sent UdpMatcher matcher = newMatcher(false); Exchange exchange = sendRequest(matcher, null); // WHEN request gets completed exchange.completeCurrentRequest(); // THEN assert that token got released KeyToken keyToken = KeyToken.fromOutboundMessage(exchange.getCurrentRequest()); assertThat(tokenProvider.isTokenInUse(keyToken), is(false)); }