this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at fixPythonPipStalling 562 lines 16 kB view raw
1/* 2 * Copyright (c) 2004-2006, 2009, 2011-2013, 2015-2018 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <stdlib.h> 25#include <strings.h> 26#include <mach/mach.h> 27#include <mach/mach_time.h> 28#include <CommonCrypto/CommonDigest.h> 29#include <CoreFoundation/CoreFoundation.h> 30#include <SystemConfiguration/SystemConfiguration.h> 31#include <SystemConfiguration/SCPrivate.h> 32#include "SCNetworkReachabilityInternal.h" 33 34#include "dnsinfo_create.h" 35#include "dnsinfo_private.h" 36#include "network_state_information_priv.h" 37 38#include "ip_plugin.h" 39 40 41#define ROUNDUP(a, size) \ 42 (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) 43 44 45/* 46 * to avoid extra calls to realloc() we want to pre-allocate the initial 47 * resolver and configuration buffers of a sufficient size that they would 48 * not normally need to be expanded. 49 */ 50#define INITIAL_CONFIGURATION_BUF_SIZE 8192 51#define INITIAL_RESOLVER_BUF_SIZE 1024 52 53 54/* 55 * DNS [configuration] buffer functions 56 */ 57 58 59__private_extern__ 60dns_create_config_t 61_dns_configuration_create() 62{ 63 _dns_config_buf_t *config; 64 65 config = calloc(1, INITIAL_CONFIGURATION_BUF_SIZE); 66 config->config.version = DNSINFO_VERSION; 67 config->config.generation = mach_absolute_time(); 68// config->n_attribute = 0; 69// config->n_padding = 0; 70 return (dns_create_config_t)config; 71} 72 73 74static void 75config_add_attribute(dns_create_config_t *_config, 76 uint32_t attribute_type, 77 uint32_t attribute_length, 78 void *attribute, 79 uint32_t extra_padding) 80{ 81 _dns_config_buf_t *config = (_dns_config_buf_t *)*_config; 82 dns_attribute_t *header; 83 uint32_t newLen; 84 uint32_t newSize; 85 uint32_t oldLen; 86 uint32_t rounded_length; 87 88 // add space 89 90 oldLen = ntohl(config->n_attribute); 91 rounded_length = ROUNDUP(attribute_length, sizeof(uint32_t)); 92 newLen = sizeof(dns_attribute_t) + rounded_length; 93 newSize = sizeof(_dns_config_buf_t) + oldLen + newLen; 94 if (newSize > INITIAL_CONFIGURATION_BUF_SIZE) { 95 config = realloc(config, newSize); 96 } 97 config->n_attribute = htonl(ntohl(config->n_attribute) + newLen); 98 99 // increment additional padding that will be needed (later) 100 config->n_padding = htonl(ntohl(config->n_padding) + extra_padding); 101 102 // add attribute [header] 103 104 /* ALIGN: _dns_config_buf_t is int aligned */ 105 header = (dns_attribute_t *)(void *)&config->attribute[oldLen]; 106 header->type = htonl(attribute_type); 107 header->length = htonl(newLen); 108 109 // add attribute [data] 110 111 memcpy(&header->attribute[0], attribute, attribute_length); 112 for (uint32_t i = attribute_length; i < rounded_length; i++) { 113 header->attribute[i] = 0; 114 } 115 116 *_config = (dns_create_config_t)config; 117 return; 118} 119 120 121static void 122_dns_resolver_set_reach_flags(dns_create_resolver_t _resolver); 123 124 125__private_extern__ 126void 127_dns_configuration_add_resolver(dns_create_config_t *_config, 128 dns_create_resolver_t _resolver) 129{ 130 _dns_config_buf_t *config = (_dns_config_buf_t *)*_config; 131 uint32_t padding = 0; 132 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)_resolver; 133 134 /* 135 * add reachability flags for this resovler configuration 136 */ 137 _dns_resolver_set_reach_flags(_resolver); 138 139 /* 140 * compute the amount of space that will be needed for 141 * pointers to the resolver, the nameservers, the search 142 * list, and the sortaddr list. 143 */ 144 padding += sizeof(DNS_PTR(dns_resolver_t *, x)); 145 if (resolver->resolver.n_nameserver != 0) { 146 padding += ntohl(resolver->resolver.n_nameserver) * sizeof(DNS_PTR(struct sockaddr *, x)); 147 } 148 if (resolver->resolver.n_search != 0) { 149 padding += ntohl(resolver->resolver.n_search) * sizeof(DNS_PTR(char *, x)); 150 } 151 if (resolver->resolver.n_sortaddr != 0) { 152 padding += ntohl(resolver->resolver.n_sortaddr) * sizeof(DNS_PTR(dns_sortaddr_t *, x)); 153 } 154 155 if ((ntohl(resolver->resolver.flags) & DNS_RESOLVER_FLAGS_SCOPED)) { 156 config->config.n_scoped_resolver = htonl(ntohl(config->config.n_scoped_resolver) + 1); 157 config_add_attribute(_config, 158 CONFIG_ATTRIBUTE_SCOPED_RESOLVER, 159 sizeof(_dns_resolver_buf_t) + ntohl(resolver->n_attribute), 160 (void *)resolver, 161 padding); 162 } else if ((ntohl(resolver->resolver.flags) & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC)) { 163 config->config.n_service_specific_resolver = htonl(ntohl(config->config.n_service_specific_resolver) + 1); 164 config_add_attribute(_config, 165 CONFIG_ATTRIBUTE_SERVICE_SPECIFIC_RESOLVER, 166 sizeof(_dns_resolver_buf_t) + ntohl(resolver->n_attribute), 167 (void *)resolver, 168 padding); 169 } else { 170 config->config.n_resolver = htonl(ntohl(config->config.n_resolver) + 1); 171 config_add_attribute(_config, 172 CONFIG_ATTRIBUTE_RESOLVER, 173 sizeof(_dns_resolver_buf_t) + ntohl(resolver->n_attribute), 174 (void *)resolver, 175 padding); 176 } 177 178 return; 179} 180 181 182__private_extern__ 183void 184_dns_configuration_signature(dns_create_config_t *_config, 185 unsigned char *signature, 186 size_t signature_len) 187{ 188 memset(signature, 0, signature_len); 189 190 if (_config != NULL) { 191 _dns_config_buf_t *config = (_dns_config_buf_t *)*_config; 192 193 if (config != NULL) { 194 CC_SHA256_CTX ctx; 195 uint64_t generation_save; 196 unsigned char *sha256; 197 unsigned char sha256_buf[CC_SHA256_DIGEST_LENGTH]; 198 199 generation_save = config->config.generation; 200 config->config.generation = 0; 201 202 sha256 = (signature_len >= CC_SHA256_DIGEST_LENGTH) ? signature : sha256_buf; 203 CC_SHA256_Init(&ctx); 204 CC_SHA256_Update(&ctx, 205 config, 206 sizeof(_dns_config_buf_t) + ntohl(config->n_attribute)); 207 CC_SHA256_Final(sha256, &ctx); 208 if (sha256 != signature) { 209 memcpy(signature, sha256, signature_len); 210 } 211 212 config->config.generation = generation_save; 213 } 214 } 215 216 return; 217} 218 219 220__private_extern__ 221void 222_dns_configuration_free(dns_create_config_t *_config) 223{ 224 _dns_config_buf_t *config = (_dns_config_buf_t *)*_config; 225 226 free(config); 227 *_config = NULL; 228 return; 229} 230 231 232/* 233 * DNS resolver configuration functions 234 */ 235 236__private_extern__ 237dns_create_resolver_t 238_dns_resolver_create() 239{ 240 _dns_resolver_buf_t *buf; 241 242 buf = calloc(1, INITIAL_RESOLVER_BUF_SIZE); 243// buf->n_attribute = 0; 244 return (dns_create_resolver_t)buf; 245} 246 247 248static void 249_dns_resolver_add_attribute(dns_create_resolver_t *_resolver, 250 uint32_t attribute_type, 251 uint32_t attribute_length, 252 void *attribute) 253{ 254 dns_attribute_t *header; 255 uint32_t newLen; 256 uint32_t newSize; 257 uint32_t oldLen; 258 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 259 uint32_t rounded_length; 260 261 // add space 262 263 oldLen = ntohl(resolver->n_attribute); 264 rounded_length = ROUNDUP(attribute_length, sizeof(uint32_t)); 265 newLen = sizeof(dns_attribute_t) + rounded_length; 266 newSize = sizeof(_dns_resolver_buf_t) + oldLen + newLen; 267 if (newSize > INITIAL_RESOLVER_BUF_SIZE) { 268 resolver = realloc(resolver, newSize); 269 } 270 resolver->n_attribute = htonl(ntohl(resolver->n_attribute) + newLen); 271 272 // add attribute [header] 273 274 /* ALIGN: _dns_resolver_buf_t is int aligned */ 275 header = (dns_attribute_t *)(void *)&resolver->attribute[oldLen]; 276 header->type = htonl(attribute_type); 277 header->length = htonl(newLen); 278 279 // add attribute [data] 280 281 memcpy(&header->attribute[0], attribute, attribute_length); 282 for (uint32_t i = attribute_length; i < rounded_length; i++) { 283 header->attribute[i] = 0; 284 } 285 286 *_resolver = (dns_create_resolver_t)resolver; 287 return; 288} 289 290 291__private_extern__ 292void 293_dns_resolver_add_nameserver(dns_create_resolver_t *_resolver, struct sockaddr *nameserver) 294{ 295 uint32_t new_flags = 0; 296 uint32_t old_flags; 297 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 298 299 old_flags = ntohl(resolver->resolver.flags); 300 301 switch (nameserver->sa_family) { 302 case AF_INET: 303 if (ntohl(((struct sockaddr_in*)(void *)nameserver)->sin_addr.s_addr) == INADDR_LOOPBACK) { 304 new_flags = DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS; 305 } 306 break; 307 case AF_INET6: 308 if (IN6_IS_ADDR_LOOPBACK(&((struct sockaddr_in6 *)(void *)nameserver)->sin6_addr)){ 309 new_flags = DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS; 310 } 311 break; 312 default: 313 break; 314 } 315 316 resolver->resolver.n_nameserver = htonl(ntohl(resolver->resolver.n_nameserver) + 1); 317 _dns_resolver_add_attribute(_resolver, RESOLVER_ATTRIBUTE_ADDRESS, nameserver->sa_len, (void *)nameserver); 318 319 if (new_flags != 0) { 320 // if DNS request flags not explicitly set and we are 321 // adding a LOOPBACK resolver address 322 _dns_resolver_set_flags(_resolver, old_flags | new_flags); 323 } 324 return; 325} 326 327 328__private_extern__ 329void 330_dns_resolver_add_search(dns_create_resolver_t *_resolver, const char *search) 331{ 332 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 333 334 resolver->resolver.n_search = htonl(ntohl(resolver->resolver.n_search) + 1); 335 _dns_resolver_add_attribute(_resolver, RESOLVER_ATTRIBUTE_SEARCH, (uint32_t)strlen(search) + 1, (void *)search); 336 return; 337} 338 339 340__private_extern__ 341void 342_dns_resolver_add_sortaddr(dns_create_resolver_t *_resolver, dns_sortaddr_t *sortaddr) 343{ 344 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 345 346 resolver->resolver.n_sortaddr = htonl(ntohl(resolver->resolver.n_sortaddr) + 1); 347 _dns_resolver_add_attribute(_resolver, RESOLVER_ATTRIBUTE_SORTADDR, (uint32_t)sizeof(dns_sortaddr_t), (void *)sortaddr); 348 return; 349} 350 351 352__private_extern__ 353void 354_dns_resolver_set_configuration_identifier(dns_create_resolver_t *_resolver, const char *cid) 355{ 356 _dns_resolver_add_attribute(_resolver, RESOLVER_ATTRIBUTE_CONFIGURATION_ID, (uint32_t)strlen(cid) + 1, (void *)cid); 357 return; 358} 359 360 361__private_extern__ 362void 363_dns_resolver_set_domain(dns_create_resolver_t *_resolver, const char *domain) 364{ 365 _dns_resolver_add_attribute(_resolver, RESOLVER_ATTRIBUTE_DOMAIN, (uint32_t)strlen(domain) + 1, (void *)domain); 366 return; 367} 368 369 370__private_extern__ 371void 372_dns_resolver_set_flags(dns_create_resolver_t *_resolver, uint32_t flags) 373{ 374 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 375 376 resolver->resolver.flags = htonl(flags); 377 return; 378} 379 380 381__private_extern__ 382void 383_dns_resolver_set_if_index(dns_create_resolver_t *_resolver, 384 uint32_t if_index, 385 const char *if_name) 386{ 387 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 388 389 resolver->resolver.if_index = htonl(if_index); 390 if (if_name != NULL) { 391 _dns_resolver_add_attribute(_resolver, RESOLVER_ATTRIBUTE_INTERFACE_NAME, (uint32_t)strlen(if_name), (void *)if_name); 392 } 393 return; 394} 395 396 397__private_extern__ 398void 399_dns_resolver_set_options(dns_create_resolver_t *_resolver, const char *options) 400{ 401 _dns_resolver_add_attribute(_resolver, RESOLVER_ATTRIBUTE_OPTIONS, (uint32_t)strlen(options) + 1, (void *)options); 402 return; 403} 404 405 406__private_extern__ 407void 408_dns_resolver_set_order(dns_create_resolver_t *_resolver, uint32_t order) 409{ 410 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 411 412 resolver->resolver.search_order = htonl(order); 413 return; 414} 415 416 417__private_extern__ 418void 419_dns_resolver_set_port(dns_create_resolver_t *_resolver, uint16_t port) 420{ 421 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 422 423 resolver->resolver.port = htons(port); 424 return; 425} 426 427 428static void 429_dns_resolver_set_reach_flags(dns_create_resolver_t _resolver) 430{ 431 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)_resolver; 432 433 if (resolver->resolver.n_nameserver != 0) { 434 dns_attribute_t *attribute; 435 SCNetworkReachabilityFlags flags = kSCNetworkReachabilityFlagsReachable; 436 uint32_t n_attribute; 437 uint32_t n_nameserver = 0; 438 CFMutableDictionaryRef targetOptions; 439 440 targetOptions = CFDictionaryCreateMutable(NULL, 441 0, 442 &kCFTypeDictionaryKeyCallBacks, 443 &kCFTypeDictionaryValueCallBacks); 444 CFDictionarySetValue(targetOptions, 445 kSCNetworkReachabilityOptionServerBypass, 446 kCFBooleanTrue); 447 if (resolver->resolver.if_index != 0) { 448 char if_name[IFNAMSIZ]; 449 450 if (if_indextoname(ntohl(resolver->resolver.if_index), if_name) != NULL) { 451 CFStringRef targetInterface; 452 453 targetInterface = CFStringCreateWithCString(NULL, 454 if_name, 455 kCFStringEncodingASCII); 456 CFDictionarySetValue(targetOptions, 457 kSCNetworkReachabilityOptionInterface, 458 targetInterface); 459 CFRelease(targetInterface); 460 } 461 } 462 463 attribute = (dns_attribute_t *)(void *)&resolver->attribute[0]; 464 n_attribute = ntohl(resolver->n_attribute); 465 466 while (n_attribute >= sizeof(dns_attribute_t)) { 467 uint32_t attribute_length = ntohl(attribute->length); 468 uint32_t attribute_type = ntohl(attribute->type); 469 470 if (attribute_type == RESOLVER_ATTRIBUTE_ADDRESS) { 471 struct sockaddr *addr; 472 CFDataRef addrData; 473 SCNetworkReachabilityFlags ns_flags; 474 Boolean ok; 475 SCNetworkReachabilityRef target; 476 477 addr = (struct sockaddr *)&attribute->attribute[0]; 478 addrData = CFDataCreate(NULL, (const UInt8 *)addr, addr->sa_len); 479 CFDictionarySetValue(targetOptions, 480 kSCNetworkReachabilityOptionRemoteAddress, 481 addrData); 482 CFRelease(addrData); 483 484 target = SCNetworkReachabilityCreateWithOptions(NULL, targetOptions); 485 if (target == NULL) { 486 CFDictionaryRemoveValue(targetOptions, kSCNetworkReachabilityOptionInterface); 487 target = SCNetworkReachabilityCreateWithOptions(NULL, targetOptions); 488 if (target != NULL) { 489 // if interface name not (no longer) valid 490 CFRelease(target); 491 flags = 0; 492 break; 493 } 494 495 // address not valid? 496 my_log(LOG_ERR, 497 "_dns_resolver_set_reach_flags SCNetworkReachabilityCreateWithOptions() failed:\n options = %@", 498 targetOptions); 499 break; 500 } 501 502 ok = SCNetworkReachabilityGetFlags(target, &ns_flags); 503 CFRelease(target); 504 if (!ok) { 505 break; 506 } 507 508 if ((n_nameserver++ == 0) || 509 (__SCNetworkReachabilityRank(ns_flags) > __SCNetworkReachabilityRank(flags))) { 510 /* return the first (and later, best case) result */ 511 flags = ns_flags; 512 if (__SCNetworkReachabilityRank(flags) == ReachabilityRankReachable) { 513 // Can't get any better than REACHABLE 514 break; 515 } 516 } 517 } 518 519 attribute = (dns_attribute_t *)((void *)attribute + attribute_length); 520 n_attribute -= attribute_length; 521 } 522 523 CFRelease(targetOptions); 524 525 resolver->resolver.reach_flags = htonl(flags); 526 } 527 528 return; 529} 530 531 532__private_extern__ 533void 534_dns_resolver_set_timeout(dns_create_resolver_t *_resolver, uint32_t timeout) 535{ 536 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 537 538 resolver->resolver.timeout = htonl(timeout); 539 return; 540} 541 542 543__private_extern__ 544void 545_dns_resolver_set_service_identifier(dns_create_resolver_t *_resolver, uint32_t service_identifier) 546{ 547 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 548 549 resolver->resolver.service_identifier = htonl(service_identifier); 550} 551 552 553__private_extern__ 554void 555_dns_resolver_free(dns_create_resolver_t *_resolver) 556{ 557 _dns_resolver_buf_t *resolver = (_dns_resolver_buf_t *)*_resolver; 558 559 free(resolver); 560 *_resolver = NULL; 561 return; 562}