Skip to content

Commit

Permalink
Fix how CoapResponse transport context is applied (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
akolosov-n committed Aug 22, 2024
1 parent 0a74d7f commit 750bbc2
Show file tree
Hide file tree
Showing 10 changed files with 25 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public CoapPacket createResponse(Code responseCode) {

public CoapPacket createResponseFrom(CoapResponse coapResponse) {
CoapPacket response = new CoapPacket(this.getRemoteAddress());
response.setTransportContext(this.transportContext.with(coapResponse.getTransContext()));
response.setTransportContext(coapResponse.getTransContext());
response.setCode(coapResponse.getCode());
response.setToken(getToken());
response.setPayload(coapResponse.getPayload());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ void shouldUseTransportContextFromResponse() {
newCoapPacket(LOCAL_5683).mid(1300).token(13).post().uriPath("/test2").payload("test").context(TransportContext.of(DUMMY_KEY_IN, true)).build(), service
);

assertEquals(newCoapPacket(LOCAL_5683).ack(Code.C205_CONTENT).mid(1300).token(13).payload("ok").context(TransportContext.of(DUMMY_KEY_IN, true).with(DUMMY_KEY_OUT, true)).build(), resp.join());
assertEquals(newCoapPacket(LOCAL_5683).ack(Code.C205_CONTENT).mid(1300).token(13).payload("ok").context(TransportContext.of(DUMMY_KEY_OUT, true)).build(), resp.join());
}
}
4 changes: 2 additions & 2 deletions coap-mbedtls/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ description = "coap-mbedtls"

dependencies {
api(project(":coap-core"))
api("io.github.open-coap:kotlin-mbedtls:1.27.0")
api("io.github.open-coap:kotlin-mbedtls-netty:1.27.0")
api("io.github.open-coap:kotlin-mbedtls:1.28.0")
api("io.github.open-coap:kotlin-mbedtls-netty:1.28.0")

testImplementation(project(":coap-netty"))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@

import static com.mbed.coap.transport.TransportContext.NON_CONFIRMABLE;
import static java.util.concurrent.CompletableFuture.completedFuture;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_SESSION_EXPIRATION_HINT;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_SESSION_SUSPENSION_HINT;
import com.mbed.coap.packet.CoapRequest;
import com.mbed.coap.packet.CoapResponse;
import com.mbed.coap.transport.TransportContext;
import com.mbed.coap.utils.Filter;
import com.mbed.coap.utils.Service;
import java.util.concurrent.CompletableFuture;

public class DtlsSessionExpirationFilter implements Filter.SimpleFilter<CoapRequest, CoapResponse> {
public class DtlsSessionSuspensionFilter implements Filter.SimpleFilter<CoapRequest, CoapResponse> {

@Override
public CompletableFuture<CoapResponse> apply(CoapRequest request, Service<CoapRequest, CoapResponse> service) {
Expand All @@ -35,6 +35,6 @@ public CompletableFuture<CoapResponse> apply(CoapRequest request, Service<CoapRe

return service
.apply(request)
.thenCompose(resp -> completedFuture(resp.withContext(TransportContext.of(DTLS_SESSION_EXPIRATION_HINT, true))));
.thenCompose(resp -> completedFuture(resp.withContext(TransportContext.of(DTLS_SESSION_SUSPENSION_HINT, true))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class DtlsTransportContext {
public static final TransportContext.Key<String> DTLS_PEER_CERTIFICATE_SUBJECT = new TransportContext.Key<>(null);
public static final TransportContext.Key<byte[]> DTLS_CID = new TransportContext.Key<>(null);
public static final TransportContext.Key<Instant> DTLS_SESSION_START_TIMESTAMP = new TransportContext.Key<>(null);
public static final TransportContext.Key<Boolean> DTLS_SESSION_EXPIRATION_HINT = new TransportContext.Key<>(false);
public static final TransportContext.Key<Boolean> DTLS_SESSION_SUSPENSION_HINT = new TransportContext.Key<>(false);

public static final BiFunction<CoapPacket, ChannelHandlerContext, DatagramPacket> DTLS_COAP_TO_DATAGRAM_CONVERTER = (coapPacket, ctx) -> {
ByteBuf buf = ctx.alloc().buffer(coapPacket.getPayload().size() + 128);
Expand All @@ -49,7 +49,7 @@ public static TransportContext toTransportContext(DtlsSessionContext dtlsSession

TransportContext dtlsContext = TransportContext
.of(DTLS_AUTHENTICATION, dtlsSessionContext.getAuthenticationContext())
.with(DTLS_SESSION_EXPIRATION_HINT, dtlsSessionContext.getSessionExpirationHint());
.with(DTLS_SESSION_SUSPENSION_HINT, dtlsSessionContext.getSessionSuspensionHint());
if (dtlsSessionContext.getPeerCertificateSubject() != null) {
dtlsContext = dtlsContext.with(DTLS_PEER_CERTIFICATE_SUBJECT, dtlsSessionContext.getPeerCertificateSubject());
}
Expand All @@ -69,7 +69,7 @@ public static DtlsSessionContext toDtlsSessionContext(TransportContext transport
transportContext.get(DTLS_PEER_CERTIFICATE_SUBJECT),
transportContext.get(DTLS_CID),
transportContext.get(DTLS_SESSION_START_TIMESTAMP),
transportContext.get(DTLS_SESSION_EXPIRATION_HINT)
transportContext.get(DTLS_SESSION_SUSPENSION_HINT)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void stop() {
@Override
public CompletableFuture<Boolean> sendPacket(CoapPacket coapPacket) {
ByteBuffer buf = ByteBuffer.wrap(CoapSerializer.serialize(coapPacket));
return dtlsTransport.send(new Packet<>(buf, coapPacket.getRemoteAddress()));
return dtlsTransport.send(new Packet<>(buf, coapPacket.getRemoteAddress(), DtlsTransportContext.toDtlsSessionContext(coapPacket.getTransportContext())));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.junit.jupiter.api.Test;

class DtlsSessionExpirationFilterTest {
private final Service<CoapRequest, CoapResponse> service = (new DtlsSessionExpirationFilter()).then(coapRequest -> completedFuture(of(Code.C201_CREATED)));
private final Service<CoapRequest, CoapResponse> service = (new DtlsSessionSuspensionFilter()).then(coapRequest -> completedFuture(of(Code.C201_CREATED)));

@Test
void shouldReturnBadRequestWhenRequestIsConfirmable() {
Expand All @@ -37,6 +37,6 @@ void shouldReturnBadRequestWhenRequestIsConfirmable() {
void shouldReturnResponseWithExpirationHint() {
CoapResponse resp = service.apply(CoapRequest.get("/test").context(TransportContext.of(TransportContext.NON_CONFIRMABLE, true)).build()).join();
assertEquals(Code.C201_CREATED, resp.getCode());
assertTrue(resp.getTransContext().get(DtlsTransportContext.DTLS_SESSION_EXPIRATION_HINT));
assertTrue(resp.getTransContext().get(DtlsTransportContext.DTLS_SESSION_SUSPENSION_HINT));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_AUTHENTICATION;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_CID;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_PEER_CERTIFICATE_SUBJECT;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_SESSION_EXPIRATION_HINT;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_SESSION_START_TIMESTAMP;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_SESSION_SUSPENSION_HINT;
import com.mbed.coap.transport.TransportContext;
import java.time.Instant;
import java.util.Collections;
Expand All @@ -41,7 +41,7 @@ void shouldConvertEmptyDtlsSessionContext() {
assertNull(transCtx.get(DTLS_PEER_CERTIFICATE_SUBJECT));
assertNull(transCtx.get(DTLS_CID));
assertNull(transCtx.get(DTLS_SESSION_START_TIMESTAMP));
assertFalse(transCtx.get(DTLS_SESSION_EXPIRATION_HINT));
assertFalse(transCtx.get(DTLS_SESSION_SUSPENSION_HINT));

assertEquals(transCtx, TransportContext.EMPTY);
}
Expand All @@ -57,6 +57,6 @@ void shouldConvertDtlsSessionContext() {
assertEquals("CN:aa", transCtx.get(DTLS_PEER_CERTIFICATE_SUBJECT));
assertEquals(Instant.ofEpochSecond(123456789), transCtx.get(DTLS_SESSION_START_TIMESTAMP));
assertArrayEquals(new byte[]{1, 2}, transCtx.get(DTLS_CID));
assertTrue(transCtx.get(DTLS_SESSION_EXPIRATION_HINT));
assertTrue(transCtx.get(DTLS_SESSION_SUSPENSION_HINT));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.HashMap;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -70,8 +71,10 @@ void setUp() throws IOException {
})
.post("/auth", it -> {
String name = it.options().getUriQueryMap().get("name");
dtlsServer.putSessionAuthenticationContext(it.getPeerAddress(), "auth", name);
return completedFuture(CoapResponse.of(Code.C201_CREATED));

HashMap<String, String> authCtx = new HashMap<>();
authCtx.put("auth", name);
return CoapResponse.coapResponse(Code.C201_CREATED).addContext(DTLS_AUTHENTICATION, authCtx).toFuture();
})
.get("/auth", it -> {
String name = it.getTransContext(DTLS_AUTHENTICATION).get("auth");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,19 @@
import static com.mbed.coap.packet.Opaque.of;
import static com.mbed.coap.utils.Assertions.assertEquals;
import static com.mbed.coap.utils.Networks.localhost;
import static java.util.Collections.singletonMap;
import static java.util.concurrent.CompletableFuture.completedFuture;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.opencoap.coap.netty.CoapCodec.EMPTY_RESOLVER;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_AUTHENTICATION;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_COAP_TO_DATAGRAM_CONVERTER;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.DTLS_SESSION_EXPIRATION_HINT;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.toTransportContext;
import com.mbed.coap.client.CoapClient;
import com.mbed.coap.exception.CoapException;
import com.mbed.coap.packet.CoapResponse;
import com.mbed.coap.packet.Code;
import com.mbed.coap.server.CoapServer;
import com.mbed.coap.server.RouterService;
import com.mbed.coap.transport.TransportContext;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
Expand All @@ -57,7 +53,6 @@
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
Expand All @@ -72,7 +67,6 @@
import org.opencoap.ssl.netty.DtlsChannelHandler;
import org.opencoap.ssl.netty.DtlsClientHandshakeChannelHandler;
import org.opencoap.ssl.netty.NettyTransportAdapter;
import org.opencoap.ssl.netty.SessionAuthenticationContext;
import org.opencoap.ssl.transport.DtlsSessionContext;
import org.opencoap.ssl.transport.SessionWriter;
import org.opencoap.ssl.transport.Transport;
Expand Down Expand Up @@ -114,7 +108,7 @@ void beforeAll() throws IOException {
})
.post("/dtls-ctx", req -> {
String key = req.options().getUriQueryMap().get("key");
HashMap<String, String> authCtx = new HashMap<>(req.getTransContext(DTLS_AUTHENTICATION));
HashMap<String, String> authCtx = new HashMap<>();
authCtx.put(key, req.getPayload().toUtf8String());
return CoapResponse.coapResponse(C201_CREATED)
.payload(authCtx.get(key))
Expand Down Expand Up @@ -176,12 +170,11 @@ void shouldUpdateAndReturnDtlsContext() throws IOException, CoapException {
CoapClient coapClient = CoapServer.builder()
.transport(clientTrans)
.buildClient(srvAddress);
InetSocketAddress cliAddress = localhost(clientTrans.getLocalSocketAddress().getPort());

assertEquals(badRequest(), coapClient.sendSync(get("/dtls-ctx").query("key", "dev-id")));

// when
serverTransport.getChannel().writeAndFlush(new SessionAuthenticationContext(cliAddress, singletonMap("dev-id", "dev01")));
coapClient.sendSync(post("/dtls-ctx").query("key", "dev-id").payload("dev01"));

// then
assertEquals(ok("dev01"), coapClient.sendSync(get("/dtls-ctx").query("key", "dev-id")));
Expand All @@ -203,7 +196,7 @@ void serverGetsDtlsContextOnResponse() throws IOException, CoapException, Execut
coapClient.sendSync(get("/test"));

// when DTLS context is set for the client's session
serverTransport.getChannel().writeAndFlush(new SessionAuthenticationContext(cliAddress, singletonMap("dev-id", "dev01")));
coapClient.sendSync(post("/dtls-ctx").query("key", "dev-id").payload("dev01"));

serverTransport.getChannel().pipeline().addAfter(
"DTLS",
Expand All @@ -220,10 +213,9 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
// when client sends a request
coapClient.sendSync(post("/dtls-ctx").query("key", "foo").payload("bar"));

// then server should see updated DTLS context on the response message
// then server should see DTLS context on the response message
DtlsSessionContext respCtx = coapResponseDtlsContextPromise.get(1, TimeUnit.SECONDS);
assertEquals("bar", respCtx.getAuthenticationContext().get("foo"));
assertEquals("dev01", respCtx.getAuthenticationContext().get("dev-id"));

coapClient.close();
serverTransport.getChannel().pipeline().remove("test-handler");
Expand Down

0 comments on commit 750bbc2

Please sign in to comment.