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 ];
@@ -381,9 +395,34 @@ static void ws_bbr_dhcp_server_dns_info_update(protocol_interface_info_entry_t *
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
+ (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);
387
426
}
388
427
389
428
static 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
406
445
//SEt max value for not limiting address allocation
407
446
DHCPv6_server_service_set_max_clients_accepts_count (cur -> id , global_id , MAX_SUPPORTED_ADDRESS_LIST_SIZE );
408
447
409
- ws_bbr_dhcp_server_dns_info_update (cur );
448
+ ws_bbr_dhcp_server_dns_info_update (cur , global_id );
410
449
411
450
ws_dhcp_client_address_request (cur , global_id , ll );
412
451
}
@@ -594,7 +633,7 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
594
633
// Add also global prefix and route to RPL
595
634
rpl_control_update_dodag_route (protocol_6lowpan_rpl_root_dodag , current_global_prefix , 64 , 0 , WS_ROUTE_LIFETIME , false);
596
635
}
597
- ws_bbr_dhcp_server_dns_info_update (cur );
636
+ ws_bbr_dhcp_server_dns_info_update (cur , current_global_prefix );
598
637
}
599
638
}
600
639
void 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],
1200
1239
{
1201
1240
#ifdef HAVE_WS_BORDER_ROUTER
1202
1241
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 ) {
1204
1243
return -1 ;
1205
1244
}
1206
1245
@@ -1210,10 +1249,62 @@ int ws_bbr_dns_query_result_set(int8_t interface_id, const uint8_t address[16],
1210
1249
*
1211
1250
* This is included in the vendor extension where the format is decided by the vendor
1212
1251
*/
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
1252
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 );
1217
1308
return 0 ;
1218
1309
#else
1219
1310
(void ) interface_id ;
0 commit comments