diff --git a/qse/cmd/http/httpd.c b/qse/cmd/http/httpd.c index 6ff91b25..46efe65a 100644 --- a/qse/cmd/http/httpd.c +++ b/qse/cmd/http/httpd.c @@ -459,6 +459,19 @@ static int get_server_root ( qpath = qse_htre_getqpath(qinfo->req); 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 (loccfg->proxy.allow_connect) @@ -538,6 +551,8 @@ static int get_server_root ( } } + + if (loccfg->root_is_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) { 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); } -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_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++) { @@ -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")); if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.index")); 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; } + 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")); if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.cgi")); 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")); if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.auth-rule")); 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")); if (!pair) pair = qse_xli_findpair (xli, QSE_NULL, QSE_T("server-default.mime")); 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++) { 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 /* 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; 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 = { { diff --git a/qse/include/qse/http/httpd.h b/qse/include/qse/http/httpd.h index cd2c9d83..cb29e697 100644 --- a/qse/include/qse/http/httpd.h +++ b/qse/include/qse/http/httpd.h @@ -261,18 +261,20 @@ struct qse_httpd_scb_t { int (*open) (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, - 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; struct { int (*open) (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, - 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; }; @@ -503,7 +505,8 @@ struct qse_httpd_dns_t QSE_HTTPD_MATE_HDR; /* == PUBLIC == */ - qse_ubi_t handle; + qse_ubi_t handle[5]; + int handle_count; void* ctx; }; @@ -513,7 +516,8 @@ struct qse_httpd_urs_t QSE_HTTPD_MATE_HDR; /* == PUBLIC == */ - qse_ubi_t handle; + qse_ubi_t handle[5]; + int handle_count; void* ctx; }; @@ -558,7 +562,9 @@ enum qse_httpd_rsrc_proxy_flag_t QSE_HTTPD_RSRC_PROXY_RAW = (1 << 0), QSE_HTTPD_RSRC_PROXY_DST_STR = (1 << 1), 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; @@ -577,6 +583,9 @@ struct qse_httpd_rsrc_proxy_t const qse_mchar_t* str; } 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: */ }; @@ -1001,6 +1010,7 @@ QSE_EXPORT 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 ); @@ -1008,6 +1018,7 @@ QSE_EXPORT int qse_httpd_rewriteurl ( qse_httpd_t* ttpd, const qse_mchar_t* url, qse_httpd_rewrite_t rewrite, + const qse_nwad_t* urs_server, void* ctx ); diff --git a/qse/include/qse/http/stdhttpd.h b/qse/include/qse/http/stdhttpd.h index 2900f4d6..0e217580 100644 --- a/qse/include/qse/http/stdhttpd.h +++ b/qse/include/qse/http/stdhttpd.h @@ -112,13 +112,6 @@ struct qse_httpd_serverstd_ssl_t 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 { QSE_HTTPD_SERVERSTD_SSL, /* qse_httpd_serverstd_ssl_t */ diff --git a/qse/lib/http/httpd-proxy.c b/qse/lib/http/httpd-proxy.c index c2bd3577..4ec5151d 100644 --- a/qse/lib/http/httpd-proxy.c +++ b/qse/lib/http/httpd-proxy.c @@ -38,19 +38,21 @@ struct task_proxy_t #define PROXY_INIT_FAILED (1 << 0) #define PROXY_RAW (1 << 1) #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 the task_proxy_t chunk. explicit deallocatin is required */ -#define PROXY_RESOLVE_PEER_NAME (1 << 4) -#define PROXY_PEER_NAME_RESOLVED (1 << 5) -#define PROXY_PEER_NAME_UNRESOLVED (1 << 6) -#define PROXY_REWRITE_URL (1 << 7) -#define PROXY_URL_REWRITTEN (1 << 8) -#define PROXY_URL_REDIRECTED (1 << 9) -#define PROXY_X_FORWARDED_FOR (1 << 10) /* X-Forwarded-For added */ -#define PROXY_VIA (1 << 11) /* Via added to the request */ -#define PROXY_VIA_RETURNING (1 << 12) /* Via added to the response */ +#define PROXY_RESOLVE_PEER_NAME (1 << 6) +#define PROXY_PEER_NAME_RESOLVED (1 << 7) +#define PROXY_PEER_NAME_UNRESOLVED (1 << 8) +#define PROXY_REWRITE_URL (1 << 9) +#define PROXY_URL_REWRITTEN (1 << 10) +#define PROXY_URL_REDIRECTED (1 << 11) +#define PROXY_X_FORWARDED_FOR (1 << 12) /* X-Forwarded-For added */ +#define PROXY_VIA (1 << 13) /* Via added to the request */ +#define PROXY_VIA_RETURNING (1 << 14) /* Via added to the response */ int flags; qse_httpd_t* httpd; qse_httpd_client_t* client; @@ -64,6 +66,8 @@ struct task_proxy_t qse_size_t qpath_pos_in_reqfwdbuf; qse_size_t qpath_len_in_reqfwdbuf; + qse_nwad_t dns_server; + qse_nwad_t urs_server; qse_mchar_t* pseudonym; 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_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* metnam; @@ -2063,7 +2078,8 @@ static int task_main_proxy ( if (proxy->flags & PROXY_REWRITE_URL) { /* 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; @@ -2079,7 +2095,8 @@ static int task_main_proxy ( 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 * in qse_httpd_resolname(), on_peer_name_resolve would be diff --git a/qse/lib/http/httpd-std-dns.h b/qse/lib/http/httpd-std-dns.h index 1c41c3c1..a1f41a97 100644 --- a/qse/lib/http/httpd-std-dns.h +++ b/qse/lib/http/httpd-std-dns.h @@ -129,6 +129,7 @@ struct dns_ctx_t qse_skad_t skad; int skadlen; + int dns_socket; qse_uint16_t seq; 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; dns_ctx_t* dc; + qse_skad_t dns_skad; + int dns_skadlen; + int dns_socket; + qse_tmr_index_t tmr_tmout; 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); return -1; #else - sock_t fd = SOCK_INIT; - int flag; qse_nwad_t nwad; dns_ctx_t* dc; 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_size_t pos; 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); httpd->opt.rcb.logact (httpd, &msg); } - fd = socket (qse_skadfamily(&dc->skad), SOCK_DGRAM, IPPROTO_UDP); - if (!is_valid_socket(fd)) + dns->handle[0].i = open_udp_socket (httpd, AF_INET); +#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; } - #if defined(FD_CLOEXEC) - flag = fcntl (fd, F_GETFD); - if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC); - #endif + if (nwad.type == QSE_NWAD_IN4) + dc->dns_socket = dns->handle[0].i; + else + dc->dns_socket = dns->handle[1].i; - #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; - - dns->handle.i = fd; + dns->handle_count = 2; dns->ctx = dc; return 0; 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); return -1; #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) { - qse_httpd_removetimerevent (req->dc->httpd, req->tmr_tmout); + qse_httpd_removetimerevent (httpd, req->tmr_tmout); 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; - dns_remove_tmr_tmout (dc->reqs[i]); + dns_remove_tmr_tmout (httpd, dc->reqs[i]); qse_httpd_freemem (httpd, dc->reqs[i]); 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); } - - 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; @@ -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; } -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; httpd_xtn_t* httpd_xtn; @@ -559,9 +556,7 @@ printf ("DNS_RECV....\n"); httpd_xtn = qse_httpd_getxtn (httpd); fromlen = QSE_SIZEOF(fromaddr); - len = recvfrom (dns->handle.i, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&fromaddr, &fromlen); - -/* TODO: check if fromaddr matches the dc->skad... */ + len = recvfrom (handle.i, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&fromaddr, &fromlen); 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) && 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 * 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 @@ -700,7 +696,7 @@ resolved: QSE_ASSERT (req != QSE_NULL); 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); /* 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.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) || - (!(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)) + 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 (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*/ } @@ -792,7 +788,7 @@ printf (">>tmr_dns_tmout_handle req->>%p\n", req); 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; httpd_xtn_t* httpd_xtn; @@ -870,6 +866,29 @@ printf ("DNS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n"); 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; qse_gettime (&tmout_event.when); @@ -879,8 +898,8 @@ printf ("DNS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n"); tmout_event.updater = tmr_dns_tmout_update; 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) || - (req->qaaaalen > 0 && sendto (dns->handle.i, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qaaaalen)) + 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 (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()); goto oops; @@ -908,7 +927,7 @@ printf ("DNS REALLY SENT>>>>>>>>>>>>>>>>>>>>>>>\n"); oops: if (req) { - dns_remove_tmr_tmout (req); + dns_remove_tmr_tmout (httpd, req); qse_httpd_freemem (httpd, req); } return -1; diff --git a/qse/lib/http/httpd-std-urs.h b/qse/lib/http/httpd-std-urs.h index faeccb3e..feff95ba 100644 --- a/qse/lib/http/httpd-std-urs.h +++ b/qse/lib/http/httpd-std-urs.h @@ -53,6 +53,7 @@ struct urs_ctx_t qse_skad_t skad; int skadlen; + int urs_socket; qse_uint16_t seq; /* TODO: change to uint32_t??? */ urs_req_t* reqs[1024]; /* TOOD: choose the right size */ @@ -72,6 +73,10 @@ struct urs_req_t void* ctx; urs_ctx_t* dc; + qse_skad_t urs_skad; + int urs_skadlen; + int urs_socket; + qse_tmr_index_t tmr_tmout; 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); return -1; #else - sock_t fd = SOCK_INIT; - int flag; qse_nwad_t nwad; urs_ctx_t* dc; 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); } - fd = socket (qse_skadfamily(&dc->skad), SOCK_DGRAM, IPPROTO_UDP); - if (!is_valid_socket(fd)) + urs->handle[0].i = open_udp_socket (httpd, AF_INET); +#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; } -/* 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) - flag = fcntl (fd, F_GETFD); - if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC); - #endif + urs->handle_count = 2; - #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; return 0; 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); return -1; #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) { - qse_httpd_removetimerevent (req->dc->httpd, req->tmr_tmout); + qse_httpd_removetimerevent (httpd, req->tmr_tmout); 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]) { 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]); dc->reqs[i] = next_req; 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); - 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); } -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; httpd_xtn_t* httpd_xtn; @@ -217,7 +216,7 @@ printf ("URS_RECV....\n"); httpd_xtn = qse_httpd_getxtn (httpd); 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... */ @@ -232,7 +231,7 @@ printf ("URS_RECV....\n"); { 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); /* 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.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 */ } @@ -321,7 +320,7 @@ printf ("urs timed out....\n"); 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; httpd_xtn_t* httpd_xtn; @@ -374,6 +373,27 @@ printf ("URS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n"); req->ctx = ctx; 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_addtime (&tmout_event.when, &httpd_xtn->urs.tmout, &tmout_event.when); tmout_event.ctx = req; @@ -381,7 +401,7 @@ printf ("URS REALLY SENING>>>>>>>>>>>>>>>>>>>>>>>\n"); tmout_event.updater = tmr_urs_tmout_update; 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()); goto oops; @@ -403,7 +423,7 @@ printf ("URS REALLY SENT>>>>>>>>>>>>>>>>>>>>>>>\n"); oops: if (req) { - urs_remove_tmr_tmout (req); + urs_remove_tmr_tmout (httpd, req); qse_httpd_freemem (httpd, req); } return -1; diff --git a/qse/lib/http/httpd-std.c b/qse/lib/http/httpd-std.c index 3fb02a68..439d279e 100644 --- a/qse/lib/http/httpd-std.c +++ b/qse/lib/http/httpd-std.c @@ -650,10 +650,10 @@ void* qse_httpd_getxtnstd (qse_httpd_t* httpd) #if defined(_WIN32) typedef SOCKET sock_t; -# define SOCK_INIT INVALID_SOCKET +# define SOCK_INVALID INVALID_SOCKET #else typedef int sock_t; -# define SOCK_INIT -1 +# define SOCK_INVALID -1 #endif #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) @@ -728,7 +764,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); return -1; #else - sock_t fd = SOCK_INIT, flag; + sock_t fd = SOCK_INVALID, flag; qse_skad_t addr; int addrsize; @@ -872,7 +908,7 @@ static int server_accept ( #else qse_skad_t addr; socklen_t addrlen; - sock_t fd = SOCK_INIT; + sock_t fd = SOCK_INVALID; int flag; 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; int connaddrsize, bindaddrsize; int connected = 1; - sock_t fd = SOCK_INIT; + sock_t fd = SOCK_INVALID; #if defined(_WIN32) unsigned long cmd; #elif defined(__OS2__) @@ -2815,7 +2851,7 @@ static int make_resource ( server_xtn->auth.ptr = tptr; /* the maximum capacity that can hold the largest authorization value */ - server_xtn->auth.len = authl; + server_xtn->auth.len = authl; } /* decoding a base64-encoded string result in a shorter value than the input. diff --git a/qse/lib/http/httpd.c b/qse/lib/http/httpd.c index 27da972a..04febe53 100644 --- a/qse/lib/http/httpd.c +++ b/qse/lib/http/httpd.c @@ -822,14 +822,31 @@ qse_httpd_server_t* qse_httpd_getprevserver (qse_httpd_t* httpd, qse_httpd_serve 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; 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++) { - httpd->opt.scb.dns.close (httpd, &httpd->dns); - return -1; + 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); + return -1; + } + } } return 0; @@ -837,7 +854,14 @@ static int activate_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); } /* ----------------------------------------------------------------------- */ @@ -845,14 +869,28 @@ static void deactivate_dns (qse_httpd_t* httpd) static int activate_urs (qse_httpd_t* httpd) { /* 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; 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++) { - httpd->opt.scb.urs.close (httpd, &httpd->urs); - return -1; + 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); + return -1; + } } return 0; @@ -860,7 +898,14 @@ static int activate_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); } @@ -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 (&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) @@ -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 (&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) @@ -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 */ @@ -1734,10 +1779,10 @@ printf ("DNS_SEND.........................\n"); 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) { @@ -1745,7 +1790,7 @@ int qse_httpd_rewriteurl (qse_httpd_t* httpd, const qse_mchar_t* url, qse_httpd_ 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)