Overview
Comment: | OFDNSResolver: Let queries time out |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
452616df69b37e5fe498c032bcebb51a |
User & Date: | js on 2018-08-05 15:24:43 |
Other Links: | manifest | tags |
Context
2018-08-05
| ||
19:27 | OFRunLoop: More robust handling of cancels check-in: 1bf3b2ac7c user: js tags: trunk | |
15:24 | OFDNSResolver: Let queries time out check-in: 452616df69 user: js tags: trunk | |
2018-08-04
| ||
23:54 | Fix compilation with GCC check-in: 7b0f48419d user: js tags: trunk | |
Changes
Modified src/OFDNSResolver.m from [ef5cd89abc] to [7ee76905cc].
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #import "OFCharacterSet.h" #import "OFData.h" #import "OFDictionary.h" #import "OFFile.h" #import "OFLocale.h" #import "OFNumber.h" #import "OFString.h" #import "OFUDPSocket.h" #ifdef OF_WINDOWS # import "OFWindowsRegistryKey.h" #endif #import "OFInvalidArgumentException.h" #import "OFInvalidServerReplyException.h" | > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #import "OFCharacterSet.h" #import "OFData.h" #import "OFDictionary.h" #import "OFFile.h" #import "OFLocale.h" #import "OFNumber.h" #import "OFString.h" #import "OFTimer.h" #import "OFUDPSocket.h" #ifdef OF_WINDOWS # import "OFWindowsRegistryKey.h" #endif #import "OFInvalidArgumentException.h" #import "OFInvalidServerReplyException.h" |
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 | * 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. */ #define MAX_ALLOWED_POINTERS 16 /* * TODO: * | > > < > > | > | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | * 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. */ #define MAX_ALLOWED_POINTERS 16 #define TIMEOUT 2 /* * TODO: * * - Resolve with each search domain * - Iterate through name servers * - Fallback to TCP */ @interface OFDNSResolver_context: OFObject { OFString *_host; of_dns_resource_record_class_t _recordClass; of_dns_resource_record_type_t _recordType; OFNumber *_ID; OFArray OF_GENERIC(OFString *) *_nameServers, *_searchDomains; size_t _nameServersIndex, _searchDomainsIndex; OFMutableData *_queryData; id _target; SEL _selector; id _userContext; OFTimer *_timer; } @property (readonly, nonatomic) OFString *host; @property (readonly, nonatomic) of_dns_resource_record_class_t recordClass; @property (readonly, nonatomic) of_dns_resource_record_type_t recordType; @property (readonly, nonatomic) OFNumber *ID; @property (readonly, nonatomic) OFArray OF_GENERIC(OFString *) *nameServers; @property (readonly, nonatomic) OFArray OF_GENERIC(OFString *) *searchDomains; @property (nonatomic) size_t nameServersIndex; @property (nonatomic) size_t searchDomainsIndex; @property (readonly, nonatomic) OFMutableData *queryData; @property (readonly, nonatomic) id target; @property (readonly, nonatomic) SEL selector; @property (readonly, nonatomic) id userContext; @property (readonly, nonatomic) OFTimer *timer; - (instancetype)initWithHost: (OFString *)host recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType ID: (OFNumber *)ID nameServers: (OFArray OF_GENERIC(OFString *) *)nameServers searchDomains: (OFArray OF_GENERIC(OFString *) *)searchDomains queryData: (OFMutableData *)queryData target: (id)target selector: (SEL)selector userContext: (id)userContext timer: (OFTimer *)timer; @end @interface OFDNSResolver () #ifdef OF_HAVE_FILES - (void)of_parseHosts: (OFString *)path; # ifndef OF_WINDOWS - (void)of_parseResolvConf: (OFString *)path; |
︙ | ︙ | |||
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | @implementation OFDNSResolver_context @synthesize host = _host, recordClass = _recordClass, recordType = _recordType; @synthesize ID = _ID, nameServers = _nameServers; @synthesize searchDomains = _searchDomains; @synthesize nameServersIndex = _nameServersIndex; @synthesize searchDomainsIndex = _searchDomainsIndex, queryData = _queryData; @synthesize target = _target, selector = _selector, userContext = _userContext; - (instancetype)initWithHost: (OFString *)host recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType ID: (OFNumber *)ID nameServers: (OFArray OF_GENERIC(OFString *) *)nameServers searchDomains: (OFArray OF_GENERIC(OFString *) *)searchDomains queryData: (OFMutableData *)queryData target: (id)target selector: (SEL)selector userContext: (id)userContext { self = [super init]; @try { _host = [host copy]; _recordClass = recordClass; _recordType = recordType; _ID = [ID retain]; _nameServers = [nameServers copy]; _searchDomains = [searchDomains copy]; _queryData = [queryData retain]; _target = [target retain]; _selector = selector; _userContext = [userContext retain]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_host release]; [_ID release]; [_nameServers release]; [_searchDomains release]; [_queryData release]; [_target release]; [_userContext release]; [super dealloc]; } @end @implementation OFDNSResolver @synthesize staticHosts = _staticHosts, nameServers = _nameServers; | > > > > | 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | @implementation OFDNSResolver_context @synthesize host = _host, recordClass = _recordClass, recordType = _recordType; @synthesize ID = _ID, nameServers = _nameServers; @synthesize searchDomains = _searchDomains; @synthesize nameServersIndex = _nameServersIndex; @synthesize searchDomainsIndex = _searchDomainsIndex, queryData = _queryData; @synthesize target = _target, selector = _selector, userContext = _userContext; @synthesize timer = _timer; - (instancetype)initWithHost: (OFString *)host recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType ID: (OFNumber *)ID nameServers: (OFArray OF_GENERIC(OFString *) *)nameServers searchDomains: (OFArray OF_GENERIC(OFString *) *)searchDomains queryData: (OFMutableData *)queryData target: (id)target selector: (SEL)selector userContext: (id)userContext timer: (OFTimer *)timer { self = [super init]; @try { _host = [host copy]; _recordClass = recordClass; _recordType = recordType; _ID = [ID retain]; _nameServers = [nameServers copy]; _searchDomains = [searchDomains copy]; _queryData = [queryData retain]; _target = [target retain]; _selector = selector; _userContext = [userContext retain]; _timer = [timer retain]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_host release]; [_ID release]; [_nameServers release]; [_searchDomains release]; [_queryData release]; [_target release]; [_userContext release]; [_timer release]; [super dealloc]; } @end @implementation OFDNSResolver @synthesize staticHosts = _staticHosts, nameServers = _nameServers; |
︙ | ︙ | |||
902 903 904 905 906 907 908 909 910 911 912 913 914 915 | ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]]; DNSResolverContext = [[[_queries objectForKey: ID] retain] autorelease]; if (DNSResolverContext == nil) return false; [_queries removeObjectForKey: ID]; target = [DNSResolverContext target]; selector = [DNSResolverContext selector]; callback = (void (*)(id, SEL, OFArray *, id, id)) [target methodForSelector: selector]; queryData = [DNSResolverContext queryData]; | > | 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 | ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]]; DNSResolverContext = [[[_queries objectForKey: ID] retain] autorelease]; if (DNSResolverContext == nil) return false; [[DNSResolverContext timer] invalidate]; [_queries removeObjectForKey: ID]; target = [DNSResolverContext target]; selector = [DNSResolverContext selector]; callback = (void (*)(id, SEL, OFArray *, id, id)) [target methodForSelector: selector]; queryData = [DNSResolverContext queryData]; |
︙ | ︙ | |||
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 | } callback(target, selector, answers, [DNSResolverContext userContext], nil); return false; } - (size_t)of_socket: (OFUDPSocket *)sock didSendBuffer: (void **)buffer bytesSent: (size_t)bytesSent receiver: (of_socket_address_t *)receiver context: (id)DNSResolverContext exception: (id)exception | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 | } callback(target, selector, answers, [DNSResolverContext userContext], nil); return false; } - (void)of_queryWithIDTimedOut: (OFNumber *)ID { OFDNSResolver_context *DNSResolverContext = [_queries objectForKey: ID]; id target; SEL selector; void (*callback)(id, SEL, OFArray *, id, id); OFResolveHostFailedException *exception; if (DNSResolverContext == nil) return; target = [[[DNSResolverContext target] retain] autorelease]; selector = [DNSResolverContext selector]; callback = (void (*)(id, SEL, OFArray *, id, id)) [target methodForSelector: selector]; exception = [OFResolveHostFailedException exceptionWithHost: [DNSResolverContext host] recordClass: [DNSResolverContext recordClass] recordType: [DNSResolverContext recordType] error: OF_DNS_RESOLVER_ERROR_TIMEOUT]; [_queries removeObjectForKey: [DNSResolverContext ID]]; callback(target, selector, nil, [DNSResolverContext userContext], exception); } - (size_t)of_socket: (OFUDPSocket *)sock didSendBuffer: (void **)buffer bytesSent: (size_t)bytesSent receiver: (of_socket_address_t *)receiver context: (id)DNSResolverContext exception: (id)exception |
︙ | ︙ | |||
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 | recordType: (of_dns_resource_record_type_t)recordType target: (id)target selector: (SEL)selector context: (id)context { void *pool = objc_autoreleasePoolPush(); OFMutableData *data = [OFMutableData dataWithCapacity: 512]; OFDNSResolver_context *DNSResolverContext; OFNumber *ID; uint16_t tmp; OFUDPSocket *sock; of_socket_address_t address; /* TODO: Properly try all search domains */ | > | 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 | recordType: (of_dns_resource_record_type_t)recordType target: (id)target selector: (SEL)selector context: (id)context { void *pool = objc_autoreleasePoolPush(); OFMutableData *data = [OFMutableData dataWithCapacity: 512]; OFTimer *timer; OFDNSResolver_context *DNSResolverContext; OFNumber *ID; uint16_t tmp; OFUDPSocket *sock; of_socket_address_t address; /* TODO: Properly try all search domains */ |
︙ | ︙ | |||
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 | count: 2]; /* QCLASS */ tmp = OF_BSWAP16_IF_LE(recordClass); [data addItems: &tmp count: 2]; DNSResolverContext = [[[OFDNSResolver_context alloc] initWithHost: host recordClass: recordClass recordType: recordType ID: ID nameServers: _nameServers searchDomains: _searchDomains queryData: data target: target selector: selector | > > > > > > > | > | 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 | count: 2]; /* QCLASS */ tmp = OF_BSWAP16_IF_LE(recordClass); [data addItems: &tmp count: 2]; timer = [OFTimer scheduledTimerWithTimeInterval: TIMEOUT target: self selector: @selector(of_queryWithIDTimedOut:) object: ID repeats: false]; DNSResolverContext = [[[OFDNSResolver_context alloc] initWithHost: host recordClass: recordClass recordType: recordType ID: ID nameServers: _nameServers searchDomains: _searchDomains queryData: data target: target selector: selector userContext: context timer: timer] autorelease]; [_queries setObject: DNSResolverContext forKey: ID]; address = of_socket_address_parse_ip( [[DNSResolverContext nameServers] firstObject], 53); #ifdef OF_HAVE_IPV6 |
︙ | ︙ |