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; } }
int syscall_que_lookup(unsigned int quename) { return queue_lookup(quename); }
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"); }
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; } }