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

Implement dns server reply retry logic.


svn:r9081
This commit is contained in:
Nick Mathewson 2006-12-12 02:56:23 +00:00
parent c58d9494df
commit e53bca15e7
2 changed files with 39 additions and 17 deletions

View File

@ -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

View File

@ -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;
}
// XXXX process pending replies.
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
}
return 1;
}
evdns_server_request_free(req);
if (req->port->pending_replies)
server_port_flush(port);
return 0;
}