added some protection againt double dns resolution and double url rewriting
This commit is contained in:
		| @ -612,12 +612,15 @@ struct qse_httpd_client_t | |||||||
| #define QSE_HTTPD_CLIENT_PENDING                (1 << 4) | #define QSE_HTTPD_CLIENT_PENDING                (1 << 4) | ||||||
| #define QSE_HTTPD_CLIENT_MUTE                   (1 << 5) | #define QSE_HTTPD_CLIENT_MUTE                   (1 << 5) | ||||||
| #define QSE_HTTPD_CLIENT_MUTE_DELETED           (1 << 6) | #define QSE_HTTPD_CLIENT_MUTE_DELETED           (1 << 6) | ||||||
| #define QSE_HTTPD_CLIENT_HANDLE_READ_IN_MUX     (1 << 7) | #define QSE_HTTPD_CLIENT_PROTOCOL_SWITCHED      (1 << 7) /* 101 Switching Protocols has been received */ | ||||||
| #define QSE_HTTPD_CLIENT_HANDLE_WRITE_IN_MUX    (1 << 8) | #define QSE_HTTPD_CLIENT_HANDLE_READ_IN_MUX     (1 << 8) | ||||||
|  | #define QSE_HTTPD_CLIENT_HANDLE_WRITE_IN_MUX    (1 << 9) | ||||||
| #define QSE_HTTPD_CLIENT_HANDLE_RW_IN_MUX       (QSE_HTTPD_CLIENT_HANDLE_READ_IN_MUX | QSE_HTTPD_CLIENT_HANDLE_WRITE_IN_MUX) | #define QSE_HTTPD_CLIENT_HANDLE_RW_IN_MUX       (QSE_HTTPD_CLIENT_HANDLE_READ_IN_MUX | QSE_HTTPD_CLIENT_HANDLE_WRITE_IN_MUX) | ||||||
|  |  | ||||||
| #define QSE_HTTPD_CLIENT_TASK_TRIGGER_READ_IN_MUX(i) (1 << ((i) + 9)) | /* 'i' must be between 0 and QSE_HTTPD_TASK_TRIGGER_MAX - 1. | ||||||
| #define QSE_HTTPD_CLIENT_TASK_TRIGGER_WRITE_IN_MUX(i) (1 << ((i) + 9  + QSE_HTTPD_TASK_TRIGGER_MAX)) |  * Be careful about potential overflown when QSE_HTTPD_TASK_TRIGGER_MAX is too large. */ | ||||||
|  | #define QSE_HTTPD_CLIENT_TASK_TRIGGER_READ_IN_MUX(i) (1 << ((i) + 10)) | ||||||
|  | #define QSE_HTTPD_CLIENT_TASK_TRIGGER_WRITE_IN_MUX(i) (1 << ((i) + 10  + QSE_HTTPD_TASK_TRIGGER_MAX)) | ||||||
| #define QSE_HTTPD_CLIENT_TASK_TRIGGER_RW_IN_MUX(i) (QSE_HTTPD_CLIENT_TASK_TRIGGER_READ_IN_MUX(i) | QSE_HTTPD_CLIENT_TASK_TRIGGER_WRITE_IN_MUX(i)) | #define QSE_HTTPD_CLIENT_TASK_TRIGGER_RW_IN_MUX(i) (QSE_HTTPD_CLIENT_TASK_TRIGGER_READ_IN_MUX(i) | QSE_HTTPD_CLIENT_TASK_TRIGGER_WRITE_IN_MUX(i)) | ||||||
|  |  | ||||||
| enum qse_httpd_server_flag_t | enum qse_httpd_server_flag_t | ||||||
| @ -626,6 +629,7 @@ enum qse_httpd_server_flag_t | |||||||
| 	QSE_HTTPD_SERVER_SECURE     = (1 << 1), | 	QSE_HTTPD_SERVER_SECURE     = (1 << 1), | ||||||
| 	QSE_HTTPD_SERVER_BINDTONWIF = (1 << 2) | 	QSE_HTTPD_SERVER_BINDTONWIF = (1 << 2) | ||||||
| }; | }; | ||||||
|  | typedef enum qse_httpd_server_flag_t qse_httpd_server_flag_t; | ||||||
|  |  | ||||||
| typedef void (*qse_httpd_server_detach_t) ( | typedef void (*qse_httpd_server_detach_t) ( | ||||||
| 	qse_httpd_t*        httpd, | 	qse_httpd_t*        httpd, | ||||||
| @ -633,7 +637,6 @@ typedef void (*qse_httpd_server_detach_t) ( | |||||||
| ); | ); | ||||||
|  |  | ||||||
| typedef struct qse_httpd_server_dope_t qse_httpd_server_dope_t; | typedef struct qse_httpd_server_dope_t qse_httpd_server_dope_t; | ||||||
|  |  | ||||||
| struct qse_httpd_server_dope_t | struct qse_httpd_server_dope_t | ||||||
| { | { | ||||||
| 	int          flags; /* bitwise-ORed of qse_httpd_server_flag_t */ | 	int          flags; /* bitwise-ORed of qse_httpd_server_flag_t */ | ||||||
|  | |||||||
| @ -45,15 +45,17 @@ struct task_proxy_t | |||||||
|                                                the task_proxy_t chunk. explicit |                                                the task_proxy_t chunk. explicit | ||||||
|                                                deallocatin is required */ |                                                deallocatin is required */ | ||||||
| #define PROXY_RESOLVE_PEER_NAME    (1 << 6) | #define PROXY_RESOLVE_PEER_NAME    (1 << 6) | ||||||
| #define PROXY_PEER_NAME_RESOLVED   (1 << 7) | #define PROXY_PEER_NAME_RESOLVING  (1 << 7) | ||||||
| #define PROXY_PEER_NAME_UNRESOLVED (1 << 8) | #define PROXY_PEER_NAME_RESOLVED   (1 << 8) | ||||||
| #define PROXY_REWRITE_URL          (1 << 9) | #define PROXY_PEER_NAME_UNRESOLVED (1 << 9) | ||||||
| #define PROXY_URL_PREREWRITTEN     (1 << 10) /* URL has been prerewritten in prerewrite(). */ | #define PROXY_REWRITE_URL          (1 << 10) | ||||||
| #define PROXY_URL_REWRITTEN        (1 << 11) | #define PROXY_URL_REWRITING        (1 << 11) | ||||||
| #define PROXY_URL_REDIRECTED       (1 << 12) | #define PROXY_URL_PREREWRITTEN     (1 << 12) /* URL has been prerewritten in prerewrite(). */ | ||||||
| #define PROXY_X_FORWARDED_FOR      (1 << 13) /* X-Forwarded-For added */ | #define PROXY_URL_REWRITTEN        (1 << 13) | ||||||
| #define PROXY_VIA                  (1 << 14) /* Via added to the request */ | #define PROXY_URL_REDIRECTED       (1 << 14) | ||||||
| #define PROXY_VIA_RETURNING        (1 << 15) /* Via added to the response */ | #define PROXY_X_FORWARDED_FOR      (1 << 15) /* X-Forwarded-For added */ | ||||||
|  | #define PROXY_VIA                  (1 << 16) /* Via added to the request */ | ||||||
|  | #define PROXY_VIA_RETURNING        (1 << 17) /* Via added to the response */ | ||||||
| 	int flags; | 	int flags; | ||||||
| 	qse_httpd_t* httpd; | 	qse_httpd_t* httpd; | ||||||
| 	qse_httpd_client_t* client; | 	qse_httpd_client_t* client; | ||||||
| @ -297,7 +299,7 @@ static int proxy_capture_client_header (qse_htre_t* req, const qse_mchar_t* key, | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| /* EXPERIMENTAL: REMOVE HEADERS. | /* EXPERIMENTAL: REMOVE HEADERS. | ||||||
|  * FOR EXAMPLE, You can remove Referer to make analysis systems harder time */ |  * FOR EXAMPLE, You can remove Referer or forge it to give analysis systems harder time  */ | ||||||
| 	if (qse_mbscasecmp (key, QSE_MT("Transfer-Encoding")) != 0 && | 	if (qse_mbscasecmp (key, QSE_MT("Transfer-Encoding")) != 0 && | ||||||
| 	    qse_mbscasecmp (key, QSE_MT("Content-Length")) != 0 /* EXPERIMENTAL */ /* && | 	    qse_mbscasecmp (key, QSE_MT("Content-Length")) != 0 /* EXPERIMENTAL */ /* && | ||||||
| 	    qse_mbscasecmp (key, QSE_MT("Referer")) != 0*/) | 	    qse_mbscasecmp (key, QSE_MT("Referer")) != 0*/) | ||||||
| @ -368,11 +370,6 @@ static int proxy_snatch_client_input ( | |||||||
| 	task = (qse_httpd_task_t*)ctx; | 	task = (qse_httpd_task_t*)ctx; | ||||||
| 	proxy = (task_proxy_t*)task->ctx; | 	proxy = (task_proxy_t*)task->ctx; | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| if (ptr) qse_printf (QSE_T("!!!PROXY SNATCHING [%.*hs]\n"), len, ptr); |  | ||||||
| else qse_printf (QSE_T("!!!PROXY SNATCHING DONE\n")); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 	if (ptr == QSE_NULL) | 	if (ptr == QSE_NULL) | ||||||
| 	{ | 	{ | ||||||
| 		/* | 		/* | ||||||
| @ -448,9 +445,6 @@ else qse_printf (QSE_T("!!!PROXY SNATCHING DONE\n")); | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE; | 		task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE; | ||||||
| #if 0 |  | ||||||
| qse_printf (QSE_T("!!!PROXY SNATCHED [%.*hs]\n"), len, ptr); |  | ||||||
| #endif |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -481,14 +475,10 @@ static int proxy_snatch_peer_output ( | |||||||
|  |  | ||||||
| 	if (ptr == QSE_NULL) | 	if (ptr == QSE_NULL) | ||||||
| 	{ | 	{ | ||||||
| 		/* content completed */ | 		/* content completed. got the entire response */ | ||||||
|  |  | ||||||
| 		QSE_ASSERT (len == 0); | 		QSE_ASSERT (len == 0); | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| qse_printf (QSE_T("PROXY GOT ALL RESPONSE>>>>>>>\n")); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 		if (qse_mbs_cat (proxy->res, QSE_MT("0\r\n")) == (qse_size_t)-1 || | 		if (qse_mbs_cat (proxy->res, QSE_MT("0\r\n")) == (qse_size_t)-1 || | ||||||
| 		    qse_htre_walktrailers (req, proxy_capture_peer_trailer, proxy) <= -1 || | 		    qse_htre_walktrailers (req, proxy_capture_peer_trailer, proxy) <= -1 || | ||||||
| 		    qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1)  | 		    qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1)  | ||||||
| @ -673,18 +663,11 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res) | |||||||
|  |  | ||||||
| 		if (proxy->resflags & PROXY_RES_PEER_LENGTH_FAKE) | 		if (proxy->resflags & PROXY_RES_PEER_LENGTH_FAKE) | ||||||
| 		{ | 		{ | ||||||
| 			qse_mchar_t buf[64]; |  | ||||||
|  |  | ||||||
| 			/* length should be added by force. | 			/* length should be added by force. | ||||||
| 			 * let me add Content-Length event if it's 0  | 			 * let me add Content-Length event if it's 0  | ||||||
| 			 * for less code */ | 			 * for less code */ | ||||||
| 			qse_fmtuintmaxtombs ( |  | ||||||
| 				buf, QSE_COUNTOF(buf), |  | ||||||
| 				proxy->peer_output_length,  |  | ||||||
| 				10, -1, QSE_MT('\0'), QSE_NULL); |  | ||||||
|  |  | ||||||
| 			if (qse_mbs_cat (proxy->res, QSE_MT("Content-Length: ")) == (qse_size_t)-1 || | 			if (qse_mbs_cat (proxy->res, QSE_MT("Content-Length: ")) == (qse_size_t)-1 || | ||||||
| 			    qse_mbs_cat (proxy->res, buf) == (qse_size_t)-1 || | 			    qse_mbs_fcat (proxy->res, QSE_MT("%zu"), (qse_size_t)proxy->peer_output_length) == (qse_size_t)-1 || | ||||||
| 			    qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) | 			    qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) | ||||||
| 			{ | 			{ | ||||||
| 				httpd->errnum = QSE_HTTPD_ENOMEM; | 				httpd->errnum = QSE_HTTPD_ENOMEM; | ||||||
| @ -948,8 +931,13 @@ static int task_init_proxy ( | |||||||
| 	proxy->peer.local = arg->rsrc->src.nwad; | 	proxy->peer.local = arg->rsrc->src.nwad; | ||||||
| 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_DST_STR) | 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_DST_STR) | ||||||
| 	{ | 	{ | ||||||
|  | 		/* the destination given is a string. | ||||||
|  | 		 * arrange to make a DNS query in task_main_proxy() */ | ||||||
|  |  | ||||||
| 		if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_ENABLE_DNS) | 		if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_ENABLE_DNS) | ||||||
| 		{ | 		{ | ||||||
|  | 			/* dns service is enabled. carry on with the arrangement */ | ||||||
|  |  | ||||||
| 			proxy->peer_name = proxy->pseudonym + len + 1; | 			proxy->peer_name = proxy->pseudonym + len + 1; | ||||||
| 			qse_mbscpy (proxy->peer_name, arg->rsrc->dst.str); | 			qse_mbscpy (proxy->peer_name, arg->rsrc->dst.str); | ||||||
| 			adjust_peer_name_and_port (proxy); | 			adjust_peer_name_and_port (proxy); | ||||||
| @ -1032,7 +1020,6 @@ static int task_init_proxy ( | |||||||
| 	{ | 	{ | ||||||
| 		int snatch_needed = 0; | 		int snatch_needed = 0; | ||||||
|  |  | ||||||
|  |  | ||||||
| 		/* compose a request to send to the peer using the request | 		/* compose a request to send to the peer using the request | ||||||
| 		 * received from the client */ | 		 * received from the client */ | ||||||
|  |  | ||||||
| @ -1911,9 +1898,10 @@ static void on_peer_name_resolved (qse_httpd_t* httpd, const qse_mchar_t* name, | |||||||
| 	task_proxy_t* proxy = (task_proxy_t*)task->ctx; | 	task_proxy_t* proxy = (task_proxy_t*)task->ctx; | ||||||
|  |  | ||||||
| 	QSE_ASSERT (proxy->flags & PROXY_RESOLVE_PEER_NAME); | 	QSE_ASSERT (proxy->flags & PROXY_RESOLVE_PEER_NAME); | ||||||
|  | 	QSE_ASSERT (proxy->flags & PROXY_PEER_NAME_RESOLVING); | ||||||
| 	QSE_ASSERT (!(proxy->flags & (PROXY_PEER_NAME_RESOLVED | PROXY_PEER_NAME_UNRESOLVED))); | 	QSE_ASSERT (!(proxy->flags & (PROXY_PEER_NAME_RESOLVED | PROXY_PEER_NAME_UNRESOLVED))); | ||||||
|  |  | ||||||
| 	proxy->flags &= ~PROXY_RESOLVE_PEER_NAME; | 	proxy->flags &= ~(PROXY_RESOLVE_PEER_NAME | PROXY_PEER_NAME_RESOLVING); | ||||||
|  |  | ||||||
| 	if (nwad) | 	if (nwad) | ||||||
| 	{ | 	{ | ||||||
| @ -1959,7 +1947,7 @@ static void on_url_rewritten (qse_httpd_t* httpd, const qse_mchar_t* url, const | |||||||
| 	{ | 	{ | ||||||
| 		qse_nwad_t nwad; | 		qse_nwad_t nwad; | ||||||
|  |  | ||||||
| 		proxy->flags &= ~PROXY_REWRITE_URL; | 		proxy->flags &= ~(PROXY_REWRITE_URL | PROXY_URL_REWRITING); | ||||||
|  |  | ||||||
| printf ("XXXXXXXXXXXXXXXXXXXXXXXXXX URL REWRITTEN TO [%s].....\n", new_url); | printf ("XXXXXXXXXXXXXXXXXXXXXXXXXX URL REWRITTEN TO [%s].....\n", new_url); | ||||||
| 		if (new_url[0] == QSE_MT('\0')) | 		if (new_url[0] == QSE_MT('\0')) | ||||||
| @ -2152,8 +2140,12 @@ static int task_main_proxy ( | |||||||
| 			on_url_rewritten (httpd, QSE_NULL, (proxy->url_to_rewrite? proxy->url_to_rewrite: QSE_MT("")), task); | 			on_url_rewritten (httpd, QSE_NULL, (proxy->url_to_rewrite? proxy->url_to_rewrite: QSE_MT("")), task); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
|  | 		{ | ||||||
|  | 			if (!(proxy->flags & PROXY_URL_REWRITING)) | ||||||
| 			{ | 			{ | ||||||
| 				/* note that url_to_rewrite is URL + extra information. */ | 				/* note that url_to_rewrite is URL + extra information. */ | ||||||
|  | 				proxy->flags |= PROXY_URL_REWRITING; /* to prevent double calls */ | ||||||
|  |  | ||||||
| 				if (qse_httpd_rewriteurl (httpd, proxy->url_to_rewrite, on_url_rewritten,  | 				if (qse_httpd_rewriteurl (httpd, proxy->url_to_rewrite, on_url_rewritten,  | ||||||
| 				                          ((proxy->flags & PROXY_URS_SERVER)? &proxy->urs_server: QSE_NULL), task) <= -1) goto oops; | 				                          ((proxy->flags & PROXY_URS_SERVER)? &proxy->urs_server: QSE_NULL), task) <= -1) goto oops; | ||||||
|  |  | ||||||
| @ -2162,16 +2154,23 @@ static int task_main_proxy ( | |||||||
| 				if ((proxy->flags & PROXY_REWRITE_URL) &&  | 				if ((proxy->flags & PROXY_REWRITE_URL) &&  | ||||||
| 				    qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1) goto oops; | 				    qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1) goto oops; | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		return 1; | 		return 1; /* not finished yet */ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (proxy->flags & PROXY_RESOLVE_PEER_NAME) | 	if (proxy->flags & PROXY_RESOLVE_PEER_NAME) | ||||||
| 	{ | 	{ | ||||||
| 		/* arrange to resolve a host name and return */ | 		/* arrange to resolve a host name and return */ | ||||||
| 		int x; | 		int x; | ||||||
|  |  | ||||||
| 		QSE_ASSERT (proxy->peer_name != QSE_NULL); | 		QSE_ASSERT (proxy->peer_name != QSE_NULL); | ||||||
|  |  | ||||||
|  | 		if (proxy->flags & PROXY_PEER_NAME_RESOLVING) | ||||||
|  | 		{ | ||||||
|  | 			return 1; /* not finished yet */ | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if (proxy->dns_preresolve_mod && proxy->dns_preresolve_mod->dns_preresolve) | 		if (proxy->dns_preresolve_mod && proxy->dns_preresolve_mod->dns_preresolve) | ||||||
| 			x = proxy->dns_preresolve_mod->dns_preresolve (proxy->dns_preresolve_mod, client, proxy->peer_name, &proxy->peer.nwad); | 			x = proxy->dns_preresolve_mod->dns_preresolve (proxy->dns_preresolve_mod, client, proxy->peer_name, &proxy->peer.nwad); | ||||||
| 		else | 		else | ||||||
| @ -2188,6 +2187,17 @@ static int task_main_proxy ( | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
|  | 			/* this function can be called more than once if a socket  | ||||||
|  | 			 * descriptor appears multiple times in the event result  | ||||||
|  | 			 * of a single event polling cycle in the main loop. | ||||||
|  | 			 * e.g.) the mux implementation doesn't collapse multiple events | ||||||
|  | 			 *       for a socket descriptor into 1 event. | ||||||
|  | 			 *  | ||||||
|  | 			 * if this happens, qse_http_resolvename() can be called  | ||||||
|  | 			 * multiple times. | ||||||
|  | 			 */ | ||||||
|  | 			proxy->flags |= PROXY_PEER_NAME_RESOLVING;  | ||||||
|  |  | ||||||
| 			x = qse_httpd_resolvename (httpd, proxy->peer_name, on_peer_name_resolved, ((proxy->flags & PROXY_DNS_SERVER)? &proxy->dns_server: QSE_NULL), task); | 			x = qse_httpd_resolvename (httpd, proxy->peer_name, on_peer_name_resolved, ((proxy->flags & PROXY_DNS_SERVER)? &proxy->dns_server: QSE_NULL), task); | ||||||
| 			if (x <= -1) goto oops; | 			if (x <= -1) goto oops; | ||||||
| 		} | 		} | ||||||
| @ -2205,7 +2215,7 @@ static int task_main_proxy ( | |||||||
| 		if (!(proxy->flags & PROXY_PEER_NAME_RESOLVED) &&  | 		if (!(proxy->flags & PROXY_PEER_NAME_RESOLVED) &&  | ||||||
| 		    qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1) goto oops; | 		    qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1) goto oops; | ||||||
|  |  | ||||||
| 		return 1; | 		return 1; /* not finished yet */ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (!(proxy->flags & PROXY_RAW)) | 	if (!(proxy->flags & PROXY_RAW)) | ||||||
|  | |||||||
| @ -782,7 +782,7 @@ resolved: | |||||||
| 	else req->prev->next = req->next; | 	else req->prev->next = req->next; | ||||||
| 	if (req->next) req->next->prev = req->prev; | 	if (req->next) req->next->prev = req->prev; | ||||||
|  |  | ||||||
| 	/* cache the negative answer instead of destroying it */ | 	/* cache the answer instead of destroying it */ | ||||||
| 	dns_cache_answer (dc, req, resolved_nwad, cache_ttl); | 	dns_cache_answer (dc, req, resolved_nwad, cache_ttl); | ||||||
| 	dc->req_count--; | 	dc->req_count--; | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user