=== modified file 'src/adaptation/icap/ServiceRep.cc' --- src/adaptation/icap/ServiceRep.cc 2011-06-17 10:41:10 +0000 +++ src/adaptation/icap/ServiceRep.cc 2011-06-24 14:59:58 +0000 @@ -106,9 +106,7 @@ else theIdleConns.closeN(1); - if (!(reused = Comm::IsConnOpen(connection))) - connection = new Comm::Connection; - else { + if ((reused = Comm::IsConnOpen(connection))) { debugs(93,3, HERE << "reused pconn " << connection); ++theBusyConns; } === modified file 'src/adaptation/icap/Xaction.cc' --- src/adaptation/icap/Xaction.cc 2011-06-17 10:41:10 +0000 +++ src/adaptation/icap/Xaction.cc 2011-06-24 16:27:17 +0000 @@ -16,6 +16,7 @@ #include "pconn.h" #include "HttpRequest.h" #include "HttpReply.h" +#include "ipcache.h" #include "acl/FilledChecklist.h" #include "icap_log.h" #include "fde.h" @@ -85,6 +86,13 @@ Must(static_cast(readBuf.potentialSpaceSize()) <= commBufSize); } +static void +icapLookupDnsResults(const ipcache_addrs *ia, const DnsLookupDetails &, void *data) +{ + Adaptation::Icap::Xaction *xa = static_cast(data); + xa->dnsLookupDone(ia); +} + // TODO: obey service-specific, OPTIONS-reported connection limit void Adaptation::Icap::Xaction::openConnection() @@ -124,9 +132,40 @@ // Attempt to open a new connection... debugs(93,3, typeName << " opens connection to " << s.cfg().host.termedBuf() << ":" << s.cfg().port); - // TODO: find the IPs and attempt each one if this is a named service. - connection->remote = s.cfg().host.termedBuf(); + // Locate the Service IP(s) to open + ipcache_nbgethostbyname(s.cfg().host.termedBuf(), icapLookupDnsResults, this); +} + +void +Adaptation::Icap::Xaction::dnsLookupDone(const ipcache_addrs *ia) +{ + Adaptation::Icap::ServiceRep &s = service(); + + if (ia == NULL) { + debugs(44, DBG_IMPORTANT, "ICAP: Unknown service host: " << s.cfg().host); + +#if WHEN_IPCACHE_NBGETHOSTBYNAME_USES_ASYNC_CALLS + dieOnConnectionFailure(); // throws +#else // take a step back into protected Async call dialing. + // fake the connect callback + typedef CommCbMemFunT Dialer; + CbcPointer self(this); + Dialer dialer(self, &Adaptation::Icap::Xaction::noteCommConnected); + dialer.params.conn = connection; + dialer.params.flag = COMM_ERROR; + // fake other parameters by copying from the existing connection + connector = asyncCall(93,3, "Adaptation::Icap::Xaction::noteCommConnected", dialer); + ScheduleCallHere(connector); +#endif + return; + } + + assert(ia->cur < ia->count); + + connection = new Comm::Connection; + connection->remote = ia->in_addrs[ia->cur]; connection->remote.SetPort(s.cfg().port); + getOutgoingAddress(NULL, connection); // TODO: service bypass status may differ from that of a transaction typedef CommCbMemFunT TimeoutDialer; === modified file 'src/adaptation/icap/Xaction.h' --- src/adaptation/icap/Xaction.h 2011-06-04 12:48:45 +0000 +++ src/adaptation/icap/Xaction.h 2011-06-24 16:28:35 +0000 @@ -41,6 +41,7 @@ #include "adaptation/Initiate.h" #include "AccessLogEntry.h" #include "HttpReply.h" +#include "ipcache.h" class CommConnectCbParams; @@ -133,6 +134,7 @@ // custom exception handling and end-of-call checks virtual void callException(const std::exception &e); virtual void callEnd(); + void dnsLookupDone(const ipcache_addrs *ia); protected: // logging