handled dns timeout in httpd
This commit is contained in:
		| @ -57,6 +57,9 @@ struct qse_tmr_event_t | |||||||
|  |  | ||||||
| #define QSE_TMR_INVALID ((qse_size_t)-1) | #define QSE_TMR_INVALID ((qse_size_t)-1) | ||||||
|  |  | ||||||
|  | #define QSE_TMR_SIZE(tmr) ((tmr)->size) | ||||||
|  | #define QSE_TMR_CAPA(tmr) ((tmr)->capa); | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -423,7 +423,6 @@ struct qse_httpd_client_t | |||||||
| 	qse_ntime_t              last_active; | 	qse_ntime_t              last_active; | ||||||
|  |  | ||||||
| 	qse_size_t               tmr_idle; | 	qse_size_t               tmr_idle; | ||||||
| 	qse_size_t               tmr_dns; |  | ||||||
|  |  | ||||||
| 	qse_httpd_client_t*      prev; | 	qse_httpd_client_t*      prev; | ||||||
| 	qse_httpd_client_t*      next; | 	qse_httpd_client_t*      next; | ||||||
|  | |||||||
| @ -142,6 +142,16 @@ enum qse_httpd_serverstd_opt_t | |||||||
| }; | }; | ||||||
| typedef enum qse_httpd_serverstd_opt_t qse_httpd_serverstd_opt_t; | typedef enum qse_httpd_serverstd_opt_t qse_httpd_serverstd_opt_t; | ||||||
|  |  | ||||||
|  | #define QSE_HTTPD_DNSSTD_DEFAULT_TMOUT 10 | ||||||
|  |  | ||||||
|  | struct qse_httpd_dnsstd_t | ||||||
|  | { | ||||||
|  | 	qse_nwad_t nwad; | ||||||
|  | 	qse_ntime_t tmout; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef struct qse_httpd_dnsstd_t qse_httpd_dnsstd_t; | ||||||
|  |  | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| @ -197,7 +207,7 @@ QSE_EXPORT void* qse_httpd_getserverstdxtn ( | |||||||
|  |  | ||||||
| QSE_EXPORT int qse_httpd_loopstd ( | QSE_EXPORT int qse_httpd_loopstd ( | ||||||
| 	qse_httpd_t*              httpd, | 	qse_httpd_t*              httpd, | ||||||
| 	const qse_nwad_t*  dnsnwad | 	const qse_httpd_dnsstd_t* dns | ||||||
| ); | ); | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  | |||||||
| @ -287,32 +287,6 @@ | |||||||
| #	define QSE_STRUCT_FIELD(id,value) value | #	define QSE_STRUCT_FIELD(id,value) value | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifdef NDEBUG |  | ||||||
| #	define QSE_ASSERT(expr) ((void)0) |  | ||||||
| #	define QSE_ASSERTX(expr,desc) ((void)0) |  | ||||||
| #else |  | ||||||
| #	ifdef __cplusplus |  | ||||||
| 		extern "C" { |  | ||||||
| #	endif |  | ||||||
| 		QSE_EXPORT void qse_assert_failed ( |  | ||||||
|         		const qse_char_t* expr, const qse_char_t* desc, |  | ||||||
|         		const qse_char_t* file, qse_size_t line); |  | ||||||
| #	ifdef __cplusplus |  | ||||||
| 		} |  | ||||||
| #	endif |  | ||||||
|  |  | ||||||
| #	define QSE_ASSERT(expr) (void)((expr) || \ |  | ||||||
| 		(qse_assert_failed (QSE_T(#expr), QSE_NULL, QSE_T(__FILE__), __LINE__), 0)) |  | ||||||
| #	define QSE_ASSERTX(expr,desc) (void)((expr) || \ |  | ||||||
| 		(qse_assert_failed (QSE_T(#expr), QSE_T(desc), QSE_T(__FILE__), __LINE__), 0)) |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| #	define QSE_BEGIN_NAMESPACE(x)    namespace x { |  | ||||||
| #	define QSE_END_NAMESPACE(x)      } |  | ||||||
| #	define QSE_BEGIN_NAMESPACE2(x,y) namespace x { namespace y { |  | ||||||
| #	define QSE_END_NAMESPACE2(y,x)   }} |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * The QSE_XTN() macro is a convenience macro to retrieve the pointer to  |  * The QSE_XTN() macro is a convenience macro to retrieve the pointer to  | ||||||
| @ -321,4 +295,39 @@ | |||||||
|  */ |  */ | ||||||
| #define QSE_XTN(obj) ((void*)(obj + 1)) | #define QSE_XTN(obj) ((void*)(obj + 1)) | ||||||
|  |  | ||||||
|  | /* ----------------------------------------------------------------------  | ||||||
|  |  * ASSERTION  | ||||||
|  |  * ---------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
|  | #ifdef NDEBUG | ||||||
|  | #	define QSE_ASSERT(expr) ((void)0) | ||||||
|  | #	define QSE_ASSERTX(expr,desc) ((void)0) | ||||||
|  | #else | ||||||
|  |  | ||||||
|  | #	define QSE_ASSERT(expr) (void)((expr) || \ | ||||||
|  | 		(qse_assert_failed (QSE_T(#expr), QSE_NULL, QSE_T(__FILE__), __LINE__), 0)) | ||||||
|  | #	define QSE_ASSERTX(expr,desc) (void)((expr) || \ | ||||||
|  | 		(qse_assert_failed (QSE_T(#expr), QSE_T(desc), QSE_T(__FILE__), __LINE__), 0)) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | QSE_EXPORT void qse_assert_failed ( | ||||||
|  | 	const qse_char_t* expr, const qse_char_t* desc, | ||||||
|  | 	const qse_char_t* file, qse_size_t line); | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /* ----------------------------------------------------------------------  | ||||||
|  |  * C++ NAMESPACE | ||||||
|  |  * ---------------------------------------------------------------------- */ | ||||||
|  | #ifdef __cplusplus | ||||||
|  | #	define QSE_BEGIN_NAMESPACE(x)    namespace x { | ||||||
|  | #	define QSE_END_NAMESPACE(x)      } | ||||||
|  | #	define QSE_BEGIN_NAMESPACE2(x,y) namespace x { namespace y { | ||||||
|  | #	define QSE_END_NAMESPACE2(y,x)   }} | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -20,9 +20,6 @@ | |||||||
|  |  | ||||||
| #include <qse/types.h> | #include <qse/types.h> | ||||||
| #include <qse/macros.h> | #include <qse/macros.h> | ||||||
|  |  | ||||||
| #if !defined(NDEBUG) |  | ||||||
|  |  | ||||||
| #include <qse/cmn/sio.h> | #include <qse/cmn/sio.h> | ||||||
| #include "mem.h" | #include "mem.h" | ||||||
|  |  | ||||||
| @ -253,5 +250,3 @@ done: | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -85,9 +85,11 @@ void* qse_tmr_getxtn (qse_tmr_t* tmr) | |||||||
| void qse_tmr_clear (qse_tmr_t* tmr) | void qse_tmr_clear (qse_tmr_t* tmr) | ||||||
| { | { | ||||||
| 	tmr->size = 0; | 	tmr->size = 0; | ||||||
|  |  | ||||||
|  | /* TOOD: use tmr_remove for notification.... */ | ||||||
| } | } | ||||||
|  |  | ||||||
| static qse_size_t sift_up (qse_tmr_t* tmr, qse_size_t index) | static qse_size_t sift_up (qse_tmr_t* tmr, qse_size_t index, int notify) | ||||||
| { | { | ||||||
| 	qse_size_t parent; | 	qse_size_t parent; | ||||||
|  |  | ||||||
| @ -109,15 +111,18 @@ static qse_size_t sift_up (qse_tmr_t* tmr, qse_size_t index) | |||||||
| 		} | 		} | ||||||
| 		while (index > 0 && YOUNGER_THAN(&item, &tmr->event[parent])); | 		while (index > 0 && YOUNGER_THAN(&item, &tmr->event[parent])); | ||||||
|  |  | ||||||
|  | 		/* we send no notification if the item is added with qse_tmr_insert() | ||||||
|  | 		 * or updated with qse_tmr_update(). the caller of the funnctions must | ||||||
|  | 		 * reply on the return value. */ | ||||||
| 		tmr->event[index] = item; | 		tmr->event[index] = item; | ||||||
| 		if (index != old_index) | 		if (notify && index != old_index) | ||||||
| 			tmr->event[index].updater (tmr, old_index, index, tmr->event[index].ctx); | 			tmr->event[index].updater (tmr, old_index, index, tmr->event[index].ctx); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return index; | 	return index; | ||||||
| } | } | ||||||
|  |  | ||||||
| static qse_size_t sift_down (qse_tmr_t* tmr, qse_size_t index) | static qse_size_t sift_down (qse_tmr_t* tmr, qse_size_t index, int notify) | ||||||
| { | { | ||||||
| 	qse_size_t base = tmr->size / 2; | 	qse_size_t base = tmr->size / 2; | ||||||
|  |  | ||||||
| @ -152,7 +157,7 @@ static qse_size_t sift_down (qse_tmr_t* tmr, qse_size_t index) | |||||||
| 		while (index < base); | 		while (index < base); | ||||||
| 		 | 		 | ||||||
| 		tmr->event[index] = item; | 		tmr->event[index] = item; | ||||||
| 		if (index != old_index) | 		if (notify && index != old_index) | ||||||
| 			tmr->event[index].updater (tmr, old_index, index, tmr->event[index].ctx); | 			tmr->event[index].updater (tmr, old_index, index, tmr->event[index].ctx); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -165,22 +170,24 @@ void qse_tmr_remove (qse_tmr_t* tmr, qse_size_t index) | |||||||
|  |  | ||||||
| 	QSE_ASSERT (index < tmr->size); | 	QSE_ASSERT (index < tmr->size); | ||||||
|  |  | ||||||
|  | printf ("tmr_remove.....>>>>>>>>>>>>size=>%d index=>%d\n", (int)tmr->size, (int)index); | ||||||
| 	item = tmr->event[index]; | 	item = tmr->event[index]; | ||||||
| 	tmr->event[index].updater (tmr, index, QSE_TMR_INVALID, tmr->event[index].ctx); | 	tmr->event[index].updater (tmr, index, QSE_TMR_INVALID, tmr->event[index].ctx); | ||||||
|  |  | ||||||
| 	tmr->size = tmr->size - 1; | 	tmr->size = tmr->size - 1; | ||||||
| 	if (tmr->size > 0) | 	if (tmr->size > 0 && index != tmr->size) | ||||||
| 	{ | 	{ | ||||||
| 		tmr->event[index] = tmr->event[tmr->size]; | 		tmr->event[index] = tmr->event[tmr->size]; | ||||||
| 		tmr->event[index].updater (tmr, tmr->size, index, tmr->event[index].ctx); | 		tmr->event[index].updater (tmr, tmr->size, index, tmr->event[index].ctx); | ||||||
| 		YOUNGER_THAN(&tmr->event[index], &item)? sift_up(tmr, index): sift_down(tmr, index); | 		YOUNGER_THAN(&tmr->event[index], &item)? sift_up(tmr, index, 1): sift_down(tmr, index, 1); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| qse_size_t qse_tmr_insert (qse_tmr_t* tmr, const qse_tmr_event_t* event) | qse_size_t qse_tmr_insert (qse_tmr_t* tmr, const qse_tmr_event_t* event) | ||||||
| { | { | ||||||
| 	qse_size_t index = tmr->size; | 	qse_size_t index = tmr->size; | ||||||
|  |  | ||||||
|  | printf ("tmr_insert ......size => %d\n", (int)tmr->size); | ||||||
| 	if (index >= tmr->capa) | 	if (index >= tmr->capa) | ||||||
| 	{ | 	{ | ||||||
| 		qse_tmr_event_t* tmp; | 		qse_tmr_event_t* tmp; | ||||||
| @ -196,7 +203,7 @@ qse_size_t qse_tmr_insert (qse_tmr_t* tmr, const qse_tmr_event_t* event) | |||||||
|  |  | ||||||
| 	tmr->size = tmr->size + 1; | 	tmr->size = tmr->size + 1; | ||||||
| 	tmr->event[index] = *event; | 	tmr->event[index] = *event; | ||||||
| 	return sift_up (tmr, index); | 	return sift_up (tmr, index, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| qse_size_t qse_tmr_update (qse_tmr_t* tmr, qse_size_t index, const qse_tmr_event_t* event) | qse_size_t qse_tmr_update (qse_tmr_t* tmr, qse_size_t index, const qse_tmr_event_t* event) | ||||||
| @ -205,7 +212,7 @@ qse_size_t qse_tmr_update (qse_tmr_t* tmr, qse_size_t index, const qse_tmr_event | |||||||
|  |  | ||||||
| 	item = tmr->event[index]; | 	item = tmr->event[index]; | ||||||
| 	tmr->event[index] = *event; | 	tmr->event[index] = *event; | ||||||
| 	return YOUNGER_THAN(event, &item)? sift_up (tmr, index): sift_down (tmr, index); | 	return YOUNGER_THAN(event, &item)? sift_up (tmr, index, 0): sift_down (tmr, index, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| qse_size_t qse_tmr_fire (qse_tmr_t* tmr, const qse_ntime_t* tm) | qse_size_t qse_tmr_fire (qse_tmr_t* tmr, const qse_ntime_t* tm) | ||||||
| @ -245,5 +252,7 @@ int qse_tmr_gettmout (qse_tmr_t* tmr, const qse_ntime_t* tm, qse_ntime_t* tmout) | |||||||
|  |  | ||||||
| 	qse_subtime (&tmr->event[0].when, &now, tmout); | 	qse_subtime (&tmr->event[0].when, &now, tmout); | ||||||
| 	if (tmout->sec < 0) qse_cleartime (tmout); | 	if (tmout->sec < 0) qse_cleartime (tmout); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -542,7 +542,7 @@ struct httpd_xtn_t | |||||||
| 	SSL_CTX* ssl_ctx; | 	SSL_CTX* ssl_ctx; | ||||||
| #endif | #endif | ||||||
| 	qse_httpd_ecb_t ecb; | 	qse_httpd_ecb_t ecb; | ||||||
| 	qse_nwad_t dnsnwad; | 	qse_httpd_dnsstd_t dns; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #if defined(HAVE_SSL) | #if defined(HAVE_SSL) | ||||||
| @ -612,9 +612,10 @@ static void fini_xtn_ssl (httpd_xtn_t* xtn) | |||||||
|  |  | ||||||
| static void cleanup_standard_httpd (qse_httpd_t* httpd) | static void cleanup_standard_httpd (qse_httpd_t* httpd) | ||||||
| { | { | ||||||
| #if defined(HAVE_SSL) |  | ||||||
| 	httpd_xtn_t* xtn; | 	httpd_xtn_t* xtn; | ||||||
| 	xtn = (httpd_xtn_t*)qse_httpd_getxtn (httpd); | 	xtn = (httpd_xtn_t*)qse_httpd_getxtn (httpd); | ||||||
|  |  | ||||||
|  | #if defined(HAVE_SSL) | ||||||
| 	if (xtn->ssl_ctx) fini_xtn_ssl (xtn); | 	if (xtn->ssl_ctx) fini_xtn_ssl (xtn); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| @ -656,6 +657,7 @@ void* qse_httpd_getxtnstd (qse_httpd_t* httpd) | |||||||
| 	typedef int sock_t; | 	typedef int sock_t; | ||||||
| #	define SOCK_INIT -1 | #	define SOCK_INIT -1 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if !defined(HAVE_SOCKLEN_T) | #if !defined(HAVE_SOCKLEN_T) | ||||||
| 	typedef int socklen_t; | 	typedef int socklen_t; | ||||||
| #endif | #endif | ||||||
| @ -2140,6 +2142,9 @@ struct dns_req_t | |||||||
| 	int qalen; | 	int qalen; | ||||||
| 	int qaaaalen; | 	int qaaaalen; | ||||||
|  |  | ||||||
|  | 	dns_ctx_t* dc; | ||||||
|  | 	qse_size_t tmr_tmout; | ||||||
|  |  | ||||||
| 	dns_req_t* next; | 	dns_req_t* next; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -2265,7 +2270,7 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns) | |||||||
|  |  | ||||||
| /* TODO: add static cache entries from /etc/hosts */ | /* TODO: add static cache entries from /etc/hosts */ | ||||||
|  |  | ||||||
| 	nwad = httpd_xtn->dnsnwad; | 	nwad = httpd_xtn->dns.nwad; | ||||||
| 	if (nwad.type == QSE_NWAD_NX) | 	if (nwad.type == QSE_NWAD_NX) | ||||||
| 	{ | 	{ | ||||||
| 		qse_sio_t* sio; | 		qse_sio_t* sio; | ||||||
| @ -2361,6 +2366,15 @@ oops: | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void dns_remove_tmr_tmout (dns_req_t* req) | ||||||
|  | { | ||||||
|  | 	if (req->tmr_tmout != QSE_TMR_INVALID) | ||||||
|  | 	{ | ||||||
|  | 		qse_tmr_remove (req->dc->httpd->tmr, req->tmr_tmout); | ||||||
|  | 		req->tmr_tmout = QSE_TMR_INVALID; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| 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; | 	dns_ctx_t* dc = (dns_ctx_t*)dns->ctx; | ||||||
| @ -2372,6 +2386,7 @@ static void dns_close (qse_httpd_t* httpd, qse_httpd_dns_t* dns) | |||||||
| 		while (dc->reqs[i]) | 		while (dc->reqs[i]) | ||||||
| 		{ | 		{ | ||||||
| 			next_req = dc->reqs[i]->next; | 			next_req = dc->reqs[i]->next; | ||||||
|  | 			dns_remove_tmr_tmout (dc->reqs[i]); | ||||||
| 			qse_httpd_freemem (httpd, dc->reqs[i]); | 			qse_httpd_freemem (httpd, dc->reqs[i]); | ||||||
| 			dc->reqs[i] = next_req; | 			dc->reqs[i] = next_req; | ||||||
| 		} | 		} | ||||||
| @ -2520,7 +2535,7 @@ printf ("DNS_RECV....\n"); | |||||||
| 		xid = (id >= QSE_COUNTOF(dc->reqs))? (id - QSE_COUNTOF(dc->reqs)): id; | 		xid = (id >= QSE_COUNTOF(dc->reqs))? (id - QSE_COUNTOF(dc->reqs)): id; | ||||||
|  |  | ||||||
| printf ("%d qdcount %d ancount %d\n", id, qdcount, ancount); | printf ("%d qdcount %d ancount %d\n", id, qdcount, ancount); | ||||||
| 		if (id >= 0 && id < QSE_COUNTOF(dc->reqs) * 2 && hdr->qr && hdr->opcode == DNS_OPCODE_QUERY && qdcount >= 1) | 		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); | 			qse_uint8_t* plptr = (qse_uint8_t*)(hdr + 1); | ||||||
| 			qse_size_t pllen = len - QSE_SIZEOF(*hdr); | 			qse_size_t pllen = len - QSE_SIZEOF(*hdr); | ||||||
| @ -2603,11 +2618,11 @@ printf ("invoking resoll with ipv4 \n"); | |||||||
| 							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) | 						if (nwad.type != QSE_NWAD_NX) | ||||||
| 						{ | 						{ | ||||||
|  | 							dns_remove_tmr_tmout (req); | ||||||
| 							req->resol (httpd, req->name, &nwad, req->ctx); | 							req->resol (httpd, req->name, &nwad, req->ctx); | ||||||
|  |  | ||||||
| 							/* detach the request off dc->reqs */ | 							/* detach the request off dc->reqs */ | ||||||
| @ -2626,7 +2641,6 @@ printf ("invoking resoll with ipv6 \n"); | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  |  | ||||||
| 			/* no good answer have been found */ | 			/* 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; | ||||||
| @ -2634,7 +2648,7 @@ printf ("invoking resoll with ipv6 \n"); | |||||||
| 			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 */ | 				/* both ipv4 and ipv6 address are unresolvable */ | ||||||
|  | 				dns_remove_tmr_tmout (req); | ||||||
| 				req->resol (httpd, req->name, QSE_NULL, req->ctx); | 				req->resol (httpd, req->name, QSE_NULL, req->ctx); | ||||||
|  |  | ||||||
| 				/* detach the request off dc->reqs */ | 				/* detach the request off dc->reqs */ | ||||||
| @ -2645,21 +2659,65 @@ printf ("invoking resoll with ipv6 \n"); | |||||||
| 				dns_cache_answer (dc, req, QSE_NULL, DNS_MIN_TTL); | 				dns_cache_answer (dc, req, QSE_NULL, DNS_MIN_TTL); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		 |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| done: | done: | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void tmr_dns_tmout_updated (qse_tmr_t* tmr, qse_size_t old_index, qse_size_t new_index, void* ctx) | ||||||
|  | { | ||||||
|  | 	dns_req_t* req = (dns_req_t*)ctx; | ||||||
|  |  | ||||||
|  | printf (">>tmr_dns_tmout_updated %d %d\n", (int)req->tmr_tmout, (int)old_index); | ||||||
|  | 	QSE_ASSERT (req->tmr_tmout == old_index); | ||||||
|  | 	req->tmr_tmout = new_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; | ||||||
|  |  | ||||||
|  | printf ("dns timed out....\n"); | ||||||
|  | 	xid = req->seqa;  | ||||||
|  | 	QSE_ASSERT (xid >= 0 && QSE_COUNTOF(req->dc->reqs)); | ||||||
|  | /* TODO: doubly linked list??? speed up ??? */ | ||||||
|  | 	for (preq = QSE_NULL, xreq = req->dc->reqs[xid]; xreq; preq = xreq, xreq = xreq->next) | ||||||
|  | 	{ | ||||||
|  | 		if (req == xreq) break; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	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) | 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) | ||||||
| { | { | ||||||
| 	qse_uint32_t seq; |  | ||||||
| 	dns_ctx_t* dc = (dns_ctx_t*)dns->ctx; | 	dns_ctx_t* dc = (dns_ctx_t*)dns->ctx; | ||||||
|  | 	httpd_xtn_t* httpd_xtn = qse_httpd_getxtn (httpd); | ||||||
|  |  | ||||||
|  | 	qse_uint32_t seq; | ||||||
| 	dns_req_t* req; | 	dns_req_t* req; | ||||||
| 	qse_size_t name_len; | 	qse_size_t name_len; | ||||||
| 	dns_ans_t* ans; | 	dns_ans_t* ans; | ||||||
|  | 	qse_tmr_event_t tmout_event; | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
|  | printf ("DNS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n"); | ||||||
| 	ans = dns_get_answer_from_cache (dc, name); | 	ans = dns_get_answer_from_cache (dc, name); | ||||||
| 	if (ans) | 	if (ans) | ||||||
| 	{ | 	{ | ||||||
| @ -2712,17 +2770,37 @@ static int dns_send (qse_httpd_t* httpd, qse_httpd_dns_t* dns, const qse_mchar_t | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ((req->qalen > 0 && sendto (dns->handle.i, req->qa, req->qalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qalen) || | 	qse_gettime (&tmout_event.when); | ||||||
| 	    (req->qaaaalen > 0 && sendto (dns->handle.i, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qaaaalen)) | 	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; | ||||||
|  | 	 | ||||||
|  | printf ("ABOUT TO REGISTER TMR_TMOUT...\n"); | ||||||
|  | 	req->tmr_tmout = qse_tmr_insert (httpd->tmr, &tmout_event); | ||||||
|  | 	if (req->tmr_tmout == QSE_TMR_INVALID) | ||||||
| 	{ | 	{ | ||||||
| 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); | 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); | ||||||
| 		qse_httpd_freemem (httpd, req); | 		qse_httpd_freemem (httpd, req); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  | printf ("???? initial tmr_tmout => %d\n", (int)req->tmr_tmout); | ||||||
|  |  | ||||||
|  | 	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)) | ||||||
|  | 	{ | ||||||
|  | 		qse_tmr_remove (httpd->tmr, req->tmr_tmout); | ||||||
|  | 		req->tmr_tmout = QSE_TMR_INVALID; | ||||||
|  | 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); | ||||||
|  | 		qse_httpd_freemem (httpd, req); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	req->dc = dc; | ||||||
| 	req->next = dc->reqs[seq]; | 	req->next = dc->reqs[seq]; | ||||||
| 	dc->reqs[seq] = req; | 	dc->reqs[seq] = req; | ||||||
|  |  | ||||||
|  | printf ("DNS REALLY SENT>>>>>>>>>>>>>>>>>>>>>>>\n"); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -3980,14 +4058,19 @@ void* qse_httpd_getserverstdxtn (qse_httpd_t* httpd, qse_httpd_server_t* server) | |||||||
|  |  | ||||||
| /* ------------------------------------------------------------------- */ | /* ------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| int qse_httpd_loopstd (qse_httpd_t* httpd, const qse_nwad_t* dnsnwad) | int qse_httpd_loopstd (qse_httpd_t* httpd, const qse_httpd_dnsstd_t* dns) | ||||||
| { | { | ||||||
| 	httpd_xtn_t* httpd_xtn = qse_httpd_getxtn (httpd); | 	httpd_xtn_t* httpd_xtn = qse_httpd_getxtn (httpd); | ||||||
|  |  | ||||||
| 	if (dnsnwad) | 	if (dns) | ||||||
| 		httpd_xtn->dnsnwad = *dnsnwad; | 	{ | ||||||
|  | 		httpd_xtn->dns = *dns; | ||||||
|  | 	} | ||||||
| 	else | 	else | ||||||
| 		httpd_xtn->dnsnwad.type = QSE_NWAD_NX; | 	{ | ||||||
|  | 		httpd_xtn->dns.nwad.type = QSE_NWAD_NX; | ||||||
|  | 		httpd_xtn->dns.tmout.sec = QSE_HTTPD_DNSSTD_DEFAULT_TMOUT; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return qse_httpd_loop (httpd); | 	return qse_httpd_loop (httpd); | ||||||
| } | } | ||||||
|  | |||||||
| @ -383,10 +383,11 @@ static qse_htrd_recbs_t htrd_recbs = | |||||||
|  |  | ||||||
| /* ----------------------------------------------------------------------- */ | /* ----------------------------------------------------------------------- */ | ||||||
| static void tmr_idle_updated (qse_tmr_t* tmr, qse_size_t old_index, qse_size_t new_index, void* ctx); | static void tmr_idle_updated (qse_tmr_t* tmr, qse_size_t old_index, qse_size_t new_index, void* ctx); | ||||||
| static void check_if_client_is_idle (qse_tmr_t* tmr, const qse_ntime_t* now, void* ctx); | static void tmr_idle_handle (qse_tmr_t* tmr, const qse_ntime_t* now, void* ctx); | ||||||
|  |  | ||||||
| static void mark_bad_client (qse_httpd_client_t* client) | static void mark_bad_client (qse_httpd_client_t* client) | ||||||
| { | { | ||||||
|  | 	/* you can call this function multiple times */ | ||||||
| 	if (!(client->status & CLIENT_BAD)) | 	if (!(client->status & CLIENT_BAD)) | ||||||
| 	{ | 	{ | ||||||
| 		client->status |= CLIENT_BAD; | 		client->status |= CLIENT_BAD; | ||||||
| @ -418,11 +419,9 @@ static qse_httpd_client_t* new_client (qse_httpd_t* httpd, qse_httpd_client_t* t | |||||||
| 	qse_gettime (&idle_event.when); | 	qse_gettime (&idle_event.when); | ||||||
| 	qse_addtime (&idle_event.when, &httpd->opt.idle_limit, &idle_event.when); | 	qse_addtime (&idle_event.when, &httpd->opt.idle_limit, &idle_event.when); | ||||||
| 	idle_event.ctx = client; | 	idle_event.ctx = client; | ||||||
| 	idle_event.handler = check_if_client_is_idle; | 	idle_event.handler = tmr_idle_handle; | ||||||
| 	idle_event.updater = tmr_idle_updated; | 	idle_event.updater = tmr_idle_updated; | ||||||
|  |  | ||||||
| /*TODO: */ client->tmr_dns = QSE_TMR_INVALID; |  | ||||||
|  |  | ||||||
| 	client->tmr_idle = qse_tmr_insert (httpd->tmr, &idle_event); | 	client->tmr_idle = qse_tmr_insert (httpd->tmr, &idle_event); | ||||||
| 	if (client->tmr_idle == QSE_TMR_INVALID) | 	if (client->tmr_idle == QSE_TMR_INVALID) | ||||||
| 	{ | 	{ | ||||||
| @ -488,12 +487,6 @@ qse_printf (QSE_T("Debug: CLOSING SOCKET %d\n"), client->handle.i); | |||||||
| 		client->tmr_idle = QSE_TMR_INVALID; | 		client->tmr_idle = QSE_TMR_INVALID; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (client->tmr_dns != QSE_TMR_INVALID) |  | ||||||
| 	{ |  | ||||||
| 		qse_tmr_remove (httpd->tmr, client->tmr_dns); |  | ||||||
| 		client->tmr_dns = QSE_TMR_INVALID; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	qse_httpd_freemem (httpd, client); | 	qse_httpd_freemem (httpd, client); | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -627,13 +620,13 @@ printf ("MUX ADDHND CLIENT READ %d\n", client->handle.i); | |||||||
|  |  | ||||||
| static void tmr_idle_updated (qse_tmr_t* tmr, qse_size_t old_index, qse_size_t new_index, void* ctx) | static void tmr_idle_updated (qse_tmr_t* tmr, qse_size_t old_index, qse_size_t new_index, void* ctx) | ||||||
| { | { | ||||||
| printf ("tmr_idle updated %d %d\n", (int)old_index, (int)new_index); |  | ||||||
| 	qse_httpd_client_t* client = (qse_httpd_client_t*)ctx; | 	qse_httpd_client_t* client = (qse_httpd_client_t*)ctx; | ||||||
|  | printf ("tmr_idle updated old_index %d new_index %d tmr_idle %d\n", (int)old_index, (int)new_index, (int)client->tmr_idle); | ||||||
| 	QSE_ASSERT (client->tmr_idle == old_index); | 	QSE_ASSERT (client->tmr_idle == old_index); | ||||||
| 	client->tmr_idle = new_index; | 	client->tmr_idle = new_index; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void check_if_client_is_idle (qse_tmr_t* tmr, const qse_ntime_t* now, void* ctx) | static void tmr_idle_handle (qse_tmr_t* tmr, const qse_ntime_t* now, void* ctx) | ||||||
| { | { | ||||||
| 	qse_httpd_client_t* client = (qse_httpd_client_t*)ctx; | 	qse_httpd_client_t* client = (qse_httpd_client_t*)ctx; | ||||||
|  |  | ||||||
| @ -656,7 +649,7 @@ printf ("client is idle purging....\n"); | |||||||
| 			idle_event.when = *now; | 			idle_event.when = *now; | ||||||
| 			qse_addtime (&idle_event.when, &client->server->httpd->opt.idle_limit, &idle_event.when); | 			qse_addtime (&idle_event.when, &client->server->httpd->opt.idle_limit, &idle_event.when); | ||||||
| 			idle_event.ctx = client; | 			idle_event.ctx = client; | ||||||
| 			idle_event.handler = check_if_client_is_idle; | 			idle_event.handler = tmr_idle_handle; | ||||||
| 			idle_event.updater = tmr_idle_updated; | 			idle_event.updater = tmr_idle_updated; | ||||||
|  |  | ||||||
| 			/* the timer must have been deleted when this callback is called. */ | 			/* the timer must have been deleted when this callback is called. */ | ||||||
| @ -1474,6 +1467,8 @@ int qse_httpd_loop (qse_httpd_t* httpd) | |||||||
| 	QSE_ASSERTX (httpd->client.list.head == QSE_NULL, | 	QSE_ASSERTX (httpd->client.list.head == QSE_NULL, | ||||||
| 		"No client should exist when this loop is started"); | 		"No client should exist when this loop is started"); | ||||||
|  |  | ||||||
|  | 	QSE_ASSERT (QSE_TMR_SIZE(httpd->tmr) == 0); | ||||||
|  |  | ||||||
| 	if (httpd->server.list.head == QSE_NULL)  | 	if (httpd->server.list.head == QSE_NULL)  | ||||||
| 	{ | 	{ | ||||||
| 		httpd->errnum = QSE_HTTPD_EINVAL; | 		httpd->errnum = QSE_HTTPD_EINVAL; | ||||||
| @ -1552,7 +1547,8 @@ int qse_httpd_loop (qse_httpd_t* httpd) | |||||||
| 	if (httpd->dnsactive) deactivate_dns (httpd); | 	if (httpd->dnsactive) deactivate_dns (httpd); | ||||||
|  |  | ||||||
| 	httpd->opt.scb.mux.close (httpd, httpd->mux); | 	httpd->opt.scb.mux.close (httpd, httpd->mux); | ||||||
| 	qse_tmr_clear (httpd->tmr); |  | ||||||
|  | 	QSE_ASSERT (QSE_TMR_SIZE(httpd->tmr) == 0); | ||||||
| 	return xret; | 	return xret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user