Commit e53bca15 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

r11492@Kushana: nickm | 2006-12-11 12:30:23 -0500

 Implement dns server reply retry logic.


svn:r9081
parent c58d9494
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -95,16 +95,18 @@ N - DNS improvements
      - Teach evdns to be able to listen for requests to be processed.
        . Design interface.
          - Rename stuff; current names suck.
        . Design backend.
        - Implement
          . Listen for questions
        o Design backend.
        . Implement
          o Listen for questions
          o Parse questions, tell user code
          o Let user code tell us the answer
          o Generate responses
          o Send responses to client
          o Queue responses when we see EAGAIN
          - Retry responses after a while
          o Retry responses after a while
          o Be efficient about labels.
          - Comment everything.
          - Clean up XXXX items
          - Test
d         - Be more memory-efficient
      - Add some kind of general question/response API so libevent can be
+32 −12
Original line number Diff line number Diff line
@@ -1243,8 +1243,19 @@ server_port_read(struct evdns_server_port *s) {
static void
server_port_flush(struct evdns_server_port *port)
{
	// XXXX Writeme.
	(void)port;
	while (port->pending_replies) {
		struct server_request *req = port->pending_replies;
		int r = sendto(port->socket, req->response, req->response_len, 0,
			   (struct sockaddr*) &req->addr, req->addrlen);
		if (r < 0) // handle errror XXXX
			return;
		evdns_server_request_free(req);
	}

	(void) event_del(&port->event);
	event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
			  server_port_ready_callback, port);
	event_add(&port->event, NULL); // handle error. XXXX
}

// set if we are waiting for the ability to write to this server.
@@ -1671,34 +1682,43 @@ int
evdns_request_respond(struct evdns_server_request *_req, int flags)
{
	struct server_request *req = TO_SERVER_REQUEST(_req);
	struct evdns_server_port *port = req->port;
	int r;
	if (!req->response) {
		if ((r = evdns_request_response_format(req, flags))<0)
			return r;
	}

	r = sendto(req->port->socket, req->response, req->response_len, 0,
	r = sendto(port->socket, req->response, req->response_len, 0,
			   (struct sockaddr*) &req->addr, req->addrlen);
	if (r<0) {
		int err = last_error(req->port->socket);
		int err = last_error(port->socket);
		if (! error_is_eagain(err))
			return -1;

		if (req->port->pending_replies) {
			req->prev_pending = req->port->pending_replies->prev_pending;
			req->next_pending = req->port->pending_replies;
		if (port->pending_replies) {
			req->prev_pending = port->pending_replies->prev_pending;
			req->next_pending = port->pending_replies;
			req->prev_pending->next_pending =
				req->next_pending->prev_pending = req;
		} else {
			req->prev_pending = req->next_pending = req;
			req->port->pending_replies = req;
			req->port->choaked = 1;
		}
		return 0;
			port->pending_replies = req;
			port->choaked = 1;

			(void) event_del(&port->event);
			event_set(&port->event, port->socket, EV_READ | EV_WRITE | EV_PERSIST, server_port_ready_callback, port);

			event_add(&port->event, NULL); // handle error. XXXX
		}
	// XXXX process pending replies.

		return 1;
	}
	evdns_server_request_free(req);

	if (req->port->pending_replies)
		server_port_flush(port);

	return 0;
}