Skip to content

Commit baaae9b

Browse files
committed
Feature: Add membership notifications on interface
1 parent 2d6846f commit baaae9b

File tree

3 files changed

+75
-3
lines changed

3 files changed

+75
-3
lines changed

README.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,37 @@ class MulticastGroupNotifier:
4848
def notify_membership(self, has_members):
4949
print(has_members)
5050

51-
notifier = MulticastGroupNotifier()
52-
multicast_group_obj.add_multicast_routing_entry(notifier)
51+
group_notifier = MulticastGroupNotifier()
52+
multicast_group_obj.add_multicast_routing_entry(group_notifier)
5353

5454
# when there is a change of multicast interest (for example group ff05::10:11:12
5555
# gets interested receivers), the object associated to this object is notified
5656
# through "notify_membership" method with has_members=True
5757

5858
# if you no longer want to monitor the interest of ff05::10:11:12, remove the
5959
# notifier from the group
60-
multicast_group_obj.remove_multicast_routing_entry(notifier)
60+
multicast_group_obj.remove_multicast_routing_entry(group_notifier)
61+
62+
# get notified of interest informations on this interface
63+
class MulticastRouterNotifier:
64+
def notify_done(self, packet):
65+
print('%s joined group %s' % (packet.ip_header.ip_src, packet.ip_header.ip_dst))
66+
67+
def notify_report(self, packet):
68+
print('%s leaved group %s' % (packet.ip_header.ip_src, packet.ip_header.ip_dst))
69+
70+
def notify_removal(self):
71+
print('the interface is no longer managed')
72+
73+
def notify_timeout(self, group_ip):
74+
print('membership timeout for group ' + group_ip)
75+
76+
router_notifier = MulticastRouterNotifier()
77+
intf.interface_state.add_to_notify_entry(router_notifier)
78+
79+
# if you no longer want to monitor the interest this interface, remove the
80+
# notifier from it
81+
intf.interface_state.remove_to_notify_entry(router_notifier)
6182

6283
intf.remove() # stop receiving MLD packets
6384
```

mld/mld1/GroupState.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ def group_membership_timeout(self):
103103
"""
104104
with self.lock:
105105
self.get_interface_group_state().group_membership_timeout(self)
106+
self.router_state.notify_timeout(self.group_ip)
106107

107108
def retransmit_timeout(self):
108109
"""

mld/mld1/RouterState.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from threading import Lock
23
from threading import Timer
34

45
from mld.utils import TYPE_CHECKING
@@ -36,6 +37,10 @@ def __init__(self, interface: 'InterfaceMLD'):
3637
self.group_state = {}
3738
self.group_state_lock = RWLockWrite()
3839

40+
# instances to notify membership timeout and report or done packet reception
41+
self.to_notify_list = []
42+
self.to_notify_list_lock = Lock()
43+
3944
# send general query
4045
packet = PacketMLDHeader(type=mld_globals.MULTICAST_LISTENER_QUERY_TYPE,
4146
max_resp_delay=mld_globals.QUERY_RESPONSE_INTERVAL * 1000)
@@ -139,13 +144,15 @@ def receive_report(self, packet: ReceivedPacket):
139144
"""
140145
mld_group = packet.payload.group_address
141146
self.get_group_state(mld_group).receive_report()
147+
self.notify_report(packet)
142148

143149
def receive_done(self, packet: ReceivedPacket):
144150
"""
145151
Received MLD Done packet
146152
"""
147153
mld_group = packet.payload.group_address
148154
self.get_group_state(mld_group).receive_done()
155+
self.notify_done(packet)
149156

150157
def receive_query(self, packet: ReceivedPacket):
151158
"""
@@ -163,8 +170,51 @@ def remove(self):
163170
"""
164171
Remove this MLD interface
165172
Clear all state
173+
Notify all interested entries that this interface is no longer managed
166174
"""
167175
for group in self.group_state.values():
168176
group.remove()
169177
self.clear_general_query_timer()
170178
self.clear_other_querier_present_timer()
179+
for to_notify in self.to_notify_list:
180+
to_notify.notify_removal()
181+
del self.to_notify_list[:]
182+
183+
###########################################
184+
# Notify Membership packets and Membership timeouts
185+
###########################################
186+
def notify_done(self, packet: ReceivedPacket):
187+
"""
188+
Notify all entries interested in this router
189+
"""
190+
for to_notify in self.to_notify_list:
191+
to_notify.notify_done(packet=packet)
192+
193+
def notify_report(self, packet: ReceivedPacket):
194+
"""
195+
Notify all entries interested in this router
196+
"""
197+
for to_notify in self.to_notify_list:
198+
to_notify.notify_report(packet=packet)
199+
200+
def notify_timeout(self, group_ip):
201+
"""
202+
Notify all entries interested in this router
203+
"""
204+
for to_notify in self.to_notify_list:
205+
to_notify.notify_timeout(group_ip)
206+
207+
def add_to_notify_entry(self, to_notify_entry):
208+
"""
209+
A new entry monitoring membership informations
210+
"""
211+
with self.to_notify_list_lock:
212+
self.to_notify_list.append(to_notify_entry)
213+
214+
def remove_to_notify_entry(self, to_notify_entry):
215+
"""
216+
A entry is no longer monitoring membership informations
217+
Remove this entry from this object
218+
"""
219+
with self.to_notify_list_lock:
220+
self.to_notify_list.remove(to_notify_entry)

0 commit comments

Comments
 (0)