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
f91a2e1a
Commit
f91a2e1a
authored
Jun 26, 2017
by
Pedro Oliveira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
deamonized program and can interact with daemon program
parent
4e436aa9
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
326 additions
and
115 deletions
+326
-115
Daemon/Daemon.py
Daemon/Daemon.py
+123
-0
Daemon/__init__.py
Daemon/__init__.py
+0
-0
Hello.py
Hello.py
+7
-8
Interface.py
Interface.py
+2
-2
Main.py
Main.py
+77
-81
Neighbor.py
Neighbor.py
+2
-3
Run.py
Run.py
+115
-21
No files found.
Daemon/Daemon.py
0 → 100644
View file @
f91a2e1a
"""Generic linux daemon base class for python 3.x."""
import
sys
,
os
,
time
,
atexit
,
signal
class
Daemon
:
"""A generic Daemon class.
Usage: subclass the Daemon class and override the run() method."""
def
__init__
(
self
,
pidfile
):
self
.
pidfile
=
pidfile
def
daemonize
(
self
):
"""Deamonize class. UNIX double fork mechanism."""
try
:
pid
=
os
.
fork
()
if
pid
>
0
:
# exit first parent
sys
.
exit
(
0
)
except
OSError
as
err
:
sys
.
stderr
.
write
(
'fork #1 failed: {0}
\
n
'
.
format
(
err
))
sys
.
exit
(
1
)
# decouple from parent environment
#os.chdir('/')
#os.setsid()
#os.umask(0)
# do second fork
try
:
pid
=
os
.
fork
()
if
pid
>
0
:
# exit from second parent
sys
.
exit
(
0
)
except
OSError
as
err
:
sys
.
stderr
.
write
(
'fork #2 failed: {0}
\
n
'
.
format
(
err
))
sys
.
exit
(
1
)
# redirect standard file descriptors
sys
.
stdout
.
flush
()
sys
.
stderr
.
flush
()
si
=
open
(
os
.
devnull
,
'r'
)
so
=
open
(
'stdout'
,
'a+'
)
se
=
open
(
os
.
devnull
,
'a+'
)
os
.
dup2
(
si
.
fileno
(),
sys
.
stdin
.
fileno
())
os
.
dup2
(
so
.
fileno
(),
sys
.
stdout
.
fileno
())
os
.
dup2
(
se
.
fileno
(),
sys
.
stderr
.
fileno
())
# write pidfile
atexit
.
register
(
self
.
delpid
)
pid
=
str
(
os
.
getpid
())
with
open
(
self
.
pidfile
,
'w+'
)
as
f
:
f
.
write
(
pid
+
'
\
n
'
)
def
delpid
(
self
):
os
.
remove
(
self
.
pidfile
)
def
start
(
self
):
"""Start the Daemon."""
# Check for a pidfile to see if the Daemon already runs
try
:
with
open
(
self
.
pidfile
,
'r'
)
as
pf
:
pid
=
int
(
pf
.
read
().
strip
())
except
IOError
:
pid
=
None
if
pid
:
message
=
"pidfile {0} already exist. "
+
\
"Daemon already running?
\
n
"
sys
.
stderr
.
write
(
message
.
format
(
self
.
pidfile
))
sys
.
exit
(
1
)
# Start the Daemon
self
.
daemonize
()
print
(
"daemonize"
)
self
.
run
()
def
stop
(
self
):
"""Stop the Daemon."""
# Get the pid from the pidfile
try
:
with
open
(
self
.
pidfile
,
'r'
)
as
pf
:
pid
=
int
(
pf
.
read
().
strip
())
except
IOError
:
pid
=
None
if
not
pid
:
message
=
"pidfile {0} does not exist. "
+
\
"Daemon not running?
\
n
"
sys
.
stderr
.
write
(
message
.
format
(
self
.
pidfile
))
return
# not an error in a restart
# Try killing the Daemon process
try
:
while
1
:
os
.
kill
(
pid
,
signal
.
SIGTERM
)
time
.
sleep
(
0.1
)
except
OSError
as
err
:
e
=
str
(
err
.
args
)
if
e
.
find
(
"No such process"
)
>
0
:
if
os
.
path
.
exists
(
self
.
pidfile
):
os
.
remove
(
self
.
pidfile
)
else
:
print
(
str
(
err
.
args
))
sys
.
exit
(
1
)
def
restart
(
self
):
"""Restart the Daemon."""
self
.
stop
()
self
.
start
()
def
run
(
self
):
"""You should override this method when you subclass Daemon.
It will be called after the process has been daemonized by
start() or restart()."""
\ No newline at end of file
Daemon/__init__.py
0 → 100644
View file @
f91a2e1a
Hello.py
View file @
f91a2e1a
...
...
@@ -5,7 +5,7 @@ from Packet.ReceivedPacket import ReceivedPacket
from
Packet.PacketPimOption
import
PacketPimOption
from
Packet.PacketPimHeader
import
PacketPimHeader
from
Interface
import
Interface
from
Main
import
Main
import
Main
from
utils
import
KEEP_ALIVE_PERIOD_TIMEOUT
...
...
@@ -14,13 +14,13 @@ class Hello:
TRIGGERED_HELLO_DELAY
=
16
# TODO: configure via external file??
def
__init__
(
self
):
Main
()
.
add_protocol
(
Hello
.
TYPE
,
self
)
Main
.
add_protocol
(
Hello
.
TYPE
,
self
)
self
.
thread
=
Timer
(
Hello
.
TRIGGERED_HELLO_DELAY
,
self
.
send_handle
)
self
.
thread
.
start
()
def
send_handle
(
self
):
for
(
ip
,
interface
)
in
list
(
Main
()
.
interfaces
.
items
()):
for
(
ip
,
interface
)
in
list
(
Main
.
interfaces
.
items
()):
self
.
packet_send_handle
(
interface
)
# reschedule timer
...
...
@@ -55,19 +55,18 @@ class Hello:
ip
=
packet
.
ip_header
.
ip
print
(
"ip = "
,
ip
)
main
=
Main
()
options
=
packet
.
pim_header
.
get_options
()
if
m
ain
.
get_neighbor
(
ip
)
is
None
:
if
M
ain
.
get_neighbor
(
ip
)
is
None
:
# Unknown Neighbor
if
(
1
in
options
)
and
(
20
in
options
):
print
(
"non neighbor and options inside"
)
m
ain
.
add_neighbor
(
packet
.
interface
,
ip
,
options
[
20
],
options
[
1
])
M
ain
.
add_neighbor
(
packet
.
interface
,
ip
,
options
[
20
],
options
[
1
])
return
print
(
"non neighbor and required options not inside"
)
else
:
# Already know Neighbor
print
(
"neighbor conhecido"
)
neighbor
=
m
ain
.
get_neighbor
(
ip
)
neighbor
=
M
ain
.
get_neighbor
(
ip
)
neighbor
.
heartbeat
()
if
1
in
options
and
neighbor
.
keep_alive_period
!=
options
[
1
]:
print
(
"keep alive period diferente"
)
...
...
@@ -75,4 +74,4 @@ class Hello:
if
20
in
options
and
neighbor
.
generation_id
!=
options
[
20
]:
print
(
"neighbor reiniciado"
)
neighbor
.
remove
()
m
ain
.
add_neighbor
(
packet
.
interface
,
ip
,
options
[
20
],
options
[
1
])
M
ain
.
add_neighbor
(
packet
.
interface
,
ip
,
options
[
20
],
options
[
1
])
Interface.py
View file @
f91a2e1a
...
...
@@ -2,6 +2,7 @@ import socket
import
threading
import
random
from
Packet.ReceivedPacket
import
ReceivedPacket
import
Main
class
Interface
:
#IF_IP = "10.0.0.1"
...
...
@@ -38,7 +39,6 @@ class Interface:
receive_thread
.
start
()
def
receive
(
self
):
from
Main
import
Main
while
self
.
interface_enabled
:
try
:
(
raw_packet
,
(
ip
,
p
))
=
self
.
socket
.
recvfrom
(
256
*
1024
)
...
...
@@ -46,7 +46,7 @@ class Interface:
#print("packet received bytes: ", packet.bytes())
#print("pim type received = ", packet.pim_header.msg_type)
#print("generation id received = ", packet.pim_header.options[1].option_value)
Main
()
.
protocols
[
packet
.
pim_header
.
msg_type
].
receive_handle
(
packet
)
# TODO: perceber se existe melhor maneira de fazer isto
Main
.
protocols
[
packet
.
pim_header
.
msg_type
].
receive_handle
(
packet
)
# TODO: perceber se existe melhor maneira de fazer isto
except
Exception
:
pass
...
...
Main.py
View file @
f91a2e1a
...
...
@@ -4,85 +4,81 @@ from Interface import Interface
from
Neighbor
import
Neighbor
class
Main
(
object
):
class
__Main
:
def
__init__
(
self
):
self
.
interfaces
=
{}
# interfaces with multicast routing enabled
self
.
neighbors
=
{}
# multicast router neighbors
self
.
protocols
=
{}
def
add_interface
(
self
,
ip
):
if
ip
not
in
self
.
interfaces
:
interface
=
Interface
(
ip
)
self
.
interfaces
[
ip
]
=
interface
self
.
protocols
[
0
].
force_send
(
interface
)
# TODO: verificar melhor este metodo:
def
remove_interface
(
self
,
ip
):
# TODO remover neighbors desta interface
if
ip
in
self
.
interfaces
:
for
(
ip_neighbor
,
neighbor
)
in
list
(
self
.
neighbors
.
items
()):
# TODO ver melhor este algoritmo
if
neighbor
.
contact_interface
==
self
.
interfaces
[
ip
]:
neighbor
.
remove
()
self
.
protocols
[
0
].
force_send_remove
(
self
.
interfaces
[
ip
])
self
.
interfaces
[
ip
].
remove
()
del
self
.
interfaces
[
ip
]
print
(
"removido interface"
)
def
add_neighbor
(
self
,
contact_interface
,
ip
,
random_number
,
keep_alive_period
):
if
ip
not
in
self
.
neighbors
:
print
(
"ADD NEIGHBOR"
)
self
.
neighbors
[
ip
]
=
Neighbor
(
contact_interface
,
ip
,
random_number
,
keep_alive_period
)
self
.
protocols
[
0
].
force_send
(
contact_interface
)
def
get_neighbor
(
self
,
ip
)
->
Neighbor
:
if
ip
not
in
self
.
neighbors
:
return
None
return
self
.
neighbors
[
ip
]
def
remove_neighbor
(
self
,
ip
):
if
ip
in
self
.
neighbors
:
del
self
.
neighbors
[
ip
]
print
(
"removido neighbor"
)
def
add_protocol
(
self
,
protocol_number
,
protocol_obj
):
self
.
protocols
[
protocol_number
]
=
protocol_obj
def
list_neighbors
(
self
):
t
=
PrettyTable
([
'Neighbor IP'
,
'KeepAlive'
,
"Generation ID"
])
for
ip
,
neighbor
in
list
(
self
.
neighbors
.
items
()):
import
socket
,
struct
# TODO atualmente conversao manual de numero para string ip
ip
=
socket
.
inet_ntoa
(
struct
.
pack
(
'!L'
,
ip
))
t
.
add_row
([
ip
,
neighbor
.
keep_alive_period
,
neighbor
.
generation_id
])
print
(
t
)
def
list_enabled_interfaces
(
self
):
t
=
PrettyTable
([
'Interface'
,
'IP'
,
'Enabled'
])
for
interface
in
netifaces
.
interfaces
():
# TODO: fix same interface with multiple ips
ip
=
netifaces
.
ifaddresses
(
interface
)[
netifaces
.
AF_INET
][
0
][
'addr'
]
status
=
ip
in
self
.
interfaces
t
.
add_row
([
interface
,
ip
,
status
])
print
(
t
)
def
main
(
self
,
ip_interfaces_to_add
):
from
Hello
import
Hello
Hello
()
for
ip
in
ip_interfaces_to_add
:
self
.
add_interface
(
ip
)
# MAIN SINGLETON
instance
=
None
def
__new__
(
cls
):
# __new__ always a classmethod
if
not
Main
.
instance
:
Main
.
instance
=
Main
.
__Main
()
return
Main
.
instance
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
instance
,
name
)
def
__setattr__
(
self
,
name
):
return
setattr
(
self
.
instance
,
name
)
interfaces
=
{}
# interfaces with multicast routing enabled
neighbors
=
{}
# multicast router neighbors
protocols
=
{}
def
add_interface
(
ip
):
global
interfaces
if
ip
not
in
interfaces
:
interface
=
Interface
(
ip
)
interfaces
[
ip
]
=
interface
protocols
[
0
].
force_send
(
interface
)
# TODO: verificar melhor este metodo:
def
remove_interface
(
ip
):
# TODO remover neighbors desta interface
global
interfaces
global
neighbors
if
ip
in
interfaces
:
for
(
ip_neighbor
,
neighbor
)
in
list
(
neighbors
.
items
()):
# TODO ver melhor este algoritmo
if
neighbor
.
contact_interface
==
interfaces
[
ip
]:
neighbor
.
remove
()
protocols
[
0
].
force_send_remove
(
interfaces
[
ip
])
interfaces
[
ip
].
remove
()
del
interfaces
[
ip
]
print
(
"removido interface"
)
def
add_neighbor
(
contact_interface
,
ip
,
random_number
,
keep_alive_period
):
global
neighbors
if
ip
not
in
neighbors
:
print
(
"ADD NEIGHBOR"
)
neighbors
[
ip
]
=
Neighbor
(
contact_interface
,
ip
,
random_number
,
keep_alive_period
)
protocols
[
0
].
force_send
(
contact_interface
)
def
get_neighbor
(
ip
)
->
Neighbor
:
global
neighbors
if
ip
not
in
neighbors
:
return
None
return
neighbors
[
ip
]
def
remove_neighbor
(
ip
):
global
neighbors
if
ip
in
neighbors
:
del
neighbors
[
ip
]
print
(
"removido neighbor"
)
def
add_protocol
(
protocol_number
,
protocol_obj
):
global
protocols
protocols
[
protocol_number
]
=
protocol_obj
def
list_neighbors
():
global
neighbors
t
=
PrettyTable
([
'Neighbor IP'
,
'KeepAlive'
,
"Generation ID"
])
for
ip
,
neighbor
in
list
(
neighbors
.
items
()):
import
socket
,
struct
# TODO atualmente conversao manual de numero para string ip
ip
=
socket
.
inet_ntoa
(
struct
.
pack
(
'!L'
,
ip
))
t
.
add_row
([
ip
,
neighbor
.
keep_alive_period
,
neighbor
.
generation_id
])
print
(
t
)
return
str
(
t
)
def
list_enabled_interfaces
():
global
interfaces
t
=
PrettyTable
([
'Interface'
,
'IP'
,
'Enabled'
])
for
interface
in
netifaces
.
interfaces
():
# TODO: fix same interface with multiple ips
ip
=
netifaces
.
ifaddresses
(
interface
)[
netifaces
.
AF_INET
][
0
][
'addr'
]
status
=
ip
in
interfaces
t
.
add_row
([
interface
,
ip
,
status
])
print
(
t
)
return
str
(
t
)
def
main
(
ip_interfaces_to_add
=
[]):
from
Hello
import
Hello
Hello
()
for
ip
in
ip_interfaces_to_add
:
add_interface
(
ip
)
Neighbor.py
View file @
f91a2e1a
from
threading
import
Timer
from
utils
import
KEEP_ALIVE_PERIOD_NO_TIMEOUT
,
KEEP_ALIVE_PERIOD_TIMEOUT
from
Interface
import
Interface
import
Main
class
Neighbor
:
def
__init__
(
self
,
contact_interface
:
Interface
,
ip
,
generation_id
:
int
,
keep_alive_period
:
int
):
...
...
@@ -34,8 +34,7 @@ class Neighbor:
self
.
neighbor_liveness_timer
.
start
()
def
remove
(
self
):
from
Main
import
Main
print
(
'HELLO TIMER EXPIRED... remove neighbor'
)
if
self
.
neighbor_liveness_timer
is
not
None
:
self
.
neighbor_liveness_timer
.
cancel
()
Main
()
.
remove_neighbor
(
self
.
ip
)
Main
.
remove_neighbor
(
self
.
ip
)
Run.py
View file @
f91a2e1a
import
time
from
Main
import
Main
#indicar ips das interfaces pim
m
=
Main
()
m
.
main
([
"10.0.0.1"
])
'''
from Packet.PacketPimHeader import *
ph = PacketPimHeader(0)
po = PacketPimOption(1, 12408)
ph.add_option(po)
ph.add_option(PacketPimOption(20, 813183289))
packet = Packet(pim_header=ph)
m.interfaces["10.0.0.1"].send(packet.bytes())'''
'''for i in range(0, 5):
m.list_enabled_interfaces()
m.list_neighbors()
time.sleep(10)'''
time
.
sleep
(
30
)
m
.
remove_interface
(
"10.0.0.1"
)
time
.
sleep
(
100
)
#!/usr/bin/env python
from
Daemon.Daemon
import
Daemon
import
Main
import
_pickle
as
pickle
import
socket
import
sys
import
os
import
argparse
class
MyDaemon
(
Daemon
):
def
run
(
self
):
Main
.
main
()
server_address
=
'./uds_socket'
# Make sure the socket does not already exist
try
:
os
.
unlink
(
server_address
)
except
OSError
:
if
os
.
path
.
exists
(
server_address
):
raise
# Create a UDS socket
sock
=
socket
.
socket
(
socket
.
AF_UNIX
,
socket
.
SOCK_STREAM
)
# Bind the socket to the port
sock
.
bind
(
server_address
)
# Listen for incoming connections
sock
.
listen
(
1
)
while
True
:
try
:
connection
,
client_address
=
sock
.
accept
()
data
=
connection
.
recv
(
256
*
1024
)
print
(
sys
.
stderr
,
'sending data back to the client'
)
print
(
pickle
.
loads
(
data
))
args
=
pickle
.
loads
(
data
)
if
args
.
list_interfaces
:
connection
.
sendall
(
pickle
.
dumps
(
Main
.
list_enabled_interfaces
()))
elif
args
.
list_neighbors
:
connection
.
sendall
(
pickle
.
dumps
(
Main
.
list_neighbors
()))
elif
args
.
add_interface
:
Main
.
add_interface
(
args
.
add_interface
[
0
])
connection
.
sendall
(
pickle
.
dumps
(
''
))
elif
args
.
remove_interface
:
Main
.
remove_interface
(
args
.
remove_interface
[
0
])
connection
.
sendall
(
pickle
.
dumps
(
''
))
finally
:
# Clean up the connection
connection
.
close
()
if
__name__
==
"__main__"
:
parser
=
argparse
.
ArgumentParser
(
description
=
'PIM'
)
parser
.
add_argument
(
"-li"
,
"--list_interfaces"
,
action
=
"store_true"
,
default
=
False
,
help
=
"List All PIM Interfaces"
)
parser
.
add_argument
(
"-ln"
,
"--list_neighbors"
,
action
=
"store_true"
,
default
=
False
,
help
=
"List All PIM Neighbors"
)
parser
.
add_argument
(
"-ai"
,
"--add_interface"
,
nargs
=
1
,
help
=
"Add PIM interface"
)
parser
.
add_argument
(
"-ri"
,
"--remove_interface"
,
nargs
=
1
,
help
=
"Remove PIM interface"
)
parser
.
add_argument
(
"-start"
,
"--start"
,
action
=
"store_true"
,
default
=
False
,
help
=
"Start PIM"
)
parser
.
add_argument
(
"-stop"
,
"--stop"
,
action
=
"store_true"
,
default
=
False
,
help
=
"Stop PIM"
)
parser
.
add_argument
(
"-restart"
,
"--restart"
,
action
=
"store_true"
,
default
=
False
,
help
=
"Restart PIM"
)
parser
.
add_argument
(
"-v"
,
"--verbose"
,
action
=
"store_true"
,
default
=
False
,
help
=
"Verbose (print all debug messages)"
)
args
=
parser
.
parse_args
()
print
(
parser
.
parse_args
())
daemon
=
MyDaemon
(
'/tmp/Daemon-pim.pid'
)
if
args
.
start
:
print
(
"start"
)
daemon
.
start
()
print
(
"start"
)
sys
.
exit
(
0
)
elif
args
.
stop
:
daemon
.
stop
()
sys
.
exit
(
0
)
elif
args
.
restart
:
daemon
.
restart
()
sys
.
exit
(
0
)
elif
args
.
verbose
:
os
.
system
(
"tailf stdout"
)
sys
.
exit
(
0
)
# Create a UDS socket
sock
=
socket
.
socket
(
socket
.
AF_UNIX
,
socket
.
SOCK_STREAM
)
# Connect the socket to the port where the server is listening
server_address
=
'./uds_socket'
print
(
'connecting to %s'
%
server_address
)
try
:
sock
.
connect
(
server_address
)
except
(
socket
.
error
):
print
(
"erro socket"
)
print
(
sys
.
stderr
)
sys
.
exit
(
1
)
try
:
sock
.
sendall
(
pickle
.
dumps
(
args
))
data
=
sock
.
recv
(
1024
*
256
)
print
(
pickle
.
loads
(
data
))
finally
:
print
(
'closing socket'
)
sock
.
close
()
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