Skip to content

Commit

Permalink
DHCPv6 update:
Browse files Browse the repository at this point in the history
DHCPv6 send support delay send.

DHCP client support now randomized Solication delay.
  • Loading branch information
Juha Heiskanen committed May 10, 2021
1 parent 99be778 commit 283f2ee
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 15 deletions.
3 changes: 2 additions & 1 deletion nanostack/dhcp_service_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,12 @@ int dhcp_service_send_resp(uint32_t msg_tr_id, uint8_t options, uint8_t *msg_ptr
* \param msg_ptr An allocated message pointer. This pointer is the responsibility of the service after this call.
* \param msg_len The length of the message.
* \param receive_resp_cb Callback pointer
* \param delay_tx Transmit may be delayed and this parameter define that
*
* \return Transaction ID of the DHCP transaction
* \return 0, if error occurred.
*/
uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr, const uint8_t addr[static 16], uint8_t *msg_ptr, uint16_t msg_len, dhcp_service_receive_resp_cb *receive_resp_cb);
uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr, const uint8_t addr[static 16], uint8_t *msg_ptr, uint16_t msg_len, dhcp_service_receive_resp_cb *receive_resp_cb, uint16_t delay_tx);

/**
* \brief Setting retransmission parameters.
Expand Down
3 changes: 2 additions & 1 deletion source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,8 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
dhcp_client_init(cur->id, DHCPV6_DUID_HARDWARE_IEEE_802_NETWORKS_TYPE);
dhcp_service_link_local_rx_cb_set(cur->id, ws_bootstrap_dhcp_neighbour_update_cb);
dhcp_client_configure(cur->id, true, true, true); //RENEW uses SOLICIT, Interface will use 1 instance for address get, IAID address hint is not used.
dhcp_client_solicit_timeout_set(cur->id, WS_DHCP_SOLICIT_TIMEOUT, WS_DHCP_SOLICIT_MAX_RT, WS_DHCP_SOLICIT_MAX_RC);

dhcp_client_solicit_timeout_set(cur->id, WS_DHCP_SOLICIT_TIMEOUT, WS_DHCP_SOLICIT_MAX_RT, WS_DHCP_SOLICIT_MAX_RC, WS_DHCP_SOLICIT_MAX_DELAY);
dhcp_client_option_notification_cb_set(cur->id, ws_bootstrap_dhcp_info_notify_cb);

// Configure memory limits and garbage collection values;
Expand Down
1 change: 1 addition & 0 deletions source/6LoWPAN/ws/ws_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ extern uint8_t DEVICE_MIN_SENS;
#define WS_DHCP_SOLICIT_TIMEOUT 60
#define WS_DHCP_SOLICIT_MAX_RT 900
#define WS_DHCP_SOLICIT_MAX_RC 0
#define WS_DHCP_SOLICIT_MAX_DELAY 5


/* Neighbour table configuration
Expand Down
3 changes: 2 additions & 1 deletion source/DHCPv6_client/dhcpv6_client_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ void dhcp_client_configure(int8_t interface, bool renew_uses_solicit, bool one_c
* /param timeout SOLICIT timeout initial value. 0 means use defaults
* /param max_rt SOLICIT timeout max value.
* /param max_rc SOLICIT re-transmission count. 0 means infinite.
* /param max_delay Max delay of first Solicit
*/
void dhcp_client_solicit_timeout_set(int8_t interface, uint16_t timeout, uint16_t max_rt, uint8_t max_rc);
void dhcp_client_solicit_timeout_set(int8_t interface, uint16_t timeout, uint16_t max_rt, uint8_t max_rc, uint8_t max_delay);

