net: lwm2m: Way to pass a destination hostname to socket
net: lwm2m: When mbedtls CONFIG_MBEDTLS_SERVER_NAME_INDICATION is enabled, a destination hostname must be passed to socket to properly connect do lwm2m server. Passing lwm2m context to lwm2m_parse_peerinfo Signed-off-by: Jair Jack <jack@icatorze.com.br>
This commit is contained in:
parent
b83128e169
commit
5b5417a1dd
4 changed files with 51 additions and 21 deletions
|
@ -94,6 +94,12 @@ struct lwm2m_ctx {
|
||||||
*/
|
*/
|
||||||
int tls_tag;
|
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
|
/** Client can set load_credentials function as a way of overriding
|
||||||
* the default behavior of load_tls_credential() in lwm2m_engine.c
|
* the default behavior of load_tls_credential() in lwm2m_engine.c
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -4652,6 +4652,7 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
||||||
int flags;
|
int flags;
|
||||||
#if defined(CONFIG_LWM2M_DTLS_SUPPORT)
|
#if defined(CONFIG_LWM2M_DTLS_SUPPORT)
|
||||||
int ret;
|
int ret;
|
||||||
|
uint8_t tmp;
|
||||||
|
|
||||||
if (client_ctx->load_credentials) {
|
if (client_ctx->load_credentials) {
|
||||||
ret = client_ctx->load_credentials(client_ctx);
|
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);
|
lwm2m_engine_context_close(client_ctx);
|
||||||
return -errno;
|
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 */
|
#endif /* CONFIG_LWM2M_DTLS_SUPPORT */
|
||||||
|
|
||||||
|
@ -4718,7 +4738,7 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
||||||
return lwm2m_socket_add(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;
|
struct http_parser_url parser;
|
||||||
#if defined(CONFIG_LWM2M_DNS_SUPPORT)
|
#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 */
|
/* check for DTLS requirement */
|
||||||
*use_dtls = false;
|
client_ctx->use_dtls = false;
|
||||||
if (len == 5U && strncmp(url + off, "coaps", len) == 0) {
|
if (len == 5U && strncmp(url + off, "coaps", len) == 0) {
|
||||||
#if defined(CONFIG_LWM2M_DTLS_SUPPORT)
|
#if defined(CONFIG_LWM2M_DTLS_SUPPORT)
|
||||||
*use_dtls = true;
|
client_ctx->use_dtls = true;
|
||||||
#else
|
#else
|
||||||
return -EPROTONOSUPPORT;
|
return -EPROTONOSUPPORT;
|
||||||
#endif /* CONFIG_LWM2M_DTLS_SUPPORT */
|
#endif /* CONFIG_LWM2M_DTLS_SUPPORT */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(parser.field_set & (1 << UF_PORT))) {
|
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 */
|
/* Set to default coaps firmware update port */
|
||||||
parser.port = CONFIG_LWM2M_FIRMWARE_PORT_SECURE;
|
parser.port = CONFIG_LWM2M_FIRMWARE_PORT_SECURE;
|
||||||
} else if (is_firmware_uri) {
|
} 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;
|
off = parser.field_data[UF_HOST].off;
|
||||||
len = parser.field_data[UF_HOST].len;
|
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 */
|
/* truncate host portion */
|
||||||
tmp = url[off + len];
|
tmp = url[off + len];
|
||||||
url[off + len] = '\0';
|
url[off + len] = '\0';
|
||||||
|
|
||||||
/* initialize addr */
|
/* initialize remote_addr */
|
||||||
(void)memset(addr, 0, sizeof(*addr));
|
(void)memset(&client_ctx->remote_addr, 0, sizeof(client_ctx->remote_addr));
|
||||||
|
|
||||||
/* try and set IP address directly */
|
/* 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,
|
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 */
|
/* Try to parse again using AF_INET */
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
addr->sa_family = AF_INET;
|
client_ctx->remote_addr.sa_family = AF_INET;
|
||||||
ret = net_addr_pton(AF_INET, url + off,
|
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) {
|
if (ret < 0) {
|
||||||
|
@ -4809,8 +4835,8 @@ int lwm2m_parse_peerinfo(char *url, struct sockaddr *addr, bool *use_dtls, bool
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(addr, res->ai_addr, sizeof(*addr));
|
memcpy(&client_ctx->remote_addr, res->ai_addr, sizeof(client_ctx->remote_addr));
|
||||||
addr->sa_family = res->ai_family;
|
client_ctx->remote_addr.sa_family = res->ai_family;
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
#else
|
#else
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -4818,10 +4844,10 @@ int lwm2m_parse_peerinfo(char *url, struct sockaddr *addr, bool *use_dtls, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set port */
|
/* set port */
|
||||||
if (addr->sa_family == AF_INET6) {
|
if (client_ctx->remote_addr.sa_family == AF_INET6) {
|
||||||
net_sin6(addr)->sin6_port = htons(parser.port);
|
net_sin6(&client_ctx->remote_addr)->sin6_port = htons(parser.port);
|
||||||
} else if (addr->sa_family == AF_INET) {
|
} else if (client_ctx->remote_addr.sa_family == AF_INET) {
|
||||||
net_sin(addr)->sin_port = htons(parser.port);
|
net_sin(&client_ctx->remote_addr)->sin_port = htons(parser.port);
|
||||||
} else {
|
} else {
|
||||||
ret = -EPROTONOSUPPORT;
|
ret = -EPROTONOSUPPORT;
|
||||||
}
|
}
|
||||||
|
@ -4849,8 +4875,7 @@ int lwm2m_engine_start(struct lwm2m_ctx *client_ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
url[url_len] = '\0';
|
url[url_len] = '\0';
|
||||||
ret = lwm2m_parse_peerinfo(url, &client_ctx->remote_addr,
|
ret = lwm2m_parse_peerinfo(url, client_ctx, false);
|
||||||
&client_ctx->use_dtls, false);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,6 @@ const char *lwm2m_engine_get_attr_name(const struct lwm2m_attr *attr);
|
||||||
int lwm2m_socket_add(struct lwm2m_ctx *ctx);
|
int lwm2m_socket_add(struct lwm2m_ctx *ctx);
|
||||||
void lwm2m_socket_del(struct lwm2m_ctx *ctx);
|
void lwm2m_socket_del(struct lwm2m_ctx *ctx);
|
||||||
int lwm2m_socket_start(struct lwm2m_ctx *client_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 */
|
#endif /* LWM2M_ENGINE_H */
|
||||||
|
|
|
@ -386,8 +386,7 @@ static void firmware_transfer(void)
|
||||||
server_addr = firmware_uri;
|
server_addr = firmware_uri;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = lwm2m_parse_peerinfo(server_addr, &firmware_ctx.remote_addr,
|
ret = lwm2m_parse_peerinfo(server_addr, &firmware_ctx, true);
|
||||||
&firmware_ctx.use_dtls, true);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG_ERR("Failed to parse server URI.");
|
LOG_ERR("Failed to parse server URI.");
|
||||||
goto error;
|
goto error;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue