@@ -37,6 +37,13 @@ std::unordered_map<std::string, boost::log::trivial::severity_level> Config::sev
37
37
{boost::log::trivial::to_string (boost::log ::trivial::fatal), boost::log ::trivial::fatal}
38
38
};
39
39
40
+ std::unordered_map<std::string, Config::IPv6Mode> Config::ipv6mode_map = {
41
+ {" Off" , Config::IPv6Mode::Off},
42
+ {" OnlyForLocal" , Config::IPv6Mode::OnlyForLocal},
43
+ {" OnlyForRemote" , Config::IPv6Mode::OnlyForRemote},
44
+ {" Full" , Config::IPv6Mode::Full},
45
+ };
46
+
40
47
void Config::trimAll () {
41
48
for (auto &local : locals) {
42
49
boost::trim (local.address );
@@ -62,9 +69,9 @@ Config *Config::load_config_file(const std::string &config_filename) {
62
69
} else {
63
70
std::cerr << " Error type of config file (either json "
64
71
65
- #ifdef ENABLE_XML
72
+ #ifdef ENABLE_XML
66
73
" or xml"
67
- #endif
74
+ #endif
68
75
" format)" << std::endl;
69
76
exit (1 );
70
77
}
@@ -119,7 +126,7 @@ void fill_scope(Config::DnsRecord &dnsRecord, const std::string &scope_str) {
119
126
try {
120
127
number = boost::lexical_cast<int >(results[1 ].c_str ());
121
128
} catch (boost::bad_lexical_cast &e) {
122
- std::cerr << " mask length must be a integer: " << e.what () << std::endl;
129
+ std::cerr << " mask length must be a integer: " << e.what () << std::endl;
123
130
exit (4 );
124
131
}
125
132
@@ -141,8 +148,8 @@ void fill_scope(Config::DnsRecord &dnsRecord, const std::string &scope_str) {
141
148
}
142
149
number--;
143
150
}
144
- *((uint64_t *) &scope.scope_mask .mask6 .s6_addr ) = htobe64 (mask_number_high);
145
- *((uint64_t *) (scope.scope_mask .mask6 .s6_addr + 8 )) = htobe64 (mask_number_low);
151
+ *((uint64_t * ) & scope.scope_mask .mask6 .s6_addr ) = htobe64 (mask_number_high);
152
+ *((uint64_t * ) (scope.scope_mask .mask6 .s6_addr + 8 )) = htobe64 (mask_number_low);
146
153
// std::cout << mask_number_high << " " << mask_number_low << std::endl;
147
154
148
155
} else {
@@ -167,6 +174,7 @@ void fill_scope(Config::DnsRecord &dnsRecord, const std::string &scope_str) {
167
174
}
168
175
169
176
#ifdef ENABLE_XML
177
+
170
178
Config *Config::load_xml_config (const std::string &filename) {
171
179
172
180
@@ -202,7 +210,23 @@ Config *Config::load_xml_config(const std::string &filename) {
202
210
203
211
config->enableCache = root.child (" enableCache" ).text ().as_bool (false );
204
212
config->enableTcp = root.child (" enableTcp" ).text ().as_bool (false );
205
- config->ipv6First = static_cast <IPv6Mode >(root.child (" ipv6First" ).text ().as_int (1 ));
213
+
214
+ try {
215
+ config->ipv6First = Config::ipv6mode_map.at (boost::trim_copy (std::string (root.child (" ipv6First" ).text ().as_string (" Off" ))));
216
+ } catch (std::out_of_range &e) {
217
+ std::cerr << " Unkown ipv6First Mode : " << e.what () << std::endl;
218
+ exit (EXIT_FAILURE);
219
+ }
220
+
221
+
222
+ if (auto ipv6FirstExceptIter = root.child (" ipv6FirstExcept" ); !ipv6FirstExceptIter.empty ()) {
223
+ for (auto &domain : ipv6FirstExceptIter.children (" domain" )) {
224
+ std::string domain_str = domain.text ().as_string ();
225
+ boost::trim (domain_str);
226
+ if (!domain_str.empty ()) config->ipv6FirstExcept .insert (domain_str);
227
+ }
228
+ }
229
+
206
230
config->gfwMode = root.child (" gfwMode" ).text ().as_bool (false );
207
231
config->daemonMode = root.child (" daemonMode" ).text ().as_bool (false );
208
232
@@ -237,6 +261,10 @@ Config *Config::load_xml_config(const std::string &filename) {
237
261
for (auto scope : scopes.children (" scope" )) {
238
262
std::string scope_str = scope.text ().as_string ();
239
263
boost::trim (scope_str);
264
+ if (scope_str.empty ()) {
265
+ std::cerr << " scope is empty\n " ;
266
+ exit (EXIT_FAILURE);
267
+ }
240
268
fill_scope (dnsRecord, scope_str);
241
269
}
242
270
}
@@ -253,6 +281,7 @@ Config *Config::load_xml_config(const std::string &filename) {
253
281
return config;
254
282
255
283
}
284
+
256
285
#endif
257
286
258
287
Config *Config::load_json_config (const std::string &filename) {
@@ -273,23 +302,22 @@ Config *Config::load_json_config(const std::string &filename) {
273
302
274
303
config->enableCache = j.value (" enableCache" , false );
275
304
config->enableTcp = j.value (" enableTcp" , false );
276
- switch (j.value (" ipv6First" , 1 )) {
277
- case 0 :
278
- config->ipv6First = IPv6Mode::Off;
279
- break ;
280
- case 1 :
281
- config->ipv6First = IPv6Mode::OnlyForRemote;
282
- break ;
283
- case 2 :
284
- config->ipv6First = IPv6Mode::Full;
285
- break ;
286
- case 3 :
287
- config->ipv6First = IPv6Mode::OnlyForLocal;
288
- break ;
289
- default :
290
- std::cerr << " err type number of ipv6First mode" << std::endl;
291
- return nullptr ;
305
+ try {
306
+ config->ipv6First = Config::ipv6mode_map.at (boost::trim_copy (std::string (j.value (" ipv6First" , " Off" ))));
307
+ } catch (std::out_of_range &e) {
308
+ std::cerr << " Unkown ipv6First Mode : " << e.what () << std::endl;
309
+ exit (EXIT_FAILURE);
310
+ }
311
+
312
+ auto it = j.find (" ipv6FirstExcept" );
313
+ if (it != j.end ()) {
314
+ for (auto &domain : *it) {
315
+ std::string domain_str = domain;
316
+ config->ipv6FirstExcept .insert (domain_str);
317
+ }
292
318
}
319
+
320
+
293
321
config->gfwMode = j.value (" gfwMode" , false );
294
322
config->daemonMode = j.value (" daemonMode" , false );
295
323
@@ -312,7 +340,7 @@ Config *Config::load_json_config(const std::string &filename) {
312
340
config->localnet_server_port = localnet.value (" port" , 53 );
313
341
314
342
315
- auto it = j.find (" mappings" );
343
+ it = j.find (" mappings" );
316
344
if (it != j.end ()) {
317
345
for (auto &item : *it) {
318
346
std::string type_str = item[" type" ];
@@ -361,23 +389,24 @@ bool Config::DnsRecord::match(struct sockaddr_storage &client_addr) {
361
389
for (auto &scope : scopes) {
362
390
switch (scope.scope_ss_family ) {
363
391
case AF_INET:
364
- if (client_addr.ss_family == AF_INET6) {
365
- if (IN6_IS_ADDR_V4MAPPED (&reinterpret_cast <sockaddr_in6 *>(&client_addr)->sin6_addr )) {
366
- if ((*reinterpret_cast <uint32_t *>(reinterpret_cast <sockaddr_in6 *>(
367
- &client_addr)->sin6_addr .s6_addr + 12 ) &
368
- scope.scope_mask .mask .s_addr ) == scope.scope_addr .addr .s_addr ) {
369
- return true ;
370
- }
371
- }
372
- } else if (client_addr.ss_family == AF_INET) {
373
- if ((reinterpret_cast <sockaddr_in *>(&client_addr)->sin_addr .s_addr & scope.scope_mask .mask .s_addr ) ==
374
- scope.scope_addr .addr .s_addr )
375
- return true ;
376
- }
392
+ if (client_addr.ss_family == AF_INET6) {
393
+ if (IN6_IS_ADDR_V4MAPPED (&reinterpret_cast <sockaddr_in6 *>(&client_addr)->sin6_addr )) {
394
+ if ((*reinterpret_cast <uint32_t *>(reinterpret_cast <sockaddr_in6 *>(
395
+ &client_addr)->sin6_addr .s6_addr + 12 ) &
396
+ scope.scope_mask .mask .s_addr ) == scope.scope_addr .addr .s_addr ) {
397
+ return true ;
398
+ }
399
+ }
400
+ } else if (client_addr.ss_family == AF_INET) {
401
+ if ((reinterpret_cast <sockaddr_in *>(&client_addr)->sin_addr .s_addr & scope.scope_mask .mask .s_addr ) ==
402
+ scope.scope_addr .addr .s_addr )
403
+ return true ;
404
+ }
377
405
break ;
378
406
379
407
case AF_INET6:
380
- if (client_addr.ss_family == AF_INET6 and ! IN6_IS_ADDR_V4MAPPED (&reinterpret_cast <sockaddr_in6 *>(&client_addr)->sin6_addr ) ) {
408
+ if (client_addr.ss_family == AF_INET6 and
409
+ !IN6_IS_ADDR_V4MAPPED (&reinterpret_cast <sockaddr_in6 *>(&client_addr)->sin6_addr )) {
381
410
382
411
uint64_t high = *reinterpret_cast <uint64_t *>(reinterpret_cast <sockaddr_in6 *>(&client_addr)->sin6_addr .s6_addr );
383
412
uint64_t low = *reinterpret_cast <uint64_t *>(
0 commit comments