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"
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+
96109static 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 ];
@@ -381,9 +395,34 @@ static void ws_bbr_dhcp_server_dns_info_update(protocol_interface_info_entry_t *
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+ (void )global_id ;
425+ //DHCPv6_server_service_set_vendor_data(cur->id, global_id, ARM_ENTERPRISE_NUMBER, dhcp_vendor_data_ptr, dhcp_vendor_data_len);
387426}
388427
389428static void ws_bbr_dhcp_server_start (protocol_interface_info_entry_t * cur , uint8_t * global_id , uint32_t dhcp_address_lifetime )
@@ -406,7 +445,7 @@ static void ws_bbr_dhcp_server_start(protocol_interface_info_entry_t *cur, uint8
406445 //SEt max value for not limiting address allocation
407446 DHCPv6_server_service_set_max_clients_accepts_count (cur -> id , global_id , MAX_SUPPORTED_ADDRESS_LIST_SIZE );
408447
409- ws_bbr_dhcp_server_dns_info_update (cur );
448+ ws_bbr_dhcp_server_dns_info_update (cur , global_id );
410449
411450 ws_dhcp_client_address_request (cur , global_id , ll );
412451}
@@ -594,7 +633,7 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
594633 // Add also global prefix and route to RPL
595634 rpl_control_update_dodag_route (protocol_6lowpan_rpl_root_dodag , current_global_prefix , 64 , 0 , WS_ROUTE_LIFETIME , false);
596635 }
597- ws_bbr_dhcp_server_dns_info_update (cur );
636+ ws_bbr_dhcp_server_dns_info_update (cur , current_global_prefix );
598637 }
599638}
600639void ws_bbr_pan_version_increase (protocol_interface_info_entry_t * cur )
@@ -1200,7 +1239,7 @@ int ws_bbr_dns_query_result_set(int8_t interface_id, const uint8_t address[16],
12001239{
12011240#ifdef HAVE_WS_BORDER_ROUTER
12021241 protocol_interface_info_entry_t * cur = protocol_stack_interface_info_get_by_id (interface_id );
1203- if (!cur || ! address || ! domain_name_ptr ) {
1242+ if (!cur ) {
12041243 return -1 ;
12051244 }
12061245
@@ -1210,10 +1249,62 @@ int ws_bbr_dns_query_result_set(int8_t interface_id, const uint8_t address[16],
12101249 *
12111250 * This is included in the vendor extension where the format is decided by the vendor
12121251 */
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
12151252
1216- ws_bbr_dhcp_server_dns_info_update (cur );
1253+ // Delete all entries
1254+ if (!domain_name_ptr ) {
1255+ for (int n = 0 ; n < MAX_DNS_RESOLUTIONS ; n ++ ) {
1256+ // Delete all entries
1257+ memset (pre_resolved_dns_queries [n ].address , 0 , 16 );
1258+ ns_dyn_mem_free (pre_resolved_dns_queries [n ].domain_name );
1259+ pre_resolved_dns_queries [n ].domain_name = NULL ;
1260+ }
1261+ goto update_information ;
1262+ }
1263+
1264+ // Update existing entries or delete
1265+ for (int n = 0 ; n < MAX_DNS_RESOLUTIONS ; n ++ ) {
1266+ if (pre_resolved_dns_queries [n ].domain_name != NULL &&
1267+ strcasecmp (pre_resolved_dns_queries [n ].domain_name , domain_name_ptr ) == 0 ) {
1268+ // Matching query updated
1269+ if (address ) {
1270+ // Update address
1271+ memcpy (pre_resolved_dns_queries [n ].address , address , 16 );
1272+ } else {
1273+ // delete entry
1274+ memset (pre_resolved_dns_queries [n ].address , 0 , 16 );
1275+ ns_dyn_mem_free (pre_resolved_dns_queries [n ].domain_name );
1276+ pre_resolved_dns_queries [n ].domain_name = NULL ;
1277+ }
1278+ goto update_information ;
1279+ }
1280+ }
1281+
1282+ if (address && domain_name_ptr ) {
1283+ // Store new entry to the list
1284+ for (int n = 0 ; n < MAX_DNS_RESOLUTIONS ; n ++ ) {
1285+ if (pre_resolved_dns_queries [n ].domain_name == NULL ) {
1286+ // Free entry found
1287+ pre_resolved_dns_queries [n ].domain_name = ns_dyn_mem_alloc (strlen (domain_name_ptr ) + 1 );
1288+ if (!pre_resolved_dns_queries [n ].domain_name ) {
1289+ // Out of memory
1290+ return -2 ;
1291+ }
1292+ memcpy (pre_resolved_dns_queries [n ].address , address , 16 );
1293+ strcpy (pre_resolved_dns_queries [n ].domain_name , domain_name_ptr );
1294+ goto update_information ;
1295+ }
1296+ }
1297+ // No room to store new field
1298+ return -3 ;
1299+ }
1300+
1301+ update_information :
1302+ if (memcmp (current_global_prefix , ADDR_UNSPECIFIED , 8 ) == 0 ) {
1303+ // Not in active state so changes are activated after start
1304+ return 0 ;
1305+ }
1306+
1307+ ws_bbr_dhcp_server_dns_info_update (cur , current_global_prefix );
12171308 return 0 ;
12181309#else
12191310 (void ) interface_id ;
0 commit comments