diff --git a/doc/nrf/libraries/networking/download_client.rst b/doc/nrf/libraries/networking/download_client.rst index 1cd0ec1b87d..869904656c0 100644 --- a/doc/nrf/libraries/networking/download_client.rst +++ b/doc/nrf/libraries/networking/download_client.rst @@ -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 *********** diff --git a/doc/nrf/releases/release-notes-changelog.rst b/doc/nrf/releases/release-notes-changelog.rst index 697c05d5c09..c9321449fd3 100644 --- a/doc/nrf/releases/release-notes-changelog.rst +++ b/doc/nrf/releases/release-notes-changelog.rst @@ -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: diff --git a/subsys/net/lib/download_client/Kconfig b/subsys/net/lib/download_client/Kconfig index aa326febde1..fc83010196e 100644 --- a/subsys/net/lib/download_client/Kconfig +++ b/subsys/net/lib/download_client/Kconfig @@ -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 diff --git a/subsys/net/lib/download_client/src/coap.c b/subsys/net/lib/download_client/src/coap.c index 514a21a7a37..e1c981af1dd 100644 --- a/subsys/net/lib/download_client/src/coap.c +++ b/subsys/net/lib/download_client/src/coap.c @@ -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; } diff --git a/subsys/net/lib/download_client/src/download_client.c b/subsys/net/lib/download_client/src/download_client.c index 9d15dd6a62d..99ebd4e516e 100644 --- a/subsys/net/lib/download_client/src/download_client.c +++ b/subsys/net/lib/download_client/src/download_client.c @@ -9,14 +9,8 @@ #include #include #include -#if defined(CONFIG_POSIX_API) -#include -#include -#include -#include -#else #include -#endif +#include #include #include #include @@ -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)); if (err) { LOG_WRN("Failed to set socket timeout, errno %d", errno); return -1; @@ -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; @@ -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); @@ -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", @@ -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); @@ -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, }; @@ -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) { @@ -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; } @@ -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; @@ -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); @@ -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; } @@ -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); } @@ -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) @@ -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);