Small changes in logs
[re6stnet.git] / db.py
1 import sqlite3, socket, xmlrpclib, time, os
2 import utils
3
4
5 class PeerManager:
6
7 # internal ip = temp arg/attribute
8 def __init__(self, db_dir_path, server, server_port, refresh_time, address,
9 internal_ip, prefix, manual, pp , db_size):
10 self._refresh_time = refresh_time
11 self._address = address
12 self._internal_ip = internal_ip
13 self._prefix = prefix
14 self._server = server
15 self._server_port = server_port
16 self._db_size = db_size
17 self._pp = pp
18 self._blacklist = [(prefix,)]
19 self._manual = manual
20
21 self._proxy = xmlrpclib.ServerProxy('http://%s:%u'
22 % (server, server_port))
23
24 utils.log('Connectiong to peers database...', 4)
25 self._db = sqlite3.connect(os.path.join(db_dir_path, 'peers.db'),
26 isolation_level=None)
27 utils.log('Database opened', 5)
28 utils.log('Preparing peers database...', 4)
29 try:
30 self._db.execute("UPDATE peers SET used = 0")
31 self._db.execute("""CREATE TABLE IF NOT EXISTS blacklist (
32 prefix TEXT PRIMARY KEY,
33 flag INTEGER NOT NULL)""")
34 self._db.execute("""CREATE INDEX IF NOT EXISTS
35 blacklist_flag ON blacklist(flag)""")
36 utils.log('Database prepared', 5)
37 except sqlite3.OperationalError, e:
38 if e.args[0] == 'no such table: peers':
39 raise RuntimeError
40 else:
41 utils.log(e, 1)
42 except sqlite3.Error, e:
43 utils.log(e, 1)
44
45 self.next_refresh = time.time()
46
47 def clear_blacklist(self, flag):
48 utils.log('Clearing blacklist from flag %u' % (flag,), 3)
49 try:
50 with self._db:
51 self._db.execute("DELETE FROM blacklist WHERE flag = ?",
52 (flag,))
53 utils.log('Blacklist cleared', 5)
54 except sqlite3.Error, e:
55 utils.log(e, 1)
56
57 def blacklist(self, prefix, flag):
58 utils.log('Blacklisting %s' % (prefix,), 4)
59 try:
60 with self._db:
61 self._db.execute("DELETE FROM peers WHERE prefix = ?",
62 (prefix,))
63 self._db.execute("""INSERT OR REPLACE INTO blacklist
64 VALUES (?,?)""", (prefix, flag))
65 utils.log('%s blacklisted' % (prefix,), 5)
66 except sqlite3.Error, e:
67 utils.log(e, 1)
68
69 def whitelist(self, prefix):
70 utils.log('Unblacklisting %s' % (prefix,), 4)
71 try:
72 with self._db:
73 self._db.execute("DELETE FROM blacklist WHERE prefix = ?", (prefix,))
74 utils.log('%s whitelisted' % (prefix,), 5)
75 except sqlite3.Error, e:
76 utils.log(e, 1)
77
78 def refresh(self):
79 utils.log('Refreshing the peers DB...', 2)
80 try:
81 self._declare()
82 self._populate()
83 utils.log('DB refreshed', 3)
84 self.next_refresh = time.time() + self._refresh_time
85 except socket.error, e:
86 utils.log(e, 4)
87 utils.log('Connection to server failed, retrying in 30s', 2)
88 self.next_refresh = time.time() + 30
89
90 def _declare(self):
91 if self._address != None:
92 utils.log('Sending connection info to server...', 3)
93 self._proxy.declare((self._internal_ip,
94 utils.address_str(self._address)))
95 utils.log('Info sent', 5)
96 else:
97 utils.log("Warning : couldn't send ip, unknown external config", 4)
98
99 def _populate(self):
100 utils.log('Populating the peers DB...', 2)
101 new_peer_list = self._proxy.getPeerList(self._db_size,
102 self._internal_ip)
103 try:
104 with self._db:
105 self._db.execute("""DELETE FROM peers WHERE used <= 0 ORDER BY
106 used,random() LIMIT MAX(0, ? + (SELECT
107 COUNT(*) FROM peers WHERE used <= 0))""",
108 (str(len(new_peer_list) - self._db_size),))
109 self._db.executemany("""INSERT OR IGNORE INTO peers (prefix, address)
110 VALUES (?,?)""", new_peer_list)
111 self._db.execute("""DELETE FROM peers WHERE prefix IN
112 (SELECT prefix FROM blacklist)""")
113 utils.log('DB populated', 3)
114 utils.log('New peers : %s' % ', '.join(map(str, new_peer_list)), 5)
115 except sqlite3.Error, e:
116 utils.log(e, 1)
117
118 def getUnusedPeers(self, peer_count):
119 try:
120 return self._db.execute("""SELECT prefix, address FROM peers WHERE used
121 <= 0 ORDER BY used DESC,RANDOM() LIMIT ?""",
122 (peer_count,))
123 except sqlite3.Error, e:
124 utils.log(e, 1)
125 return [('0', '')]
126
127 def usePeer(self, prefix):
128 utils.log('Updating peers database : using peer ' + str(prefix), 5)
129 try:
130 with self._db:
131 self._db.execute("UPDATE peers SET used = 1 WHERE prefix = ?",
132 (prefix,))
133 utils.log('DB updated', 5)
134 except sqlite3.Error, e:
135 utils.log(e, 1)
136
137 def unusePeer(self, prefix):
138 utils.log('Updating peers database : unusing peer ' + str(prefix), 5)
139 try:
140 with self._db:
141 self._db.execute("UPDATE peers SET used = 0 WHERE prefix = ?",
142 (prefix,))
143 utils.log('DB updated', 5)
144 except sqlite3.Error, e:
145 utils.log(e, 1)
146
147 def flagPeer(self, prefix):
148 utils.log('Updating peers database : flagging peer ' + str(prefix), 5)
149 try:
150 with self._db:
151 self._db.execute("UPDATE peers SET used = -1 WHERE prefix = ?",
152 (prefix,))
153 utils.log('DB updated', 5)
154 except sqlite3.Error, e:
155 utils.log(e, 1)
156
157 def handle_message(self, msg):
158 script_type, arg = msg.split()
159 if script_type == 'client-connect':
160 utils.log('Incomming connection from %s' % (arg,), 3)
161 elif script_type == 'client-disconnect':
162 utils.log('%s has disconnected' % (arg,), 3)
163 elif script_type == 'route-up':
164 if not self._manual:
165 external_ip = arg
166 new_address = list([external_ip, port, proto]
167 for port, proto in self._pp)
168 if self._address != new_address:
169 self._address = new_address
170 utils.log('Received new external ip : %s'
171 % (external_ip,), 3)
172 self._declare()
173 else:
174 utils.log('Unknow message recieved from the openvpn pipe : '
175 + msg, 1)
176