Skip to content

Commit 374d1e1

Browse files
committed
mgmt: hawkbit: interface support for ip addresses and domain name
Previously, hawkbit interface only supported a url/hostname and a port, and internally it resolves to an IP address. This does not work for network layers that rely on NAT64, like OpenThread. Zephyr's implementation of `getaddrinfo` is not aware of NAT64. DNS will resolve an IPV4 address that needs to be converted to IPV6 with the NAT64 prefix. This commit alters the Hawkbit interface to allow providing an explicit domain name as a string via `server_domain`, and an already resolved IP address as `server_addr`. This commit changes the usage of `hawkbit_runtime_config.server_addr` to point to either an IP address or domain name. It adds a new Kconfig (`HAWKBIT_USE_DOMAIN_NAME`) to specify an explicit domain name and adds a new variable `hawkbit_runtime_config.server_domain`. If `HAWKBIT_USE_DOMAIN_NAME` is enabled and a user provides an IP address to `server_addr`, the user must provide a domain name to `server_domain`. Signed-off-by: Neal Jackson <[email protected]>
1 parent b915e24 commit 374d1e1

File tree

3 files changed

+110
-10
lines changed

3 files changed

+110
-10
lines changed

include/zephyr/mgmt/hawkbit/config.h

+42-1
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@
2929
* settings.
3030
*/
3131
struct hawkbit_runtime_config {
32-
/** Server address */
32+
/**
33+
* Server address (domain name or IP address if
34+
* CONFIG_HAWKBIT_USE_DOMAIN_NAME is enabled
35+
*/
3336
char *server_addr;
37+
/** Server domain name */
38+
char *server_domain;
3439
/** Server port */
3540
uint16_t server_port;
3641
/** Security token */
@@ -44,6 +49,7 @@ struct hawkbit_runtime_config {
4449
*
4550
* @param config Configuration settings to set.
4651
* @retval 0 on success.
52+
* @retval -EINVAL if string length mismatch for server_domain
4753
* @retval -EAGAIN if probe is currently running.
4854
*/
4955
int hawkbit_set_config(struct hawkbit_runtime_config *config);
@@ -55,6 +61,27 @@ int hawkbit_set_config(struct hawkbit_runtime_config *config);
5561
*/
5662
struct hawkbit_runtime_config hawkbit_get_config(void);
5763

64+
/**
65+
* @brief Set the hawkBit server hostname.
66+
*
67+
* @param hostname_str Server hostname to set.
68+
* @retval 0 on success.
69+
* @retval -EINVAL if string length mismatch for server_domain
70+
* @retval -EAGAIN if probe is currently running.
71+
*/
72+
static inline int hawkbit_set_server_domain(char *domain_str)
73+
{
74+
struct hawkbit_runtime_config set_config = {
75+
.server_addr = NULL,
76+
.server_domain = domain_str,
77+
.server_port = 0,
78+
.auth_token = NULL,
79+
.tls_tag = 0,
80+
};
81+
82+
return hawkbit_set_config(&set_config);
83+
}
84+
5885
/**
5986
* @brief Set the hawkBit server address.
6087
*
@@ -66,6 +93,7 @@ static inline int hawkbit_set_server_addr(char *addr_str)
6693
{
6794
struct hawkbit_runtime_config set_config = {
6895
.server_addr = addr_str,
96+
.server_domain = NULL,
6997
.server_port = 0,
7098
.auth_token = NULL,
7199
.tls_tag = 0,
@@ -85,6 +113,7 @@ static inline int hawkbit_set_server_port(uint16_t port)
85113
{
86114
struct hawkbit_runtime_config set_config = {
87115
.server_addr = NULL,
116+
.server_domain = NULL,
88117
.server_port = port,
89118
.auth_token = NULL,
90119
.tls_tag = 0,
@@ -104,6 +133,7 @@ static inline int hawkbit_set_ddi_security_token(char *token)
104133
{
105134
struct hawkbit_runtime_config set_config = {
106135
.server_addr = NULL,
136+
.server_domain = NULL,
107137
.server_port = 0,
108138
.auth_token = token,
109139
.tls_tag = 0,
@@ -123,6 +153,7 @@ static inline int hawkbit_set_tls_tag(sec_tag_t tag)
123153
{
124154
struct hawkbit_runtime_config set_config = {
125155
.server_addr = NULL,
156+
.server_domain = NULL,
126157
.server_port = 0,
127158
.auth_token = NULL,
128159
.tls_tag = tag,
@@ -141,6 +172,16 @@ static inline char *hawkbit_get_server_addr(void)
141172
return hawkbit_get_config().server_addr;
142173
}
143174

175+
/**
176+
* @brief Get the hawkBit server hostname.
177+
*
178+
* @return Server hostname.
179+
*/
180+
static inline char *hawkbit_get_server_domain(void)
181+
{
182+
return hawkbit_get_config().server_domain;
183+
}
184+
144185
/**
145186
* @brief Get the hawkBit server port.
146187
*

subsys/mgmt/hawkbit/Kconfig

+8
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ config HAWKBIT_SET_SETTINGS_RUNTIME
7070
help
7171
Enable to set hawkbit settings at runtime.
7272

73+
config HAWKBIT_USE_DOMAIN_NAME
74+
bool "Use server_domain for domain name instead of server_addr"
75+
depends on HAWKBIT_SET_SETTINGS_RUNTIME
76+
help
77+
Enable to use the server_domain field for TLS and HTTP. If enabled,
78+
server_addr can accept an already resolved IP address, and the domain name
79+
can be provided via server_domain.
80+
7381
choice HAWKBIT_DDI_SECURITY
7482
prompt "hawkBit DDI API authentication modes"
7583
default HAWKBIT_DDI_NO_SECURITY

subsys/mgmt/hawkbit/hawkbit.c

+60-9
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include <zephyr/mgmt/hawkbit/hawkbit.h>
2222
#include <zephyr/mgmt/hawkbit/config.h>
2323
#include <zephyr/mgmt/hawkbit/event.h>
24-
#include <zephyr/net/dns_resolve.h>
2524
#include <zephyr/net/http/client.h>
2625
#include <zephyr/net/net_ip.h>
2726
#include <zephyr/net/net_mgmt.h>
@@ -75,10 +74,19 @@ static bool hawkbit_initialized;
7574

7675
#endif /* CONFIG_HAWKBIT_DDI_NO_SECURITY */
7776

77+
#ifdef CONFIG_DNS_RESOLVER_MAX_QUERY_LEN
78+
#define SERVER_DOMAIN_LEN CONFIG_DNS_RESOLVER_MAX_QUERY_LEN
79+
#else
80+
#define SERVER_DOMAIN_LEN 255
81+
#endif
82+
7883
static struct hawkbit_config {
7984
int32_t action_id;
8085
#ifdef CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME
8186
char server_addr[DNS_MAX_NAME_SIZE + 1];
87+
#ifdef CONFIG_HAWKBIT_USE_DOMAIN_NAME
88+
char server_domain[SERVER_DOMAIN_LEN + 1];
89+
#endif
8290
char server_port[sizeof(STRINGIFY(__UINT16_MAX__))];
8391
#ifndef CONFIG_HAWKBIT_DDI_NO_SECURITY
8492
char ddi_security_token[DDI_SECURITY_TOKEN_SIZE + 1];
@@ -90,11 +98,17 @@ static struct hawkbit_config {
9098
} hb_cfg;
9199

92100
#ifdef CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME
93-
#define HAWKBIT_SERVER hb_cfg.server_addr
101+
#ifdef CONFIG_HAWKBIT_USE_DOMAIN_NAME
102+
#define HAWKBIT_SERVER_DOMAIN hb_cfg.server_domain
103+
#else
104+
#define HAWKBIT_SERVER_DOMAIN hb_cfg.server_addr
105+
#endif /* CONFIG_HAWKBIT_USE_DOMAIN_NAME */
106+
#define HAWKBIT_SERVER_ADDR hb_cfg.server_addr
94107
#define HAWKBIT_PORT hb_cfg.server_port
95108
#define HAWKBIT_PORT_INT atoi(hb_cfg.server_port)
96109
#else
97-
#define HAWKBIT_SERVER CONFIG_HAWKBIT_SERVER
110+
#define HAWKBIT_SERVER_ADDR CONFIG_HAWKBIT_SERVER
111+
#define HAWKBIT_SERVER_DOMAIN CONFIG_HAWKBIT_SERVER
98112
#define HAWKBIT_PORT STRINGIFY(CONFIG_HAWKBIT_PORT)
99113
#define HAWKBIT_PORT_INT CONFIG_HAWKBIT_PORT
100114
#endif /* CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME */
@@ -298,6 +312,22 @@ static int hawkbit_settings_set(const char *name, size_t len, settings_read_cb r
298312
return rc;
299313
}
300314

315+
#ifdef CONFIG_HAWKBIT_USE_DOMAIN_NAME
316+
if (settings_name_steq(name, "server_domain", &next) && !next) {
317+
if (len != sizeof(hb_cfg.server_domain)) {
318+
return -EINVAL;
319+
}
320+
321+
rc = read_cb(cb_arg, &hb_cfg.server_domain, sizeof(hb_cfg.server_domain));
322+
LOG_DBG("<%s> = %s", "hawkbit/server_domain", hb_cfg.server_domain);
323+
if (rc >= 0) {
324+
return 0;
325+
}
326+
327+
return rc;
328+
}
329+
#endif /* CONFIG_HAWKBIT_USE_DOMAIN_NAME */
330+
301331
if (settings_name_steq(name, "server_port", &next) && !next) {
302332
if (len != sizeof(uint16_t)) {
303333
return -EINVAL;
@@ -336,6 +366,9 @@ static int hawkbit_settings_set(const char *name, size_t len, settings_read_cb r
336366
}
337367
#else /* CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME */
338368
if (settings_name_steq(name, "server_addr", NULL) ||
369+
#ifdef CONFIG_HAWKBIT_USE_DOMAIN_NAME
370+
settings_name_steq(name, "server_domain", NULL) ||
371+
#endif /* CONFIG_HAWKBIT_USE_DOMAIN_NAME */
339372
settings_name_steq(name, "server_port", NULL) ||
340373
settings_name_steq(name, "ddi_token", NULL)) {
341374
rc = read_cb(cb_arg, NULL, 0);
@@ -359,6 +392,9 @@ static int hawkbit_settings_export(int (*cb)(const char *name, const void *value
359392
(void)cb("hawkbit/action_id", &hb_cfg.action_id, sizeof(hb_cfg.action_id));
360393
#ifdef CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME
361394
(void)cb("hawkbit/server_addr", &hb_cfg.server_addr, sizeof(hb_cfg.server_addr));
395+
#ifdef CONFIG_HAWKBIT_USE_DOMAIN_NAME
396+
(void)cb("hawkbit/server_domain", &hb_cfg.server_domain, sizeof(hb_cfg.server_domain));
397+
#endif /* CONFIG_HAWKBIT_USE_DOMAIN_NAME */
362398
uint16_t hawkbit_port = atoi(hb_cfg.server_port);
363399
(void)cb("hawkbit/server_port", &hawkbit_port, sizeof(hawkbit_port));
364400
#ifndef CONFIG_HAWKBIT_DDI_NO_SECURITY
@@ -439,7 +475,7 @@ static bool start_http_client(int *hb_sock)
439475
}
440476

441477
while (resolve_attempts--) {
442-
ret = zsock_getaddrinfo(HAWKBIT_SERVER, HAWKBIT_PORT, &hints, &addr);
478+
ret = zsock_getaddrinfo(HAWKBIT_SERVER_ADDR, HAWKBIT_PORT, &hints, &addr);
443479
if (ret == 0) {
444480
break;
445481
}
@@ -469,8 +505,8 @@ static bool start_http_client(int *hb_sock)
469505
goto err_sock;
470506
}
471507

472-
if (zsock_setsockopt(*hb_sock, SOL_TLS, TLS_HOSTNAME, HAWKBIT_SERVER,
473-
sizeof(CONFIG_HAWKBIT_SERVER)) < 0) {
508+
if (zsock_setsockopt(*hb_sock, SOL_TLS, TLS_HOSTNAME, HAWKBIT_SERVER_DOMAIN,
509+
sizeof(HAWKBIT_SERVER_DOMAIN)) < 0) {
474510
goto err_sock;
475511
}
476512
#endif /* CONFIG_HAWKBIT_USE_TLS */
@@ -778,12 +814,27 @@ int hawkbit_default_config_data_cb(const char *device_id, uint8_t *buffer, const
778814
#ifdef CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME
779815
int hawkbit_set_config(struct hawkbit_runtime_config *config)
780816
{
817+
size_t length;
818+
781819
if (k_sem_take(&probe_sem, HAWKBIT_SET_SERVER_TIMEOUT) == 0) {
782820
if (config->server_addr != NULL) {
783821
strncpy(hb_cfg.server_addr, config->server_addr,
784822
sizeof(hb_cfg.server_addr));
785823
LOG_DBG("configured %s: %s", "hawkbit/server_addr", hb_cfg.server_addr);
786824
}
825+
#ifdef CONFIG_HAWKBIT_USE_DOMAIN_NAME
826+
if (config->server_domain != NULL) {
827+
length = strnlen(config->server_domain, CONFIG_DNS_RESOLVER_MAX_QUERY_LEN + 1);
828+
if (length > CONFIG_DNS_RESOLVER_MAX_QUERY_LEN) {
829+
LOG_ERR("%s too long: %s", "hawkbit/server_domain", config->server_domain);
830+
return -EINVAL;
831+
}
832+
strncpy(hb_cfg.server_domain, config->server_domain,
833+
sizeof(hb_cfg.server_domain));
834+
LOG_DBG("configured %s: %s", "hawkbit/server_domain",
835+
hb_cfg.server_domain);
836+
}
837+
#endif /* CONFIG_HAWKBIT_USE_DOMAIN_NAME */
787838
if (config->server_port != 0) {
788839
snprintf(hb_cfg.server_port, sizeof(hb_cfg.server_port), "%u",
789840
config->server_port);
@@ -817,7 +868,7 @@ int hawkbit_set_config(struct hawkbit_runtime_config *config)
817868
struct hawkbit_runtime_config hawkbit_get_config(void)
818869
{
819870
struct hawkbit_runtime_config config = {
820-
.server_addr = HAWKBIT_SERVER,
871+
.server_addr = HAWKBIT_SERVER_ADDR,
821872
.server_port = HAWKBIT_PORT_INT,
822873
.auth_token = HAWKBIT_DDI_SECURITY_TOKEN,
823874
.tls_tag = HAWKBIT_CERT_TAG,
@@ -1041,7 +1092,7 @@ static bool send_request(struct hawkbit_context *hb_context, enum hawkbit_http_r
10411092
#endif /* CONFIG_HAWKBIT_DDI_NO_SECURITY */
10421093

10431094
http_req.url = url_buffer;
1044-
http_req.host = HAWKBIT_SERVER;
1095+
http_req.host = HAWKBIT_SERVER_DOMAIN;
10451096
http_req.port = HAWKBIT_PORT;
10461097
http_req.protocol = "HTTP/1.1";
10471098
http_req.response = response_cb;
@@ -1155,7 +1206,7 @@ void hawkbit_reboot(void)
11551206

11561207
static bool check_hawkbit_server(void)
11571208
{
1158-
if (strlen(HAWKBIT_SERVER) == 0) {
1209+
if (strlen(HAWKBIT_SERVER_ADDR) == 0) {
11591210
if (sizeof(CONFIG_HAWKBIT_SERVER) > 1) {
11601211
hawkbit_set_server_addr(CONFIG_HAWKBIT_SERVER);
11611212
} else {

0 commit comments

Comments
 (0)