19
19
#include "nsconfig.h"
20
20
#include "ns_types.h"
21
21
#include "ns_trace.h"
22
+ #include "nsdynmemLIB.h"
22
23
#include "net_interface.h"
23
24
#include "socket_api.h"
24
25
#include "eventOS_event.h"
41
42
#include "6LoWPAN/ws/ws_pae_controller.h"
42
43
#include "DHCPv6_Server/DHCPv6_server_service.h"
43
44
#include "DHCPv6_client/dhcpv6_client_api.h"
45
+ #include "libDHCPv6/libDHCPv6_vendordata.h"
44
46
#include "libNET/src/net_dns_internal.h"
45
47
46
48
@@ -93,6 +95,17 @@ static rpl_dodag_conf_t rpl_conf = {
93
95
.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_SMALL
94
96
};
95
97
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
+
96
109
static void ws_bbr_rpl_version_timer_start (protocol_interface_info_entry_t * cur , uint8_t version )
97
110
{
98
111
// 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
368
381
wisun_bbr_na_send (backbone_interface_id , address_info -> allocatedAddress );
369
382
return true;
370
383
}
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 )
372
386
{
373
387
//add DNS server information to DHCP server that is learned from the backbone interface.
374
388
uint8_t dns_server_address [16 ];
@@ -377,13 +391,37 @@ static void ws_bbr_dhcp_server_dns_info_update(protocol_interface_info_entry_t *
377
391
(void )cur ;
378
392
if (net_dns_server_get (backbone_interface_id , dns_server_address , & dns_search_list_ptr , & dns_search_list_len , 0 ) == 0 ) {
379
393
/*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 );
381
395
}
382
396
383
397
//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 );
387
425
}
388
426
389
427
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
406
444
//SEt max value for not limiting address allocation
407
445
DHCPv6_server_service_set_max_clients_accepts_count (cur -> id , global_id , MAX_SUPPORTED_ADDRESS_LIST_SIZE );
408
446
409
- ws_bbr_dhcp_server_dns_info_update (cur );
447
+ ws_bbr_dhcp_server_dns_info_update (cur , global_id );
410
448
411
449
ws_dhcp_client_address_request (cur , global_id , ll );
412
450
}
@@ -594,7 +632,7 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
594
632
// Add also global prefix and route to RPL
595
633
rpl_control_update_dodag_route (protocol_6lowpan_rpl_root_dodag , current_global_prefix , 64 , 0 , WS_ROUTE_LIFETIME , false);
596
634
}
597
- ws_bbr_dhcp_server_dns_info_update (cur );
635
+ ws_bbr_dhcp_server_dns_info_update (cur , current_global_prefix );
598
636
}
599
637
}
600
638
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],
1200
1238
{
1201
1239
#ifdef HAVE_WS_BORDER_ROUTER
1202
1240
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 ) {
1204
1242
return -1 ;
1205
1243
}
1206
1244
@@ -1210,10 +1248,62 @@ int ws_bbr_dns_query_result_set(int8_t interface_id, const uint8_t address[16],
1210
1248
*
1211
1249
* This is included in the vendor extension where the format is decided by the vendor
1212
1250
*/
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
1215
1251
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 );
1217
1307
return 0 ;
1218
1308
#else
1219
1309
(void ) interface_id ;
0 commit comments