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
2
Issues
2
List
Boards
Labels
Milestones
Merge Requests
4
Merge Requests
4
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
nexedi
re6stnet
Commits
118c1ba4
Commit
118c1ba4
authored
Oct 21, 2013
by
Jondy Zhao
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into cygwin
parents
eb9a9237
7dbc38d7
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
150 additions
and
84 deletions
+150
-84
TODO
TODO
+1
-7
daemon/re6stnet.service
daemon/re6stnet.service
+1
-0
demo/demo
demo/demo
+23
-0
demo/registry/re6st-registry.conf
demo/registry/re6st-registry.conf
+0
-1
docs/re6stnet.rst
docs/re6stnet.rst
+9
-14
re6st-registry
re6st-registry
+0
-3
re6st/db.py
re6st/db.py
+33
-30
re6st/registry.py
re6st/registry.py
+50
-29
re6st/utils.py
re6st/utils.py
+27
-0
re6stnet
re6stnet
+6
-0
No files found.
TODO
View file @
118c1ba4
...
@@ -5,12 +5,6 @@
...
@@ -5,12 +5,6 @@
- the ip address of the network being built
- the ip address of the network being built
- the creator of the network ( add option in registry ? )
- the creator of the network ( add option in registry ? )
- Fix bootstrap problem:
registry & --private option ( see re6stnet man page HOW TO ).
one have to start the registry twice, the first time without
the --private option
- Babel limitations:
- Babel limitations:
- The metric does not take latency into account.
- The metric does not take latency into account.
...
...
daemon/re6stnet.service
View file @
118c1ba4
...
@@ -7,6 +7,7 @@ WorkingDirectory=/etc/re6stnet
...
@@ -7,6 +7,7 @@ WorkingDirectory=/etc/re6stnet
# systemd plans to implement "something like ConditionExec= or ExecStartPre= without failure state" (cf its TODO file)
# systemd plans to implement "something like ConditionExec= or ExecStartPre= without failure state" (cf its TODO file)
ExecStart=/bin/sh -c 'set re6stnet @re6stnet.conf; "$@" --test main_interface==\"lo\" || exec "$@"'
ExecStart=/bin/sh -c 'set re6stnet @re6stnet.conf; "$@" --test main_interface==\"lo\" || exec "$@"'
Restart=on-failure
Restart=on-failure
StandardOutput=null
[Install]
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target
demo/demo
View file @
118c1ba4
...
@@ -33,6 +33,29 @@ def _add_interface(node, iface):
...
@@ -33,6 +33,29 @@ def _add_interface(node, iface):
return Node__add_interface(node, iface)
return Node__add_interface(node, iface)
nemu.Node._add_interface = _add_interface
nemu.Node._add_interface = _add_interface
def get_addr_data():
ipdata = backticks([IP_PATH, "-o", "addr", "list"])
byidx = {}
bynam = {}
for line in ipdata.split("\n"):
if line == "":
continue
match = re.search(r'^(\d+):\s+(\S+?)(:?)\s+(.*)', line)
if not match:
raise RuntimeError("Invalid `ip' command output")
idx = int(match.group(1))
name = match.group(2)
#
<patch>
if name not in bynam:
bynam[name] = byidx[idx] = []
if match.group(3): # BBB: old iproute also shows link info
continue
#
</patch>
bynam[name].append(_parse_ip_addr(match.group(4)))
return byidx, bynam
nemu.iproute.get_addr_data.func_code = get_addr_data.func_code
# create nodes
# create nodes
for name in """internet=I registry=R
for name in """internet=I registry=R
gateway1=g1 machine1=1 machine2=2
gateway1=g1 machine1=1 machine2=2
...
...
demo/registry/re6st-registry.conf
View file @
118c1ba4
ca
ca
.
crt
ca
ca
.
crt
key
registry
/
ca
.
key
key
registry
/
ca
.
key
private
2001
:
db8
:
42
::
1
logfile
registry
/
registry
.
log
logfile
registry
/
registry
.
log
docs/re6stnet.rst
View file @
118c1ba4
...
@@ -117,25 +117,20 @@ certificates, as follows: translate the significant part to hexadecimal
...
@@ -117,25 +117,20 @@ certificates, as follows: translate the significant part to hexadecimal
-days 365 -out ca.crt
-days 365 -out ca.crt
The CA email will be used as sender for mails containing tokens.
The CA email will be used as sender for mails containing tokens.
The registry can now be started::
Now start the registry in order to setup the main re6st node, which should be
on the same machine::
re6st-registry --ca ca.crt --key ca.key --mailhost smtp.example.com
re6st-registry --ca ca.crt --key ca.key --mailhost smtp.example.com
re6st-conf --registry http://localhost/
If `re6st-conf` is run in the directory containing CA files, ca.crt will be
overridden without harm.
Note that the registry was started without specifying the re6st IP of the main
Like the registry, the first registered node should be always up because its
node, because it was not known yet. For your network to work, it has to be
presence is used by all other nodes to garantee they are connected to the
restarted with appropriate --private option.
network. It is therefore recommended to run it on the same machine as the
registry::
Let's suppose your first node is allocated subnet 2001:db8:42::/64.
re6st-conf --registry http://localhost/
Its IP is the first unicast address::
re6st-registry --private 2001:db8:42::1 ...
If `re6st-conf` is run in the directory containing CA files, ca.crt will be
re6stnet --registry http://localhost/ --ip re6st.example.com ...
overridden without harm. See previous section for more information to create
a node.
TROUBLESHOOTING
TROUBLESHOOTING
===============
===============
...
...
re6st-registry
View file @
118c1ba4
...
@@ -75,9 +75,6 @@ def main():
...
@@ -75,9 +75,6 @@ def main():
help
=
"SMTP host to send confirmation emails. For debugging"
help
=
"SMTP host to send confirmation emails. For debugging"
" purpose, it can also be an absolute or existing path to"
" purpose, it can also be an absolute or existing path to"
" a mailbox file"
)
" a mailbox file"
)
_
(
'--private'
,
help
=
"re6stnet IP of the node on which runs the registry."
" Required for normal operation."
)
_
(
'--prefix-length'
,
default
=
16
,
type
=
int
,
_
(
'--prefix-length'
,
default
=
16
,
type
=
int
,
help
=
"Default length of allocated prefixes."
)
help
=
"Default length of allocated prefixes."
)
_
(
'--anonymous-prefix-length'
,
type
=
int
,
_
(
'--anonymous-prefix-length'
,
type
=
int
,
...
...
re6st/db.py
View file @
118c1ba4
...
@@ -31,29 +31,24 @@ class PeerDB(object):
...
@@ -31,29 +31,24 @@ class PeerDB(object):
q
(
"INSERT INTO volatile.stat (peer) SELECT prefix FROM peer"
)
q
(
"INSERT INTO volatile.stat (peer) SELECT prefix FROM peer"
)
try
:
try
:
a
=
q
(
"SELECT value FROM config WHERE name='registry'"
).
next
()[
0
]
a
=
q
(
"SELECT value FROM config WHERE name='registry'"
).
next
()[
0
]
except
StopIteration
:
int
(
a
,
2
)
a
=
self
.
_updateRegistryIP
()
except
(
StopIteration
,
ValueError
):
else
:
self
.
registry_ip
=
utils
.
binFromIp
(
a
)
if
not
self
.
registry_ip
.
startswith
(
network
):
a
=
self
.
_updateRegistryIP
()
logging
.
info
(
"Cache initialized. Registry IP is %s"
,
a
)
def
_updateRegistryIP
(
self
):
logging
.
info
(
"Asking registry its private IP..."
)
logging
.
info
(
"Asking registry its private IP..."
)
retry
=
1
retry
=
1
while
True
:
while
True
:
try
:
try
:
a
=
self
.
_registry
.
getPrivateAddress
(
self
.
_prefix
)
a
=
self
.
_registry
.
getPrefix
(
self
.
_prefix
)
int
(
a
,
2
)
break
break
except
socket
.
error
,
e
:
except
socket
.
error
,
e
:
logging
.
warning
(
e
)
logging
.
warning
(
e
)
time
.
sleep
(
retry
)
time
.
sleep
(
retry
)
retry
=
min
(
60
,
retry
*
2
)
retry
=
min
(
60
,
retry
*
2
)
self
.
_db
.
execute
(
"INSERT OR REPLACE INTO config VALUES ('registry',?)"
,
q
(
"INSERT OR REPLACE INTO config VALUES ('registry',?)"
,
(
a
,))
(
a
,))
self
.
_db
.
commit
()
self
.
registry_ip
=
utils
.
binFromIp
(
a
)
self
.
registry_prefix
=
a
return
a
logging
.
info
(
"Cache initialized. Prefix of registry node is %s/%u"
,
int
(
a
,
2
),
len
(
a
))
def
log
(
self
):
def
log
(
self
):
if
logging
.
getLogger
().
isEnabledFor
(
5
):
if
logging
.
getLogger
().
isEnabledFor
(
5
):
...
@@ -64,6 +59,19 @@ class PeerDB(object):
...
@@ -64,6 +59,19 @@ class PeerDB(object):
logging
.
trace
(
"- %s: %s%s"
,
prefix
,
address
,
logging
.
trace
(
"- %s: %s%s"
,
prefix
,
address
,
' (blacklisted)'
if
_try
else
''
)
' (blacklisted)'
if
_try
else
''
)
def
cacheMinimize
(
self
,
size
):
with
self
.
_db
:
self
.
_cacheMinimize
(
size
)
def
_cacheMinimize
(
self
,
size
):
a
=
self
.
_db
.
execute
(
"SELECT peer FROM volatile.stat ORDER BY try, RANDOM() LIMIT ?,-1"
,
(
size
,)).
fetchall
()
if
a
:
q
=
self
.
_db
.
executemany
q
(
"DELETE FROM peer WHERE prefix IN (?)"
,
a
)
q
(
"DELETE FROM volatile.stat WHERE peer IN (?)"
,
a
)
def
connecting
(
self
,
prefix
,
connecting
):
def
connecting
(
self
,
prefix
,
connecting
):
self
.
_db
.
execute
(
"UPDATE volatile.stat SET try=? WHERE peer=?"
,
self
.
_db
.
execute
(
"UPDATE volatile.stat SET try=? WHERE peer=?"
,
(
connecting
,
prefix
))
(
connecting
,
prefix
))
...
@@ -119,13 +127,8 @@ class PeerDB(object):
...
@@ -119,13 +127,8 @@ class PeerDB(object):
return
len
(
preferred
)
return
len
(
preferred
)
address
=
';'
.
join
(
sorted
(
address
.
split
(
';'
),
key
=
key
))
address
=
';'
.
join
(
sorted
(
address
.
split
(
';'
),
key
=
key
))
except
ValueError
:
except
ValueError
:
a
=
q
(
"SELECT peer FROM volatile.stat ORDER BY try, RANDOM()"
self
.
_cacheMinimize
(
self
.
_db_size
)
" LIMIT ?,-1"
,
(
self
.
_db_size
,)).
fetchall
()
a
=
None
if
a
:
qq
=
self
.
_db
.
executemany
qq
(
"DELETE FROM peer WHERE prefix IN (?)"
,
a
)
qq
(
"DELETE FROM volatile.stat WHERE peer IN (?)"
,
a
)
# 'a != address' will evaluate to True because types differs
if
a
!=
address
:
if
a
!=
address
:
q
(
"INSERT OR REPLACE INTO peer VALUES (?,?)"
,
(
prefix
,
address
))
q
(
"INSERT OR REPLACE INTO peer VALUES (?,?)"
,
(
prefix
,
address
))
q
(
"INSERT OR REPLACE INTO volatile.stat VALUES (?,0)"
,
(
prefix
,))
q
(
"INSERT OR REPLACE INTO volatile.stat VALUES (?,0)"
,
(
prefix
,))
re6st/registry.py
View file @
118c1ba4
...
@@ -30,24 +30,27 @@ class getcallargs(type):
...
@@ -30,24 +30,27 @@ class getcallargs(type):
class
RegistryServer
(
object
):
class
RegistryServer
(
object
):
__metaclass__
=
getcallargs
__metaclass__
=
getcallargs
_peers
=
0
,
()
def
__init__
(
self
,
config
):
def
__init__
(
self
,
config
):
self
.
config
=
config
self
.
config
=
config
self
.
cert_duration
=
365
*
86400
self
.
cert_duration
=
365
*
86400
self
.
lock
=
threading
.
Lock
()
self
.
lock
=
threading
.
Lock
()
self
.
sessions
=
{}
self
.
sessions
=
{}
if
self
.
config
.
private
:
self
.
sock
=
socket
.
socket
(
socket
.
AF_INET6
,
socket
.
SOCK_DGRAM
)
self
.
sock
=
socket
.
socket
(
socket
.
AF_INET6
,
socket
.
SOCK_DGRAM
)
else
:
logging
.
warning
(
'You have declared no private address'
', either this is the first start, or you should'
'check you configuration'
)
# Database initializing
# Database initializing
utils
.
makedirs
(
os
.
path
.
dirname
(
self
.
config
.
db
))
utils
.
makedirs
(
os
.
path
.
dirname
(
self
.
config
.
db
))
self
.
db
=
sqlite3
.
connect
(
self
.
config
.
db
,
isolation_level
=
None
,
self
.
db
=
sqlite3
.
connect
(
self
.
config
.
db
,
isolation_level
=
None
,
check_same_thread
=
False
)
check_same_thread
=
False
)
self
.
db
.
execute
(
"""CREATE TABLE IF NOT EXISTS config (
name text primary key,
value text)"""
)
try
:
(
self
.
prefix
,),
=
self
.
db
.
execute
(
"SELECT value FROM config WHERE name='prefix'"
)
except
ValueError
:
self
.
prefix
=
None
self
.
db
.
execute
(
"""CREATE TABLE IF NOT EXISTS token (
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,
...
@@ -157,7 +160,7 @@ class RegistryServer(object):
...
@@ -157,7 +160,7 @@ class RegistryServer(object):
s
.
sendmail
(
self
.
_email
,
email
,
msg
.
as_string
())
s
.
sendmail
(
self
.
_email
,
email
,
msg
.
as_string
())
s
.
quit
()
s
.
quit
()
def
_
get
Prefix
(
self
,
prefix_len
):
def
_
new
Prefix
(
self
,
prefix_len
):
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
:
...
@@ -173,7 +176,7 @@ class RegistryServer(object):
...
@@ -173,7 +176,7 @@ class RegistryServer(object):
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 cert SET cert = 'reserved' WHERE prefix = ?"
,
(
prefix
,))
self
.
db
.
execute
(
"UPDATE cert SET cert = 'reserved' WHERE prefix = ?"
,
(
prefix
,))
return
self
.
_
get
Prefix
(
prefix_len
)
return
self
.
_
new
Prefix
(
prefix_len
)
def
requestCertificate
(
self
,
token
,
req
):
def
requestCertificate
(
self
,
token
,
req
):
req
=
crypto
.
load_certificate_request
(
crypto
.
FILETYPE_PEM
,
req
)
req
=
crypto
.
load_certificate_request
(
crypto
.
FILETYPE_PEM
,
req
)
...
@@ -193,9 +196,13 @@ class RegistryServer(object):
...
@@ -193,9 +196,13 @@ class RegistryServer(object):
if
not
prefix_len
:
if
not
prefix_len
:
return
return
email
=
None
email
=
None
prefix
=
self
.
_
get
Prefix
(
prefix_len
)
prefix
=
self
.
_
new
Prefix
(
prefix_len
)
self
.
db
.
execute
(
"UPDATE cert SET email = ? WHERE prefix = ?"
,
self
.
db
.
execute
(
"UPDATE cert SET email = ? WHERE prefix = ?"
,
(
email
,
prefix
))
(
email
,
prefix
))
if
self
.
prefix
is
None
:
self
.
prefix
=
prefix
self
.
db
.
execute
(
"INSERT INTO config VALUES ('prefix',?)"
,
(
prefix
,))
return
self
.
_createCertificate
(
prefix
,
req
.
get_subject
(),
return
self
.
_createCertificate
(
prefix
,
req
.
get_subject
(),
req
.
get_pubkey
())
req
.
get_pubkey
())
...
@@ -227,37 +234,51 @@ class RegistryServer(object):
...
@@ -227,37 +234,51 @@ class RegistryServer(object):
def
getCa
(
self
):
def
getCa
(
self
):
return
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
self
.
ca
)
return
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
self
.
ca
)
def
getPrefix
(
self
,
cn
):
return
self
.
prefix
def
getPrivateAddress
(
self
,
cn
):
def
getPrivateAddress
(
self
,
cn
):
return
self
.
config
.
private
# BBB: Deprecated by getPrefix.
return
utils
.
ipFromBin
(
self
.
network
+
self
.
prefix
)
def
getBootstrapPeer
(
self
,
cn
):
def
getBootstrapPeer
(
self
,
cn
):
with
self
.
lock
:
with
self
.
lock
:
cert
=
self
.
_getCert
(
cn
)
cert
=
self
.
_getCert
(
cn
)
address
=
self
.
config
.
private
,
tunnel
.
PORT
age
,
peers
=
self
.
_peers
if
time
.
time
()
<
age
or
not
peers
:
peers
=
[
x
[
1
]
for
x
in
utils
.
iterRoutes
(
self
.
network
)]
random
.
shuffle
(
peers
)
self
.
_peers
=
time
.
time
()
+
60
,
peers
peer
=
peers
.
pop
()
if
peer
==
cn
:
# Very unlikely (e.g. peer restarted with empty cache),
# so don't bother looping over above code
# (in case 'peers' is empty).
peer
=
self
.
prefix
address
=
utils
.
ipFromBin
(
self
.
network
+
peer
),
tunnel
.
PORT
self
.
sock
.
sendto
(
'
\
2
'
,
address
)
self
.
sock
.
sendto
(
'
\
2
'
,
address
)
peer
=
None
start
=
time
.
time
()
while
select
.
select
([
self
.
sock
],
[],
[],
peer
is
None
)[
0
]:
timeout
=
1
# Loop because there may be answers from previous requests.
while
select
.
select
([
self
.
sock
],
[],
[],
timeout
)[
0
]:
msg
=
self
.
sock
.
recv
(
1
<<
16
)
msg
=
self
.
sock
.
recv
(
1
<<
16
)
if
msg
[
0
]
==
'
\
1
'
:
if
msg
[
0
]
==
'
\
1
'
:
try
:
try
:
peer
=
msg
[
1
:].
split
(
'
\
n
'
)[
-
2
]
msg
=
msg
[
1
:
msg
.
index
(
'
\
n
'
)]
except
IndexError
:
except
ValueError
:
peer
=
''
continue
if
peer
is
None
:
if
msg
.
split
()[
0
]
==
peer
:
raise
EnvironmentError
(
"Timeout while querying [%s]:%u"
%
address
)
break
if
not
peer
or
peer
.
split
()[
0
]
==
cn
:
timeout
=
max
(
0
,
time
.
time
()
-
start
)
raise
LookupError
(
"No bootstrap peer found"
)
else
:
logging
.
info
(
"Sending bootstrap peer: %s"
,
peer
)
raise
EnvironmentError
(
"Timeout while querying [%s]:%u"
return
utils
.
encrypt
(
cert
,
peer
)
%
address
)
logging
.
info
(
"Sending bootstrap peer: %s"
,
msg
)
return
utils
.
encrypt
(
cert
,
msg
)
def
topology
(
self
):
def
topology
(
self
):
with
self
.
lock
:
with
self
.
lock
:
is_registry
=
utils
.
binFromIp
(
self
.
config
.
private
peers
=
deque
((
'%u/%u'
%
(
int
(
self
.
prefix
,
2
),
len
(
self
.
prefix
)),))
)[
len
(
self
.
network
):].
startswith
peers
=
deque
(
'%u/%u'
%
(
int
(
x
,
2
),
len
(
x
))
for
x
,
in
self
.
db
.
execute
(
"SELECT prefix FROM cert"
)
if
is_registry
(
x
))
assert
len
(
peers
)
==
1
cookie
=
hex
(
random
.
randint
(
0
,
1
<<
32
))[
2
:]
cookie
=
hex
(
random
.
randint
(
0
,
1
<<
32
))[
2
:]
graph
=
dict
.
fromkeys
(
peers
)
graph
=
dict
.
fromkeys
(
peers
)
asked
=
0
asked
=
0
...
...
re6st/utils.py
View file @
118c1ba4
...
@@ -199,6 +199,33 @@ def iterRoutes(network, exclude_prefix=None):
...
@@ -199,6 +199,33 @@ def iterRoutes(network, exclude_prefix=None):
if
prefix
and
prefix
!=
exclude_prefix
:
if
prefix
and
prefix
!=
exclude_prefix
:
yield
iface
,
prefix
yield
iface
,
prefix
if
1
:
def
_iterRoutes
():
with
open
(
'/proc/net/ipv6_route'
)
as
f
:
routing_table
=
f
.
read
()
for
line
in
routing_table
.
splitlines
():
line
=
line
.
split
()
iface
=
line
[
-
1
]
if
0
<
int
(
line
[
5
],
16
)
<
1
<<
31
:
# positive metric
yield
(
iface
,
bin
(
int
(
line
[
0
],
16
))[
2
:].
rjust
(
128
,
'0'
),
int
(
line
[
1
],
16
))
_iterRoutes
.
__doc__
=
"""Iterates over all routes
Amongst all returned routes starting with re6st prefix:
- one is the local one with our prefix
- any route with null prefix will be ignored
- other are reachable routes installed by babeld
"""
def
iterRoutes
(
network
,
exclude_prefix
=
None
):
a
=
len
(
network
)
for
iface
,
ip
,
prefix_len
in
_iterRoutes
():
if
ip
[:
a
]
==
network
:
prefix
=
ip
[
a
:
prefix_len
]
if
prefix
and
prefix
!=
exclude_prefix
:
yield
iface
,
prefix
def
decrypt
(
key_path
,
data
):
def
decrypt
(
key_path
,
data
):
p
=
subprocess
.
Popen
(
p
=
subprocess
.
Popen
(
(
'openssl'
,
'rsautl'
,
'-decrypt'
,
'-inkey'
,
key_path
),
(
'openssl'
,
'rsautl'
,
'-decrypt'
,
'-inkey'
,
key_path
),
...
...
re6stnet
View file @
118c1ba4
...
@@ -134,6 +134,11 @@ def maybe_renew(path, cert, info, renew):
...
@@ -134,6 +134,11 @@ def maybe_renew(path, cert, info, renew):
new_path
=
path
+
'.new'
new_path
=
path
+
'.new'
with
open
(
new_path
,
'w'
)
as
f
:
with
open
(
new_path
,
'w'
)
as
f
:
f
.
write
(
pem
)
f
.
write
(
pem
)
try
:
s
=
os
.
stat
(
path
)
os
.
chown
(
new_path
,
s
.
st_uid
,
s
.
st_gid
)
except
OSError
:
pass
os
.
rename
(
new_path
,
path
)
os
.
rename
(
new_path
,
path
)
logging
.
info
(
"%s renewed until %s UTC"
,
logging
.
info
(
"%s renewed until %s UTC"
,
info
,
time
.
asctime
(
time
.
gmtime
(
utils
.
notAfter
(
cert
))))
info
,
time
.
asctime
(
time
.
gmtime
(
utils
.
notAfter
(
cert
))))
...
@@ -274,6 +279,7 @@ def main():
...
@@ -274,6 +279,7 @@ def main():
r_pipe
,
write_pipe
=
os
.
pipe
()
r_pipe
,
write_pipe
=
os
.
pipe
()
read_pipe
=
os
.
fdopen
(
r_pipe
)
read_pipe
=
os
.
fdopen
(
r_pipe
)
peer_db
=
db
.
PeerDB
(
db_path
,
registry
,
config
.
key
,
network
,
prefix
)
peer_db
=
db
.
PeerDB
(
db_path
,
registry
,
config
.
key
,
network
,
prefix
)
cleanup
.
append
(
lambda
:
peer_db
.
cacheMinimize
(
config
.
client_count
))
tunnel_manager
=
tunnel
.
TunnelManager
(
write_pipe
,
peer_db
,
tunnel_manager
=
tunnel
.
TunnelManager
(
write_pipe
,
peer_db
,
config
.
openvpn_args
,
timeout
,
config
.
tunnel_refresh
,
config
.
openvpn_args
,
timeout
,
config
.
tunnel_refresh
,
config
.
client_count
,
config
.
iface_list
,
network
,
prefix
,
config
.
client_count
,
config
.
iface_list
,
network
,
prefix
,
...
...
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