comparison src/core/ngx_resolver.c @ 5475:07dd5bd222ac

Changed resolver API to use ngx_addr_t.
author Ruslan Ermilov <ru@nginx.com>
date Fri, 06 Dec 2013 14:30:27 +0400
parents b43b02bb54db
children 950c9ed3e66f
comparison
equal deleted inserted replaced
5474:b43b02bb54db 5475:07dd5bd222ac
86 static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size); 86 static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size);
87 static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size); 87 static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size);
88 static void ngx_resolver_free(ngx_resolver_t *r, void *p); 88 static void ngx_resolver_free(ngx_resolver_t *r, void *p);
89 static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p); 89 static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
90 static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size); 90 static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
91 static in_addr_t *ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, 91 static ngx_addr_t *ngx_resolver_export(ngx_resolver_t *r, in_addr_t *src,
92 ngx_uint_t n); 92 ngx_uint_t n, ngx_uint_t rotate);
93 static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len); 93 static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
94 94
95 95
96 ngx_resolver_t * 96 ngx_resolver_t *
97 ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) 97 ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
279 if (addr != INADDR_NONE) { 279 if (addr != INADDR_NONE) {
280 temp->resolver = r; 280 temp->resolver = r;
281 temp->state = NGX_OK; 281 temp->state = NGX_OK;
282 temp->naddrs = 1; 282 temp->naddrs = 1;
283 temp->addrs = &temp->addr; 283 temp->addrs = &temp->addr;
284 temp->addr = addr; 284 temp->addr.sockaddr = (struct sockaddr *) &temp->sin;
285 temp->addr.socklen = sizeof(struct sockaddr_in);
286 ngx_memzero(&temp->sin, sizeof(struct sockaddr_in));
287 temp->sin.sin_family = AF_INET;
288 temp->sin.sin_addr.s_addr = addr;
285 temp->quick = 1; 289 temp->quick = 1;
286 290
287 return temp; 291 return temp;
288 } 292 }
289 } 293 }
415 419
416 static ngx_int_t 420 static ngx_int_t
417 ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) 421 ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
418 { 422 {
419 uint32_t hash; 423 uint32_t hash;
420 in_addr_t addr, *addrs;
421 ngx_int_t rc; 424 ngx_int_t rc;
422 ngx_uint_t naddrs; 425 ngx_uint_t naddrs;
426 ngx_addr_t *addrs;
423 ngx_resolver_ctx_t *next; 427 ngx_resolver_ctx_t *next;
424 ngx_resolver_node_t *rn; 428 ngx_resolver_node_t *rn;
425 429
426 hash = ngx_crc32_short(ctx->name.data, ctx->name.len); 430 hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
427 431
443 447
444 if (naddrs) { 448 if (naddrs) {
445 449
446 /* NGX_RESOLVE_A answer */ 450 /* NGX_RESOLVE_A answer */
447 451
448 if (naddrs != 1) { 452 if (naddrs == 1) {
449 addr = 0; 453 addrs = NULL;
450 addrs = ngx_resolver_rotate(r, rn->u.addrs, naddrs); 454
455 } else {
456 addrs = ngx_resolver_export(r, rn->u.addrs, naddrs, 1);
451 if (addrs == NULL) { 457 if (addrs == NULL) {
452 return NGX_ERROR; 458 return NGX_ERROR;
453 } 459 }
454
455 } else {
456 addr = rn->u.addr;
457 addrs = NULL;
458 } 460 }
459 461
460 ctx->next = rn->waiting; 462 ctx->next = rn->waiting;
461 rn->waiting = NULL; 463 rn->waiting = NULL;
462 464
463 /* unlock name mutex */ 465 /* unlock name mutex */
464 466
465 do { 467 do {
466 ctx->state = NGX_OK; 468 ctx->state = NGX_OK;
467 ctx->naddrs = naddrs; 469 ctx->naddrs = naddrs;
468 ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs; 470
469 ctx->addr = addr; 471 if (addrs == NULL) {
472 ctx->addrs = &ctx->addr;
473 ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin;
474 ctx->addr.socklen = sizeof(struct sockaddr_in);
475 ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in));
476 ctx->sin.sin_family = AF_INET;
477 ctx->sin.sin_addr.s_addr = rn->u.addr;
478
479 } else {
480 ctx->addrs = addrs;
481 }
482
470 next = ctx->next; 483 next = ctx->next;
471 484
472 ctx->handler(ctx); 485 ctx->handler(ctx);
473 486
474 ctx = next; 487 ctx = next;
475 } while (ctx); 488 } while (ctx);
476 489
477 if (addrs) { 490 if (addrs != NULL) {
491 ngx_resolver_free(r, addrs->sockaddr);
478 ngx_resolver_free(r, addrs); 492 ngx_resolver_free(r, addrs);
479 } 493 }
480 494
481 return NGX_OK; 495 return NGX_OK;
482 } 496 }
624 638
625 return NGX_ERROR; 639 return NGX_ERROR;
626 } 640 }
627 641
628 642
643 /* AF_INET only */
644
629 ngx_int_t 645 ngx_int_t
630 ngx_resolve_addr(ngx_resolver_ctx_t *ctx) 646 ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
631 { 647 {
632 u_char *name; 648 u_char *name;
649 in_addr_t addr;
633 ngx_resolver_t *r; 650 ngx_resolver_t *r;
651 struct sockaddr_in *sin;
634 ngx_resolver_node_t *rn; 652 ngx_resolver_node_t *rn;
635 653
636 r = ctx->resolver; 654 r = ctx->resolver;
637 655
638 ctx->addr = ntohl(ctx->addr); 656 if (ctx->addr.sockaddr->sa_family != AF_INET) {
657 return NGX_ERROR;
658 }
659
660 sin = (struct sockaddr_in *) ctx->addr.sockaddr;
661 addr = ntohl(sin->sin_addr.s_addr);
639 662
640 /* lock addr mutex */ 663 /* lock addr mutex */
641 664
642 rn = ngx_resolver_lookup_addr(r, ctx->addr); 665 rn = ngx_resolver_lookup_addr(r, addr);
643 666
644 if (rn) { 667 if (rn) {
645 668
646 if (rn->valid >= ngx_time()) { 669 if (rn->valid >= ngx_time()) {
647 670
692 rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t)); 715 rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t));
693 if (rn == NULL) { 716 if (rn == NULL) {
694 goto failed; 717 goto failed;
695 } 718 }
696 719
697 rn->node.key = ctx->addr; 720 rn->node.key = addr;
698 rn->query = NULL; 721 rn->query = NULL;
699 722
700 ngx_rbtree_insert(&r->addr_rbtree, &rn->node); 723 ngx_rbtree_insert(&r->addr_rbtree, &rn->node);
701 } 724 }
702 725
763 786
764 return NGX_ERROR; 787 return NGX_ERROR;
765 } 788 }
766 789
767 790
791 /* AF_INET only */
792
768 void 793 void
769 ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx) 794 ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
770 { 795 {
771 in_addr_t addr; 796 in_addr_t addr;
772 ngx_resolver_t *r; 797 ngx_resolver_t *r;
773 ngx_resolver_ctx_t *w, **p; 798 ngx_resolver_ctx_t *w, **p;
799 struct sockaddr_in *sin;
774 ngx_resolver_node_t *rn; 800 ngx_resolver_node_t *rn;
801
802 if (ctx->addr.sockaddr->sa_family != AF_INET) {
803 return;
804 }
805
806 sin = (struct sockaddr_in *) ctx->addr.sockaddr;
807 addr = ntohl(sin->sin_addr.s_addr);
775 808
776 r = ctx->resolver; 809 r = ctx->resolver;
777 810
778 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, 811 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
779 "resolve addr done: %i", ctx->state); 812 "resolve addr done: %i", ctx->state);
784 817
785 /* lock addr mutex */ 818 /* lock addr mutex */
786 819
787 if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) { 820 if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
788 821
789 rn = ngx_resolver_lookup_addr(r, ctx->addr); 822 rn = ngx_resolver_lookup_addr(r, addr);
790 823
791 if (rn) { 824 if (rn) {
792 p = &rn->waiting; 825 p = &rn->waiting;
793 w = rn->waiting; 826 w = rn->waiting;
794 827
801 834
802 p = &w->next; 835 p = &w->next;
803 w = w->next; 836 w = w->next;
804 } 837 }
805 } 838 }
806
807 addr = ntohl(ctx->addr);
808 839
809 ngx_log_error(NGX_LOG_ALERT, r->log, 0, 840 ngx_log_error(NGX_LOG_ALERT, r->log, 0,
810 "could not cancel %ud.%ud.%ud.%ud resolving", 841 "could not cancel %ud.%ud.%ud.%ud resolving",
811 (addr >> 24) & 0xff, (addr >> 16) & 0xff, 842 (addr >> 24) & 0xff, (addr >> 16) & 0xff,
812 (addr >> 8) & 0xff, addr & 0xff); 843 (addr >> 8) & 0xff, addr & 0xff);
1175 char *err; 1206 char *err;
1176 u_char *cname; 1207 u_char *cname;
1177 size_t len; 1208 size_t len;
1178 int32_t ttl; 1209 int32_t ttl;
1179 uint32_t hash; 1210 uint32_t hash;
1180 in_addr_t addr, *addrs; 1211 in_addr_t *addr;
1181 ngx_str_t name; 1212 ngx_str_t name;
1213 ngx_addr_t *addrs;
1182 ngx_uint_t type, class, qident, naddrs, a, i, n, start; 1214 ngx_uint_t type, class, qident, naddrs, a, i, n, start;
1183 ngx_resolver_an_t *an; 1215 ngx_resolver_an_t *an;
1184 ngx_resolver_ctx_t *ctx, *next; 1216 ngx_resolver_ctx_t *ctx, *next;
1185 ngx_resolver_node_t *rn; 1217 ngx_resolver_node_t *rn;
1186 1218
1245 return; 1277 return;
1246 } 1278 }
1247 1279
1248 i = ans; 1280 i = ans;
1249 naddrs = 0; 1281 naddrs = 0;
1250 addr = 0;
1251 addrs = NULL;
1252 cname = NULL; 1282 cname = NULL;
1253 ttl = 0; 1283 ttl = 0;
1254 1284
1255 for (a = 0; a < nan; a++) { 1285 for (a = 0; a < nan; a++) {
1256 1286
1317 1347
1318 if (i + 4 > last) { 1348 if (i + 4 > last) {
1319 goto short_response; 1349 goto short_response;
1320 } 1350 }
1321 1351
1322 addr = htonl((buf[i] << 24) + (buf[i + 1] << 16)
1323 + (buf[i + 2] << 8) + (buf[i + 3]));
1324
1325 naddrs++; 1352 naddrs++;
1326 1353
1327 break; 1354 break;
1328 1355
1329 case NGX_RESOLVE_CNAME: 1356 case NGX_RESOLVE_CNAME:
1350 naddrs, cname, ttl); 1377 naddrs, cname, ttl);
1351 1378
1352 if (naddrs) { 1379 if (naddrs) {
1353 1380
1354 if (naddrs == 1) { 1381 if (naddrs == 1) {
1355 rn->u.addr = addr; 1382 addr = &rn->u.addr;
1383 rn->naddrs = 1;
1356 1384
1357 } else { 1385 } else {
1358 1386 addr = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));
1359 addrs = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t)); 1387 if (addr == NULL) {
1388 goto failed;
1389 }
1390
1391 rn->u.addrs = addr;
1392 rn->naddrs = (u_short) naddrs;
1393 }
1394
1395 n = 0;
1396 i = ans;
1397
1398 for (a = 0; a < nan; a++) {
1399
1400 for ( ;; ) {
1401
1402 if (buf[i] & 0xc0) {
1403 i += 2;
1404 break;
1405 }
1406
1407 if (buf[i] == 0) {
1408 i++;
1409 break;
1410 }
1411
1412 i += 1 + buf[i];
1413 }
1414
1415 an = (ngx_resolver_an_t *) &buf[i];
1416
1417 type = (an->type_hi << 8) + an->type_lo;
1418 len = (an->len_hi << 8) + an->len_lo;
1419
1420 i += sizeof(ngx_resolver_an_t);
1421
1422 if (type == NGX_RESOLVE_A) {
1423
1424 addr[n] = htonl((buf[i] << 24) + (buf[i + 1] << 16)
1425 + (buf[i + 2] << 8) + (buf[i + 3]));
1426
1427 if (++n == naddrs) {
1428 break;
1429 }
1430 }
1431
1432 i += len;
1433 }
1434
1435 if (naddrs == 1) {
1436 addrs = NULL;
1437
1438 } else {
1439 addrs = ngx_resolver_export(r, rn->u.addrs, naddrs, 0);
1360 if (addrs == NULL) { 1440 if (addrs == NULL) {
1361 goto failed; 1441 goto failed;
1362 } 1442 }
1363 1443 }
1364 n = 0;
1365 i = ans;
1366
1367 for (a = 0; a < nan; a++) {
1368
1369 for ( ;; ) {
1370
1371 if (buf[i] & 0xc0) {
1372 i += 2;
1373 break;
1374 }
1375
1376 if (buf[i] == 0) {
1377 i++;
1378 break;
1379 }
1380
1381 i += 1 + buf[i];
1382 }
1383
1384 an = (ngx_resolver_an_t *) &buf[i];
1385
1386 type = (an->type_hi << 8) + an->type_lo;
1387 len = (an->len_hi << 8) + an->len_lo;
1388
1389 i += sizeof(ngx_resolver_an_t);
1390
1391 if (type == NGX_RESOLVE_A) {
1392
1393 addrs[n++] = htonl((buf[i] << 24) + (buf[i + 1] << 16)
1394 + (buf[i + 2] << 8) + (buf[i + 3]));
1395
1396 if (n == naddrs) {
1397 break;
1398 }
1399 }
1400
1401 i += len;
1402 }
1403
1404 rn->u.addrs = addrs;
1405
1406 addrs = ngx_resolver_dup(r, rn->u.addrs,
1407 naddrs * sizeof(in_addr_t));
1408 if (addrs == NULL) {
1409 goto failed;
1410 }
1411 }
1412
1413 rn->naddrs = (u_short) naddrs;
1414 1444
1415 ngx_queue_remove(&rn->queue); 1445 ngx_queue_remove(&rn->queue);
1416 1446
1417 rn->valid = ngx_time() + (r->valid ? r->valid : ttl); 1447 rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
1418 rn->expire = ngx_time() + r->expire; 1448 rn->expire = ngx_time() + r->expire;
1426 1456
1427 while (next) { 1457 while (next) {
1428 ctx = next; 1458 ctx = next;
1429 ctx->state = NGX_OK; 1459 ctx->state = NGX_OK;
1430 ctx->naddrs = naddrs; 1460 ctx->naddrs = naddrs;
1431 ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs; 1461
1432 ctx->addr = addr; 1462 if (addrs == NULL) {
1463 ctx->addrs = &ctx->addr;
1464 ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin;
1465 ctx->addr.socklen = sizeof(struct sockaddr_in);
1466 ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in));
1467 ctx->sin.sin_family = AF_INET;
1468 ctx->sin.sin_addr.s_addr = rn->u.addr;
1469
1470 } else {
1471 ctx->addrs = addrs;
1472 }
1473
1433 next = ctx->next; 1474 next = ctx->next;
1434 1475
1435 ctx->handler(ctx); 1476 ctx->handler(ctx);
1436 } 1477 }
1437 1478
1438 if (naddrs > 1) { 1479 if (addrs != NULL) {
1480 ngx_resolver_free(r, addrs->sockaddr);
1439 ngx_resolver_free(r, addrs); 1481 ngx_resolver_free(r, addrs);
1440 } 1482 }
1441 1483
1442 ngx_resolver_free(r, rn->query); 1484 ngx_resolver_free(r, rn->query);
1443 rn->query = NULL; 1485 rn->query = NULL;
1916 static ngx_int_t 1958 static ngx_int_t
1917 ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx) 1959 ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
1918 { 1960 {
1919 u_char *p, *d; 1961 u_char *p, *d;
1920 size_t len; 1962 size_t len;
1963 in_addr_t addr;
1921 ngx_int_t n; 1964 ngx_int_t n;
1922 ngx_uint_t ident; 1965 ngx_uint_t ident;
1923 ngx_resolver_hdr_t *query; 1966 ngx_resolver_hdr_t *query;
1967 struct sockaddr_in *sin;
1968
1969 if (ctx->addr.sockaddr->sa_family != AF_INET) {
1970 return NGX_ERROR;
1971 }
1924 1972
1925 len = sizeof(ngx_resolver_hdr_t) 1973 len = sizeof(ngx_resolver_hdr_t)
1926 + sizeof(".255.255.255.255.in-addr.arpa.") - 1 1974 + sizeof(".255.255.255.255.in-addr.arpa.") - 1
1927 + sizeof(ngx_resolver_qs_t); 1975 + sizeof(ngx_resolver_qs_t);
1928 1976
1948 query->nns_hi = 0; query->nns_lo = 0; 1996 query->nns_hi = 0; query->nns_lo = 0;
1949 query->nar_hi = 0; query->nar_lo = 0; 1997 query->nar_hi = 0; query->nar_lo = 0;
1950 1998
1951 p += sizeof(ngx_resolver_hdr_t); 1999 p += sizeof(ngx_resolver_hdr_t);
1952 2000
2001 sin = (struct sockaddr_in *) ctx->addr.sockaddr;
2002 addr = ntohl(sin->sin_addr.s_addr);
2003
1953 for (n = 0; n < 32; n += 8) { 2004 for (n = 0; n < 32; n += 8) {
1954 d = ngx_sprintf(&p[1], "%ud", (ctx->addr >> n) & 0xff); 2005 d = ngx_sprintf(&p[1], "%ud", (addr >> n) & 0xff);
1955 *p = (u_char) (d - &p[1]); 2006 *p = (u_char) (d - &p[1]);
1956 p = d; 2007 p = d;
1957 } 2008 }
1958 2009
1959 /* query type "PTR", IN query class */ 2010 /* query type "PTR", IN query class */
2165 2216
2166 return dst; 2217 return dst;
2167 } 2218 }
2168 2219
2169 2220
2170 static in_addr_t * 2221 static ngx_addr_t *
2171 ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n) 2222 ngx_resolver_export(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n,
2172 { 2223 ngx_uint_t rotate)
2173 void *dst, *p; 2224 {
2174 ngx_uint_t j; 2225 ngx_addr_t *dst;
2175 2226 ngx_uint_t i, j;
2176 dst = ngx_resolver_alloc(r, n * sizeof(in_addr_t)); 2227 struct sockaddr_in *sin;
2177 2228
2229 dst = ngx_resolver_calloc(r, n * sizeof(ngx_addr_t));
2178 if (dst == NULL) { 2230 if (dst == NULL) {
2179 return dst; 2231 return NULL;
2180 } 2232 }
2181 2233
2182 j = ngx_random() % n; 2234 sin = ngx_resolver_calloc(r, n * sizeof(struct sockaddr_in));
2183 2235
2184 if (j == 0) { 2236 if (sin == NULL) {
2185 ngx_memcpy(dst, src, n * sizeof(in_addr_t)); 2237 ngx_resolver_free(r, dst);
2186 return dst; 2238 return NULL;
2187 } 2239 }
2188 2240
2189 p = ngx_cpymem(dst, &src[j], (n - j) * sizeof(in_addr_t)); 2241 j = rotate ? ngx_random() % n : 0;
2190 ngx_memcpy(p, src, j * sizeof(in_addr_t)); 2242
2243 for (i = 0; i < n; i++) {
2244 dst[i].sockaddr = (struct sockaddr *) &sin[i];
2245 dst[i].socklen = sizeof(struct sockaddr_in);
2246 sin[i].sin_family = AF_INET;
2247 sin[i].sin_addr.s_addr = src[j++];
2248
2249 if (j == n) {
2250 j = 0;
2251 }
2252 }
2191 2253
2192 return dst; 2254 return dst;
2193 } 2255 }
2194 2256
2195 2257