X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fcommon%2Fsignalproxy.cpp;h=db4a675835e733d4a616d14f6404c9ed2a391b1d;hb=30fa961d1aca319b52071ad9d6e4527ea2638fb7;hp=45f3b50acc83c92c62c604bffa12f94cd392bb5d;hpb=c1722505b4906fe59c48aad54e6545a17afb78d7;p=quassel.git diff --git a/src/common/signalproxy.cpp b/src/common/signalproxy.cpp index 45f3b50a..db4a6758 100644 --- a/src/common/signalproxy.cpp +++ b/src/common/signalproxy.cpp @@ -156,9 +156,11 @@ int SignalProxy::SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void ** params << QVariant(argTypes[i], _a[i+1]); } - if (argTypes.size() >= 1 && argTypes[0] == qMetaTypeId() && proxy()->proxyMode() == SignalProxy::Server) { - Peer *peer = params[0].value(); - proxy()->dispatch(peer, RpcCall(signal.signature, params)); + if (proxy()->_restrictMessageTarget) { + for (auto peer : proxy()->_restrictedTargets) { + if (peer != nullptr) + proxy()->dispatch(peer, RpcCall(signal.signature, params)); + } } else proxy()->dispatch(RpcCall(signal.signature, params)); } @@ -207,7 +209,7 @@ SignalProxy::~SignalProxy() void SignalProxy::setProxyMode(ProxyMode mode) { - if (_peers.count()) { + if (!_peerMap.empty()) { qWarning() << Q_FUNC_INFO << "Cannot change proxy mode while connected"; return; } @@ -266,7 +268,7 @@ bool SignalProxy::addPeer(Peer *peer) if (!peer) return false; - if (_peers.contains(peer)) + if (_peerMap.values().contains(peer)) return true; if (!peer->isOpen()) { @@ -275,7 +277,7 @@ bool SignalProxy::addPeer(Peer *peer) } if (proxyMode() == Client) { - if (!_peers.isEmpty()) { + if (!_peerMap.isEmpty()) { qWarning("SignalProxy: only one peer allowed in client mode!"); return false; } @@ -288,16 +290,16 @@ bool SignalProxy::addPeer(Peer *peer) if (!peer->parent()) peer->setParent(this); - if (peer->_id < 0) { - peer->_id = nextPeerId(); + if (peer->id() < 0) { + peer->setId(nextPeerId()); + peer->setConnectedSince(QDateTime::currentDateTimeUtc()); } - _peers.insert(peer); - _peerMap[peer->_id] = peer; + _peerMap[peer->id()] = peer; peer->setSignalProxy(this); - if (_peers.count() == 1) + if (peerCount() == 1) emit connected(); updateSecureState(); @@ -307,10 +309,10 @@ bool SignalProxy::addPeer(Peer *peer) void SignalProxy::removeAllPeers() { - Q_ASSERT(proxyMode() == Server || _peers.count() <= 1); + Q_ASSERT(proxyMode() == Server || peerCount() <= 1); // wee need to copy that list since we modify it in the loop - QSet peers = _peers; - foreach(Peer *peer, peers) { + QList peers = _peerMap.values(); + for (auto peer : peers) { removePeer(peer); } } @@ -323,12 +325,12 @@ void SignalProxy::removePeer(Peer *peer) return; } - if (_peers.isEmpty()) { + if (_peerMap.isEmpty()) { qWarning() << "SignalProxy::removePeer(): No peers in use!"; return; } - if (!_peers.contains(peer)) { + if (!_peerMap.values().contains(peer)) { qWarning() << "SignalProxy: unknown Peer" << peer; return; } @@ -336,8 +338,7 @@ void SignalProxy::removePeer(Peer *peer) disconnect(peer, 0, this, 0); peer->setSignalProxy(0); - _peerMap.remove(peer->_id); - _peers.remove(peer); + _peerMap.remove(peer->id()); emit peerRemoved(peer); if (peer->parent() == this) @@ -345,7 +346,7 @@ void SignalProxy::removePeer(Peer *peer) updateSecureState(); - if (_peers.isEmpty()) + if (_peerMap.isEmpty()) emit disconnected(); } @@ -512,7 +513,7 @@ void SignalProxy::stopSynchronize(SyncableObject *obj) template void SignalProxy::dispatch(const T &protoMessage) { - foreach (Peer *peer, _peers) { + for (auto peer : _peerMap.values()) { if (peer->isOpen()) peer->dispatch(protoMessage); else @@ -667,12 +668,8 @@ bool SignalProxy::invokeSlot(QObject *receiver, int methodId, const QVariantList qWarning() << "SignalProxy::invokeSlot(): incompatible param types to invoke" << eMeta->methodName(methodId); return false; } - // if first arg is a PeerPtr, replace it by the address of the peer originally receiving the RpcCall - if (peer && i == 0 && args[0] == qMetaTypeId()) { - QVariant v = QVariant::fromValue(peer); - _a[1] = const_cast(v.constData()); - } else - _a[i+1] = const_cast(params[i].constData()); + + _a[i+1] = const_cast(params[i].constData()); } if (returnValue.type() != QVariant::Invalid) @@ -683,9 +680,11 @@ bool SignalProxy::invokeSlot(QObject *receiver, int methodId, const QVariantList : Qt::QueuedConnection; if (type == Qt::DirectConnection) { - return receiver->qt_metacall(QMetaObject::InvokeMetaMethod, methodId, _a) < 0; - } - else { + _sourcePeer = peer; + auto result = receiver->qt_metacall(QMetaObject::InvokeMetaMethod, methodId, _a) < 0; + _sourcePeer = nullptr; + return result; + } else { qWarning() << "Queued Connections are not implemented yet"; // note to self: qmetaobject.cpp:990 ff return false; @@ -764,9 +763,11 @@ void SignalProxy::sync_call__(const SyncableObject *obj, SignalProxy::ProxyMode params << QVariant(argTypes[i], va_arg(ap, void *)); } - if (argTypes.size() >= 1 && argTypes[0] == qMetaTypeId() && proxyMode() == SignalProxy::Server) { - Peer *peer = params[0].value(); - dispatch(peer, SyncMessage(eMeta->metaObject()->className(), obj->objectName(), QByteArray(funcname), params)); + if (_restrictMessageTarget) { + for (auto peer : _restrictedTargets) { + if (peer != nullptr) + dispatch(peer, SyncMessage(eMeta->metaObject()->className(), obj->objectName(), QByteArray(funcname), params)); + } } else dispatch(SyncMessage(eMeta->metaObject()->className(), obj->objectName(), QByteArray(funcname), params)); } @@ -807,8 +808,8 @@ void SignalProxy::updateSecureState() { bool wasSecure = _secure; - _secure = !_peers.isEmpty(); - foreach (const Peer *peer, _peers) { + _secure = !_peerMap.isEmpty(); + for (auto peer : _peerMap.values()) { _secure &= peer->isSecure(); } @@ -818,12 +819,15 @@ void SignalProxy::updateSecureState() QVariantList SignalProxy::peerData() { QVariantList result; - for (auto peer : _peers) { + for (auto peer : _peerMap.values()) { QVariantMap data; - data["id"] = peer->_id; - data["buildData"] = peer->_buildDate; - data["clientVersion"] = peer->_clientVersion; - data["description"] = peer->description(); + data["id"] = peer->id(); + data["clientVersion"] = peer->clientVersion(); + // We explicitly rename this, as, due to the Debian reproducability changes, buildDate isn’t actually the build + // date anymore, but on newer clients the date of the last git commit + data["clientVersionDate"] = peer->buildDate(); + data["remoteAddress"] = peer->address(); + data["connectedSince"] = peer->connectedSince(); data["secure"] = peer->isSecure(); result << data; } @@ -834,6 +838,18 @@ Peer *SignalProxy::peerById(int peerId) { return _peerMap[peerId]; } +void SignalProxy::restrictTargetPeers(QSet peers, std::function closure) +{ + auto previousRestrictMessageTarget = _restrictMessageTarget; + auto previousRestrictedTargets = _restrictedTargets; + _restrictMessageTarget = true; + _restrictedTargets = peers; + + closure(); + + _restrictMessageTarget = previousRestrictMessageTarget; + _restrictedTargets = previousRestrictedTargets; +} // ================================================== // ExtendedMetaObject