diff options
author | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-17 17:55:35 +0000 |
---|---|---|
committer | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-17 17:55:35 +0000 |
commit | 00106e1c05c9dcd01f055f8682e87bc97a09c648 (patch) | |
tree | 9fb08a6a44726056dd75607022dbbf31315cb994 /net/proxy/dhcp_proxy_script_fetcher_win.cc | |
parent | 92c6608cda88cf297275ba4b964b64f3475abbd6 (diff) | |
download | chromium_src-00106e1c05c9dcd01f055f8682e87bc97a09c648.zip chromium_src-00106e1c05c9dcd01f055f8682e87bc97a09c648.tar.gz chromium_src-00106e1c05c9dcd01f055f8682e87bc97a09c648.tar.bz2 |
Revert 85646 - Adds support for the DHCP portion of the WPAD (proxy auto-discovery) protocol.
This is Windows-only for now, and is disabled by default. Start
Chrome with the flag --enable-dhcp-wpad to enable the feature. See
discussion in comment on DhcpProxyScriptFetcherFactory for why this
needs to be done in a per-platform way rather than cross-platform.
The code is factored so that adding other platform implementations
will be straight forward.
Most of the implementation is stand-alone and extends the
ScriptProxyFetcher class hierarchy (and makes its interface slightly
more generic). The integration point into existing code is in
InitProxyResolver, which previously handled fallback from DNS
auto-detect to custom PAC URL and now does fallback from DHCP to DNS
to custom PAC URL.
BUG=18575
TEST=net_unittests has good coverage for the new and changed code, but
manual tests on a network with a PAC URL configured in DHCP are also
needed.
Review URL: http://codereview.chromium.org/6831025
TBR=joi@chromium.org
Review URL: http://codereview.chromium.org/7019015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85648 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy/dhcp_proxy_script_fetcher_win.cc')
-rw-r--r-- | net/proxy/dhcp_proxy_script_fetcher_win.cc | 246 |
1 files changed, 0 insertions, 246 deletions
diff --git a/net/proxy/dhcp_proxy_script_fetcher_win.cc b/net/proxy/dhcp_proxy_script_fetcher_win.cc deleted file mode 100644 index 35109f6..0000000 --- a/net/proxy/dhcp_proxy_script_fetcher_win.cc +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/proxy/dhcp_proxy_script_fetcher_win.h" - -#include "net/base/net_errors.h" -#include "net/proxy/dhcp_proxy_script_adapter_fetcher_win.h" - -#include <winsock2.h> -#include <iphlpapi.h> -#pragma comment(lib, "iphlpapi.lib") - -namespace { - -// How long to wait at maximum after we get results (a PAC file or -// knowledge that no PAC file is configured) from whichever network -// adapter finishes first. -const int kMaxWaitAfterFirstResultMs = 400; - -} // namespace - -namespace net { - -DhcpProxyScriptFetcherWin::DhcpProxyScriptFetcherWin( - URLRequestContext* url_request_context) - : state_(STATE_START), - ALLOW_THIS_IN_INITIALIZER_LIST(fetcher_callback_( - this, &DhcpProxyScriptFetcherWin::OnFetcherDone)), - num_pending_fetchers_(0), - url_request_context_(url_request_context) { - DCHECK(url_request_context_); -} - -DhcpProxyScriptFetcherWin::~DhcpProxyScriptFetcherWin() { - Cancel(); -} - -int DhcpProxyScriptFetcherWin::Fetch(string16* utf16_text, - CompletionCallback* callback) { - DCHECK(CalledOnValidThread()); - if (state_ != STATE_START && state_ != STATE_DONE) { - NOTREACHED(); - return ERR_UNEXPECTED; - } - - std::set<std::string> adapter_names; - if (!ImplGetCandidateAdapterNames(&adapter_names)) { - return ERR_UNEXPECTED; - } - if (adapter_names.empty()) { - return ERR_PAC_NOT_IN_DHCP; - } - - state_ = STATE_NO_RESULTS; - - client_callback_ = callback; - destination_string_ = utf16_text; - - for (std::set<std::string>::iterator it = adapter_names.begin(); - it != adapter_names.end(); - ++it) { - DhcpProxyScriptAdapterFetcher* fetcher(ImplCreateAdapterFetcher()); - fetcher->Fetch(*it, &fetcher_callback_); - fetchers_.push_back(fetcher); - } - num_pending_fetchers_ = fetchers_.size(); - - return ERR_IO_PENDING; -} - -void DhcpProxyScriptFetcherWin::Cancel() { - DCHECK(CalledOnValidThread()); - - if (state_ != STATE_DONE) { - wait_timer_.Stop(); - state_ = STATE_DONE; - - for (FetcherVector::iterator it = fetchers_.begin(); - it != fetchers_.end(); - ++it) { - (*it)->Cancel(); - } - - fetchers_.reset(); - } -} - -std::string DhcpProxyScriptFetcherWin::GetFetcherName() const { - DCHECK(CalledOnValidThread()); - return "win"; -} - -const GURL& DhcpProxyScriptFetcherWin::GetPacURL() const { - DCHECK(CalledOnValidThread()); - DCHECK_EQ(state_, STATE_DONE); - - return pac_url_; -} - -void DhcpProxyScriptFetcherWin::OnFetcherDone(int result) { - DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS); - - if (--num_pending_fetchers_ == 0) { - TransitionToDone(); - return; - } - - // If the only pending adapters are those less preferred than one - // with a valid PAC script, we do not need to wait any longer. - for (FetcherVector::iterator it = fetchers_.begin(); - it != fetchers_.end(); - ++it) { - bool did_finish = (*it)->DidFinish(); - int result = (*it)->GetResult(); - if (did_finish && result == OK) { - TransitionToDone(); - return; - } - if (!did_finish || result != ERR_PAC_NOT_IN_DHCP) { - break; - } - } - - // Once we have a single result, we set a maximum on how long to wait - // for the rest of the results. - if (state_ == STATE_NO_RESULTS) { - state_ = STATE_SOME_RESULTS; - wait_timer_.Start( - base::TimeDelta::FromMilliseconds(ImplGetMaxWaitMs()), - this, &DhcpProxyScriptFetcherWin::OnWaitTimer); - } -} - -void DhcpProxyScriptFetcherWin::OnWaitTimer() { - DCHECK_EQ(state_, STATE_SOME_RESULTS); - TransitionToDone(); -} - -void DhcpProxyScriptFetcherWin::TransitionToDone() { - DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS); - - // Should have returned immediately at Fetch() if no adapters to check. - DCHECK(!fetchers_.empty()); - - // Scan twice for the result; once through the whole list for success, - // then if no success, return result for most preferred network adapter, - // preferring "real" network errors to the ERR_PAC_NOT_IN_DHCP error. - // Default to ERR_ABORTED if no fetcher completed. - int result = ERR_ABORTED; - for (FetcherVector::iterator it = fetchers_.begin(); - it != fetchers_.end(); - ++it) { - if ((*it)->DidFinish() && (*it)->GetResult() == OK) { - result = OK; - *destination_string_ = (*it)->GetPacScript(); - pac_url_ = (*it)->GetPacURL(); - break; - } - } - if (result != OK) { - destination_string_->clear(); - for (FetcherVector::iterator it = fetchers_.begin(); - it != fetchers_.end(); - ++it) { - if ((*it)->DidFinish()) { - result = (*it)->GetResult(); - if (result != ERR_PAC_NOT_IN_DHCP) { - break; - } - } - } - } - - Cancel(); - DCHECK_EQ(state_, STATE_DONE); - DCHECK(fetchers_.empty()); - - client_callback_->Run(result); -} - -DhcpProxyScriptAdapterFetcher* - DhcpProxyScriptFetcherWin::ImplCreateAdapterFetcher() { - return new DhcpProxyScriptAdapterFetcher(url_request_context_); -} - -bool DhcpProxyScriptFetcherWin::ImplGetCandidateAdapterNames( - std::set<std::string>* adapter_names) { - return GetCandidateAdapterNames(adapter_names); -} - -int DhcpProxyScriptFetcherWin::ImplGetMaxWaitMs() { - return kMaxWaitAfterFirstResultMs; -} - -bool DhcpProxyScriptFetcherWin::GetCandidateAdapterNames( - std::set<std::string>* adapter_names) { - DCHECK(adapter_names); - adapter_names->clear(); - - // The GetAdaptersAddresses MSDN page recommends using a size of 15000 to - // avoid reallocation. - ULONG adapters_size = 15000; - scoped_ptr_malloc<IP_ADAPTER_ADDRESSES> adapters; - ULONG error = ERROR_SUCCESS; - int num_tries = 0; - do { - adapters.reset( - reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(adapters_size))); - // Return only unicast addresses, and skip information we do not need. - error = GetAdaptersAddresses(AF_UNSPEC, - GAA_FLAG_SKIP_ANYCAST | - GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER | - GAA_FLAG_SKIP_FRIENDLY_NAME, - NULL, - adapters.get(), - &adapters_size); - ++num_tries; - } while (error == ERROR_BUFFER_OVERFLOW && num_tries <= 3); - - if (error == ERROR_NO_DATA) { - // There are no adapters that we care about. - return true; - } - - if (error != ERROR_SUCCESS) { - LOG(WARNING) << "Unexpected error retrieving WPAD configuration from DHCP."; - return false; - } - - IP_ADAPTER_ADDRESSES* adapter = NULL; - for (adapter = adapters.get(); adapter; adapter = adapter->Next) { - if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) - continue; - if ((adapter->Flags & IP_ADAPTER_DHCP_ENABLED) == 0) - continue; - - DCHECK(adapter->AdapterName); - adapter_names->insert(adapter->AdapterName); - } - - return true; -} - -} // namespace net |