Exemple #1
0
int 
process_request()
{
	client.request->contents = read_socket(client.request->socket);
	if (!client.request->contents) return request_retry();
	if (!client.request->body && process_request_contents()) return -1;
	if (request_done()) dechunk_request();
	return 0;
}
Exemple #2
0
int udp_request_retry (Context *cont) {
	char *fn = "udp_request_retry()";
	struct sockaddr *sa;
	int len, timeout;

	syslog (LOG_DEBUG, "%s: start", fn);

	/* remove old I/O List (if it is still there) */
	sa = (struct sockaddr *) cont->current_ns->list_data;
	ev_udp_in_remove (sa, cont->q_id);

	/*
	 * Fast GiveUp Hack.
	 *
	 * decisions like this should only be made in request.c,
	 * so this hack is ugly too.
	 */
	if (cont->q_type == RT_AAAA || cont->q_type == RT_A6) {
		/*
		 * Some nameservers just do not like IPv6
		 * address records. We guess that is the case
		 * here and tell the parent to continue if it
		 * can.
		 *
		 * We perform the code of request_finish()
		 * here, but without the parsing of the
		 * response (we have none).
		 *
		 * Note that this means that a timeout for a IPv6
		 * address record request never causes a shift to
		 * the next forwarder! Seems reasonable in the
		 * for the majority of cases.
		 */

		syslog (LOG_DEBUG, "Giving up quickly on IPv6 address record");

		/* re-initialize answer, nameserver, additional record lists */
		list_destroy (cont->an_list, rrset_freev);
		list_destroy (cont->ns_list, rrset_freev);
		list_destroy (cont->ar_list, rrset_freev);
		cont->an_list = list_init ();
		cont->ns_list = list_init ();
		cont->ar_list = list_init ();
		if (!cont->an_list || !cont->ns_list || !cont->ar_list)
			return request_abort (cont, -1);

		if (cont->parent) {
			syslog (LOG_DEBUG, "%s: process parent context", fn);
			cont->parent->process (cont->parent);
		}

		/* ... so we cleanup ourselves in any case */
		context_destroy (cont);

		syslog (LOG_DEBUG, "%s: return success", fn);
		return 0; /* SUCCESS */
	}

	if (request_retry (cont) < 0)
		return (request_abort (cont, -2));

	/* send/forward the message/request again */
	sa = (struct sockaddr *) cont->current_ns->list_data;
	len = net_mesg_send (NULL, cont->mesg.p, cont->mesg_len, sa);
	if (len < cont->mesg_len) {
		if (len < 0)
			syslog (LOG_NOTICE, "retry failed(default socket): %m");
		else
			syslog (LOG_NOTICE, "can't send whole datagram");
		/* forcing immediate retry */
		timeout = 0;
	} else {
		/* we retried the request, now wait for response or timeout */
		timeout = cont->timeout;
		/* put me to input list */
		if (ev_udp_in_register (cont, sa,
		     SOCKADDR_SIZEOF (*sa), cont->q_id) < 0)
			return (request_abort (cont, -1));
	}

	/* put me to timeout list */
	if (context_timeout_register (cont, timeout) < 0)
		return (request_abort (cont, -1));

	/* no state change... */
	syslog (LOG_DEBUG, "%s: end", fn);
	return 0;
}