Skip to content

Instantly share code, notes, and snippets.

@ammarfaizi2
Created July 13, 2023 12:59
Show Gist options
  • Save ammarfaizi2/8604fbabd9d95ef23e75a080b206a766 to your computer and use it in GitHub Desktop.
Save ammarfaizi2/8604fbabd9d95ef23e75a080b206a766 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../io_ring_internal.h"
#include "../dns/dns_resolver.h"
#include "../dns/dns_ares.h"
#define MAX_TRY_COUNT 5
struct dns_arg {
struct io_ring *ring;
struct dns_resolver_result **result;
struct io_ring_sqe sqe;
uint8_t try_count;
};
static bool issue_sqe_dns_query(struct dns_arg *arg);
void gw_dns_cb(int code, struct dns_resolver_result *result, void *parg)
{
struct dns_arg *arg = parg;
struct io_ring *ring = arg->ring;
struct io_ring_sqe *sqe = &arg->sqe;
if (code == ARES_ECANCELLED && arg->try_count < MAX_TRY_COUNT) {
dns_res_result_free(result);
mutex_lock(&ring->sq_lock);
issue_sqe_dns_query(arg);
mutex_unlock(&ring->sq_lock);
return;
}
*arg->result = result;
gw_post_cqe(ring, code, sqe->user_data);
free(arg->sqe.arg2_ptr);
free(arg);
}
static bool issue_sqe_dns_query(struct dns_arg *arg)
__must_hold(&ring->sq_lock)
{
struct io_ring_sqe *sqe = &arg->sqe;
struct io_ring *ring = arg->ring;
int ret = -ENOSYS;
arg->try_count++;
switch (sqe->op) {
case GW_RING_OP_DNS_QUERY:
ret = dns_res_query(sqe->arg1_ptr, sqe->arg2_ptr, gw_dns_cb, arg);
break;
case GW_RING_OP_DNS_QUERY4:
ret = dns_res_query4(sqe->arg1_ptr, sqe->arg2_ptr, gw_dns_cb, arg);
break;
case GW_RING_OP_DNS_QUERY6:
ret = dns_res_query6(sqe->arg1_ptr, sqe->arg2_ptr, gw_dns_cb, arg);
break;
}
if (unlikely(ret != 0)) {
free(arg->sqe.arg2_ptr);
free(arg);
return gw_post_cqe(ring, ret, sqe->user_data);
}
return true;
}
bool gw_issue_sqe_dns_query(struct io_ring *ring, struct io_ring_sqe *sqe)
__must_hold(&ring->sq_lock)
{
struct dns_arg *arg;
arg = malloc(sizeof(*arg));
if (unlikely(!arg)) {
return false;
}
arg->sqe = *sqe;
arg->sqe.arg2_ptr = strdup(sqe->arg2_ptr);
if (unlikely(!arg->sqe.arg2_ptr)) {
free(arg);
return false;
}
arg->ring = ring;
arg->result = arg->sqe.arg3_ptr;
arg->try_count = 0;
return issue_sqe_dns_query(arg);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment