@Override public void receiveData(final RawData raw) { LOG.log(Level.INFO, "Received request: {0}", new String(raw.getBytes())); connector.send(new RawData("ACK".getBytes(), raw.getAddress(), raw.getPort())); } }
/** * {@inheritDoc} */ @Override public final void send(RawData msg) { if (msg == null) { LOGGER.finest("Ignoring NULL msg ..."); } else if (msg.getBytes().length > MAX_PLAINTEXT_FRAGMENT_LENGTH) { throw new IllegalArgumentException("Message data must not exceed " + MAX_PLAINTEXT_FRAGMENT_LENGTH + " bytes"); } else { boolean queueFull = !outboundMessages.offer(msg); if (queueFull) { LOGGER.log(Level.WARNING, "Outbound message queue is full! Dropping outbound message to peer [{0}]", msg.getInetSocketAddress()); } } }
@Override public void send(RawData msg) { if (msg.getMessageCallback() != null) { msg.getMessageCallback().onContextEstablished(context); latch.countDown(); } sentLatch.countDown(); }
@Override public void send(RawData msg) { Channel channel = activeChannels.get(msg.getInetSocketAddress()); if (channel == null) { // TODO: Is it worth allowing opening a new connection when in server mode? LOGGER.log(Level.WARNING, "Attempting to send message to an address without an active connection {0}", msg.getAddress()); return; } channel.writeAndFlush(Unpooled.wrappedBuffer(msg.getBytes())); }
@Override public void receiveData(final RawData raw) { if (raw.getAddress() == null) throw new NullPointerException(); if (raw.getPort() == 0) throw new NullPointerException(); // Create a new task to process this message Runnable task = new Runnable() { public void run() { receiveMessage(raw); } }; runInProtocolStage(task); }
private void receiveMessage(RawData raw) { DataParser parser = new DataParser(raw.getBytes()); } catch (IllegalStateException e) { StringBuffer log = new StringBuffer("message format error caused by ") .append(raw.getInetSocketAddress()); if (!parser.isReply()) { rst.setMID(parser.getMID()); rst.setToken(new byte[0]); rst.setDestination(raw.getAddress()); rst.setDestinationPort(raw.getPort()); for (MessageInterceptor interceptor:interceptors) interceptor.sendEmptyMessage(rst); request.setSource(raw.getAddress()); request.setSourcePort(raw.getPort()); request.setSenderIdentity(raw.getSenderIdentity()); response.setSource(raw.getAddress()); response.setSourcePort(raw.getPort()); coapstack.receiveResponse(exchange, response); } else if (response.getType() != Type.ACK) { LOGGER.fine("Rejecting unmatchable response from " + raw.getInetSocketAddress()); reject(response); message.setSource(raw.getAddress()); message.setSourcePort(raw.getPort());
/** * Instantiates a new raw data for a message received from a peer. * * @param data the data that is to be sent or has been received. * @param address the IP address and port the data has been received from. * @param clientIdentity the identity of the authenticated sender of the message * (or <code>null</code> if sender is not authenticated). * @param correlationContext additional information regarding the context the message has been * received in. The information contained will usually come from the transport layer, e.g. * the ID of the DTLS session the message has been received in, and can be used to correlate * this message with another (previously sent) message. * @param isMulticast indicates whether the data has been received as a multicast message. * @return the raw data object containing the inbound message. * @throws NullPointerException if data or address is <code>null</code>. */ public static RawData inbound(byte[] data, InetSocketAddress address, Principal clientIdentity, CorrelationContext correlationContext, boolean isMulticast) { return new RawData(data, address, clientIdentity, correlationContext, isMulticast); }
protected void work() throws InterruptedException, IOException { RawData raw = outgoing.take(); // Blocking datagram.setData(raw.getBytes()); datagram.setAddress(raw.getAddress()); datagram.setPort(raw.getPort()); if (LOGGER.isLoggable(Level.FINER)) { LOGGER.log(Level.FINER, "UDPConnector ({0}) sends {1} bytes to {2}:{3}", new Object[]{socket.getLocalSocketAddress(), datagram.getLength(), datagram.getAddress(), datagram.getPort()}); } socket.send(datagram); } }
@Override public void receiveData(RawData raw) { LOG.log(Level.INFO, "Received response: {0}", new String(raw.getBytes())); latch.countDown(); dtlsConnector.destroy(); } });
private void sendMessage(final RawData message, final DTLSSession session) { try { Record record = new Record( ContentType.APPLICATION_DATA, session.getWriteEpoch(), session.getSequenceNumber(), new ApplicationMessage(message.getBytes(), message.getInetSocketAddress()), session); if (message.getMessageCallback() != null) { CorrelationContext ctx = new DtlsCorrelationContext( session.getSessionIdentifier().toString(), String.valueOf(session.getWriteEpoch()), session.getWriteStateCipher()); message.getMessageCallback().onContextEstablished(ctx); } sendRecord(record); } catch (GeneralSecurityException e) { LOGGER.log(Level.FINE, String.format("Cannot send APPLICATION record to peer [%s]", message.getInetSocketAddress()), e); } }
@Override public void operationComplete(Future<Channel> future) throws Exception { if (future.isSuccess()) { Channel channel = future.getNow(); try { channel.writeAndFlush(Unpooled.wrappedBuffer(msg.getBytes())); } finally { channelPool.release(channel); } } else { LOGGER.log(Level.WARNING, "Unable to open connection to " + msg.getAddress(), future.cause()); } } });
msg.setSource(raw.getAddress()); msg.setSourcePort(raw.getPort()); LOGGER.log(Level.FINER, "Silently ignoring non-CoAP message from {0}", raw.getInetSocketAddress()); Level.FINE, "rejected malformed message from [{0}], reason: {1}", new Object[]{raw.getInetSocketAddress(), e.getMessage()}); } else { LOGGER.log(Level.FINER, "discarding malformed message from [{0}]", raw.getInetSocketAddress()); LOGGER.log(Level.FINER, "discarding malformed message from [{0}]", raw.getInetSocketAddress());
@Override public Object getStripe() { return msg.getInetSocketAddress(); }
stream.flush(); return RawData.outbound(stream.toByteArray(), getDestination(address), callback, false);
/** * Verifies that isSecure() detects that the data has been received via a secure channel * based on the correlation context. */ @Test public void testIsSecure() { RawData rawData = RawData.inbound(new byte[]{0x01, 0x02}, SOURCE, null, getSecureCorrelationContext(), false); assertTrue(rawData.isSecure()); rawData = RawData.inbound(new byte[]{0x01, 0x02}, SOURCE, null, getNonSecureCorrelationContext(), false); assertFalse(rawData.isSecure()); rawData = RawData.inbound(new byte[]{0x01, 0x02}, SOURCE, null, null, false); assertFalse(rawData.isSecure()); }
private void receiveResponse(final Response response, final RawData raw) { /* * Logging here causes significant performance loss. * If necessary, add an interceptor that logs the messages, * e.g., the MessageTracer. */ for (MessageInterceptor interceptor:interceptors) { interceptor.receiveResponse(response); } // MessageInterceptor might have canceled if (!response.isCanceled()) { Exchange exchange = matcher.receiveResponse(response, raw.getCorrelationContext()); if (exchange != null) { exchange.setEndpoint(CoapEndpoint.this); response.setRTT(System.currentTimeMillis() - exchange.getTimestamp()); coapstack.receiveResponse(exchange, response); } else if (response.getType() != Type.ACK) { LOGGER.log(Level.FINE, "Rejecting unmatchable response from {0}", raw.getInetSocketAddress()); reject(response); } } }
private RawData createApplicationMessage(ApplicationMessage message, DTLSSession session) { DtlsCorrelationContext context = new DtlsCorrelationContext(session.getSessionIdentifier().toString(), String.valueOf(session.getReadEpoch()), session.getReadStateCipher()); return RawData.inbound(message.getData(), message.getPeer(), session.getPeerIdentity(), context, false); }
/** * Instantiates a new raw data for a message to be sent to a peer. * <p> * The given callback handler is notified when the message has been sent by a <code>Connector</code>. * The information contained in the <code>MessageContext</code> object that is passed in to the * handler may be relevant for matching a response received via a <code>RawDataChannel</code> to a request * sent using this method, e.g. when using a DTLS based connector the context may contain the DTLS session * ID and epoch number which is required to match a response to a request as defined in the CoAP specification. * </p> * <p> * The message context is set via a callback in order to allow <code>Connector</code> implementations to * process (send) messages asynchronously. * </p> * * @param data the data to send. * @param address the IP address and port the data is to be sent to. * @param callback the handler to call when this message has been sent (may be <code>null</code>). * @param useMulticast indicates whether the data should be sent using a multicast message. * @return the raw data object containing the outbound message. * @throws NullPointerException if data or address is <code>null</code>. */ public static RawData outbound(byte[] data, InetSocketAddress address, MessageCallback callback, boolean useMulticast) { RawData result = new RawData(data, address); result.callback = callback; result.multicast = useMulticast; return result; }
protected void work() throws InterruptedException, IOException { RawData raw = outgoing.take(); // Blocking datagram.setData(raw.getBytes()); datagram.setAddress(raw.getAddress()); datagram.setPort(raw.getPort()); if (LOGGER.isLoggable(Level.FINER)) { LOGGER.log(Level.FINER, "UDPConnector ({0}) sends {1} bytes to {2}:{3}", new Object[]{socket.getLocalSocketAddress(), datagram.getLength(), datagram.getAddress(), datagram.getPort()}); } socket.send(datagram); } }
/** * Parses a byte array into a CoAP Message. * * @param raw contains the byte array to parse. * @return the message. * @throws MessageFormatException if the array cannot be parsed into a message. */ public final Message parseMessage(final RawData raw) { return parseMessage(raw.getBytes()); }