Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

download_client: Allow use of DTLS CID #11493

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/nrf/libraries/networking/download_client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ Make sure to configure the :kconfig:option:`CONFIG_DOWNLOAD_CLIENT_BUF_SIZE` and

The application must provision the TLS credentials and pass the security tag to the library when using CoAPS and calling :c:func:`download_client_connect`.

When modem firmware v1.3.5 or newer is used, you can enable the support for DTLS Connection Identifier feature in the download client library by enabling :kconfig:option:`CONFIG_DOWNLOAD_CLIENT_CID` Kconfig option.

Limitations
***********

Expand Down
4 changes: 4 additions & 0 deletions doc/nrf/releases/release-notes-changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@ Libraries for networking

* Added explanation of text versus dictionary logs.

* :ref:`lib_download_client` library:

* Added support for DTLS Connection Identifier feature.

* :ref:`lib_nrf_cloud` library:

* Added:
Expand Down
6 changes: 6 additions & 0 deletions subsys/net/lib/download_client/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ config DOWNLOAD_CLIENT_IPV6
Prefer IPv6 protocol but fallback to
IPv4 when the hostname can't be resolved.

config DOWNLOAD_CLIENT_CID
bool "Use DTLS Connection-ID"
help
Use DTLS Connection-ID option when downloading from CoAPS resources.
This requires modem firmware 1.3.5 or newer.

config DOWNLOAD_CLIENT_SHELL
bool "Enable shell"
depends on SHELL
Expand Down
1 change: 1 addition & 0 deletions subsys/net/lib/download_client/src/coap.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ int coap_block_init(struct download_client *client, size_t from)
coap_block_transfer_init(&client->coap.block_ctx,
CONFIG_DOWNLOAD_CLIENT_COAP_BLOCK_SIZE, 0);
client->coap.block_ctx.current = from;
coap_pending_clear(&client->coap.pending);
return 0;
}

Expand Down
55 changes: 31 additions & 24 deletions subsys/net/lib/download_client/src/download_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,8 @@
#include <zephyr/kernel.h>
#include <zephyr/types.h>
#include <zephyr/toolchain/common.h>
#if defined(CONFIG_POSIX_API)
#include <zephyr/posix/unistd.h>
#include <zephyr/posix/netdb.h>
#include <zephyr/posix/sys/time.h>
#include <zephyr/posix/sys/socket.h>
#else
#include <zephyr/net/socket.h>
#endif
#include <zephyr/net/socket_ncs.h>
#include <zephyr/net/tls_credentials.h>
#include <net/download_client.h>
#include <zephyr/logging/log.h>
Expand Down Expand Up @@ -134,7 +128,7 @@ static int set_recv_socket_timeout(int fd, int timeout_ms)
.tv_usec = (timeout_ms % 1000) * 1000,
};

err = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
err = zsock_setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine in principle, but we should try to keep this aligned throughout the codebase, at least in sdk-nrf. It would be a bit messy if some libraries used zsock_ and others the POSIX names; what guideline do we set for ourselves? Is it up to personal preference which one to use?

if (err) {
LOG_WRN("Failed to set socket timeout, errno %d", errno);
return -1;
Expand All @@ -156,7 +150,7 @@ static int set_snd_socket_timeout(int fd, int timeout_ms)
.tv_usec = (timeout_ms % 1000) * 1000,
};

err = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
err = zsock_setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
if (err) {
LOG_WRN("Failed to set socket timeout, errno %d", errno);
return -1;
Expand All @@ -178,14 +172,14 @@ static int socket_sectag_set(int fd, const int * const sec_tag_list, uint8_t sec

verify = REQUIRED;

err = setsockopt(fd, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));
err = zsock_setsockopt(fd, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));
if (err) {
LOG_ERR("Failed to setup peer verification, errno %d", errno);
return -errno;
}

