enhanced httpd's dns handling
This commit is contained in:
parent
ccb6ddcefd
commit
4f4f42ae4f
@ -142,12 +142,20 @@ enum qse_httpd_serverstd_opt_t
|
||||
};
|
||||
typedef enum qse_httpd_serverstd_opt_t qse_httpd_serverstd_opt_t;
|
||||
|
||||
#define QSE_HTTPD_DNSSTD_DEFAULT_TMOUT 10
|
||||
#define QSE_HTTPD_DNSSTD_DEFAULT_TMOUT 3
|
||||
#define QSE_HTTPD_DNSSTD_DEFAULT_RESENDS 2
|
||||
#define QSE_HTTPD_DNSSTD_DEFAULT_CACHE_TTL 120
|
||||
#define QSE_HTTPD_DNSSTD_DEFAULT_CACHE_NEGTTL 10
|
||||
#define QSE_HTTPD_DNSSTD_DEFAULT_CACHE_MINTTL 2
|
||||
|
||||
struct qse_httpd_dnsstd_t
|
||||
{
|
||||
qse_nwad_t nwad;
|
||||
qse_ntime_t tmout;
|
||||
qse_uint32_t resends;
|
||||
qse_uint32_t cache_ttl;
|
||||
qse_uint32_t cache_minttl; /* minimum ttl */
|
||||
qse_uint32_t cache_negttl; /* negative ttl */
|
||||
};
|
||||
|
||||
typedef struct qse_httpd_dnsstd_t qse_httpd_dnsstd_t;
|
||||
|
@ -170,7 +170,6 @@ void qse_tmr_remove (qse_tmr_t* tmr, qse_size_t index)
|
||||
|
||||
QSE_ASSERT (index < tmr->size);
|
||||
|
||||
printf ("tmr_remove.....>>>>>>>>>>>>size=>%d index=>%d\n", (int)tmr->size, (int)index);
|
||||
item = tmr->event[index];
|
||||
tmr->event[index].updater (tmr, index, QSE_TMR_INVALID, tmr->event[index].ctx);
|
||||
|
||||
@ -187,7 +186,6 @@ qse_size_t qse_tmr_insert (qse_tmr_t* tmr, const qse_tmr_event_t* event)
|
||||
{
|
||||
qse_size_t index = tmr->size;
|
||||
|
||||
printf ("tmr_insert ......size => %d\n", (int)tmr->size);
|
||||
if (index >= tmr->capa)
|
||||
{
|
||||
qse_tmr_event_t* tmp;
|
||||
|
@ -35,13 +35,14 @@ struct task_proxy_arg_t
|
||||
typedef struct task_proxy_t task_proxy_t;
|
||||
struct task_proxy_t
|
||||
{
|
||||
#define PROXY_INIT_FAILED (1 << 0)
|
||||
#define PROXY_RAW (1 << 1)
|
||||
#define PROXY_RESOL_PEER_NAME (1 << 2)
|
||||
#define PROXY_UNKNOWN_PEER_NWAD (1 << 3)
|
||||
#define PROXY_X_FORWARDED_FOR (1 << 4)
|
||||
#define PROXY_VIA (1 << 5)
|
||||
#define PROXY_VIA_RETURNING (1 << 6)
|
||||
#define PROXY_INIT_FAILED (1 << 0)
|
||||
#define PROXY_RAW (1 << 1)
|
||||
#define PROXY_RESOLVE_PEER_NAME (1 << 2)
|
||||
#define PROXY_PEER_NAME_RESOLVED (1 << 3)
|
||||
#define PROXY_PEER_NAME_UNRESOLVED (1 << 4)
|
||||
#define PROXY_X_FORWARDED_FOR (1 << 5)
|
||||
#define PROXY_VIA (1 << 6)
|
||||
#define PROXY_VIA_RETURNING (1 << 7)
|
||||
int flags;
|
||||
qse_httpd_t* httpd;
|
||||
qse_httpd_client_t* client;
|
||||
@ -907,7 +908,7 @@ static int task_init_proxy (
|
||||
{
|
||||
qse_mchar_t* colon;
|
||||
|
||||
proxy->flags |= PROXY_RESOL_PEER_NAME;
|
||||
proxy->flags |= PROXY_RESOLVE_PEER_NAME;
|
||||
proxy->peer_name = proxy->pseudonym + len + 1;
|
||||
qse_mbscpy (proxy->peer_name, arg->rsrc->dst.str);
|
||||
|
||||
@ -1794,9 +1795,10 @@ static void on_peer_name_resolved (qse_httpd_t* httpd, const qse_mchar_t* name,
|
||||
qse_httpd_task_t* task = (qse_httpd_task_t*)ctx;
|
||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||
|
||||
QSE_ASSERT (proxy->flags & PROXY_RESOL_PEER_NAME);
|
||||
QSE_ASSERT (proxy->flags & PROXY_RESOLVE_PEER_NAME);
|
||||
QSE_ASSERT (!(proxy->flags & (PROXY_PEER_NAME_RESOLVED | PROXY_PEER_NAME_UNRESOLVED)));
|
||||
|
||||
proxy->flags &= ~PROXY_RESOL_PEER_NAME;
|
||||
proxy->flags &= ~PROXY_RESOLVE_PEER_NAME;
|
||||
|
||||
if (nwad)
|
||||
{
|
||||
@ -1807,11 +1809,13 @@ static void on_peer_name_resolved (qse_httpd_t* httpd, const qse_mchar_t* name,
|
||||
|
||||
if (proxy->peer.local.type == QSE_NWAD_NX)
|
||||
proxy->peer.local.type = proxy->peer.nwad.type;
|
||||
|
||||
proxy->flags |= PROXY_PEER_NAME_RESOLVED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* resolution failure. */
|
||||
proxy->flags |= PROXY_INIT_FAILED | PROXY_UNKNOWN_PEER_NWAD;
|
||||
proxy->flags |= PROXY_INIT_FAILED | PROXY_PEER_NAME_UNRESOLVED;
|
||||
}
|
||||
|
||||
if (qse_httpd_activatetasktrigger (httpd, proxy->client, task) <= -1)
|
||||
@ -1832,13 +1836,28 @@ static int task_main_proxy (
|
||||
|
||||
if (proxy->flags & PROXY_INIT_FAILED)
|
||||
{
|
||||
if (proxy->flags & PROXY_UNKNOWN_PEER_NWAD) http_errnum = 404; /* 404 Not Found */
|
||||
if (proxy->flags & PROXY_PEER_NAME_UNRESOLVED) http_errnum = 404; /* 404 Not Found */
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (proxy->flags & PROXY_RESOL_PEER_NAME)
|
||||
#if 0
|
||||
if (proxy->flags & PROXY_REWRITE_URL)
|
||||
{
|
||||
if (qse_httpd_rewriteurl (httpd, proxy->url, on_url_rewritten, task) <= -1) goto oops;
|
||||
|
||||
if (proxy->flags & PROXY_INIT_FAILED) goto oops;
|
||||
|
||||
if ((proxy->flags & PROXY_RESOL_REWRITE_URL) &&
|
||||
qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1) goto oops;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (proxy->flags & PROXY_RESOLVE_PEER_NAME)
|
||||
{
|
||||
/* arrange to resolve a host name and return */
|
||||
|
||||
QSE_ASSERT (proxy->peer_name != QSE_NULL);
|
||||
|
||||
if (qse_httpd_resolname (httpd, proxy->peer_name, on_peer_name_resolved, task) <= -1) goto oops;
|
||||
@ -1848,11 +1867,12 @@ static int task_main_proxy (
|
||||
* called. */
|
||||
if (proxy->flags & PROXY_INIT_FAILED)
|
||||
{
|
||||
if (proxy->flags & PROXY_UNKNOWN_PEER_NWAD) http_errnum = 404; /* 404 Not Found */
|
||||
if (proxy->flags & PROXY_PEER_NAME_UNRESOLVED) http_errnum = 404; /* 404 Not Found */
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if ((proxy->flags & PROXY_RESOL_PEER_NAME) &&
|
||||
/* peer name is not resolved yet. */
|
||||
if (!(proxy->flags & PROXY_PEER_NAME_RESOLVED) &&
|
||||
qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1) goto oops;
|
||||
|
||||
return 1;
|
||||
|
@ -2113,6 +2113,7 @@ struct dns_antrail_t
|
||||
struct dns_ctx_t
|
||||
{
|
||||
qse_httpd_t* httpd;
|
||||
qse_httpd_dns_t* dns;
|
||||
|
||||
qse_skad_t skad;
|
||||
int skadlen;
|
||||
@ -2144,6 +2145,7 @@ struct dns_req_t
|
||||
|
||||
dns_ctx_t* dc;
|
||||
qse_size_t tmr_tmout;
|
||||
int resends;
|
||||
|
||||
dns_req_t* next;
|
||||
};
|
||||
@ -2267,6 +2269,7 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||
if (dc == NULL) goto oops;
|
||||
|
||||
dc->httpd = httpd;
|
||||
dc->dns = dns;
|
||||
|
||||
/* TODO: add static cache entries from /etc/hosts */
|
||||
|
||||
@ -2506,6 +2509,7 @@ static dns_ans_t* dns_get_answer_from_cache (dns_ctx_t* dc, const qse_mchar_t* n
|
||||
static int dns_recv (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||
{
|
||||
dns_ctx_t* dc = (dns_ctx_t*)dns->ctx;
|
||||
httpd_xtn_t* httpd_xtn;
|
||||
|
||||
qse_skad_t fromaddr;
|
||||
socklen_t fromlen;
|
||||
@ -2516,7 +2520,7 @@ static int dns_recv (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||
|
||||
printf ("DNS_RECV....\n");
|
||||
|
||||
/* TODO: delete requests that're not replied at all for long time */
|
||||
httpd_xtn = qse_httpd_getxtn (httpd);
|
||||
|
||||
fromlen = QSE_SIZEOF(fromaddr);
|
||||
len = recvfrom (dns->handle.i, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&fromaddr, &fromlen);
|
||||
@ -2534,7 +2538,6 @@ printf ("DNS_RECV....\n");
|
||||
|
||||
xid = (id >= QSE_COUNTOF(dc->reqs))? (id - QSE_COUNTOF(dc->reqs)): id;
|
||||
|
||||
printf ("%d qdcount %d ancount %d\n", id, qdcount, ancount);
|
||||
if (xid >= 0 && xid < QSE_COUNTOF(dc->reqs) && hdr->qr && hdr->opcode == DNS_OPCODE_QUERY && qdcount >= 1)
|
||||
{
|
||||
qse_uint8_t* plptr = (qse_uint8_t*)(hdr + 1);
|
||||
@ -2622,6 +2625,8 @@ printf ("invoking resoll with ipv6 \n");
|
||||
|
||||
if (nwad.type != QSE_NWAD_NX)
|
||||
{
|
||||
int ttl;
|
||||
|
||||
dns_remove_tmr_tmout (req);
|
||||
req->resol (httpd, req->name, &nwad, req->ctx);
|
||||
|
||||
@ -2630,7 +2635,10 @@ printf ("invoking resoll with ipv6 \n");
|
||||
else dc->reqs[xid] = req->next;
|
||||
|
||||
/*qse_httpd_freemem (httpd, req);*/
|
||||
dns_cache_answer (dc, req, &nwad, qse_ntoh32(antrail->ttl));
|
||||
ttl = httpd_xtn->dns.cache_ttl;
|
||||
if (ttl > qse_ntoh32(antrail->ttl)) ttl = qse_ntoh32(antrail->ttl);
|
||||
if (ttl < httpd_xtn->dns.cache_minttl) ttl = httpd_xtn->dns.cache_minttl;
|
||||
dns_cache_answer (dc, req, &nwad, ttl);
|
||||
|
||||
goto done;
|
||||
}
|
||||
@ -2656,7 +2664,7 @@ printf ("invoking resoll with ipv6 \n");
|
||||
else dc->reqs[xid] = req->next;
|
||||
|
||||
/*qse_httpd_freemem (httpd, req);*/
|
||||
dns_cache_answer (dc, req, QSE_NULL, DNS_MIN_TTL);
|
||||
dns_cache_answer (dc, req, QSE_NULL, httpd_xtn->dns.cache_negttl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2677,10 +2685,44 @@ printf (">>tmr_dns_tmout_updated %d %d\n", (int)req->tmr_tmout, (int)old_index);
|
||||
static void tmr_dns_tmout_handle (qse_tmr_t* tmr, const qse_ntime_t* now, void* ctx)
|
||||
{
|
||||
/* destory the unanswered request if timed out */
|
||||
|
||||
dns_req_t* req = (dns_req_t*)ctx;
|
||||
dns_req_t* preq, * xreq;
|
||||
qse_uint16_t xid;
|
||||
|
||||
/* when this handler is called, the event should be removed from the timer */
|
||||
QSE_ASSERT (req->tmr_tmout == QSE_TMR_INVALID);
|
||||
|
||||
/* TODO: resend?? + reschedule?? */
|
||||
if (req->resends > 0)
|
||||
{
|
||||
httpd_xtn_t* httpd_xtn;
|
||||
qse_tmr_event_t tmout_event;
|
||||
|
||||
httpd_xtn = qse_httpd_getxtn (req->dc->httpd);
|
||||
|
||||
qse_gettime (&tmout_event.when);
|
||||
qse_addtime (&tmout_event.when, &httpd_xtn->dns.tmout, &tmout_event.when);
|
||||
tmout_event.ctx = req;
|
||||
tmout_event.handler = tmr_dns_tmout_handle;
|
||||
tmout_event.updater = tmr_dns_tmout_updated;
|
||||
|
||||
if ((!(req->flags & DNS_REQ_A_NX) && req->qalen > 0 && sendto (req->dc->dns->handle.i, req->qa, req->qalen, 0, (struct sockaddr*)&req->dc->skad, req->dc->skadlen) != req->qalen) ||
|
||||
(!(req->flags & DNS_REQ_AAAA_NX) && req->qaaaalen > 0 && sendto (req->dc->dns->handle.i, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&req->dc->skad, req->dc->skadlen) != req->qaaaalen))
|
||||
{
|
||||
/* error. fall thru */
|
||||
}
|
||||
else
|
||||
{
|
||||
req->tmr_tmout = qse_tmr_insert (req->dc->httpd->tmr, &tmout_event);
|
||||
if (req->tmr_tmout != QSE_TMR_INVALID)
|
||||
{
|
||||
req->resends--;
|
||||
return; /* resend ok */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf ("dns timed out....\n");
|
||||
xid = req->seqa;
|
||||
QSE_ASSERT (xid >= 0 && QSE_COUNTOF(req->dc->reqs));
|
||||
@ -2690,32 +2732,32 @@ printf ("dns timed out....\n");
|
||||
if (req == xreq) break;
|
||||
}
|
||||
|
||||
/* this request that timed out must be inside the request list */
|
||||
QSE_ASSERT (req == xreq);
|
||||
|
||||
/* detach the request off dc->reqs */
|
||||
if (preq) preq->next = req->next;
|
||||
else req->dc->reqs[xid] = req->next;
|
||||
|
||||
QSE_ASSERT (req->tmr_tmout == QSE_TMR_INVALID);
|
||||
|
||||
/* dns timed out. report that name resolution failed */
|
||||
req->resol (req->dc->httpd, req->name, QSE_NULL, req->ctx);
|
||||
|
||||
/* i don't cache the items that have timed out */
|
||||
qse_httpd_freemem (req->dc->httpd, req);
|
||||
|
||||
}
|
||||
|
||||
static int dns_send (qse_httpd_t* httpd, qse_httpd_dns_t* dns, const qse_mchar_t* name, qse_httpd_resol_t resol, void* ctx)
|
||||
{
|
||||
dns_ctx_t* dc = (dns_ctx_t*)dns->ctx;
|
||||
httpd_xtn_t* httpd_xtn = qse_httpd_getxtn (httpd);
|
||||
httpd_xtn_t* httpd_xtn;
|
||||
|
||||
qse_uint32_t seq;
|
||||
dns_req_t* req;
|
||||
qse_size_t name_len;
|
||||
dns_ans_t* ans;
|
||||
qse_tmr_event_t tmout_event;
|
||||
|
||||
|
||||
httpd_xtn = qse_httpd_getxtn (httpd);
|
||||
|
||||
printf ("DNS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
ans = dns_get_answer_from_cache (dc, name);
|
||||
@ -2775,8 +2817,7 @@ printf ("DNS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
tmout_event.ctx = req;
|
||||
tmout_event.handler = tmr_dns_tmout_handle;
|
||||
tmout_event.updater = tmr_dns_tmout_updated;
|
||||
|
||||
printf ("ABOUT TO REGISTER TMR_TMOUT...\n");
|
||||
|
||||
req->tmr_tmout = qse_tmr_insert (httpd->tmr, &tmout_event);
|
||||
if (req->tmr_tmout == QSE_TMR_INVALID)
|
||||
{
|
||||
@ -2784,7 +2825,7 @@ printf ("ABOUT TO REGISTER TMR_TMOUT...\n");
|
||||
qse_httpd_freemem (httpd, req);
|
||||
return -1;
|
||||
}
|
||||
printf ("???? initial tmr_tmout => %d\n", (int)req->tmr_tmout);
|
||||
req->resends = httpd_xtn->dns.resends;
|
||||
|
||||
if ((req->qalen > 0 && sendto (dns->handle.i, req->qa, req->qalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qalen) ||
|
||||
(req->qaaaalen > 0 && sendto (dns->handle.i, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qaaaalen))
|
||||
@ -2837,7 +2878,6 @@ static int process_request (
|
||||
* non-peek mode as well */
|
||||
if (peek) qse_perdechttpstr (qse_htre_getqpath(req), qse_htre_getqpath(req));
|
||||
|
||||
|
||||
if (peek && (httpd->opt.trait & QSE_HTTPD_LOGACT))
|
||||
{
|
||||
/* TODO: improve logging */
|
||||
@ -4070,6 +4110,11 @@ int qse_httpd_loopstd (qse_httpd_t* httpd, const qse_httpd_dnsstd_t* dns)
|
||||
{
|
||||
httpd_xtn->dns.nwad.type = QSE_NWAD_NX;
|
||||
httpd_xtn->dns.tmout.sec = QSE_HTTPD_DNSSTD_DEFAULT_TMOUT;
|
||||
httpd_xtn->dns.tmout.nsec = 0;
|
||||
httpd_xtn->dns.resends = QSE_HTTPD_DNSSTD_DEFAULT_RESENDS;
|
||||
httpd_xtn->dns.cache_ttl = QSE_HTTPD_DNSSTD_DEFAULT_CACHE_TTL;
|
||||
httpd_xtn->dns.cache_minttl = QSE_HTTPD_DNSSTD_DEFAULT_CACHE_MINTTL;
|
||||
httpd_xtn->dns.cache_negttl = QSE_HTTPD_DNSSTD_DEFAULT_CACHE_NEGTTL;
|
||||
}
|
||||
|
||||
return qse_httpd_loop (httpd);
|
||||
|
@ -185,6 +185,7 @@ static qse_httpd_task_t* entask_status (
|
||||
switch (code)
|
||||
{
|
||||
case 301:
|
||||
case 302:
|
||||
case 307:
|
||||
{
|
||||
status_reloc_t* reloc;
|
||||
|
@ -1681,6 +1681,13 @@ printf ("DNS_SEND.........................\n");
|
||||
return httpd->opt.scb.dns.send (httpd, &httpd->dns, name, resol, ctx);
|
||||
}
|
||||
|
||||
#if 0
|
||||
int qse_httpd_rewriteurl (qse_httpd_t* httpd, const qse_mchar_t* url, qse_httpd_rewrite_t rewrite, void* ctx)
|
||||
{
|
||||
return httpd->opt.scb.url.send (httpd, &httpd->dns, name, resol, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
int qse_httpd_activatetasktrigger (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
||||
{
|
||||
int x, org_cmask;
|
||||
|
Loading…
Reference in New Issue
Block a user