diff options
author | David 'Digit' Turner <digit@android.com> | 2010-07-30 15:35:00 -0700 |
---|---|---|
committer | David 'Digit' Turner <digit@android.com> | 2010-07-30 15:35:00 -0700 |
commit | 9b98dbde344781e93e2bdcfa599428cda2fda41d (patch) | |
tree | 984065a5cd8d66a99000096fb2018f3ba7988320 | |
parent | 7fd67eba0b961d94a5d6baa8e3c3de37b729f738 (diff) | |
download | external_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.TXT | 5 | ||||
-rw-r--r-- | android/qemu-setup.c | 20 | ||||
-rw-r--r-- | iolooper-select.c | 11 | ||||
-rw-r--r-- | proxy/proxy_common.c | 47 | ||||
-rw-r--r-- | proxy/proxy_common.h | 12 | ||||
-rw-r--r-- | proxy/proxy_http_rewriter.c | 2 |
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; |