Skip to content

Commit

Permalink
move tcp inbound buffer to connection object
Browse files Browse the repository at this point in the history
  • Loading branch information
bradh352 committed Aug 17, 2024
1 parent 63cf11b commit 4934c7a
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 29 deletions.
9 changes: 4 additions & 5 deletions src/lib/ares__close_sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,19 @@ void ares__close_connection(ares_conn_t *conn, ares_status_t requeue_status)
{
ares_server_t *server = conn->server;
ares_channel_t *channel = server->channel;

fprintf(stderr, "%s(): close fd=%d\n", __FUNCTION__, (int)conn->fd);
/* Unlink */
ares__llist_node_claim(
ares__htable_asvp_get_direct(channel->connnode_by_socket, conn->fd));
ares__htable_asvp_remove(channel->connnode_by_socket, conn->fd);

ares__buf_destroy(conn->out_buf);

if (conn->flags & ARES_CONN_FLAG_TCP) {
/* Reset any existing input and output buffer. */
ares__buf_consume(server->tcp_parser, ares__buf_len(server->tcp_parser));
server->tcp_conn = NULL;
}

ares__buf_destroy(conn->in_buf);
ares__buf_destroy(conn->out_buf);

/* Requeue queries to other connections */
ares__requeue_queries(conn, requeue_status);

Expand Down
5 changes: 4 additions & 1 deletion src/lib/ares__socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -935,8 +935,10 @@ fprintf(stderr, "%s(): %s\n", __FUNCTION__, is_tcp?"tcp":"udp");
conn->queries_to_conn = ares__llist_create(NULL);
conn->flags = is_tcp ? ARES_CONN_FLAG_TCP : ARES_CONN_FLAG_NONE;
conn->out_buf = ares__buf_create();
conn->in_buf = ares__buf_create();

if (conn->queries_to_conn == NULL || conn->out_buf == NULL) {
if (conn->queries_to_conn == NULL || conn->out_buf == NULL ||
conn->in_buf == NULL) {
/* LCOV_EXCL_START: OutOfMemory */
status = ARES_ENOMEM;
goto done;
Expand Down Expand Up @@ -1054,6 +1056,7 @@ fprintf(stderr, "%s(): %s\n", __FUNCTION__, is_tcp?"tcp":"udp");
ares__llist_destroy(conn->queries_to_conn);
ares__close_socket(channel, conn->fd);
ares__buf_destroy(conn->out_buf);
ares__buf_destroy(conn->in_buf);
ares_free(conn);
} else {
*conn_out = conn;
Expand Down
1 change: 0 additions & 1 deletion src/lib/ares_destroy.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ void ares__destroy_server(ares_server_t *server)

ares__close_sockets(server);
ares__llist_destroy(server->connections);
ares__buf_destroy(server->tcp_parser);
ares_free(server);
}

Expand Down
10 changes: 6 additions & 4 deletions src/lib/ares_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ struct ares_conn {
* be sent per-packet (stripping the length prefix) */
ares__buf_t *out_buf;

/*! Inbound buffered data that is not yet parsed. Exists as one contiguous
* stream in TCP format (big endian 16bit length prefix followed by DNS
* wire-format message). TCP may have partial data and this needs to be
* handled gracefully, but UDP will always have a full message */
ares__buf_t *in_buf;

/* total number of queries run on this connection since it was established */
size_t total_queries;

Expand Down Expand Up @@ -289,10 +295,6 @@ struct ares_server {
/* The next time when we will retry this server if it has hit failures */
ares_timeval_t next_retry_time;

/* TCP buffer since multiple responses can come back in one read, or partial
* in a read */
ares__buf_t *tcp_parser;

/*! Buckets for collecting metrics about the server */
ares_server_metrics_t metrics[ARES_METRIC_COUNT];

Expand Down
23 changes: 11 additions & 12 deletions src/lib/ares_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,14 +388,13 @@ static void read_tcp_data(ares_channel_t *channel, ares_conn_t *conn,
const ares_timeval_t *now)
{
size_t count;
ares_server_t *server = conn->server;
ares_conn_err_t err;

/* Fetch buffer to store data we are reading */
size_t ptr_len = 65535;
unsigned char *ptr;

ptr = ares__buf_append_start(server->tcp_parser, &ptr_len);
ptr = ares__buf_append_start(conn->in_buf, &ptr_len);

if (ptr == NULL) {
handle_conn_error(conn, ARES_FALSE /* not critical to connection */,
Expand All @@ -408,15 +407,15 @@ static void read_tcp_data(ares_channel_t *channel, ares_conn_t *conn,
err = ares__conn_read(conn, ptr, ptr_len, &count);

if (err != ARES_CONN_ERR_SUCCESS) {
ares__buf_append_finish(server->tcp_parser, 0);
ares__buf_append_finish(conn->in_buf, 0);
if (err != ARES_CONN_ERR_WOULDBLOCK) {
handle_conn_error(conn, ARES_TRUE, ARES_ECONNREFUSED);
}
return;
}

/* Record amount of data read */
ares__buf_append_finish(server->tcp_parser, (size_t)count);
ares__buf_append_finish(conn->in_buf, (size_t)count);

/* Process all queued answers */
while (1) {
Expand All @@ -426,24 +425,24 @@ static void read_tcp_data(ares_channel_t *channel, ares_conn_t *conn,
ares_status_t status;

/* Tag so we can roll back */
ares__buf_tag(server->tcp_parser);
ares__buf_tag(conn->in_buf);

/* Read length indicator */
if (ares__buf_fetch_be16(server->tcp_parser, &dns_len) != ARES_SUCCESS) {
ares__buf_tag_rollback(server->tcp_parser);
if (ares__buf_fetch_be16(conn->in_buf, &dns_len) != ARES_SUCCESS) {
ares__buf_tag_rollback(conn->in_buf);
break;
}

/* Not enough data for a full response yet */
if (ares__buf_consume(server->tcp_parser, dns_len) != ARES_SUCCESS) {
ares__buf_tag_rollback(server->tcp_parser);
if (ares__buf_consume(conn->in_buf, dns_len) != ARES_SUCCESS) {
ares__buf_tag_rollback(conn->in_buf);
break;
}

/* Can't fail except for misuse */
data = ares__buf_tag_fetch(server->tcp_parser, &data_len);
data = ares__buf_tag_fetch(conn->in_buf, &data_len);
if (data == NULL || data_len < 2) {
ares__buf_tag_clear(server->tcp_parser);
ares__buf_tag_clear(conn->in_buf);
break;
}

Expand All @@ -459,7 +458,7 @@ static void read_tcp_data(ares_channel_t *channel, ares_conn_t *conn,
}

/* Since we processed the answer, clear the tag so space can be reclaimed */
ares__buf_tag_clear(server->tcp_parser);
ares__buf_tag_clear(conn->in_buf);
}
}

Expand Down
6 changes: 0 additions & 6 deletions src/lib/ares_update_servers.c
Original file line number Diff line number Diff line change
Expand Up @@ -608,12 +608,6 @@ static ares_status_t ares__server_create(ares_channel_t *channel,
server->ll_scope = sconfig->ll_scope;
}

server->tcp_parser = ares__buf_create();
if (server->tcp_parser == NULL) {
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
goto done; /* LCOV_EXCL_LINE: OutOfMemory */
}

server->connections = ares__llist_create(NULL);
if (server->connections == NULL) {
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
Expand Down

0 comments on commit 4934c7a

Please sign in to comment.