43 debugs(5, 3,
"will connect to " << c <<
" with " << ctimeout <<
" timeout");
63 if (conn_ ==
nullptr) {
68 if (callback_ ==
nullptr || callback_->canceled()) {
73 Must(temporaryFd_ >= 0 || calls_.sleep_);
80 if (callback_ !=
nullptr) {
86 if (temporaryFd_ >= 0)
90 if (conn_ && conn_->isOpen())
104 if (host_ !=
nullptr)
108 if (new_host !=
nullptr)
126 if (host_ !=
nullptr) {
138 if (callback_ !=
nullptr) {
141 if (callback_->canceled()) {
142 debugs(5, 4, conn_ <<
" not calling canceled " << *callback_ <<
143 " [" << callback_->id <<
']' );
155 Params ¶ms = GetCommParams<Params>(callback_);
158 params.flag = errFlag;
159 params.xerrno = xerrno;
176 debugs(5, 4, conn_ <<
"; temp FD " << temporaryFd_);
178 Must(temporaryFd_ >= 0);
203 if (calls_.timeout_ !=
nullptr) {
204 calls_.timeout_->cancel(
"Comm::ConnOpener::cleanFd");
205 calls_.timeout_ =
nullptr;
212 if (calls_.earlyAbort_ !=
nullptr) {
214 calls_.earlyAbort_ =
nullptr;
222 if (temporaryFd_ < 0)
241 Must(conn_ !=
nullptr);
242 Must(temporaryFd_ >= 0);
246 conn_->fd = temporaryFd_;
253 Must(conn_ !=
nullptr);
257 conn_->local.setIPv4();
269 debugs(5, 5, conn_ <<
" restarting after sleep");
270 calls_.sleep_ =
false;
281 Must(temporaryFd_ < 0);
285 if (callback_ ==
nullptr || callback_->canceled())
288 temporaryFd_ =
comm_open(SOCK_STREAM, IPPROTO_TCP, conn_->local, conn_->flags, host_);
289 if (temporaryFd_ < 0) {
296 Ip::Qos::setSockTos(temporaryFd_, conn_->tos, conn_->remote.isIPv4() ? AF_INET : AF_INET6) < 0)
304 fd_table[temporaryFd_].tosToServer = conn_->tos;
305 fd_table[temporaryFd_].nfmarkToServer = conn_->nfmark;
319 Params ¶ms = GetCommParams<Params>(calls_.timeout_);
321 fd_table[temporaryFd_].timeoutHandler = calls_.timeout_;
322 fd_table[temporaryFd_].timeout = deadline_;
330 Must(temporaryFd_ >= 0);
340 ++peer->stats.conn_open;
342 lookupLocalAddress();
350 fd_table[conn_->fd].local_addr = conn_->local;
352 sendAnswer(
Comm::OK, 0,
"Comm::ConnOpener::connected");
359 Must(conn_ !=
nullptr);
360 Must(temporaryFd_ >= 0);
367 debugs(5, 5, conn_ <<
": Comm::INPROGRESS");
372 debugs(5, 5, conn_ <<
": Comm::OK - connected");
377 const int xerrno = errno;
380 debugs(5, 7, conn_ <<
": failure #" << failRetries_ <<
" <= " <<
384 debugs(5, 5, conn_ <<
": * - try again");
389 debugs(5, 5, conn_ <<
": * - ERR tried too many times already.");
400 Must(!calls_.sleep_);
402 calls_.sleep_ =
true;
403 eventAdd(
"Comm::ConnOpener::DelayedConnectRetry",
405 new Pointer(
this), 0.05, 0,
false);
421 calls_.sleep_ =
false;
422 debugs(5, 9, conn_ <<
" stops sleeping");
433 struct sockaddr_storage addr = {};
435 if (
xgetsockname(conn_->fd,
reinterpret_cast<struct sockaddr *
>(&addr), &len) != 0) {
452 calls_.earlyAbort_ =
nullptr;
464 debugs(5, 5, conn_ <<
": * - ERR took too long to receive response.");
465 calls_.timeout_ =
nullptr;
466 sendAnswer(
Comm::TIMEOUT, ETIMEDOUT,
"Comm::ConnOpener::timeout");
#define ScheduleCallHere(call)
#define JobCallback(dbgSection, dbgLevel, Dialer, job, method)
Convenience macro to create a Dialer-based job callback.
#define CBDATA_NAMESPACED_CLASS_INIT(namespace, type)
virtual bool doneAll() const
whether positive goal has been reached
Cbc * valid() const
was set and is valid
int xerrno
The last errno to occur. non-zero if flag is Comm::COMM_ERROR.
Comm::ConnectionPointer conn
void timeout(const CommTimeoutCbParams &)
Comm::ConnectionPointer conn_
single connection currently to be opened.
void restart()
called at the end of Comm::ConnOpener::DelayedConnectRetry event
static void InProgressConnectRetry(int fd, void *data)
void retrySleep()
Close and wait a little before trying to open and connect again.
void cancelSleep()
cleans up this job sleep state
static void DelayedConnectRetry(void *data)
void setHost(const char *)
set the hostname note for this connection
void earlyAbort(const CommCloseCbParams &)
void closeFd()
cleans I/O state and ends I/O for temporaryFd_
void sendAnswer(Comm::Flag errFlag, int xerrno, const char *why)
ConnOpener(const Comm::ConnectionPointer &, const AsyncCall::Pointer &handler, time_t connect_timeout)
void start() override
called by AsyncStart; do not call directly
void lookupLocalAddress()
bool doneAll() const override
whether positive goal has been reached
void keepFd()
cleans I/O state and moves temporaryFd_ to the conn_ for long-term use
void doConnect()
Make an FD connection attempt.
const char * getHost() const
get the hostname noted for this connection
struct SquidConfig::@90 onoff
AsyncCall::Pointer timeoutHandler
AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *handler, void *data)
void comm_remove_close_handler(int fd, CLCB *handler, void *data)
int comm_open(int sock_type, int proto, Ip::Address &addr, int flags, const char *note)
int comm_connect_addr(int sock, const Ip::Address &address)
#define debugs(SECTION, LEVEL, CONTENT)
#define COMM_SELECT_WRITE
void eventAdd(const char *name, EVH *func, void *arg, double when, int weight, bool cbdata)
void ipcacheMarkGoodAddr(const char *name, const Ip::Address &addr)
void ipcacheMarkBadAddr(const char *name, const Ip::Address &addr)
Abstraction layer for TCP, UDP, TLS, UDS and filedescriptor sockets.
void SetSelect(int, unsigned int, PF *, void *, time_t)
Mark an FD to be watched for its IO status.
int setSockTos(const Comm::ConnectionPointer &conn, tos_t tos)
int setSockNfmark(const Comm::ConnectionPointer &conn, nfmark_t mark)
void netdbDeleteAddrNetwork(Ip::Address &addr)
int xgetsockname(int socketFd, struct sockaddr *sa, socklen_t *saLength)
POSIX getsockname(2) equivalent.
const char * xstrerr(int error)