如何解决OpenVPN v3 Dbus 客户端未收到所有信号
我正在为 Linux Mint/Cinnamon 编写一个 Applet 来管理 OpenVPN v3 连接。
为了避免可能导致 DE 卡顿或冻结的同步调用,我正在使用 GJS 提供的 Gio
和 GLib
库编写一个简单的 DBus 客户端。这允许异步的、部分事件驱动的方法,并且应该避免任何令人讨厌的副作用。这是我第一次使用这些技术中的任何一种,但 OpenVPN DBus API 是 pretty well documented,Gio and GLib 的 API 文档也很好。
我遇到的问题是信号订阅,特别是 StatusChange
服务发布的 net.openvpn.v3.sessions
信号。每当建立、暂停、恢复或关闭连接时,就会发布一堆这些信号。大多数信号都被我订阅的听众接收到,但不是全部。特别是,我没有收到 session closed
信号。
使用 dbus-monitor
命令行工具,您可以看到在建立连接(7 个信号)然后关闭(2 个信号)时发布的所有 StatusChange
信号:
$ sudo dbus-monitor --system "type='signal',interface='net.openvpn.v3.sessions',member='StatusChange'"
...
// Connect:
signal time=1625847543.107244 sender=:1.891 -> destination=:1.892 serial=2745 path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.openvpn.v3.sessions; member=StatusChange
uint32 3
uint32 27
string "session_path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49,backend_pid=42584"
signal time=1625847543.116395 sender=:1.891 -> destination=:1.892 serial=2762 path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.openvpn.v3.sessions; member=StatusChange
uint32 3
uint32 17
string "session_path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49 backend_busname=net.openvpn.v3.backends.be42585 backend_path=/net/openvpn/v3/backends/session"
signal time=1625847543.117286 sender=:1.891 -> destination=(null destination) serial=2764 path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.openvpn.v3.sessions; member=StatusChange
uint32 2
uint32 2
string "config_path=/net/openvpn/v3/configuration/9dd3fa9cxb6e0x48acxaa1ex566312bea232"
signal time=1625847543.638519 sender=:1.891 -> destination=(null destination) serial=2775 path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.openvpn.v3.sessions; member=StatusChange
uint32 2
uint32 2
string "config_path=/net/openvpn/v3/configuration/9dd3fa9cxb6e0x48acxaa1ex566312bea232"
signal time=1625847543.638533 sender=:1.891 -> destination=(null destination) serial=2776 path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.openvpn.v3.sessions; member=StatusChange
uint32 2
uint32 6
string ""
signal time=1625847543.735357 sender=:1.891 -> destination=(null destination) serial=2777 path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.openvpn.v3.sessions; member=StatusChange
uint32 2
uint32 6
string ""
signal time=1625847543.974784 sender=:1.891 -> destination=(null destination) serial=2778 path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.openvpn.v3.sessions; member=StatusChange
uint32 2
uint32 7
string ""
// disconnect:
signal time=1625847646.846790 sender=:1.891 -> destination=:1.892 serial=2834 path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.openvpn.v3.sessions; member=StatusChange
uint32 3
uint32 28
string "Session closed"
signal time=1625847646.848262 sender=:1.891 -> destination=:1.892 serial=2839 path=/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.openvpn.v3.sessions; member=StatusChange
uint32 3
uint32 19
string ""
以下代码创建了一个订阅,据我所知,它应该接收到与上面相同的信号。注意我在这里使用较低级别的方法来获取订阅;订阅是在全局连接上进行的,而不是通过特定对象路径的 DBusProxy
。我已经尝试了两种方法(相同的结果),但以下应该更接近于上面的 dbus-monitor
命令。
subscribetoStatusChangeSignals() {
this.statusChangeHandlerId = Gio.DBus.system.signal_subscribe(
'net.openvpn.v3.sessions','net.openvpn.v3.sessions','StatusChange',null,Gio.DBusSignalFlags.NONE,this._handleGlobalStatusChangeSignal
);
}
_handleGlobalStatusChangeSignal(connection,sender,path,iface,signal,params) {
let container = params.deep_unpack();
let statusMajorCode = container[0];
let statusMinorCode = container[1];
let statusMajor = lookupStatusMajor(statusMajorCode); // lookup the corresponding text
let statusMinor = lookupStatusMinor(statusMinorCode); // from something resembling an enum
let message = container[2];
global.log(`Received StatusChange signal
path: [${path}]
Status Major: [${statusMajorCode} - ${statusMajor}]
Status Minor: [${statusMinorCode} - ${statusMinor}]
Message: [${message}]`
);
}
打开和关闭与以前相同的连接时产生的日志:
// Connect:
Cjs-Message: 18:19:03.117: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [2 - CFG_OK]
Message: [config_path=/net/openvpn/v3/configuration/9dd3fa9cxb6e0x48acxaa1ex566312bea232]
Cjs-Message: 18:19:03.638: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [2 - CFG_OK]
Message: [config_path=/net/openvpn/v3/configuration/9dd3fa9cxb6e0x48acxaa1ex566312bea232]
Cjs-Message: 18:19:03.639: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [6 - CONN_CONNECTING]
Message: []
Cjs-Message: 18:19:03.735: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [6 - CONN_CONNECTING]
Message: []
Cjs-Message: 18:19:03.974: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/openvpn/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [7 - CONN_CONNECTED]
Message: []
// disconnect:
<nada>
我注意到的一种模式是,我收到的所有信号在 null destination
输出中都有一个 dbus-monitor
:
... sender=:1.891 -> destination=(null destination) ...
虽然我没有收到的信号有一个特定的目的地:
... sender=:1.891 -> destination=:1.892 ...
据推测,这些是针对特定接收者的直接信号,而不是向所有感兴趣的订阅者广播的信号,但我没有在文档中的任何地方找到对此的解释。
那么问题是,为什么我会收到一些信号而不是全部?这是设计使然,还是 Gio
的问题,或者(更有可能)我使用它的方式的问题?
解决方法
经过深入研究后,似乎这种行为是设计使然 - 携带目标值的信号被视为单播消息。预定收件人以外的订阅者只有在配置为 eavesdrop
时才会收到此类消息。大概 dbus-monitor
就是这种情况。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。