comparison src/core/ngx_resolver.c @ 372:6639b93e81b2 NGINX_0_6_30

nginx 0.6.30 *) Change: now if an "include" directive pattern does not match any file, then nginx does not issue an error. *) Feature: now the time in directives may be specified without spaces, for example, "1h50m". *) Bugfix: memory leaks if the "ssl_verify_client" directive was on. Thanks to Chavelle Vincent. *) Bugfix: the "sub_filter" directive might set text to change into output. *) Bugfix: the "error_page" directive did not take into account arguments in redirected URI. *) Bugfix: now nginx always opens files in binary mode under Cygwin. *) Bugfix: nginx could not be built on OpenBSD; bug appeared in 0.6.15.
author Igor Sysoev <http://sysoev.ru>
date Tue, 29 Apr 2008 00:00:00 +0400
parents babd3d9efb62
children edf1cb6c328e
comparison
equal deleted inserted replaced
371:b6a2a305fdad 372:6639b93e81b2
367 static ngx_int_t 367 static ngx_int_t
368 ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) 368 ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
369 { 369 {
370 uint32_t hash; 370 uint32_t hash;
371 in_addr_t addr, *addrs; 371 in_addr_t addr, *addrs;
372 ngx_int_t rc;
372 ngx_uint_t naddrs; 373 ngx_uint_t naddrs;
373 ngx_resolver_ctx_t *next; 374 ngx_resolver_ctx_t *next;
374 ngx_resolver_node_t *rn; 375 ngx_resolver_node_t *rn;
375 376
376 hash = ngx_crc32_short(ctx->name.data, ctx->name.len); 377 hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
432 return NGX_OK; 433 return NGX_OK;
433 } 434 }
434 435
435 /* NGX_RESOLVE_CNAME */ 436 /* NGX_RESOLVE_CNAME */
436 437
437 ctx->name.len = rn->cnlen; 438 if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
438 ctx->name.data = rn->u.cname; 439
439 440 ctx->name.len = rn->cnlen;
440 return ngx_resolve_name_locked(r, ctx); 441 ctx->name.data = rn->u.cname;
442
443 return ngx_resolve_name_locked(r, ctx);
444 }
445
446 ctx->next = rn->waiting;
447 rn->waiting = NULL;
448
449 /* unlock name mutex */
450
451 do {
452 ctx->state = NGX_RESOLVE_NXDOMAIN;
453 next = ctx->next;
454
455 ctx->handler(ctx);
456
457 ctx = next;
458 } while (ctx);
459
460 return NGX_OK;
441 } 461 }
442 462
443 if (rn->waiting) { 463 if (rn->waiting) {
444 464
445 ctx->next = rn->waiting; 465 ctx->next = rn->waiting;
451 ngx_queue_remove(&rn->queue); 471 ngx_queue_remove(&rn->queue);
452 472
453 /* lock alloc mutex */ 473 /* lock alloc mutex */
454 474
455 ngx_resolver_free_locked(r, rn->query); 475 ngx_resolver_free_locked(r, rn->query);
476 rn->query = NULL;
456 477
457 if (rn->cnlen) { 478 if (rn->cnlen) {
458 ngx_resolver_free_locked(r, rn->u.cname); 479 ngx_resolver_free_locked(r, rn->u.cname);
459 } 480 }
460 481
477 return NGX_ERROR; 498 return NGX_ERROR;
478 } 499 }
479 500
480 rn->node.key = hash; 501 rn->node.key = hash;
481 rn->nlen = (u_short) ctx->name.len; 502 rn->nlen = (u_short) ctx->name.len;
503 rn->query = NULL;
482 504
483 ngx_rbtree_insert(&r->name_rbtree, &rn->node); 505 ngx_rbtree_insert(&r->name_rbtree, &rn->node);
484 } 506 }
485 507
486 if (ngx_resolver_create_name_query(rn, ctx) != NGX_OK) { 508 rc = ngx_resolver_create_name_query(rn, ctx);
509
510 if (rc == NGX_ERROR) {
487 goto failed; 511 goto failed;
512 }
513
514 if (rc == NGX_DECLINED) {
515 ngx_rbtree_delete(&r->name_rbtree, &rn->node);
516
517 ngx_resolver_free(r, rn->query);
518 ngx_resolver_free(r, rn->name);
519 ngx_resolver_free(r, rn);
520
521 ctx->state = NGX_RESOLVE_NXDOMAIN;
522 ctx->handler(ctx);
523
524 return NGX_OK;
488 } 525 }
489 526
490 if (ngx_resolver_send_query(r, rn) != NGX_OK) { 527 if (ngx_resolver_send_query(r, rn) != NGX_OK) {
491 goto failed; 528 goto failed;
492 } 529 }
523 return NGX_AGAIN; 560 return NGX_AGAIN;
524 561
525 failed: 562 failed:
526 563
527 ngx_rbtree_delete(&r->name_rbtree, &rn->node); 564 ngx_rbtree_delete(&r->name_rbtree, &rn->node);
565
566 if (rn->query) {
567 ngx_resolver_free(r, rn->query);
568 }
528 569
529 ngx_resolver_free(r, rn->name); 570 ngx_resolver_free(r, rn->name);
530 571
531 ngx_resolver_free(r, rn); 572 ngx_resolver_free(r, rn);
532 573
586 } 627 }
587 628
588 ngx_queue_remove(&rn->queue); 629 ngx_queue_remove(&rn->queue);
589 630
590 ngx_resolver_free(r, rn->query); 631 ngx_resolver_free(r, rn->query);
632 rn->query = NULL;
591 633
592 } else { 634 } else {
593 rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t)); 635 rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t));
594 if (rn == NULL) { 636 if (rn == NULL) {
595 goto failed; 637 goto failed;
596 } 638 }
597 639
598 rn->node.key = ctx->addr; 640 rn->node.key = ctx->addr;
641 rn->query = NULL;
599 642
600 ngx_rbtree_insert(&r->addr_rbtree, &rn->node); 643 ngx_rbtree_insert(&r->addr_rbtree, &rn->node);
601 } 644 }
602 645
603 if (ngx_resolver_create_addr_query(rn, ctx) != NGX_OK) { 646 if (ngx_resolver_create_addr_query(rn, ctx) != NGX_OK) {
644 failed: 687 failed:
645 688
646 if (rn) { 689 if (rn) {
647 ngx_rbtree_delete(&r->addr_rbtree, &rn->node); 690 ngx_rbtree_delete(&r->addr_rbtree, &rn->node);
648 691
692 if (rn->query) {
693 ngx_resolver_free(r, rn->query);
694 }
695
649 ngx_resolver_free(r, rn); 696 ngx_resolver_free(r, rn);
650 } 697 }
651 698
652 /* unlock addr mutex */ 699 /* unlock addr mutex */
653 700
923 flags = (query->flags_hi << 8) + query->flags_lo; 970 flags = (query->flags_hi << 8) + query->flags_lo;
924 nqs = (query->nqs_hi << 8) + query->nqs_lo; 971 nqs = (query->nqs_hi << 8) + query->nqs_lo;
925 nan = (query->nan_hi << 8) + query->nan_lo; 972 nan = (query->nan_hi << 8) + query->nan_lo;
926 973
927 ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0, 974 ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0,
928 "resolver DNS response %d fl:%04Xud %d/%d/%d/%d", 975 "resolver DNS response %ui fl:%04Xui %ui/%ui/%ui/%ui",
929 ident, flags, nqs, nan, 976 ident, flags, nqs, nan,
930 (query->nns_hi << 8) + query->nns_lo, 977 (query->nns_hi << 8) + query->nns_lo,
931 (query->nar_hi << 8) + query->nar_lo); 978 (query->nar_hi << 8) + query->nar_lo);
932 979
933 if (!(flags & 0x8000)) { 980 if (!(flags & 0x8000)) {
934 ngx_log_error(r->log_level, r->log, 0, 981 ngx_log_error(r->log_level, r->log, 0,
935 "invalid DNS response %d fl:%04Xud", ident, flags); 982 "invalid DNS response %ui fl:%04Xui", ident, flags);
936 return; 983 return;
937 } 984 }
938 985
939 code = flags & 0x7f; 986 code = flags & 0x7f;
940 987
941 if (code == NGX_RESOLVE_FORMERR || code > NGX_RESOLVE_REFUSED) { 988 if (code == NGX_RESOLVE_FORMERR || code > NGX_RESOLVE_REFUSED) {
942 ngx_log_error(r->log_level, r->log, 0, 989 ngx_log_error(r->log_level, r->log, 0,
943 "DNS error (%d: %s), query id:%d", 990 "DNS error (%ui: %s), query id:%ui",
944 code, ngx_resolver_strerror(code), ident); 991 code, ngx_resolver_strerror(code), ident);
945 return; 992 return;
946 } 993 }
947 994
948 if (nqs != 1) { 995 if (nqs != 1) {
980 1027
981 qtype = (qs->type_hi << 8) + qs->type_lo; 1028 qtype = (qs->type_hi << 8) + qs->type_lo;
982 qclass = (qs->class_hi << 8) + qs->class_lo; 1029 qclass = (qs->class_hi << 8) + qs->class_lo;
983 1030
984 ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, 1031 ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
985 "resolver DNS response qt:%d cl:%d", qtype, qclass); 1032 "resolver DNS response qt:%ui cl:%ui", qtype, qclass);
986 1033
987 if (qclass != 1) { 1034 if (qclass != 1) {
988 ngx_log_error(r->log_level, r->log, 0, 1035 ngx_log_error(r->log_level, r->log, 0,
989 "unknown query class %d in DNS response", qclass); 1036 "unknown query class %ui in DNS response", qclass);
990 return; 1037 return;
991 } 1038 }
992 1039
993 switch (qtype) { 1040 switch (qtype) {
994 1041
1005 1052
1006 break; 1053 break;
1007 1054
1008 default: 1055 default:
1009 ngx_log_error(r->log_level, r->log, 0, 1056 ngx_log_error(r->log_level, r->log, 0,
1010 "unknown query type %d in DNS response", qtype); 1057 "unknown query type %ui in DNS response", qtype);
1011 return; 1058 return;
1012 } 1059 }
1013 1060
1014 return; 1061 return;
1015 1062
1060 1107
1061 qident = (rn->query[0] << 8) + rn->query[1]; 1108 qident = (rn->query[0] << 8) + rn->query[1];
1062 1109
1063 if (ident != qident) { 1110 if (ident != qident) {
1064 ngx_log_error(r->log_level, r->log, 0, 1111 ngx_log_error(r->log_level, r->log, 0,
1065 "wrong ident %d response for %V, expect %d", 1112 "wrong ident %ui response for %V, expect %ui",
1066 ident, &name, qident); 1113 ident, &name, qident);
1067 goto failed; 1114 goto failed;
1068 } 1115 }
1069 1116
1070 if (code == 0 && nan == 0) { 1117 if (code == 0 && nan == 0) {
1156 i += len; 1203 i += len;
1157 1204
1158 } else if (qtype == NGX_RESOLVE_CNAME) { 1205 } else if (qtype == NGX_RESOLVE_CNAME) {
1159 cname = &buf[i] + sizeof(ngx_resolver_an_t); 1206 cname = &buf[i] + sizeof(ngx_resolver_an_t);
1160 i += sizeof(ngx_resolver_an_t) + len; 1207 i += sizeof(ngx_resolver_an_t) + len;
1208
1209 } else if (qtype == NGX_RESOLVE_DNAME) {
1210 i += sizeof(ngx_resolver_an_t) + len;
1211
1212 } else {
1213 ngx_log_error(r->log_level, r->log, 0,
1214 "unexpected qtype %ui", qtype);
1161 } 1215 }
1162 } 1216 }
1163 1217
1164 ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, 1218 ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
1165 "resolver naddrs:%ui cname:%p", naddrs, cname); 1219 "resolver naddrs:%ui cname:%p", naddrs, cname);
1289 1343
1290 return; 1344 return;
1291 } 1345 }
1292 1346
1293 ngx_log_error(r->log_level, r->log, 0, 1347 ngx_log_error(r->log_level, r->log, 0,
1294 "no A or CNAME types in DNS responses, unknown query type: %d", 1348 "no A or CNAME types in DNS responses, unknown query type: %ui",
1295 qtype); 1349 qtype);
1296 return; 1350 return;
1297 1351
1298 short_response: 1352 short_response:
1299 1353
1300 err = "short dns response"; 1354 err = "short dns response";
1366 1420
1367 qident = (rn->query[0] << 8) + rn->query[1]; 1421 qident = (rn->query[0] << 8) + rn->query[1];
1368 1422
1369 if (ident != qident) { 1423 if (ident != qident) {
1370 ngx_log_error(r->log_level, r->log, 0, 1424 ngx_log_error(r->log_level, r->log, 0,
1371 "wrong ident %d response for %ud.%ud.%ud.%ud, expect %d", 1425 "wrong ident %ui response for %ud.%ud.%ud.%ud, expect %ui",
1372 ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff, 1426 ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff,
1373 (addr >> 8) & 0xff, addr & 0xff, qident); 1427 (addr >> 8) & 0xff, addr & 0xff, qident);
1374 goto failed; 1428 goto failed;
1375 } 1429 }
1376 1430
1377 if (code == 0 && nan == 0) { 1431 if (code == 0 && nan == 0) {
1378 code = 3; /* NXDOMAIN */ 1432 code = 3; /* NXDOMAIN */
1419 qtype = (an->type_hi << 8) + an->type_lo; 1473 qtype = (an->type_hi << 8) + an->type_lo;
1420 qclass = (an->class_hi << 8) + an->class_lo; 1474 qclass = (an->class_hi << 8) + an->class_lo;
1421 len = (an->len_hi << 8) + an->len_lo; 1475 len = (an->len_hi << 8) + an->len_lo;
1422 1476
1423 ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, 1477 ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
1424 "resolver qt:%d cl:%d len:%uz", qtype, qclass, len); 1478 "resolver qt:%ui cl:%ui len:%uz", qtype, qclass, len);
1425 1479
1426 i += 2 + sizeof(ngx_resolver_an_t); 1480 i += 2 + sizeof(ngx_resolver_an_t);
1427 1481
1428 if (i + len > (ngx_uint_t) n) { 1482 if (i + len > (ngx_uint_t) n) {
1429 goto short_response; 1483 goto short_response;
1682 if (*s != '.') { 1736 if (*s != '.') {
1683 *p = *s; 1737 *p = *s;
1684 len++; 1738 len++;
1685 1739
1686 } else { 1740 } else {
1741 if (len == 0) {
1742 return NGX_DECLINED;
1743 }
1744
1687 *p = (u_char) len; 1745 *p = (u_char) len;
1688 len = 0; 1746 len = 0;
1689 } 1747 }
1690 1748
1691 p--; 1749 p--;