implemented simple dns caching in httpd
This commit is contained in:
parent
1231b3b941
commit
6137df4e86
11
qse/configure
vendored
11
qse/configure
vendored
@ -20079,6 +20079,7 @@ done
|
|||||||
|
|
||||||
if test "$ac_cv_func_quadmath_snprintf" = "no"
|
if test "$ac_cv_func_quadmath_snprintf" = "no"
|
||||||
then
|
then
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for quadmath_snprintf in -lquadmath" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for quadmath_snprintf in -lquadmath" >&5
|
||||||
$as_echo_n "checking for quadmath_snprintf in -lquadmath... " >&6; }
|
$as_echo_n "checking for quadmath_snprintf in -lquadmath... " >&6; }
|
||||||
if ${ac_cv_lib_quadmath_quadmath_snprintf+:} false; then :
|
if ${ac_cv_lib_quadmath_quadmath_snprintf+:} false; then :
|
||||||
@ -20122,6 +20123,13 @@ if test "x$ac_cv_lib_quadmath_quadmath_snprintf" = xyes; then :
|
|||||||
$as_echo "#define HAVE_QUADMATH_SNPRINTF 1" >>confdefs.h
|
$as_echo "#define HAVE_QUADMATH_SNPRINTF 1" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test "$ac_cv_lib_quadmath_quadmath_snprintf" = "no"
|
||||||
|
then
|
||||||
|
|
||||||
|
ac_cv_sizeof___float128=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -20129,6 +20137,8 @@ fi
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test ${ac_cv_sizeof___float128} -gt 0
|
||||||
|
then
|
||||||
OLDLIBS="$LIBS"
|
OLDLIBS="$LIBS"
|
||||||
LIBS="$LIBM $LIBS"
|
LIBS="$LIBM $LIBS"
|
||||||
for ac_func in powq fmodq sinq cosq tanq sinhq coshq tanhq asinq acosq atanq atan2q logq log10q expq sqrtq ceilq floorq roundq
|
for ac_func in powq fmodq sinq cosq tanq sinhq coshq tanhq asinq acosq atanq atan2q logq log10q expq sqrtq ceilq floorq roundq
|
||||||
@ -20156,6 +20166,7 @@ done
|
|||||||
|
|
||||||
LIBS="$OLDLIBS"
|
LIBS="$OLDLIBS"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -435,6 +435,9 @@ then
|
|||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl Quadmath functions may not be in the default c library.
|
||||||
|
dnl Find a library containing them. Disable the float128 type
|
||||||
|
dnl if they are not available.
|
||||||
if test ${ac_cv_sizeof___float128} -gt 0
|
if test ${ac_cv_sizeof___float128} -gt 0
|
||||||
then
|
then
|
||||||
AC_CHECK_FUNCS([quadmath_snprintf])
|
AC_CHECK_FUNCS([quadmath_snprintf])
|
||||||
@ -447,22 +450,37 @@ then
|
|||||||
|
|
||||||
if test "$ac_cv_func_quadmath_snprintf" = "no"
|
if test "$ac_cv_func_quadmath_snprintf" = "no"
|
||||||
then
|
then
|
||||||
|
dnl quadmath_snprintf not avalable in the
|
||||||
|
dnl standard math lib.
|
||||||
|
|
||||||
AC_CHECK_LIB([quadmath], [quadmath_snprintf], [
|
AC_CHECK_LIB([quadmath], [quadmath_snprintf], [
|
||||||
QUADMATH_LIBS="-lquadmath"
|
QUADMATH_LIBS="-lquadmath"
|
||||||
LIBM="$LIBM -lquadmath"
|
LIBM="$LIBM -lquadmath"
|
||||||
AC_DEFINE(HAVE_QUADMATH_SNPRINTF, 1)
|
AC_DEFINE(HAVE_QUADMATH_SNPRINTF, 1)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
if test "$ac_cv_lib_quadmath_quadmath_snprintf" = "no"
|
||||||
|
then
|
||||||
|
dnl quadmath_snprintf not avalable in the
|
||||||
|
dnl quadmath lib.
|
||||||
|
|
||||||
|
ac_cv_sizeof___float128=0
|
||||||
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
QUADMATH_LIBS="$LIBM"
|
QUADMATH_LIBS="$LIBM"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test ${ac_cv_sizeof___float128} -gt 0
|
||||||
|
then
|
||||||
OLDLIBS="$LIBS"
|
OLDLIBS="$LIBS"
|
||||||
LIBS="$LIBM $LIBS"
|
LIBS="$LIBM $LIBS"
|
||||||
AC_CHECK_FUNCS([powq fmodq sinq cosq tanq sinhq coshq tanhq asinq acosq atanq atan2q logq log10q expq sqrtq ceilq floorq roundq])
|
AC_CHECK_FUNCS([powq fmodq sinq cosq tanq sinhq coshq tanhq asinq acosq atanq atan2q logq log10q expq sqrtq ceilq floorq roundq])
|
||||||
AC_CHECK_FUNCS([strtoflt128])
|
AC_CHECK_FUNCS([strtoflt128])
|
||||||
LIBS="$OLDLIBS"
|
LIBS="$OLDLIBS"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
AC_SUBST(QUADMATH_LIBS)
|
AC_SUBST(QUADMATH_LIBS)
|
||||||
|
|
||||||
AC_DEFINE_UNQUOTED(QSE_SIZEOF_CHAR, ${ac_cv_sizeof_char}, [sizeof(char)])
|
AC_DEFINE_UNQUOTED(QSE_SIZEOF_CHAR, ${ac_cv_sizeof_char}, [sizeof(char)])
|
||||||
|
@ -1016,7 +1016,6 @@ static void task_fini_proxy (
|
|||||||
{
|
{
|
||||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||||
|
|
||||||
printf ("task_fini_proxy.................\n");
|
|
||||||
if (proxy->peer_status & PROXY_PEER_OPEN)
|
if (proxy->peer_status & PROXY_PEER_OPEN)
|
||||||
httpd->opt.scb.peer.close (httpd, &proxy->peer);
|
httpd->opt.scb.peer.close (httpd, &proxy->peer);
|
||||||
|
|
||||||
@ -1083,7 +1082,7 @@ static int task_main_proxy_4 (
|
|||||||
{
|
{
|
||||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
||||||
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||||
#endif
|
#endif
|
||||||
@ -1577,12 +1576,13 @@ static void on_peer_name_resolved (qse_httpd_t* httpd, const qse_mchar_t* name,
|
|||||||
|
|
||||||
QSE_ASSERT (proxy->flags & PROXY_RESOL_PEER_NAME);
|
QSE_ASSERT (proxy->flags & PROXY_RESOL_PEER_NAME);
|
||||||
|
|
||||||
|
proxy->flags &= ~PROXY_RESOL_PEER_NAME;
|
||||||
|
|
||||||
if (nwad)
|
if (nwad)
|
||||||
{
|
{
|
||||||
/* resolved successfully */
|
/* resolved successfully */
|
||||||
proxy->flags &= ~PROXY_RESOL_PEER_NAME;
|
|
||||||
proxy->peer.nwad = *nwad;
|
|
||||||
|
|
||||||
|
proxy->peer.nwad = *nwad;
|
||||||
qse_setnwadport (&proxy->peer.nwad, qse_hton16(proxy->peer_port));
|
qse_setnwadport (&proxy->peer.nwad, qse_hton16(proxy->peer_port));
|
||||||
|
|
||||||
if (proxy->peer.local.type == QSE_NWAD_NX)
|
if (proxy->peer.local.type == QSE_NWAD_NX)
|
||||||
@ -1620,8 +1620,21 @@ static int task_main_proxy (
|
|||||||
{
|
{
|
||||||
/* arrange to resolve a host name and return */
|
/* arrange to resolve a host name and return */
|
||||||
QSE_ASSERT (proxy->peer_name != QSE_NULL);
|
QSE_ASSERT (proxy->peer_name != QSE_NULL);
|
||||||
if (qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1 ||
|
|
||||||
qse_httpd_resolname (httpd, proxy->peer_name, on_peer_name_resolved, task)) goto oops;
|
if (qse_httpd_resolname (httpd, proxy->peer_name, on_peer_name_resolved, task) <= -1) goto oops;
|
||||||
|
|
||||||
|
/* if the name could be resolved without sending a request
|
||||||
|
* in qse_httpd_resolname(), on_peer_name_resolve would be
|
||||||
|
* called. */
|
||||||
|
if (proxy->flags & PROXY_INIT_FAILED)
|
||||||
|
{
|
||||||
|
if (proxy->flags & PROXY_UNKNOWN_PEER_NWAD) http_errnum = 404; /* 404 Not Found */
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((proxy->flags & PROXY_RESOL_PEER_NAME) &&
|
||||||
|
qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1) goto oops;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1960,43 +1960,19 @@ static void client_closed (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
|||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
|
#define DNS_MAX_DN_LEN 255 /* full domain name length in binary form (i.e. 3xyz2eu0) */
|
||||||
|
#define DNS_MAX_MSG_LEN 512 /* basic dns only. no EDNS0. so 512 at most */
|
||||||
|
|
||||||
|
#define DNS_MIN_TTL 10
|
||||||
|
#define DNS_MAX_TTL 120 /* TODO: make these configurable... */
|
||||||
|
|
||||||
typedef struct dns_ctx_t dns_ctx_t;
|
typedef struct dns_ctx_t dns_ctx_t;
|
||||||
typedef struct dns_req_t dns_req_t;
|
typedef struct dns_req_t dns_req_t;
|
||||||
|
typedef struct dns_ans_t dns_ans_t;
|
||||||
typedef struct dns_hdr_t dns_hdr_t;
|
typedef struct dns_hdr_t dns_hdr_t;
|
||||||
typedef struct dns_qdtrail_t dns_qdtrail_t;
|
typedef struct dns_qdtrail_t dns_qdtrail_t;
|
||||||
typedef struct dns_antrail_t dns_antrail_t;
|
typedef struct dns_antrail_t dns_antrail_t;
|
||||||
|
|
||||||
struct dns_ctx_t
|
|
||||||
{
|
|
||||||
qse_skad_t skad;
|
|
||||||
int skadlen;
|
|
||||||
|
|
||||||
qse_uint16_t seq;
|
|
||||||
dns_req_t* reqs[1024]; /* TOOD: choose the right size */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dns_req_t
|
|
||||||
{
|
|
||||||
#define DNS_REQ_A_NX (1 << 0)
|
|
||||||
#define DNS_REQ_AAAA_NX (1 << 1)
|
|
||||||
int flags;
|
|
||||||
qse_uint16_t seqa, seqaaaa;
|
|
||||||
|
|
||||||
qse_mchar_t* name;
|
|
||||||
qse_uint8_t* dn;
|
|
||||||
qse_size_t dnlen;
|
|
||||||
|
|
||||||
qse_httpd_resol_t resol;
|
|
||||||
void* ctx;
|
|
||||||
|
|
||||||
qse_uint8_t qa[384];
|
|
||||||
qse_uint8_t qaaaa[384];
|
|
||||||
int qalen;
|
|
||||||
int qaaaalen;
|
|
||||||
|
|
||||||
dns_req_t* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
DNS_OPCODE_QUERY = 0,
|
DNS_OPCODE_QUERY = 0,
|
||||||
@ -2083,6 +2059,50 @@ struct dns_antrail_t
|
|||||||
#include <qse/unpack.h>
|
#include <qse/unpack.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct dns_ctx_t
|
||||||
|
{
|
||||||
|
qse_httpd_t* httpd;
|
||||||
|
|
||||||
|
qse_skad_t skad;
|
||||||
|
int skadlen;
|
||||||
|
|
||||||
|
qse_uint16_t seq;
|
||||||
|
dns_req_t* reqs[1024]; /* TOOD: choose the right size */
|
||||||
|
dns_ans_t* anss[1024];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dns_req_t
|
||||||
|
{
|
||||||
|
qse_mchar_t* name;
|
||||||
|
|
||||||
|
#define DNS_REQ_A_NX (1 << 0)
|
||||||
|
#define DNS_REQ_AAAA_NX (1 << 1)
|
||||||
|
int flags;
|
||||||
|
qse_uint16_t seqa, seqaaaa;
|
||||||
|
|
||||||
|
qse_uint8_t* dn;
|
||||||
|
qse_size_t dnlen;
|
||||||
|
|
||||||
|
qse_httpd_resol_t resol;
|
||||||
|
void* ctx;
|
||||||
|
|
||||||
|
qse_uint8_t qa[DNS_MAX_DN_LEN + QSE_SIZEOF(dns_hdr_t) + QSE_SIZEOF(dns_qdtrail_t)];
|
||||||
|
qse_uint8_t qaaaa[DNS_MAX_DN_LEN + QSE_SIZEOF(dns_hdr_t) + QSE_SIZEOF(dns_qdtrail_t)];
|
||||||
|
int qalen;
|
||||||
|
int qaaaalen;
|
||||||
|
|
||||||
|
dns_req_t* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dns_ans_t
|
||||||
|
{
|
||||||
|
qse_mchar_t* name;
|
||||||
|
qse_nwad_t nwad;
|
||||||
|
qse_int64_t age;
|
||||||
|
qse_uint32_t ttl;
|
||||||
|
dns_ans_t* next;
|
||||||
|
};
|
||||||
|
|
||||||
#define DN_AT_END(ptr) (ptr[0] == QSE_MT('\0') || (ptr[0] == QSE_MT('.') && ptr[1] == QSE_MT('\0')))
|
#define DN_AT_END(ptr) (ptr[0] == QSE_MT('\0') || (ptr[0] == QSE_MT('.') && ptr[1] == QSE_MT('\0')))
|
||||||
|
|
||||||
static qse_size_t to_dn (const qse_mchar_t* str, qse_uint8_t* buf, qse_size_t bufsz)
|
static qse_size_t to_dn (const qse_mchar_t* str, qse_uint8_t* buf, qse_size_t bufsz)
|
||||||
@ -2191,6 +2211,8 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
|||||||
dc = (dns_ctx_t*) qse_httpd_callocmem (httpd, QSE_SIZEOF(dns_ctx_t));
|
dc = (dns_ctx_t*) qse_httpd_callocmem (httpd, QSE_SIZEOF(dns_ctx_t));
|
||||||
if (dc == NULL) goto oops;
|
if (dc == NULL) goto oops;
|
||||||
|
|
||||||
|
dc->httpd = httpd;
|
||||||
|
|
||||||
/* TODO: add static cache entries from /etc/hosts */
|
/* TODO: add static cache entries from /etc/hosts */
|
||||||
|
|
||||||
nwad = httpd_xtn->dnsnwad;
|
nwad = httpd_xtn->dnsnwad;
|
||||||
@ -2198,7 +2220,7 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
|||||||
{
|
{
|
||||||
qse_sio_t* sio;
|
qse_sio_t* sio;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
/* TODO: */
|
/* TODO: windns.h dnsapi.lib DnsQueryConfig... */
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
#else
|
#else
|
||||||
@ -2295,6 +2317,31 @@ oops:
|
|||||||
|
|
||||||
static void dns_close (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
static void dns_close (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||||
{
|
{
|
||||||
|
dns_ctx_t* dc = (dns_ctx_t*)dns->ctx;
|
||||||
|
qse_size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < QSE_COUNTOF(dc->reqs); i++)
|
||||||
|
{
|
||||||
|
dns_req_t* next_req;
|
||||||
|
while (dc->reqs[i])
|
||||||
|
{
|
||||||
|
next_req = dc->reqs[i]->next;
|
||||||
|
qse_httpd_freemem (httpd, dc->reqs[i]);
|
||||||
|
dc->reqs[i] = next_req;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < QSE_COUNTOF(dc->anss); i++)
|
||||||
|
{
|
||||||
|
dns_ans_t* next_ans;
|
||||||
|
while (dc->anss[i])
|
||||||
|
{
|
||||||
|
next_ans = dc->anss[i]->next;
|
||||||
|
qse_httpd_freemem (httpd, dc->anss[i]);
|
||||||
|
dc->anss[i] = next_ans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
closesocket (dns->handle.i);
|
closesocket (dns->handle.i);
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
@ -2308,22 +2355,112 @@ static void dns_close (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
|||||||
qse_httpd_freemem (httpd, dns->ctx);
|
qse_httpd_freemem (httpd, dns->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long dns_hash_name (const qse_mchar_t *str)
|
||||||
|
{
|
||||||
|
qse_size_t h = 0;
|
||||||
|
while (*str) h = ((h << 5) + h) ^ *str++;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dns_cache_answer (dns_ctx_t* dc, dns_req_t* req, const qse_nwad_t* nwad, qse_uint32_t ttl)
|
||||||
|
{
|
||||||
|
dns_ans_t* ans, * prv, * cur;
|
||||||
|
qse_size_t hid;
|
||||||
|
qse_ntime_t now;
|
||||||
|
|
||||||
|
/* TODO: implement the maximum number of entries in cache... */
|
||||||
|
|
||||||
|
/* i use the given request as a space to hold an answer.
|
||||||
|
* the following assertion must be met for this to work */
|
||||||
|
QSE_ASSERT (QSE_SIZEOF(dns_req_t) >= QSE_SIZEOF(dns_ans_t));
|
||||||
|
|
||||||
|
qse_gettime (&now);
|
||||||
|
|
||||||
|
ans = (dns_ans_t*)req; /* shadow the request with an answer */
|
||||||
|
if (nwad) ans->nwad = *nwad; /* positive */
|
||||||
|
else ans->nwad.type = QSE_NWAD_NX; /* negative */
|
||||||
|
ans->age = now.sec; /* the granularity of a second should be good enough */
|
||||||
|
|
||||||
|
if (ttl < DNS_MIN_TTL) ttl = DNS_MIN_TTL; /* TODO: use configured value */
|
||||||
|
else if (ttl > DNS_MAX_TTL) ttl = DNS_MAX_TTL;
|
||||||
|
|
||||||
|
ans->ttl = ttl;
|
||||||
|
hid = dns_hash_name (req->name) % QSE_COUNTOF(dc->anss);
|
||||||
|
|
||||||
|
prv = QSE_NULL;
|
||||||
|
cur = dc->anss[hid];
|
||||||
|
while (cur)
|
||||||
|
{
|
||||||
|
if (qse_mbscasecmp(cur->name, ans->name) == 0)
|
||||||
|
{
|
||||||
|
ans->next = cur->next;
|
||||||
|
if (prv) prv->next = ans;
|
||||||
|
else dc->anss[hid] = ans;
|
||||||
|
qse_httpd_freemem (dc->httpd, cur);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
prv = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
ans->next = dc->anss[hid];
|
||||||
|
dc->anss[hid] = ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dns_ans_t* dns_get_answer_from_cache (dns_ctx_t* dc, const qse_mchar_t* name)
|
||||||
|
{
|
||||||
|
dns_ans_t* prv, * cur;
|
||||||
|
qse_size_t hid;
|
||||||
|
qse_ntime_t now;
|
||||||
|
|
||||||
|
hid = dns_hash_name (name) % QSE_COUNTOF(dc->anss);
|
||||||
|
|
||||||
|
qse_gettime (&now);
|
||||||
|
|
||||||
|
prv = QSE_NULL;
|
||||||
|
cur = dc->anss[hid];
|
||||||
|
while (cur)
|
||||||
|
{
|
||||||
|
if (qse_mbscasecmp(cur->name, name) == 0)
|
||||||
|
{
|
||||||
|
if (cur->age + cur->ttl < now.sec)
|
||||||
|
{
|
||||||
|
/* entry expired. evict the entry from the cache */
|
||||||
|
if (prv) prv->next = cur->next;
|
||||||
|
else dc->anss[hid] = cur->next;
|
||||||
|
qse_httpd_freemem (dc->httpd, cur);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
prv = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int dns_recv (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
static int dns_recv (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||||
{
|
{
|
||||||
dns_ctx_t* dc = (dns_ctx_t*)dns->ctx;
|
dns_ctx_t* dc = (dns_ctx_t*)dns->ctx;
|
||||||
|
|
||||||
qse_skad_t fromaddr;
|
qse_skad_t fromaddr;
|
||||||
socklen_t fromlen; /* TODO: change type */
|
socklen_t fromlen; /* TODO: change type */
|
||||||
qse_uint8_t buf[384];
|
|
||||||
|
qse_uint8_t buf[DNS_MAX_MSG_LEN];
|
||||||
qse_ssize_t len;
|
qse_ssize_t len;
|
||||||
dns_hdr_t* hdr;
|
dns_hdr_t* hdr;
|
||||||
|
|
||||||
printf ("RECV....\n");
|
printf ("DNS_RECV....\n");
|
||||||
|
|
||||||
|
/* TODO: delete requests that're not replied at all for long time */
|
||||||
|
|
||||||
fromlen = QSE_SIZEOF(fromaddr);
|
fromlen = QSE_SIZEOF(fromaddr);
|
||||||
len = recvfrom (dns->handle.i, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&fromaddr, &fromlen);
|
len = recvfrom (dns->handle.i, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&fromaddr, &fromlen);
|
||||||
|
|
||||||
/* TODO: check if fromaddr matches the dc->skad... */
|
/* TODO: check if fromaddr matches the dc->skad... */
|
||||||
/* TODO: dns caching .... */
|
|
||||||
|
|
||||||
if (len >= QSE_SIZEOF(*hdr))
|
if (len >= QSE_SIZEOF(*hdr))
|
||||||
{
|
{
|
||||||
@ -2345,7 +2482,7 @@ printf ("%d qdcount %d ancount %d\n", id, qdcount, ancount);
|
|||||||
dns_req_t* req = QSE_NULL, * preq = QSE_NULL;
|
dns_req_t* req = QSE_NULL, * preq = QSE_NULL;
|
||||||
qse_size_t reclen;
|
qse_size_t reclen;
|
||||||
|
|
||||||
printf ("finding match req...\n");
|
/* inspect the question section */
|
||||||
for (i = 0; i < qdcount; i++)
|
for (i = 0; i < qdcount; i++)
|
||||||
{
|
{
|
||||||
dnlen = dn_length (plptr, pllen);
|
dnlen = dn_length (plptr, pllen);
|
||||||
@ -2364,7 +2501,6 @@ printf ("finding match req...\n");
|
|||||||
(qdtrail->qtype == qse_hton16(DNS_QTYPE_A) || qdtrail->qtype == qse_hton16(DNS_QTYPE_AAAA)))
|
(qdtrail->qtype == qse_hton16(DNS_QTYPE_A) || qdtrail->qtype == qse_hton16(DNS_QTYPE_AAAA)))
|
||||||
{
|
{
|
||||||
/* found a matching request */
|
/* found a matching request */
|
||||||
printf ("found matching req...\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2374,14 +2510,14 @@ printf ("found matching req...\n");
|
|||||||
pllen -= reclen;
|
pllen -= reclen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req) goto done;
|
if (!req) goto done; /* no matching request for the question */
|
||||||
|
|
||||||
if (hdr->rcode == DNS_RCODE_NOERROR && ancount > 0)
|
if (hdr->rcode == DNS_RCODE_NOERROR && ancount > 0)
|
||||||
{
|
{
|
||||||
dns_antrail_t* antrail;
|
dns_antrail_t* antrail;
|
||||||
qse_uint16_t qtype, anlen;
|
qse_uint16_t qtype, anlen;
|
||||||
|
|
||||||
printf ("checking answers.... pllen => %d\n", (int)pllen);
|
/* inspect the answer section */
|
||||||
for (i = 0; i < ancount; i++)
|
for (i = 0; i < ancount; i++)
|
||||||
{
|
{
|
||||||
if (pllen < 1) goto done;
|
if (pllen < 1) goto done;
|
||||||
@ -2389,7 +2525,6 @@ printf ("checking answers.... pllen => %d\n", (int)pllen);
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
dnlen = dn_length (plptr, pllen);
|
dnlen = dn_length (plptr, pllen);
|
||||||
printf ("........... %d\n", dnlen);
|
|
||||||
if (dnlen <= 0) goto done; /* invalid dn name */
|
if (dnlen <= 0) goto done; /* invalid dn name */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2403,39 +2538,38 @@ printf ("........... %d\n", dnlen);
|
|||||||
qtype = qse_ntoh16(antrail->qtype);
|
qtype = qse_ntoh16(antrail->qtype);
|
||||||
anlen = qse_ntoh16(antrail->dlen);
|
anlen = qse_ntoh16(antrail->dlen);
|
||||||
|
|
||||||
if (antrail->qclass == qse_hton16(DNS_QCLASS_IN))
|
if (qse_ntoh16(antrail->qclass) == DNS_QCLASS_IN)
|
||||||
{
|
|
||||||
if (qtype == DNS_QTYPE_A && anlen == 4)
|
|
||||||
{
|
{
|
||||||
qse_nwad_t nwad;
|
qse_nwad_t nwad;
|
||||||
|
|
||||||
|
nwad.type = QSE_NWAD_NX;
|
||||||
|
|
||||||
|
if (qtype == DNS_QTYPE_A && anlen == 4)
|
||||||
|
{
|
||||||
QSE_MEMSET (&nwad, 0, QSE_SIZEOF(nwad));
|
QSE_MEMSET (&nwad, 0, QSE_SIZEOF(nwad));
|
||||||
nwad.type = QSE_NWAD_IN4;
|
nwad.type = QSE_NWAD_IN4;
|
||||||
QSE_MEMCPY (&nwad.u.in4.addr, antrail + 1, 4);
|
QSE_MEMCPY (&nwad.u.in4.addr, antrail + 1, 4);
|
||||||
printf ("invoking resoll with ipv4 \n");
|
printf ("invoking resoll with ipv4 \n");
|
||||||
req->resol (httpd, req->name, &nwad, req->ctx);
|
|
||||||
|
|
||||||
/* delete the request from dc */
|
|
||||||
if (preq) preq->next = req->next;
|
|
||||||
else dc->reqs[xid] = req->next;
|
|
||||||
qse_httpd_freemem (httpd, req);
|
|
||||||
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
else if (qtype == DNS_QTYPE_AAAA || anlen == 16)
|
else if (qtype == DNS_QTYPE_AAAA && anlen == 16)
|
||||||
{
|
{
|
||||||
qse_nwad_t nwad;
|
|
||||||
|
|
||||||
QSE_MEMSET (&nwad, 0, QSE_SIZEOF(nwad));
|
QSE_MEMSET (&nwad, 0, QSE_SIZEOF(nwad));
|
||||||
nwad.type = QSE_NWAD_IN6;
|
nwad.type = QSE_NWAD_IN6;
|
||||||
QSE_MEMCPY (&nwad.u.in6.addr, antrail + 1, 16);
|
QSE_MEMCPY (&nwad.u.in6.addr, antrail + 1, 16);
|
||||||
printf ("invoking resoll with ipv6 \n");
|
printf ("invoking resoll with ipv6 \n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nwad.type != QSE_NWAD_NX)
|
||||||
|
{
|
||||||
req->resol (httpd, req->name, &nwad, req->ctx);
|
req->resol (httpd, req->name, &nwad, req->ctx);
|
||||||
|
|
||||||
/* delete the request from dc */
|
/* detach the request off dc->reqs */
|
||||||
if (preq) preq->next = req->next;
|
if (preq) preq->next = req->next;
|
||||||
else dc->reqs[xid] = req->next;
|
else dc->reqs[xid] = req->next;
|
||||||
qse_httpd_freemem (httpd, req);
|
|
||||||
|
/*qse_httpd_freemem (httpd, req);*/
|
||||||
|
dns_cache_answer (dc, req, &nwad, qse_ntoh32(antrail->ttl));
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -2445,23 +2579,25 @@ printf ("invoking resoll with ipv6 \n");
|
|||||||
pllen -= reclen;
|
pllen -= reclen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
|
/* no good answer have been found */
|
||||||
if (id == req->seqa) req->flags |= DNS_REQ_A_NX;
|
if (id == req->seqa) req->flags |= DNS_REQ_A_NX;
|
||||||
else if (id == req->seqaaaa) req->flags |= DNS_REQ_AAAA_NX;
|
else if (id == req->seqaaaa) req->flags |= DNS_REQ_AAAA_NX;
|
||||||
|
|
||||||
if ((req->flags & (DNS_REQ_A_NX | DNS_REQ_AAAA_NX)) == (DNS_REQ_A_NX | DNS_REQ_AAAA_NX))
|
if ((req->flags & (DNS_REQ_A_NX | DNS_REQ_AAAA_NX)) == (DNS_REQ_A_NX | DNS_REQ_AAAA_NX))
|
||||||
{
|
{
|
||||||
|
/* both ipv4 and ipv6 address are unresolvable */
|
||||||
|
|
||||||
req->resol (httpd, req->name, QSE_NULL, req->ctx);
|
req->resol (httpd, req->name, QSE_NULL, req->ctx);
|
||||||
|
|
||||||
/* delete the request from dc */
|
/* detach the request off dc->reqs */
|
||||||
if (preq) preq->next = req->next;
|
if (preq) preq->next = req->next;
|
||||||
else dc->reqs[xid] = req->next;
|
else dc->reqs[xid] = req->next;
|
||||||
qse_httpd_freemem (httpd, req);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*req->resol (httpd, req->name, QSE_NULL, req->ctx);*//* TODO: handle this better */
|
/*qse_httpd_freemem (httpd, req);*/
|
||||||
|
dns_cache_answer (dc, req, QSE_NULL, DNS_MIN_TTL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2476,7 +2612,18 @@ static int dns_send (qse_httpd_t* httpd, qse_httpd_dns_t* dns, const qse_mchar_t
|
|||||||
dns_ctx_t* dc = (dns_ctx_t*)dns->ctx;
|
dns_ctx_t* dc = (dns_ctx_t*)dns->ctx;
|
||||||
dns_req_t* req;
|
dns_req_t* req;
|
||||||
qse_size_t name_len;
|
qse_size_t name_len;
|
||||||
|
dns_ans_t* ans;
|
||||||
|
|
||||||
|
printf ("finding answer in cache...\n");
|
||||||
|
ans = dns_get_answer_from_cache (dc, name);
|
||||||
|
if (ans)
|
||||||
|
{
|
||||||
|
printf ("found answer in cache...\n");
|
||||||
|
resol (httpd, name, ((ans->nwad.type == QSE_NWAD_NX)? QSE_NULL: &ans->nwad), ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("found XXXXX in cache...\n");
|
||||||
seq = dc->seq;
|
seq = dc->seq;
|
||||||
seq = (seq + 1) % QSE_COUNTOF(dc->reqs);
|
seq = (seq + 1) % QSE_COUNTOF(dc->reqs);
|
||||||
dc->seq = seq;
|
dc->seq = seq;
|
||||||
@ -3169,7 +3316,6 @@ static int make_resource (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* htrd compacts double slashes to a single slash.
|
/* htrd compacts double slashes to a single slash.
|
||||||
* so inspect if the query path begins with http:/ instead of http:// */
|
* so inspect if the query path begins with http:/ instead of http:// */
|
||||||
/*if (qse_mbszcasecmp (tmp.qpath, QSE_MT("http://"), 7) == 0)*/
|
/*if (qse_mbszcasecmp (tmp.qpath, QSE_MT("http://"), 7) == 0)*/
|
||||||
@ -3190,6 +3336,7 @@ static int make_resource (
|
|||||||
if (qse_mbsntonwad (host, slash - host, &target->u.proxy.dst.nwad) <= -1)
|
if (qse_mbsntonwad (host, slash - host, &target->u.proxy.dst.nwad) <= -1)
|
||||||
{
|
{
|
||||||
/* TODO: refrain from manipulating the request like this */
|
/* TODO: refrain from manipulating the request like this */
|
||||||
|
|
||||||
QSE_MEMMOVE (host - 1, host, slash - host);
|
QSE_MEMMOVE (host - 1, host, slash - host);
|
||||||
slash[-1] = QSE_MT('\0');
|
slash[-1] = QSE_MT('\0');
|
||||||
|
|
||||||
|
@ -904,7 +904,7 @@ static int update_mux_for_current_task (qse_httpd_t* httpd, qse_httpd_client_t*
|
|||||||
|
|
||||||
clear_trigger_mask_result (task);
|
clear_trigger_mask_result (task);
|
||||||
|
|
||||||
printf ("update_mux_for_current_task..............\n");
|
/*printf ("update_mux_for_current_task..............\n");*/
|
||||||
if (QSE_MEMCMP (&client->trigger, &task->trigger, QSE_SIZEOF(client->trigger)) != 0 ||
|
if (QSE_MEMCMP (&client->trigger, &task->trigger, QSE_SIZEOF(client->trigger)) != 0 ||
|
||||||
((client->status & CLIENT_MUTE) && !(client->status & CLIENT_MUTE_DELETED)))
|
((client->status & CLIENT_MUTE) && !(client->status & CLIENT_MUTE_DELETED)))
|
||||||
{
|
{
|
||||||
@ -1070,7 +1070,7 @@ static int update_mux_for_next_task (qse_httpd_t* httpd, qse_httpd_client_t* cli
|
|||||||
int expected_mux_status;
|
int expected_mux_status;
|
||||||
int expected_trigger_cmask;
|
int expected_trigger_cmask;
|
||||||
|
|
||||||
printf ("update_mux_for_next_task\n");
|
/*printf ("update_mux_for_next_task\n");*/
|
||||||
expected_mux_mask = QSE_HTTPD_MUX_READ;
|
expected_mux_mask = QSE_HTTPD_MUX_READ;
|
||||||
expected_mux_status = CLIENT_HANDLE_READ_IN_MUX;
|
expected_mux_status = CLIENT_HANDLE_READ_IN_MUX;
|
||||||
expected_trigger_cmask = QSE_HTTPD_TASK_TRIGGER_READ;
|
expected_trigger_cmask = QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
@ -1422,7 +1422,6 @@ int qse_httpd_loop (qse_httpd_t* httpd)
|
|||||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
{
|
{
|
||||||
qse_httpd_act_t msg;
|
qse_httpd_act_t msg;
|
||||||
qse_size_t len;
|
|
||||||
msg.code = QSE_HTTPD_CATCH_MWARNMSG;
|
msg.code = QSE_HTTPD_CATCH_MWARNMSG;
|
||||||
qse_mbscpy (msg.u.mwarnmsg, QSE_MT("cannot activate dns"));
|
qse_mbscpy (msg.u.mwarnmsg, QSE_MT("cannot activate dns"));
|
||||||
httpd->opt.rcb.logact (httpd, &msg);
|
httpd->opt.rcb.logact (httpd, &msg);
|
||||||
@ -1601,7 +1600,7 @@ int qse_httpd_resolname (qse_httpd_t* httpd, const qse_mchar_t* name, qse_httpd_
|
|||||||
/* TODO: find the name in cache */
|
/* TODO: find the name in cache */
|
||||||
|
|
||||||
/* not found in the cache */
|
/* not found in the cache */
|
||||||
printf ("dns_send.........................\n");
|
printf ("DNS_SEND.........................\n");
|
||||||
if (!httpd->dnsactive)
|
if (!httpd->dnsactive)
|
||||||
{
|
{
|
||||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENODNS);
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENODNS);
|
||||||
@ -1615,11 +1614,9 @@ int qse_httpd_activatetasktrigger (qse_httpd_t* httpd, qse_httpd_client_t* clien
|
|||||||
{
|
{
|
||||||
int x, org_cmask;
|
int x, org_cmask;
|
||||||
|
|
||||||
printf ("activate ..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$..\n");
|
|
||||||
/* don't do anything if it's active */
|
/* don't do anything if it's active */
|
||||||
if (!(task->trigger.flags & QSE_HTTPD_TASK_TRIGGER_INACTIVE)) return 0;
|
if (!(task->trigger.flags & QSE_HTTPD_TASK_TRIGGER_INACTIVE)) return 0;
|
||||||
|
|
||||||
printf ("activate reakly....\n");
|
|
||||||
/* when task trigger is inactive, no handle are registered
|
/* when task trigger is inactive, no handle are registered
|
||||||
* into mux. update_mux_for_current_task adds the client handle
|
* into mux. update_mux_for_current_task adds the client handle
|
||||||
* to mux for reading only if writing is not requested explicitly.
|
* to mux for reading only if writing is not requested explicitly.
|
||||||
|
Loading…
Reference in New Issue
Block a user