예제 #1
0
파일: chinadns.c 프로젝트: mysqto/ChinaDNS
static void dns_handle_remote() {
  struct sockaddr *src_addr = malloc(sizeof(struct sockaddr));
  socklen_t src_len = sizeof(struct sockaddr);
  uint16_t query_id;
  ssize_t len;
  const char *question_hostname;
  int r;
  ns_msg msg;
  len = recvfrom(remote_sock, global_buf, BUF_SIZE, 0, src_addr, &src_len);
  if (len > 0) {
    if (ns_initparse((const u_char *)global_buf, len, &msg) < 0) {
      ERR("ns_initparse");
      free(src_addr);
      return;
    }
    // parse DNS query id
    query_id = ns_msg_id(msg);
    question_hostname = hostname_from_question(msg);
    if (question_hostname) {
      LOG("response %s from %s:%d - ", question_hostname,
          inet_ntoa(((struct sockaddr_in *)src_addr)->sin_addr),
          htons(((struct sockaddr_in *)src_addr)->sin_port));
    }
    id_addr_t *id_addr = queue_lookup(query_id);
    if (id_addr) {
      id_addr->addr->sa_family = AF_INET;
      uint16_t ns_old_id = htons(id_addr->old_id);
      memcpy(global_buf, &ns_old_id, 2);
      r = should_filter_query(msg, ((struct sockaddr_in *)src_addr)->sin_addr);
      if (r == 0) {
        if (verbose)
          printf("pass\n");
        if (-1 == sendto(local_sock, global_buf, len, 0, id_addr->addr,
                         id_addr->addrlen))
          ERR("sendto");
      } else if (r == -1) {
        schedule_delay(query_id, global_buf, len, id_addr->addr,
                       id_addr->addrlen);
        if (verbose)
          printf("delay\n");
      } else {
        if (verbose)
          printf("filter\n");
      }
    } else {
      if (verbose)
        printf("skip\n");
    }
    free(src_addr);
  }
  else
    ERR("recvfrom");
}
status_t devfs_entry_remove_by_name (devfs_inode_t node, char * name)
{
  devfs_entry_t entry;
  status_t status;

  watch (status_t)
  {
    ensure (node != NULL, DNA_BAD_ARGUMENT);
    ensure (name != NULL, DNA_BAD_ARGUMENT);

    entry = queue_lookup (& node -> entry_list,
        devfs_entry_name_inspector, name);
    ensure (entry != NULL, DNA_NO_ENTRY);

    status = queue_extract (& node -> entry_list, entry);
    ensure (status == DNA_OK, DNA_NO_ENTRY);
 
    kernel_free (entry);
    return DNA_OK;
  }
}
예제 #3
0
int syscall_que_lookup(unsigned int quename)
{
  return queue_lookup(quename);
}
예제 #4
0
파일: chinadns.c 프로젝트: mysqto/ChinaDNS
static void dns_handle_local() {
  struct sockaddr *src_addr = malloc(sizeof(struct sockaddr));
  socklen_t src_addrlen = sizeof(struct sockaddr);
  uint16_t query_id;
  ssize_t len;
  int i;
  int sended = 0;
  const char *question_hostname;
  ns_msg msg;
  len = recvfrom(local_sock, global_buf, BUF_SIZE, 0, src_addr, &src_addrlen);
  if (len > 0) {
    if (ns_initparse((const u_char *)global_buf, len, &msg) < 0) {
      ERR("ns_initparse");
      free(src_addr);
      return;
    }
    // parse DNS query id
    // TODO generate id for each request to avoid conflicts
    query_id = ns_msg_id(msg);
    question_hostname = hostname_from_question(msg);
    LOG("request %s\n", question_hostname);

    // assign a new id
    uint16_t new_id;
    do {
      struct timeval tv;
      gettimeofday(&tv, 0);
      int randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
      new_id = randombits & 0xffff;
    } while (queue_lookup(new_id));

    uint16_t ns_new_id = htons(new_id);
    memcpy(global_buf, &ns_new_id, 2);

    id_addr_t id_addr;
    id_addr.id = new_id;
    id_addr.old_id = query_id;

    id_addr.addr = src_addr;
    id_addr.addrlen = src_addrlen;
    queue_add(id_addr);
    if (compression) {
      if (len > 16) {
        size_t off = 12;
        int ended = 0;
        while (off < len - 4) {
          if (global_buf[off] & 0xc0)
            break;
          if (global_buf[off] == 0) {
            ended = 1;
            off ++;
            break;
          }
          off += 1 + global_buf[off];
        }
        if (ended) {
          memcpy(compression_buf, global_buf, off-1);
          memcpy(compression_buf + off + 1, global_buf + off, len - off);
          compression_buf[off-1] = '\xc0';
          compression_buf[off] = '\x04';
          for (i = 0; i < has_chn_dns; i++) {
            if (-1 == sendto(remote_sock, global_buf, len, 0,
                             dns_server_addrs[i].addr,
                             dns_server_addrs[i].addrlen))
              ERR("sendto");
          }
          for (i =  has_chn_dns; i < dns_servers_len; i++) {
            if (-1 == sendto(remote_sock, compression_buf, len + 1, 0,
                             dns_server_addrs[i].addr,
                             dns_server_addrs[i].addrlen))
              ERR("sendto");
            sended = 1;
          }
        }
      }
    }
    if (!sended) {
      for (i = 0; i < dns_servers_len; i++) {
        if (-1 == sendto(remote_sock, global_buf, len, 0,
                         dns_server_addrs[i].addr,
                         dns_server_addrs[i].addrlen))
          ERR("sendto");
      }
    }
  }
  else
    ERR("recvfrom");
}
예제 #5
0
status_t interrupt_detach (int32_t cpuid, interrupt_id_t id,
    interrupt_handler_t handler)

/*
 * ARGUMENTS
 * * cpuid : id of the target CPU
 * * id : an interrupt ID
 * * handler : handler of the interrupt
 *
 * RESULT
 * * DNA_BAD_ARGUMENT: one of the arguments is incorrect
 * * DNA_OK: the operation is successful
 *
 * SOURCE
 */

{
  isr_t isr = NULL;
  queue_t * queue = NULL;
  interrupt_status_t it_status = 0;

  watch (status_t)
  {
    ensure (id < CPU_TRAP_COUNT, DNA_BAD_ARGUMENT);
    ensure (cpuid < cpu_mp_count (), DNA_BAD_ARGUMENT);

    /*
     * Remove the ISR from the appropriate queue.
     */

    it_status = cpu_trap_mask_and_backup();
    queue = & cpu_pool . cpu[cpuid] . isr[id];
    lock_acquire (& queue -> lock);

    isr = queue_lookup (queue, interrupt_handler_inspector, handler);
    check (no_isr, isr != NULL, DNA_BAD_ARGUMENT);

    queue_extract (queue, isr);

    /*
     * If there is no more handler for the specified
     * interrupt, disable it.
     */

    if (queue -> status == 0)
    {
      if (cpuid == cpu_mp_id ())
      {
        cpu_trap_disable (id);
      }
      else
      {
        lock_acquire (& cpu_pool . cpu[cpuid] . ipi_lock);
        cpu_mp_send_ipi (cpuid, DNA_IPI_TRAP_DISABLE, (void *) id);
      }
    }

    lock_release (& queue -> lock);
    cpu_trap_restore(it_status);

    kernel_free (isr);
    return DNA_OK;
  }

  rescue (no_isr)
  {
    lock_release (& queue -> lock);
    cpu_trap_restore(it_status);
    leave;
  }
}