LOG_INF("Setting up TLS credentials, sec tag count %u", sec_tag_count);
err = setsockopt(fd, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list,
err = zsock_setsockopt(fd, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list,
sizeof(sec_tag_t) * sec_tag_count);
if (err) {
LOG_ERR("Failed to setup socket security tag list, errno %d", errno);
Expand All @@ -208,7 +202,7 @@ static int socket_tls_hostname_set(int fd, const char * const hostname)
return err;
}

err = setsockopt(fd, SOL_TLS, TLS_HOSTNAME, parsed_host,
err = zsock_setsockopt(fd, SOL_TLS, TLS_HOSTNAME, parsed_host,
strlen(parsed_host));
if (err) {
LOG_ERR("Failed to setup TLS hostname (%s), errno %d",
Expand All @@ -227,7 +221,7 @@ static int socket_pdn_id_set(int fd, uint8_t pdn_id)
(void) snprintf(buf, sizeof(buf), "pdn%d", pdn_id);

LOG_INF("Binding to PDN ID: %s", buf);
err = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &buf, strlen(buf));
err = zsock_setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &buf, strlen(buf));
if (err) {
LOG_ERR("Failed to bind socket to PDN ID %d, err %d",
pdn_id, errno);
Expand All @@ -243,9 +237,9 @@ static int host_lookup(const char *host, int family, uint8_t pdn_id,
int err;
char pdnserv[4];
char hostname[HOSTNAME_SIZE];
struct addrinfo *ai;
struct zsock_addrinfo *ai;

struct addrinfo hints = {
struct zsock_addrinfo hints = {
.ai_family = family,
};

Expand All @@ -258,9 +252,9 @@ static int host_lookup(const char *host, int family, uint8_t pdn_id,
if (pdn_id) {
hints.ai_flags = AI_PDNSERV;
(void)snprintf(pdnserv, sizeof(pdnserv), "%d", pdn_id);
err = getaddrinfo(hostname, pdnserv, &hints, &ai);
err = zsock_getaddrinfo(hostname, pdnserv, &hints, &ai);
} else {
err = getaddrinfo(hostname, NULL, &hints, &ai);
err = zsock_getaddrinfo(hostname, NULL, &hints, &ai);
}

if (err) {
Expand All @@ -270,7 +264,7 @@ static int host_lookup(const char *host, int family, uint8_t pdn_id,
}

*sa = *(ai->ai_addr);
freeaddrinfo(ai);
zsock_freeaddrinfo(ai);

return 0;
}
Expand Down Expand Up @@ -363,7 +357,7 @@ static int client_connect(struct download_client *dl)
LOG_DBG("family: %d, type: %d, proto: %d",
dl->remote_addr.sa_family, type, dl->proto);

dl->fd = socket(dl->remote_addr.sa_family, type, dl->proto);
dl->fd = zsock_socket(dl->remote_addr.sa_family, type, dl->proto);
if (dl->fd < 0) {
LOG_ERR("Failed to create socket, err %d", errno);
return -errno;
Expand All @@ -389,13 +383,26 @@ static int client_connect(struct download_client *dl)
goto cleanup;
}
}

if (dl->proto == IPPROTO_DTLS_1_2 && IS_ENABLED(CONFIG_DOWNLOAD_CLIENT_CID)) {
/* Enable connection ID */
uint32_t dtls_cid = TLS_DTLS_CID_ENABLED;

err = zsock_setsockopt(dl->fd, SOL_TLS, TLS_DTLS_CID, &dtls_cid,
sizeof(dtls_cid));
if (err) {
err = -errno;
LOG_ERR("Failed to enable TLS_DTLS_CID: %d", err);
/* Not fatal, so continue */
}
}
}

LOG_INF("Connecting to %s", dl->host);
LOG_DBG("fd %d, addrlen %d, fam %s, port %d",
dl->fd, addrlen, str_family(dl->remote_addr.sa_family), port);

err = connect(dl->fd, &dl->remote_addr, addrlen);
err = zsock_connect(dl->fd, &dl->remote_addr, addrlen);
if (err) {
err = -errno;
LOG_ERR("Unable to connect, errno %d", -err);
Expand All @@ -422,7 +429,7 @@ int socket_send(const struct download_client *client, size_t len, int timeout)
}

while (len) {
sent = send(client->fd, client->buf + off, len, 0);
sent = zsock_send(client->fd, client->buf + off, len, 0);
if (sent < 0) {
return -errno;
}
Expand Down Expand Up @@ -490,7 +497,7 @@ static int reconnect(struct download_client *dl)

LOG_INF("Reconnecting...");
if (dl->fd >= 0) {
err = close(dl->fd);
err = zsock_close(dl->fd);
if (err) {
LOG_DBG("disconnect failed, %d", err);
}
Expand Down Expand Up @@ -530,7 +537,7 @@ static ssize_t socket_recv(struct download_client *dl)
return -1;
}

return recv(dl->fd, dl->buf + dl->offset, sizeof(dl->buf) - dl->offset, 0);
return zsock_recv(dl->fd, dl->buf + dl->offset, sizeof(dl->buf) - dl->offset, 0);
}

static int request_resend(struct download_client *dl)
Expand Down Expand Up @@ -717,7 +724,7 @@ static int handle_disconnect(struct download_client *client)
k_mutex_lock(&client->mutex, K_FOREVER);

if (client->fd != -1) {
err = close(client->fd);
err = zsock_close(client->fd);
if (err) {
err = errno;
LOG_ERR("Failed to close socket, errno %d", err);
Expand Down
Loading