コード例 #1
0
ファイル: ixfr.c プロジェクト: corretgecom/mydns-ng
static uchar *
ixfr_gobble_authority_rr(TASK *t, uchar *query, size_t querylen, uchar *current, IARR *rr){
  uchar * src = current;
  int rdlength = 0;
  task_error_t errcode = TASK_FAILED;

  if (!(IARR_NAME(rr) = name_unencode2(query, querylen, &src, &errcode))) {
    formerr(t, DNS_RCODE_FORMERR, errcode, NULL);
    return NULL;
  }
  DNS_GET16(rr->type, src);
  DNS_GET16(rr->class, src);
  DNS_GET32(rr->ttl, src);

  DNS_GET16(rdlength, src);
  if (!(IARR_MNAME(rr) = name_unencode2(query, querylen, &src, &errcode))) {
    formerr(t, DNS_RCODE_FORMERR, errcode, NULL);
    return NULL;
  }

  if (!(IARR_RNAME(rr) = name_unencode2(query, querylen, &src, &errcode))) {
    formerr(t, DNS_RCODE_FORMERR, errcode, NULL);
    return NULL;
  }

  DNS_GET32(rr->serial, src);
  DNS_GET32(rr->refresh, src);
  DNS_GET32(rr->retry, src);
  DNS_GET32(rr->expire, src);
  DNS_GET32(rr->minimum, src);

  return src;
}
コード例 #2
0
ファイル: dns.c プロジェクト: chenbk85/dplus-c
int make_dns_query(char *buf, int query_len, time_t *ttl, int *Anum)
{
    struct sockaddr_in addr;
    int sockfd = -1;
    struct timeval timeout = { RETRANS_INTERVAL, 0 };
    int i, ret = -1;
    int addrlen, send_len, result_len;
    int try_num = 0;
    dns_head_type *dns_head;
#ifdef WIN32
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);
#endif

    addr.sin_family = AF_INET;
    //addr.sin_addr.s_addr = inet_addr(PUBLIC_DNS_DEFAULT_SERVER);
    inet_pton(AF_INET, PUBLIC_DNS_DEFAULT_SERVER, &(addr.sin_addr.s_addr));
    addr.sin_port = htons((uint16_t)PUBLIC_DNS_DEFAULT_PORT);
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == sockfd) {
        fprintf(stderr, "socket error\n");
        goto clear;
    }

    ret = wait_writable(sockfd, timeout);
    if (ret != 0) {
        fprintf(stderr, "wait writable timeout\n");
        goto clear;
    }
    while (try_num++ <= RETRANS_TRY_NUM) {
        send_len = sendto(sockfd, buf, query_len, 0, (struct sockaddr*)&addr, sizeof(struct sockaddr));
        if (send_len != query_len) {
            fprintf(stderr, "sendto dns query failed\n");
            ret = -1;
            goto clear;
        }
        ret = wait_readable(sockfd, timeout);
        if (ret == 0) {
            break;
        }
    }
    if (try_num > RETRANS_TRY_NUM) {
        fprintf(stderr, "dns query failed over try num\n");
        ret = -1;
        goto clear;
    }

    addrlen = sizeof(struct sockaddr);
    result_len = recvfrom(sockfd, buf, DNS_DEFAULT_DATA_SIZE, 0/*MSG_WAITALL*/,
        (struct sockaddr *)&addr, (socklen_t*)&addrlen);
    if (result_len <= 0) {
        fprintf(stderr, "receve dns response failed\n");
        ret = -1;
        goto clear;
    }

    //只支持A记录
    dns_head = (dns_head_type *)buf;
    int off = 0;
    int num = DNS_GET16(dns_head->numA);
    for (i = 0; i < num; i++) {
        char *result_set = buf + query_len + off;
        response *rp = (response *)(result_set + 2); //2 bytes' offsets
        uint16_t type = DNS_GET16(rp->type);
        *ttl = DNS_GET32(rp->ttl);
        //解析A记录
        if (TYPE_A == type) {
            memcpy(buf + (*Anum) * 4, (char *)(rp + 1), 4);
            (*Anum)++;
            off += (2 + sizeof(response) + 4);
        }
        else if (TYPE_CNAME == type) {
            //如果是CNAME记录则直接查找下一条记录
            off += (2 + sizeof(response) + DNS_GET16(rp->length));
        }
        else {
            //其他类型不支持
            goto clear;
        }
    }

    ret = 0;

clear:
    if (sockfd != -1) {
#ifdef WIN32
        closesocket(sockfd);
        WSACleanup();
#else
        close(sockfd);
#endif
    }

    return ret;
}