added host/location specific dns/urs server
This commit is contained in:
		| @ -459,6 +459,19 @@ static int get_server_root ( | |||||||
| 	qpath = qse_htre_getqpath(qinfo->req); | 	qpath = qse_htre_getqpath(qinfo->req); | ||||||
|  |  | ||||||
| 	qse_memset (root, 0, QSE_SIZEOF(*root)); | 	qse_memset (root, 0, QSE_SIZEOF(*root)); | ||||||
|  |  | ||||||
|  | 	if (loccfg->proxy.dns_nwad.type != QSE_NWAD_NX) | ||||||
|  | 	{ | ||||||
|  | 		root->u.proxy.dns_server = loccfg->proxy.dns_nwad; | ||||||
|  | 		root->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_DNS_SERVER; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (loccfg->proxy.urs_nwad.type != QSE_NWAD_NX) | ||||||
|  | 	{ | ||||||
|  | 		root->u.proxy.urs_server = loccfg->proxy.urs_nwad; | ||||||
|  | 		root->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_URS_SERVER; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (mth == QSE_HTTP_CONNECT) | 	if (mth == QSE_HTTP_CONNECT) | ||||||
| 	{ | 	{ | ||||||
| 		if (loccfg->proxy.allow_connect) | 		if (loccfg->proxy.allow_connect) | ||||||
| @ -538,6 +551,8 @@ static int get_server_root ( | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (loccfg->root_is_nwad) | 	if (loccfg->root_is_nwad) | ||||||
| 	{ | 	{ | ||||||
| 		root->type = QSE_HTTPD_SERVERSTD_ROOT_NWAD; | 		root->type = QSE_HTTPD_SERVERSTD_ROOT_NWAD; | ||||||
| @ -878,43 +893,6 @@ found: | |||||||
|  |  | ||||||
| /* --------------------------------------------------------------------- */ | /* --------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| static struct |  | ||||||
| { |  | ||||||
| 	const qse_char_t* x; |  | ||||||
| 	const qse_char_t* y; |  | ||||||
| } scfg_items[] = |  | ||||||
| { |  | ||||||
| 	{ QSE_T("ssl-cert-file"),  QSE_T("server-default.ssl-cert-file") }, |  | ||||||
| 	{ QSE_T("ssl-key-file"),   QSE_T("server-default.ssl-key-file") } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static struct  |  | ||||||
| { |  | ||||||
| 	const qse_char_t* x; |  | ||||||
| 	const qse_char_t* y; |  | ||||||
| } loc_xcfg_items[] = |  | ||||||
| { |  | ||||||
| 	{ QSE_T("root"),        QSE_T("server-default.root") }, |  | ||||||
| 	{ QSE_T("realm"),       QSE_T("server-default.realm") }, |  | ||||||
| 	{ QSE_T("auth"),        QSE_T("server-default.auth") }, |  | ||||||
| 	{ QSE_T("dir-head"),    QSE_T("server-default.dir-head") }, |  | ||||||
| 	{ QSE_T("dir-foot"),    QSE_T("server-default.dir-foot") }, |  | ||||||
| 	{ QSE_T("error-head"),  QSE_T("server-default.error-head") }, |  | ||||||
| 	{ QSE_T("error-foot"),  QSE_T("server-default.error-foot") }, |  | ||||||
| 	{ QSE_T("pseudonym"),   QSE_T("server-default.pseudonym") } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /* local access items */ |  | ||||||
| static struct  |  | ||||||
| { |  | ||||||
| 	const qse_char_t* x; |  | ||||||
| 	const qse_char_t* y; |  | ||||||
| } loc_acc_items[] =  |  | ||||||
| { |  | ||||||
| 	{ QSE_T("dir-access"), QSE_T("server-default.dir-access") }, |  | ||||||
| 	{ QSE_T("file-access"), QSE_T("server-default.file-access") } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static void free_loccfg_contents (qse_httpd_t* httpd, loccfg_t* loccfg) | static void free_loccfg_contents (qse_httpd_t* httpd, loccfg_t* loccfg) | ||||||
| { | { | ||||||
| 	qse_size_t i, j; | 	qse_size_t i, j; | ||||||
| @ -1013,75 +991,26 @@ static int get_boolean (const qse_xli_str_t* v) | |||||||
| 	        qse_strxcasecmp (v->ptr, v->len, QSE_T("on")) == 0); | 	        qse_strxcasecmp (v->ptr, v->len, QSE_T("on")) == 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int load_loccfg_proxy (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) | static int load_loccfg_basic (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) | ||||||
| { | { | ||||||
|  | 	static struct  | ||||||
|  | 	{ | ||||||
|  | 		const qse_char_t* x; | ||||||
|  | 		const qse_char_t* y; | ||||||
|  | 	} loc_xcfg_items[] = | ||||||
|  | 	{ | ||||||
|  | 		{ QSE_T("root"),        QSE_T("server-default.root") }, | ||||||
|  | 		{ QSE_T("realm"),       QSE_T("server-default.realm") }, | ||||||
|  | 		{ QSE_T("auth"),        QSE_T("server-default.auth") }, | ||||||
|  | 		{ QSE_T("dir-head"),    QSE_T("server-default.dir-head") }, | ||||||
|  | 		{ QSE_T("dir-foot"),    QSE_T("server-default.dir-foot") }, | ||||||
|  | 		{ QSE_T("error-head"),  QSE_T("server-default.error-head") }, | ||||||
|  | 		{ QSE_T("error-foot"),  QSE_T("server-default.error-foot") }, | ||||||
|  | 		{ QSE_T("pseudonym"),   QSE_T("server-default.pseudonym") } | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	int i; | ||||||
| 	qse_xli_pair_t* pair; | 	qse_xli_pair_t* pair; | ||||||
| 	qse_xli_list_t* proxy = QSE_NULL; |  | ||||||
| 	qse_xli_list_t* default_proxy = QSE_NULL; |  | ||||||
| 	/*qse_xli_atom_t* atom;*/ |  | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpair (xli, list, QSE_T("proxy")); |  | ||||||
| 	if (pair)  |  | ||||||
| 	{ |  | ||||||
| 		QSE_ASSERT (pair->val->type == QSE_XLI_LIST); |  | ||||||
| 		proxy = (qse_xli_list_t*)pair->val; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.proxy")); |  | ||||||
| 	if (pair) |  | ||||||
| 	{ |  | ||||||
| 		QSE_ASSERT (pair->val->type == QSE_XLI_LIST); |  | ||||||
| 		default_proxy = (qse_xli_list_t*)pair->val; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	pair = QSE_NULL; |  | ||||||
| 	if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("http")); /* server.host[].location[].proxy.http */ |  | ||||||
| 	if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("http")); /* server-default.proxy.http */ |  | ||||||
| 	if (pair) cfg->proxy.allow_http = get_boolean ((qse_xli_str_t*)pair->val); |  | ||||||
|  |  | ||||||
| 	pair = QSE_NULL; |  | ||||||
| 	if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("connect")); |  | ||||||
| 	if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("connect")); |  | ||||||
| 	if (pair) cfg->proxy.allow_connect = get_boolean ((qse_xli_str_t*)pair->val); |  | ||||||
|  |  | ||||||
| 	pair = QSE_NULL; |  | ||||||
| 	if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("dns-server")); |  | ||||||
| 	if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("dns-server")); |  | ||||||
| 	if (pair)  |  | ||||||
| 	{ |  | ||||||
| 		qse_xli_str_t* str = (qse_xli_str_t*)pair->val; |  | ||||||
| 		if (qse_strtonwad (str->ptr, &cfg->proxy.dns_nwad) <= -1) |  | ||||||
| 		{ |  | ||||||
| 			qse_printf (QSE_T("ERROR: invalid address for proxy dns - %s"), str->ptr); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	pair = QSE_NULL; |  | ||||||
| 	if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("urs-server")); |  | ||||||
| 	if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("urs-server")); |  | ||||||
| 	if (pair) |  | ||||||
| 	{ |  | ||||||
| 		qse_xli_str_t* str = (qse_xli_str_t*)pair->val; |  | ||||||
| 		if (qse_strtonwad (str->ptr, &cfg->proxy.urs_nwad) <= -1) |  | ||||||
| 		{ |  | ||||||
| 			qse_printf (QSE_T("ERROR: invalid address for proxy urs - %s"), str->ptr); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int load_loccfg (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) |  | ||||||
| { |  | ||||||
| 	qse_size_t i; |  | ||||||
| 	qse_xli_pair_t* pair; |  | ||||||
| 	qse_xli_atom_t* atom; |  | ||||||
| 	/*httpd_xtn_t* httpd_xtn; |  | ||||||
|  |  | ||||||
| 	httpd_xtn = qse_httpd_getxtnstd (httpd);*/ |  | ||||||
|  |  | ||||||
| 	for (i = 0; i < QSE_COUNTOF(loc_xcfg_items); i++) | 	for (i = 0; i < QSE_COUNTOF(loc_xcfg_items); i++) | ||||||
| 	{ | 	{ | ||||||
| @ -1099,6 +1028,13 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int load_loccfg_index (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) | ||||||
|  | { | ||||||
|  | 	qse_xli_pair_t* pair; | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpair (xli, list, QSE_T("index")); | 	pair = qse_xli_findpair (xli, list, QSE_T("index")); | ||||||
| 	if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.index")); | 	if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.index")); | ||||||
| 	if (pair && pair->val->type == QSE_XLI_STR) | 	if (pair && pair->val->type == QSE_XLI_STR) | ||||||
| @ -1125,6 +1061,14 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list | |||||||
| 		cfg->index.count = count; | 		cfg->index.count = count; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int load_loccfg_cgi (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) | ||||||
|  | { | ||||||
|  | 	qse_xli_pair_t* pair; | ||||||
|  | 	qse_xli_atom_t* atom; | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpair (xli, list, QSE_T("cgi")); | 	pair = qse_xli_findpair (xli, list, QSE_T("cgi")); | ||||||
| 	if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.cgi")); | 	if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.cgi")); | ||||||
| 	if (pair && pair->val->type == QSE_XLI_LIST) | 	if (pair && pair->val->type == QSE_XLI_LIST) | ||||||
| @ -1198,6 +1142,14 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int load_loccfg_authrule (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) | ||||||
|  | { | ||||||
|  | 	qse_xli_pair_t* pair; | ||||||
|  | 	qse_xli_atom_t* atom; | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpair (xli, list, QSE_T("auth-rule")); | 	pair = qse_xli_findpair (xli, list, QSE_T("auth-rule")); | ||||||
| 	if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.auth-rule")); | 	if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.auth-rule")); | ||||||
| 	if (pair && pair->val->type == QSE_XLI_LIST) | 	if (pair && pair->val->type == QSE_XLI_LIST) | ||||||
| @ -1248,6 +1200,16 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/* TODO: support multiple auth entries  */ | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int load_loccfg_mime (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) | ||||||
|  | { | ||||||
|  | 	qse_xli_pair_t* pair; | ||||||
|  | 	qse_xli_atom_t* atom; | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpair (xli, list, QSE_T("mime")); | 	pair = qse_xli_findpair (xli, list, QSE_T("mime")); | ||||||
| 	if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.mime")); | 	if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.mime")); | ||||||
| 	if (pair && pair->val->type == QSE_XLI_LIST) | 	if (pair && pair->val->type == QSE_XLI_LIST) | ||||||
| @ -1301,6 +1263,26 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list | |||||||
| 		} | 		} | ||||||
| 	}	 | 	}	 | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int load_loccfg_access (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) | ||||||
|  | { | ||||||
|  | 	/* local access items */ | ||||||
|  | 	static struct  | ||||||
|  | 	{ | ||||||
|  | 		const qse_char_t* x; | ||||||
|  | 		const qse_char_t* y; | ||||||
|  | 	} loc_acc_items[] =  | ||||||
|  | 	{ | ||||||
|  | 		{ QSE_T("dir-access"), QSE_T("server-default.dir-access") }, | ||||||
|  | 		{ QSE_T("file-access"), QSE_T("server-default.file-access") } | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	int i; | ||||||
|  | 	qse_xli_pair_t* pair; | ||||||
|  | 	qse_xli_atom_t* atom; | ||||||
|  |  | ||||||
| 	for (i = 0; i < 2;  i++) | 	for (i = 0; i < 2;  i++) | ||||||
| 	{ | 	{ | ||||||
| 		pair = qse_xli_findpair (xli, list, loc_acc_items[i].x); | 		pair = qse_xli_findpair (xli, list, loc_acc_items[i].x); | ||||||
| @ -1362,10 +1344,82 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list | |||||||
| 		}	 | 		}	 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (load_loccfg_proxy (httpd, xli, list, cfg) <= -1) return -1; | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| 	/* TODO: support multiple auth entries here and above */ | static int load_loccfg_proxy (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) | ||||||
|  | { | ||||||
|  | 	qse_xli_pair_t* pair; | ||||||
|  | 	qse_xli_list_t* proxy = QSE_NULL; | ||||||
|  | 	qse_xli_list_t* default_proxy = QSE_NULL; | ||||||
|  |  | ||||||
|  | 	pair = qse_xli_findpair (xli, list, QSE_T("proxy")); | ||||||
|  | 	if (pair)  | ||||||
|  | 	{ | ||||||
|  | 		QSE_ASSERT (pair->val->type == QSE_XLI_LIST); | ||||||
|  | 		proxy = (qse_xli_list_t*)pair->val; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.proxy")); | ||||||
|  | 	if (pair) | ||||||
|  | 	{ | ||||||
|  | 		QSE_ASSERT (pair->val->type == QSE_XLI_LIST); | ||||||
|  | 		default_proxy = (qse_xli_list_t*)pair->val; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	pair = QSE_NULL; | ||||||
|  | 	if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("http")); /* server.host[].location[].proxy.http */ | ||||||
|  | 	if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("http")); /* server-default.proxy.http */ | ||||||
|  | 	if (pair) cfg->proxy.allow_http = get_boolean ((qse_xli_str_t*)pair->val); | ||||||
|  |  | ||||||
|  | 	pair = QSE_NULL; | ||||||
|  | 	if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("connect")); | ||||||
|  | 	if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("connect")); | ||||||
|  | 	if (pair) cfg->proxy.allow_connect = get_boolean ((qse_xli_str_t*)pair->val); | ||||||
|  |  | ||||||
|  | 	pair = QSE_NULL; | ||||||
|  | 	if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("dns-server")); | ||||||
|  | 	if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("dns-server")); | ||||||
|  | 	if (pair)  | ||||||
|  | 	{ | ||||||
|  | 		qse_xli_str_t* str = (qse_xli_str_t*)pair->val; | ||||||
|  | 		if (qse_strtonwad (str->ptr, &cfg->proxy.dns_nwad) <= -1) | ||||||
|  | 		{ | ||||||
|  | 			qse_printf (QSE_T("ERROR: invalid address for proxy dns - %s"), str->ptr); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	pair = QSE_NULL; | ||||||
|  | 	if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("urs-server")); | ||||||
|  | 	if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("urs-server")); | ||||||
|  | 	if (pair) | ||||||
|  | 	{ | ||||||
|  | 		qse_xli_str_t* str = (qse_xli_str_t*)pair->val; | ||||||
|  | 		if (qse_strtonwad (str->ptr, &cfg->proxy.urs_nwad) <= -1) | ||||||
|  | 		{ | ||||||
|  | 			qse_printf (QSE_T("ERROR: invalid address for proxy urs - %s"), str->ptr); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int load_loccfg (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t* list, loccfg_t* cfg) | ||||||
|  | { | ||||||
|  | 	/*httpd_xtn_t* httpd_xtn; | ||||||
|  |  | ||||||
|  | 	httpd_xtn = qse_httpd_getxtnstd (httpd);*/ | ||||||
|  |  | ||||||
|  | 	if (load_loccfg_basic (httpd, xli, list, cfg) <= -1 || | ||||||
|  | 	    load_loccfg_index (httpd, xli, list, cfg) <= -1 || | ||||||
|  | 	    load_loccfg_cgi (httpd, xli, list, cfg) <= -1 || | ||||||
|  | 	    load_loccfg_authrule (httpd, xli, list, cfg) <= -1 || | ||||||
|  | 	    load_loccfg_mime (httpd, xli, list, cfg) <= -1 || | ||||||
|  | 	    load_loccfg_access (httpd, xli, list, cfg) <= -1 || | ||||||
|  | 	    load_loccfg_proxy (httpd, xli, list, cfg) <= -1) return -1; | ||||||
|  |  | ||||||
| #if 0 | #if 0 | ||||||
| 	/* TODO: perform more sanity check */ | 	/* TODO: perform more sanity check */ | ||||||
| @ -1416,6 +1470,16 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q | |||||||
| 	server_hostcfg_t* hostcfg; | 	server_hostcfg_t* hostcfg; | ||||||
| 	loccfg_t* loccfg; | 	loccfg_t* loccfg; | ||||||
|  |  | ||||||
|  | 	static struct | ||||||
|  | 	{ | ||||||
|  | 		const qse_char_t* x; | ||||||
|  | 		const qse_char_t* y; | ||||||
|  | 	} scfg_items[] = | ||||||
|  | 	{ | ||||||
|  | 		{ QSE_T("ssl-cert-file"),  QSE_T("server-default.ssl-cert-file") }, | ||||||
|  | 		{ QSE_T("ssl-key-file"),   QSE_T("server-default.ssl-key-file") } | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	static qse_htb_style_t cfgtab_style = | 	static qse_htb_style_t cfgtab_style = | ||||||
| 	{ | 	{ | ||||||
| 		{ | 		{ | ||||||
|  | |||||||
| @ -261,18 +261,20 @@ struct qse_httpd_scb_t | |||||||
| 	{ | 	{ | ||||||
| 		int (*open) (qse_httpd_t* httpd, qse_httpd_dns_t* dns); | 		int (*open) (qse_httpd_t* httpd, qse_httpd_dns_t* dns); | ||||||
| 		void (*close) (qse_httpd_t* httpd, qse_httpd_dns_t* dns); | 		void (*close) (qse_httpd_t* httpd, qse_httpd_dns_t* dns); | ||||||
| 		int (*recv) (qse_httpd_t* httpd, qse_httpd_dns_t* dns); | 		int (*recv) (qse_httpd_t* httpd, qse_httpd_dns_t* dns, qse_ubi_t handle); | ||||||
| 		int (*send) (qse_httpd_t* httpd, qse_httpd_dns_t* dns, | 		int (*send) (qse_httpd_t* httpd, qse_httpd_dns_t* dns, | ||||||
| 		             const qse_mchar_t* name, qse_httpd_resol_t resol, void* ctx); | 		             const qse_mchar_t* name, qse_httpd_resol_t resol, | ||||||
|  | 		             const qse_nwad_t* dns_server, void* ctx); | ||||||
| 	} dns; | 	} dns; | ||||||
|  |  | ||||||
| 	struct | 	struct | ||||||
| 	{ | 	{ | ||||||
| 		int (*open) (qse_httpd_t* httpd, qse_httpd_urs_t* urs); | 		int (*open) (qse_httpd_t* httpd, qse_httpd_urs_t* urs); | ||||||
| 		void (*close) (qse_httpd_t* httpd, qse_httpd_urs_t* urs); | 		void (*close) (qse_httpd_t* httpd, qse_httpd_urs_t* urs); | ||||||
| 		int (*recv) (qse_httpd_t* httpd, qse_httpd_urs_t* urs); | 		int (*recv) (qse_httpd_t* httpd, qse_httpd_urs_t* urs, qse_ubi_t handle); | ||||||
| 		int (*send) (qse_httpd_t* httpd, qse_httpd_urs_t* urs,  | 		int (*send) (qse_httpd_t* httpd, qse_httpd_urs_t* urs,  | ||||||
| 		             const qse_mchar_t* url, qse_httpd_rewrite_t rewrite, void* ctx); | 		             const qse_mchar_t* url, qse_httpd_rewrite_t rewrite, | ||||||
|  | 		             const qse_nwad_t* urs_server, void* ctx); | ||||||
| 	} urs; | 	} urs; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -503,7 +505,8 @@ struct qse_httpd_dns_t | |||||||
| 	QSE_HTTPD_MATE_HDR; | 	QSE_HTTPD_MATE_HDR; | ||||||
|  |  | ||||||
| 	/* == PUBLIC == */ | 	/* == PUBLIC == */ | ||||||
| 	qse_ubi_t handle; | 	qse_ubi_t handle[5]; | ||||||
|  | 	int handle_count; | ||||||
| 	void* ctx; | 	void* ctx; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -513,7 +516,8 @@ struct qse_httpd_urs_t | |||||||
| 	QSE_HTTPD_MATE_HDR; | 	QSE_HTTPD_MATE_HDR; | ||||||
|  |  | ||||||
| 	/* == PUBLIC == */ | 	/* == PUBLIC == */ | ||||||
| 	qse_ubi_t handle; | 	qse_ubi_t handle[5]; | ||||||
|  | 	int handle_count; | ||||||
| 	void* ctx; | 	void* ctx; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -558,7 +562,9 @@ enum qse_httpd_rsrc_proxy_flag_t | |||||||
| 	QSE_HTTPD_RSRC_PROXY_RAW         = (1 << 0), | 	QSE_HTTPD_RSRC_PROXY_RAW         = (1 << 0), | ||||||
| 	QSE_HTTPD_RSRC_PROXY_DST_STR     = (1 << 1), | 	QSE_HTTPD_RSRC_PROXY_DST_STR     = (1 << 1), | ||||||
| 	QSE_HTTPD_RSRC_PROXY_TRANSPARENT = (1 << 2), | 	QSE_HTTPD_RSRC_PROXY_TRANSPARENT = (1 << 2), | ||||||
| 	QSE_HTTPD_RSRC_PROXY_URS         = (1 << 3) /* url rewriting enabled */ | 	QSE_HTTPD_RSRC_PROXY_ENABLE_URS  = (1 << 3), /* url rewriting enabled */ | ||||||
|  | 	QSE_HTTPD_RSRC_PROXY_DNS_SERVER  = (1 << 4), | ||||||
|  | 	QSE_HTTPD_RSRC_PROXY_URS_SERVER  = (1 << 5) | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef struct qse_httpd_rsrc_proxy_t qse_httpd_rsrc_proxy_t; | typedef struct qse_httpd_rsrc_proxy_t qse_httpd_rsrc_proxy_t; | ||||||
| @ -577,6 +583,9 @@ struct qse_httpd_rsrc_proxy_t | |||||||
| 		const qse_mchar_t* str; | 		const qse_mchar_t* str; | ||||||
| 	} dst; /* remote destination address to connect to */ | 	} dst; /* remote destination address to connect to */ | ||||||
|  |  | ||||||
|  | 	qse_nwad_t dns_server; | ||||||
|  | 	qse_nwad_t urs_server; | ||||||
|  |  | ||||||
| 	const qse_mchar_t* pseudonym; /* pseudonym to use in Via: */ | 	const qse_mchar_t* pseudonym; /* pseudonym to use in Via: */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -1001,6 +1010,7 @@ QSE_EXPORT int qse_httpd_resolname ( | |||||||
| 	qse_httpd_t*       httpd, | 	qse_httpd_t*       httpd, | ||||||
| 	const qse_mchar_t* name, | 	const qse_mchar_t* name, | ||||||
| 	qse_httpd_resol_t  resol, | 	qse_httpd_resol_t  resol, | ||||||
|  | 	const qse_nwad_t*  dns_server, | ||||||
| 	void*              ctx | 	void*              ctx | ||||||
| ); | ); | ||||||
|  |  | ||||||
| @ -1008,6 +1018,7 @@ QSE_EXPORT int qse_httpd_rewriteurl ( | |||||||
| 	qse_httpd_t*         ttpd, | 	qse_httpd_t*         ttpd, | ||||||
| 	const qse_mchar_t*   url, | 	const qse_mchar_t*   url, | ||||||
| 	qse_httpd_rewrite_t  rewrite, | 	qse_httpd_rewrite_t  rewrite, | ||||||
|  | 	const qse_nwad_t*   urs_server, | ||||||
| 	void*                ctx | 	void*                ctx | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | |||||||
| @ -112,13 +112,6 @@ struct qse_httpd_serverstd_ssl_t | |||||||
| 	const qse_mchar_t* keyfile; | 	const qse_mchar_t* keyfile; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef struct qse_httpd_serverstd_proxy_t qse_httpd_serverstd_proxy_t; |  | ||||||
| struct qse_httpd_serverstd_proxy_t |  | ||||||
| { |  | ||||||
| 	int tproxy: 1; |  | ||||||
| 	const qse_mchar_t* pseudonym; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum qse_httpd_serverstd_query_code_t | enum qse_httpd_serverstd_query_code_t | ||||||
| { | { | ||||||
| 	QSE_HTTPD_SERVERSTD_SSL,             /* qse_httpd_serverstd_ssl_t */ | 	QSE_HTTPD_SERVERSTD_SSL,             /* qse_httpd_serverstd_ssl_t */ | ||||||
|  | |||||||
| @ -38,19 +38,21 @@ struct task_proxy_t | |||||||
| #define PROXY_INIT_FAILED          (1 << 0) | #define PROXY_INIT_FAILED          (1 << 0) | ||||||
| #define PROXY_RAW                  (1 << 1) | #define PROXY_RAW                  (1 << 1) | ||||||
| #define PROXY_TRANSPARENT          (1 << 2) | #define PROXY_TRANSPARENT          (1 << 2) | ||||||
| #define PROXY_OUTBAND_PEER_NAME    (1 << 3) /* the peer_name pointer points to | #define PROXY_DNS_SERVER           (1 << 3) /* dns server address specified */ | ||||||
|  | #define PROXY_URS_SERVER           (1 << 4) /* urs server address specified */ | ||||||
|  | #define PROXY_OUTBAND_PEER_NAME    (1 << 5) /* the peer_name pointer points to | ||||||
|                                                a separate memory chunk outside |                                                a separate memory chunk outside | ||||||
|                                                the task_proxy_t chunk. explicit |                                                the task_proxy_t chunk. explicit | ||||||
|                                                deallocatin is required */ |                                                deallocatin is required */ | ||||||
| #define PROXY_RESOLVE_PEER_NAME    (1 << 4) | #define PROXY_RESOLVE_PEER_NAME    (1 << 6) | ||||||
| #define PROXY_PEER_NAME_RESOLVED   (1 << 5) | #define PROXY_PEER_NAME_RESOLVED   (1 << 7) | ||||||
| #define PROXY_PEER_NAME_UNRESOLVED (1 << 6) | #define PROXY_PEER_NAME_UNRESOLVED (1 << 8) | ||||||
| #define PROXY_REWRITE_URL          (1 << 7) | #define PROXY_REWRITE_URL          (1 << 9) | ||||||
| #define PROXY_URL_REWRITTEN        (1 << 8) | #define PROXY_URL_REWRITTEN        (1 << 10) | ||||||
| #define PROXY_URL_REDIRECTED       (1 << 9) | #define PROXY_URL_REDIRECTED       (1 << 11) | ||||||
| #define PROXY_X_FORWARDED_FOR      (1 << 10) /* X-Forwarded-For added */ | #define PROXY_X_FORWARDED_FOR      (1 << 12) /* X-Forwarded-For added */ | ||||||
| #define PROXY_VIA                  (1 << 11) /* Via added to the request */ | #define PROXY_VIA                  (1 << 13) /* Via added to the request */ | ||||||
| #define PROXY_VIA_RETURNING        (1 << 12) /* Via added to the response */ | #define PROXY_VIA_RETURNING        (1 << 14) /* 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; | ||||||
| @ -64,6 +66,8 @@ struct task_proxy_t | |||||||
| 	qse_size_t qpath_pos_in_reqfwdbuf; | 	qse_size_t qpath_pos_in_reqfwdbuf; | ||||||
| 	qse_size_t qpath_len_in_reqfwdbuf; | 	qse_size_t qpath_len_in_reqfwdbuf; | ||||||
|  |  | ||||||
|  | 	qse_nwad_t dns_server; | ||||||
|  | 	qse_nwad_t urs_server; | ||||||
| 	qse_mchar_t* pseudonym; | 	qse_mchar_t* pseudonym; | ||||||
| 	qse_htrd_t* peer_htrd; | 	qse_htrd_t* peer_htrd; | ||||||
|  |  | ||||||
| @ -939,7 +943,18 @@ static int task_init_proxy ( | |||||||
| 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_RAW) proxy->flags |= PROXY_RAW; | 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_RAW) proxy->flags |= PROXY_RAW; | ||||||
| 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_TRANSPARENT) proxy->flags |= PROXY_TRANSPARENT; | 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_TRANSPARENT) proxy->flags |= PROXY_TRANSPARENT; | ||||||
|  |  | ||||||
| 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_URS) | 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_DNS_SERVER) | ||||||
|  | 	{ | ||||||
|  | 		proxy->flags |= PROXY_DNS_SERVER; | ||||||
|  | 		proxy->dns_server = arg->rsrc->dns_server; | ||||||
|  | 	} | ||||||
|  | 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_URS_SERVER) | ||||||
|  | 	{ | ||||||
|  | 		proxy->flags |= PROXY_URS_SERVER; | ||||||
|  | 		proxy->urs_server = arg->rsrc->urs_server; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_ENABLE_URS) | ||||||
| 	{ | 	{ | ||||||
| 		const qse_mchar_t* qpath; | 		const qse_mchar_t* qpath; | ||||||
| 		const qse_mchar_t* metnam; | 		const qse_mchar_t* metnam; | ||||||
| @ -2063,7 +2078,8 @@ static int task_main_proxy ( | |||||||
| 	if (proxy->flags & PROXY_REWRITE_URL) | 	if (proxy->flags & PROXY_REWRITE_URL) | ||||||
| 	{ | 	{ | ||||||
| 		/* note that url_to_rewrite is URL + extra information. */ | 		/* note that url_to_rewrite is URL + extra information. */ | ||||||
| 		if (qse_httpd_rewriteurl (httpd, proxy->url_to_rewrite, on_url_rewritten, task) <= -1) goto oops; | 		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; | ||||||
|  |  | ||||||
| 		if (proxy->flags & PROXY_INIT_FAILED) goto oops; | 		if (proxy->flags & PROXY_INIT_FAILED) goto oops; | ||||||
| 		 | 		 | ||||||
| @ -2079,7 +2095,8 @@ static int task_main_proxy ( | |||||||
|  |  | ||||||
| 		QSE_ASSERT (proxy->peer_name != QSE_NULL); | 		QSE_ASSERT (proxy->peer_name != QSE_NULL); | ||||||
|  |  | ||||||
| 		if (qse_httpd_resolname (httpd, proxy->peer_name, on_peer_name_resolved, task) <= -1) goto oops; | 		if (qse_httpd_resolname (httpd, proxy->peer_name, on_peer_name_resolved,  | ||||||
|  | 		                         ((proxy->flags & PROXY_DNS_SERVER)? &proxy->dns_server: QSE_NULL), task) <= -1) goto oops; | ||||||
|  |  | ||||||
| 		/* if the name could be resolved without sending a request  | 		/* if the name could be resolved without sending a request  | ||||||
| 		 * in qse_httpd_resolname(), on_peer_name_resolve would be  | 		 * in qse_httpd_resolname(), on_peer_name_resolve would be  | ||||||
|  | |||||||
| @ -129,6 +129,7 @@ struct dns_ctx_t | |||||||
|  |  | ||||||
| 	qse_skad_t skad; | 	qse_skad_t skad; | ||||||
| 	int skadlen; | 	int skadlen; | ||||||
|  | 	int dns_socket; | ||||||
|  |  | ||||||
| 	qse_uint16_t seq; | 	qse_uint16_t seq; | ||||||
| 	dns_req_t* reqs[2048]; /* TOOD: choose the right size or make it configurable. must be < DNS_SEQ_RANGE_SIZE */ | 	dns_req_t* reqs[2048]; /* TOOD: choose the right size or make it configurable. must be < DNS_SEQ_RANGE_SIZE */ | ||||||
| @ -161,6 +162,10 @@ struct dns_req_t | |||||||
| 	int qaaaalen; | 	int qaaaalen; | ||||||
|  |  | ||||||
| 	dns_ctx_t* dc; | 	dns_ctx_t* dc; | ||||||
|  | 	qse_skad_t dns_skad; | ||||||
|  | 	int dns_skadlen; | ||||||
|  | 	int dns_socket; | ||||||
|  |  | ||||||
| 	qse_tmr_index_t tmr_tmout; | 	qse_tmr_index_t tmr_tmout; | ||||||
| 	int resends; | 	int resends; | ||||||
|  |  | ||||||
| @ -281,8 +286,6 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns) | |||||||
| 	qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); | 	qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); | ||||||
| 	return -1; | 	return -1; | ||||||
| #else | #else | ||||||
| 	sock_t fd = SOCK_INIT;  |  | ||||||
| 	int flag; |  | ||||||
| 	qse_nwad_t nwad; | 	qse_nwad_t nwad; | ||||||
| 	dns_ctx_t* dc; | 	dns_ctx_t* dc; | ||||||
| 	httpd_xtn_t* httpd_xtn; | 	httpd_xtn_t* httpd_xtn; | ||||||
| @ -355,53 +358,45 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns) | |||||||
| 		qse_httpd_act_t msg; | 		qse_httpd_act_t msg; | ||||||
| 		qse_size_t pos; | 		qse_size_t pos; | ||||||
| 		msg.code = QSE_HTTPD_CATCH_MDBGMSG; | 		msg.code = QSE_HTTPD_CATCH_MDBGMSG; | ||||||
| 		pos = qse_mbsxcpy (msg.u.mdbgmsg, QSE_COUNTOF(msg.u.mdbgmsg), "nameserver set to "); | 		pos = qse_mbsxcpy (msg.u.mdbgmsg, QSE_COUNTOF(msg.u.mdbgmsg), "global nameserver set to "); | ||||||
| 		qse_nwadtombs (&nwad, &msg.u.mdbgmsg[pos], QSE_COUNTOF(msg.u.mdbgmsg) - pos, QSE_NWADTOMBS_ALL); | 		qse_nwadtombs (&nwad, &msg.u.mdbgmsg[pos], QSE_COUNTOF(msg.u.mdbgmsg) - pos, QSE_NWADTOMBS_ALL); | ||||||
| 		httpd->opt.rcb.logact (httpd, &msg); | 		httpd->opt.rcb.logact (httpd, &msg); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fd = socket (qse_skadfamily(&dc->skad), SOCK_DGRAM, IPPROTO_UDP); | 	dns->handle[0].i = open_udp_socket (httpd, AF_INET); | ||||||
| 	if (!is_valid_socket(fd))  | #if defined(AF_INET6) | ||||||
|  | 	dns->handle[1].i = open_udp_socket (httpd, AF_INET6); | ||||||
|  | #endif | ||||||
|  | 	if (!is_valid_socket(dns->handle[0].i) &&  | ||||||
|  | 	    !is_valid_socket(dns->handle[1].i)) | ||||||
| 	{ | 	{ | ||||||
| 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); |  | ||||||
| 		goto oops; | 		goto oops; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	#if defined(FD_CLOEXEC) | 	if (nwad.type == QSE_NWAD_IN4) | ||||||
| 	flag = fcntl (fd, F_GETFD); | 		dc->dns_socket = dns->handle[0].i; | ||||||
| 	if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC); | 	else | ||||||
| 	#endif | 		dc->dns_socket = dns->handle[1].i; | ||||||
|  |  | ||||||
| 	#if defined(SO_REUSEADDR) | 	dns->handle_count = 2; | ||||||
| 	flag = 1; |  | ||||||
| 	setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (void*)&flag, QSE_SIZEOF(flag)); |  | ||||||
| 	#endif |  | ||||||
| 	 |  | ||||||
| 	#if defined(SO_REUSEPORT) |  | ||||||
| 	flag = 1; |  | ||||||
| 	setsockopt (fd, SOL_SOCKET, SO_REUSEPORT, (void*)&flag, QSE_SIZEOF(flag)); |  | ||||||
| 	#endif |  | ||||||
|  |  | ||||||
| 	if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops; |  | ||||||
|  |  | ||||||
| 	dns->handle.i = fd; |  | ||||||
| 	dns->ctx = dc; | 	dns->ctx = dc; | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
| oops: | oops: | ||||||
| 	if (is_valid_socket(fd)) close_socket (fd); | 	if (is_valid_socket(dns->handle[0].i)) close_socket (dns->handle[0].i); | ||||||
|  | 	if (is_valid_socket(dns->handle[1].i)) close_socket (dns->handle[1].i); | ||||||
| 	if (dc) qse_httpd_freemem (httpd, dc); | 	if (dc) qse_httpd_freemem (httpd, dc); | ||||||
| 	return -1; | 	return -1; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| static void dns_remove_tmr_tmout (dns_req_t* req) | static void dns_remove_tmr_tmout (qse_httpd_t* httpd, dns_req_t* req) | ||||||
| { | { | ||||||
| 	if (req->tmr_tmout != QSE_TMR_INVALID_INDEX) | 	if (req->tmr_tmout != QSE_TMR_INVALID_INDEX) | ||||||
| 	{ | 	{ | ||||||
| 		qse_httpd_removetimerevent (req->dc->httpd, req->tmr_tmout); | 		qse_httpd_removetimerevent (httpd, req->tmr_tmout); | ||||||
| 		req->tmr_tmout = QSE_TMR_INVALID_INDEX; | 		req->tmr_tmout = QSE_TMR_INVALID_INDEX; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -418,7 +413,7 @@ static void dns_close (qse_httpd_t* httpd, qse_httpd_dns_t* dns) | |||||||
| 		{ | 		{ | ||||||
| 			next_req = dc->reqs[i]->next; | 			next_req = dc->reqs[i]->next; | ||||||
|  |  | ||||||
| 			dns_remove_tmr_tmout (dc->reqs[i]); | 			dns_remove_tmr_tmout (httpd, 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; | ||||||
| @ -439,12 +434,14 @@ static void dns_close (qse_httpd_t* httpd, qse_httpd_dns_t* dns) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	close_socket (dns->handle.i); | 	for (i = 0; i < dns->handle_count; i++)  | ||||||
|  | 	{ | ||||||
|  | 		if (is_valid_socket(dns->handle[i].i)) | ||||||
|  | 			close_socket (dns->handle[i].i); | ||||||
|  | 	} | ||||||
| 	qse_httpd_freemem (httpd, dns->ctx); | 	qse_httpd_freemem (httpd, dns->ctx); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static void dns_cache_answer (dns_ctx_t* dc, dns_req_t* req, const qse_nwad_t* nwad, qse_uint32_t ttl) | 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; | 	dns_ans_t* ans, * prv, * cur; | ||||||
| @ -529,7 +526,7 @@ static dns_ans_t* dns_get_answer_from_cache (dns_ctx_t* dc, const qse_mchar_t* n | |||||||
| 	return QSE_NULL; | 	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, qse_ubi_t handle) | ||||||
| { | { | ||||||
| 	dns_ctx_t* dc = (dns_ctx_t*)dns->ctx; | 	dns_ctx_t* dc = (dns_ctx_t*)dns->ctx; | ||||||
| 	httpd_xtn_t* httpd_xtn; | 	httpd_xtn_t* httpd_xtn; | ||||||
| @ -559,9 +556,7 @@ printf ("DNS_RECV....\n"); | |||||||
| 	httpd_xtn = qse_httpd_getxtn (httpd); | 	httpd_xtn = qse_httpd_getxtn (httpd); | ||||||
|  |  | ||||||
| 	fromlen = QSE_SIZEOF(fromaddr); | 	fromlen = QSE_SIZEOF(fromaddr); | ||||||
| 	len = recvfrom (dns->handle.i, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&fromaddr, &fromlen); | 	len = recvfrom (handle.i, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&fromaddr, &fromlen); | ||||||
|  |  | ||||||
| /* TODO: check if fromaddr matches the dc->skad... */ |  | ||||||
|  |  | ||||||
| 	if (len < QSE_SIZEOF(*hdr)) goto done; /* packet too small */ | 	if (len < QSE_SIZEOF(*hdr)) goto done; /* packet too small */ | ||||||
|  |  | ||||||
| @ -606,6 +601,7 @@ printf ("DNS_RECV....\n"); | |||||||
| 					if ((id == req->seqa || id == req->seqaaaa) && | 					if ((id == req->seqa || id == req->seqaaaa) && | ||||||
| 					    req->dnlen == dnlen && QSE_MEMCMP (req->dn, plptr, req->dnlen) == 0)  | 					    req->dnlen == dnlen && QSE_MEMCMP (req->dn, plptr, req->dnlen) == 0)  | ||||||
| 					{ | 					{ | ||||||
|  | /* TODO: check if fromadd/fromlen matches req->dns_skad/req->dns_skadlen */ | ||||||
| 						/* found a match. note that the test here is a bit loose | 						/* found a match. note that the test here is a bit loose | ||||||
| 						 * in that it doesn't really check if the original question  | 						 * in that it doesn't really check if the original question  | ||||||
| 						 * was A or AAAA. it is possible that it can process an AAAA answer | 						 * was A or AAAA. it is possible that it can process an AAAA answer | ||||||
| @ -700,7 +696,7 @@ resolved: | |||||||
| 	QSE_ASSERT (req != QSE_NULL); | 	QSE_ASSERT (req != QSE_NULL); | ||||||
| 	QSE_ASSERT (xid >= 0 && xid < QSE_COUNTOF(dc->reqs)); | 	QSE_ASSERT (xid >= 0 && xid < QSE_COUNTOF(dc->reqs)); | ||||||
|  |  | ||||||
| 	dns_remove_tmr_tmout (req); | 	dns_remove_tmr_tmout (httpd, req); | ||||||
| 	req->resol (httpd, req->name, resolved_nwad, req->ctx); | 	req->resol (httpd, req->name, resolved_nwad, req->ctx); | ||||||
|  |  | ||||||
| 	/* detach the request off dc->reqs */ | 	/* detach the request off dc->reqs */ | ||||||
| @ -753,8 +749,8 @@ printf (">>tmr_dns_tmout_handle  req->>%p\n", req); | |||||||
| 		tmout_event.handler = tmr_dns_tmout_handle; | 		tmout_event.handler = tmr_dns_tmout_handle; | ||||||
| 		tmout_event.updater = tmr_dns_tmout_update; | 		tmout_event.updater = tmr_dns_tmout_update; | ||||||
|  |  | ||||||
| 		if ((!(req->flags & DNS_REQ_A_NX) && req->qalen > 0 && sendto (dc->dns->handle.i, req->qa, req->qalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qalen) || | 		if ((!(req->flags & DNS_REQ_A_NX) && req->qalen > 0 && sendto (req->dns_socket, req->qa, req->qalen, 0, (struct sockaddr*)&req->dns_skad, req->dns_skadlen) != req->qalen) || | ||||||
| 			(!(req->flags & DNS_REQ_AAAA_NX) && req->qaaaalen > 0 && sendto (dc->dns->handle.i, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qaaaalen)) | 			(!(req->flags & DNS_REQ_AAAA_NX) && req->qaaaalen > 0 && sendto (req->dns_socket, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&req->dns_skad, req->dns_skadlen) != req->qaaaalen)) | ||||||
| 		{ | 		{ | ||||||
| 			/* resend failed. fall thru and destroy the request*/ | 			/* resend failed. fall thru and destroy the request*/ | ||||||
| 		} | 		} | ||||||
| @ -792,7 +788,7 @@ printf (">>tmr_dns_tmout_handle  req->>%p\n", req); | |||||||
| 	dc->req_count--; | 	dc->req_count--; | ||||||
| } | } | ||||||
|  |  | ||||||
| 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, const qse_nwad_t* dns_server, void* ctx) | ||||||
| { | { | ||||||
| 	dns_ctx_t* dc = (dns_ctx_t*)dns->ctx; | 	dns_ctx_t* dc = (dns_ctx_t*)dns->ctx; | ||||||
| 	httpd_xtn_t* httpd_xtn; | 	httpd_xtn_t* httpd_xtn; | ||||||
| @ -870,6 +866,29 @@ printf ("DNS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n"); | |||||||
| 		goto oops; | 		goto oops; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (dns_server)  | ||||||
|  | 	{ | ||||||
|  | printf ("GETTING DNS_SERVER XXXXXXXXXXXXXXXXXXXXXXX\n"); | ||||||
|  | 		req->dns_skadlen = qse_nwadtoskad (dns_server, &req->dns_skad); | ||||||
|  | 		if (req->dns_skadlen <= -1) | ||||||
|  | 		{ | ||||||
|  | 			qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL); | ||||||
|  | 			goto oops; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (dns_server->type == QSE_NWAD_IN4) | ||||||
|  | 			req->dns_socket = dns->handle[0].i; | ||||||
|  | 		else  | ||||||
|  | 			req->dns_socket = dns->handle[1].i; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | printf ("GETTING DNS_SERVER XXXXXXXXXXXXXXXXXXXXXXX GLOBAL XXXXXXXXXXXXXXXXXXXXXX\n"); | ||||||
|  | 		req->dns_skad = dc->skad; | ||||||
|  | 		req->dns_skadlen = dc->skadlen; | ||||||
|  | 		req->dns_socket = dc->dns_socket; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	req->resends = httpd_xtn->dns.resends; | 	req->resends = httpd_xtn->dns.resends; | ||||||
|  |  | ||||||
| 	qse_gettime (&tmout_event.when); | 	qse_gettime (&tmout_event.when); | ||||||
| @ -879,8 +898,8 @@ printf ("DNS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n"); | |||||||
| 	tmout_event.updater = tmr_dns_tmout_update; | 	tmout_event.updater = tmr_dns_tmout_update; | ||||||
| 	if (qse_httpd_inserttimerevent (httpd, &tmout_event, &req->tmr_tmout) <= -1) goto oops; | 	if (qse_httpd_inserttimerevent (httpd, &tmout_event, &req->tmr_tmout) <= -1) goto oops; | ||||||
|  |  | ||||||
| 	if ((req->qalen > 0 && sendto (dns->handle.i, req->qa, req->qalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qalen) || | 	if ((req->qalen > 0 && sendto (req->dns_socket, req->qa, req->qalen, 0, (struct sockaddr*)&req->dns_skad, req->dns_skadlen) != req->qalen) || | ||||||
| 	    (req->qaaaalen > 0 && sendto (dns->handle.i, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qaaaalen)) | 	    (req->qaaaalen > 0 && sendto (req->dns_socket, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&req->dns_skad, req->dns_skadlen) != req->qaaaalen)) | ||||||
| 	{ | 	{ | ||||||
| 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); | 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); | ||||||
| 		goto oops; | 		goto oops; | ||||||
| @ -908,7 +927,7 @@ printf ("DNS REALLY SENT>>>>>>>>>>>>>>>>>>>>>>>\n"); | |||||||
| oops: | oops: | ||||||
| 	if (req) | 	if (req) | ||||||
| 	{ | 	{ | ||||||
| 		dns_remove_tmr_tmout (req); | 		dns_remove_tmr_tmout (httpd, req); | ||||||
| 		qse_httpd_freemem (httpd, req); | 		qse_httpd_freemem (httpd, req); | ||||||
| 	} | 	} | ||||||
| 	return -1; | 	return -1; | ||||||
|  | |||||||
| @ -53,6 +53,7 @@ struct urs_ctx_t | |||||||
|  |  | ||||||
| 	qse_skad_t skad; | 	qse_skad_t skad; | ||||||
| 	int skadlen; | 	int skadlen; | ||||||
|  | 	int urs_socket; | ||||||
|  |  | ||||||
| 	qse_uint16_t seq; /* TODO: change to uint32_t??? */ | 	qse_uint16_t seq; /* TODO: change to uint32_t??? */ | ||||||
| 	urs_req_t* reqs[1024]; /* TOOD: choose the right size */ | 	urs_req_t* reqs[1024]; /* TOOD: choose the right size */ | ||||||
| @ -72,6 +73,10 @@ struct urs_req_t | |||||||
| 	void* ctx; | 	void* ctx; | ||||||
|  |  | ||||||
| 	urs_ctx_t* dc; | 	urs_ctx_t* dc; | ||||||
|  | 	qse_skad_t urs_skad; | ||||||
|  | 	int urs_skadlen; | ||||||
|  | 	int urs_socket; | ||||||
|  |  | ||||||
| 	qse_tmr_index_t tmr_tmout; | 	qse_tmr_index_t tmr_tmout; | ||||||
| 	int resends; | 	int resends; | ||||||
|  |  | ||||||
| @ -86,8 +91,6 @@ static int urs_open (qse_httpd_t* httpd, qse_httpd_urs_t* urs) | |||||||
| 	qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); | 	qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); | ||||||
| 	return -1; | 	return -1; | ||||||
| #else | #else | ||||||
| 	sock_t fd = SOCK_INIT;  |  | ||||||
| 	int flag; |  | ||||||
| 	qse_nwad_t nwad; | 	qse_nwad_t nwad; | ||||||
| 	urs_ctx_t* dc; | 	urs_ctx_t* dc; | ||||||
| 	httpd_xtn_t* httpd_xtn; | 	httpd_xtn_t* httpd_xtn; | ||||||
| @ -127,49 +130,40 @@ static int urs_open (qse_httpd_t* httpd, qse_httpd_urs_t* urs) | |||||||
| 		httpd->opt.rcb.logact (httpd, &msg); | 		httpd->opt.rcb.logact (httpd, &msg); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fd = socket (qse_skadfamily(&dc->skad), SOCK_DGRAM, IPPROTO_UDP); | 	urs->handle[0].i = open_udp_socket (httpd, AF_INET); | ||||||
| 	if (!is_valid_socket(fd))  | #if defined(AF_INET6) | ||||||
|  | 	urs->handle[1].i = open_udp_socket (httpd, AF_INET6); | ||||||
|  | #endif | ||||||
|  | 	if (!is_valid_socket(urs->handle[0].i) &&  | ||||||
|  | 	    !is_valid_socket(urs->handle[1].i)) | ||||||
| 	{ | 	{ | ||||||
| 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); |  | ||||||
| 		goto oops; | 		goto oops; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| /* TODO: set socket send/recv buffer size. it's needed as urs may be long */ | 	if (nwad.type == QSE_NWAD_IN4) | ||||||
|  | 		dc->urs_socket = urs->handle[0].i; | ||||||
|  | 	else | ||||||
|  | 		dc->urs_socket = urs->handle[1].i; | ||||||
|  |  | ||||||
| 	#if defined(FD_CLOEXEC) | 	urs->handle_count = 2; | ||||||
| 	flag = fcntl (fd, F_GETFD); |  | ||||||
| 	if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC); |  | ||||||
| 	#endif |  | ||||||
|  |  | ||||||
| 	#if defined(SO_REUSEADDR) |  | ||||||
| 	flag = 1; |  | ||||||
| 	setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (void*)&flag, QSE_SIZEOF(flag)); |  | ||||||
| 	#endif |  | ||||||
| 	 |  | ||||||
| 	#if defined(SO_REUSEPORT) |  | ||||||
| 	flag = 1; |  | ||||||
| 	setsockopt (fd, SOL_SOCKET, SO_REUSEPORT, (void*)&flag, QSE_SIZEOF(flag)); |  | ||||||
| 	#endif |  | ||||||
|  |  | ||||||
| 	if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops; |  | ||||||
| 	 |  | ||||||
| 	urs->handle.i = fd; |  | ||||||
| 	urs->ctx = dc; | 	urs->ctx = dc; | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
| oops: | oops: | ||||||
| 	if (is_valid_socket(fd)) close_socket (fd); | 	if (is_valid_socket(urs->handle[0].i)) close_socket (urs->handle[0].i); | ||||||
|  | 	if (is_valid_socket(urs->handle[1].i)) close_socket (urs->handle[1].i); | ||||||
| 	if (dc) qse_httpd_freemem (httpd, dc); | 	if (dc) qse_httpd_freemem (httpd, dc); | ||||||
| 	return -1; | 	return -1; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| static void urs_remove_tmr_tmout (urs_req_t* req) | static void urs_remove_tmr_tmout (qse_httpd_t* httpd, urs_req_t* req) | ||||||
| { | { | ||||||
| 	if (req->tmr_tmout != QSE_TMR_INVALID_INDEX) | 	if (req->tmr_tmout != QSE_TMR_INVALID_INDEX) | ||||||
| 	{ | 	{ | ||||||
| 		qse_httpd_removetimerevent (req->dc->httpd, req->tmr_tmout); | 		qse_httpd_removetimerevent (httpd, req->tmr_tmout); | ||||||
| 		req->tmr_tmout = QSE_TMR_INVALID_INDEX; | 		req->tmr_tmout = QSE_TMR_INVALID_INDEX; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -185,7 +179,7 @@ static void urs_close (qse_httpd_t* httpd, qse_httpd_urs_t* urs) | |||||||
| 		while (dc->reqs[i]) | 		while (dc->reqs[i]) | ||||||
| 		{ | 		{ | ||||||
| 			next_req = dc->reqs[i]->next; | 			next_req = dc->reqs[i]->next; | ||||||
| 			urs_remove_tmr_tmout (dc->reqs[i]); | 			urs_remove_tmr_tmout (httpd, 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; | ||||||
| 			dc->req_count--; | 			dc->req_count--; | ||||||
| @ -194,12 +188,17 @@ static void urs_close (qse_httpd_t* httpd, qse_httpd_urs_t* urs) | |||||||
|  |  | ||||||
| 	QSE_ASSERT (dc->req_count == 0); | 	QSE_ASSERT (dc->req_count == 0); | ||||||
|  |  | ||||||
| 	close_socket (urs->handle.i); | 	for (i = 0; i < urs->handle_count; i++)  | ||||||
|  | 	{ | ||||||
|  | 		if (is_valid_socket(urs->handle[i].i))  | ||||||
|  | 			close_socket (urs->handle[i].i); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	qse_httpd_freemem (httpd, urs->ctx); | 	qse_httpd_freemem (httpd, urs->ctx); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| static int urs_recv (qse_httpd_t* httpd, qse_httpd_urs_t* urs) | static int urs_recv (qse_httpd_t* httpd, qse_httpd_urs_t* urs, qse_ubi_t handle) | ||||||
| { | { | ||||||
| 	urs_ctx_t* dc = (urs_ctx_t*)urs->ctx; | 	urs_ctx_t* dc = (urs_ctx_t*)urs->ctx; | ||||||
| 	httpd_xtn_t* httpd_xtn; | 	httpd_xtn_t* httpd_xtn; | ||||||
| @ -217,7 +216,7 @@ printf ("URS_RECV....\n"); | |||||||
| 	httpd_xtn = qse_httpd_getxtn (httpd); | 	httpd_xtn = qse_httpd_getxtn (httpd); | ||||||
|  |  | ||||||
| 	fromlen = QSE_SIZEOF(fromaddr); | 	fromlen = QSE_SIZEOF(fromaddr); | ||||||
| 	len = recvfrom (urs->handle.i, dc->rcvbuf, QSE_SIZEOF(dc->rcvbuf) - 1, 0, (struct sockaddr*)&fromaddr, &fromlen); | 	len = recvfrom (handle.i, dc->rcvbuf, QSE_SIZEOF(dc->rcvbuf) - 1, 0, (struct sockaddr*)&fromaddr, &fromlen); | ||||||
|  |  | ||||||
| /* TODO: check if fromaddr matches the dc->skad... */ | /* TODO: check if fromaddr matches the dc->skad... */ | ||||||
|  |  | ||||||
| @ -232,7 +231,7 @@ printf ("URS_RECV....\n"); | |||||||
| 			{ | 			{ | ||||||
| 				pkt->url[qse_ntoh16(pkt->hdr.len)] = QSE_MT('\0'); | 				pkt->url[qse_ntoh16(pkt->hdr.len)] = QSE_MT('\0'); | ||||||
|  |  | ||||||
| 				urs_remove_tmr_tmout (req); | 				urs_remove_tmr_tmout (httpd, req); | ||||||
| 				req->rewrite (httpd, req->pkt->url, pkt->url, req->ctx); | 				req->rewrite (httpd, req->pkt->url, pkt->url, req->ctx); | ||||||
|  |  | ||||||
| 				/* detach the request off dc->reqs */ | 				/* detach the request off dc->reqs */ | ||||||
| @ -287,7 +286,7 @@ static void tmr_urs_tmout_handle (qse_tmr_t* tmr, const qse_ntime_t* now, void* | |||||||
| 		tmout_event.handler = tmr_urs_tmout_handle; | 		tmout_event.handler = tmr_urs_tmout_handle; | ||||||
| 		tmout_event.updater = tmr_urs_tmout_update; | 		tmout_event.updater = tmr_urs_tmout_update; | ||||||
|  |  | ||||||
| 		if (sendto (dc->urs->handle.i, req->pkt, req->pktlen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->pktlen) | 		if (sendto (req->urs_socket, req->pkt, req->pktlen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->pktlen) | ||||||
| 		{ | 		{ | ||||||
| 			/* error. fall thru */ | 			/* error. fall thru */ | ||||||
| 		} | 		} | ||||||
| @ -321,7 +320,7 @@ printf ("urs timed out....\n"); | |||||||
| 	dc->req_count--; | 	dc->req_count--; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int urs_send (qse_httpd_t* httpd, qse_httpd_urs_t* urs, const qse_mchar_t* url, qse_httpd_rewrite_t rewrite, void* ctx) | static int urs_send (qse_httpd_t* httpd, qse_httpd_urs_t* urs, const qse_mchar_t* url, qse_httpd_rewrite_t rewrite, const qse_nwad_t* urs_server, void* ctx) | ||||||
| { | { | ||||||
| 	urs_ctx_t* dc = (urs_ctx_t*)urs->ctx; | 	urs_ctx_t* dc = (urs_ctx_t*)urs->ctx; | ||||||
| 	httpd_xtn_t* httpd_xtn; | 	httpd_xtn_t* httpd_xtn; | ||||||
| @ -374,6 +373,27 @@ printf ("URS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n"); | |||||||
| 	req->ctx = ctx; | 	req->ctx = ctx; | ||||||
| 	req->resends = httpd_xtn->urs.resends; | 	req->resends = httpd_xtn->urs.resends; | ||||||
|  |  | ||||||
|  | 	if (urs_server)  | ||||||
|  | 	{ | ||||||
|  | 		req->urs_skadlen = qse_nwadtoskad (urs_server, &req->urs_skad); | ||||||
|  | 		if (req->urs_skadlen <= -1) | ||||||
|  | 		{ | ||||||
|  | 			qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL); | ||||||
|  | 			goto oops; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (urs_server->type == QSE_NWAD_IN4) | ||||||
|  | 			req->urs_socket = urs->handle[0].i; | ||||||
|  | 		else  | ||||||
|  | 			req->urs_socket = urs->handle[1].i; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		req->urs_skad = dc->skad; | ||||||
|  | 		req->urs_skadlen = dc->skadlen; | ||||||
|  | 		req->urs_socket = dc->urs_socket; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	qse_gettime (&tmout_event.when); | 	qse_gettime (&tmout_event.when); | ||||||
| 	qse_addtime (&tmout_event.when, &httpd_xtn->urs.tmout, &tmout_event.when); | 	qse_addtime (&tmout_event.when, &httpd_xtn->urs.tmout, &tmout_event.when); | ||||||
| 	tmout_event.ctx = req; | 	tmout_event.ctx = req; | ||||||
| @ -381,7 +401,7 @@ printf ("URS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n"); | |||||||
| 	tmout_event.updater = tmr_urs_tmout_update; | 	tmout_event.updater = tmr_urs_tmout_update; | ||||||
| 	if (qse_httpd_inserttimerevent (httpd, &tmout_event, &req->tmr_tmout) <= -1) goto oops; | 	if (qse_httpd_inserttimerevent (httpd, &tmout_event, &req->tmr_tmout) <= -1) goto oops; | ||||||
|  |  | ||||||
| 	if (sendto (urs->handle.i, req->pkt, req->pktlen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->pktlen) | 	if (sendto (req->urs_socket, req->pkt, req->pktlen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->pktlen) | ||||||
| 	{ | 	{ | ||||||
| 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); | 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); | ||||||
| 		goto oops; | 		goto oops; | ||||||
| @ -403,7 +423,7 @@ printf ("URS REALLY SENT>>>>>>>>>>>>>>>>>>>>>>>\n"); | |||||||
| oops: | oops: | ||||||
| 	if (req) | 	if (req) | ||||||
| 	{ | 	{ | ||||||
| 		urs_remove_tmr_tmout (req); | 		urs_remove_tmr_tmout (httpd, req); | ||||||
| 		qse_httpd_freemem (httpd, req); | 		qse_httpd_freemem (httpd, req); | ||||||
| 	} | 	} | ||||||
| 	return -1; | 	return -1; | ||||||
|  | |||||||
| @ -650,10 +650,10 @@ void* qse_httpd_getxtnstd (qse_httpd_t* httpd) | |||||||
|  |  | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| 	typedef SOCKET sock_t; | 	typedef SOCKET sock_t; | ||||||
| #	define SOCK_INIT INVALID_SOCKET | #	define SOCK_INVALID INVALID_SOCKET | ||||||
| #else | #else | ||||||
| 	typedef int sock_t; | 	typedef int sock_t; | ||||||
| #	define SOCK_INIT -1 | #	define SOCK_INVALID -1 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if !defined(HAVE_SOCKLEN_T) | #if !defined(HAVE_SOCKLEN_T) | ||||||
| @ -720,6 +720,42 @@ static int set_socket_nonblock (qse_httpd_t* httpd, sock_t fd, int enabled) | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static sock_t open_udp_socket (qse_httpd_t* httpd, int domain) | ||||||
|  | { | ||||||
|  | 	sock_t fd; | ||||||
|  | 	int flag; | ||||||
|  |  | ||||||
|  | 	fd = socket (domain, SOCK_DGRAM, IPPROTO_UDP); | ||||||
|  | 	if (!is_valid_socket(fd))  | ||||||
|  | 	{ | ||||||
|  | 		qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); | ||||||
|  | 		goto oops; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	#if defined(FD_CLOEXEC) | ||||||
|  | 	flag = fcntl (fd, F_GETFD); | ||||||
|  | 	if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC); | ||||||
|  | 	#endif | ||||||
|  |  | ||||||
|  | 	#if defined(SO_REUSEADDR) | ||||||
|  | 	flag = 1; | ||||||
|  | 	setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (void*)&flag, QSE_SIZEOF(flag)); | ||||||
|  | 	#endif | ||||||
|  |  | ||||||
|  | 	#if defined(SO_REUSEPORT) | ||||||
|  | 	flag = 1; | ||||||
|  | 	setsockopt (fd, SOL_SOCKET, SO_REUSEPORT, (void*)&flag, QSE_SIZEOF(flag)); | ||||||
|  | 	#endif | ||||||
|  |  | ||||||
|  | 	if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops; | ||||||
|  |  | ||||||
|  | 	return fd; | ||||||
|  |  | ||||||
|  | oops: | ||||||
|  | 	if (is_valid_socket(fd)) close_socket (fd); | ||||||
|  | 	return SOCK_INVALID; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* ------------------------------------------------------------------- */ | /* ------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) | static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) | ||||||
| @ -728,7 +764,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) | |||||||
| 	qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); | 	qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); | ||||||
| 	return -1; | 	return -1; | ||||||
| #else | #else | ||||||
| 	sock_t fd = SOCK_INIT, flag; | 	sock_t fd = SOCK_INVALID, flag; | ||||||
| 	qse_skad_t addr; | 	qse_skad_t addr; | ||||||
| 	int addrsize; | 	int addrsize; | ||||||
|  |  | ||||||
| @ -872,7 +908,7 @@ static int server_accept ( | |||||||
| #else | #else | ||||||
| 	qse_skad_t addr; | 	qse_skad_t addr; | ||||||
| 	socklen_t addrlen; | 	socklen_t addrlen; | ||||||
| 	sock_t fd = SOCK_INIT; | 	sock_t fd = SOCK_INVALID; | ||||||
| 	int flag; | 	int flag; | ||||||
|  |  | ||||||
| 	addrlen = QSE_SIZEOF(addr); | 	addrlen = QSE_SIZEOF(addr); | ||||||
| @ -963,7 +999,7 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer) | |||||||
| 	qse_skad_t connaddr, bindaddr; | 	qse_skad_t connaddr, bindaddr; | ||||||
| 	int connaddrsize, bindaddrsize; | 	int connaddrsize, bindaddrsize; | ||||||
| 	int connected = 1; | 	int connected = 1; | ||||||
| 	sock_t fd = SOCK_INIT; | 	sock_t fd = SOCK_INVALID; | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| 	unsigned long cmd; | 	unsigned long cmd; | ||||||
| #elif defined(__OS2__) | #elif defined(__OS2__) | ||||||
|  | |||||||
| @ -822,22 +822,46 @@ qse_httpd_server_t* qse_httpd_getprevserver (qse_httpd_t* httpd, qse_httpd_serve | |||||||
|  |  | ||||||
| static int activate_dns (qse_httpd_t* httpd) | static int activate_dns (qse_httpd_t* httpd) | ||||||
| { | { | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	QSE_MEMSET (&httpd->dns, 0, QSE_SIZEOF(httpd->dns)); | ||||||
|  | 	for (i = 0; i < QSE_COUNTOF(httpd->dns.handle); i++) | ||||||
|  | 		httpd->dns.handle[i].i = -1; | ||||||
|  |  | ||||||
| 	if (httpd->opt.scb.dns.open (httpd, &httpd->dns) <= -1) return -1; | 	if (httpd->opt.scb.dns.open (httpd, &httpd->dns) <= -1) return -1; | ||||||
|  |  | ||||||
| 	httpd->dns.type = QSE_HTTPD_DNS; | 	httpd->dns.type = QSE_HTTPD_DNS; | ||||||
|  |  | ||||||
| 	if (httpd->opt.scb.mux.addhnd (httpd, httpd->mux, httpd->dns.handle, QSE_HTTPD_MUX_READ, &httpd->dns) <= -1)  | 	for (i = 0; i < httpd->dns.handle_count; i++) | ||||||
| 	{ | 	{ | ||||||
|  | 		if (httpd->dns.handle[i].i >= 0) | ||||||
|  | 		{ | ||||||
|  | 			if (httpd->opt.scb.mux.addhnd (httpd, httpd->mux, httpd->dns.handle[i], QSE_HTTPD_MUX_READ, &httpd->dns) <= -1)  | ||||||
|  | 			{ | ||||||
|  | 				while (i > 0) | ||||||
|  | 				{ | ||||||
|  | 					qse_ubi_t handle = httpd->dns.handle[--i]; | ||||||
|  | 					if (handle.i >= 0) httpd->opt.scb.mux.delhnd (httpd, httpd->mux, handle); | ||||||
|  | 				} | ||||||
| 				httpd->opt.scb.dns.close (httpd, &httpd->dns); | 				httpd->opt.scb.dns.close (httpd, &httpd->dns); | ||||||
| 				return -1; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void deactivate_dns (qse_httpd_t* httpd) | static void deactivate_dns (qse_httpd_t* httpd) | ||||||
| { | { | ||||||
| 	httpd->opt.scb.mux.delhnd (httpd, httpd->mux, httpd->dns.handle); | 	int i; | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < httpd->dns.handle_count; i++) | ||||||
|  | 	{ | ||||||
|  | 		if (httpd->dns.handle[i].i >= 0) | ||||||
|  | 			httpd->opt.scb.mux.delhnd (httpd, httpd->mux, httpd->dns.handle[i]); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	httpd->opt.scb.dns.close (httpd, &httpd->dns); | 	httpd->opt.scb.dns.close (httpd, &httpd->dns); | ||||||
| } | } | ||||||
| /* ----------------------------------------------------------------------- */ | /* ----------------------------------------------------------------------- */ | ||||||
| @ -845,22 +869,43 @@ static void deactivate_dns (qse_httpd_t* httpd) | |||||||
| static int activate_urs (qse_httpd_t* httpd) | static int activate_urs (qse_httpd_t* httpd) | ||||||
| { | { | ||||||
| /* TODO: how to disable URS??? */ | /* TODO: how to disable URS??? */ | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	QSE_MEMSET (&httpd->urs, 0, QSE_SIZEOF(httpd->urs)); | ||||||
|  | 	for (i = 0; i < QSE_COUNTOF(httpd->urs.handle); i++) | ||||||
|  | 		httpd->urs.handle[i].i = -1; | ||||||
|  |  | ||||||
| 	if (httpd->opt.scb.urs.open (httpd, &httpd->urs) <= -1) return -1; | 	if (httpd->opt.scb.urs.open (httpd, &httpd->urs) <= -1) return -1; | ||||||
|  |  | ||||||
| 	httpd->urs.type = QSE_HTTPD_URS; | 	httpd->urs.type = QSE_HTTPD_URS; | ||||||
|  |  | ||||||
| 	if (httpd->opt.scb.mux.addhnd (httpd, httpd->mux, httpd->urs.handle, QSE_HTTPD_MUX_READ, &httpd->urs) <= -1)  | 	for (i = 0; i < httpd->dns.handle_count; i++) | ||||||
| 	{ | 	{ | ||||||
|  | 		if (httpd->opt.scb.mux.addhnd (httpd, httpd->mux, httpd->urs.handle[i], QSE_HTTPD_MUX_READ, &httpd->urs) <= -1)  | ||||||
|  | 		{ | ||||||
|  | 			while (i > 0)  | ||||||
|  | 			{ | ||||||
|  | 				qse_ubi_t handle = httpd->urs.handle[--i]; | ||||||
|  | 				httpd->opt.scb.mux.delhnd (httpd, httpd->mux, handle); | ||||||
|  | 			} | ||||||
| 			httpd->opt.scb.urs.close (httpd, &httpd->urs); | 			httpd->opt.scb.urs.close (httpd, &httpd->urs); | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void deactivate_urs (qse_httpd_t* httpd) | static void deactivate_urs (qse_httpd_t* httpd) | ||||||
| { | { | ||||||
| 	httpd->opt.scb.mux.delhnd (httpd, httpd->mux, httpd->urs.handle); | 	int i; | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < httpd->urs.handle_count; i++) | ||||||
|  | 	{ | ||||||
|  | 		if (httpd->urs.handle[i].i >= 0) | ||||||
|  | 			httpd->opt.scb.mux.delhnd (httpd, httpd->mux, httpd->urs.handle[i]); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	httpd->opt.scb.urs.close (httpd, &httpd->urs); | 	httpd->opt.scb.urs.close (httpd, &httpd->urs); | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -1411,7 +1456,7 @@ static int perform_dns (qse_httpd_t* httpd, void* mux, qse_ubi_t handle, int mas | |||||||
| 	QSE_ASSERT (mask & QSE_HTTPD_MUX_READ); | 	QSE_ASSERT (mask & QSE_HTTPD_MUX_READ); | ||||||
| 	QSE_ASSERT (&httpd->dns == dns); | 	QSE_ASSERT (&httpd->dns == dns); | ||||||
|  |  | ||||||
| 	return httpd->opt.scb.dns.recv (httpd, dns); | 	return httpd->opt.scb.dns.recv (httpd, dns, handle); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int perform_urs (qse_httpd_t* httpd, void* mux, qse_ubi_t handle, int mask, void* cbarg) | static int perform_urs (qse_httpd_t* httpd, void* mux, qse_ubi_t handle, int mask, void* cbarg) | ||||||
| @ -1421,7 +1466,7 @@ static int perform_urs (qse_httpd_t* httpd, void* mux, qse_ubi_t handle, int mas | |||||||
| 	QSE_ASSERT (mask & QSE_HTTPD_MUX_READ); | 	QSE_ASSERT (mask & QSE_HTTPD_MUX_READ); | ||||||
| 	QSE_ASSERT (&httpd->urs == urs); | 	QSE_ASSERT (&httpd->urs == urs); | ||||||
|  |  | ||||||
| 	return httpd->opt.scb.urs.recv (httpd, urs); | 	return httpd->opt.scb.urs.recv (httpd, urs, handle); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void purge_bad_clients (qse_httpd_t* httpd) | static void purge_bad_clients (qse_httpd_t* httpd) | ||||||
| @ -1722,7 +1767,7 @@ qse_mchar_t* qse_httpd_escapehtml (qse_httpd_t* httpd, const qse_mchar_t* str) | |||||||
|  |  | ||||||
| /* ----------------------------------------------------------------------- */ | /* ----------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| int qse_httpd_resolname (qse_httpd_t* httpd, const qse_mchar_t* name, qse_httpd_resol_t resol, void* ctx) | int qse_httpd_resolname (qse_httpd_t* httpd, const qse_mchar_t* name, qse_httpd_resol_t resol, const qse_nwad_t* dns_server, void* ctx) | ||||||
| { | { | ||||||
| 	/* TODO: find the name in cache */ | 	/* TODO: find the name in cache */ | ||||||
|  |  | ||||||
| @ -1734,10 +1779,10 @@ printf ("DNS_SEND.........................\n"); | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return httpd->opt.scb.dns.send (httpd, &httpd->dns, name, resol, ctx); | 	return httpd->opt.scb.dns.send (httpd, &httpd->dns, name, resol, dns_server, ctx); | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_httpd_rewriteurl (qse_httpd_t* httpd, const qse_mchar_t* url, qse_httpd_rewrite_t rewrite, void* ctx) | int qse_httpd_rewriteurl (qse_httpd_t* httpd, const qse_mchar_t* url, qse_httpd_rewrite_t rewrite, const qse_nwad_t* urs_server, void* ctx) | ||||||
| { | { | ||||||
| 	if (!httpd->ursactive) | 	if (!httpd->ursactive) | ||||||
| 	{ | 	{ | ||||||
| @ -1745,7 +1790,7 @@ int qse_httpd_rewriteurl (qse_httpd_t* httpd, const qse_mchar_t* url, qse_httpd_ | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return httpd->opt.scb.urs.send (httpd, &httpd->urs, url, rewrite, ctx); | 	return httpd->opt.scb.urs.send (httpd, &httpd->urs, url, rewrite, urs_server, ctx); | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_httpd_activatetasktrigger (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) | int qse_httpd_activatetasktrigger (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user