|
19 | 19 | encryptedBroadcastSwitchoverTime = 1369735200 |
20 | 20 |
|
21 | 21 | import sys |
22 | | -import ConfigParser |
23 | 22 | import Queue |
24 | 23 | from addresses import * |
25 | 24 | import shared |
|
33 | 32 | import random |
34 | 33 | import sqlite3 |
35 | 34 | from time import strftime, localtime, gmtime |
36 | | -import shutil # used for moving the messages.dat file |
37 | 35 | import string |
38 | 36 | import socks |
39 | 37 | import highlevelcrypto |
40 | 38 | from pyelliptic.openssl import OpenSSL |
41 | | -import ctypes |
42 | | -from pyelliptic import arithmetic |
| 39 | +#import ctypes |
43 | 40 | import signal # Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully. |
44 | 41 | # The next 3 are used for the API |
45 | 42 | from SimpleXMLRPCServer import * |
|
49 | 46 | import proofofwork |
50 | 47 |
|
51 | 48 | # Classes |
52 | | -from class_singleListener import * |
53 | 49 | from class_sqlThread import * |
54 | 50 | from class_singleCleaner import * |
55 | 51 | from class_addressGenerator import * |
@@ -223,10 +219,81 @@ def run(self): |
223 | 219 | time.sleep(0.1) |
224 | 220 |
|
225 | 221 |
|
| 222 | +# Only one singleListener thread will ever exist. It creates the |
| 223 | +# receiveDataThread and sendDataThread for each incoming connection. Note |
| 224 | +# that it cannot set the stream number because it is not known yet- the |
| 225 | +# other node will have to tell us its stream number in a version message. |
| 226 | +# If we don't care about their stream, we will close the connection |
| 227 | +# (within the recversion function of the recieveData thread) |
| 228 | + |
| 229 | +class singleListener(threading.Thread): |
| 230 | + |
| 231 | + def __init__(self): |
| 232 | + threading.Thread.__init__(self) |
| 233 | + |
| 234 | + def run(self): |
| 235 | + # We don't want to accept incoming connections if the user is using a |
| 236 | + # SOCKS proxy. If they eventually select proxy 'none' then this will |
| 237 | + # start listening for connections. |
| 238 | + while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS': |
| 239 | + time.sleep(300) |
| 240 | + |
| 241 | + shared.printLock.acquire() |
| 242 | + print 'Listening for incoming connections.' |
| 243 | + shared.printLock.release() |
| 244 | + HOST = '' # Symbolic name meaning all available interfaces |
| 245 | + PORT = shared.config.getint('bitmessagesettings', 'port') |
| 246 | + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| 247 | + # This option apparently avoids the TIME_WAIT state so that we can |
| 248 | + # rebind faster |
| 249 | + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
| 250 | + sock.bind((HOST, PORT)) |
| 251 | + sock.listen(2) |
| 252 | + |
| 253 | + while True: |
| 254 | + # We don't want to accept incoming connections if the user is using |
| 255 | + # a SOCKS proxy. If the user eventually select proxy 'none' then |
| 256 | + # this will start listening for connections. |
| 257 | + while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS': |
| 258 | + time.sleep(10) |
| 259 | + while len(shared.connectedHostsList) > 220: |
| 260 | + shared.printLock.acquire() |
| 261 | + print 'We are connected to too many people. Not accepting further incoming connections for ten seconds.' |
| 262 | + shared.printLock.release() |
| 263 | + time.sleep(10) |
| 264 | + a, (HOST, PORT) = sock.accept() |
| 265 | + |
| 266 | + # The following code will, unfortunately, block an incoming |
| 267 | + # connection if someone else on the same LAN is already connected |
| 268 | + # because the two computers will share the same external IP. This |
| 269 | + # is here to prevent connection flooding. |
| 270 | + while HOST in shared.connectedHostsList: |
| 271 | + shared.printLock.acquire() |
| 272 | + print 'We are already connected to', HOST + '. Ignoring connection.' |
| 273 | + shared.printLock.release() |
| 274 | + a.close() |
| 275 | + a, (HOST, PORT) = sock.accept() |
| 276 | + objectsOfWhichThisRemoteNodeIsAlreadyAware = {} |
| 277 | + a.settimeout(20) |
| 278 | + |
| 279 | + sd = sendDataThread() |
| 280 | + sd.setup( |
| 281 | + a, HOST, PORT, -1, objectsOfWhichThisRemoteNodeIsAlreadyAware) |
| 282 | + sd.start() |
| 283 | + |
| 284 | + rd = receiveDataThread() |
| 285 | + rd.daemon = True # close the main program even if there are threads left |
| 286 | + rd.setup( |
| 287 | + a, HOST, PORT, -1, objectsOfWhichThisRemoteNodeIsAlreadyAware) |
| 288 | + rd.start() |
| 289 | + |
| 290 | + shared.printLock.acquire() |
| 291 | + print self, 'connected to', HOST, 'during INCOMING request.' |
| 292 | + shared.printLock.release() |
| 293 | + |
226 | 294 | # This thread is created either by the synSenderThread(for outgoing |
227 | 295 | # connections) or the singleListenerThread(for incoming connectiosn). |
228 | 296 |
|
229 | | - |
230 | 297 | class receiveDataThread(threading.Thread): |
231 | 298 |
|
232 | 299 | def __init__(self): |
|
0 commit comments