Search code examples
clientcoapcalifornium

Californium client port


Im new to coap. So, sorry if this is a dump question.

Currently, Im using Californium latest version - 4.0.0-M2.

When I tried to write a unit test as Coap client to do handshake with Coap server. I realized that the client has random ip address. I want to test a case with same port for different request during handshake. Is there a way I can do that?

My code looks like:

private DTLSConnector createDtlsConnector(String clientCertAlias) {
        List<Certificate> trustList = new ArrayList<>();

        try (InputStream ksStream = sslProperties.getKeyStore().getInputStream(); InputStream tsStream =
                sslProperties.getTrustStore().getInputStream()) {
            KeyStore keyStore = KeyStore.getInstance(STORE_TYPE);
            keyStore.load(ksStream, sslProperties.getKeyStorePassword().toCharArray());
            KeyStore trustStore = KeyStore.getInstance(STORE_TYPE);
            trustStore.load(tsStream, sslProperties.getTrustStorePassword().toCharArray());

            // Load certificates from the trust storage
            loadTrustedCertificates(trustList, trustStore, sslProperties.getTrustServerCaAlias());

            InetSocketAddress socketAddress = new InetSocketAddress(0);
            DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder(configuration);
            builder.setAddress(socketAddress);

            builder.setCertificateIdentityProvider(new SingleCertificateProvider((PrivateKey) keyStore.getKey(
                            clientCertAlias,
                            sslProperties.getKeyStorePassword().toCharArray()),
                            keyStore.getCertificateChain(clientCertAlias), (CertificateType[]) null))
                    .set(DtlsConfig.DTLS_CLIENT_AUTHENTICATION_MODE, CertificateAuthenticationMode.NONE);
            if (verifierBuilder == null) {
                verifierBuilder = (StaticNewAdvancedCertificateVerifier) StaticNewAdvancedCertificateVerifier.builder()
                        .setTrustedCertificates(trustList.toArray(new Certificate[0])).build();
            }

            builder.setAdvancedCertificateVerifier(verifierBuilder);
            builder.set(DtlsConfig.DTLS_RETRANSMISSION_TIMEOUT, coapProperties.getRetransmissionTimeout(), TimeUnit.MILLISECONDS);
            builder.set(DtlsConfig.DTLS_MAX_TRANSMISSION_UNIT, coapProperties.getMtu());

            return new DTLSConnector(builder.build());
        } catch (GeneralSecurityException | IOException e) {
            log.error("Could not load the keystore");
            throw new RuntimeException("Unable to load the keystore");
        }
    }
public CoapResponse sendRequest(Request request) throws ConnectorException, IOException {
        CoapClient client;
        String url = schema + coapProperties.getServerHost() + ":" + coapProperties.getServerPort() + request.getUri();

        try {
            URI uri = new URI(url);

            client = new CoapClient(uri);
            client.setTimeout(TIME_OUT);
            client.setEndpoint(new CoapEndpoint.Builder()
                    .setConnector(createDtlsConnector(getClientCertificateAlias(request.getUri())))
                    .setConfiguration(configuration)
                    .build());
        } catch (URISyntaxException e) {
            log.error("Invalid URI: " + e.getMessage());
            throw new RuntimeException(String.format("Invalid URI: %s", e.getMessage()));
        }

        return sendRequest(client, request);
    }

After request sent, the logs in coap is like this:

handshake completed dtls-con: CID=9AD368936C4B, 172.31.75.61:57954, session established 342FA80FAE38, is alive
handshake completed dtls-con: CID=0D8A6DDAE64C, 172.31.75.61:4884, session established 0FE9347D53AC, is alive
handshake completed dtls-con: CID=F6358D9F0B85, 172.31.75.61:62782, session established 18D918F4F710, is alive

Each time it has different port 57954, 4884, 62782....


Solution

  • InetSocketAddress socketAddress = new InetSocketAddress(0);
    

    According javadoc - InetSocketAddress, the used value 0 is documented with

    A port number of zero will let the system pick up an ephemeral port in a bind operation.

    So just use InetSocketAddress(15684);