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 + -
显示快捷键?