4
4
#
5
5
# Copyright (C) 2018 - 2023 OpenVPN Inc <sales@openvpn.net>
6
6
# Copyright (C) 2018 - 2023 David Sommerseth <davids@openvpn.net>
7
+ # Copyright (C) 2023 Jeremy Fleischman <jeremyfleischman@gmail.com>
7
8
#
8
9
9
10
##
@@ -114,6 +115,7 @@ def __init__(self, dbuscon, objpath):
114
115
self .__log_callback = None
115
116
self .__status_callback = None
116
117
self .__deleted = False
118
+ self .__log_forward_enabled = False
117
119
118
120
119
121
def __del__ (self ):
@@ -284,23 +286,33 @@ def GetFormattedStatistics(self, prefix='Connection statistics:\n', format_str='
284
286
#
285
287
#
286
288
def LogCallback (self , cbfnc ):
289
+ if cbfnc is not None and self .__log_callback is not None :
290
+ # In this case, the program must first disable the
291
+ # current LogCallback() before setting a new one.
292
+ raise RuntimeError ('LogCallback() is already enabled' )
293
+
294
+ if cbfnc is None and self .__log_callback is None :
295
+ # This is fine: disabling a callback when there is no
296
+ # callback is a simple no-op.
297
+ return
298
+
287
299
if cbfnc is not None :
300
+ # Subscribe to Log signals, which will be processed
301
+ # by the callback function
288
302
self .__log_callback = cbfnc
289
303
self .__dbuscon .add_signal_receiver (cbfnc ,
290
304
signal_name = 'Log' ,
291
305
dbus_interface = 'net.openvpn.v3.backends' ,
292
306
bus_name = 'net.openvpn.v3.log' ,
293
307
path = self .__session_path )
294
- self .__session_intf .LogForward (True )
295
308
else :
296
- try :
297
- self .__session_intf .LogForward (False )
298
- except dbus .exceptions .DBusException :
299
- # If this fails, the session is typically already removed
300
- pass
301
- self .__dbuscon .remove_signal_receiver (self .__log_callback , 'Log' )
302
- self .__log_callback = None
309
+ # Only remove the callback if there actually *is* a callback
310
+ # currently.
311
+ if self .__log_callback is not None :
312
+ self .__dbuscon .remove_signal_receiver (self .__log_callback , 'Log' )
313
+ self .__log_callback = None
303
314
315
+ self .__set_log_forward ()
304
316
305
317
##
306
318
# Subscribes to the StatusChange signals for this session and register
@@ -310,18 +322,34 @@ def LogCallback(self, cbfnc):
310
322
# (integer) StatusMajor, (integer) StatusMinor, (string) message
311
323
#
312
324
def StatusChangeCallback (self , cbfnc ):
325
+ if cbfnc is not None and self .__status_callback is not None :
326
+ # In this case, the program must first disable the
327
+ # current StatusChangeCallback() before setting a new one.
328
+ raise RuntimeError ('StatusChangeCallback() is already enabled' )
329
+
330
+ if cbfnc is None and self .__status_callback is None :
331
+ # This is fine: disabling a callback when there is no
332
+ # callback is a simple no-op.
333
+ return
334
+
313
335
if cbfnc is not None :
336
+ # Subscribe to StatusChange signals, which will be processed
337
+ # by the callback function
314
338
self .__status_callback = cbfnc
315
339
self .__dbuscon .add_signal_receiver (cbfnc ,
316
340
signal_name = 'StatusChange' ,
317
341
dbus_interface = 'net.openvpn.v3.backends' ,
318
342
bus_name = 'net.openvpn.v3.log' ,
319
343
path = self .__session_path )
320
344
else :
321
- self .__dbuscon .remove_signal_receiver (self .__status_callback ,
322
- 'StatusChange' )
323
- self .__status_callback = None
345
+ # Only remove the callback if there actually *is* a callback
346
+ # currently.
347
+ if self .__status_callback is not None :
348
+ self .__dbuscon .remove_signal_receiver (self .__status_callback ,
349
+ 'StatusChange' )
350
+ self .__status_callback = None
324
351
352
+ self .__set_log_forward ()
325
353
326
354
327
355
##
@@ -417,6 +445,30 @@ def GetDCO(self):
417
445
def SetDCO (self , dco ):
418
446
self .__prop_intf .Set ('net.openvpn.v3.sessions' , 'dco' , dco )
419
447
448
+ ##
449
+ # Internal method to enable/disable LogForward as needed.
450
+ # Must be called whenever a callback that needs LogForward enabled is
451
+ # added or removed.
452
+ #
453
+ def __set_log_forward (self ):
454
+ # The LogCallback and the StatusChangeCallback both need LogForward
455
+ # enabled. In other words, LogForward should be enabled if one or both
456
+ # of those callbacks are registered.
457
+ should_log_forward_be_enabled = (
458
+ self .__log_callback is not None or self .__status_callback is not None
459
+ )
460
+
461
+ if should_log_forward_be_enabled and not self .__log_forward_enabled :
462
+ self .__session_intf .LogForward (True )
463
+ self .__log_forward_enabled = True
464
+ elif not should_log_forward_be_enabled and self .__log_forward_enabled :
465
+ try :
466
+ self .__session_intf .LogForward (False )
467
+ except dbus .exceptions .DBusException :
468
+ # If this fails, the session is typically already removed
469
+ pass
470
+
471
+ self .__log_forward_enabled = False
420
472
421
473
422
474
##
0 commit comments