diff --git a/include/net/lwm2m.h b/include/net/lwm2m.h index 6bc6c5d7edf..a34d40cdd88 100644 --- a/include/net/lwm2m.h +++ b/include/net/lwm2m.h @@ -94,6 +94,12 @@ struct lwm2m_ctx { */ int tls_tag; + /** When MBEDTLS SNI is enabled socket must be set with destination + * hostname server. + */ + char *desthostname; + uint16_t desthostnamelen; + /** Client can set load_credentials function as a way of overriding * the default behavior of load_tls_credential() in lwm2m_engine.c */ diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 463f088bcee..c0457082a9e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -4652,6 +4652,7 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx) int flags; #if defined(CONFIG_LWM2M_DTLS_SUPPORT) int ret; + uint8_t tmp; if (client_ctx->load_credentials) { ret = client_ctx->load_credentials(client_ctx); @@ -4699,6 +4700,25 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx) lwm2m_engine_context_close(client_ctx); return -errno; } + + if (client_ctx->desthostname != NULL) { + /** store character at len position */ + tmp = client_ctx->desthostname[client_ctx->desthostnamelen]; + + /** change it to '\0' to pass to socket*/ + client_ctx->desthostname[client_ctx->desthostnamelen] = '\0'; + + /** mbedtls ignores length */ + ret = setsockopt(client_ctx->sock_fd, SOL_TLS, TLS_HOSTNAME, + client_ctx->desthostname, client_ctx->desthostnamelen); + + /** restore character */ + client_ctx->desthostname[client_ctx->desthostnamelen] = tmp; + if (ret < 0) { + LOG_ERR("Failed to set TLS_HOSTNAME option: %d", errno); + return -errno; + } + } } #endif /* CONFIG_LWM2M_DTLS_SUPPORT */ @@ -4718,7 +4738,7 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx) return lwm2m_socket_add(client_ctx); } -int lwm2m_parse_peerinfo(char *url, struct sockaddr *addr, bool *use_dtls, bool is_firmware_uri) +int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmware_uri) { struct http_parser_url parser; #if defined(CONFIG_LWM2M_DNS_SUPPORT) @@ -4746,17 +4766,17 @@ int lwm2m_parse_peerinfo(char *url, struct sockaddr *addr, bool *use_dtls, bool } /* check for DTLS requirement */ - *use_dtls = false; + client_ctx->use_dtls = false; if (len == 5U && strncmp(url + off, "coaps", len) == 0) { #if defined(CONFIG_LWM2M_DTLS_SUPPORT) - *use_dtls = true; + client_ctx->use_dtls = true; #else return -EPROTONOSUPPORT; #endif /* CONFIG_LWM2M_DTLS_SUPPORT */ } if (!(parser.field_set & (1 << UF_PORT))) { - if (is_firmware_uri && *use_dtls) { + if (is_firmware_uri && client_ctx->use_dtls) { /* Set to default coaps firmware update port */ parser.port = CONFIG_LWM2M_FIRMWARE_PORT_SECURE; } else if (is_firmware_uri) { @@ -4771,22 +4791,28 @@ int lwm2m_parse_peerinfo(char *url, struct sockaddr *addr, bool *use_dtls, bool off = parser.field_data[UF_HOST].off; len = parser.field_data[UF_HOST].len; +#if defined(CONFIG_LWM2M_DTLS_SUPPORT) + /** copy url pointer to be used in socket */ + client_ctx->desthostname = url + off; + client_ctx->desthostnamelen = len; +#endif + /* truncate host portion */ tmp = url[off + len]; url[off + len] = '\0'; - /* initialize addr */ - (void)memset(addr, 0, sizeof(*addr)); + /* initialize remote_addr */ + (void)memset(&client_ctx->remote_addr, 0, sizeof(client_ctx->remote_addr)); /* try and set IP address directly */ - addr->sa_family = AF_INET6; + client_ctx->remote_addr.sa_family = AF_INET6; ret = net_addr_pton(AF_INET6, url + off, - &((struct sockaddr_in6 *)addr)->sin6_addr); + &((struct sockaddr_in6 *)&client_ctx->remote_addr)->sin6_addr); /* Try to parse again using AF_INET */ if (ret < 0) { - addr->sa_family = AF_INET; + client_ctx->remote_addr.sa_family = AF_INET; ret = net_addr_pton(AF_INET, url + off, - &((struct sockaddr_in *)addr)->sin_addr); + &((struct sockaddr_in *)&client_ctx->remote_addr)->sin_addr); } if (ret < 0) { @@ -4809,8 +4835,8 @@ int lwm2m_parse_peerinfo(char *url, struct sockaddr *addr, bool *use_dtls, bool goto cleanup; } - memcpy(addr, res->ai_addr, sizeof(*addr)); - addr->sa_family = res->ai_family; + memcpy(&client_ctx->remote_addr, res->ai_addr, sizeof(client_ctx->remote_addr)); + client_ctx->remote_addr.sa_family = res->ai_family; freeaddrinfo(res); #else goto cleanup; @@ -4818,10 +4844,10 @@ int lwm2m_parse_peerinfo(char *url, struct sockaddr *addr, bool *use_dtls, bool } /* set port */ - if (addr->sa_family == AF_INET6) { - net_sin6(addr)->sin6_port = htons(parser.port); - } else if (addr->sa_family == AF_INET) { - net_sin(addr)->sin_port = htons(parser.port); + if (client_ctx->remote_addr.sa_family == AF_INET6) { + net_sin6(&client_ctx->remote_addr)->sin6_port = htons(parser.port); + } else if (client_ctx->remote_addr.sa_family == AF_INET) { + net_sin(&client_ctx->remote_addr)->sin_port = htons(parser.port); } else { ret = -EPROTONOSUPPORT; } @@ -4849,8 +4875,7 @@ int lwm2m_engine_start(struct lwm2m_ctx *client_ctx) } url[url_len] = '\0'; - ret = lwm2m_parse_peerinfo(url, &client_ctx->remote_addr, - &client_ctx->use_dtls, false); + ret = lwm2m_parse_peerinfo(url, client_ctx, false); if (ret < 0) { return ret; } diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.h b/subsys/net/lib/lwm2m/lwm2m_engine.h index e38f92a10dd..8ad786dd345 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.h +++ b/subsys/net/lib/lwm2m/lwm2m_engine.h @@ -144,6 +144,6 @@ const char *lwm2m_engine_get_attr_name(const struct lwm2m_attr *attr); int lwm2m_socket_add(struct lwm2m_ctx *ctx); void lwm2m_socket_del(struct lwm2m_ctx *ctx); int lwm2m_socket_start(struct lwm2m_ctx *client_ctx); -int lwm2m_parse_peerinfo(char *url, struct sockaddr *addr, bool *use_dtls, bool is_firmware_uri); +int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmware_uri); #endif /* LWM2M_ENGINE_H */ diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_firmware_pull.c b/subsys/net/lib/lwm2m/lwm2m_obj_firmware_pull.c index 7ad1d711e1e..e6444657559 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_firmware_pull.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_firmware_pull.c @@ -386,8 +386,7 @@ static void firmware_transfer(void) server_addr = firmware_uri; #endif - ret = lwm2m_parse_peerinfo(server_addr, &firmware_ctx.remote_addr, - &firmware_ctx.use_dtls, true); + ret = lwm2m_parse_peerinfo(server_addr, &firmware_ctx, true); if (ret < 0) { LOG_ERR("Failed to parse server URI."); goto error;