task.c
来自「此dns服务器是在mydns基础上改写」· C语言 代码 · 共 615 行 · 第 1/2 页
C
615 行
_task_free(TASK *t, const char *file, int line){ if (!t) return; sockclose(t->recursive_fd);#if DEBUG_ENABLED && DEBUG_TASK Debug("%s: task_free(%p) from %s:%d", desctask(t), t, file, line);#endif#if DYNAMIC_NAMES { register int n; for (n = 0; n < t->numNames; n++) Free(t->Names[n]); if (t->numNames) Free(t->Names); Free(t->Offsets); }#endif Free(t->query); Free(t->qd); rrlist_free(&t->an); rrlist_free(&t->ns); rrlist_free(&t->ar); Free(t->rdata); Free(t->reply); Free(t); if (answer_then_quit && (Status.udp_requests + Status.tcp_requests) >= answer_then_quit) named_cleanup(SIGQUIT);}/*--- _task_free() ------------------------------------------------------------------------------*//************************************************************************************************** TASK_INIT_HEADER Sets and/or clears header fields and values as necessary.**************************************************************************************************/voidtask_init_header(TASK *t){ t->hdr.qr = 1; /* This is the response, not the query */ t->hdr.ra = forward_recursive; /* Are recursive queries available? */ t->hdr.rcode = DNS_RCODE_NOERROR; /* Assume success unless told otherwise */}/*--- task_init_header() ------------------------------------------------------------------------*//************************************************************************************************** TASK_OUTPUT_INFO**************************************************************************************************/voidtask_output_info(TASK *t, char *update_desc){#if !DISABLE_DATE_LOGGING struct timeval tv; time_t tt; struct tm *tm; char datebuf[80];#endif /* If we've already outputted the info for this (i.e. multiple DNS UPDATE requests), ignore */ if (t->info_already_out) return; /* Don't output anything for TCP sockets in the process of closing */ if (t->protocol == SOCK_STREAM && t->fd < 0) return;#if !DISABLE_DATE_LOGGING gettimeofday(&tv, NULL); tt = tv.tv_sec; tm = localtime(&tt); strftime(datebuf, sizeof(datebuf)-1, "%d-%b-%Y %H:%M:%S", tm);#endif Verbose(#if !DISABLE_DATE_LOGGING "%s+%06lu "#endif "#%lu " "%d " /* Client-provided ID */ "%s " /* TCP or UDP? */ "%s " /* Client IP */ "%s " /* Class */ "%s " /* Query type (A, MX, etc) */ "%s " /* Name */ "%s " /* Return code (NOERROR, NXDOMAIN, etc) */ "%s " /* Reason */ "%d " /* Question section */ "%d " /* Answer section */ "%d " /* Authority section */ "%d " /* Additional section */ "LOG " "%s " /* Reply from cache? */ "%s " /* Opcode */ "\"%s\"" /* UPDATE description (if any) */ ,#if !DISABLE_DATE_LOGGING datebuf, tv.tv_usec,#endif t->internal_id, t->id, t->protocol == SOCK_STREAM ? "TCP" : "UDP", clientaddr(t), mydns_class_str(t->qclass), mydns_qtype_str(t->qtype), t->qname, mydns_rcode_str(t->hdr.rcode), err_reason_str(t, t->reason), t->qdcount, t->an.size, t->ns.size, t->ar.size, (t->reply_from_cache ? "Y" : "N"), mydns_opcode_str(t->hdr.opcode), update_desc ? update_desc : "" );}/*--- task_output_info() ------------------------------------------------------------------------*//************************************************************************************************** TASK_PROCESS Process the specified task, if possible. Returns a pointer to the next task.**************************************************************************************************/voidtask_process(register TASK *t){ int rv; /* ** NEED_READ: Need to read query */ if (t->status == NEED_READ) {#if DEBUG_ENABLED && DEBUG_TASK Debug("%s: starting task_process() with NEED_READ status", desctask(t));#endif switch (t->protocol) { case SOCK_DGRAM: Warnx("%s: %s", desctask(t), _("invalid state for UDP query")); return dequeue(Tasks, t); case SOCK_STREAM: if ((rv = read_tcp_query(t)) < 0) {#if 0 /* WHY?? 20 May 2004 WDM */ if (t->status == NEED_WRITE) break;#endif sockclose(t->fd); /* If read_tcp_query() returns -2, the task has already been freed */ if (rv == -1) dequeue(Tasks, t); return; } if (t->status != NEED_ANSWER) return; /* read_tcp_query did OK, status is now NEED_ANSWER, so move down and resolve */ break; default: Warnx("%s: %d: %s", desctask(t), t->protocol, _("unknown/unsupported protocol")); return dequeue(Tasks, t); } } /* ** NEED_ANSWER: Need to resolve query */ if (t->status == NEED_ANSWER) {#if DEBUG_ENABLED && DEBUG_TASK Debug("%s: starting task_process() with NEED_ANSWER status", desctask(t));#endif if (reply_cache_find(t)) { char *dest = t->reply; DNS_PUT16(dest, t->id); /* Query ID */ DNS_PUT(dest, &t->hdr, SIZE16); /* Header */ t->status = NEED_WRITE; } else { resolve(t, ANSWER, t->qtype, t->qname, 0); if (t->status < NEED_RECURSIVE_FWD_CONNECT) { build_reply(t, 1); if (t->reply_cache_ok) add_reply_to_cache(t); t->status = NEED_WRITE; if (t->protocol == SOCK_STREAM) return; } } } /* ** NEED_WRITE: Need to write reply */ if (t->status == NEED_WRITE) {#if DEBUG_ENABLED && DEBUG_TASK Debug("%s: starting task_process() with NEED_WRITE status", desctask(t));#endif switch (t->protocol) { case SOCK_DGRAM: return write_udp_reply(t); case SOCK_STREAM: /* No need to check return value, since we always return anyway. */ write_tcp_reply(t); return; default: Warnx("%s: %d: %s", desctask(t), t->protocol, _("unknown/unsupported protocol")); return dequeue(Tasks, t); } } /* ** NEED_RECURSIVE_FWD_CONNECT: Need to connnect to recursive forwarder */ if (t->status == NEED_RECURSIVE_FWD_CONNECT) {#if DEBUG_ENABLED && DEBUG_TASK Debug("%s: starting task_process() with NEED_RECURSIVE_FWD_CONNECT status", desctask(t));#endif if (recursive_fwd_connect(t) < 0) return dequeue(Tasks, t); /* Successfully connected to the recursive forwarder */ t->status = NEED_RECURSIVE_FWD_WRITE; } /* ** NEED_RECURSIVE_FWD_WRITE: Need to write request to recursive forwarder */ if (t->status == NEED_RECURSIVE_FWD_WRITE) { int rv2;#if DEBUG_ENABLED && DEBUG_TASK Debug("%s: starting task_process() with NEED_RECURSIVE_FWD_WRITE status", desctask(t));#endif rv2 = recursive_fwd_write(t); if (rv2 < 0) return dequeue(Tasks, t); else if (rv2 == 1) /* 1 means "try again" */ return; /* Forwarded recursive query written successfully */ t->status = NEED_RECURSIVE_FWD_READ; } /* ** NEED_RECURSIVE_FWD_READ: Need to read reply from recursive forwarder */ if (t->status == NEED_RECURSIVE_FWD_READ) { int rv2;#if DEBUG_ENABLED && DEBUG_TASK Debug("%s: starting task_process() with NEED_RECURSIVE_FWD_READ status", desctask(t));#endif rv2 = recursive_fwd_read(t); if (rv2 < 0) return dequeue(Tasks, t); else if (rv2 == 1) /* 1 means "try again" */ return; /* Got recursive forwarder's reply; write it to the client */ if (t->reply_cache_ok) add_reply_to_cache(t); t->status = NEED_WRITE; } return;}/*--- task_process() ----------------------------------------------------------------------------*//* vi:set ts=3: *//* NEED_PO */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?