It seems the proxy handling code was initially written to only handle proxies in the form of IP addresses. 38b75abddb5b changed that implicitly by always doing a hostname lookup for the proxy address, which fixes proxies given by hostname but breaks ip based proxy configuration (as sending an A query to most DNS server for an ip address gets you a result with no answers).
Clean up the confusion by not overloading the meaning of the address field in web_session and short-circuiting the lookup iff either the proxy host or the real host is an ip address (as applicable). Signed-off-by: Sjoerd Simons <[email protected]> --- gweb/gweb.c | 67 +++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/gweb/gweb.c b/gweb/gweb.c index 8cdd5d9..e5d6d56 100644 --- a/gweb/gweb.c +++ b/gweb/gweb.c @@ -68,6 +68,7 @@ struct web_session { char *address; char *host; + char *proxy_host; uint16_t port; unsigned long flags; struct addrinfo *addr; @@ -190,6 +191,7 @@ static void free_session(struct web_session *session) g_free(session->content_type); g_free(session->host); + g_free(session->proxy_host); g_free(session->address); if (session->addr) freeaddrinfo(session->addr); @@ -1190,27 +1192,20 @@ static int parse_url(struct web_session *session, } } - session->address = g_strdup(host); + session->proxy_host = g_strdup(host); g_free(scheme); return 0; } -static void resolv_result(GResolvResultStatus status, - char **results, gpointer user_data) +static void got_address (struct web_session *session, const char *address) { - struct web_session *session = user_data; struct addrinfo hints; char *port; int ret; - if (!results || !results[0]) { - call_result_func(session, 404); - return; - } - - debug(session->web, "address %s", results[0]); + debug(session->web, "address %s", address); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = AI_NUMERICHOST; @@ -1222,7 +1217,7 @@ static void resolv_result(GResolvResultStatus status, } port = g_strdup_printf("%u", session->port); - ret = getaddrinfo(results[0], port, &hints, &session->addr); + ret = getaddrinfo(address, port, &hints, &session->addr); g_free(port); if (ret != 0 || !session->addr) { call_result_func(session, 400); @@ -1230,7 +1225,8 @@ static void resolv_result(GResolvResultStatus status, } g_free(session->address); - session->address = g_strdup(results[0]); + session->address = g_strdup(address); + call_route_func(session); if (create_transport(session) < 0) { @@ -1239,12 +1235,42 @@ static void resolv_result(GResolvResultStatus status, } } +static void resolv_result(GResolvResultStatus status, + char **results, gpointer user_data) +{ + struct web_session *session = user_data; + + if (!results || !results[0]) { + call_result_func(session, 404); + return; + } + + got_address (session, results[0]); +} + +bool is_ip_address(const char *host) +{ + struct addrinfo hints; + struct addrinfo *addr; + int result; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = AI_NUMERICHOST; + addr = NULL; + + result = getaddrinfo(host, NULL, &hints, &addr); + freeaddrinfo(addr); + + return result == 0; +} + static guint do_request(GWeb *web, const char *url, const char *type, GWebInputFunc input, int fd, gsize length, GWebResultFunc func, GWebRouteFunc route, gpointer user_data) { struct web_session *session; + const gchar *host; if (!web || !url) return 0; @@ -1260,7 +1286,7 @@ static guint do_request(GWeb *web, const char *url, return 0; } - debug(web, "address %s", session->address); + debug(web, "proxy host %s", session->proxy_host); debug(web, "port %u", session->port); debug(web, "host %s", session->host); debug(web, "flags %lu", session->flags); @@ -1301,19 +1327,12 @@ static guint do_request(GWeb *web, const char *url, session->header_done = false; session->body_done = false; - if (!session->address && inet_aton(session->host, NULL) == 0) { - session->resolv_action = g_resolv_lookup_hostname(web->resolv, - session->host, resolv_result, session); - if (session->resolv_action == 0) { - free_session(session); - return 0; - } + host = session->proxy_host ? session->proxy_host : session->host; + if (is_ip_address (host)) { + got_address (session, host); } else { - if (!session->address) - session->address = g_strdup(session->host); - session->resolv_action = g_resolv_lookup_hostname(web->resolv, - session->address, resolv_result, session); + host, resolv_result, session); if (session->resolv_action == 0) { free_session(session); return 0; -- 1.8.5.2 _______________________________________________ connman mailing list [email protected] https://lists.connman.net/mailman/listinfo/connman
