Skip to content

Commit d879e6d

Browse files
author
Arto Kinnunen
committed
Merge branch 'release_internal' into release_external
* release_internal: Fixed network border router timeout recovery and EAPOL relay address fix Changed RADIUS MTU and small fixes Addeed support for DHCP vendor data DHCPv6 functionality update Added DHCPv6 vendor data generation for DNS queries FHSS: Changed retry backoffs when no BC schedule or TX slots (ARMmbed#2440)
2 parents 91acece + eef9246 commit d879e6d

26 files changed

+748
-80
lines changed

nanostack/ws_bbr_api.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,8 @@ int ws_bbr_radius_timing_validate(int8_t interface_id, bbr_radius_timing_t *timi
490490
*
491491
* This function can be called multiple times.
492492
* if domain name matches a existing entry address is updated.
493-
* If address and domain name is set to NULL entire list is cleared
493+
* If domain name is set to NULL entire list is cleared
494+
* if address is set to NULL the Domain name is removed from the list.
494495
*
495496
* \param interface_id Network interface ID.
496497
* \param address The address of the DNS query result.

source/6LoWPAN/ws/ws_bbr_api.c

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "nsconfig.h"
2020
#include "ns_types.h"
2121
#include "ns_trace.h"
22+
#include "nsdynmemLIB.h"
2223
#include "net_interface.h"
2324
#include "socket_api.h"
2425
#include "eventOS_event.h"
@@ -41,6 +42,7 @@
4142
#include "6LoWPAN/ws/ws_pae_controller.h"
4243
#include "DHCPv6_Server/DHCPv6_server_service.h"
4344
#include "DHCPv6_client/dhcpv6_client_api.h"
45+
#include "libDHCPv6/libDHCPv6_vendordata.h"
4446
#include "libNET/src/net_dns_internal.h"
4547

4648

@@ -93,6 +95,17 @@ static rpl_dodag_conf_t rpl_conf = {
9395
.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_SMALL
9496
};
9597

98+
typedef struct dns_resolution {
99+
/** Resolved address for the domain*/
100+
uint8_t address[16];
101+
/** Domain name string */
102+
char *domain_name;
103+
} dns_resolution_t;
104+
105+
#define MAX_DNS_RESOLUTIONS 4
106+
107+
static dns_resolution_t pre_resolved_dns_queries[MAX_DNS_RESOLUTIONS] = {0};
108+
96109
static void ws_bbr_rpl_version_timer_start(protocol_interface_info_entry_t *cur, uint8_t version)
97110
{
98111
// Set the next timeout value for version update
@@ -368,7 +381,8 @@ static bool wisun_dhcp_address_add_cb(int8_t interfaceId, dhcp_address_cache_upd
368381
wisun_bbr_na_send(backbone_interface_id, address_info->allocatedAddress);
369382
return true;
370383
}
371-
static void ws_bbr_dhcp_server_dns_info_update(protocol_interface_info_entry_t *cur)
384+
385+
static void ws_bbr_dhcp_server_dns_info_update(protocol_interface_info_entry_t *cur, uint8_t *global_id)
372386
{
373387
//add DNS server information to DHCP server that is learned from the backbone interface.
374388
uint8_t dns_server_address[16];
@@ -377,13 +391,37 @@ static void ws_bbr_dhcp_server_dns_info_update(protocol_interface_info_entry_t *
377391
(void)cur;
378392
if (net_dns_server_get(backbone_interface_id, dns_server_address, &dns_search_list_ptr, &dns_search_list_len, 0) == 0) {
379393
/*Only supporting one DNS server address*/
380-
//DHCPv6_server_service_set_dns_server(cur->id, dns_server_address, dns_search_list_ptr, dns_search_list_len);
394+
DHCPv6_server_service_set_dns_server(cur->id, global_id, dns_server_address, dns_search_list_ptr, dns_search_list_len);
381395
}
382396

383397
//TODO Generate vendor data in Wi-SUN network include the cached DNS query results in some sort of TLV format
384-
(void)dhcp_vendor_data_ptr;
385-
(void)dhcp_vendor_data_len;
386-
//DHCPv6_server_service_set_vendor_data(cur->id, dhcp_vendor_data_ptr, dhcp_vendor_data_len);
398+
int vendor_data_len = 0;
399+
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
400+
if (pre_resolved_dns_queries[n].domain_name != NULL) {
401+
vendor_data_len += net_dns_option_vendor_option_data_dns_query_length(pre_resolved_dns_queries[n].domain_name);
402+
}
403+
}
404+
if (vendor_data_len) {
405+
ns_dyn_mem_free(dhcp_vendor_data_ptr);
406+
dhcp_vendor_data_ptr = ns_dyn_mem_alloc(vendor_data_len);
407+
if (!dhcp_vendor_data_ptr) {
408+
tr_warn("Vendor info set fail");
409+
return;
410+
}
411+
dhcp_vendor_data_len = vendor_data_len;
412+
}
413+
if (dhcp_vendor_data_ptr) {
414+
// Write vendor data
415+
uint8_t *ptr = dhcp_vendor_data_ptr;
416+
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
417+
if (pre_resolved_dns_queries[n].domain_name != NULL) {
418+
ptr = net_dns_option_vendor_option_data_dns_query_write(ptr, pre_resolved_dns_queries[n].address, pre_resolved_dns_queries[n].domain_name);
419+
tr_info("set DNS query result for %s, addr: %s", pre_resolved_dns_queries[n].domain_name, tr_ipv6(pre_resolved_dns_queries[n].address));
420+
}
421+
}
422+
}
423+
424+
DHCPv6_server_service_set_vendor_data(cur->id, global_id, ARM_ENTERPRISE_NUMBER, dhcp_vendor_data_ptr, dhcp_vendor_data_len);
387425
}
388426

389427
static void ws_bbr_dhcp_server_start(protocol_interface_info_entry_t *cur, uint8_t *global_id, uint32_t dhcp_address_lifetime)
@@ -406,7 +444,7 @@ static void ws_bbr_dhcp_server_start(protocol_interface_info_entry_t *cur, uint8
406444
//SEt max value for not limiting address allocation
407445
DHCPv6_server_service_set_max_clients_accepts_count(cur->id, global_id, MAX_SUPPORTED_ADDRESS_LIST_SIZE);
408446

409-
ws_bbr_dhcp_server_dns_info_update(cur);
447+
ws_bbr_dhcp_server_dns_info_update(cur, global_id);
410448

411449
ws_dhcp_client_address_request(cur, global_id, ll);
412450
}
@@ -594,7 +632,7 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
594632
// Add also global prefix and route to RPL
595633
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, current_global_prefix, 64, 0, WS_ROUTE_LIFETIME, false);
596634
}
597-
ws_bbr_dhcp_server_dns_info_update(cur);
635+
ws_bbr_dhcp_server_dns_info_update(cur, current_global_prefix);
598636
}
599637
}
600638
void ws_bbr_pan_version_increase(protocol_interface_info_entry_t *cur)
@@ -1200,7 +1238,7 @@ int ws_bbr_dns_query_result_set(int8_t interface_id, const uint8_t address[16],
12001238
{
12011239
#ifdef HAVE_WS_BORDER_ROUTER
12021240
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
1203-
if (!cur || !address || !domain_name_ptr) {
1241+
if (!cur) {
12041242
return -1;
12051243
}
12061244

@@ -1210,10 +1248,62 @@ int ws_bbr_dns_query_result_set(int8_t interface_id, const uint8_t address[16],
12101248
*
12111249
* This is included in the vendor extension where the format is decided by the vendor
12121250
*/
1213-
// TODO search if entry exists replace if address is NULL delete the entry
1214-
// TODO This information should expire if not updated by client
12151251

1216-
ws_bbr_dhcp_server_dns_info_update(cur);
1252+
// Delete all entries
1253+
if (!domain_name_ptr) {
1254+
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
1255+
// Delete all entries
1256+
memset(pre_resolved_dns_queries[n].address, 0, 16);
1257+
ns_dyn_mem_free(pre_resolved_dns_queries[n].domain_name);
1258+
pre_resolved_dns_queries[n].domain_name = NULL;
1259+
}
1260+
goto update_information;
1261+
}
1262+
1263+
// Update existing entries or delete
1264+
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
1265+
if (pre_resolved_dns_queries[n].domain_name != NULL &&
1266+
strcasecmp(pre_resolved_dns_queries[n].domain_name, domain_name_ptr) == 0) {
1267+
// Matching query updated
1268+
if (address) {
1269+
// Update address
1270+
memcpy(pre_resolved_dns_queries[n].address, address, 16);
1271+
} else {
1272+
// delete entry
1273+
memset(pre_resolved_dns_queries[n].address, 0, 16);
1274+
ns_dyn_mem_free(pre_resolved_dns_queries[n].domain_name);
1275+
pre_resolved_dns_queries[n].domain_name = NULL;
1276+
}
1277+
goto update_information;
1278+
}
1279+
}
1280+
1281+
if (address && domain_name_ptr) {
1282+
// Store new entry to the list
1283+
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
1284+
if (pre_resolved_dns_queries[n].domain_name == NULL) {
1285+
// Free entry found
1286+
pre_resolved_dns_queries[n].domain_name = ns_dyn_mem_alloc(strlen(domain_name_ptr) + 1);
1287+
if (!pre_resolved_dns_queries[n].domain_name) {
1288+
// Out of memory
1289+
return -2;
1290+
}
1291+
memcpy(pre_resolved_dns_queries[n].address, address, 16);
1292+
strcpy(pre_resolved_dns_queries[n].domain_name, domain_name_ptr);
1293+
goto update_information;
1294+
}
1295+
}
1296+
// No room to store new field
1297+
return -3;
1298+
}
1299+
1300+
update_information:
1301+
if (memcmp(current_global_prefix, ADDR_UNSPECIFIED, 8) == 0) {
1302+
// Not in active state so changes are activated after start
1303+
return 0;
1304+
}
1305+
1306+
ws_bbr_dhcp_server_dns_info_update(cur, current_global_prefix);
12171307
return 0;
12181308
#else
12191309
(void) interface_id;

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include "platform/topo_trace.h"
6666
#include "dhcp_service_api.h"
6767
#include "libDHCPv6/libDHCPv6.h"
68+
#include "libDHCPv6/libDHCPv6_vendordata.h"
6869
#include "DHCPv6_client/dhcpv6_client_api.h"
6970
#include "ws_management_api.h"
7071
#include "net_rpl.h"
@@ -73,6 +74,7 @@
7374
#include "6LoWPAN/ws/ws_eapol_pdu.h"
7475
#include "6LoWPAN/ws/ws_eapol_auth_relay.h"
7576
#include "6LoWPAN/ws/ws_eapol_relay.h"
77+
#include "libNET/src/net_dns_internal.h"
7678

7779
#define TRACE_GROUP "wsbs"
7880

@@ -872,6 +874,80 @@ static void ws_bootstrap_dhcp_neighbour_update_cb(int8_t interface_id, uint8_t l
872874
ws_bootstrap_mac_neighbor_short_time_set(cur, mac64, WS_NEIGHBOUR_DHCP_ENTRY_LIFETIME);
873875
}
874876

877+
static void ws_bootstrap_dhcp_info_notify_cb(int8_t interface, dhcp_option_notify_t *options, dhcp_server_notify_info_t *server_info)
878+
{
879+
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface);
880+
if (!cur) {
881+
return;
882+
}
883+
uint8_t server_ll64[16];
884+
memcpy(server_ll64, ADDR_LINK_LOCAL_PREFIX, 8);
885+
886+
if (server_info->duid_length == 8) {
887+
memcpy(server_ll64 + 8, server_info->duid, 8);
888+
} else {
889+
server_ll64[8] = server_info->duid[0];
890+
server_ll64[9] = server_info->duid[1];
891+
server_ll64[10] = server_info->duid[2];
892+
server_ll64[11] = 0xff;
893+
server_ll64[12] = 0xfe;
894+
server_ll64[13] = server_info->duid[3];
895+
server_ll64[14] = server_info->duid[4];
896+
server_ll64[15] = server_info->duid[5];
897+
}
898+
server_ll64[8] ^= 2;
899+
900+
switch (options->option_type) {
901+
case DHCPV6_OPTION_VENDOR_SPECIFIC_INFO:
902+
if (options->option.vendor_spesific.enterprise_number != ARM_ENTERPRISE_NUMBER) {
903+
break;
904+
}
905+
while (options->option.vendor_spesific.data_length) {
906+
uint16_t option_type;
907+
char *domain;
908+
uint8_t *address;
909+
uint16_t option_len;
910+
option_len = net_dns_option_vendor_option_data_get_next(options->option.vendor_spesific.data, options->option.vendor_spesific.data_length, &option_type);
911+
tr_debug("DHCP vendor specific data type:%u length %d", option_type, option_len);
912+
//tr_debug("DHCP vendor specific data %s", trace_array(options->option.vendor_spesific.data, options->option.vendor_spesific.data_length));
913+
914+
if (option_len == 0) {
915+
// Option fields were corrupted
916+
break;
917+
}
918+
if (option_type == ARM_DHCP_VENDOR_DATA_DNS_QUERY_RESULT) {
919+
// Process ARM DNS query result
920+
domain = NULL;
921+
address = NULL;
922+
if (net_dns_option_vendor_option_data_dns_query_read(options->option.vendor_spesific.data, options->option.vendor_spesific.data_length, &address, &domain) > 0 ||
923+
domain || address) {
924+
// Valid ARM DNS query entry
925+
net_dns_query_result_set(interface, address, domain, server_info->life_time);
926+
}
927+
}
928+
929+
options->option.vendor_spesific.data_length -= option_len;
930+
options->option.vendor_spesific.data += option_len;
931+
}
932+
break;
933+
934+
case DHCPV6_OPTION_DNS_SERVERS:
935+
while (options->option.generic.data_length) {
936+
net_dns_server_address_set(interface, server_ll64, options->option.generic.data, server_info->life_time);
937+
options->option.generic.data_length -= 16;
938+
options->option.generic.data += 16;
939+
}
940+
break;
941+
case DHCPV6_OPTION_DOMAIN_LIST:
942+
net_dns_server_search_list_set(interface, server_ll64, options->option.generic.data, options->option.generic.data_length, server_info->life_time);
943+
break;
944+
default:
945+
break;
946+
}
947+
948+
}
949+
950+
875951
static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
876952
{
877953
int8_t ret_val = -1;
@@ -923,6 +999,7 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
923999
dhcp_service_link_local_rx_cb_set(cur->id, ws_bootstrap_dhcp_neighbour_update_cb);
9241000
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.
9251001
dhcp_client_solicit_timeout_set(cur->id, WS_DHCP_SOLICIT_TIMEOUT, WS_DHCP_SOLICIT_MAX_RT, WS_DHCP_SOLICIT_MAX_RC);
1002+
dhcp_client_option_notification_cb_set(cur->id, ws_bootstrap_dhcp_info_notify_cb);
9261003

9271004

9281005
ws_nud_table_reset(cur);
@@ -1520,7 +1597,11 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
15201597
tr_info("Updated PAN configuration own:%d, heard:%d", cur->ws_info->pan_information.pan_version, pan_version);
15211598

15221599
// restart PAN version timer
1523-
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
1600+
//Check Here Do we have a selected Primary parent
1601+
if (!cur->ws_info->configuration_learned || cur->ws_info->rpl_state == RPL_EVENT_DAO_DONE) {
1602+
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
1603+
}
1604+
15241605
cur->ws_info->pan_information.pan_version = pan_version;
15251606

15261607
ws_pae_controller_gtk_hash_update(cur, gtkhash_ptr);

source/6LoWPAN/ws/ws_config.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,4 +273,11 @@ extern uint8_t DEVICE_MIN_SENS;
273273
#define RADIUS_CLIENT_RETRY_IMAX 30 // First retry maximum 3 seconds
274274
#define RADIUS_CLIENT_TIMER_EXPIRATIONS 3 // Number of retries is three
275275

276+
/*
277+
* EAP-TLS fragment length
278+
*
279+
* Configures both EAP-TLS and the RADIUS client (Framed-MTU on RFC 2864)
280+
*/
281+
#define EAP_TLS_FRAGMENT_LEN_VALUE 600 // EAP-TLS fragment length
282+
276283
#endif /* WS_CONFIG_H_ */

source/6LoWPAN/ws/ws_eapol_relay.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,14 @@ int8_t ws_eapol_relay_start(protocol_interface_info_entry_t *interface_ptr, uint
6666
return -1;
6767
}
6868

69-
if (ws_eapol_relay_get(interface_ptr)) {
69+
eapol_relay_t *eapol_relay = ws_eapol_relay_get(interface_ptr);
70+
71+
if (eapol_relay) {
72+
memcpy(&eapol_relay->remote_addr.address, remote_addr, 16);
7073
return 0;
7174
}
7275

73-
eapol_relay_t *eapol_relay = ns_dyn_mem_alloc(sizeof(eapol_relay_t));
76+
eapol_relay = ns_dyn_mem_alloc(sizeof(eapol_relay_t));
7477
if (!eapol_relay) {
7578
return -1;
7679
}

source/6LoWPAN/ws/ws_pae_controller.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,8 @@ int8_t ws_pae_controller_radius_address_set(int8_t interface_id, const uint8_t *
12211221
}
12221222

12231223
if (ws_pae_auth_radius_address_set(controller->interface_ptr, radius_cfg->radius_addr) < 0) {
1224-
return -1;
1224+
// If not set here since authenticator not created, then set on authenticator initialization
1225+
return 0;
12251226
}
12261227

12271228
return 0;

source/Common_Protocols/icmpv6.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,21 @@ if_address_entry_t *icmpv6_slaac_address_add(protocol_interface_info_entry_t *cu
639639
}
640640

641641
#ifdef HAVE_IPV6_ND
642+
643+
static uint8_t icmpv6_dns_search_list_remove_pad(uint8_t *data_ptr, uint8_t length)
644+
{
645+
while (length) {
646+
647+
if (data_ptr[length - 2] && data_ptr[length - 1] == 0) {
648+
break;
649+
} else if (data_ptr[length - 2] == 0 && data_ptr[length - 1] == 0) {
650+
length--;
651+
}
652+
}
653+
654+
return length;
655+
}
656+
642657
static buffer_t *icmpv6_ra_handler(buffer_t *buf)
643658
{
644659
protocol_interface_info_entry_t *cur;
@@ -869,7 +884,8 @@ static buffer_t *icmpv6_ra_handler(buffer_t *buf)
869884
uint32_t dns_lifetime = common_read_32_bit(dptr + 2); // 2 x reserved
870885
uint8_t *dns_search_list = dptr + 6;
871886
uint8_t dns_search_list_len = length - 8; // Length includes type and length
872-
887+
//Cut Padding
888+
dns_search_list_len = icmpv6_dns_search_list_remove_pad(dns_search_list, dns_search_list_len);
873889
//tr_info("DNS Search List: %s Lifetime: %lu", trace_array(dns_search_list, dns_search_list_len), (unsigned long) dns_lifetime);
874890
// Add DNS server to DNS information storage.
875891
net_dns_server_search_list_set(cur->id, buf->src_sa.address, dns_search_list, dns_search_list_len, dns_lifetime);

0 commit comments

Comments
 (0)