Exemple #1
0
static int should_filter_query(ns_msg msg, struct in_addr dns_addr) {
    ns_rr rr;
    int rrnum, rrmax;
    void *r;
    // TODO cache result for each dns server
    int dns_is_chn = chnroute_file && (dns_servers_len > 1) &&
                     test_ip_in_list(dns_addr, &chnroute_list);
    rrmax = ns_msg_count(msg, ns_s_an);
    if (rrmax == 0)
        return -1;
    for (rrnum = 0; rrnum < rrmax; rrnum++) {
        if (ns_parserr(&msg, ns_s_an, rrnum, &rr)) {
            ERR("ns_parserr");
            return 0;
        }
        u_int type;
        const u_char *rd;
        type = ns_rr_type(rr);
        rd = ns_rr_rdata(rr);
        if (type == ns_t_a) {
            if (verbose)
                printf("%s, ", inet_ntoa(*(struct in_addr *)rd));
            r = bsearch(rd, ip_list.ips, ip_list.entries, sizeof(struct in_addr),
                        cmp_in_addr);
            if (r)
                return 1;
            if (chnroute_file && dns_is_chn) {
                // filter DNS result from chn dns if result is outside chn
                if (!test_ip_in_list(*(struct in_addr *)rd, &chnroute_list))
                    return 1;
            }
        }
    }
    return 0;
}
Exemple #2
0
static int should_filter_query(ns_msg msg, struct in_addr dns_addr) {
  ns_rr rr;
  int rrnum, rrmax;
  void *r;
  // TODO cache result for each dns server
  int dns_is_chn = 0;
  int dns_is_foreign = 0;
  if (chnroute_file && (dns_servers_len > 1)) {
    dns_is_chn = test_ip_in_list(dns_addr, &chnroute_list);
    dns_is_foreign = !dns_is_chn;
  }
  rrmax = ns_msg_count(msg, ns_s_an);
  if (rrmax == 0) {
    if (compression) {
      // Wait for foreign dns
      if (dns_is_chn) {
        return 1;
      } else {
        return 0;
      }
    }
    return -1;
  }
  for (rrnum = 0; rrnum < rrmax; rrnum++) {
    if (ns_parserr(&msg, ns_s_an, rrnum, &rr)) {
      ERR("ns_parserr");
      return 0;
    }
    u_int type;
    const u_char *rd;
    type = ns_rr_type(rr);
    rd = ns_rr_rdata(rr);
    if (type == ns_t_a) {
      if (verbose)
        printf("%s, ", inet_ntoa(*(struct in_addr *)rd));
      if (!compression) {
        r = bsearch(rd, ip_list.ips, ip_list.entries, sizeof(struct in_addr),
                    cmp_in_addr);
        if (r) {
          return 1;
        }
      }
      if (test_ip_in_list(*(struct in_addr *)rd, &chnroute_list)) {
        // result is chn
        if (dns_is_foreign) {
          if (bidirectional) {
            // filter DNS result from foreign dns if result is inside chn
            return 1;
          }
        }
      } else {
        // result is foreign
        if (dns_is_chn) {
          // filter DNS result from chn dns if result is outside chn
          return 1;
        }
      }
    } else if (type == ns_t_aaaa || type == ns_t_ptr) {
      // if we've got an IPv6 result or a PTR result, pass
      return 0;
    }
  }
  if (rrmax == 1) {
    if (compression) {
      return 0;
    } else {
      return -1;
    }
  }
  return 0;
}
Exemple #3
0
static int resolve_dns_servers() {
  struct addrinfo hints;
  struct addrinfo *addr_ip;
  char* token;
  int r;
  int i = 0;
  char *pch = strchr(dns_servers, ',');
  has_chn_dns = 0;
  int has_foreign_dns = 0;
  dns_servers_len = 1;
  if (compression) {
    if (!chnroute_file) {
      VERR("Chnroutes are necessary when using DNS compression pointer mutation\n");
      return -1;
    }
  }
  while (pch != NULL) {
    dns_servers_len++;
    pch = strchr(pch + 1, ',');
  }
  dns_server_addrs = calloc(dns_servers_len, sizeof(id_addr_t));

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
  token = strtok(dns_servers, ",");
  while (token) {
    char *port;
    memset(global_buf, 0, BUF_SIZE);
    strncpy(global_buf, token, BUF_SIZE - 1);
    port = (strrchr(global_buf, ':'));
    if (port) {
      *port = '\0';
      port++;
    } else {
      port = "53";
    }
    if (0 != (r = getaddrinfo(global_buf, port, &hints, &addr_ip))) {
      VERR("%s:%s\n", gai_strerror(r), token);
      return -1;
    }
    if (compression) {
      if (test_ip_in_list(((struct sockaddr_in *)addr_ip->ai_addr)->sin_addr,
                          &chnroute_list)) {
        dns_server_addrs[has_chn_dns].addr = addr_ip->ai_addr;
        dns_server_addrs[has_chn_dns].addrlen = addr_ip->ai_addrlen;
        has_chn_dns++;
      } else {
        has_foreign_dns++;
        dns_server_addrs[dns_servers_len - has_foreign_dns].addr = addr_ip->ai_addr;
        dns_server_addrs[dns_servers_len - has_foreign_dns].addrlen = addr_ip->ai_addrlen;
      }
      token = strtok(0, ",");
    } else {
      dns_server_addrs[i].addr = addr_ip->ai_addr;
      dns_server_addrs[i].addrlen = addr_ip->ai_addrlen;
      i++;
      token = strtok(0, ",");
      if (chnroute_file) {
        if (test_ip_in_list(((struct sockaddr_in *)addr_ip->ai_addr)->sin_addr,
                            &chnroute_list)) {
          has_chn_dns = 1;
        } else {
          has_foreign_dns = 1;
        }
      }
    }
  }
  if (chnroute_file) {
    if (!(has_chn_dns && has_foreign_dns)) {
      if (compression) {
        VERR("You should have at least one Chinese DNS and one foreign DNS when "
             "using DNS compression pointer mutation\n");
        return -1;
      } else {
        VERR("You should have at least one Chinese DNS and one foreign DNS when "
             "chnroutes is enabled\n");
        return 0;
      }
    }
  }
  return 0;
}