37#ifdef HAVE_NETINET_TCP_H
39#include <netinet/tcp.h>
63 debugs(5, 5, status() <<
" AsyncCall Subscription: " << aSub);
64 unsubscribe(
"subscription change");
71 debugs(5, 5, status() <<
" AsyncCall Subscription " << theCallSub <<
" removed: " << reason);
78 debugs(5, 5, status() <<
" AsyncCall Subscription: " << theCallSub);
100 if (theCallSub ==
nullptr) {
112 unsubscribe(
"swanSong");
114 if (closer_ !=
nullptr)
128 return "[nil connection]";
135 buf.
appendf(
" FD %d, %s",conn->fd, ipbuf);
138 buf.
append(jobStatus, strlen(jobStatus));
161#ifdef SO_ACCEPTFILTER
162 struct accept_filter_arg afa;
163 bzero(&afa,
sizeof(afa));
166 if (
xsetsockopt(conn->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa,
sizeof(afa)) < 0) {
170#elif defined(TCP_DEFER_ACCEPT)
174 if (
xsetsockopt(conn->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &seconds,
sizeof(seconds)) < 0) {
214 debugs(5, 2,
"New connection on FD " << fd);
225 }
catch (
const std::exception &e) {
226 fatalf(
"FATAL: error while accepting new client connection: %s\n", e.what());
228 fatal(
"FATAL: error while accepting new client connection: [unknown]\n");
235 static time_t last_warn = 0;
254 al->
url =
"error:accept-client-connection";
276 if (acceptInto(newConnDetails)) {
279 debugs(5, 5,
"Listener: " << conn <<
280 " accepted new connection " << newConnDetails <<
281 " handler Subscription: " << theCallSub);
285 debugs(5, 5,
"try later: " << conn <<
" handler Subscription: " << theCallSub);
286 newConnDetails->
close();
292 const auto debugLevel = intendedForUserConnections() ?
DBG_CRITICAL : 3;
293 debugs(5, debugLevel,
"ERROR: Stopped accepting connections:" <<
297 if (intendedForUserConnections())
298 logAcceptError(newConnDetails);
301 newConnDetails->
close();
309 mustStop(
"unrecoverable accept failure");
316 debugs(5, 2,
"connection on " << conn);
329 if (theCallSub !=
nullptr) {
332 params.
port = listenPort_;
333 params.
fd = conn->fd;
334 params.
conn = newConnDetails;
350 struct sockaddr_storage remoteAddress = {};
351 socklen_t remoteAddressSize =
sizeof(remoteAddress);
352 const auto rawSock =
xaccept(conn->fd,
reinterpret_cast<struct sockaddr *
>(&remoteAddress), &remoteAddressSize);
355 if (
ignoreErrno(errcode) || errcode == ECONNABORTED) {
368 const auto sock = rawSock;
374 details->
remote = remoteAddress;
377 struct sockaddr_storage localAddress = {};
378 socklen_t localAddressSize =
sizeof(localAddress);
379 if (
xgetsockname(sock,
reinterpret_cast<struct sockaddr *
>(&localAddress), &localAddressSize) != 0) {
381 debugs(50,
DBG_IMPORTANT,
"ERROR: Closing accepted TCP connection after failing to obtain its local IP address" <<
387 details->
local = localAddress;
391 if (!Ip::Interceptor.TransparentActive()) {
392 debugs(50,
DBG_IMPORTANT,
"ERROR: Cannot use transparent " << details <<
" because TPROXY mode became inactive");
398 if (!Ip::Interceptor.LookupNat(*details)) {
399 debugs(50,
DBG_IMPORTANT,
"ERROR: NAT lookup failed to locate original IPs on " << details);
void accessLogLog(const AccessLogEntryPointer &, ACLChecklist *)
#define Assure(condition)
#define ScheduleCallHere(call)
#define JobCallback(dbgSection, dbgLevel, Dialer, job, method)
Convenience macro to create a Dialer-based job callback.
void CallBack(const CodeContext::Pointer &callbackContext, Fun &&callback)
#define COMM_INTERCEPTION
#define Here()
source code location of the caller
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
#define CBDATA_NAMESPACED_CLASS_INIT(namespace, type)
AccessLogEntry::Pointer al
info for the future access.log, and external ACL
Comm::ConnectionPointer tcpClient
TCP/IP level details about the client connection.
void setVirginUrlForMissingRequest(const SBuf &vu)
Remember Client URI (or equivalent) when there is no HttpRequest.
virtual bool doneAll() const
whether positive goal has been reached
virtual const char * status() const
internal cleanup; do not call directly
AnyP::PortCfgPointer port
the configuration listening port this call relates to (may be nil)
int xerrno
The last errno to occur. non-zero if flag is Comm::COMM_ERROR.
int fd
FD which the call was about. Set by the async call creator.
Comm::Flag flag
comm layer result status.
Comm::ConnectionPointer conn
void defer(const TcpAcceptor::Pointer &afd)
void removeDead(const TcpAcceptor::Pointer &afd)
static AcceptLimiter & Instance()
void enterOrphanage()
close the still-open connection when its last reference is gone
static void doAccept(int fd, void *data)
Method callback for whenever an FD is ready to accept a client connection.
void start() override
called by AsyncStart; do not call directly
TcpAcceptor(const TcpAcceptor &)
void unsubscribe(const char *reason)
bool doneAll() const override
whether positive goal has been reached
void handleClosure(const CommCloseCbParams &io)
const char * status() const override
internal cleanup; do not call directly
bool acceptInto(Comm::ConnectionPointer &)
void subscribe(const Subscription::Pointer &aSub)
void notify(const Comm::Flag flag, const Comm::ConnectionPointer &details) const
Call the subscribed callback handler with details about a new connection.
void logAcceptError(const ConnectionPointer &tcpClient) const
static std::ostream & Extra(std::ostream &)
bool lookup(const Ip::Address &c)
bool lookup(const Ip::Address &c)
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
unsigned short port() const
void append(const char *c, int sz) override
char * content()
start of the added data
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
int client_ip_max_connections
struct StatCounters::@112 syscalls
struct StatCounters::@112::@117 sock
an std::runtime_error with thrower location info
struct fde::_fde_flags flags
unsigned short remote_port
char ipaddr[MAX_IPSTRLEN]
int clientdbEstablished(const Ip::Address &addr, int delta)
void fd_open(const int fd, unsigned int, const char *description)
int commSetNonBlocking(int fd)
AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *handler, void *data)
void comm_remove_close_handler(int fd, CLCB *handler, void *data)
void commSetCloseOnExec(int fd)
int ignoreErrno(int ierrno)
bool isOpen(const int fd)
#define debugs(SECTION, LEVEL, CONTENT)
void fatal(const char *message)
void fatalf(const char *fmt,...)
int incoming_sockets_accepted
#define MAX_IPSTRLEN
Length of buffer that needs to be allocated to old a null-terminated IP-string.
Abstraction layer for TCP, UDP, TLS, UDS and filedescriptor sockets.
bool IsConnOpen(const Comm::ConnectionPointer &conn)
void ApplyTcpKeepAlive(int fd, const TcpKeepAlive &)
apply configured TCP keep-alive settings to the given FD socket
void SetSelect(int, unsigned int, PF *, void *, time_t)
Mark an FD to be watched for its IO status.
@ dirAccepted
accepted (from a client by Squid)
nfmark_t getNfConnmark(const Comm::ConnectionPointer &conn, const ConnectionDirection connDir)
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
int xgetsockname(int socketFd, struct sockaddr *sa, socklen_t *saLength)
POSIX getsockname(2) equivalent.
int xaccept(int socketFd, struct sockaddr *sa, socklen_t *saLength)
POSIX accept(2) equivalent.
int xsetsockopt(int socketFd, int level, int option, const void *value, socklen_t valueLength)
POSIX setsockopt(2) equivalent.
int xlisten(int socketFd, int backlog)
POSIX listen(2) equivalent.
const char * xstrerr(int error)
char * xstrncpy(char *dst, const char *src, size_t n)