/* Delete dhcp client.
*
Expand Down
14 changes: 11 additions & 3 deletions source/DHCPv6_client/dhcpv6_client_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <ns_types.h>
#include <ns_trace.h>
#include "nsdynmemLIB.h"
#include "randLIB.h"
#include "ns_list.h"
#include "common_functions.h"

Expand All @@ -36,6 +37,7 @@ typedef struct {
dhcp_client_options_notify_cb *option_information_cb;
uint16_t service_instance;
uint16_t relay_instance;
uint16_t sol_max_delay;
uint16_t sol_timeout;
uint16_t sol_max_rt;
uint8_t sol_max_rc;
Expand Down Expand Up @@ -104,6 +106,7 @@ void dhcp_client_init(int8_t interface, uint16_t link_type)
dhcp_client->sol_timeout = 0;
dhcp_client->sol_max_rt = 0;
dhcp_client->sol_max_rc = 0;
dhcp_client->sol_max_delay = 0;
dhcp_client->renew_uses_solicit = false;
dhcp_client->one_instance_interface = false;
dhcp_client->no_address_hint = false;
Expand Down Expand Up @@ -139,13 +142,14 @@ void dhcp_client_configure(int8_t interface, bool renew_uses_solicit, bool one_c
dhcp_client->no_address_hint = no_address_hint;
}

void dhcp_client_solicit_timeout_set(int8_t interface, uint16_t timeout, uint16_t max_rt, uint8_t max_rc)
void dhcp_client_solicit_timeout_set(int8_t interface, uint16_t timeout, uint16_t max_rt, uint8_t max_rc, uint8_t max_delay)
{
// Set the default retry values for SOLICIT and RENEW messages.
dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface);
if (!dhcp_client) {
return;
}
dhcp_client->sol_max_delay = max_delay * 10; //Convert to ticks
dhcp_client->sol_timeout = timeout;
dhcp_client->sol_max_rt = max_rt;
dhcp_client->sol_max_rc = max_rc;
Expand Down Expand Up @@ -498,8 +502,12 @@ int dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[static 16
libdhcpv6_generic_nontemporal_address_message_write(payload_ptr, &solPacket, NULL, NULL);
}

uint16_t delay_tx = 0;
if (dhcp_client->sol_max_delay) {
delay_tx = randLIB_get_random_in_range(0, dhcp_client->sol_max_delay);
}
// send solicit
srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client->service_instance, 0, srv_data_ptr, dhcp_addr, payload_ptr, payload_len, dhcp_solicit_resp_cb);
srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client->service_instance, 0, srv_data_ptr, dhcp_addr, payload_ptr, payload_len, dhcp_solicit_resp_cb, delay_tx);
if (srv_data_ptr->transActionId == 0) {
ns_dyn_mem_free(payload_ptr);
libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr);
Expand Down Expand Up @@ -657,7 +665,7 @@ void dhcpv6_renew(protocol_interface_info_entry_t *interface, if_address_entry_t
server_address = srv_data_ptr->server_address;
}

srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client->service_instance, 0, srv_data_ptr, server_address, payload_ptr, payload_len, dhcp_solicit_resp_cb);
srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client->service_instance, 0, srv_data_ptr, server_address, payload_ptr, payload_len, dhcp_solicit_resp_cb, 0);
if (srv_data_ptr->transActionId == 0) {
ns_dyn_mem_free(payload_ptr);
if (addr) {
Expand Down
37 changes: 30 additions & 7 deletions source/libDHCPv6/dhcp_service_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ typedef struct {
uint32_t msg_tr_id;
uint32_t message_tr_id;
uint32_t first_transmit_time;
uint16_t delayed_tx;
uint16_t timeout;
uint16_t timeout_init;
uint16_t timeout_max;
Expand Down Expand Up @@ -768,7 +769,7 @@ int dhcp_service_send_resp(uint32_t msg_tr_id, uint8_t options, uint8_t *msg_ptr
dhcp_tr_delete(msg_tr_ptr);
return 0;
}
uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr, const uint8_t addr[static 16], uint8_t *msg_ptr, uint16_t msg_len, dhcp_service_receive_resp_cb *receive_resp_cb)
uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr, const uint8_t addr[static 16], uint8_t *msg_ptr, uint16_t msg_len, dhcp_service_receive_resp_cb *receive_resp_cb, uint16_t delay_tx)
{
tr_debug("Send DHCPv6 request");
msg_tr_t *msg_tr_ptr;
Expand All @@ -792,7 +793,8 @@ uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr,
msg_tr_ptr->instance_id = instance_id;
msg_tr_ptr->socket = dhcp_service->dhcp_client_socket;
msg_tr_ptr->recv_resp_cb = receive_resp_cb;
msg_tr_ptr->first_transmit_time = protocol_core_monotonic_time;
msg_tr_ptr->delayed_tx = delay_tx;
msg_tr_ptr->first_transmit_time = protocol_core_monotonic_time + delay_tx;
dhcp_tr_set_retry_timers(msg_tr_ptr, msg_tr_ptr->msg_ptr[0]);
common_write_24_bit(msg_tr_ptr->msg_tr_id, &msg_tr_ptr->msg_ptr[1]);

Expand Down Expand Up @@ -911,12 +913,20 @@ void dhcp_service_send_message(msg_tr_t *msg_tr_ptr)

uint8_t *ptr = msg_tr_ptr->relay_start;
*ptr = DHCPV6_RELAY_REPLY;
retval = socket_sendmsg(msg_tr_ptr->socket, &msghdr, NS_MSG_LEGACY0);
if (msg_tr_ptr->delayed_tx) {
retval = 0;
} else {
retval = socket_sendmsg(msg_tr_ptr->socket, &msghdr, NS_MSG_LEGACY0);
}

} else {
int16_t tc = 0;
socket_setsockopt(msg_tr_ptr->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_TCLASS, &tc, sizeof(tc));
retval = socket_sendto(msg_tr_ptr->socket, &msg_tr_ptr->addr, msg_tr_ptr->msg_ptr, msg_tr_ptr->msg_len);
if (msg_tr_ptr->delayed_tx) {
retval = 0;
} else {
int16_t tc = 0;
socket_setsockopt(msg_tr_ptr->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_TCLASS, &tc, sizeof(tc));
retval = socket_sendto(msg_tr_ptr->socket, &msg_tr_ptr->addr, msg_tr_ptr->msg_ptr, msg_tr_ptr->msg_len);
}
}
if (retval != 0) {
tr_warn("dhcp service socket_sendto fails: %i", retval);
Expand All @@ -928,6 +938,18 @@ bool dhcp_service_timer_tick(uint16_t ticks)
{
bool activeTimerNeed = false;
ns_list_foreach_safe(msg_tr_t, cur_ptr, &dhcp_service->tr_list) {

if (cur_ptr->delayed_tx) {
activeTimerNeed = true;
if (cur_ptr->delayed_tx <= ticks) {
cur_ptr->delayed_tx = 0;
dhcp_service_send_message(cur_ptr);
} else {
cur_ptr->delayed_tx -= ticks;
}
continue;
}

if (cur_ptr->timeout == 0) {
continue;
}
Expand Down Expand Up @@ -1023,7 +1045,7 @@ int dhcp_service_send_resp(uint32_t msg_tr_id, uint8_t options, uint8_t *msg_ptr
return -1;
}

uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr, const uint8_t addr[static 16], uint8_t *msg_ptr, uint16_t msg_len, dhcp_service_receive_resp_cb *receive_resp_cb)
uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr, const uint8_t addr[static 16], uint8_t *msg_ptr, uint16_t msg_len, dhcp_service_receive_resp_cb *receive_resp_cb, uint16_t delay_tx)
{
(void)instance_id;
(void)options;
Expand All @@ -1032,6 +1054,7 @@ uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr,
(void)msg_ptr;
(void)msg_len;
(void)receive_resp_cb;
(void)delay_tx;
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion test/nanostack/unittest/stub/dhcp_service_api_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ int dhcp_service_send_resp(uint32_t msg_tr_id, uint8_t options, uint8_t *msg_ptr
return 0;
}

uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr, const uint8_t addr[static 16], uint8_t *msg_ptr, uint16_t msg_len, dhcp_service_receive_resp_cb *receive_resp_cb)
uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr, const uint8_t addr[static 16], uint8_t *msg_ptr, uint16_t msg_len, dhcp_service_receive_resp_cb *receive_resp_cb, uint16_t delay_tx)
{
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion unittest/thread_dhcp_servers/Test.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ void test_service_server_multi_client_test_2(void)
instance1 = dhcp_service_init(1, sim_dhcp_service_receive_req_cb);
instance2 = dhcp_service_init(1, sim_dhcp_service_receive_req_cb);

dhcp_service_send_req(1, 0, (void *)3333, gua_dhcp_addr, router_solicit_req, sizeof(router_solicit_req), test_dhcp_service_receive_resp_cb_a);
dhcp_service_send_req(1, 0, (void *)3333, gua_dhcp_addr, router_solicit_req, sizeof(router_solicit_req), test_dhcp_service_receive_resp_cb_a, 0);
lt_test_socket_sendto(2, gua_dhcp_addr, router_solicit_req, sizeof(router_solicit_req));

lt_test_socket_recv_data(1, 1, clt_addr1, router_solicit_req, sizeof(router_solicit_req));
Expand Down

0 comments on commit 283f2ee

Please sign in to comment.