Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pim_dm
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
pim_dm
Commits
b5bd0d28
Commit
b5bd0d28
authored
Nov 06, 2017
by
Pedro Oliveira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
assert, unicast routing update... not tested (just for backup)
parent
215be907
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1039 additions
and
553 deletions
+1039
-553
CustomTimer/RemainingTimer.py
CustomTimer/RemainingTimer.py
+28
-0
CustomTimer/__init__.py
CustomTimer/__init__.py
+0
-0
Interface.py
Interface.py
+1
-0
InterfacePIM.py
InterfacePIM.py
+4
-1
Kernel.py
Kernel.py
+11
-1
Main.py
Main.py
+8
-3
Neighbor.py
Neighbor.py
+24
-4
Packet/PacketPimAssert.py
Packet/PacketPimAssert.py
+6
-2
Packet/PacketPimHeader.py
Packet/PacketPimHeader.py
+2
-1
UnicastRouting.py
UnicastRouting.py
+208
-97
tree/KernelEntry.py
tree/KernelEntry.py
+71
-9
tree/assert_.py
tree/assert_.py
+189
-148
tree/downstream_prune.py
tree/downstream_prune.py
+17
-7
tree/globals.py
tree/globals.py
+4
-0
tree/local_membership.py
tree/local_membership.py
+25
-0
tree/metric.py
tree/metric.py
+50
-47
tree/tree_if_downstream.py
tree/tree_if_downstream.py
+27
-26
tree/tree_if_upstream.py
tree/tree_if_upstream.py
+14
-6
tree/tree_interface.py
tree/tree_interface.py
+179
-39
tree/upstream_prune.py
tree/upstream_prune.py
+171
-162
No files found.
CustomTimer/RemainingTimer.py
0 → 100644
View file @
b5bd0d28
from
time
import
time
try
:
from
threading
import
_Timer
as
Timer
except
ImportError
:
from
threading
import
Timer
class
RemainingTimer
(
Timer
):
def
__init__
(
self
,
interval
,
function
):
super
().
__init__
(
interval
,
function
)
self
.
start_time
=
time
()
def
time_remaining
(
self
):
delta_time
=
time
()
-
self
.
start_time
return
self
.
interval
-
delta_time
'''
def test():
print("ola")
x = RemainingTimer(10, test)
x.start()
from time import sleep
for i in range(0, 10):
print(x.time_remaining())
sleep(1)
'''
CustomTimer/__init__.py
0 → 100644
View file @
b5bd0d28
Interface.py
View file @
b5bd0d28
...
...
@@ -15,6 +15,7 @@ class Interface(object):
def
__init__
(
self
,
interface_name
:
str
):
self
.
interface_name
=
interface_name
ip_interface
=
netifaces
.
ifaddresses
(
interface_name
)[
netifaces
.
AF_INET
][
0
][
'addr'
]
self
.
ip_mask_interface
=
netifaces
.
ifaddresses
(
interface_name
)[
netifaces
.
AF_INET
][
0
][
'netmask'
]
self
.
ip_interface
=
ip_interface
s
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_RAW
,
socket
.
IPPROTO_PIM
)
...
...
InterfacePIM.py
View file @
b5bd0d28
...
...
@@ -125,7 +125,10 @@ class InterfacePim(Interface):
def
get_neighbor
(
self
,
ip
):
with
self
.
neighbors_lock
.
genRlock
():
return
self
.
neighbors
[
ip
]
if
ip
in
self
.
neighbors
:
return
self
.
neighbors
[
ip
]
else
:
return
None
def
remove_neighbor
(
self
,
ip
):
with
self
.
neighbors_lock
.
genWlock
():
...
...
Kernel.py
View file @
b5bd0d28
...
...
@@ -3,6 +3,9 @@ import struct
import
netifaces
import
threading
import
traceback
import
ipaddress
from
RWLock.RWLock
import
RWLockWrite
import
Main
...
...
@@ -364,8 +367,15 @@ class Kernel:
return
None
def
n
eighbor_removed
(
self
,
interface_name
,
neighbor_ip
):
def
n
otify_unicast_changes
(
self
,
subnet
):
# todo
with
self
.
rwlock
.
genWlock
():
for
(
source_ip
,
group
)
in
self
.
routing
.
keys
():
source_ip_obj
=
ipaddress
.
ip_address
(
source_ip
)
if
source_ip_obj
in
subnet
:
self
.
routing
[(
source_ip
,
group
)].
network_update
()
print
(
source_ip
)
pass
...
...
Main.py
View file @
b5bd0d28
...
...
@@ -173,7 +173,7 @@ def list_routing_state():
routing_entries
=
kernel
.
routing
.
values
()
vif_indexes
=
kernel
.
vif_index_to_name_dic
.
keys
()
t
=
PrettyTable
([
'SourceIP'
,
'GroupIP'
,
'Interface'
,
'PruneState'
,
'AssertState'
,
"Is Forwarding?"
])
t
=
PrettyTable
([
'SourceIP'
,
'GroupIP'
,
'Interface'
,
'PruneState'
,
'AssertState'
,
'LocalMembership'
,
"Is Forwarding?"
])
for
entry
in
routing_entries
:
ip
=
entry
.
source_ip
group
=
entry
.
group_ip
...
...
@@ -182,19 +182,21 @@ def list_routing_state():
for
index
in
vif_indexes
:
interface_state
=
entry
.
interface_state
[
index
]
interface_name
=
kernel
.
vif_index_to_name_dic
[
index
]
is_forwarding
=
interface_state
.
is_forwarding
()
local_membership
=
type
(
interface_state
.
_local_membership_state
).
__name__
try
:
if
index
!=
upstream_if_index
:
prune_state
=
type
(
interface_state
.
_prune_state
).
__name__
assert_state
=
type
(
interface_state
.
_assert_state
).
__name__
is_forwarding
=
interface_state
.
is_forwarding
()
else
:
prune_state
=
type
(
interface_state
.
_graft_prune_state
).
__name__
assert_state
=
"-"
is_forwarding
=
"upstream"
except
:
prune_state
=
"-"
assert_state
=
"-"
t
.
add_row
([
ip
,
group
,
interface_name
,
prune_state
,
assert_state
,
is_forwarding
])
t
.
add_row
([
ip
,
group
,
interface_name
,
prune_state
,
assert_state
,
local_membership
,
is_forwarding
])
return
str
(
t
)
...
...
@@ -222,3 +224,6 @@ def main():
global
igmp
igmp
=
IGMP
()
global
u
u
=
UnicastRouting
.
UnicastRouting
()
Neighbor.py
View file @
b5bd0d28
...
...
@@ -2,6 +2,7 @@ from threading import Timer
import
time
from
utils
import
HELLO_HOLD_TIME_NO_TIMEOUT
,
HELLO_HOLD_TIME_TIMEOUT
,
TYPE_CHECKING
from
threading
import
Lock
from
RWLock.RWLock
import
RWLockWrite
import
Main
if
TYPE_CHECKING
:
from
InterfacePIM
import
InterfacePim
...
...
@@ -24,6 +25,10 @@ class Neighbor:
self
.
time_of_last_update
=
time
.
time
()
self
.
neighbor_lock
=
Lock
()
self
.
tree_interface_nlt_subscribers
=
[]
self
.
tree_interface_nlt_subscribers_lock
=
RWLockWrite
()
# send hello to new neighbor
#self.contact_interface.send_hello()
# todo RANDOM DELAY??? => DO NOTHING... EVENTUALLY THE HELLO MESSAGE WILL BE SENT
...
...
@@ -71,11 +76,14 @@ class Neighbor:
del
self
.
contact_interface
.
neighbors
[
self
.
ip
]
# notify interfaces which have this neighbor as AssertWinner
with
self
.
tree_interface_nlt_subscribers_lock
.
genRlock
():
for
tree_if
in
self
.
tree_interface_nlt_subscribers
:
tree_if
.
assert_winner_nlt_expires
()
def
reset
(
self
):
interface_name
=
self
.
contact_interface
.
interface_name
neighbor_ip
=
self
.
ip
Main
.
kernel
.
neighbor_removed
(
interface_name
,
neighbor_ip
)
# todo new neighbor
return
def
receive_hello
(
self
,
generation_id
,
hello_hold_time
):
...
...
@@ -85,3 +93,15 @@ class Neighbor:
self
.
time_of_last_update
=
time
.
time
()
self
.
set_generation_id
(
generation_id
)
self
.
set_hello_hold_time
(
hello_hold_time
)
def
subscribe_nlt_expiration
(
self
,
tree_if
):
with
self
.
tree_interface_nlt_subscribers_lock
.
genWlock
():
if
tree_if
not
in
self
.
tree_interface_nlt_subscribers
:
self
.
tree_interface_nlt_subscribers
.
append
(
tree_if
)
def
unsubscribe_nlt_expiration
(
self
,
tree_if
):
with
self
.
tree_interface_nlt_subscribers_lock
.
genWlock
():
if
tree_if
in
self
.
tree_interface_nlt_subscribers
:
self
.
tree_interface_nlt_subscribers
.
remove
(
tree_if
)
Packet/PacketPimAssert.py
View file @
b5bd0d28
...
...
@@ -2,6 +2,7 @@ import struct
import
socket
from
Packet.PacketPimEncodedGroupAddress
import
PacketPimEncodedGroupAddress
from
Packet.PacketPimEncodedUnicastAddress
import
PacketPimEncodedUnicastAddress
from
tree.globals
import
ASSERT_CANCEL_METRIC
'''
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
...
...
@@ -29,12 +30,15 @@ class PacketPimAssert:
PIM_HDR_ASSERT_v4_LEN
=
struct
.
calcsize
(
PIM_HDR_ASSERT_v4
)
PIM_HDR_ASSERT_v6_LEN
=
struct
.
calcsize
(
PIM_HDR_ASSERT_v6
)
def
__init__
(
self
,
multicast_group_address
:
str
or
bytes
,
source_address
:
str
or
bytes
,
metric_preference
,
metric
):
def
__init__
(
self
,
multicast_group_address
:
str
or
bytes
,
source_address
:
str
or
bytes
,
metric_preference
:
int
,
metric
:
int
or
float
):
if
type
(
multicast_group_address
)
is
bytes
:
multicast_group_address
=
socket
.
inet_ntoa
(
multicast_group_address
)
if
type
(
source_address
)
is
bytes
:
source_address
=
socket
.
inet_ntoa
(
source_address
)
if
metric_preference
>
ASSERT_CANCEL_METRIC
:
metric_preference
=
ASSERT_CANCEL_METRIC
if
metric
>
ASSERT_CANCEL_METRIC
:
metric
=
ASSERT_CANCEL_METRIC
self
.
multicast_group_address
=
multicast_group_address
self
.
source_address
=
source_address
self
.
metric_preference
=
metric_preference
...
...
Packet/PacketPimHeader.py
View file @
b5bd0d28
...
...
@@ -65,9 +65,10 @@ class PacketPimHeader(PacketPayload):
raise
Exception
msg_to_checksum
=
data
[
0
:
2
]
+
b'
\
x00
\
x00
'
+
data
[
4
:]
print
(
"checksum calculated: "
+
str
(
checksum
(
msg_to_checksum
)))
if
checksum
(
msg_to_checksum
)
!=
rcv_checksum
:
print
(
"wrong checksum"
)
print
(
"checksum calculated: "
+
str
(
checksum
(
msg_to_checksum
)))
print
(
"checksum recv: "
+
str
(
rcv_checksum
))
raise
Exception
pim_payload
=
data
[
PacketPimHeader
.
PIM_HDR_LEN
:]
...
...
UnicastRouting.py
View file @
b5bd0d28
from
queue
import
Queue
from
threading
import
Thread
from
pyroute2
import
IPDB
,
IPRoute
import
socket
import
RWLock
import
Main
import
ipaddress
#ipdb = IPDB()
ipr
=
IPRoute
()
def
get_route
(
ip_dst
:
str
):
with
IPDB
()
as
ipdb
:
return
UnicastRouting
.
get_route
(
ip_dst
)
def
get_metric
(
ip_dst
:
str
):
return
UnicastRouting
.
get_metric
(
ip_dst
)
def
check_rpf
(
ip_dst
):
return
UnicastRouting
.
check_rpf
(
ip_dst
)
class
UnicastRouting
(
object
):
ipr
=
None
ipdb
=
None
def
__init__
(
self
):
self
.
event_queue
=
Queue
(
maxsize
=
0
)
UnicastRouting
.
ipr
=
IPRoute
()
UnicastRouting
.
ipdb
=
IPDB
()
self
.
_ipdb
=
UnicastRouting
.
ipdb
self
.
_ipdb
.
register_callback
(
UnicastRouting
.
unicast_changes
)
#self.working = True
#self.worker_thread = Thread(target=self.worker)
#self.worker_thread.daemon = True
#self.worker_thread.start()
@
staticmethod
def
get_route
(
ip_dst
:
str
):
ipdb
=
UnicastRouting
.
ipdb
ip_bytes
=
socket
.
inet_aton
(
ip_dst
)
ip_int
=
int
.
from_bytes
(
ip_bytes
,
byteorder
=
'big'
)
info
=
None
...
...
@@ -25,97 +59,174 @@ def get_route(ip_dst: str):
return
info
# get metrics (routing preference and cost) to IP ip_dst
def
get_metric
(
ip_dst
:
str
):
unicast_routing_entry
=
get_route
(
ip_dst
)
entry_protocol
=
unicast_routing_entry
[
"proto"
]
entry_cost
=
unicast_routing_entry
[
"priority"
]
return
(
entry_protocol
,
entry_cost
)
"""
def get_rpf(ip_dst: str):
unicast_routing_entry = get_route(ip_dst)
#interface_oif = unicast_routing_entry['oif']
if not unicast_routing_entry['multipath']:
interface_oif = unicast_routing_entry['oif']
else:
multiple_entries = unicast_routing_entry['multipath']
print(multiple_entries)
(entry0, _) = multiple_entries
print(entry0)
interface_oif = entry0['oif']
print("ola")
print(ipdb.interfaces[interface_oif]['ipaddr'])
for i in range(len(ipdb.interfaces[interface_oif]['ipaddr'])):
print("ola2")
interface = ipdb.interfaces[interface_oif]['ipaddr'][i]
print(interface)
if interface['family'] == socket.AF_INET:
return interface['address']
return None
"""
# get output interface IP, used to send data to IP ip_dst
# (root interface IP to ip_dst)
def
check_rpf
(
ip_dst
):
# obter index da interface
# rpf_interface_index = ipr.get_routes(family=socket.AF_INET, dst=ip)[0]['attrs'][2][1]
# interface_name = if_indextoname(rpf_interface_index)
# return interface_name
# obter ip da interface de saida
rpf_interface_source
=
ipr
.
get_routes
(
family
=
socket
.
AF_INET
,
dst
=
ip_dst
)[
0
][
'attrs'
][
3
][
1
]
return
rpf_interface_source
"""
def get_metric(ip_dst: str):
ip_bytes = socket.inet_aton(ip_dst)
ip_int = int.from_bytes(ip_bytes, byteorder='big')
info = None
for mask_len in range(32, 0, -1):
ip_bytes = (ip_int & (0xFFFFFFFF << (32 - mask_len))).to_bytes(4, "big")
ip_dst = socket.inet_ntoa(ip_bytes) + "/" + str(mask_len)
print(ip_dst)
try:
info = ipdb.routes[ip_dst]
break
except:
continue
if not info:
print("0.0.0.0/0")
info = ipdb.routes["default"]
print(info)
print("metric=", info["priority"])
print("proto=", info["proto"])
#print(info.keys())
#if info["gateway"]:
# print("next_hop=", info["gateway"])
#elif info["prefsrc"]:
# print("next_hop=", info["prefsrc"])
return (info["proto"], info["priority"])
def check_rpf(ip_dst: str):
from pyroute2 import IPRoute
# from utils import if_indextoname
ipr = IPRoute()
# obter index da interface
# rpf_interface_index = ipr.get_routes(family=socket.AF_INET, dst=ip)[0]['attrs'][2][1]
# interface_name = if_indextoname(rpf_interface_index)
# return interface_name
# obter ip da interface de saida
rpf_interface_source = ipr.get_routes(family=socket.AF_INET, dst=ip_dst)[0]['attrs'][3][1]
return rpf_interface_source
"""
def
stop
():
ipr
.
close
()
#ip = input("ip=")
#get_metric(ip)
\ No newline at end of file
# get metrics (routing preference and cost) to IP ip_dst
@
staticmethod
def
get_metric
(
ip_dst
:
str
):
unicast_routing_entry
=
UnicastRouting
.
get_route
(
ip_dst
)
entry_protocol
=
unicast_routing_entry
[
"proto"
]
entry_cost
=
unicast_routing_entry
[
"priority"
]
return
(
entry_protocol
,
entry_cost
)
"""
def get_rpf(ip_dst: str):
unicast_routing_entry = get_route(ip_dst)
#interface_oif = unicast_routing_entry['oif']
if not unicast_routing_entry['multipath']:
interface_oif = unicast_routing_entry['oif']
else:
multiple_entries = unicast_routing_entry['multipath']
print(multiple_entries)
(entry0, _) = multiple_entries
print(entry0)
interface_oif = entry0['oif']
print("ola")
print(ipdb.interfaces[interface_oif]['ipaddr'])
for i in range(len(ipdb.interfaces[interface_oif]['ipaddr'])):
print("ola2")
interface = ipdb.interfaces[interface_oif]['ipaddr'][i]
print(interface)
if interface['family'] == socket.AF_INET:
return interface['address']
return None
"""
# get output interface IP, used to send data to IP ip_dst
# (root interface IP to ip_dst)
@
staticmethod
def
check_rpf
(
ip_dst
):
# obter index da interface
# rpf_interface_index = ipr.get_routes(family=socket.AF_INET, dst=ip)[0]['attrs'][2][1]
# interface_name = if_indextoname(rpf_interface_index)
# return interface_name
# obter ip da interface de saida
rpf_interface_source
=
UnicastRouting
.
ipr
.
get_routes
(
family
=
socket
.
AF_INET
,
dst
=
ip_dst
)[
0
][
'attrs'
][
3
][
1
]
return
rpf_interface_source
@
staticmethod
def
unicast_changes
(
ipdb
,
msg
,
action
):
#unicast_event = QueueItem(ipdb, msg, action)
#self.event_queue.put(unicast_event)
print
(
"unicast change?"
)
print
(
action
)
UnicastRouting
.
ipdb
=
ipdb
if
action
==
"RTM_NEWROUTE"
or
action
==
"RTM_DELROUTE"
:
print
(
ipdb
.
routes
)
mask_len
=
msg
[
"dst_len"
]
network_address
=
None
attrs
=
msg
[
"attrs"
]
print
(
attrs
)
for
(
key
,
value
)
in
attrs
:
print
((
key
,
value
))
if
key
==
"RTA_DST"
:
network_address
=
value
break
if
network_address
is
None
:
network_address
=
"0.0.0.0"
print
(
network_address
)
print
(
mask_len
)
print
(
network_address
+
"/"
+
str
(
mask_len
))
subnet
=
ipaddress
.
ip_network
(
network_address
+
"/"
+
str
(
mask_len
))
print
(
str
(
subnet
))
#Main.kernel.notify_unicast_changes(subnet)
elif
action
==
"RTM_NEWADDR"
or
action
==
"RTM_DELADDR"
:
print
(
"a"
)
'''
def worker(self):
global ipdb
while self.working:
item = self.event_queue.get()
ipdb = item.ipdb
if item.action == "RTM_NEWROUTE" or item.action == "RTM_DELROUTE":
mask_len = item.action["dst_len"]
network_address = None
attrs = item.action["attrs"]
for (key, value) in attrs:
if key == "RTA_DST":
network_address = value
break
subnet = ipaddress.ip_network(network_address + "/" + mask_len)
Main.kernel.notify_kernel_about_unicast_change(subnet)
elif item.action == "RTM_NEWADDR" or item.action == "RTM_DELADDR":
print("a")
'''
#print(ipdb)
#print(msg)
#print(action)
"""
def get_metric(ip_dst: str):
ip_bytes = socket.inet_aton(ip_dst)
ip_int = int.from_bytes(ip_bytes, byteorder='big')
info = None
for mask_len in range(32, 0, -1):
ip_bytes = (ip_int & (0xFFFFFFFF << (32 - mask_len))).to_bytes(4, "big")
ip_dst = socket.inet_ntoa(ip_bytes) + "/" + str(mask_len)
print(ip_dst)
try:
info = ipdb.routes[ip_dst]
break
except:
continue
if not info:
print("0.0.0.0/0")
info = ipdb.routes["default"]
print(info)
print("metric=", info["priority"])
print("proto=", info["proto"])
#print(info.keys())
#if info["gateway"]:
# print("next_hop=", info["gateway"])
#elif info["prefsrc"]:
# print("next_hop=", info["prefsrc"])
return (info["proto"], info["priority"])
def check_rpf(ip_dst: str):
from pyroute2 import IPRoute
# from utils import if_indextoname
ipr = IPRoute()
# obter index da interface
# rpf_interface_index = ipr.get_routes(family=socket.AF_INET, dst=ip)[0]['attrs'][2][1]
# interface_name = if_indextoname(rpf_interface_index)
# return interface_name
# obter ip da interface de saida
rpf_interface_source = ipr.get_routes(family=socket.AF_INET, dst=ip_dst)[0]['attrs'][3][1]
return rpf_interface_source
"""
def
stop
(
self
):
#self.working = False
if
UnicastRouting
.
ipr
:
UnicastRouting
.
ipr
.
close
()
if
UnicastRouting
.
ipdb
:
UnicastRouting
.
ipdb
=
None
if
self
.
_ipdb
:
self
.
_ipdb
.
release
()
#ip = input("ip=")
#get_metric(ip)
'''
class QueueItem(object):
def __init__(self, ipdb, msg, action):
self.ipdb = ipdb
self.msg = msg
self.action = action
'''
tree/KernelEntry.py
View file @
b5bd0d28
...
...
@@ -6,6 +6,7 @@ from tree.tree_if_upstream import TreeInterfaceUpstream
from
tree.tree_if_downstream
import
TreeInterfaceDownstream
from
.tree_interface
import
TreeInterface
from
threading
import
Timer
,
Lock
,
RLock
from
tree.metric
import
AssertMetric
import
UnicastRouting
class
KernelEntry
:
...
...
@@ -17,7 +18,25 @@ class KernelEntry:
self
.
group_ip
=
group_ip
# ip of neighbor of the rpf
self
.
_rpf_node
=
None
#next_hop = UnicastRouting.get_route(source_ip)["gateway"]
#self.rpf_node = source_ip if next_hop is None else next_hop
next_hop
=
UnicastRouting
.
get_route
(
source_ip
)[
"gateway"
]
multipaths
=
UnicastRouting
.
get_route
(
source_ip
)[
"multipath"
]
self
.
rpf_node
=
next_hop
if
next_hop
is
not
None
else
source_ip
print
(
"MUL"
,
multipaths
)
#self.rpf_node = multipaths[0]["gateway"]
for
m
in
multipaths
:
if
m
[
"gateway"
]
is
None
:
self
.
rpf_node
=
source_ip
break
else
:
self
.
rpf_node
=
m
[
"gateway"
]
print
(
"RPF_NODE:"
,
UnicastRouting
.
get_route
(
source_ip
))
print
(
self
.
rpf_node
==
source_ip
)
# (S,G) starts IG state
self
.
_was_olist_null
=
None
...
...
@@ -81,20 +100,29 @@ class KernelEntry:
def
recv_assert_msg
(
self
,
index
,
packet
):
print
(
"recv assert"
)
self
.
interface_state
[
index
].
recv_assert_msg
()
pkt_assert
=
packet
.
payload
.
payload
metric
=
pkt_assert
.
metric
metric_preference
=
pkt_assert
.
metric_preference
assert_sender_ip
=
packet
.
ip_header
.
ip_src
received_metric
=
AssertMetric
(
metric_preference
=
metric_preference
,
route_metric
=
metric
,
ip_address
=
assert_sender_ip
)
self
.
interface_state
[
index
].
recv_assert_msg
(
received_metric
)
def
recv_prune_msg
(
self
,
index
,
packet
):
print
(
"recv prune msg"
)
self
.
interface_state
[
index
].
recv_prune_msg
()
holdtime
=
packet
.
payload
.
payload
.
hold_time
upstream_neighbor_address
=
packet
.
payload
.
payload
.
upstream_neighbor_address
self
.
interface_state
[
index
].
recv_prune_msg
(
upstream_neighbor_address
=
upstream_neighbor_address
,
holdtime
=
holdtime
)
def
recv_join_msg
(
self
,
index
,
packet
):
print
(
"recv join msg"
)
print
(
"type: "
)
self
.
interface_state
[
index
].
recv_join_msg
()
upstream_neighbor_address
=
packet
.
payload
.
payload
.
upstream_neighbor_address
self
.
interface_state
[
index
].
recv_join_msg
(
upstream_neighbor_address
)
def
recv_graft_msg
(
self
,
index
,
packet
):
print
(
"recv graft msg"
)
self
.
interface_state
[
index
].
recv_graft_msg
()
upstream_neighbor_address
=
packet
.
payload
.
payload
.
upstream_neighbor_address
self
.
interface_state
[
index
].
recv_graft_msg
(
upstream_neighbor_address
)
def
recv_graft_ack_msg
(
self
,
index
,
packet
):
print
(
"recv graft ack msg"
)
...
...
@@ -105,13 +133,47 @@ class KernelEntry:
prune_indicator
=
1
self
.
interface_state
[
index
].
recv_state_refresh_msg
(
prune_indicator
)
def
network_update
(
self
,
change
,
args
):
#todo
return
###############################################################
# Unicast Changes to RPF
###############################################################
def
network_update
(
self
):
with
self
.
CHANGE_STATE_LOCK
:
#next_hop = UnicastRouting.get_route(self.source_ip)["gateway"]
#rpf_node = self.source_ip if next_hop is None else next_hop
next_hop
=
UnicastRouting
.
get_route
(
self
.
source_ip
)[
"gateway"
]
multipaths
=
UnicastRouting
.
get_route
(
self
.
source_ip
)[
"multipath"
]
rpf_node
=
next_hop
print
(
"MUL"
,
multipaths
)
# self.rpf_node = multipaths[0]["gateway"]
for
m
in
multipaths
:
if
m
[
"gateway"
]
is
None
:
rpf_node
=
self
.
source_ip
break
else
:
rpf_node
=
m
[
"gateway"
]
print
(
"RPF_NODE:"
,
UnicastRouting
.
get_route
(
self
.
source_ip
))
print
(
self
.
rpf_node
==
self
.
source_ip
)
new_inbound_interface_index
=
Main
.
kernel
.
vif_dic
[
self
.
check_rpf
()]
if
new_inbound_interface_index
!=
self
.
inbound_interface_index
:
# todo: criar novo upstream e downstream interface
# todo: stop upstream e downstream
#self.interface_state[self.inbound_interface_index].stop()
#self.interface_state[new_inbound_interface_index].stop()
#Unicast routing or Assert state causes RPF'(S) to change,
self
.
interface_state
[
self
.
inbound_interface_index
]
=
TreeInterfaceDownstream
self
.
interface_state
[
new_inbound_interface_index
]
=
TreeInterfaceUpstream
self
.
inbound_interface_index
=
new_inbound_interface_index
if
self
.
rpf_node
!=
rpf_node
:
self
.
rpf_node
=
rpf_node
self
.
interface_state
[
self
.
inbound_interface_index
].
change_rpf
(
self
.
_was_olist_null
)
def
update
(
self
,
caller
,
arg
):
#todo
...
...
tree/assert_.py
View file @
b5bd0d28
...
...
@@ -2,11 +2,14 @@ from abc import ABCMeta, abstractstaticmethod
import
tree.globals
as
pim_globals
from
.metric
import
AssertMetric
from
utils
import
TYPE_CHECKING
if
TYPE_CHECKING
:
from
.tree_if_downstream
import
TreeInterfaceDownstream
class
AssertStateABC
(
metaclass
=
ABCMeta
):
@
abstractstaticmethod
def
receivedDataFromDownstreamIf
(
interface
):
def
receivedDataFromDownstreamIf
(
interface
:
"TreeInterfaceDownstream"
):
"""
An (S,G) Data packet received on downstream interface
...
...
@@ -15,7 +18,7 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
@
abstractstaticmethod
def
receivedInferiorMetricFromWinner
(
interface
):
def
receivedInferiorMetricFromWinner
(
interface
:
"TreeInterfaceDownstream"
):
"""
Receive Inferior (Assert OR State Refresh) from Assert Winner
...
...
@@ -24,7 +27,7 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
@
abstractstaticmethod
def
receivedInferiorMetricFromNonWinner_couldAssertIsTrue
(
interface
):
def
receivedInferiorMetricFromNonWinner_couldAssertIsTrue
(
interface
:
"TreeInterfaceDownstream"
):
"""
Receive Inferior (Assert OR State Refresh) from non-Assert Winner
AND CouldAssert==TRUE
...
...
@@ -34,7 +37,7 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
@
abstractstaticmethod
def
receivedPreferedMetric
(
interface
,
assert_time
,
better_metric
):
def
receivedPreferedMetric
(
interface
:
"TreeInterfaceDownstream"
,
assert_time
,
better_metric
):
"""
Receive Preferred Assert OR State Refresh
...
...
@@ -45,7 +48,7 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
@
abstractstaticmethod
def
sendStateRefresh
(
interface
,
time
):
def
sendStateRefresh
(
interface
:
"TreeInterfaceDownstream"
,
time
):
"""
Send State Refresh
...
...
@@ -56,7 +59,7 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
@
abstractstaticmethod
def
assertTimerExpires
(
interface
):
def
assertTimerExpires
(
interface
:
"TreeInterfaceDownstream"
):
"""
AT(S,G) Expires
...
...
@@ -65,7 +68,7 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
@
abstractstaticmethod
def
couldAssertIsNowFalse
(
interface
):
def
couldAssertIsNowFalse
(
interface
:
"TreeInterfaceDownstream"
):
"""
CouldAssert -> FALSE
...
...
@@ -74,7 +77,7 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
@
abstractstaticmethod
def
couldAssertIsNowTrue
(
interface
):
def
couldAssertIsNowTrue
(
interface
:
"TreeInterfaceDownstream"
):
"""
CouldAssert -> TRUE
...
...
@@ -83,7 +86,7 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
@
abstractstaticmethod
def
winnerLivelinessTimerExpires
(
interface
):
def
winnerLivelinessTimerExpires
(
interface
:
"TreeInterfaceDownstream"
):
"""
Winner’s NLT(N,I) Expires
...
...
@@ -92,7 +95,7 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
@
abstractstaticmethod
def
receivedPruneOrJoinOrGraft
(
interface
):
def
receivedPruneOrJoinOrGraft
(
interface
:
"TreeInterfaceDownstream"
):
"""
Receive Prune(S,G), Join(S,G) or Graft(S,G)
...
...
@@ -101,264 +104,302 @@ class AssertStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
def
_sendAssert_setAT
(
interface
):
def
_sendAssert_setAT
(
interface
:
"TreeInterfaceDownstream"
):
interface
.
send_assert
()
interface
.
assert_timer
.
set_timer
(
pim_globals
.
ASSERT_TIME
)
interface
.
assert_timer
.
reset
()
#interface.assert_timer.set_timer(pim_globals.ASSERT_TIME)
interface
.
set_assert_timer
(
pim_globals
.
ASSERT_TIME
)
#interface.assert_timer.reset()
@
staticmethod
def
rprint
(
interface
,
msg
,
*
entrys
):
def
rprint
(
interface
:
"TreeInterfaceDownstream"
,
msg
,
*
entrys
):
'''
Method used for simplifiyng the process of reporting changes in a assert state
Tree Interface.
@type interface: TreeInterface
'''
interface
.
r
print
(
msg
,
'assert state'
,
*
entrys
)
print
(
msg
,
'assert state'
,
*
entrys
)
# Override
def
__str__
(
self
)
->
str
:
return
"PruneSM:"
+
self
.
__class__
.
__name__
class
Loser
State
(
AssertStateABC
):
class
NoInfo
State
(
AssertStateABC
):
'''
I am Assert Loser (L)
This router has lost an (S,G) Assert on interface I. It must not
forward packets from S destined for G onto interface I.
NoInfoState (NI)
This router has no (S,G) Assert state on interface I.
'''
@
staticmethod
def
receivedDataFromDownstreamIf
(
interface
):
def
receivedDataFromDownstreamIf
(
interface
:
"TreeInterfaceDownstream"
):
"""
@type interface: TreeInterface
"""
interface
.
rprint
(
'receivedDataFromDownstreamIf, L -> L'
)
NoInfoState
.
_sendAssert_setAT
(
interface
)
@
staticmethod
def
receivedInferiorMetricFromWinner
(
interface
):
LoserState
.
_to_NoInfo
(
interface
)
interface
.
set_assert_state
(
AssertState
.
Winner
)
#interface.assert_winner_metric = interface.assert_metric
interface
.
set_assert_winner_metric
(
interface
.
my_assert_metric
()
)
interface
.
rprint
(
'receivedInferiorMetricFromWinner, L -> NI
'
)
print
(
'receivedDataFromDownstreamIf, NI -> W
'
)
@
staticmethod
def
receivedInferiorMetricFromNonWinner_couldAssertIsTrue
(
interface
):
interface
.
rprint
(
'receivedInferiorMetricFromNonWinner_couldAssertIsTrue, L -> L'
)
def
receivedInferiorMetricFromWinner
(
interface
:
"TreeInterfaceDownstream"
):
assert
False
,
"this should never ocurr"
@
staticmethod
def
receivedPreferedMetric
(
interface
,
assert_time
,
better_metric
):
'''
@type better_metric: AssertMetric
'''
interface
.
assert_timer
.
set_timer
(
assert_time
)
interface
.
assert_timer
.
reset
()
has_winner_changed
=
interface
.
assert_winner_metric
.
node
!=
better_metric
.
node
interface
.
assert_winner_metric
=
better_metric
if
interface
.
could_assert
()
and
has_winner_changed
:
interface
.
send_prune
()
def
receivedInferiorMetricFromNonWinner_couldAssertIsTrue
(
interface
:
"TreeInterfaceDownstream"
):
NoInfoState
.
_sendAssert_setAT
(
interface
)
interface
.
rprint
(
'receivedPreferedMetric, L -> L'
,
'from:'
,
better_metric
.
node
)
#interface.assert_state = AssertState.Winner
interface
.
set_assert_state
(
AssertState
.
Winner
)
#interface.assert_winner_metric = interface.assert_metric
interface
.
set_assert_winner_metric
(
interface
.
my_assert_metric
())
@
staticmethod
def
sendStateRefresh
(
interface
,
time
):
assert
False
,
"this should never ocurr"
print
(
'receivedInferiorMetricFromNonWinner_couldAssertIsTrue, NI -> W'
)
@
staticmethod
def
assertTimerExpires
(
interface
):
LoserState
.
_to_NoInfo
(
interface
)
def
receivedPreferedMetric
(
interface
:
"TreeInterfaceDownstream"
,
better_metric
,
state_refresh_interval
=
None
):
'''
@type interface: TreeInterface
'''
#interface.assert_timer.set_timer(assert_time)
if
state_refresh_interval
is
None
:
# event caused by Assert Msg
assert_timer_value
=
pim_globals
.
ASSERT_TIME
else
:
# event caused by StateRefreshMsg
assert_timer_value
=
state_refresh_interval
*
3
interface
.
set_assert_timer
(
assert_timer_value
)
#interface.assert_timer.reset()
#interface.assert_state = AssertState.Loser
interface
.
set_assert_state
(
AssertState
.
Loser
)
#interface.assert_winner_metric = better_metric
interface
.
set_assert_winner_metric
(
better_metric
)
# todo MUST also multicast a Prune(S,G) to the Assert winner <- TO THE colocar endereco do winner
if
interface
.
could_assert
():
interface
.
send_prune
(
holdtime
=
assert_timer_value
)
interface
.
rprint
(
'assertTimerExpires, L -> NI
'
)
print
(
'receivedPreferedMetric, NI -> L
'
)
@
staticmethod
def
couldAssertIsNowFalse
(
interface
):
LoserState
.
_to_NoInfo
(
interface
)
interface
.
rprint
(
'couldAssertIsNowFalse, L -> NI'
)
def
sendStateRefresh
(
interface
:
"TreeInterfaceDownstream"
,
time
):
pass
@
staticmethod
def
couldAssertIsNowTrue
(
interface
):
LoserState
.
_to_NoInfo
(
interface
)
interface
.
rprint
(
'couldAssertIsNowTrue, L -> NI'
)
def
assertTimerExpires
(
interface
:
"TreeInterfaceDownstream"
):
assert
False
,
"this should never ocurr"
@
staticmethod
def
winnerLivelinessTimerExpires
(
interface
):
LoserState
.
_to_NoInfo
(
interface
)
interface
.
rprint
(
'winnerLivelinessTimerExpires, L -> NI'
)
def
couldAssertIsNowFalse
(
interface
:
"TreeInterfaceDownstream"
):
print
(
'couldAssertIsNowFalse, NI -> NI'
)
@
staticmethod
def
receivedPruneOrJoinOrGraft
(
interface
):
interface
.
send_assert
(
)
def
couldAssertIsNowTrue
(
interface
:
"TreeInterfaceDownstream"
):
print
(
'couldAssertIsNowTrue, NI -> NI'
)
interface
.
rprint
(
'receivedPruneOrJoinOrGraft, L -> L'
)
@
staticmethod
def
winnerLivelinessTimerExpires
(
interface
:
"TreeInterfaceDownstream"
):
assert
False
,
"this should never ocurr"
@
staticmethod
def
_to_NoInfo
(
interface
):
interface
.
assert_timer
.
stop
()
interface
.
assert_state
=
AssertState
.
NoInfo
interface
.
assert_winner_metric
=
AssertMetric
.
infinite_assert_metric
()
def
receivedPruneOrJoinOrGraft
(
interface
:
"TreeInterfaceDownstream"
):
print
(
'receivedPruneOrJoinOrGraft, NI -> NI'
)
class
NoInfo
State
(
AssertStateABC
):
class
Winner
State
(
AssertStateABC
):
'''
NoInfoState (NI)
This router has no (S,G) Assert state on interface I.
I am Assert Winner (W)
This router has won an (S,G) Assert on interface I. It is now
responsible for forwarding traffic from S destined for G via
interface I.
'''
@
staticmethod
def
receivedDataFromDownstreamIf
(
interface
):
def
receivedDataFromDownstreamIf
(
interface
:
"TreeInterfaceDownstream"
):
"""
@type interface: TreeInterface
"""
NoInfoState
.
_sendAssert_setAT
(
interface
)
interface
.
assert_state
=
AssertState
.
Winner
interface
.
assert_winner_metric
=
interface
.
assert_metric
WinnerState
.
_sendAssert_setAT
(
interface
)
interface
.
rprint
(
'receivedDataFromDownstreamIf, NI
-> W'
)
print
(
'receivedDataFromDownstreamIf, W
-> W'
)
@
staticmethod
def
receivedInferiorMetricFromWinner
(
interface
):
def
receivedInferiorMetricFromWinner
(
interface
:
"TreeInterfaceDownstream"
):
assert
False
,
"this should never ocurr"
@
staticmethod
def
receivedInferiorMetricFromNonWinner_couldAssertIsTrue
(
interface
):
NoInfoState
.
_sendAssert_setAT
(
interface
)
interface
.
assert_state
=
AssertState
.
Winner
interface
.
assert_winner_metric
=
interface
.
assert_metric
def
receivedInferiorMetricFromNonWinner_couldAssertIsTrue
(
interface
:
"TreeInterfaceDownstream"
):
WinnerState
.
_sendAssert_setAT
(
interface
)
interface
.
r
print
(
'receivedInferiorMetricFromNonWinner_couldAssertIsTrue,
NI
-> W'
)
print
(
'receivedInferiorMetricFromNonWinner_couldAssertIsTrue,
W
-> W'
)
@
staticmethod
def
receivedPreferedMetric
(
interface
,
assert_time
,
better_metric
):
def
receivedPreferedMetric
(
interface
:
"TreeInterfaceDownstream"
,
better_metric
,
state_refresh_interval
=
None
):
'''
@type
interface: TreeInterface
@type
better_metric: AssertMetric
'''
interface
.
assert_timer
.
set_timer
(
assert_time
)
interface
.
assert_timer
.
reset
()
interface
.
assert_state
=
AssertState
.
Loser
interface
.
assert_winner_metric
=
better_metric
#interface.assert_timer.set_timer(assert_time)
#interface.assert_timer.reset()
if
interface
.
could_assert
():
interface
.
send_prune
()
if
state_refresh_interval
is
None
:
# event caused by AssertMsg
assert_timer_value
=
pim_globals
.
ASSERT_TIME
else
:
# event caused by State Refresh Msg
assert_timer_value
=
state_refresh_interval
*
3
interface
.
set_assert_timer
(
assert_timer_value
)
interface
.
set_assert_winner_metric
(
better_metric
)
interface
.
rprint
(
'receivedPreferedMetric, NI -> L'
)
#interface.assert_state = AssertState.Loser
interface
.
set_assert_state
(
AssertState
.
Loser
)
if
interface
.
could_assert
:
interface
.
send_prune
(
holdtime
=
assert_timer_value
)
print
(
'receivedPreferedMetric, W -> L'
)
@
staticmethod
def
sendStateRefresh
(
interface
,
time
):
pass
def
sendStateRefresh
(
interface
:
"TreeInterfaceDownstream"
,
state_refresh_interval
):
#interface.assert_timer.set_timer(time)
interface
.
set_assert_timer
(
state_refresh_interval
*
3
)
#interface.assert_timer.reset()
@
staticmethod
def
assertTimerExpires
(
interface
):
assert
False
,
"this should never ocurr"
def
assertTimerExpires
(
interface
:
"TreeInterfaceDownstream"
):
#interface.assert_state = AssertState.NoInfo
interface
.
set_assert_state
(
AssertState
.
NoInfo
)
interface
.
set_assert_winner_metric
(
AssertMetric
.
infinite_assert_metric
())
print
(
'assertTimerExpires, W -> NI'
)
@
staticmethod
def
couldAssertIsNowFalse
(
interface
):
interface
.
rprint
(
'couldAssertIsNowFalse, NI -> NI'
)
def
couldAssertIsNowFalse
(
interface
:
"TreeInterfaceDownstream"
):
interface
.
send_assert_cancel
()
#interface.assert_timer.stop()
interface
.
clear_assert_timer
()
#interface.assert_state = AssertState.NoInfo
interface
.
set_assert_state
(
AssertState
.
NoInfo
)
interface
.
set_assert_winner_metric
(
AssertMetric
.
infinite_assert_metric
())
print
(
'couldAssertIsNowFalse, W -> NI'
)
@
staticmethod
def
couldAssertIsNowTrue
(
interface
):
interface
.
rprint
(
'couldAssertIsNowTrue, NI -> NI'
)
def
couldAssertIsNowTrue
(
interface
:
"TreeInterfaceDownstream"
):
assert
False
,
"this should never ocurr"
@
staticmethod
def
winnerLivelinessTimerExpires
(
interface
):
def
winnerLivelinessTimerExpires
(
interface
:
"TreeInterfaceDownstream"
):
assert
False
,
"this should never ocurr"
@
staticmethod
def
receivedPruneOrJoinOrGraft
(
interface
):
interface
.
rprint
(
'receivedPruneOrJoinOrGraft, NI -> NI'
)
def
receivedPruneOrJoinOrGraft
(
interface
:
"TreeInterfaceDownstream"
):
pass
class
Winn
erState
(
AssertStateABC
):
class
Los
erState
(
AssertStateABC
):
'''
I am Assert Winner (W)
This router has won an (S,G) Assert on interface I. It is now
responsible for forwarding traffic from S destined for G via
interface I.
I am Assert Loser (L)
This router has lost an (S,G) Assert on interface I. It must not
forward packets from S destined for G onto interface I.
'''
@
staticmethod
def
receivedDataFromDownstreamIf
(
interface
):
def
receivedDataFromDownstreamIf
(
interface
:
"TreeInterfaceDownstream"
):
"""
@type interface: TreeInterface
"""
WinnerState
.
_sendAssert_setAT
(
interface
)
interface
.
rprint
(
'receivedDataFromDownstreamIf, W -> W'
)
print
(
'receivedDataFromDownstreamIf, L -> L'
)
@
staticmethod
def
receivedInferiorMetricFromWinner
(
interface
):
assert
False
,
"this should never ocurr"
def
receivedInferiorMetricFromWinner
(
interface
:
"TreeInterfaceDownstream"
):
LoserState
.
_to_NoInfo
(
interface
)
@
staticmethod
def
receivedInferiorMetricFromNonWinner_couldAssertIsTrue
(
interface
):
WinnerState
.
_sendAssert_setAT
(
interface
)
print
(
'receivedInferiorMetricFromWinner, L -> NI'
)
interface
.
rprint
(
'receivedInferiorMetricFromNonWinner_couldAssertIsTrue, W -> W'
)
@
staticmethod
def
receivedInferiorMetricFromNonWinner_couldAssertIsTrue
(
interface
:
"TreeInterfaceDownstream"
):
print
(
'receivedInferiorMetricFromNonWinner_couldAssertIsTrue, L -> L'
)
@
staticmethod
def
receivedPreferedMetric
(
interface
,
assert_time
,
better_metric
):
def
receivedPreferedMetric
(
interface
:
"TreeInterfaceDownstream"
,
better_metric
,
state_refresh_interval
=
None
):
'''
@type better_metric: AssertMetric
'''
#interface.assert_timer.set_timer(assert_time)
#interface.assert_timer.reset()
if
state_refresh_interval
is
None
:
assert_timer_value
=
pim_globals
.
ASSERT_TIME
else
:
assert_timer_value
=
state_refresh_interval
*
3
interface
.
assert_timer
.
set_timer
(
assert_time
)
interface
.
assert_timer
.
reset
()
interface
.
set_assert_timer
(
assert_timer_value
)
interface
.
assert_winner_metric
=
better_metric
#has_winner_changed = interface.assert_winner_metric.node != better_metric.node
interface
.
assert_state
=
AssertState
.
Loser
interface
.
set_assert_winner_metric
(
better_metric
)
if
interface
.
could_assert
:
if
interface
.
could_assert
():
# todo enviar holdtime = assert_timer_value???!
interface
.
send_prune
()
interface
.
rprint
(
'receivedPreferedMetric, W -> L'
,
'from:'
,
str
(
better_metric
.
node
))
print
(
'receivedPreferedMetric, L -> L'
)
@
staticmethod
def
sendStateRefresh
(
interface
,
time
):
interface
.
assert_timer
.
set_timer
(
time
)
interface
.
assert_timer
.
reset
()
def
sendStateRefresh
(
interface
:
"TreeInterfaceDownstream"
,
time
):
assert
False
,
"this should never ocurr"
@
staticmethod
def
assertTimerExpires
(
interface
):
interface
.
assert_state
=
AssertState
.
NoInfo
interface
.
assert_winner_metric
=
AssertMetric
.
infinite_assert_metric
()
def
assertTimerExpires
(
interface
:
"TreeInterfaceDownstream"
):
LoserState
.
_to_NoInfo
(
interface
)
interface
.
rprint
(
'assertTimerExpires, W -> NI'
)
if
interface
.
could_assert
():
interface
.
evaluate_ingroup
()
print
(
'assertTimerExpires, L -> NI'
)
@
staticmethod
def
couldAssertIsNowFalse
(
interface
):
interface
.
send_assert_cancel
(
)
def
couldAssertIsNowFalse
(
interface
:
"TreeInterfaceDownstream"
):
LoserState
.
_to_NoInfo
(
interface
)
interface
.
assert_timer
.
stop
(
)
print
(
'couldAssertIsNowFalse, L -> NI'
)
interface
.
assert_state
=
AssertState
.
NoInfo
interface
.
assert_winner_metric
=
AssertMetric
.
infinite_assert_metric
()
@
staticmethod
def
couldAssertIsNowTrue
(
interface
:
"TreeInterfaceDownstream"
):
LoserState
.
_to_NoInfo
(
interface
)
interface
.
rprint
(
'couldAssertIsNowFalse, W
-> NI'
)
print
(
'couldAssertIsNowTrue, L
-> NI'
)
@
staticmethod
def
couldAssertIsNowTrue
(
interface
):
assert
False
,
"this should never ocurr"
def
winnerLivelinessTimerExpires
(
interface
:
"TreeInterfaceDownstream"
):
LoserState
.
_to_NoInfo
(
interface
)
print
(
'winnerLivelinessTimerExpires, L -> NI'
)
@
staticmethod
def
winnerLivelinessTimerExpires
(
interface
):
assert
False
,
"this should never ocurr"
def
receivedPruneOrJoinOrGraft
(
interface
:
"TreeInterfaceDownstream"
):
interface
.
send_assert
()
print
(
'receivedPruneOrJoinOrGraft, L -> L'
)
@
staticmethod
def
receivedPruneOrJoinOrGraft
(
interface
):
pass
def
_to_NoInfo
(
interface
:
"TreeInterfaceDownstream"
):
#interface.assert_timer.stop()
interface
.
clear_assert_timer
()
interface
.
set_assert_state
(
AssertState
.
NoInfo
)
interface
.
set_assert_winner_metric
(
AssertMetric
.
infinite_assert_metric
())
class
AssertState
():
...
...
tree/downstream_prune.py
View file @
b5bd0d28
...
...
@@ -133,7 +133,8 @@ class NoInfo(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream
"""
assert
False
#assert False
return
@
staticmethod
def
PTexpires
(
interface
:
"TreeInterfaceDownstream"
):
...
...
@@ -142,7 +143,8 @@ class NoInfo(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream
"""
assert
False
#assert False
return
@
staticmethod
def
is_now_RPF_Interface
(
interface
:
"TreeInterfaceDownstream"
):
...
...
@@ -230,7 +232,8 @@ class PrunePending(DownstreamStateABS):
#pt = interface.get_pt()
#pt.start(interface.get_lpht() - pim_globals.JT_OVERRIDE_INTERVAL)
interface
.
set_prune_timer
(
prune_holdtime
-
pim_globals
.
JT_OVERRIDE_INTERVAL
)
#interface.set_prune_timer(prune_holdtime - pim_globals.JT_OVERRIDE_INTERVAL)
interface
.
set_prune_timer
(
interface
.
get_received_prune_holdtime
()
-
pim_globals
.
JT_OVERRIDE_INTERVAL
)
interface
.
send_pruneecho
()
...
...
@@ -245,7 +248,8 @@ class PrunePending(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream
"""
assert
False
#assert False
return
@
staticmethod
def
is_now_RPF_Interface
(
interface
:
"TreeInterfaceDownstream"
):
...
...
@@ -259,6 +263,8 @@ class PrunePending(DownstreamStateABS):
#interface.get_ppt().stop()
interface
.
clear_prune_pending_timer
()
interface
.
set_prune_state
(
DownstreamState
.
NoInfo
)
print
(
'is_now_RPF_Interface, PP -> NI'
)
@
staticmethod
...
...
@@ -293,7 +299,8 @@ class Pruned(DownstreamStateABS):
# ppt.set_timer(interface.get_lpht())
# ppt.reset()
# todo nao percebo... corrigir 0
if
holdtime
>
0
:
#if holdtime > 0:
if
interface
.
get_received_prune_holdtime
()
>
interface
.
remaining_prune_timer
():
interface
.
set_prune_timer
(
holdtime
)
print
(
'receivedPrune, P -> P'
)
...
...
@@ -334,7 +341,8 @@ class Pruned(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream
"""
assert
False
#assert False
return
@
staticmethod
def
PTexpires
(
interface
:
"TreeInterfaceDownstream"
):
...
...
@@ -358,6 +366,7 @@ class Pruned(DownstreamStateABS):
# todo ver melhor
#interface.get_pt().stop()
interface
.
clear_prune_timer
()
interface
.
set_prune_state
(
DownstreamState
.
NoInfo
)
print
(
'is_now_RPF_Interface, P -> NI'
)
...
...
@@ -372,7 +381,8 @@ class Pruned(DownstreamStateABS):
#pt = interface.get_pt()
#pt.set_timer(interface.get_lpht())
#pt.reset()
interface
.
set_prune_timer
(
interface
.
get_lpht
())
#interface.set_prune_timer(interface.get_lpht())
interface
.
set_prune_timer
(
interface
.
get_received_prune_holdtime
())
print
(
'send_state_refresh, P -> P'
)
...
...
tree/globals.py
View file @
b5bd0d28
...
...
@@ -13,3 +13,7 @@ OVERRIDE_INTERVAL = 2.5
REFRESH_INTERVAL
=
60
# State Refresh Interval
SOURCE_LIFETIME
=
210
T_LIMIT
=
210
ASSERT_CANCEL_METRIC
=
0xFFFFFFFF
\ No newline at end of file
tree/local_membership.py
0 → 100644
View file @
b5bd0d28
from
abc
import
ABCMeta
,
abstractmethod
class
LocalMembershipStateABC
(
metaclass
=
ABCMeta
):
@
staticmethod
@
abstractmethod
def
has_members
():
raise
NotImplementedError
class
NoInfo
(
LocalMembershipStateABC
):
@
staticmethod
def
has_members
():
return
False
class
Include
(
LocalMembershipStateABC
):
@
staticmethod
def
has_members
():
return
True
class
LocalMembership
():
NoInfo
=
NoInfo
()
Include
=
Include
()
\ No newline at end of file
tree/metric.py
View file @
b5bd0d28
'''
Created on Sep 8, 2014
@author: alex
'''
import
ipaddress
class
AssertMetric
(
object
):
'''
Note: we consider the node name the ip of the metric.
'''
def
__init__
(
self
):
'''
@type tree_if: TreeInterface
'''
self
.
_pref
=
None
self
.
_metric
=
None
self
.
_node
=
None
def
is_worse_than
(
self
,
other
):
if
self
.
_pref
!=
other
.
pref
:
return
self
.
_pref
>
other
.
pref
def
__init__
(
self
,
metric_preference
:
int
or
float
=
float
(
"Inf"
),
route_metric
:
int
or
float
=
float
(
"Inf"
),
ip_address
:
str
=
"0.0.0.0"
):
if
type
(
ip_address
)
is
str
:
ip_address
=
ipaddress
.
ip_address
(
ip_address
)
elif
self
.
_metric
!=
other
.
metric
:
return
self
.
_metric
>
other
.
metric
self
.
_metric_preference
=
metric_preference
self
.
_route_metric
=
route_metric
self
.
_ip_address
=
ip_address
def
is_better_than
(
self
,
other
):
if
self
.
metric_preference
!=
other
.
metric_preference
:
return
self
.
metric_preference
<
other
.
metric_preference
elif
self
.
route_metric
!=
other
.
route_metric
:
return
self
.
route_metric
<
other
.
route_metric
else
:
return
self
.
_node
.
__str__
()
<=
other
.
node
.
__str__
()
return
self
.
ip_address
>
other
.
ip_address
@
property
def
pref
(
self
):
return
self
.
_pref
@
property
def
metric
(
self
):
return
self
.
_metric
@
property
def
node
(
self
):
return
self
.
_node
def
is_worse
(
self
,
other
):
return
not
self
.
is_better_than
(
other
)
@
staticmethod
def
infinite_assert_metric
():
'''
@type metric: AssertMetric
'''
metric
=
AssertMetric
()
metric
.
_pref
=
1
metric
.
_metric
=
float
(
"Inf"
)
metric
.
_node
=
""
return
metric
return
AssertMetric
(
metric_preference
=
float
(
"Inf"
),
route_metric
=
float
(
"Inf"
),
ip_address
=
"0.0.0.0"
)
@
staticmethod
def
spt_assert_metric
(
tree_if
):
...
...
@@ -59,15 +37,40 @@ class AssertMetric(object):
@type metric: AssertMetric
@type tree_if: TreeInterface
'''
metric
=
AssertMetric
()
(
source_ip
,
_
)
=
tree_if
.
get_tree_id
()
import
UnicastRouting
metric_preference
,
metric_cost
=
UnicastRouting
.
get_metric
(
source_ip
)
return
AssertMetric
(
metric_preference
,
metric_cost
,
tree_if
.
get_ip
())
def
i_am_assert_winner
(
self
,
tree_if
):
interface_ip
=
ipaddress
.
ip_address
(
tree_if
.
get_ip
())
return
self
.
_ip_address
==
interface_ip
@
property
def
metric_preference
(
self
):
return
self
.
_metric_preference
@
metric_preference
.
setter
def
metric_preference
(
self
,
value
):
self
.
_metric_preference
=
value
metric
.
_pref
=
1
# TODO: ver isto melhor no route preference
metric
.
_metric
=
tree_if
.
metric
metric
.
_node
=
tree_if
.
node
@
property
def
route_metric
(
self
):
return
self
.
_route_metric
@
route_metric
.
setter
def
route_metric
(
self
,
value
):
self
.
_route_metric
=
value
@
property
def
ip_address
(
self
):
return
self
.
_ip_address
return
metric
@
ip_address
.
setter
def
ip_address
(
self
,
value
):
if
type
(
value
)
is
str
:
value
=
ipaddress
.
ip_address
(
value
)
# overrides
def
__str__
(
self
):
return
"AssertMetric<{}:{}:{}>"
.
format
(
self
.
_pref
,
self
.
_metric
,
self
.
_node
)
self
.
_ip_address
=
value
tree/tree_if_downstream.py
View file @
b5bd0d28
...
...
@@ -7,6 +7,7 @@ Created on Jul 16, 2015
#from convergence import Convergence
#from des.event.timer import Timer
from
threading
import
Timer
from
CustomTimer.RemainingTimer
import
RemainingTimer
from
.assert_
import
AssertState
,
AssertStateABC
#from .messages.assert_msg import SFMRAssertMsg
#from .messages.reset import SFMResetMsg
...
...
@@ -22,18 +23,18 @@ class TreeInterfaceDownstream(TreeInterface):
TreeInterface
.
__init__
(
self
,
kernel_entry
,
interface_id
)
# State
self
.
_local_membership_state
=
None
# todo NoInfo or Include
#
self._local_membership_state = None # todo NoInfo or Include
# Prune State
self
.
_prune_state
=
DownstreamState
.
NoInfo
self
.
_prune_pending_timer
=
None
self
.
_prune_timer
=
None
#
self._prune_state = DownstreamState.NoInfo
#
self._prune_pending_timer = None
#
self._prune_timer = None
# Assert Winner State
self
.
_assert_state
=
AssertState
.
Winner
self
.
_assert_timer
=
None
self
.
_assert_winner_ip
=
None
self
.
_assert_winner_metric
=
None
#self._assert_state = AssertState.NoInfo
#
self._assert_timer = None
#
self._assert_winner_ip = None
#
self._assert_winner_metric = None
#self.set_dipt_timer()
#self.send_prune()
...
...
@@ -58,6 +59,9 @@ class TreeInterfaceDownstream(TreeInterface):
def
is_prune_timer_running
(
self
):
return
self
.
_prune_timer
is
not
None
and
self
.
_prune_timer
.
is_alive
()
def
remaining_prune_timer
(
self
):
return
0
if
not
self
.
_prune_timer
else
self
.
_prune_timer
.
time_remaining
()
##########################################
# Set timers
##########################################
...
...
@@ -72,7 +76,8 @@ class TreeInterfaceDownstream(TreeInterface):
def
set_prune_timer
(
self
,
time
):
self
.
clear_prune_timer
()
self
.
_prune_timer
=
Timer
(
time
,
self
.
prune_timeout
)
#self._prune_timer = Timer(time, self.prune_timeout)
self
.
_prune_timer
=
RemainingTimer
(
time
,
self
.
prune_timeout
)
self
.
_prune_timer
.
start
()
def
clear_prune_timer
(
self
):
...
...
@@ -88,27 +93,32 @@ class TreeInterfaceDownstream(TreeInterface):
def
prune_timeout
(
self
):
self
.
_prune_state
.
PTexpires
(
self
)
###########################################
# Recv packets
###########################################
def
recv_data_msg
(
self
):
self
.
_assert_state
.
receivedDataFromDownstreamIf
(
self
)
# Override
def
recv_prune_msg
(
self
):
self
.
_prune_state
.
receivedPrune
(
self
,
0
)
def
recv_prune_msg
(
self
,
upstream_neighbor_address
,
holdtime
):
super
().
recv_prune_msg
(
upstream_neighbor_address
,
holdtime
)
# set here???
self
.
set_receceived_prune_holdtime
(
holdtime
)
self
.
_prune_state
.
receivedPrune
(
self
,
holdtime
)
# Override
def
recv_join_msg
(
self
):
def
recv_join_msg
(
self
,
upstream_neighbor_address
):
super
().
recv_join_msg
(
upstream_neighbor_address
)
self
.
_prune_state
.
receivedJoin
(
self
)
# Override
def
recv_graft_msg
(
self
):
def
recv_graft_msg
(
self
,
upstream_neighbor_address
):
super
().
recv_graft_msg
(
upstream_neighbor_address
)
self
.
_prune_state
.
receivedGraft
(
self
)
# Override
def
is_forwarding
(
self
):
return
((
len
(
self
.
get_interface
().
neighbors
)
>=
1
and
not
self
.
is_pruned
())
or
self
.
igmp_has_members
())
and
not
self
.
lost_assert
()
...
...
@@ -133,15 +143,6 @@ class TreeInterfaceDownstream(TreeInterface):
def
get_metric
(
self
):
return
AssertMetric
.
spt_assert_metric
(
self
)
def
_set_assert_state
(
self
,
value
:
AssertStateABC
):
with
self
.
get_state_lock
():
if
value
!=
self
.
_assert_state
:
self
.
_assert_state
=
value
self
.
change_tree
()
self
.
evaluate_ingroup
()
#Convergence.mark_change()
def
_get_winner_metric
(
self
):
'''
@rtype: SFMRAssertMetric
...
...
tree/tree_if_upstream.py
View file @
b5bd0d28
...
...
@@ -24,6 +24,9 @@ class TreeInterfaceUpstream(TreeInterface):
self
.
_originator_state
=
None
if
self
.
is_S_directly_conn
():
self
.
_graft_prune_state
.
sourceIsNowDirectConnect
(
self
)
##########################################
# Set state
##########################################
...
...
@@ -95,7 +98,7 @@ class TreeInterfaceUpstream(TreeInterface):
###########################################
def
recv_data_msg
(
self
):
# todo check olist
if
self
.
is_olist_null
()
and
not
self
.
is_prune_limit_timer_running
():
if
self
.
is_olist_null
()
and
not
self
.
is_prune_limit_timer_running
()
and
not
self
.
is_S_directly_conn
()
:
self
.
_graft_prune_state
.
dataArrivesRPFinterface_OListNull_PLTstoped
(
self
)
def
recv_state_refresh_msg
(
self
,
prune_indicator
:
int
):
...
...
@@ -105,11 +108,13 @@ class TreeInterfaceUpstream(TreeInterface):
elif
prune_indicator
==
0
and
not
self
.
is_prune_limit_timer_running
():
self
.
_graft_prune_state
.
stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped
(
self
)
def
recv_join_msg
(
self
):
def
recv_join_msg
(
self
,
upstream_neighbor_address
):
super
().
recv_join_msg
(
upstream_neighbor_address
)
# todo check rpf nbr
self
.
_graft_prune_state
.
seeJoinToRPFnbr
(
self
)
def
recv_prune_msg
(
self
):
def
recv_prune_msg
(
self
,
upstream_neighbor_address
,
holdtime
):
super
().
recv_prune_msg
(
upstream_neighbor_address
,
holdtime
)
self
.
_graft_prune_state
.
seePrune
(
self
)
def
recv_graft_ack_msg
(
self
):
...
...
@@ -128,8 +133,11 @@ class TreeInterfaceUpstream(TreeInterface):
###########################################
# Changes on Unicast Routing Table
###########################################
# todo
def
change_rpf
(
self
,
olist_is_null
):
if
olist_is_null
:
self
.
_graft_prune_state
.
RPFnbrChanges_olistIsNull
()
else
:
self
.
_graft_prune_state
.
RPFnbrChanges_olistIsNotNull
()
#Override
def
is_forwarding
(
self
):
...
...
@@ -149,5 +157,5 @@ class TreeInterfaceUpstream(TreeInterface):
@
property
def
t_override
(
self
):
oi
=
self
.
get_interface
().
_override_inter
n
al
oi
=
self
.
get_interface
().
_override_inter
v
al
return
random
.
uniform
(
0
,
oi
)
tree/tree_interface.py
View file @
b5bd0d28
...
...
@@ -12,7 +12,7 @@ import traceback
#from sfmr.messages.prune import SFMRPruneMsg
#from .router_interface import SFMRInterface
from
.downstream_prune
import
DownstreamState
from
.assert_
import
AssertState
from
.assert_
import
AssertState
,
AssertStateABC
from
Packet.PacketPimGraft
import
PacketPimGraft
from
Packet.PacketPimGraftAck
import
PacketPimGraftAck
...
...
@@ -23,6 +23,10 @@ from Packet.Packet import Packet
from
Packet.PacketPimJoinPrune
import
PacketPimJoinPrune
from
Packet.PacketPimAssert
import
PacketPimAssert
from
Packet.PacketPimStateRefresh
import
PacketPimStateRefresh
from
.metric
import
AssertMetric
from
threading
import
Timer
from
.local_membership
import
LocalMembership
from
.globals
import
*
class
TreeInterface
(
metaclass
=
ABCMeta
):
def
__init__
(
self
,
kernel_entry
,
interface_id
):
...
...
@@ -44,14 +48,16 @@ class TreeInterface(metaclass=ABCMeta):
interface_name
=
Main
.
kernel
.
vif_index_to_name_dic
[
interface_id
]
igmp_interface
=
Main
.
igmp_interfaces
[
interface_name
]
# type: InterfaceIGMP
group_state
=
igmp_interface
.
interface_state
.
get_group_state
(
kernel_entry
.
group_ip
)
self
.
_igmp_has_members
=
group_state
.
add_multicast_routing_entry
(
self
)
#self._igmp_has_members = group_state.add_multicast_routing_entry(self)
igmp_has_members
=
group_state
.
add_multicast_routing_entry
(
self
)
self
.
_local_membership_state
=
LocalMembership
.
Include
if
igmp_has_members
else
LocalMembership
.
NoInfo
except
:
#traceback.print_exc()
self
.
_
igmp_has_members
=
False
self
.
_
local_membership_state
=
LocalMembership
.
NoInfo
# Local Membership State
self
.
_local_membership_state
=
None
# todo NoInfo or Include
#
self._local_membership_state = None # todo NoInfo or Include
# Prune State
self
.
_prune_state
=
DownstreamState
.
NoInfo
...
...
@@ -59,35 +65,104 @@ class TreeInterface(metaclass=ABCMeta):
self
.
_prune_timer
=
None
# Assert Winner State
self
.
_assert_state
=
AssertState
.
Winner
self
.
_assert_state
=
AssertState
.
NoInfo
self
.
_assert_winner_metric
=
AssertMetric
()
self
.
_assert_timer
=
None
self
.
_assert_winner_ip
=
None
self
.
_assert_winner_metric
=
None
#self._assert_winner_ip = None
#self._assert_winner_metric = None
# Received prune hold time
self
.
_received_prune_holdtime
=
None
self
.
_igmp_lock
=
RLock
()
#self.rprint('new ' + self.__class__.__name__)
############################################
# Set ASSERT State
############################################
def
set_assert_state
(
self
,
new_state
:
AssertStateABC
):
with
self
.
get_state_lock
():
if
new_state
!=
self
.
_assert_state
:
self
.
_assert_state
=
new_state
self
.
change_tree
()
self
.
evaluate_ingroup
()
def
set_assert_winner_metric
(
self
,
new_assert_metric
:
AssertMetric
):
import
ipaddress
with
self
.
get_state_lock
():
try
:
old_neighbor
=
self
.
get_interface
().
get_neighbor
(
str
(
self
.
_assert_winner_metric
.
ip_address
))
new_neighbor
=
self
.
get_interface
().
get_neighbor
(
str
(
new_assert_metric
.
ip_address
))
if
old_neighbor
is
not
None
:
old_neighbor
.
unsubscribe_nlt_expiration
(
self
)
if
new_neighbor
is
not
None
:
new_neighbor
.
subscribe_nlt_expiration
(
self
)
'''
if new_assert_metric.ip_address == ipaddress.ip_address("0.0.0.0") or new_assert_metric.ip_address is None:
if old_neighbor is not None:
old_neighbor.unsubscribe_nlt_expiration(self)
else:
old_neighbor.unsubscribe_nlt_expiration(self)
new_neighbor.subscribe_nlt_expiration(self)
'''
finally
:
self
.
_assert_winner_metric
=
new_assert_metric
############################################
# ASSERT Timer
############################################
def
set_assert_timer
(
self
,
time
):
self
.
clear_assert_timer
()
self
.
_assert_timer
=
Timer
(
time
,
self
.
assert_timeout
)
self
.
_assert_timer
.
start
()
def
clear_assert_timer
(
self
):
if
self
.
_assert_timer
is
not
None
:
self
.
_assert_timer
.
cancel
()
def
assert_timeout
(
self
):
self
.
_assert_state
.
assertTimerExpires
(
self
)
def
recv_data_msg
(
self
):
pass
def
recv_assert_msg
(
self
):
pass
def
recv_assert_msg
(
self
,
received_metric
:
AssertMetric
):
if
self
.
_assert_winner_metric
.
is_better_than
(
received_metric
):
# received inferior assert
if
self
.
_assert_winner_metric
.
ip_address
==
received_metric
.
ip_address
:
# received from assert winner
self
.
_assert_state
.
receivedInferiorMetricFromWinner
(
self
)
elif
self
.
could_assert
():
# received from non assert winner and could_assert
self
.
_assert_state
.
receivedInferiorMetricFromNonWinner_couldAssertIsTrue
(
self
)
else
:
#received preferred assert
self
.
_assert_state
.
receivedPreferedMetric
(
self
,
received_metric
)
def
recv_reset_msg
(
self
):
pass
def
recv_prune_msg
(
self
):
pass
def
recv_prune_msg
(
self
,
upstream_neighbor_address
,
holdtime
):
if
upstream_neighbor_address
==
self
.
get_ip
():
self
.
_assert_state
.
receivedPruneOrJoinOrGraft
(
self
)
def
recv_join_msg
(
self
):
pass
def
recv_join_msg
(
self
,
upstream_neighbor_address
):
if
upstream_neighbor_address
==
self
.
get_ip
():
self
.
_assert_state
.
receivedPruneOrJoinOrGraft
(
self
)
def
recv_graft_msg
(
self
):
pass
def
recv_graft_msg
(
self
,
upstream_neighbor_address
):
if
upstream_neighbor_address
==
self
.
get_ip
():
self
.
_assert_state
.
receivedPruneOrJoinOrGraft
(
self
)
def
recv_graft_ack_msg
(
self
):
pass
...
...
@@ -139,12 +214,17 @@ class TreeInterface(metaclass=ABCMeta):
def
send_prune
(
self
):
def
send_prune
(
self
,
holdtime
=
None
):
if
holdtime
is
None
:
holdtime
=
T_LIMIT
print
(
"send prune"
)
try
:
(
source
,
group
)
=
self
.
get_tree_id
()
# todo help ip of ph
ph
=
PacketPimJoinPrune
(
"123.123.123.123"
,
210
)
#ph = PacketPimJoinPrune("123.123.123.123", 210)
ph
=
PacketPimJoinPrune
(
"123.123.123.123"
,
holdtime
)
ph
.
add_multicast_group
(
PacketPimJoinPruneMulticastGroup
(
group
,
pruned_src_addresses
=
[
source
]))
pckt
=
Packet
(
payload
=
PacketPimHeader
(
ph
))
...
...
@@ -155,13 +235,22 @@ class TreeInterface(metaclass=ABCMeta):
def
send_pruneecho
(
self
):
print
(
"send prune echo"
)
holdtime
=
T_LIMIT
try
:
(
source
,
group
)
=
self
.
get_tree_id
()
# todo help ip of ph
ph
=
PacketPimJoinPrune
(
self
.
get_ip
(),
holdtime
)
ph
.
add_multicast_group
(
PacketPimJoinPruneMulticastGroup
(
group
,
pruned_src_addresses
=
[
source
]))
pckt
=
Packet
(
payload
=
PacketPimHeader
(
ph
))
self
.
get_interface
().
send
(
pckt
.
bytes
())
print
(
"send prune echo"
)
except
:
return
# todo
#msg = PruneMsg(self.get_tree().tree_id,
# self.get_node(), self._assert_timer.time_left())
#self.pim_if.send_mcast(msg)
return
def
send_join
(
self
):
print
(
"send join"
)
...
...
@@ -183,17 +272,13 @@ class TreeInterface(metaclass=ABCMeta):
def
send_assert
(
self
):
print
(
"send assert"
)
import
UnicastRouting
try
:
(
source
,
group
)
=
self
.
get_tree_id
()
(
entry_protocol
,
entry_cost
)
=
UnicastRouting
.
get_metric
(
source
)
# todo help ip of ph
ph
=
PacketPimAssert
(
multicast_group_address
=
group
,
source_address
=
source
,
metric_preference
=
entry_protocol
,
metric
=
entry_cost
)
assert_metric
=
self
.
my_assert_metric
()
ph
=
PacketPimAssert
(
multicast_group_address
=
group
,
source_address
=
source
,
metric_preference
=
assert_metric
.
metric_preference
,
metric
=
assert_metric
.
route_metric
)
pckt
=
Packet
(
payload
=
PacketPimHeader
(
ph
))
self
.
get_interface
().
send
(
pckt
.
bytes
())
#msg = AssertMsg(self.tree_id, self.assert_metric)
#self.pim_if.send_mcast(msg)
except
:
return
...
...
@@ -201,22 +286,37 @@ class TreeInterface(metaclass=ABCMeta):
def
send_assert_cancel
(
self
):
print
(
"send cancel"
)
print
(
"send assert cancel"
)
try
:
(
source
,
group
)
=
self
.
get_tree_id
()
ph
=
PacketPimAssert
(
multicast_group_address
=
group
,
source_address
=
source
,
metric_preference
=
1
,
metric
=
float
(
"Inf"
))
pckt
=
Packet
(
payload
=
PacketPimHeader
(
ph
))
self
.
get_interface
().
send
(
pckt
.
bytes
())
except
:
return
#msg = AssertMsg.new_assert_cancel(self.tree_id)
#self.pim_if.send_mcast(msg)
pass
def
send_state_refresh
(
self
):
# todo time
self
.
_assert_state
.
sendStateRefresh
(
self
)
@
abstractmethod
def
is_forwarding
(
self
):
pass
def
nbr_died
(
self
,
node
):
def
nbr_died
(
self
):
pass
def
nbr_connected
(
self
):
pass
def
assert_winner_nlt_expires
(
self
):
self
.
_assert_state
.
winnerLivelinessTimerExpires
(
self
)
#@abstractmethod
def
is_now_root
(
self
):
pass
...
...
@@ -231,18 +331,24 @@ class TreeInterface(metaclass=ABCMeta):
def
evaluate_ingroup
(
self
):
self
.
_kernel_entry
.
evaluate_olist_change
()
#############################################################
# Local Membership (IGMP)
############################################################
def
notify_igmp
(
self
,
has_members
:
bool
):
with
self
.
get_state_lock
():
#with self._igmp_lock:
if
has_members
!=
self
.
_igmp_has_members
:
self
.
_igmp_has_members
=
has_members
self
.
change_tree
()
self
.
evaluate_ingroup
()
with
self
.
_igmp_lock
:
if
has_members
!=
self
.
_local_membership_state
.
has_members
():
#self._igmp_has_members = has_members
self
.
_local_membership_state
=
LocalMembership
.
Include
if
has_members
else
LocalMembership
.
NoInfo
self
.
change_tree
()
self
.
evaluate_ingroup
()
def
igmp_has_members
(
self
):
#with self._igmp_lock:
return
self
.
_igmp_has_members
with
self
.
_igmp_lock
:
#return self._igmp_has_members
return
self
.
_local_membership_state
.
has_members
()
def
rprint
(
self
,
msg
,
*
entrys
):
return
...
...
@@ -294,7 +400,41 @@ class TreeInterface(metaclass=ABCMeta):
if
not
self
.
is_assert_winner
():
return
self
.
_assert_winner_ip
else
:
return
self
.
_kernel_entry
.
_
rpf_node
return
self
.
_kernel_entry
.
rpf_node
def
is_assert_winner
(
self
):
return
not
self
.
is_downstream
()
and
not
self
.
_assert_state
==
AssertState
.
Loser
\ No newline at end of file
return
not
self
.
is_downstream
()
and
not
self
.
_assert_state
==
AssertState
.
Loser
def
is_S_directly_conn
(
self
):
return
self
.
_kernel_entry
.
rpf_node
==
self
.
_kernel_entry
.
source_ip
def
set_receceived_prune_holdtime
(
self
,
holdtime
):
self
.
_received_prune_holdtime
=
holdtime
def
get_received_prune_holdtime
(
self
):
return
self
.
_received_prune_holdtime
###################################################
# ASSERT
###################################################
def
lost_assert
(
self
):
if
not
self
.
is_downstream
():
return
False
else
:
return
not
AssertMetric
.
i_am_assert_winner
(
self
)
and
\
self
.
_assert_winner_metric
.
is_better_than
(
AssertMetric
.
spt_assert_metric
(
self
))
def
could_assert
(
self
):
return
self
.
is_downstream
()
def
my_assert_metric
(
self
):
'''
The assert metric of this interface for usage in assert state machine
@rtype: AssertMetric
'''
if
self
.
could_assert
():
return
AssertMetric
.
spt_assert_metric
(
self
)
else
:
return
AssertMetric
.
infinite_assert_metric
()
tree/upstream_prune.py
View file @
b5bd0d28
...
...
@@ -130,15 +130,12 @@ class UpstreamStateABC(metaclass=ABCMeta):
raise
NotImplementedError
()
class
AckPending
(
UpstreamStateABC
):
class
Forward
(
UpstreamStateABC
):
"""
AckPending (AP)
The router was in the Pruned(P) state, but a transition has
occurred in the Downstream(S,G) state machine for one of this
(S,G) entry’s outgoing interfaces, indicating that traffic from S
addressed to G should again be forwarded. A Graft message has
been sent to RPF’(S), but a Graft Ack message has not yet been
received.
Forwarding (F)
This is the starting state of the Upsteam(S,G) state machine.
The state machine is in this state if it just started or if
oiflist(S,G) != NULL.
"""
@
staticmethod
...
...
@@ -150,9 +147,19 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
if
not
interface
.
is_S_directly_conn
():
interface
.
set_state
(
UpstreamState
.
Pruned
)
#assert False
return
#interface.get_ot().stop()
#timer = interface._prune_limit_timer
#timer.set_timer(interface.t_override)
#timer.start()
interface
.
set_prune_limit_timer
()
interface
.
send_prune
()
print
(
"dataArrivesRPFinterface_OListNull_PLTstoped, F -> P"
)
@
staticmethod
def
stateRefreshArrivesRPFnbr_pruneIs1
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -165,7 +172,7 @@ class AckPending(UpstreamStateABC):
#interface.set_ot()
interface
.
set_override_timer
()
print
(
'stateRefreshArrivesRPFnbr_pruneIs1,
AP -> AP
'
)
print
(
'stateRefreshArrivesRPFnbr_pruneIs1,
F -> F
'
)
@
staticmethod
def
stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -177,13 +184,8 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
print
(
UpstreamState
.
Forward
)
interface
.
set_state
(
UpstreamState
.
Forward
)
#interface.get_grt().cancel()
interface
.
clear_graft_retry_timer
()
print
(
'stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped,
AP -> P
'
)
'stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped,
F -> F
'
)
@
staticmethod
def
seeJoinToRPFnbr
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -196,7 +198,7 @@ class AckPending(UpstreamStateABC):
#interface.cancel_ot()
interface
.
clear_override_timer
()
print
(
'seeJoinToRPFnbr,
P -> P
'
)
print
(
'seeJoinToRPFnbr,
F -> F
'
)
@
staticmethod
def
seePrune
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -205,11 +207,11 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#interface.set_ot()
interface
.
set_override_timer
()
if
not
interface
.
is_S_directly_conn
():
interface
.
set_override_timer
()
interface
.
rprint
(
'seePrune, AP -> AP
'
)
print
(
'seePrune, F -> F
'
)
@
staticmethod
def
OTexpires
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -218,9 +220,10 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
send_join
()
if
not
interface
.
is_S_directly_conn
():
interface
.
send_join
()
interface
.
rprint
(
'OTexpires, AP -> AP
'
)
print
(
'OTexpires, F -> F
'
)
@
staticmethod
def
olistIsNowNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -229,20 +232,18 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
set_state
(
UpstreamState
.
Pruned
)
#timer = interface._prune_limit_timer
#timer.set_timer(interface.t_override)
interface
.
set_prune_limit_timer
()
#timer.start()
print
(
"is direct con -> "
,
interface
.
is_S_directly_conn
())
if
not
interface
.
is_S_directly_conn
():
interface
.
set_state
(
UpstreamState
.
Pruned
)
#interface.get_grt().stop()
interface
.
clear_graft_retry_timer
()
#timer = interface._prune_limit_timer
#timer.set_timer(interface.t_override)
#timer.start()
interface
.
set_prune_limit_timer
()
interface
.
send_prune
()
interface
.
send_prune
()
print
(
"olistIsNowNull, AP
-> P"
)
print
(
"olistIsNowNull, F
-> P"
)
@
staticmethod
def
olistIsNowNotNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -263,12 +264,15 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
send_graft
()
if
not
interface
.
is_S_directly_conn
():
interface
.
send_graft
()
#interface.get_grt().rese
t()
interface
.
set_graft_retry_timer
()
#interface.get_grt().star
t()
interface
.
set_graft_retry_timer
()
print
(
'olistIsNowNotNull, AP -> AP'
)
interface
.
set_state
(
UpstreamState
.
AckPending
)
print
(
'RPFnbrChanges_olistIsNotNull, F -> AP'
)
@
staticmethod
def
RPFnbrChanges_olistIsNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -278,10 +282,9 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#interface.get_grt().cancel()
interface
.
clear_graft_retry_timer
()
interface
.
set_state
(
UpstreamState
.
Pruned
)
print
(
'RPFnbrChanges_olistIsNull,
AP
-> P'
)
print
(
'RPFnbrChanges_olistIsNull,
F
-> P'
)
@
staticmethod
def
sourceIsNowDirectConnect
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -290,11 +293,7 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
set_state
(
UpstreamState
.
Forward
)
#interface.get_grt().stop()
interface
.
clear_graft_retry_timer
()
print
(
"sourceIsNowDirectConnect, AP -> F"
)
print
(
"sourceIsNowDirectConnect, F -> F"
)
@
staticmethod
def
GRTexpires
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -303,12 +302,8 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#interface.get_grt().start()
interface
.
set_graft_retry_timer
()
interface
.
send_graft
()
print
(
'GRTexpires, AP -> AP'
)
#assert False
return
@
staticmethod
def
recvGraftAckFromRPFnbr
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -317,21 +312,15 @@ class AckPending(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
set_state
(
UpstreamState
.
Forward
)
#interface.get_grt().stop()
interface
.
clear_graft_retry_timer
()
print
(
'recvGraftAckFromRPFnbr, AP -> F'
)
print
(
'recvGraftAckFromRPFnbr, F -> F'
)
class
Forward
(
UpstreamStateABC
):
"""
Forwarding (F)
This is the starting state of the Upsteam(S,G) state machine.
The state machine is in this state if it just started or if
oiflist(S,G) != NULL.
"""
class
Pruned
(
UpstreamStateABC
):
'''
Pruned (P)
The set, olist(S,G), is empty.
The router will not forward data from S addressed to group G.
'''
@
staticmethod
def
dataArrivesRPFinterface_OListNull_PLTstoped
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -342,18 +331,17 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
set_state
(
UpstreamState
.
Pruned
)
if
not
interface
.
is_S_directly_conn
():
#interface.set_state(UpstreamState.Pruned)
#interface.get_ot().stop()
#timer = interface._prune_limit_timer
#timer.set_timer(interface.t_override)
#timer.start()
interface
.
set_prune_limit_timer
()
# todo send prune?!?!?!?!
interface
.
send_prune
()
#timer = interface._prune_limit_timer
#timer.set_timer(interface.t_override)
#timer.start()
interface
.
set_prune_limit_timer
()
print
(
"dataArrivesRPFinterface_OListNull_PLTstoped, F
-> P"
)
print
(
"dataArrivesRPFinterface_OListNull_PLTstoped, P
-> P"
)
@
staticmethod
def
stateRefreshArrivesRPFnbr_pruneIs1
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -363,10 +351,10 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#interface.
set_o
t()
interface
.
set_
override
_timer
()
#interface.
get_plt().rese
t()
interface
.
set_
prune_limit
_timer
()
print
(
'stateRefreshArrivesRPFnbr_pruneIs1, F -> F
'
)
interface
.
rprint
(
'stateRefreshArrivesRPFnbr_pruneIs1, P -> P
'
)
@
staticmethod
def
stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -377,9 +365,16 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
# todo: desnecessario pq PLT stopped????!!!
#plt = interface.get_plt()
#if not plt.is_ticking():
# plt.start()
# interface.send_prune()
interface
.
send_prune
()
interface
.
set_prune_limit_timer
()
print
(
'stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped,
F -> F
'
)
'stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped,
P -> P
'
)
@
staticmethod
def
seeJoinToRPFnbr
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -388,11 +383,9 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
# Do nothing
#interface.cancel_ot()
interface
.
clear_override_timer
()
print
(
'seeJoinToRPFnbr, F -> F'
)
print
(
'seeJoinToRPFnbr, P -> P'
)
@
staticmethod
def
seePrune
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -401,10 +394,8 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#interface.set_ot()
interface
.
set_override_timer
()
print
(
'seePrune,
F -> F
'
)
print
(
'seePrune,
P -> P
'
)
@
staticmethod
def
OTexpires
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -413,9 +404,9 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
send_join
()
print
(
'OTexpires, F -> F'
)
#assert False
return
@
staticmethod
def
olistIsNowNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -424,16 +415,8 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
set_state
(
UpstreamState
.
Pruned
)
#timer = interface._prune_limit_timer
#timer.set_timer(interface.t_override)
#timer.start()
interface
.
set_prune_limit_timer
()
interface
.
send_prune
()
print
(
"olistIsNowNull, F -> P"
)
#assert False
return
@
staticmethod
def
olistIsNowNotNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -442,8 +425,15 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#assert False
return
if
not
interface
.
is_S_directly_conn
():
interface
.
send_graft
()
#interface.get_grt().start()
interface
.
set_graft_retry_timer
()
interface
.
set_state
(
UpstreamState
.
AckPending
)
print
(
'olistIsNowNotNull, P -> AP'
)
@
staticmethod
def
RPFnbrChanges_olistIsNotNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -454,14 +444,15 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
send_graft
()
if
not
interface
.
is_S_directly_conn
():
interface
.
send_graft
()
#interface.get_grt().start()
interface
.
set_graft_retry_timer
()
#interface.get_grt().start()
interface
.
set_graft_retry_timer
()
interface
.
set_state
(
UpstreamState
.
AckPending
)
interface
.
set_state
(
UpstreamState
.
AckPending
)
print
(
'RPFnbrChanges_olistIsNotNull, F
-> AP'
)
print
(
'olistIsNowNotNull, P
-> AP'
)
@
staticmethod
def
RPFnbrChanges_olistIsNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -471,9 +462,11 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
set_state
(
UpstreamState
.
Pruned
)
#interface.get_plt().stop()
if
not
interface
.
is_S_directly_conn
():
interface
.
clear_prune_limit_timer
()
print
(
'RPFnbrChanges_olistIsNull, F
-> P'
)
print
(
'RPFnbrChanges_olistIsNull, P
-> P'
)
@
staticmethod
def
sourceIsNowDirectConnect
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -482,7 +475,7 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
print
(
"sourceIsNowDirectConnect,
F -> F
"
)
print
(
"sourceIsNowDirectConnect,
P -> P
"
)
@
staticmethod
def
GRTexpires
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -501,15 +494,19 @@ class Forward(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
print
(
'recvGraftAckFromRPFnbr, P -> P'
)
print
(
'recvGraftAckFromRPFnbr, P -> P'
)
class
Pruned
(
UpstreamStateABC
):
'''
Pruned (P)
The set, olist(S,G), is empty.
The router will not forward data from S addressed to group G.
'''
class
AckPending
(
UpstreamStateABC
):
"""
AckPending (AP)
The router was in the Pruned(P) state, but a transition has
occurred in the Downstream(S,G) state machine for one of this
(S,G) entry’s outgoing interfaces, indicating that traffic from S
addressed to G should again be forwarded. A Graft message has
been sent to RPF’(S), but a Graft Ack message has not yet been
received.
"""
@
staticmethod
def
dataArrivesRPFinterface_OListNull_PLTstoped
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -520,16 +517,9 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
set_state
(
UpstreamState
.
Pruned
)
# todo send prune?!?!?!?!
#timer = interface._prune_limit_timer
#timer.set_timer(interface.t_override)
#timer.start()
interface
.
set_prune_limit_timer
()
print
(
"dataArrivesRPFinterface_OListNull_PLTstoped, P -> P"
)
#assert False
return
@
staticmethod
def
stateRefreshArrivesRPFnbr_pruneIs1
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -539,10 +529,10 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#interface.
get_plt().rese
t()
interface
.
set_
prune_limit
_timer
()
#interface.
set_o
t()
interface
.
set_
override
_timer
()
interface
.
rprint
(
'stateRefreshArrivesRPFnbr_pruneIs1, P ->
P'
)
print
(
'stateRefreshArrivesRPFnbr_pruneIs1, AP -> A
P'
)
@
staticmethod
def
stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -553,16 +543,13 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
# todo: desnecessario pq PLT stopped????!!!
#plt = interface.get_plt()
#if not plt.is_ticking():
# plt.start()
# interface.send_prune()
interface
.
send_prune
()
interface
.
set_prune_limit_timer
()
interface
.
set_state
(
UpstreamState
.
Forward
)
#interface.get_grt().cancel()
interface
.
clear_graft_retry_timer
()
print
(
'stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped, P -> P'
)
'stateRefreshArrivesRPFnbr_pruneIs0_PLTstoped,
A
P -> P'
)
@
staticmethod
def
seeJoinToRPFnbr
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -571,9 +558,11 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
# Do nothing
print
(
'seeJoinToRPFnbr, P -> P'
)
#interface.cancel_ot()
interface
.
clear_override_timer
()
print
(
'seeJoinToRPFnbr, AP -> AP'
)
@
staticmethod
def
seePrune
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -583,7 +572,10 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
print
(
'seePrune, P -> P'
)
#interface.set_ot()
interface
.
set_override_timer
()
interface
.
rprint
(
'seePrune, AP -> AP'
)
@
staticmethod
def
OTexpires
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -592,9 +584,9 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
send_join
()
#assert False
return
interface
.
rprint
(
'OTexpires, AP -> AP'
)
@
staticmethod
def
olistIsNowNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -603,8 +595,20 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#assert False
return
interface
.
set_state
(
UpstreamState
.
Pruned
)
#timer = interface._prune_limit_timer
#timer.set_timer(interface.t_override)
interface
.
set_prune_limit_timer
()
#timer.start()
#interface.get_grt().stop()
interface
.
clear_graft_retry_timer
()
interface
.
send_prune
()
print
(
"olistIsNowNull, AP -> P"
)
@
staticmethod
def
olistIsNowNotNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -613,14 +617,8 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
send_graft
()
#interface.get_grt().start()
interface
.
set_graft_retry_timer
()
interface
.
set_state
(
UpstreamState
.
AckPending
)
print
(
'olistIsNowNotNull, P -> AP'
)
#assert False
return
@
staticmethod
def
RPFnbrChanges_olistIsNotNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -631,14 +629,13 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
interface
.
send_graft
()
#interface.get_grt().start()
interface
.
set_graft_retry_timer
()
if
not
interface
.
is_S_directly_conn
():
interface
.
send_graft
()
interface
.
set_state
(
UpstreamState
.
AckPending
)
#interface.get_grt().reset()
interface
.
set_graft_retry_timer
()
print
(
'olistIsNowNotNull,
P -> AP'
)
print
(
'olistIsNowNotNull, A
P -> AP'
)
@
staticmethod
def
RPFnbrChanges_olistIsNull
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -648,10 +645,11 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#interface.get_plt().stop()
interface
.
clear_prune_limit_timer
()
#interface.get_grt().cancel()
if
not
interface
.
is_S_directly_conn
():
interface
.
clear_graft_retry_timer
()
print
(
'RPFnbrChanges_olistIsNull,
P -> P'
)
print
(
'RPFnbrChanges_olistIsNull, A
P -> P'
)
@
staticmethod
def
sourceIsNowDirectConnect
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -660,7 +658,11 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
print
(
"sourceIsNowDirectConnect, P -> P"
)
interface
.
set_state
(
UpstreamState
.
Forward
)
#interface.get_grt().stop()
interface
.
clear_graft_retry_timer
()
print
(
"sourceIsNowDirectConnect, AP -> F"
)
@
staticmethod
def
GRTexpires
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -669,8 +671,12 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
#assert False
return
#interface.get_grt().start()
interface
.
set_graft_retry_timer
()
interface
.
send_graft
()
print
(
'GRTexpires, AP -> AP'
)
@
staticmethod
def
recvGraftAckFromRPFnbr
(
interface
:
"TreeInterfaceUpstream"
):
...
...
@@ -680,8 +686,11 @@ class Pruned(UpstreamStateABC):
@type interface: TreeInterfaceUpstream
"""
print
(
'recvGraftAckFromRPFnbr, P -> P'
)
interface
.
set_state
(
UpstreamState
.
Forward
)
#interface.get_grt().stop()
interface
.
clear_graft_retry_timer
()
print
(
'recvGraftAckFromRPFnbr, AP -> F'
)
class
UpstreamState
():
Forward
=
Forward
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment