Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
R
re6stnet
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Rafael Monnerat
re6stnet
Commits
b1e97826
Commit
b1e97826
authored
Aug 29, 2012
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bugfixes
parent
b3cb14da
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
202 additions
and
199 deletions
+202
-199
docs/re6st-registry.rst
docs/re6st-registry.rst
+1
-0
docs/re6stnet.rst
docs/re6stnet.rst
+15
-11
re6st-registry
re6st-registry
+22
-25
re6st/db.py
re6st/db.py
+22
-18
re6st/plib.py
re6st/plib.py
+31
-17
re6st/tunnel.py
re6st/tunnel.py
+7
-14
re6st/upnpigd.py
re6st/upnpigd.py
+29
-38
re6st/utils.py
re6st/utils.py
+12
-1
re6stnet
re6stnet
+63
-75
No files found.
docs/re6st-registry.rst
View file @
b1e97826
...
@@ -33,6 +33,7 @@ request.
...
@@ -33,6 +33,7 @@ request.
--port port
--port port
The port on which the server will listen
The port on which the server will listen
Default: 80
--db path
--db path
Path to the server Database file. A new DB file will be created
Path to the server Database file. A new DB file will be created
...
...
docs/re6stnet.rst
View file @
b1e97826
...
@@ -72,10 +72,10 @@ Generic options
...
@@ -72,10 +72,10 @@ Generic options
file ( since it is an optioin, it must be alone on the line ).
file ( since it is an optioin, it must be alone on the line ).
--ip address port proto
--ip address port proto
Specify connection information to be advertised to other nodes.
IP address advertised to other nodes. Special values:
address MUST be a ipv4 address since as of now openvpn does not
- upnp: force autoconfiguration via UPnP
support ipv6 addresses.
- any: ask peers our IP
Proto should be either udp or tcp-client
Default: ask peers if UPnP fails
-l, ``--log`` `directory`
-l, ``--log`` `directory`
Path to the directory used for log files. Will create one file
Path to the directory used for log files. Will create one file
...
@@ -103,6 +103,12 @@ Generic options
...
@@ -103,6 +103,12 @@ Generic options
Babel options
Babel options
~~~~~~~~~~~~~
~~~~~~~~~~~~~
--babel-pidfile
Specify a file to write our process id to (option -I of Babel).
--babel-verb
Babel verbosity (option -d of Babel).
-i, ``--interface`` `interface`
-i, ``--interface`` `interface`
Give one interface name for each use of the argument. The interface
Give one interface name for each use of the argument. The interface
will be used to detect other nodes on the local network.
will be used to detect other nodes on the local network.
...
@@ -135,13 +141,11 @@ Tunnel & Peers options
...
@@ -135,13 +141,11 @@ Tunnel & Peers options
Default : 3600 ( 1 hour )
Default : 3600 ( 1 hour )
--pp port proto
--pp port proto
Port and protocol used by the openvpn server(s). Start one openvpn
Port and protocol to be announced to other peers, ordered by
server for each couple port/protocol specified.
preference. For each protocol, start one openvpn server on the
Additionally, if no external configuration is given in the command
first given port.
line, re6stnet will attempt to forward a port with upnp for each
Protocols: udp, tcp
couple port/proto given.
Default : --pp 1194 udp --pp 1194 tcp
Protocols should be either udp or tcp-server.
Default : (1194, udp), (1194, tcp-server)
--tunnel-refresh duration
--tunnel-refresh duration
Interval in seconds between two tunnel refresh. Refreshing tunnels
Interval in seconds between two tunnel refresh. Refreshing tunnels
...
...
re6st-registry
View file @
b1e97826
#!/usr/bin/env python
#!/usr/bin/env python
import
argparse
,
random
,
select
,
smtplib
,
sqlite3
,
string
,
socket
import
random
,
select
,
smtplib
,
sqlite3
,
string
,
socket
import
subprocess
,
time
,
threading
,
traceback
,
errno
,
logging
,
os
,
xmlrpclib
import
subprocess
,
time
,
threading
,
traceback
,
errno
,
logging
,
os
,
xmlrpclib
from
SimpleXMLRPCServer
import
SimpleXMLRPCServer
,
SimpleXMLRPCRequestHandler
from
SimpleXMLRPCServer
import
SimpleXMLRPCServer
,
SimpleXMLRPCRequestHandler
from
email.mime.text
import
MIMEText
from
email.mime.text
import
MIMEText
...
@@ -15,18 +15,18 @@ SOL_IPV6 = 41
...
@@ -15,18 +15,18 @@ SOL_IPV6 = 41
class
RequestHandler
(
SimpleXMLRPCRequestHandler
):
class
RequestHandler
(
SimpleXMLRPCRequestHandler
):
def
address_string
(
self
):
# Workaround for http://bugs.python.org/issue6085
return
self
.
client_address
[
0
]
def
_dispatch
(
self
,
method
,
params
):
def
_dispatch
(
self
,
method
,
params
):
logging
.
debug
(
'%s%r'
,
method
,
params
)
return
self
.
server
.
_dispatch
(
method
,
(
self
,)
+
params
)
return
self
.
server
.
_dispatch
(
method
,
(
self
,)
+
params
)
class
SimpleXMLRPCServer4
(
SimpleXMLRPCServer
):
class
SimpleXMLRPCServer4
(
SimpleXMLRPCServer
):
allow_reuse_address
=
True
allow_reuse_address
=
True
def
address_string
(
self
):
# Workaround for http://bugs.python.org/issue6085
return
self
.
client_address
[
0
]
class
SimpleXMLRPCServer6
(
SimpleXMLRPCServer4
):
class
SimpleXMLRPCServer6
(
SimpleXMLRPCServer4
):
...
@@ -48,10 +48,10 @@ class main(object):
...
@@ -48,10 +48,10 @@ class main(object):
utils
.
setupLog
(
3
)
utils
.
setupLog
(
3
)
# Command line parsing
# Command line parsing
parser
=
argparse
.
ArgumentParser
(
parser
=
utils
.
ArgParser
(
fromfile_prefix_chars
=
'@'
,
description
=
'Peer discovery http server for re6stnet'
)
description
=
'Peer discovery http server for re6stnet'
)
_
=
parser
.
add_argument
_
=
parser
.
add_argument
_
(
'--port'
,
required
=
True
,
type
=
int
,
help
=
'Port of the host server'
)
_
(
'--port'
,
type
=
int
,
default
=
80
,
help
=
'Port of the host server'
)
_
(
'--db'
,
required
=
True
,
_
(
'--db'
,
required
=
True
,
help
=
'Path to database file'
)
help
=
'Path to database file'
)
_
(
'--ca'
,
required
=
True
,
_
(
'--ca'
,
required
=
True
,
...
@@ -76,21 +76,21 @@ class main(object):
...
@@ -76,21 +76,21 @@ class main(object):
address text not null,
address text not null,
date integer default (strftime('%s','now')))"""
)
date integer default (strftime('%s','now')))"""
)
self
.
db
.
execute
(
"CREATE INDEX IF NOT EXISTS peers_ping ON peers(date)"
)
self
.
db
.
execute
(
"CREATE INDEX IF NOT EXISTS peers_ping ON peers(date)"
)
self
.
db
.
execute
(
"""CREATE TABLE IF NOT EXISTS token
s
(
self
.
db
.
execute
(
"""CREATE TABLE IF NOT EXISTS token (
token text primary key not null,
token text primary key not null,
email text not null,
email text not null,
prefix_len integer not null,
prefix_len integer not null,
date integer not null)"""
)
date integer not null)"""
)
try
:
try
:
self
.
db
.
execute
(
"""CREATE TABLE
vpn
(
self
.
db
.
execute
(
"""CREATE TABLE
cert
(
prefix text primary key not null,
prefix text primary key not null,
email text,
email text,
cert text)"""
)
cert text)"""
)
except
sqlite3
.
OperationalError
,
e
:
except
sqlite3
.
OperationalError
,
e
:
if
e
.
args
[
0
]
!=
'table
vpn
already exists'
:
if
e
.
args
[
0
]
!=
'table
cert
already exists'
:
raise
RuntimeError
raise
RuntimeError
else
:
else
:
self
.
db
.
execute
(
"INSERT INTO
vpn
VALUES ('',null,null)"
)
self
.
db
.
execute
(
"INSERT INTO
cert
VALUES ('',null,null)"
)
# Loading certificates
# Loading certificates
with
open
(
self
.
config
.
ca
)
as
f
:
with
open
(
self
.
config
.
ca
)
as
f
:
...
@@ -124,7 +124,7 @@ class main(object):
...
@@ -124,7 +124,7 @@ class main(object):
token
=
''
.
join
(
random
.
sample
(
string
.
ascii_lowercase
,
8
))
token
=
''
.
join
(
random
.
sample
(
string
.
ascii_lowercase
,
8
))
# Updating database
# Updating database
try
:
try
:
self
.
db
.
execute
(
"INSERT INTO token
s
VALUES (?,?,?,?)"
,
(
token
,
email
,
16
,
int
(
time
.
time
())))
self
.
db
.
execute
(
"INSERT INTO token VALUES (?,?,?,?)"
,
(
token
,
email
,
16
,
int
(
time
.
time
())))
break
break
except
sqlite3
.
IntegrityError
:
except
sqlite3
.
IntegrityError
:
pass
pass
...
@@ -143,18 +143,18 @@ class main(object):
...
@@ -143,18 +143,18 @@ class main(object):
max_len
=
128
-
len
(
self
.
network
)
max_len
=
128
-
len
(
self
.
network
)
assert
0
<
prefix_len
<=
max_len
assert
0
<
prefix_len
<=
max_len
try
:
try
:
prefix
,
=
self
.
db
.
execute
(
"""SELECT prefix FROM
vpn
WHERE length(prefix) <= ? AND cert is null
prefix
,
=
self
.
db
.
execute
(
"""SELECT prefix FROM
cert
WHERE length(prefix) <= ? AND cert is null
ORDER BY length(prefix) DESC"""
,
(
prefix_len
,)).
next
()
ORDER BY length(prefix) DESC"""
,
(
prefix_len
,)).
next
()
except
StopIteration
:
except
StopIteration
:
logging
.
error
(
'There are no more free /%s prefix available'
%
(
prefix_len
,))
logging
.
error
(
'There are no more free /%s prefix available'
%
(
prefix_len
,))
raise
raise
while
len
(
prefix
)
<
prefix_len
:
while
len
(
prefix
)
<
prefix_len
:
self
.
db
.
execute
(
"UPDATE
vpn
SET prefix = ? WHERE prefix = ?"
,
(
prefix
+
'1'
,
prefix
))
self
.
db
.
execute
(
"UPDATE
cert
SET prefix = ? WHERE prefix = ?"
,
(
prefix
+
'1'
,
prefix
))
prefix
+=
'0'
prefix
+=
'0'
self
.
db
.
execute
(
"INSERT INTO
vpn
VALUES (?,null,null)"
,
(
prefix
,))
self
.
db
.
execute
(
"INSERT INTO
cert
VALUES (?,null,null)"
,
(
prefix
,))
if
len
(
prefix
)
<
max_len
or
'1'
in
prefix
:
if
len
(
prefix
)
<
max_len
or
'1'
in
prefix
:
return
prefix
return
prefix
self
.
db
.
execute
(
"UPDATE
vpn
SET cert = 'reserved' WHERE prefix = ?"
,
(
prefix
,))
self
.
db
.
execute
(
"UPDATE
cert
SET cert = 'reserved' WHERE prefix = ?"
,
(
prefix
,))
return
self
.
_getPrefix
(
prefix_len
)
return
self
.
_getPrefix
(
prefix_len
)
def
requestCertificate
(
self
,
handler
,
token
,
cert_req
):
def
requestCertificate
(
self
,
handler
,
token
,
cert_req
):
...
@@ -162,11 +162,11 @@ class main(object):
...
@@ -162,11 +162,11 @@ class main(object):
req
=
crypto
.
load_certificate_request
(
crypto
.
FILETYPE_PEM
,
cert_req
)
req
=
crypto
.
load_certificate_request
(
crypto
.
FILETYPE_PEM
,
cert_req
)
with
self
.
db
:
with
self
.
db
:
try
:
try
:
token
,
email
,
prefix_len
,
_
=
self
.
db
.
execute
(
"SELECT * FROM token
s
WHERE token = ?"
,
(
token
,)).
next
()
token
,
email
,
prefix_len
,
_
=
self
.
db
.
execute
(
"SELECT * FROM token WHERE token = ?"
,
(
token
,)).
next
()
except
StopIteration
:
except
StopIteration
:
logging
.
exception
(
'Bad token (%s) in request'
%
(
token
,))
logging
.
exception
(
'Bad token (%s) in request'
%
(
token
,))
raise
raise
self
.
db
.
execute
(
"DELETE FROM token
s
WHERE token = ?"
,
(
token
,))
self
.
db
.
execute
(
"DELETE FROM token WHERE token = ?"
,
(
token
,))
# Get a new prefix
# Get a new prefix
prefix
=
self
.
_getPrefix
(
prefix_len
)
prefix
=
self
.
_getPrefix
(
prefix_len
)
...
@@ -185,7 +185,7 @@ class main(object):
...
@@ -185,7 +185,7 @@ class main(object):
cert
=
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
cert
)
cert
=
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
cert
)
# Insert certificate into db
# Insert certificate into db
self
.
db
.
execute
(
"UPDATE
vpn
SET email = ?, cert = ? WHERE prefix = ?"
,
(
email
,
cert
,
prefix
))
self
.
db
.
execute
(
"UPDATE
cert
SET email = ?, cert = ? WHERE prefix = ?"
,
(
email
,
cert
,
prefix
))
return
cert
return
cert
except
:
except
:
...
@@ -199,16 +199,14 @@ class main(object):
...
@@ -199,16 +199,14 @@ class main(object):
return
'http://[%s]:%u'
%
(
self
.
config
.
private
,
self
.
config
.
port
)
return
'http://[%s]:%u'
%
(
self
.
config
.
private
,
self
.
config
.
port
)
def
getBootstrapPeer
(
self
,
handler
,
client_prefix
):
def
getBootstrapPeer
(
self
,
handler
,
client_prefix
):
cert
,
=
self
.
db
.
execute
(
"SELECT cert FROM
vpn
WHERE prefix = ?"
,
cert
,
=
self
.
db
.
execute
(
"SELECT cert FROM
cert
WHERE prefix = ?"
,
(
client_prefix
,)).
next
()
(
client_prefix
,)).
next
()
logging
.
trace
(
'Getting bootpeer info...'
)
try
:
try
:
prefix
,
address
=
self
.
db
.
execute
(
"""SELECT prefix, address FROM peers
prefix
,
address
=
self
.
db
.
execute
(
"""SELECT prefix, address FROM peers
WHERE prefix != ? ORDER BY random() LIMIT 1"""
,
(
client_prefix
,)).
next
()
WHERE prefix != ? ORDER BY random() LIMIT 1"""
,
(
client_prefix
,)).
next
()
except
StopIteration
:
except
StopIteration
:
logging
.
info
(
'No peer to send for bootstrap'
)
logging
.
info
(
'No peer to send for bootstrap'
)
raise
raise
logging
.
trace
(
'Gotten bootpeer info from db'
)
r
,
w
=
os
.
pipe
()
r
,
w
=
os
.
pipe
()
try
:
try
:
threading
.
Thread
(
target
=
os
.
write
,
args
=
(
w
,
cert
)).
start
()
threading
.
Thread
(
target
=
os
.
write
,
args
=
(
w
,
cert
)).
start
()
...
@@ -221,12 +219,11 @@ class main(object):
...
@@ -221,12 +219,11 @@ class main(object):
os
.
close
(
w
)
os
.
close
(
w
)
def
declare
(
self
,
handler
,
address
):
def
declare
(
self
,
handler
,
address
):
print
"declaring new node"
client_address
,
_
,
_
,
_
=
handler
.
client_address
client_address
,
_
,
_
,
_
=
handler
.
client_address
client_ip
=
utils
.
binFromIp
(
client_address
)
client_ip
=
utils
.
binFromIp
(
client_address
)
if
client_ip
.
startswith
(
self
.
network
):
if
client_ip
.
startswith
(
self
.
network
):
prefix
=
client_ip
[
len
(
self
.
network
):]
prefix
=
client_ip
[
len
(
self
.
network
):]
prefix
,
=
self
.
db
.
execute
(
"SELECT prefix FROM
vpn
WHERE prefix <= ? ORDER BY prefix DESC LIMIT 1"
,
(
prefix
,)).
next
()
prefix
,
=
self
.
db
.
execute
(
"SELECT prefix FROM
cert
WHERE prefix <= ? ORDER BY prefix DESC LIMIT 1"
,
(
prefix
,)).
next
()
self
.
db
.
execute
(
"INSERT OR REPLACE INTO peers (prefix, address) VALUES (?,?)"
,
(
prefix
,
address
))
self
.
db
.
execute
(
"INSERT OR REPLACE INTO peers (prefix, address) VALUES (?,?)"
,
(
prefix
,
address
))
return
True
return
True
else
:
else
:
...
...
re6st/db.py
View file @
b1e97826
...
@@ -10,7 +10,7 @@ class PeerManager:
...
@@ -10,7 +10,7 @@ class PeerManager:
# internal ip = temp arg/attribute
# internal ip = temp arg/attribute
def
__init__
(
self
,
db_path
,
registry
,
key_path
,
refresh_time
,
address
,
def
__init__
(
self
,
db_path
,
registry
,
key_path
,
refresh_time
,
address
,
internal_ip
,
prefix
,
manual
,
pp
,
db_size
):
internal_ip
,
prefix
,
ip_changed
,
db_size
):
self
.
_refresh_time
=
refresh_time
self
.
_refresh_time
=
refresh_time
self
.
address
=
address
self
.
address
=
address
self
.
_internal_ip
=
internal_ip
self
.
_internal_ip
=
internal_ip
...
@@ -18,8 +18,7 @@ class PeerManager:
...
@@ -18,8 +18,7 @@ class PeerManager:
self
.
db_size
=
db_size
self
.
db_size
=
db_size
self
.
_registry
=
registry
self
.
_registry
=
registry
self
.
_key_path
=
key_path
self
.
_key_path
=
key_path
self
.
_pp
=
pp
self
.
_ip_changed
=
ip_changed
self
.
_manual
=
manual
self
.
tunnel_manager
=
None
self
.
tunnel_manager
=
None
self
.
sock
=
socket
.
socket
(
socket
.
AF_INET6
,
socket
.
SOCK_DGRAM
)
self
.
sock
=
socket
.
socket
(
socket
.
AF_INET6
,
socket
.
SOCK_DGRAM
)
...
@@ -53,7 +52,15 @@ class PeerManager:
...
@@ -53,7 +52,15 @@ class PeerManager:
a
,
=
self
.
_db
.
execute
(
"SELECT value FROM config WHERE name='registry'"
).
next
()
a
,
=
self
.
_db
.
execute
(
"SELECT value FROM config WHERE name='registry'"
).
next
()
except
StopIteration
:
except
StopIteration
:
proxy
=
xmlrpclib
.
ServerProxy
(
registry
)
proxy
=
xmlrpclib
.
ServerProxy
(
registry
)
a
=
proxy
.
getPrivateAddress
()
retry
=
1
while
True
:
try
:
a
=
proxy
.
getPrivateAddress
()
break
except
socket
.
error
,
e
:
logging
.
warning
(
e
)
time
.
sleep
(
retry
)
retry
=
min
(
60
,
retry
*
2
)
self
.
_db
.
execute
(
"INSERT INTO config VALUES ('registry',?)"
,
(
a
,))
self
.
_db
.
execute
(
"INSERT INTO config VALUES ('registry',?)"
,
(
a
,))
self
.
_proxy
=
xmlrpclib
.
ServerProxy
(
a
)
self
.
_proxy
=
xmlrpclib
.
ServerProxy
(
a
)
logging
.
debug
(
'Database prepared'
)
logging
.
debug
(
'Database prepared'
)
...
@@ -97,7 +104,7 @@ class PeerManager:
...
@@ -97,7 +104,7 @@ class PeerManager:
self
.
next_refresh
=
time
.
time
()
+
self
.
_refresh_time
self
.
next_refresh
=
time
.
time
()
+
self
.
_refresh_time
logging
.
debug
(
'Info sent'
)
logging
.
debug
(
'Info sent'
)
else
:
else
:
logging
.
warning
(
"
Warning : couldn'
t send ip, unknown external config. retrying in 30s"
)
logging
.
warning
(
"
Could no
t send ip, unknown external config. retrying in 30s"
)
def
getUnusedPeers
(
self
,
peer_count
):
def
getUnusedPeers
(
self
,
peer_count
):
for
populate
in
self
.
_bootstrap
,
bool
:
for
populate
in
self
.
_bootstrap
,
bool
:
...
@@ -107,7 +114,7 @@ class PeerManager:
...
@@ -107,7 +114,7 @@ class PeerManager:
if
peer_list
:
if
peer_list
:
return
peer_list
return
peer_list
populate
()
populate
()
logging
.
warning
(
'Can
not find any new peers
'
)
logging
.
warning
(
'Can
not find any new peer
'
)
return
[]
return
[]
def
_bootstrap
(
self
):
def
_bootstrap
(
self
):
...
@@ -152,22 +159,19 @@ class PeerManager:
...
@@ -152,22 +159,19 @@ class PeerManager:
self
.
whitelist
(
utils
.
binFromSubnet
(
arg
))
self
.
whitelist
(
utils
.
binFromSubnet
(
arg
))
logging
.
info
(
'%s has disconnected'
%
(
arg
,))
logging
.
info
(
'%s has disconnected'
%
(
arg
,))
elif
script_type
==
'route-up'
:
elif
script_type
==
'route-up'
:
if
not
self
.
_manual
:
if
self
.
_ip_changed
:
external_ip
=
arg
address
=
self
.
_ip_changed
(
arg
)
new_address
=
list
([
external_ip
,
port
,
proto
]
if
self
.
address
!=
address
:
for
port
,
proto
,
_
in
self
.
_pp
)
self
.
address
=
address
if
self
.
address
!=
new_address
:
logging
.
info
(
'Received new external ip : %s'
,
arg
)
self
.
address
=
new_address
logging
.
info
(
'Received new external ip : %s'
%
(
external_ip
,))
try
:
try
:
self
.
_declare
()
self
.
_declare
()
except
socket
.
error
,
e
:
except
socket
.
error
,
e
:
logging
.
debug
(
'socket.error : %s'
%
e
)
logging
.
info
(
"Connection to server failed while"
logging
.
info
(
"""Connection to server failed while declaring external infos"""
)
" declaring external infos (%s)"
,
e
)
else
:
else
:
logging
.
debug
(
'Unknow message recieved from the openvpn pipe : %s'
logging
.
info
(
"Unknown message received from the openvpn pipe: %s"
,
%
msg
)
msg
)
def
readSocket
(
self
):
def
readSocket
(
self
):
msg
=
self
.
socket_file
.
readline
()
msg
=
self
.
socket_file
.
readline
()
...
...
re6st/plib.py
View file @
b1e97826
import
errno
import
os
import
os
import
subprocess
import
subprocess
import
logging
import
logging
import
utils
import
utils
verbose
=
0
here
=
os
.
path
.
realpath
(
os
.
path
.
dirname
(
__file__
))
here
=
os
.
path
.
realpath
(
os
.
path
.
dirname
(
__file__
))
ovpn_server
=
os
.
path
.
join
(
here
,
'ovpn-server'
)
ovpn_server
=
os
.
path
.
join
(
here
,
'ovpn-server'
)
ovpn_client
=
os
.
path
.
join
(
here
,
'ovpn-client'
)
ovpn_client
=
os
.
path
.
join
(
here
,
'ovpn-client'
)
def
openvpn
(
hello_interval
,
encrypt
,
*
args
,
**
kw
):
def
openvpn
(
iface
,
hello_interval
,
encrypt
,
*
args
,
**
kw
):
args
=
[
'openvpn'
,
args
=
[
'openvpn'
,
'--dev-type'
,
'tap'
,
'--dev-type'
,
'tap'
,
'--dev'
,
iface
,
'--persist-tun'
,
'--persist-tun'
,
'--persist-key'
,
'--persist-key'
,
'--script-security'
,
'2'
,
'--script-security'
,
'2'
,
'--user'
,
'nobody'
,
'--ping-exit'
,
str
(
4
*
hello_interval
),
'--ping-exit'
,
str
(
4
*
hello_interval
),
'--group'
,
'nogroup'
,
#'--user', 'nobody',
'--group', 'nogroup',
]
+
list
(
args
)
]
+
list
(
args
)
if
not
encrypt
:
if
not
encrypt
:
args
.
extend
([
'--cipher'
,
'none'
])
args
.
extend
([
'--cipher'
,
'none'
])
logging
.
trace
(
'%s'
%
(
args
,))
logging
.
trace
(
'%r'
,
args
)
return
subprocess
.
Popen
(
args
,
**
kw
)
fd
=
os
.
open
(
os
.
path
.
join
(
log
,
'%s.log'
%
iface
),
os
.
O_WRONLY
|
os
.
O_CREAT
|
os
.
O_APPEND
)
try
:
return
subprocess
.
Popen
(
args
,
stdout
=
fd
,
stderr
=
subprocess
.
STDOUT
,
**
kw
)
finally
:
os
.
close
(
fd
)
def
server
(
server_ip
,
ip_length
,
max_clients
,
dh_path
,
pipe_fd
,
port
,
proto
,
hello_interval
,
encrypt
,
*
args
,
**
kw
):
def
server
(
iface
,
server_ip
,
ip_length
,
max_clients
,
dh_path
,
pipe_fd
,
port
,
proto
,
hello_interval
,
encrypt
,
*
args
,
**
kw
):
logging
.
debug
(
'Starting server...'
)
logging
.
debug
(
'Starting server...'
)
if
server_ip
!=
''
:
if
server_ip
:
script_up
=
'%s %s/%u'
%
(
ovpn_server
,
server_ip
,
64
)
script_up
=
'%s %s/%u'
%
(
ovpn_server
,
server_ip
,
64
)
else
:
else
:
script_up
=
'%s none'
%
(
ovpn_server
)
script_up
=
'%s none'
%
(
ovpn_server
)
return
openvpn
(
hello_interval
,
encrypt
,
return
openvpn
(
iface
,
hello_interval
,
encrypt
,
'--tls-server'
,
'--tls-server'
,
'--mode'
,
'server'
,
'--mode'
,
'server'
,
'--up'
,
script_up
,
'--up'
,
script_up
,
...
@@ -40,11 +45,11 @@ def server(server_ip, ip_length, max_clients, dh_path, pipe_fd, port, proto, hel
...
@@ -40,11 +45,11 @@ def server(server_ip, ip_length, max_clients, dh_path, pipe_fd, port, proto, hel
'--dh'
,
dh_path
,
'--dh'
,
dh_path
,
'--max-clients'
,
str
(
max_clients
),
'--max-clients'
,
str
(
max_clients
),
'--port'
,
str
(
port
),
'--port'
,
str
(
port
),
'--proto'
,
proto
,
'--proto'
,
'tcp-server'
if
proto
==
'tcp'
else
proto
,
*
args
,
**
kw
)
*
args
,
**
kw
)
def
client
(
server_address
,
pipe_fd
,
hello_interval
,
encrypt
,
*
args
,
**
kw
):
def
client
(
iface
,
server_address
,
pipe_fd
,
hello_interval
,
encrypt
,
*
args
,
**
kw
):
logging
.
debug
(
'Starting client...'
)
logging
.
debug
(
'Starting client...'
)
remote
=
[
'--nobind'
,
remote
=
[
'--nobind'
,
'--client'
,
'--client'
,
...
@@ -52,18 +57,17 @@ def client(server_address, pipe_fd, hello_interval, encrypt, *args, **kw):
...
@@ -52,18 +57,17 @@ def client(server_address, pipe_fd, hello_interval, encrypt, *args, **kw):
'--route-up'
,
ovpn_client
+
' '
+
str
(
pipe_fd
)]
'--route-up'
,
ovpn_client
+
' '
+
str
(
pipe_fd
)]
try
:
try
:
for
ip
,
port
,
proto
in
utils
.
address_list
(
server_address
):
for
ip
,
port
,
proto
in
utils
.
address_list
(
server_address
):
if
proto
==
'tcp-server'
:
remote
+=
'--remote'
,
ip
,
port
,
\
proto
=
'tcp-client'
'tcp-client'
if
proto
==
'tcp'
else
proto
remote
+=
'--remote'
,
ip
,
port
,
proto
except
ValueError
,
e
:
except
ValueError
,
e
:
logging
.
warning
(
'Error "%s" in unpacking address %s for openvpn client'
logging
.
warning
(
'Error "%s" in unpacking address %s for openvpn client'
%
(
e
,
server_address
,))
%
(
e
,
server_address
,))
remote
+=
args
remote
+=
args
return
openvpn
(
hello_interval
,
encrypt
,
*
remote
,
**
kw
)
return
openvpn
(
iface
,
hello_interval
,
encrypt
,
*
remote
,
**
kw
)
def
router
(
network
,
subnet
,
subnet_size
,
interface_list
,
def
router
(
network
,
subnet
,
subnet_size
,
interface_list
,
wireless
,
hello_interval
,
state_path
,
**
kw
):
wireless
,
hello_interval
,
verbose
,
pidfile
,
state_path
,
**
kw
):
logging
.
info
(
'Starting babel...'
)
logging
.
info
(
'Starting babel...'
)
args
=
[
'babeld'
,
args
=
[
'babeld'
,
'-C'
,
'redistribute local ip %s/%s le %s'
%
(
subnet
,
subnet_size
,
subnet_size
),
'-C'
,
'redistribute local ip %s/%s le %s'
%
(
subnet
,
subnet_size
,
subnet_size
),
...
@@ -86,8 +90,18 @@ def router(network, subnet, subnet_size, interface_list,
...
@@ -86,8 +90,18 @@ def router(network, subnet, subnet_size, interface_list,
'-S'
,
state_path
,
'-S'
,
state_path
,
'-s'
,
'-s'
,
]
]
if
pidfile
:
args
+=
'-I'
,
pidfile
# WKRD: babeld fails to start if pidfile already exists
else
:
pidfile
=
'/var/run/babeld.pid'
try
:
os
.
remove
(
pidfile
)
except
OSError
,
e
:
if
e
.
errno
!=
errno
.
ENOENT
:
raise
if
wireless
:
if
wireless
:
args
.
append
(
'-w'
)
args
.
append
(
'-w'
)
args
=
args
+
interface_list
args
=
args
+
interface_list
logging
.
trace
(
'%
s'
%
args
)
logging
.
trace
(
'%
r'
,
args
)
return
subprocess
.
Popen
(
args
,
**
kw
)
return
subprocess
.
Popen
(
args
,
**
kw
)
re6st/tunnel.py
View file @
b1e97826
...
@@ -6,19 +6,13 @@ import utils
...
@@ -6,19 +6,13 @@ import utils
# Be carfull the refresh interval should let the routes be established
# Be carfull the refresh interval should let the routes be established
log
=
None
class
Connection
:
class
Connection
:
def
__init__
(
self
,
address
,
write_pipe
,
hello
,
iface
,
prefix
,
encrypt
,
def
__init__
(
self
,
address
,
write_pipe
,
hello
,
iface
,
prefix
,
encrypt
,
ovpn_args
):
ovpn_args
):
self
.
process
=
plib
.
client
(
address
,
write_pipe
,
hello
,
encrypt
,
'--dev'
,
iface
,
self
.
process
=
plib
.
client
(
iface
,
address
,
write_pipe
,
hello
,
encrypt
,
*
ovpn_args
,
stdout
=
os
.
open
(
os
.
path
.
join
(
log
,
*
ovpn_args
)
're6stnet.client.%s.log'
%
(
prefix
,)),
os
.
O_WRONLY
|
os
.
O_CREAT
|
os
.
O_TRUNC
),
stderr
=
subprocess
.
STDOUT
)
self
.
iface
=
iface
self
.
iface
=
iface
self
.
routes
=
0
self
.
routes
=
0
self
.
_prefix
=
prefix
self
.
_prefix
=
prefix
...
@@ -61,10 +55,9 @@ class TunnelManager:
...
@@ -61,10 +55,9 @@ class TunnelManager:
for
i
in
xrange
(
1
,
self
.
_client_count
+
1
))
for
i
in
xrange
(
1
,
self
.
_client_count
+
1
))
def
refresh
(
self
):
def
refresh
(
self
):
logging
.
info
(
'Checking the
tunnels...'
)
logging
.
debug
(
'Checking
tunnels...'
)
self
.
_cleanDeads
()
self
.
_cleanDeads
()
if
self
.
_next_tunnel_refresh
<
time
.
time
():
if
self
.
_next_tunnel_refresh
<
time
.
time
():
logging
.
info
(
'Refreshing the tunnels...'
)
self
.
_countRoutes
()
self
.
_countRoutes
()
self
.
_removeSomeTunnels
()
self
.
_removeSomeTunnels
()
self
.
_next_tunnel_refresh
=
time
.
time
()
+
self
.
_refresh_time
self
.
_next_tunnel_refresh
=
time
.
time
()
+
self
.
_refresh_time
...
@@ -84,12 +77,12 @@ class TunnelManager:
...
@@ -84,12 +77,12 @@ class TunnelManager:
self
.
_client_count
+
self
.
_refresh_count
)]:
self
.
_client_count
+
self
.
_refresh_count
)]:
self
.
_kill
(
prefix
)
self
.
_kill
(
prefix
)
def
_kill
(
self
,
prefix
):
def
_kill
(
self
,
prefix
,
kill
=
False
):
logging
.
info
(
'Killing the connection with %s/%u...'
logging
.
info
(
'Killing the connection with %s/%u...'
%
(
hex
(
int
(
prefix
,
2
))[
2
:],
len
(
prefix
)))
%
(
hex
(
int
(
prefix
,
2
))[
2
:],
len
(
prefix
)))
connection
=
self
.
_connection_dict
.
pop
(
prefix
)
connection
=
self
.
_connection_dict
.
pop
(
prefix
)
try
:
try
:
connection
.
process
.
terminate
()
getattr
(
connection
.
process
,
'kill'
if
kill
else
'terminate'
)
()
except
OSError
:
except
OSError
:
# If the process is already exited
# If the process is already exited
pass
pass
...
@@ -144,7 +137,7 @@ class TunnelManager:
...
@@ -144,7 +137,7 @@ class TunnelManager:
if
iface
in
self
.
_iface_list
and
self
.
_net_len
<
subnet_size
<
128
:
if
iface
in
self
.
_iface_list
and
self
.
_net_len
<
subnet_size
<
128
:
prefix
=
ip
[
self
.
_net_len
:
subnet_size
]
prefix
=
ip
[
self
.
_net_len
:
subnet_size
]
logging
.
debug
(
'A route to %s has been discovered on the LAN'
logging
.
debug
(
'A route to %s has been discovered on the LAN'
%
(
hex
(
int
(
prefix
),
2
)[
2
:])
)
%
hex
(
int
(
prefix
,
2
))[
2
:]
)
self
.
_peer_db
.
blacklist
(
prefix
,
0
)
self
.
_peer_db
.
blacklist
(
prefix
,
0
)
possiblePeers
.
add
(
line
[
0
])
possiblePeers
.
add
(
line
[
0
])
...
@@ -163,7 +156,7 @@ class TunnelManager:
...
@@ -163,7 +156,7 @@ class TunnelManager:
def
killAll
(
self
):
def
killAll
(
self
):
for
prefix
in
self
.
_connection_dict
.
keys
():
for
prefix
in
self
.
_connection_dict
.
keys
():
self
.
_kill
(
prefix
)
self
.
_kill
(
prefix
,
True
)
def
checkIncomingTunnel
(
self
,
prefix
):
def
checkIncomingTunnel
(
self
,
prefix
):
if
prefix
in
self
.
_connection_dict
:
if
prefix
in
self
.
_connection_dict
:
...
...
re6st/upnpigd.py
View file @
b1e97826
...
@@ -3,57 +3,48 @@ import logging
...
@@ -3,57 +3,48 @@ import logging
import
time
import
time
class
NoUPnPDevice
(
Exception
):
def
__init__
(
self
):
pass
def
__str__
(
self
):
return
'No upnp device found'
class
Forwarder
:
class
Forwarder
:
def
__init__
(
self
):
def
__init__
(
self
):
self
.
_u
=
miniupnpc
.
UPnP
()
self
.
_u
=
miniupnpc
.
UPnP
()
self
.
_u
.
discoverdelay
=
200
self
.
_u
.
discoverdelay
=
200
self
.
_rules
=
[]
self
.
_rules
=
[]
self
.
_u
.
discover
()
self
.
_u
.
discover
()
try
:
self
.
_u
.
selectigd
()
self
.
_u
.
selectigd
()
except
:
raise
NoUPnPDevice
self
.
_external_ip
=
self
.
_u
.
externalipaddress
()
self
.
_external_ip
=
self
.
_u
.
externalipaddress
()
self
.
next_refresh
=
time
.
time
()
self
.
next_refresh
=
time
.
time
()
def
A
ddRule
(
self
,
local_port
,
proto
):
def
a
ddRule
(
self
,
local_port
,
proto
):
# Init parameters
# Init parameters
external_port
=
1000
external_port
=
1023
if
proto
==
'udp'
:
desc
=
're6stnet openvpn %s server'
%
proto
upnp_proto
=
'UDP'
proto
=
proto
.
upper
()
elif
proto
==
'tcp-server'
:
lanaddr
=
self
.
_u
.
lanaddr
upnp_proto
=
'TCP'
else
:
logging
.
info
(
'Unknown protocol : %s'
%
proto
)
raise
RuntimeError
# Choose a free port
# Choose a free port
while
True
:
while
True
:
while
self
.
_u
.
getspecificportmapping
(
external_port
,
external_port
+=
1
upnp_proto
)
!=
None
:
if
external_port
>
65535
:
external_port
+=
1
raise
Exception
(
'Failed to redirect %u/%s via UPnP'
if
external_port
==
65536
:
%
(
local_port
,
proto
))
return
None
try
:
if
not
self
.
_u
.
getspecificportmapping
(
external_port
,
proto
):
# Make the redirection
args
=
external_port
,
proto
,
lanaddr
,
local_port
,
desc
,
''
if
self
.
_u
.
addportmapping
(
external_port
,
upnp_proto
,
self
.
_u
.
lanaddr
,
self
.
_u
.
addportmapping
(
*
args
)
int
(
local_port
),
're6stnet openvpn server'
,
''
):
break
logging
.
debug
(
'Forwarding %s:%s to %s:%s'
%
(
self
.
_external_ip
,
except
Exception
,
e
:
external_port
,
self
.
_u
.
lanaddr
,
local_port
))
if
str
(
e
)
!=
'ConflictInMappingEntry'
:
self
.
_rules
.
append
((
external_port
,
int
(
local_port
),
upnp_proto
))
raise
return
(
self
.
_external_ip
,
str
(
external_port
),
proto
)
logging
.
debug
(
'Forwarding %s:%s to %s:%s'
,
self
.
_external_ip
,
external_port
,
self
.
_u
.
lanaddr
,
local_port
)
self
.
_rules
.
append
(
args
)
return
self
.
_external_ip
,
external_port
def
refresh
(
self
):
def
refresh
(
self
):
logging
.
debug
(
'Refreshing port forwarding'
)
logging
.
debug
(
'Refreshing port forwarding'
)
for
external_port
,
local_port
,
proto
in
self
.
_rules
:
for
args
in
self
.
_rules
:
self
.
_u
.
addportmapping
(
external_port
,
proto
,
self
.
_u
.
lanaddr
,
self
.
_u
.
addportmapping
(
*
args
)
local_port
,
're6stnet openvpn server'
,
''
)
self
.
next_refresh
=
time
.
time
()
+
500
self
.
next_refresh
=
time
.
time
()
+
500
def
clear
(
self
):
for
args
in
self
.
_rules
:
self
.
_u
.
deleteportmapping
(
args
[
0
],
args
[
1
])
del
self
.
rules
[:]
re6st/utils.py
View file @
b1e97826
...
@@ -6,11 +6,22 @@ logging_levels = logging.WARNING, logging.INFO, logging.DEBUG, 5
...
@@ -6,11 +6,22 @@ logging_levels = logging.WARNING, logging.INFO, logging.DEBUG, 5
def
setupLog
(
log_level
):
def
setupLog
(
log_level
):
logging
.
basicConfig
(
level
=
logging_levels
[
log_level
],
logging
.
basicConfig
(
level
=
logging_levels
[
log_level
],
format
=
'%(asctime)s
:
%(message)s'
,
format
=
'%(asctime)s
%(levelname)-9s
%(message)s'
,
datefmt
=
'%d-%m-%Y %H:%M:%S'
)
datefmt
=
'%d-%m-%Y %H:%M:%S'
)
logging
.
addLevelName
(
5
,
'TRACE'
)
logging
.
addLevelName
(
5
,
'TRACE'
)
logging
.
trace
=
lambda
*
args
,
**
kw
:
logging
.
log
(
5
,
*
args
,
**
kw
)
logging
.
trace
=
lambda
*
args
,
**
kw
:
logging
.
log
(
5
,
*
args
,
**
kw
)
class
ArgParser
(
argparse
.
ArgumentParser
):
def
convert_arg_line_to_args
(
self
,
arg_line
):
arg_line
=
arg_line
.
split
(
'#'
)[
0
].
rstrip
()
if
arg_line
:
if
arg_line
.
startswith
(
'@'
):
yield
arg_line
return
for
arg
in
(
'--'
+
arg_line
.
lstrip
(
'--'
)).
split
():
if
arg
.
strip
():
yield
arg
def
binFromIp
(
ip
):
def
binFromIp
(
ip
):
ip1
,
ip2
=
struct
.
unpack
(
'>QQ'
,
socket
.
inet_pton
(
socket
.
AF_INET6
,
ip
))
ip1
,
ip2
=
struct
.
unpack
(
'>QQ'
,
socket
.
inet_pton
(
socket
.
AF_INET6
,
ip
))
...
...
re6stnet
View file @
b1e97826
#!/usr/bin/env python
#!/usr/bin/env python
import
os
,
sys
,
select
,
time
,
socket
import
atexit
,
os
,
sys
,
select
,
socket
,
time
import
argparse
,
subprocess
,
sqlite3
,
logging
,
traceback
import
argparse
,
signal
,
subprocess
,
sqlite3
,
logging
,
traceback
from
argparse
import
ArgumentParser
from
re6st
import
plib
,
utils
,
db
,
tunnel
from
re6st
import
plib
,
utils
,
db
,
upnpigd
,
tunnel
class
ArgParser
(
ArgumentParser
):
def
convert_arg_line_to_args
(
self
,
arg_line
):
arg_line
=
arg_line
.
split
(
'#'
)[
0
].
rstrip
()
if
arg_line
:
if
arg_line
.
startswith
(
'@'
):
yield
arg_line
return
for
arg
in
(
'--'
+
arg_line
.
lstrip
(
'--'
)).
split
():
if
arg
.
strip
():
yield
arg
def
ovpnArgs
(
optional_args
,
ca_path
,
cert_path
,
key_path
):
def
ovpnArgs
(
optional_args
,
ca_path
,
cert_path
,
key_path
):
# Treat openvpn arguments
# Treat openvpn arguments
...
@@ -32,13 +17,13 @@ def ovpnArgs(optional_args, ca_path, cert_path, key_path):
...
@@ -32,13 +17,13 @@ def ovpnArgs(optional_args, ca_path, cert_path, key_path):
def
getConfig
():
def
getConfig
():
parser
=
ArgParser
(
fromfile_prefix_chars
=
'@'
,
parser
=
utils
.
ArgParser
(
fromfile_prefix_chars
=
'@'
,
description
=
'Resilient virtual private network application'
)
description
=
'Resilient virtual private network application'
)
_
=
parser
.
add_argument
_
=
parser
.
add_argument
# General Configuration options
# General Configuration options
_
(
'--ip'
,
default
=
None
,
dest
=
'address'
,
action
=
'append'
,
nargs
=
3
,
_
(
'--ip'
,
help
=
'I
p address, port and protocol advertised to other vpn
nodes'
)
help
=
'I
P address advertised to other
nodes'
)
_
(
'--registry'
,
required
=
True
,
_
(
'--registry'
,
required
=
True
,
help
=
"HTTP URL of the discovery peer server,"
help
=
"HTTP URL of the discovery peer server,"
" with public host (default port: 80)"
)
" with public host (default port: 80)"
)
...
@@ -49,11 +34,15 @@ def getConfig():
...
@@ -49,11 +34,15 @@ def getConfig():
_
(
'-s'
,
'--state'
,
default
=
'/var/lib/re6stnet'
,
_
(
'-s'
,
'--state'
,
default
=
'/var/lib/re6stnet'
,
help
=
'Path to re6stnet state directory'
)
help
=
'Path to re6stnet state directory'
)
_
(
'-v'
,
'--verbose'
,
default
=
0
,
type
=
int
,
_
(
'-v'
,
'--verbose'
,
default
=
0
,
type
=
int
,
help
=
'
Defines the verbose level
'
)
help
=
'
Log level of re6st itself
'
)
_
(
'-i'
,
'--interface'
,
action
=
'append'
,
dest
=
'iface_list'
,
default
=
[],
_
(
'-i'
,
'--interface'
,
action
=
'append'
,
dest
=
'iface_list'
,
default
=
[],
help
=
'Extra interface for LAN discovery'
)
help
=
'Extra interface for LAN discovery'
)
# Routing algorithm options
# Routing algorithm options
_
(
'--babel-pidfile'
,
help
=
'Specify a file to write our process id to'
)
_
(
'--babel-verb'
,
default
=
0
,
help
=
'Babel verbosity'
)
_
(
'--hello'
,
type
=
int
,
default
=
15
,
_
(
'--hello'
,
type
=
int
,
default
=
15
,
help
=
'Hello interval for babel, in seconds'
)
help
=
'Hello interval for babel, in seconds'
)
_
(
'-w'
,
'--wireless'
,
action
=
'store_true'
,
_
(
'-w'
,
'--wireless'
,
action
=
'store_true'
,
...
@@ -87,11 +76,6 @@ def getConfig():
...
@@ -87,11 +76,6 @@ def getConfig():
def
main
():
def
main
():
# Get arguments
# Get arguments
config
=
getConfig
()
config
=
getConfig
()
if
not
config
.
pp
:
config
.
pp
=
[[
'1194'
,
'udp'
],
[
'1194'
,
'tcp-server'
]]
config
.
pp
=
list
((
port
,
proto
,
're6stnet-%s'
%
proto
)
for
port
,
proto
in
config
.
pp
)
manual
=
bool
(
config
.
address
)
network
=
utils
.
networkFromCa
(
config
.
ca
)
network
=
utils
.
networkFromCa
(
config
.
ca
)
internal_ip
,
prefix
=
utils
.
ipFromCert
(
network
,
config
.
cert
)
internal_ip
,
prefix
=
utils
.
ipFromCert
(
network
,
config
.
cert
)
openvpn_args
=
ovpnArgs
(
config
.
openvpn_args
,
config
.
ca
,
config
.
cert
,
openvpn_args
=
ovpnArgs
(
config
.
openvpn_args
,
config
.
ca
,
config
.
cert
,
...
@@ -104,76 +88,76 @@ def main():
...
@@ -104,76 +88,76 @@ def main():
logging
.
trace
(
"Configuration :
\
n
%s"
%
config
)
logging
.
trace
(
"Configuration :
\
n
%s"
%
config
)
# Set global variables
# Set global variables
tunnel
.
log
=
config
.
log
plib
.
log
=
tunnel
.
log
=
config
.
log
plib
.
verbose
=
config
.
verbose
# Create and open read_only pipe to get server events
# Create and open read_only pipe to get server events
logging
.
info
(
'Creating pipe for server events...'
)
logging
.
info
(
'Creating pipe for server events...'
)
r_pipe
,
write_pipe
=
os
.
pipe
()
r_pipe
,
write_pipe
=
os
.
pipe
()
read_pipe
=
os
.
fdopen
(
r_pipe
)
read_pipe
=
os
.
fdopen
(
r_pipe
)
logging
.
debug
(
'Pipe created'
)
signal
.
signal
(
signal
.
SIGHUP
,
lambda
*
args
:
sys
.
exit
(
-
1
))
# Init db and tunnels
# Init db and tunnels
forwarder
=
None
address
=
[]
if
manual
:
if
config
.
pp
:
logging
.
info
(
'Detected manual external configuration'
)
pp
=
[(
int
(
port
),
proto
)
for
port
,
proto
in
config
.
pp
]
for
c
,
s
in
(
'udp'
,
'udp'
),
(
'tcp-client'
,
'tcp-server'
):
if
len
(
list
(
x
for
x
in
config
.
address
if
x
[
2
]
==
c
))
\
<
len
(
list
(
x
for
x
in
config
.
pp
if
x
[
1
]
==
s
)):
logging
.
warning
(
"""Beware: in manual configuration, you
declared less external configurations regarding
protocol %s/%s than you gave internal server
configurations"""
%
(
c
,
s
))
else
:
else
:
pp
=
(
1194
,
'udp'
),
(
1194
,
'tcp'
)
ip_changed
=
lambda
ip
:
[(
ip
,
str
(
port
),
proto
)
for
port
,
proto
in
pp
]
forwarder
=
None
if
config
.
ip
==
'upnp'
or
not
config
.
ip
:
logging
.
info
(
'Attempting automatic configuration via UPnP...'
)
logging
.
info
(
'Attempting automatic configuration via UPnP...'
)
try
:
try
:
forwarder
=
upnpigd
.
Forwarder
()
from
re6st.upnpigd
import
Forwarder
config
.
address
=
[]
forwarder
=
Forwarder
()
for
port
,
proto
,
_
in
config
.
pp
:
except
Exception
,
e
:
ext
=
forwarder
.
AddRule
(
port
,
proto
)
if
config
.
ip
:
if
ext
:
raise
config
.
address
.
append
(
ext
)
logging
.
info
(
"%s: assume we are not NATed"
,
e
)
except
upnpigd
.
NoUPnPDevice
:
else
:
logging
.
info
(
'No upnp device found'
)
atexit
.
register
(
forwarder
.
clear
)
for
port
,
proto
in
pp
:
ip
,
port
=
forwarder
.
addRule
(
port
,
proto
)
address
.
append
((
ip
,
str
(
port
),
proto
))
elif
config
.
ip
!=
'any'
:
address
=
ip_changed
(
config
.
ip
)
if
address
:
ip_changed
=
None
peer_db
=
db
.
PeerManager
(
db_path
,
config
.
registry
,
config
.
key
,
peer_db
=
db
.
PeerManager
(
db_path
,
config
.
registry
,
config
.
key
,
config
.
peers_db_refresh
,
config
.
address
,
internal_ip
,
prefix
,
config
.
peers_db_refresh
,
address
,
internal_ip
,
prefix
,
manual
,
config
.
pp
,
200
)
ip_changed
,
200
)
tunnel_manager
=
tunnel
.
TunnelManager
(
write_pipe
,
peer_db
,
openvpn_args
,
tunnel_manager
=
tunnel
.
TunnelManager
(
write_pipe
,
peer_db
,
openvpn_args
,
config
.
hello
,
config
.
tunnel_refresh
,
config
.
connection_count
,
config
.
hello
,
config
.
tunnel_refresh
,
config
.
connection_count
,
config
.
iface_list
,
network
,
prefix
,
2
,
config
.
encrypt
)
config
.
iface_list
,
network
,
prefix
,
2
,
config
.
encrypt
)
peer_db
.
tunnel_manager
=
tunnel_manager
peer_db
.
tunnel_manager
=
tunnel_manager
# Launch routing protocol. WARNING : you have to be root to start babeld
# Launch routing protocol. WARNING : you have to be root to start babeld
server_tunnels
=
{}
for
x
in
pp
:
server_tunnels
.
setdefault
(
're6stnet-'
+
x
[
1
],
x
)
interface_list
=
list
(
tunnel_manager
.
free_interface_set
)
\
interface_list
=
list
(
tunnel_manager
.
free_interface_set
)
\
+
config
.
iface_list
+
list
(
iface
+
config
.
iface_list
+
server_tunnels
.
keys
()
for
_
,
_
,
iface
in
config
.
pp
)
subnet
=
utils
.
ipFromBin
((
network
+
prefix
).
ljust
(
128
,
'0'
))
subnet
=
utils
.
ipFromBin
((
network
+
prefix
).
ljust
(
128
,
'0'
))
router
=
plib
.
router
(
network
,
subnet
,
len
(
prefix
)
+
len
(
network
),
interface_list
,
router
=
plib
.
router
(
network
,
subnet
,
len
(
prefix
)
+
len
(
network
),
config
.
wireless
,
config
.
hello
,
os
.
path
.
join
(
config
.
state
,
'babeld.state'
),
interface_list
,
config
.
wireless
,
config
.
hello
,
config
.
babel_verb
,
stdout
=
os
.
open
(
os
.
path
.
join
(
config
.
log
,
'babeld.log'
),
config
.
babel_pidfile
,
os
.
path
.
join
(
config
.
state
,
'babeld.state'
),
os
.
O_WRONLY
|
os
.
O_CREAT
|
os
.
O_TRUNC
),
stderr
=
subprocess
.
STDOUT
)
stdout
=
os
.
open
(
os
.
path
.
join
(
config
.
log
,
'babeld.log'
),
os
.
O_WRONLY
|
os
.
O_CREAT
|
os
.
O_APPEND
),
stderr
=
subprocess
.
STDOUT
)
# Establish connections
server_process
=
[]
server_ip
=
internal_ip
for
port
,
proto
,
iface
in
config
.
pp
:
server_process
.
append
(
plib
.
server
(
server_ip
,
len
(
network
)
+
len
(
prefix
),
config
.
connection_count
,
config
.
dh
,
write_pipe
,
port
,
proto
,
config
.
hello
,
config
.
encrypt
,
'--dev'
,
iface
,
*
openvpn_args
,
stdout
=
os
.
open
(
os
.
path
.
join
(
config
.
log
,
're6stnet.server.%s.log'
%
(
proto
,)),
os
.
O_WRONLY
|
os
.
O_CREAT
|
os
.
O_TRUNC
),
stderr
=
subprocess
.
STDOUT
))
server_ip
=
''
# main loop
# main loop
try
:
try
:
try
:
try
:
server_process
=
[]
for
iface
,
(
port
,
proto
)
in
server_tunnels
.
iteritems
():
server_process
.
append
(
plib
.
server
(
iface
,
internal_ip
if
proto
==
pp
[
0
][
1
]
else
None
,
len
(
network
)
+
len
(
prefix
),
config
.
connection_count
,
config
.
dh
,
write_pipe
,
port
,
proto
,
config
.
hello
,
config
.
encrypt
,
*
openvpn_args
))
while
True
:
while
True
:
logging
.
info
(
'Sleeping ...'
)
nextUpdate
=
min
(
tunnel_manager
.
next_refresh
,
peer_db
.
next_refresh
)
nextUpdate
=
min
(
tunnel_manager
.
next_refresh
,
peer_db
.
next_refresh
)
if
forwarder
!=
None
:
if
forwarder
:
nextUpdate
=
min
(
nextUpdate
,
forwarder
.
next_refresh
)
nextUpdate
=
min
(
nextUpdate
,
forwarder
.
next_refresh
)
nextUpdate
=
max
(
0
,
nextUpdate
-
time
.
time
())
nextUpdate
=
max
(
0
,
nextUpdate
-
time
.
time
())
select_list
=
[
read_pipe
]
select_list
=
[
read_pipe
]
...
@@ -186,14 +170,15 @@ def main():
...
@@ -186,14 +170,15 @@ def main():
peer_db
.
refresh
()
peer_db
.
refresh
()
if
time
.
time
()
>=
tunnel_manager
.
next_refresh
:
if
time
.
time
()
>=
tunnel_manager
.
next_refresh
:
tunnel_manager
.
refresh
()
tunnel_manager
.
refresh
()
if
forwarder
!=
None
and
time
.
time
()
>
forwarder
.
next_refresh
:
if
forwarder
and
time
.
time
()
>
forwarder
.
next_refresh
:
forwarder
.
refresh
()
forwarder
.
refresh
()
if
peer_db
.
socket_file
in
ready
:
if
peer_db
.
socket_file
in
ready
:
peer_db
.
readSocket
()
peer_db
.
readSocket
()
finally
:
finally
:
for
p
in
[
router
]
+
server_process
:
router
.
terminate
()
for
p
in
server_process
:
try
:
try
:
p
.
terminate
()
p
.
kill
()
except
:
except
:
pass
pass
try
:
try
:
...
@@ -203,7 +188,10 @@ def main():
...
@@ -203,7 +188,10 @@ def main():
except
sqlite3
.
Error
:
except
sqlite3
.
Error
:
traceback
.
print_exc
()
traceback
.
print_exc
()
os
.
rename
(
db_path
,
db_path
+
'.bak'
)
os
.
rename
(
db_path
,
db_path
+
'.bak'
)
os
.
execvp
(
sys
.
executable
,
sys
.
argv
)
try
:
sys
.
exitfunc
()
finally
:
os
.
execvp
(
sys
.
executable
,
sys
.
argv
)
except
KeyboardInterrupt
:
except
KeyboardInterrupt
:
return
0
return
0
...
...
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