aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@android.com>2010-07-30 15:35:00 -0700
committerDavid 'Digit' Turner <digit@android.com>2010-07-30 15:35:00 -0700
commit9b98dbde344781e93e2bdcfa599428cda2fda41d (patch)
tree984065a5cd8d66a99000096fb2018f3ba7988320
parent7fd67eba0b961d94a5d6baa8e3c3de37b729f738 (diff)
downloadexternal_qemu-9b98dbde344781e93e2bdcfa599428cda2fda41d.zip
external_qemu-9b98dbde344781e93e2bdcfa599428cda2fda41d.tar.gz
external_qemu-9b98dbde344781e93e2bdcfa599428cda2fda41d.tar.bz2
Better detection of incorrect proxy values when starting the emulator.
Change-Id: I344f06fc16e051359669b8fe9b8dcec0ceca377d
-rw-r--r--CHANGES.TXT5
-rw-r--r--android/qemu-setup.c20
-rw-r--r--iolooper-select.c11
-rw-r--r--proxy/proxy_common.c47
-rw-r--r--proxy/proxy_common.h12
-rw-r--r--proxy/proxy_http_rewriter.c2
6 files changed, 87 insertions, 10 deletions
diff --git a/CHANGES.TXT b/CHANGES.TXT
index 225223b..12e4314 100644
--- a/CHANGES.TXT
+++ b/CHANGES.TXT
@@ -43,7 +43,10 @@ OTHER:
1 555 521 5554
- Fix -http-proxy implementation to properly work with chunked encodings.
- Also accept strings like "http://:8080" as a valid proxy address.
+
+ Also try to connect to the proxy on startup to see if the host/port are
+ valid. If no connection succeeds after 1 second, dump a warning and
+ ignore the proxy for the session.
- The console's "geo fix" command was modified:
diff --git a/android/qemu-setup.c b/android/qemu-setup.c
index 4f05c24..9a41c4d 100644
--- a/android/qemu-setup.c
+++ b/android/qemu-setup.c
@@ -422,19 +422,25 @@ void android_emulation_setup( void )
proxy_name_len = p - env;
proxy_port = atoi(p+1);
- /* handle the rare case where the proxy name is omitted, e.g. "http://:8080" */
- if (proxy_name_len == 0) {
- proxy_name = "localhost";
- proxy_name_len = strlen(proxy_name);
- }
-
D( "setting up http proxy: server=%.*s port=%d",
proxy_name_len, proxy_name, proxy_port );
+ /* Check that we can connect to the proxy in the next second.
+ * If not, the proxy setting is probably garbage !!
+ */
+ if ( proxy_check_connection( proxy_name, proxy_name_len, proxy_port, 1000 ) < 0) {
+ dprint("Could not connect to proxy at %.*s:%d: %s !",
+ proxy_name_len, proxy_name, proxy_port, errno_str);
+ dprint("Proxy will be ignored !");
+ break;
+ }
+
if ( proxy_http_setup( proxy_name, proxy_name_len, proxy_port,
option - option_tab, option_tab ) < 0 )
{
- dprint( "http proxy setup failed, check your $http_proxy variable");
+ dprint( "Http proxy setup failed for '%.*s:%d': %s",
+ proxy_name_len, proxy_name, proxy_port, errno_str);
+ dprint( "Proxy will be ignored !");
}
}
while (0);
diff --git a/iolooper-select.c b/iolooper-select.c
index bf7ae8f..f5aecbd 100644
--- a/iolooper-select.c
+++ b/iolooper-select.c
@@ -146,17 +146,26 @@ iolooper_wait( IoLooper* iol, int64_t duration )
int count = iolooper_fd_count(iol);
int ret;
fd_set errs;
+ struct timeval tm0, *tm = NULL;
if (count == 0)
return 0;
+ if (duration < 0)
+ tm = NULL;
+ else {
+ tm = &tm0;
+ tm->tv_sec = duration / 1000;
+ tm->tv_usec = (duration - 1000*tm->tv_sec) * 1000;
+ }
+
FD_ZERO(&errs);
do {
iol->reads_result[0] = iol->reads[0];
iol->writes_result[0] = iol->writes[0];
- ret = select( count, iol->reads_result, iol->writes_result, &errs, NULL);
+ ret = select( count, iol->reads_result, iol->writes_result, &errs, tm);
} while (ret < 0 && errno == EINTR);
return ret;
diff --git a/proxy/proxy_common.c b/proxy/proxy_common.c
index 7794a62..3a04eb8 100644
--- a/proxy/proxy_common.c
+++ b/proxy/proxy_common.c
@@ -17,6 +17,7 @@
#include <errno.h>
#include "android/utils/misc.h"
#include "android/utils/system.h"
+#include "iolooper.h"
#include <stdlib.h>
int proxy_log = 0;
@@ -530,3 +531,49 @@ Exit:
}
+int
+proxy_check_connection( const char* proxyname,
+ int proxyname_len,
+ int proxyport,
+ int timeout_ms )
+{
+ SockAddress addr;
+ int sock;
+ IoLooper* looper;
+ int ret;
+
+ if (proxy_resolve_server(&addr, proxyname, proxyname_len, proxyport) < 0) {
+ return -1;
+ }
+
+ sock = socket_create(addr.family, SOCKET_STREAM);
+ if (sock < 0) {
+ PROXY_LOG("%s: Could not create socket !?: %s", __FUNCTION__, errno_str);
+ return -1;
+ }
+
+ socket_set_nonblock(sock);
+
+ /* An immediate connection is very unlikely, but deal with it, just in case */
+ if (socket_connect(sock, &addr) == 0) {
+ PROXY_LOG("%s: Immediate connection to %.*s:%d: %s !",
+ __FUNCTION__, proxyname_len, proxyname, proxyport);
+ socket_close(sock);
+ return 0;
+ }
+
+ /* Ok, create an IoLooper object to wait for the connection */
+ looper = iolooper_new();
+ iolooper_add_write(looper, sock);
+
+ ret = iolooper_wait(looper, timeout_ms);
+
+ iolooper_free(looper);
+ socket_close(sock);
+
+ if (ret == 0) {
+ errno = ETIMEDOUT;
+ ret = -1;
+ }
+ return ret;
+}
diff --git a/proxy/proxy_common.h b/proxy/proxy_common.h
index 78eddd8..5c5789f 100644
--- a/proxy/proxy_common.h
+++ b/proxy/proxy_common.h
@@ -85,4 +85,16 @@ extern void proxy_manager_poll( fd_set* read_fds,
fd_set* write_fds,
fd_set* err_fds );
+/* this function checks that one can connect to a given proxy. It will simply try to connect()
+ * to it, for a specified timeout, in milliseconds, then close the connection.
+ *
+ * returns 0 in case of success, and -1 in case of error. errno will be set to ETIMEDOUT in
+ * case of timeout, or ECONNREFUSED if the connection is refused.
+ */
+
+extern int proxy_check_connection( const char* proxyname,
+ int proxyname_len,
+ int proxyport,
+ int timeout_ms );
+
#endif /* END */
diff --git a/proxy/proxy_http_rewriter.c b/proxy/proxy_http_rewriter.c
index 7645ecc..af3f5e7 100644
--- a/proxy/proxy_http_rewriter.c
+++ b/proxy/proxy_http_rewriter.c
@@ -1121,7 +1121,7 @@ http_rewriter_connect( HttpService* service,
RewriteConnection* conn;
int s;
- s = socket_create_inet( SOCKET_STREAM );
+ s = socket_create(address->family, SOCKET_STREAM );
if (s < 0)
return NULL;