commit 5abc2e4: [Project] Rdns: More fixes in TCP handling
Vsevolod Stakhov
vsevolod at highsecure.ru
Wed Jan 5 11:28:19 UTC 2022
Author: Vsevolod Stakhov
Date: 2022-01-05 09:56:25 +0000
URL: https://github.com/rspamd/rspamd/commit/5abc2e4b45134c79bc4989744261ccb00675be56
[Project] Rdns: More fixes in TCP handling
---
contrib/librdns/resolver.c | 37 +++++++++++++++++++++++++++++++------
1 file changed, 31 insertions(+), 6 deletions(-)
diff --git a/contrib/librdns/resolver.c b/contrib/librdns/resolver.c
index ff1acf789..a86dd4030 100644
--- a/contrib/librdns/resolver.c
+++ b/contrib/librdns/resolver.c
@@ -154,16 +154,19 @@ rdns_send_request (struct rdns_request *req, int fd, bool new_req)
static struct rdns_request *
rdns_find_dns_request (uint8_t *in, struct rdns_io_channel *ioc)
{
- struct dns_header *header = (struct dns_header *)in;
+ struct dns_header header;
int id;
struct rdns_resolver *resolver = ioc->resolver;
- id = header->qid;
+ memcpy (&header, in, sizeof(header));
+ id = header.qid;
khiter_t k = kh_get(rdns_requests_hash, ioc->requests, id);
if (k == kh_end(ioc->requests)) {
/* No such requests found */
rdns_debug ("DNS request with id %d has not been found for IO channel", id);
+
+ return NULL;
}
return kh_value(ioc->requests, k);
@@ -319,7 +322,7 @@ rdns_process_tcp_read (int fd, struct rdns_io_channel *ioc)
ioc->tcp->cur_read += r;
if (r == sizeof(ioc->tcp->next_read_size)) {
- ioc->tcp->next_read_size = ntohl(ioc->tcp->next_read_size);
+ ioc->tcp->next_read_size = ntohs(ioc->tcp->next_read_size);
/* We have read the size, so we can try read one more time */
if (!rdns_tcp_maybe_realloc_read_buf(ioc)) {
@@ -342,7 +345,7 @@ rdns_process_tcp_read (int fd, struct rdns_io_channel *ioc)
}
ioc->tcp->cur_read += r;
- ioc->tcp->next_read_size = ntohl(ioc->tcp->next_read_size);
+ ioc->tcp->next_read_size = ntohs(ioc->tcp->next_read_size);
/* We have read the size, so we can try read one more time */
if (!rdns_tcp_maybe_realloc_read_buf(ioc)) {
@@ -464,7 +467,7 @@ rdns_reschedule_req_over_tcp (struct rdns_request *req, struct rdns_server *serv
}
oc->req = req;
- oc->next_write_size = req->packet_len;
+ oc->next_write_size = htons(req->packet_len);
DL_APPEND(ioc->tcp->output_chain, oc);
@@ -477,9 +480,31 @@ rdns_reschedule_req_over_tcp (struct rdns_request *req, struct rdns_server *serv
req->state = RDNS_REQUEST_TCP;
/* Switch IO channel from UDP to TCP */
req->io = ioc;
+
+ khiter_t k;
+ for (;;) {
+ int pr;
+ k = kh_put(rdns_requests_hash, ioc->requests, req->id, &pr);
+
+ if (pr == 0) {
+ /* We have already a request with this id, so we have to regenerate ID */
+ req->id = rdns_permutor_generate_id ();
+ /* Update packet as well */
+ uint16_t raw_id = req->id;
+ memcpy(req->packet, &raw_id, sizeof(raw_id));
+ }
+ else {
+ break;
+ }
+ }
+
+ kh_value(req->io->requests, k) = req;
REF_RETAIN(ioc);
REF_RELEASE(old_ioc);
+ /* We do extra ref as we push a request into a TCP hash table */
+ REF_RETAIN(req);
+
return true;
}
@@ -877,7 +902,7 @@ rdns_process_tcp_write (int fd, struct rdns_io_channel *ioc)
return;
}
}
- else if (ntohl(oc->next_write_size) < oc->cur_write) {
+ else if (ntohs(oc->next_write_size) < oc->cur_write) {
/* Packet has been fully written, remove it */
DL_DELETE(ioc->tcp->output_chain, oc);
/* Data in output buffer belongs to request */
More information about the Commits
mailing list