enhanced httpd's dns handling
This commit is contained in:
		| @ -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; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user