void WbDlg::endSession() { if(sender() == act_end_) { int n = QMessageBox::information(this, tr("Warning"), tr("Are you sure you want to end the session?\nThe contents of the whiteboard will be lost."), tr("&Yes"), tr("&No")); if(n != 0) return; } // terminate the underlying SXE session session()->endSession(); emit sessionEnded(this); }
/** * @brief Delete a session * * If the session is hibernatable, it will be stored before it is deleted. * * @param session */ void SessionServer::destroySession(Session *session) { Q_ASSERT(_sessions.contains(session)); session->unlistAnnouncement(); logger::debug() << session << "Deleting session. User count is" << session->userCount(); _sessions.removeOne(session); QString id = session->id(); session->stopRecording(); session->deleteLater(); // destroySession call might be triggered by a signal emitted from the session emit sessionEnded(id); }
/** * @brief Delete a session * * If the session is hibernatable, it will be stored before it is deleted. * * @param session */ void SessionServer::destroySession(SessionState *session) { Q_ASSERT(_sessions.contains(session)); logger::debug() << session << "Deleting session. User count is" << session->userCount(); _sessions.removeOne(session); QString id = session->id(); session->stopRecording(); if(session->isHibernatable() && _store) { logger::info() << session << "Hibernating."; _store->storeSession(session); } session->deleteLater(); // destroySession call might be triggered by a signal emitted from the session emit sessionEnded(id); }
MultiServer::MultiServer(QObject *parent) : QObject(parent), _server(0), _state(NOT_STARTED), _autoStop(false) { _sessions = new SessionServer(this); connect(_sessions, SIGNAL(sessionCreated(SessionState*)), this, SLOT(assignRecording(SessionState*))); connect(_sessions, SIGNAL(sessionEnded(QString)), this, SLOT(tryAutoStop())); connect(_sessions, SIGNAL(userLoggedIn()), this, SLOT(printStatusUpdate())); connect(_sessions, &SessionServer::userDisconnected, [this]() { printStatusUpdate(); // The server will be fully stopped after all users have disconnected if(_state == STOPPING) stop(); else tryAutoStop(); }); }
BuiltinServer::BuiltinServer(QObject *parent) : QObject(parent), _server(0), _state(NOT_STARTED) { _sessions = new SessionServer(this); // Set configurable settings QSettings cfg; cfg.beginGroup("settings/server"); _sessions->setHistoryLimit(qMax(0, int(cfg.value("historylimit", 0).toDouble() * 1024 * 1024))); _sessions->setConnectionTimeout(cfg.value("timeout", 60).toInt() * 1000); // Only one session per server is supported here _sessions->setSessionLimit(1); connect(_sessions, SIGNAL(sessionEnded(QString)), this, SLOT(stop())); connect(_sessions, &SessionServer::userDisconnected, [this]() { // The server will be fully stopped after all users have disconnected if(_state == STOPPING) stop(); }); }
static Iface_DEFUN incomingMsg(struct Message* msg, struct Pathfinder_pvt* pf) { struct Address addr; struct RouteHeader* hdr = (struct RouteHeader*) msg->bytes; Message_shift(msg, -(RouteHeader_SIZE + DataHeader_SIZE), NULL); Bits_memcpy(addr.ip6.bytes, hdr->ip6, 16); Bits_memcpy(addr.key, hdr->publicKey, 32); addr.protocolVersion = Endian_bigEndianToHost32(hdr->version_be); addr.padding = 0; addr.path = Endian_bigEndianToHost64(hdr->sh.label_be); //Log_debug(pf->log, "Incoming DHT"); struct DHTMessage dht = { .address = &addr, .binMessage = msg, .allocator = msg->alloc }; DHTModuleRegistry_handleIncoming(&dht, pf->registry); struct Message* nodeMsg = Message_new(0, 256, msg->alloc); Iface_CALL(sendNode, nodeMsg, &addr, 0xfffffff0u, pf); if (dht.pleaseRespond) { // what a beautiful hack, see incomingFromDHT return Iface_next(&pf->pub.eventIf, msg); } return NULL; } static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* eventIf) { struct Pathfinder_pvt* pf = Identity_containerOf(eventIf, struct Pathfinder_pvt, pub.eventIf); enum PFChan_Core ev = Message_pop32(msg, NULL); if (Pathfinder_pvt_state_INITIALIZING == pf->state) { Assert_true(ev == PFChan_Core_CONNECT); return connected(pf, msg); } // Let the PF send another 128 path changes again because it's basically a new tick. pf->bestPathChanges = 0; switch (ev) { case PFChan_Core_SWITCH_ERR: return switchErr(msg, pf); case PFChan_Core_SEARCH_REQ: return searchReq(msg, pf); case PFChan_Core_PEER: return peer(msg, pf); case PFChan_Core_PEER_GONE: return peerGone(msg, pf); case PFChan_Core_SESSION: return session(msg, pf); case PFChan_Core_SESSION_ENDED: return sessionEnded(msg, pf); case PFChan_Core_DISCOVERED_PATH: return discoveredPath(msg, pf); case PFChan_Core_MSG: return incomingMsg(msg, pf); case PFChan_Core_PING: return handlePing(msg, pf); case PFChan_Core_PONG: return handlePong(msg, pf); case PFChan_Core_UNSETUP_SESSION: case PFChan_Core_LINK_STATE: case PFChan_Core_CTRL_MSG: return NULL; default:; } Assert_failure("unexpected event [%d]", ev); } static void sendEvent(struct Pathfinder_pvt* pf, enum PFChan_Pathfinder ev, void* data, int size) { struct Allocator* alloc = Allocator_child(pf->alloc); struct Message* msg = Message_new(0, 512+size, alloc); Message_push(msg, data, size, NULL); Message_push32(msg, ev, NULL); Iface_send(&pf->pub.eventIf, msg); Allocator_free(alloc); } static void init(void* vpf) { struct Pathfinder_pvt* pf = Identity_check((struct Pathfinder_pvt*) vpf); struct PFChan_Pathfinder_Connect conn = { .superiority_be = Endian_hostToBigEndian32(1), .version_be = Endian_hostToBigEndian32(Version_CURRENT_PROTOCOL) }; CString_strncpy(conn.userAgent, "Cjdns internal pathfinder", 64); sendEvent(pf, PFChan_Pathfinder_CONNECT, &conn, PFChan_Pathfinder_Connect_SIZE); } struct Pathfinder* Pathfinder_register(struct Allocator* allocator, struct Log* log, struct EventBase* base, struct Random* rand, struct Admin* admin) { struct Allocator* alloc = Allocator_child(allocator); struct Pathfinder_pvt* pf = Allocator_calloc(alloc, sizeof(struct Pathfinder_pvt), 1); Identity_set(pf); pf->alloc = alloc; pf->log = log; pf->base = base; pf->rand = rand; pf->admin = admin; pf->pub.eventIf.send = incomingFromEventIf; pf->dhtModule.context = pf; pf->dhtModule.handleOutgoing = incomingFromDHT; // This needs to be done asynchronously so the pf can be plumbed to the core Timeout_setTimeout(init, pf, 0, base, alloc); return &pf->pub; }
WbDlg::~WbDlg() { // terminate the underlying SXE session session()->endSession(); emit sessionEnded(this); }