⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngx_resolver.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 4 页
字号:
    ngx_log_error(r->log_level, r->log, 0, err);    return;}static voidngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,    ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, ngx_uint_t ans){    char                 *err;    u_char               *cname;    size_t                len;    uint32_t              hash;    in_addr_t             addr, *addrs;    ngx_str_t             name;    ngx_uint_t            qtype, qident, naddrs, a, i, n, start;    ngx_resolver_an_t    *an;    ngx_resolver_ctx_t   *ctx, *next;    ngx_resolver_node_t  *rn;    if (ngx_resolver_copy(r, &name, buf, &buf[12], &buf[last]) != NGX_OK) {        return;    }    ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name);    hash = ngx_crc32_short(name.data, name.len);    /* lock name mutex */    rn = ngx_resolver_lookup_name(r, &name, hash);    if (rn == NULL || rn->query == NULL) {        ngx_log_error(r->log_level, r->log, 0,                      "unexpected response for %V", &name);        goto failed;    }    qident = (rn->query[0] << 8) + rn->query[1];    if (ident != qident) {        ngx_log_error(r->log_level, r->log, 0,                      "wrong ident %ui response for %V, expect %ui",                      ident, &name, qident);        goto failed;    }    if (code == 0 && nan == 0) {        code = 3; /* NXDOMAIN */    }    if (code) {        next = rn->waiting;        rn->waiting = NULL;        ngx_queue_remove(&rn->queue);        ngx_rbtree_delete(&r->name_rbtree, &rn->node);        ngx_resolver_free_node(r, rn);        /* unlock name mutex */        while (next) {             ctx = next;             ctx->state = code;             next = ctx->next;             ctx->handler(ctx);        }        return;    }    i = ans;    naddrs = 0;    addr = 0;    addrs = NULL;    cname = NULL;    qtype = 0;    for (a = 0; a < nan; a++) {        start = i;        while (i < last) {            if (buf[i] & 0xc0) {                i += 2;                goto found;            }            if (buf[i] == 0) {                i++;                goto test_length;            }            i += 1 + buf[i];        }        goto short_response;    test_length:        if (i - start < 2) {            err = "invalid name in dns response";            goto invalid;        }    found:        if (i + sizeof(ngx_resolver_an_t) >= last) {            goto short_response;        }        an = (ngx_resolver_an_t *) &buf[i];        qtype = (an->type_hi << 8) + an->type_lo;        len = (an->len_hi << 8) + an->len_lo;        if (qtype == NGX_RESOLVE_A) {            i += sizeof(ngx_resolver_an_t);            if (i + len > last) {                goto short_response;            }            addr = htonl((buf[i] << 24) + (buf[i + 1] << 16)                         + (buf[i + 2] << 8) + (buf[i + 3]));            naddrs++;            i += len;        } else if (qtype == NGX_RESOLVE_CNAME) {            cname = &buf[i] + sizeof(ngx_resolver_an_t);            i += sizeof(ngx_resolver_an_t) + len;        } else if (qtype == NGX_RESOLVE_DNAME) {            i += sizeof(ngx_resolver_an_t) + len;        } else {            ngx_log_error(r->log_level, r->log, 0,                          "unexpected qtype %ui", qtype);        }    }    ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,                   "resolver naddrs:%ui cname:%p", naddrs, cname);    if (naddrs) {        if (naddrs == 1) {            rn->u.addr = addr;        } else {            addrs = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));            if (addrs == NULL) {                return;            }            n = 0;            i = ans;            for (a = 0; a < nan; a++) {                for ( ;; ) {                    if (buf[i] & 0xc0) {                        i += 2;                        goto ok;                    }                    if (buf[i] == 0) {                        i++;                        goto ok;                    }                    i += 1 + buf[i];                }            ok:                an = (ngx_resolver_an_t *) &buf[i];                qtype = (an->type_hi << 8) + an->type_lo;                len = (an->len_hi << 8) + an->len_lo;                i += sizeof(ngx_resolver_an_t);                if (qtype == NGX_RESOLVE_A) {                    addrs[n++] = htonl((buf[i] << 24) + (buf[i + 1] << 16)                                       + (buf[i + 2] << 8) + (buf[i + 3]));                    if (n == naddrs) {                        break;                    }                }                i += len;            }            rn->u.addrs = addrs;            addrs = ngx_resolver_dup(r, rn->u.addrs,                                     naddrs * sizeof(in_addr_t));            if (addrs == NULL) {                return;            }        }        rn->naddrs = (u_short) naddrs;        ngx_queue_remove(&rn->queue);        rn->valid = ngx_time() + r->valid;        rn->expire = ngx_time() + r->expire;        ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);        next = rn->waiting;        rn->waiting = NULL;        /* unlock name mutex */        while (next) {             ctx = next;             ctx->state = NGX_OK;             ctx->naddrs = naddrs;             ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs;             ctx->addr = addr;             next = ctx->next;             ctx->handler(ctx);        }        if (naddrs) {            ngx_resolver_free(r, addrs);        }        return;    } else if (cname) {        /* CNAME only */        if (ngx_resolver_copy(r, &name, buf, cname, &buf[last]) != NGX_OK) {            return;        }        ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,                       "resolver cname:\"%V\"", &name);        ngx_queue_remove(&rn->queue);        rn->cnlen = (u_short) name.len;        rn->u.cname = name.data;        rn->valid = ngx_time() + r->valid;        rn->expire = ngx_time() + r->expire;        ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);        ctx = rn->waiting;        rn->waiting = NULL;        if (ctx) {            ctx->name = name;            (void) ngx_resolve_name_locked(r, ctx);        }        return;    }    ngx_log_error(r->log_level, r->log, 0,               "no A or CNAME types in DNS responses, unknown query type: %ui",               qtype);    return;short_response:    err = "short dns response";invalid:    /* unlock name mutex */    ngx_log_error(r->log_level, r->log, 0, err);    return;failed:    /* unlock name mutex */    return;}static voidngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,    ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan){    char                 *err;    size_t                len;    in_addr_t             addr;    ngx_int_t             digit;    ngx_str_t             name;    ngx_uint_t            i, mask, qtype, qclass, qident;    ngx_resolver_an_t    *an;    ngx_resolver_ctx_t   *ctx, *next;    ngx_resolver_node_t  *rn;    if (ngx_resolver_copy(r, NULL, buf, &buf[12], &buf[n]) != NGX_OK) {        goto invalid_in_addr_arpa;    }    addr = 0;    i = 12;    for (mask = 0; mask < 32; mask += 8) {        len = buf[i++];        digit = ngx_atoi(&buf[i], len);        if (digit == NGX_ERROR || digit > 255) {            goto invalid_in_addr_arpa;        }        addr += digit << mask;        i += len;    }    if (ngx_strcmp(&buf[i], "\7in-addr\4arpa") != 0) {        goto invalid_in_addr_arpa;    }    /* lock addr mutex */    rn = ngx_resolver_lookup_addr(r, addr);    if (rn == NULL || rn->query == NULL) {        ngx_log_error(r->log_level, r->log, 0,                      "unexpected response for %ud.%ud.%ud.%ud",                      (addr >> 24) & 0xff, (addr >> 16) & 0xff,                      (addr >> 8) & 0xff, addr & 0xff);        goto failed;    }    qident = (rn->query[0] << 8) + rn->query[1];    if (ident != qident) {        ngx_log_error(r->log_level, r->log, 0,                    "wrong ident %ui response for %ud.%ud.%ud.%ud, expect %ui",                    ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff,                    (addr >> 8) & 0xff, addr & 0xff, qident);        goto failed;    }    if (code == 0 && nan == 0) {        code = 3; /* NXDOMAIN */    }    if (code) {        next = rn->waiting;        rn->waiting = NULL;        ngx_queue_remove(&rn->queue);        ngx_rbtree_delete(&r->addr_rbtree, &rn->node);        ngx_resolver_free_node(r, rn);        /* unlock addr mutex */        while (next) {             ctx = next;             ctx->state = code;             next = ctx->next;             ctx->handler(ctx);        }        return;    }    i += sizeof("\7in-addr\4arpa") + sizeof(ngx_resolver_qs_t);    if (i + 2 + sizeof(ngx_resolver_an_t) > (ngx_uint_t) n) {        goto short_response;    }    /* compression pointer to "XX.XX.XX.XX.in-addr.arpa */    if (buf[i] != 0xc0 || buf[i + 1] != 0x0c) {        err = "invalid in-addr.arpa name in DNS response";        goto invalid;    }    an = (ngx_resolver_an_t *) &buf[i + 2];    qtype = (an->type_hi << 8) + an->type_lo;    qclass = (an->class_hi << 8) + an->class_lo;    len = (an->len_hi << 8) + an->len_lo;    ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,                  "resolver qt:%ui cl:%ui len:%uz", qtype, qclass, len);    i += 2 + sizeof(ngx_resolver_an_t);    if (i + len > (ngx_uint_t) n) {        goto short_response;    }    len -= 2;    if (ngx_resolver_copy(r, &name, buf, &buf[i], &buf[n]) != NGX_OK) {        return;    }    ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver an:%V", &name);    if (len != (size_t) rn->nlen || ngx_strncmp(name.data, rn->name, len) != 0)    {        ngx_resolver_free(r, rn->name);        rn->name = name.data;        name.data = ngx_resolver_dup(r, rn->name, len);        if (name.data == NULL) {            goto failed;        }    }    ngx_queue_remove(&rn->queue);    rn->valid = ngx_time() + r->valid;    rn->expire = ngx_time() + r->expire;    ngx_queue_insert_head(&r->addr_expire_queue, &rn->queue);    next = rn->waiting;    rn->waiting = NULL;    /* unlock addr mutex */    while (next) {         ctx = next;         ctx->state = NGX_OK;         ctx->name = name;         next = ctx->next;         ctx->handler(ctx);    }    ngx_resolver_free(r, name.data);    return;invalid_in_addr_arpa:    ngx_log_error(r->log_level, r->log, 0,                  "invalid in-addr.arpa name in DNS response");    return;short_response:    err = "short DNS response";invalid:    /* unlock addr mutex */    ngx_log_error(r->log_level, r->log, 0, err);    return;failed:    /* unlock addr mutex */    return;}static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash){    ngx_int_t             rc;    size_t                len;    ngx_rbtree_node_t    *node, *sentinel;    ngx_resolver_node_t  *rn;    node = r->name_rbtree.root;    sentinel = r->name_rbtree.sentinel;    while (node != sentinel) {        if (hash < node->key) {            node = node->left;            continue;        }        if (hash > node->key) {            node = node->right;            continue;        }        /* hash == node->key */        do {            rn = (ngx_resolver_node_t *) node;            len = (name->len > (size_t) rn->nlen) ? rn->nlen : name->len;            rc = ngx_strncmp(name->data, rn->name, len);            if (rc == 0) {                return rn;            }            node = (rc < 0) ? node->left : node->right;        } while (node != sentinel && hash == node->key);        break;    }    /* not found */    return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -