void Server::checkAndDispatchEpoll(int epollMillis) { constexpr int maxEvents = 256; epoll_event events[maxEvents]; std::list<Connection*> toBeDeleted; int numEvents = epoll_wait(_epollFd, events, maxEvents, epollMillis); if (numEvents == -1) { if (errno != EINTR) { LS_ERROR(_logger, "Error from epoll_wait: " << getLastError()); } return; } if (numEvents == maxEvents) { static time_t lastWarnTime = 0; time_t now = time(nullptr); if (now - lastWarnTime >= 60) { LS_WARNING(_logger, "Full event queue; may start starving connections. " "Will warn at most once a minute"); lastWarnTime = now; } } for (int i = 0; i < numEvents; ++i) { if (events[i].data.ptr == this) { if (events[i].events & ~EPOLLIN) { LS_SEVERE(_logger, "Got unexpected event on listening socket (" << EventBits(events[i].events) << ") - terminating"); _terminate = true; break; } handleAccept(); } else if (events[i].data.ptr == &_eventFd) { if (events[i].events & ~EPOLLIN) { LS_SEVERE(_logger, "Got unexpected event on management pipe (" << EventBits(events[i].events) << ") - terminating"); _terminate = true; break; } handlePipe(); } else { auto connection = reinterpret_cast<Connection*>(events[i].data.ptr); if (handleConnectionEvents(connection, events[i].events) == Close) { toBeDeleted.push_back(connection); } } } // The connections are all deleted at the end so we've processed any other subject's // closes etc before we call onDisconnect(). for (auto it = toBeDeleted.begin(); it != toBeDeleted.end(); ++it) { auto connection = *it; if (_connections.find(connection) == _connections.end()) { LS_SEVERE(_logger, "Attempt to delete connection we didn't know about: " << (void*)connection << formatAddress(connection->getRemoteAddress())); _terminate = true; break; } LS_DEBUG(_logger, "Deleting connection: " << formatAddress(connection->getRemoteAddress())); delete connection; } }
QString SpimView::formatMemoryContents(mem_addr from, mem_addr to) { mem_addr i = ROUND_UP(from, BYTES_PER_WORD); QString windowContents = formatPartialQuadWord(i, to); i = ROUND_UP(i, BYTES_PER_LINE); // Next quadword for ( ; i < to; ) { mem_word val; /* Count consecutive zero words */ int j; for (j = 0; (i + (uint32) j * BYTES_PER_WORD) < to; j += 1) { val = read_mem_word(i + (uint32) j * BYTES_PER_WORD); if (val != 0) { break; } } if (j >= 4) { /* Block of 4 or more zero memory words: */ windowContents += QString("[") % formatAddress(i) % QString("]..[") % formatAddress(i + (uint32) j * BYTES_PER_WORD - 1) % QString("]") % nnbsp(2) % QString("00000000<br>"); i = i + (uint32) j * BYTES_PER_WORD; windowContents += formatPartialQuadWord(i, to); i = ROUND_UP(i, BYTES_PER_LINE); // Next quadword } else { /* Fewer than 4 zero words, print them on a single line: */ windowContents += QString("[") % formatAddress(i) % "]" % nnbsp(2); mem_addr j = i; do { val = read_mem_word(i); windowContents += nnbsp(2) % formatWord(val, st_dataSegmentDisplayBase); i += BYTES_PER_WORD; } while ((i % BYTES_PER_LINE) != 0 && i < to); windowContents += nnbsp(2) % formatAsChars(j, i) % QString("<br>"); } } return windowContents; }
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))); }
QVariant DecisionDecisionTableModel::data(const QModelIndex &index, int role) const { if(!index.isValid()) return QVariant(); const marketDecision *decision = (const marketDecision *) index.internalPointer(); switch(role) { case Qt::DisplayRole: switch(index.column()) { case Address: return formatAddress(decision); case Prompt: return formatPrompt(decision); case EventOverBy: return QVariant((int)decision->eventOverBy); case IsScaled: return formatIsScaled(decision); case Minimum: return QVariant((double)decision->min*1e-8); case Maximum: return QVariant((double)decision->max*1e-8); case AnswerOptional: return formatAnswerOptional(decision); case Hash: return formatHash(decision); default: ; } break; case AddressRole: return formatAddress(decision); case PromptRole: return formatPrompt(decision); case Qt::TextAlignmentRole: return column_alignments[index.column()]; } return QVariant(); }
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; }
void dataTextEdit::changeValue() { QTextCursor cursor; mem_addr addr = addrFromPos(&cursor); if (addr != 0) { int base = Window->DataDisplayBase(); QString val = promptForNewValue("New Contents for " + formatAddress(addr), &base); bool ok; int newMemVal = val.toInt(&ok, base); if (ok) { set_mem_word(addr, newMemVal); } Window->DisplayDataSegments(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; } }
QString SpimView::formatPartialQuadWord(mem_addr from, mem_addr to) { QString windowContents = QString(""); if ((from % BYTES_PER_LINE) != 0 && from < to) { windowContents += QString("[") % formatAddress(from) % QString("]") % nnbsp(2); mem_addr a; for (a = from; (a % BYTES_PER_LINE) != 0; a += BYTES_PER_WORD) { mem_word val = read_mem_word(a); windowContents += nnbsp(2) % formatWord(val, st_dataSegmentDisplayBase); } windowContents += formatAsChars(from, a) % QString("<br>"); } return windowContents; }
std::string Server::getStatsDocument() const { std::ostringstream doc; doc << "clear();" << std::endl; for (auto it = _connections.begin(); it != _connections.end(); ++it) { doc << "connection({"; auto connection = it->first; jsonKeyPairToStream(doc, "since", EpochTimeAsLocal(it->second), "fd", connection->getFd(), "id", reinterpret_cast<uint64_t>(connection), "uri", connection->getRequestUri(), "addr", formatAddress(connection->getRemoteAddress()), "user", connection->credentials() ? connection->credentials()->username : "******", "input", connection->inputBufferSize(), "read", connection->bytesReceived(), "output", connection->outputBufferSize(), "written", connection->bytesSent() ); doc << "});" << std::endl; } return doc.str(); }
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; } } }
int session(const struct sockaddr* modem_address, socklen_t modem_address_length, uint32_t router_heartbeat_interval) { int ret = -1; char str_address[FORMATADDRESS_LEN] = {0}; /* First we must initialise, RFC 8175 section 7.2 */ int s = socket(modem_address->sa_family,SOCK_STREAM,0); if (s == -1) { printf("Failed to create socket: %s\n",strerror(errno)); return -1; } printf("Connecting to modem at %s\n",formatAddress(modem_address,str_address,sizeof(str_address))); /* Connect to the modem */ if (connect(s,modem_address,modem_address_length) == -1) { printf("Failed to connect socket: %s\n",strerror(errno)); } else if (send_session_init_message(s,router_heartbeat_interval)) { uint8_t* msg = NULL; ssize_t received; printf("Waiting for Session Initialization Response message\n"); /* Receive a Session Initialization Response message */ received = recv_message(s,&msg); if (received == -1) printf("Failed to receive from TCP socket: %s\n",strerror(errno)); else if (received == 0) printf("Modem disconnected TCP session\n"); else { printf("Received possible Session Initialization Response message (%u bytes)\n",(unsigned int)received); /* Check it's a valid Session Initialization Response message */ if (check_session_init_resp_message(msg,received) == DLEP_SC_SUCCESS) { uint32_t modem_heartbeat_interval = 60000; enum dlep_status_code init_sc = DLEP_SC_SUCCESS; enum dlep_status_code sc = parse_session_init_resp_message(msg+4,received-4,&modem_heartbeat_interval,&init_sc); if (sc != DLEP_SC_SUCCESS) { send_session_term(s,sc,&msg,modem_heartbeat_interval); } else if (init_sc != DLEP_SC_SUCCESS) { printf("Non-zero Status data item in Session Initialization Response message: %u, Terminating\n",init_sc); ret = send_session_term(s,DLEP_SC_SHUTDOWN,&msg,modem_heartbeat_interval); } else { printf("Moving to 'in-session' state\n"); ret = in_session(s,&msg,modem_heartbeat_interval,router_heartbeat_interval); } } } free(msg); } close(s); return ret; }
QString formatSegLabel(QString segName, mem_addr low, mem_addr high) { return QString("<center><b>") % segName % QString(" [") % formatAddress(low) % QString("]..[") % formatAddress(high) % QString("]</b></center>"); }