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);
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)) {
}
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)) {
}
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);
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;
}
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 */