微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

OpenVPN v3 Dbus 客户端未收到所有信号

如何解决OpenVPN v3 Dbus 客户端未收到所有信号

我正在为 Linux Mint/Cinnamon 编写一个 Applet 来管理 OpenVPN v3 连接。

为了避免可能导致 DE 卡顿或冻结的同步调用,我正在使用 GJS 提供的 GioGLib 库编写一个简单的 DBus 客户端。这允许异步的、部分事件驱动的方法,并且应该避免任何令人讨厌的副作用。这是我第一次使用这些技术中的任何一种,但 OpenVPN DBus API 是 pretty well documentedGio 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 就是这种情况。

来源:DBus Specification (Message Routing)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。