summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2009-09-02 20:29:42 +0000
committerjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2009-09-02 20:29:42 +0000
commit1588eb9916c0ac8bb02010e91599fe3e78823165 (patch)
treea90c41a9ad343d3266df5f1f705ea7ef425cc097
parent163858a5390a5347c6b84a4a75956a646755cac4 (diff)
downloadneon-1588eb9916c0ac8bb02010e91599fe3e78823165.tar.gz
Merge r1713, r1714 from trunk:
* src/ne_request.c (socks_origin_lookup): New function. (open_connection): Use it to fix support for SOCKSv4 servers. * test/request.c (socks_v4_proxy): Add test case. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Require inet_pton for getaddrinfo support. git-svn-id: http://svn.webdav.org/repos/projects/neon/branches/0.29.x@1715 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
-rw-r--r--macros/neon.m43
-rw-r--r--src/ne_request.c71
-rw-r--r--test/request.c25
3 files changed, 86 insertions, 13 deletions
diff --git a/macros/neon.m4 b/macros/neon.m4
index ca9bf12..a673027 100644
--- a/macros/neon.m4
+++ b/macros/neon.m4
@@ -645,7 +645,8 @@ NE_SEARCH_LIBS(getaddrinfo, nsl,,
AC_MSG_NOTICE([getaddrinfo support disabled on HP-UX 11.0x/11.1x]) ;;
*)
ne_enable_gai=yes
- NE_CHECK_FUNCS(gai_strerror getnameinfo inet_ntop,,[ne_enable_gai=no; break]) ;;
+ NE_CHECK_FUNCS(gai_strerror getnameinfo inet_ntop inet_pton,,
+ [ne_enable_gai=no; break]) ;;
esac
])
diff --git a/src/ne_request.c b/src/ne_request.c
index 72ce448..6eaacde 100644
--- a/src/ne_request.c
+++ b/src/ne_request.c
@@ -1122,7 +1122,7 @@ static int read_response_headers(ne_request *req)
}
/* Perform any necessary DNS lookup for the host given by *info;
- * return NE_ code. */
+ * returns NE_ code with error string set on error. */
static int lookup_host(ne_session *sess, struct host_info *info)
{
NE_DEBUG(NE_DBG_HTTP, "Doing DNS lookup on %s...\n", info->hostname);
@@ -1514,6 +1514,42 @@ static int do_connect(ne_session *sess, struct host_info *host)
return NE_OK;
}
+/* For a SOCKSv4 proxy only, the IP address of the origin server (in
+ * addition to the proxy) must be known, and must be an IPv4 address.
+ * Returns NE_*; connection closed and error string set on error. */
+static int socks_origin_lookup(ne_session *sess)
+{
+ const ne_inet_addr *ia;
+ int ret;
+
+ ret = lookup_host(sess, &sess->server);
+ if (ret) {
+ /* lookup_host already set the error string. */
+ ne_close_connection(sess);
+ return ret;
+ }
+
+ /* Find the first IPv4 address available for the server. */
+ for (ia = ne_addr_first(sess->server.address);
+ ia && ne_iaddr_typeof(ia) == ne_iaddr_ipv6;
+ ia = ne_addr_next(sess->server.address)) {
+ /* noop */
+ }
+
+ /* ... if any */
+ if (ia == NULL) {
+ ne_set_error(sess, _("Could not find IPv4 address of "
+ "hostname %s for SOCKS v4 proxy"),
+ sess->server.hostname);
+ ne_close_connection(sess);
+ return NE_LOOKUP;
+ }
+
+ sess->server.current = ia;
+
+ return ret;
+}
+
static int open_connection(ne_session *sess)
{
int ret;
@@ -1545,17 +1581,28 @@ static int open_connection(ne_session *sess)
}
if (ret == NE_OK && sess->nexthop->proxy == PROXY_SOCKS) {
- ret = ne_sock_proxy(sess->socket, sess->socks_ver, NULL,
- sess->server.hostname, sess->server.port,
- sess->socks_user, sess->socks_password);
- if (ret) {
- ne_set_error(sess,
- _("Could not establish connection from "
- "SOCKS proxy (%s:%u): %s"),
- sess->nexthop->hostname,
- sess->nexthop->port,
- ne_sock_error(sess->socket));
- ne_close_connection(sess);
+ /* Special-case for SOCKS v4 proxies, which require the
+ * client to resolve the origin server IP address. */
+ if (sess->socks_ver == NE_SOCK_SOCKSV4) {
+ ret = socks_origin_lookup(sess);
+ }
+
+ if (ret == NE_OK) {
+ /* Perform the SOCKS handshake, instructing the proxy
+ * to set up the connection to the origin server. */
+ ret = ne_sock_proxy(sess->socket, sess->socks_ver,
+ sess->server.current,
+ sess->server.hostname, sess->server.port,
+ sess->socks_user, sess->socks_password);
+ if (ret) {
+ ne_set_error(sess,
+ _("Could not establish connection from "
+ "SOCKS proxy (%s:%u): %s"),
+ sess->nexthop->hostname,
+ sess->nexthop->port,
+ ne_sock_error(sess->socket));
+ ne_close_connection(sess);
+ }
}
}
diff --git a/test/request.c b/test/request.c
index d95223a..55f9c8d 100644
--- a/test/request.c
+++ b/test/request.c
@@ -2212,6 +2212,30 @@ static int socks_proxy(void)
return await_server();
}
+static int socks_v4_proxy(void)
+{
+ ne_session *sess;
+ struct socks_server srv = {0};
+
+ srv.version = NE_SOCK_SOCKSV4;
+ srv.failure = fail_none;
+ srv.expect_port = 4242;
+ srv.expect_addr = ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv4);
+ srv.expect_fqdn = "localhost";
+ srv.username = "bloggs";
+ srv.password = "guessme";
+
+ CALL(socks_session(&sess, &srv, srv.expect_fqdn, srv.expect_port,
+ single_serve_string, EMPTY_RESP));
+
+ CALL(any_2xx_request(sess, "/blee"));
+
+ ne_iaddr_free(srv.expect_addr);
+
+ ne_session_destroy(sess);
+ return await_server();
+}
+
/* TODO: test that ne_set_notifier(, NULL, NULL) DTRT too. */
ne_test tests[] = {
@@ -2302,5 +2326,6 @@ ne_test tests[] = {
T(dereg_progress),
T(addrlist),
T(socks_proxy),
+ T(socks_v4_proxy),
T(NULL)
};