int LcReplGroup::connGroupLstnrs() { Addr2ClntConnMap_t::iterator itr; Addr2ClntConnMap_t &lstrMap = m_pSockConnMgr->getClntConnMap(); const char* sockAddr; ClientConn * pConn; for (itr = lstrMap.begin(); itr != lstrMap.end(); itr = lstrMap.next ( itr )) { sockAddr = itr.first(); pConn = itr.second(); LS_DBG_M("LcReplGroup::connAllListenSvr addr:%s", sockAddr); if (!pConn->isActive() ) { LS_DBG_M("LcReplGroup::connAllListenSvr is not active, pMultiplexer:%p", getMultiplexer()); pConn->closeConnection(); pConn->SetMultiplexer(getMultiplexer() ); GSockAddr serverAddr; serverAddr.set(sockAddr, AF_INET ); if (pConn->connectTo (&serverAddr) != -1) { LS_INFO ("node[%s] addr=%p, is connecting to master[%s]" ,pConn->getLocalAddr(), pConn, sockAddr); LcReplSender::getInstance().clientJoinListenSvrReq(pConn); } else LS_INFO ("failed to connect to master %d", pConn->isActive()); } } return LS_OK; }
void ProxyConn::onTimer() { // if (!( getEvents() & POLLIN )) // { // LS_WARN( this, "Oops! POLLIN is turned off for this proxy connection," // " turn it on, this should never happen!!!!"); // continueRead(); // } // if (( m_iTotalPending > 0 )&& !( getEvents() & POLLOUT )) // { // LS_WARN( this, "Oops! POLLOUT is turned off while there is pending data," // " turn it on, this should never happen!!!!"); // continueWrite(); // } if (m_lLastRespRecvTime) { long tm = time(NULL); long delta = tm - m_lLastRespRecvTime; if ((delta > getWorker()->getTimeout()) && (m_iRespBodyRecv)) { if (m_pChunkIS) { LS_INFO(this, "Timeout, partial chunk encoded body received," " received: %d, chunk len: %d, remain: %d!", m_iRespBodyRecv, m_pChunkIS->getChunkLen(), m_pChunkIS->getChunkRemain()); } else LS_INFO(this, "Timeout, partial response body received," " body len: %d, received: %d!", m_iRespBodySize, m_iRespBodyRecv); setState(ABORT); getConnector()->endResponse(0, 0);; return; } else if ((m_pChunkIS) && (!m_pChunkIS->getChunkLen()) && (delta > 1)) { if ((getConnector())) { LS_DBG_L(this, "Missing trailing CRLF in Chunked Encoding," " remain: %d!", m_pChunkIS->getChunkRemain()); // const char * p = m_pChunkIS->getLastBytes(); // LS_INFO(this, // "Last 8 bytes are: %#x %#x %#x %#x %#x %#x %#x %#x", // p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); // HttpReq * pReq = getConnector()->getHttpSession()->getReq(); // pReq->dumpHeader(); setState(CLOSING); getConnector()->endResponse(0, 0); return; } } } ExtConn::onTimer(); }
/*** * We try to make log available even if errorlog is not setup. * So, at the beginning, we put the logs to StringList plainconf::errorLogList by call logToMem() * once flushErrorLog() is called, it means errorlog is setup, and this function will save all * the buffered logs to errorlog file. * Then if logToMem still be called, it should not access the stringlist anymore, * but just access the errorlog directly. */ void plainconf::logToMem(char errorLevel, const char *format, ...) { char buf[512]; sprintf(buf, "%c[PlainConf] ", errorLevel); int len = strlen(buf); if (gModuleList.size() > 0) { XmlNode *pCurNode = (XmlNode *)gModuleList.back(); sprintf(buf + len, "[%s:%s] ", pCurNode->getName(), ((pCurNode->getValue() == NULL) ? "" : pCurNode->getValue())); } len = strlen(buf); va_list ap; va_start(ap, format); int ret = vsnprintf(buf + len, 512 - len, format, ap); va_end(ap); if (!bErrorLogSetup) errorLogList.add(buf, ret + len); else { if (errorLevel == LOG_LEVEL_ERR) LS_ERROR(buf + 1); else LS_INFO(buf + 1); } }
void Server::handleAccept() { sockaddr_in address; socklen_t addrLen = sizeof(address); int fd = ::accept(_listenSock, reinterpret_cast<sockaddr*>(&address), &addrLen); if (fd == -1) { LS_ERROR(_logger, "Unable to accept: " << getLastError()); return; } if (!configureSocket(fd)) { ::close(fd); return; } LS_INFO(_logger, formatAddress(address) << " : Accepted on descriptor " << fd); Connection* newConnection = new Connection(_logger, *this, fd, address); epoll_event event = { EPOLLIN, { newConnection } }; if (epoll_ctl(_epollFd, EPOLL_CTL_ADD, fd, &event) == -1) { LS_ERROR(_logger, "Unable to add socket to epoll: " << getLastError()); delete newConnection; ::close(fd); return; } _connections.insert(std::make_pair(newConnection, time(nullptr))); }
//the min IP is the one bool LcReplGroup::isSelfMinAddr(const StringList &clntlist, const char* pMyAddr) { char pSvrAddr[64]; StringList::const_iterator itr; for ( itr = clntlist.begin(); itr != clntlist.end(); itr++ ) { if (isEqualIpOfAddr(pSvrAddr, pMyAddr) < 0) { LS_INFO( "Myself[%s] is not min Addr, at leaset node[%s] exists", pMyAddr, pSvrAddr); return false; } } LS_INFO( "MySelf[%s] is the min Addr", pMyAddr); return true; }
int LcReplGroup::clearClntOnClose(const char *pAddr) { LS_INFO ( "LcReplGroup::clearClntOnClose: deleting socket client[%s]", pAddr); getSockConnMgr()->delAcceptedNode(pAddr); getNodeInfoMgr()->delNodeInfo(pAddr); getStNodeInfoMgr()->delNodeInfo(pAddr); LS_DBG_M( "clearClntOnClose client[%s], ReplStatus size=%d, StaticStatus size=%d, m_hClientReplPeer size=%d" , pAddr, getNodeInfoMgr()->size(), getStNodeInfoMgr()->size(), getSockConnMgr()->getAcptedConnCnt()); return LS_OK; }
void LcReplGroup::delClntInfoAll(const char *pClntAddr) { LS_INFO ( "LcReplGroup::delClntInfoAll: deleting socket client[%s]", pClntAddr); getSockConnMgr()->delAcceptedNode(pClntAddr); getNodeInfoMgr()->delNodeInfo(pClntAddr); getStNodeInfoMgr()->delNodeInfo(pClntAddr); LS_DBG_M( "delClntInfoAll client[%s], ReplStatus size=%d, StaticStatus size=%d, m_hClientReplPeer size=%d" , pClntAddr, getNodeInfoMgr()->size(), getStNodeInfoMgr()->size(), getSockConnMgr()->getAcptedConnCnt()); }
Server::~Server() { LS_INFO(_logger, "Server destruction"); shutdown(); // Only shut the eventfd and epoll at the very end if (_eventFd != -1) { close(_eventFd); } if (_epollFd != -1) { close(_epollFd); } }
void ProxyConn::dump() { LS_INFO(this, "Proxy connection state: %d, watching event: %d, " "Request header:%d, body:%d, sent:%d, " "Response header: %d, total: %d bytes received in %ld seconds," "Total processing time: %ld.", getState(), getEvents(), m_iReqHeaderSize, m_iReqBodySize, m_iReqTotalSent, m_iRespHeaderRecv, m_iRespRecv, (m_lReqSentTime) ? time(NULL) - m_lReqSentTime : 0, time(NULL) - m_lReqBeginTime); // if ( m_iRespHeaderRecv > 0 ) // { // m_achRespBuf[ m_iRespHeaderRecv ] = 0; // LS_INFO(this, "Response Header Received:%s", m_achRespBuf); // } }
bool Server::startListening(uint32_t hostAddr, int port) { if (_epollFd == -1 || _eventFd == -1) { LS_ERROR(_logger, "Unable to serve, did not initialize properly."); return false; } auto port16 = static_cast<uint16_t>(port); if (port != port16) { LS_ERROR(_logger, "Invalid port: " << port); return false; } _listenSock = socket(AF_INET, SOCK_STREAM, 0); if (_listenSock == -1) { LS_ERROR(_logger, "Unable to create listen socket: " << getLastError()); return false; } if (!configureSocket(_listenSock)) { return false; } sockaddr_in sock; memset(&sock, 0, sizeof(sock)); sock.sin_port = htons(port16); sock.sin_addr.s_addr = htonl(hostAddr); sock.sin_family = AF_INET; if (bind(_listenSock, reinterpret_cast<const sockaddr*>(&sock), sizeof(sock)) == -1) { LS_ERROR(_logger, "Unable to bind socket: " << getLastError()); return false; } if (listen(_listenSock, 5) == -1) { LS_ERROR(_logger, "Unable to listen on socket: " << getLastError()); return false; } epoll_event event = { EPOLLIN, { this } }; if (epoll_ctl(_epollFd, EPOLL_CTL_ADD, _listenSock, &event) == -1) { LS_ERROR(_logger, "Unable to add listen socket to epoll: " << getLastError()); return false; } char buf[1024]; ::gethostname(buf, sizeof(buf)); LS_INFO(_logger, "Listening on http://" << buf << ":" << port << "/"); return true; }
void Server::processEventQueue() { runExecutables(); time_t now = time(nullptr); if (now < _nextDeadConnectionCheck) return; std::list<Connection*> toRemove; for (auto it = _connections.cbegin(); it != _connections.cend(); ++it) { time_t numSecondsSinceConnection = now - it->second; auto connection = it->first; if (connection->bytesReceived() == 0 && numSecondsSinceConnection >= _lameConnectionTimeoutSeconds) { LS_INFO(_logger, formatAddress(connection->getRemoteAddress()) << " : Killing lame connection - no bytes received after " << numSecondsSinceConnection << "s"); toRemove.push_back(connection); } } for (auto it = toRemove.begin(); it != toRemove.end(); ++it) { delete *it; } }
bool Server::loop() { if (_listenSock == -1) { LS_ERROR(_logger, "Server not initialised"); return false; } // Stash away "the" server thread id. _threadId = gettid(); while (!_terminate) { // Always process events first to catch start up events. processEventQueue(); checkAndDispatchEpoll(EpollTimeoutMillis); } // Reasonable effort to ensure anything enqueued during terminate has a chance to run. processEventQueue(); LS_INFO(_logger, "Server terminating"); shutdown(); return _expectedTerminate; }
static int for_each_fn(void *s) { const char *p = ((AutoStr2 *)s)->c_str(); switch (*p) { case LOG_LEVEL_ERR: LS_ERROR(p + 1); break; case LOG_LEVEL_INFO: LS_INFO(p + 1); break; default: break; } return 0; }
Server::PollResult Server::poll(int millis) { // Grab the thread ID on the first poll. if (_threadId == 0) _threadId = gettid(); if (_threadId != gettid()) { LS_ERROR(_logger, "poll() called from the wrong thread"); return PollResult::Error; } if (_listenSock == -1) { LS_ERROR(_logger, "Server not initialised"); return PollResult::Error; } processEventQueue(); checkAndDispatchEpoll(millis); if (!_terminate) return PollResult::Continue; // Reasonable effort to ensure anything enqueued during terminate has a chance to run. processEventQueue(); LS_INFO(_logger, "Server terminating"); shutdown(); return _expectedTerminate ? PollResult::Terminated : PollResult::Error; }
void Server::processEventQueue() { for (;;) { std::shared_ptr<Runnable> runnable = popNextRunnable(); if (!runnable) break; runnable->run(); } time_t now = time(NULL); if (now >= _nextDeadConnectionCheck) { std::list<Connection*> toRemove; for (auto it = _connections.cbegin(); it != _connections.cend(); ++it) { time_t numSecondsSinceConnection = now - it->second; auto connection = it->first; if (connection->bytesReceived() == 0 && numSecondsSinceConnection >= _lameConnectionTimeoutSeconds) { LS_INFO(_logger, formatAddress(connection->getRemoteAddress()) << " : Killing lame connection - no bytes received after " << numSecondsSinceConnection << "s"); toRemove.push_back(connection); } } for (auto it = toRemove.begin(); it != toRemove.end(); ++it) { delete *it; } } }
Server::NewState Server::handleConnectionEvents(Connection* connection, uint32_t events) { if (events & ~(EPOLLIN|EPOLLOUT|EPOLLHUP|EPOLLERR)) { LS_WARNING(_logger, "Got unhandled epoll event (" << EventBits(events) << ") on connection: " << formatAddress(connection->getRemoteAddress())); return Close; } else if (events & EPOLLERR) { LS_INFO(_logger, "Error on socket (" << EventBits(events) << "): " << formatAddress(connection->getRemoteAddress())); return Close; } else if (events & EPOLLHUP) { LS_DEBUG(_logger, "Graceful hang-up (" << EventBits(events) << ") of socket: " << formatAddress(connection->getRemoteAddress())); return Close; } else { if (events & EPOLLOUT) { connection->handleDataReadyForWrite(); } if (events & EPOLLIN) { connection->handleDataReadyForRead(); } } return KeepOpen; }
bool Server::startListeningUnix(const char* socketPath) { struct sockaddr_un sock; _listenSock = socket(AF_UNIX, SOCK_STREAM, 0); if (_listenSock == -1) { LS_ERROR(_logger, "Unable to create unix listen socket: " << getLastError()); return false; } if (!configureSocket(_listenSock)) { return false; } memset(&sock, 0, sizeof(struct sockaddr_un)); sock.sun_family = AF_UNIX; strncpy(sock.sun_path, socketPath, sizeof(sock.sun_path) - 1); if (bind(_listenSock, reinterpret_cast<const sockaddr*>(&sock), sizeof(sock)) == -1) { LS_ERROR(_logger, "Unable to bind unix socket (" << socketPath << "): " << getLastError()); return false; } if (listen(_listenSock, 5) == -1) { LS_ERROR(_logger, "Unable to listen on unix socket: " << getLastError()); return false; } epoll_event event = { EPOLLIN, { this } }; if (epoll_ctl(_epollFd, EPOLL_CTL_ADD, _listenSock, &event) == -1) { LS_ERROR(_logger, "Unable to add unix listen socket to epoll: " << getLastError()); return false; } LS_INFO(_logger, "Listening on unix socket: http://unix:" << socketPath); return true; }
void Server::setMaxKeepAliveDrops(int maxKeepAliveDrops) { LS_INFO(_logger, "Setting max keep alive drops to " << maxKeepAliveDrops); _maxKeepAliveDrops = maxKeepAliveDrops; }
void Server::setLameConnectionTimeoutSeconds(int seconds) { LS_INFO(_logger, "Setting lame connection timeout to " << seconds); _lameConnectionTimeoutSeconds = seconds; }
void Server::setStaticPath(const char* staticPath) { LS_INFO(_logger, "Serving content from " << staticPath); _staticPath = staticPath; }
void Awstats::config(HttpVHost *pVHost, int val, char *achBuf, const XmlNode *pAwNode, char *iconURI, const char *vhDomain, int vhAliasesLen) { const char *pURI; const char *pValue; char *p; int handlerType; int len = strlen(achBuf); int iChrootLen = 0; if (ServerProcessConfig::getInstance().getChroot() != NULL) iChrootLen = ServerProcessConfig::getInstance().getChroot()->len(); setMode(val); if (achBuf[len - 1] == '/') achBuf[len - 1] = 0; setWorkingDir(achBuf); pURI = pAwNode->getChildValue("awstatsURI"); if ((!pURI) || (*pURI != '/') || (* (pURI + strlen(pURI) - 1) != '/') || (strlen(pURI) > 100)) { LS_WARN(ConfigCtx::getCurConfigCtx(), "AWStats URI is invalid" ", use default [/awstats/]."); iconURI[9] = 0;; pURI = iconURI; } setURI(pURI); if (val == AWS_STATIC) { handlerType = HandlerType::HT_NULL; strcat(achBuf, "/html/"); } else { ConfigCtx::getCurConfigCtx()->getValidPath(achBuf, "$SERVER_ROOT/add-ons/awstats/wwwroot/cgi-bin/", "AWStats CGI-BIN directory"); if (pVHost->getRootContext().determineMime("pl", NULL)->getHandler()->getType()) handlerType = HandlerType::HT_NULL; else handlerType = HandlerType::HT_CGI; } HttpContext *pContext = pVHost->addContext(pURI, handlerType, &achBuf[iChrootLen], NULL, 1); p = achBuf; if (ConfigCtx::getCurConfigCtx()->getLongValue(pAwNode, "securedConn", 0, 1, 0) == 1) { p += ls_snprintf(achBuf, 8192, "rewriteCond %%{HTTPS} !on\n" "rewriteCond %%{HTTP:X-Forwarded-Proto} !https\n" "rewriteRule ^(.*)$ https://%%{SERVER_NAME}%%{REQUEST_URI} [R,L]\n"); } if (val == AWS_STATIC) { ls_snprintf(p, &achBuf[8192] - p, "RewriteRule ^$ awstats.%s.html\n", pVHost->getName()); } else { ls_snprintf(p, &achBuf[8192] - p, "RewriteRule ^$ awstats.pl\n" "RewriteCond %%{QUERY_STRING} !configdir=\n" "RewriteRule ^awstats.pl " "$0?config=%s&configdir=%s/conf [QSA]\n", pVHost->getName(), getWorkingDir() + iChrootLen); pContext->setUidMode(UID_DOCROOT); } pContext->enableRewrite(1); pContext->configRewriteRule(pVHost->getRewriteMaps(), achBuf); pValue = pAwNode->getChildValue("realm"); if (pValue) pVHost->configAuthRealm(pContext, pValue); pValue = pAwNode->getChildValue("siteDomain"); if (!pValue) { LS_WARN(ConfigCtx::getCurConfigCtx(), "SiteDomain configuration is invalid" ", use default [%s].", vhDomain); pValue = vhDomain; } else { ConfigCtx::getCurConfigCtx()->expandDomainNames(pValue, achBuf, 4096); pValue = achBuf; } setSiteDomain(pValue); pValue = pAwNode->getChildValue("siteAliases"); int needConvert = 1; if (!pValue) { if (vhAliasesLen == 0) { ls_snprintf(achBuf, 8192, "127.0.0.1 localhost REGEX[%s]", getSiteDomain()); LS_WARN(ConfigCtx::getCurConfigCtx(), "SiteAliases configuration is invalid" ", use default [%s].", achBuf); pValue = achBuf; needConvert = 0; } else pValue = "$vh_aliases"; } if (needConvert) { ConfigCtx::getCurConfigCtx()->expandDomainNames(pValue, &achBuf[4096], 4096, ' '); ConfigCtx::getCurConfigCtx()->convertToRegex(&achBuf[4096], achBuf, 4096); pValue = achBuf; LS_INFO(ConfigCtx::getCurConfigCtx(), "SiteAliases is set to '%s'", achBuf); } setAliases(pValue); val = ConfigCtx::getCurConfigCtx()->getLongValue(pAwNode, "updateInterval", 3600, 3600 * 24, 3600 * 24); if (val % 3600 != 0) val = ((val + 3599) / 3600) * 3600; setInterval(val); val = ConfigCtx::getCurConfigCtx()->getLongValue(pAwNode, "updateOffset", 0, LONG_MAX, 0); if (val > getInterval()) val %= getInterval(); setOffset(val); pVHost->setAwstats(this); }
void Task::slotResultReady(const QString &result) { LS_FUNC(""); LS_INFO("WorkerThread: " << result); }