Changed database structure, introduced address to replace ip, port, proto tuples
[re6stnet.git] / db.py
1 import sqlite3, xmlrpclib, time
2 import utils
3
4 class PeerManager:
5
6 # internal ip = temp arg/attribute
7 def __init__(self, db_path, server, server_port, refresh_time, address, internal_ip, prefix, manual, db_size):
8 self._refresh_time = refresh_time
9 self._address = address
10 self._internal_ip = internal_ip
11 self._prefix = prefix
12 self._server = server
13 self._server_port = server_port
14 self._db_size = db_size
15 self._manual = manual
16
17 self._proxy = xmlrpclib.ServerProxy('http://%s:%u' % (server, server_port))
18
19 utils.log('Connectiong to peers database', 4)
20 self._db = sqlite3.connect(db_path, isolation_level=None)
21 utils.log('Preparing peers database', 4)
22 try:
23 self._db.execute("UPDATE peers SET used = 0")
24 except sqlite3.OperationalError, e:
25 if e.args[0] == 'no such table: peers':
26 raise RuntimeError
27
28 self.next_refresh = time.time()
29
30 def refresh(self):
31 utils.log('Refreshing the peers DB', 2)
32 self._declare()
33 self._populate()
34 self.next_refresh = time.time() + self._refresh_time
35
36 def _declare(self):
37 if self._address != None:
38 utils.log('Sending connection info to server', 3)
39 self._proxy.declare((self._internal_ip, utils.address_list(self._address)))
40 else:
41 utils.log("Warning : couldn't advertise to server, external config not known", 4)
42
43 def _populate(self):
44 utils.log('Populating the peers DB', 2)
45 new_peer_list = self._proxy.getPeerList(self._db_size, self._internal_ip)
46 self._db.executemany("INSERT OR IGNORE INTO peers (prefix, address) VALUES (?,?)", new_peer_list)
47 self._db.execute("DELETE FROM peers WHERE prefix = ?", (self._prefix,))
48 utils.log('New peers : %s' % ', '.join(map(str, new_peer_list)), 5)
49
50 def getUnusedPeers(self, peer_count):
51 return self._db.execute("""SELECT prefix, address FROM peers WHERE used = 0
52 ORDER BY RANDOM() LIMIT ?""", (peer_count,))
53
54 def usePeer(self, prefix):
55 utils.log('Updating peers database : using peer ' + str(prefix), 5)
56 self._db.execute("UPDATE peers SET used = 1 WHERE prefix = ?", (prefix,))
57
58 def unusePeer(self, prefix):
59 utils.log('Updating peers database : unusing peer ' + str(prefix), 5)
60 self._db.execute("UPDATE peers SET used = 0 WHERE id = ?", (prefix,))
61
62 def handle_message(self, msg):
63 script_type, arg = msg.split()
64 if script_type == 'client-connect':
65 utils.log('Incomming connection from %s' % (arg,), 3)
66 elif script_type == 'client-disconnect':
67 utils.log('%s has disconnected' % (arg,), 3)
68 elif script_type == 'route-up':
69 if not self._manual:
70 external_ip, external_port = arg.split(',')
71 new_address = [[external_ip, external_port, 'udp'],
72 [external_ip, external_port, 'tcp-client']]
73 if self._address != new_address:
74 self._address = new_address
75 utils.log('Received new external configuration : %:%s' % (external_ip, external_port), 3)
76 self._declare()
77 else:
78 utils.log('Unknow message recieved from the openvpn pipe : ' + msg, 1)