Esempio n. 1
0
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);
}
Esempio n. 2
0
/**
 * @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);
}
Esempio n. 3
0
/**
 * @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);
}
Esempio n. 4
0
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();
	});
}
Esempio n. 5
0
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();
	});
}
Esempio n. 6
0
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);
}