Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -59,10 +59,14 @@ # define __NOGLOBALIFACE__ # include # include #endif +#ifdef OF_NINTENDO_3DS +# include <3ds.h> +#endif + /* * RFC 1035 doesn't specify if pointers to pointers are allowed, and if so how * many. Since it's unspecified, we have to assume that it might happen, but we * also want to limit it to avoid DoS. Limiting it to 16 levels of pointers and * immediately rejecting pointers to itself seems like a fair balance. @@ -154,11 +158,11 @@ @end @interface OFDNSResolver () - (void)of_setDefaults; - (void)of_obtainSystemConfig; -#ifdef OF_HAVE_FILES +#if defined(OF_HAVE_FILES) && !defined(OF_NINTENDO_3DS) - (void)of_parseHosts: (OFString *)path; # if !defined(OF_WINDOWS) && !defined(OF_AMIGAOS4) - (void)of_parseResolvConf: (OFString *)path; - (void)of_parseResolvConfOption: (OFString *)option; # endif @@ -167,10 +171,13 @@ - (void)of_obtainWindowsSystemConfig; #endif #ifdef OF_AMIGAOS4 - (void)of_obtainAmigaOS4SystemConfig; #endif +#ifdef OF_NINTENDO_3DS +- (void)of_obtainNintendo3DSSytemConfig; +#endif - (void)of_reloadSystemConfig; - (void)of_resolveHost: (OFString *)host recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType settings: (OFDNSResolverSettings *)settings @@ -799,11 +806,15 @@ { _timeout = 2; _maxAttempts = 3; _minNumberOfDotsInAbsoluteName = 1; _usesTCP = false; +#ifndef OF_NINTENDO_3DS _configReloadInterval = 2; +#else + _configReloadInterval = 0; +#endif } - (void)of_obtainSystemConfig { void *pool = objc_autoreleasePoolPush(); @@ -827,10 +838,12 @@ [self of_obtainWindowsSystemConfig]; #elif defined(OF_AMIGAOS4) [self of_parseHosts: HOSTS_PATH]; [self of_obtainAmigaOS4SystemConfig]; +#elif defined(OF_NINTENDO_3DS) + [self of_obtainNintendo3DSSytemConfig]; #elif defined(OF_HAVE_FILES) [self of_parseHosts: HOSTS_PATH]; # ifdef OF_OPENBSD [self of_parseHosts: @"/etc/resolv.conf.tail"]; # endif @@ -893,11 +906,11 @@ [_queries release]; [super dealloc]; } -#ifdef OF_HAVE_FILES +#if defined(OF_HAVE_FILES) && !defined(OF_NINTENDO_3DS) - (void)of_parseHosts: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFCharacterSet *whitespaceCharacterSet = [OFCharacterSet whitespaceCharacterSet]; @@ -1152,10 +1165,53 @@ } if (GetDefaultDomainName(buffer, sizeof(buffer))) _localDomain = [[OFString alloc] initWithCString: buffer encoding: encoding]; +} +#endif + +#ifdef OF_NINTENDO_3DS +- (void)of_obtainNintendo3DSSytemConfig +{ + OFMutableArray *nameServers = [OFMutableArray array]; + union { + /* + * For some unknown reason, this needs a 336 bytes buffer and + * always returns 336 bytes. + */ + char bytes[336]; + SOCU_DNSTableEntry entries[2]; + } buffer; + socklen_t optLen = sizeof(buffer); + + if (SOCU_GetNetworkOpt(SOL_CONFIG, NETOPT_DNS_TABLE, + &buffer, &optLen) != 0) + return; + + /* + * We're fine if this gets smaller in a future release (unlikely), as + * long as two entries still fit. + */ + if (optLen < sizeof(buffer.entries)) + return; + + for (uint_fast8_t i = 0; i < 2; i++) { + uint32_t ip = OF_BSWAP32_IF_LE(buffer.entries[i].ip.s_addr); + + if (ip == 0) + continue; + + [nameServers addObject: [OFString stringWithFormat: + @"%u.%u.%u.%u", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, + (ip >> 8) & 0xFF, ip & 0xFF]]; + } + + if ([nameServers count] > 0) { + [nameServers makeImmutable]; + _nameServers = [nameServers copy]; + } } #endif - (void)of_reloadSystemConfig {