~ubuntu-branches/ubuntu/oneiric/bittornado/oneiric

« back to all changes in this revision

Viewing changes to .pc/09_timtuckerfixes.dpatch/BitTornado/BT1/Encrypter.py

  • Committer: Bazaar Package Importer
  • Author(s): Cameron Dale
  • Date: 2010-03-21 14:36:30 UTC
  • Revision ID: james.westby@ubuntu.com-20100321143630-d1zk1zdasaf8125s
Tags: 0.3.18-10
* New patch from upstream's CVS to allow torrents that only have an
  announce list: 30_announce_list_only_torrents.dpatch (Closes: #551766)
* Fix a lot of lintian warnings
  - Update standards version to 3.8.4 (no changes)
* Fix for when compact_reqd is turned off:
  31_fix_for_compact_reqd_off.dpatch (Closes: #574860)
* Switch to the new "3.0 (quilt)" source format

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Written by Bram Cohen
 
2
# see LICENSE.txt for license information
 
3
 
 
4
from cStringIO import StringIO
 
5
from binascii import b2a_hex
 
6
from socket import error as socketerror
 
7
from urllib import quote
 
8
from traceback import print_exc
 
9
from BitTornado.BTcrypto import Crypto
 
10
 
 
11
try:
 
12
    True
 
13
except:
 
14
    True = 1
 
15
    False = 0
 
16
    bool = lambda x: not not x
 
17
 
 
18
DEBUG = False
 
19
 
 
20
MAX_INCOMPLETE = 8
 
21
 
 
22
protocol_name = 'BitTorrent protocol'
 
23
option_pattern = chr(0)*8
 
24
 
 
25
def toint(s):
 
26
    return long(b2a_hex(s), 16)
 
27
 
 
28
def tobinary16(i):
 
29
    return chr((i >> 8) & 0xFF) + chr(i & 0xFF)
 
30
 
 
31
hexchars = '0123456789ABCDEF'
 
32
hexmap = []
 
33
for i in xrange(256):
 
34
    hexmap.append(hexchars[(i&0xF0)/16]+hexchars[i&0x0F])
 
35
 
 
36
def tohex(s):
 
37
    r = []
 
38
    for c in s:
 
39
        r.append(hexmap[ord(c)])
 
40
    return ''.join(r)
 
41
 
 
42
def make_readable(s):
 
43
    if not s:
 
44
        return ''
 
45
    if quote(s).find('%') >= 0:
 
46
        return tohex(s)
 
47
    return '"'+s+'"'
 
48
   
 
49
 
 
50
class IncompleteCounter:
 
51
    def __init__(self):
 
52
        self.c = 0
 
53
    def increment(self):
 
54
        self.c += 1
 
55
    def decrement(self):
 
56
        self.c -= 1
 
57
    def toomany(self):
 
58
        return self.c >= MAX_INCOMPLETE
 
59
    
 
60
incompletecounter = IncompleteCounter()
 
61
 
 
62
 
 
63
# header, options, download id, my id, [length, message]
 
64
 
 
65
class Connection:
 
66
    def __init__(self, Encoder, connection, id,
 
67
                 ext_handshake=False, encrypted = None, options = None):
 
68
        self.Encoder = Encoder
 
69
        self.connection = connection
 
70
        self.connecter = Encoder.connecter
 
71
        self.id = id
 
72
        self.locally_initiated = (id != None)
 
73
        self.readable_id = make_readable(id)
 
74
        self.complete = False
 
75
        self.keepalive = lambda: None
 
76
        self.closed = False
 
77
        self.buffer = ''
 
78
        self.bufferlen = None
 
79
        self.log = None
 
80
        self.read = self._read
 
81
        self.write = self._write
 
82
        self.cryptmode = 0
 
83
        self.encrypter = None
 
84
        if self.locally_initiated:
 
85
            incompletecounter.increment()
 
86
            if encrypted:
 
87
                self.encrypted = True
 
88
                self.encrypter = Crypto(True)
 
89
                self.write(self.encrypter.pubkey+self.encrypter.padding())
 
90
            else:
 
91
                self.encrypted = False
 
92
                self.write(chr(len(protocol_name)) + protocol_name + 
 
93
                    option_pattern + self.Encoder.download_id )
 
94
            self.next_len, self.next_func = 1+len(protocol_name), self.read_header
 
95
        elif ext_handshake:
 
96
            self.Encoder.connecter.external_connection_made += 1
 
97
            if encrypted:   # passed an already running encrypter
 
98
                self.encrypter = encrypted
 
99
                self.encrypted = True
 
100
                self._start_crypto()
 
101
                self.next_len, self.next_func = 14, self.read_crypto_block3c
 
102
            else:
 
103
                self.encrypted = False
 
104
                self.options = options
 
105
                self.write(self.Encoder.my_id)
 
106
                self.next_len, self.next_func = 20, self.read_peer_id
 
107
        else:
 
108
            self.encrypted = None       # don't know yet
 
109
            self.next_len, self.next_func = 1+len(protocol_name), self.read_header
 
110
        self.Encoder.raw_server.add_task(self._auto_close, 30)
 
111
 
 
112
 
 
113
    def _log_start(self):   # only called with DEBUG = True
 
114
        self.log = open('peerlog.'+self.get_ip()+'.txt','a')
 
115
        self.log.write('connected - ')
 
116
        if self.locally_initiated:
 
117
            self.log.write('outgoing\n')
 
118
        else:
 
119
            self.log.write('incoming\n')
 
120
        self._logwritefunc = self.write
 
121
        self.write = self._log_write
 
122
 
 
123
    def _log_write(self, s):
 
124
        self.log.write('w:'+b2a_hex(s)+'\n')
 
125
        self._logwritefunc(s)
 
126
        
 
127
 
 
128
    def get_ip(self, real=False):
 
129
        return self.connection.get_ip(real)
 
130
 
 
131
    def get_id(self):
 
132
        return self.id
 
133
 
 
134
    def get_readable_id(self):
 
135
        return self.readable_id
 
136
 
 
137
    def is_locally_initiated(self):
 
138
        return self.locally_initiated
 
139
 
 
140
    def is_encrypted(self):
 
141
        return bool(self.encrypted)
 
142
 
 
143
    def is_flushed(self):
 
144
        return self.connection.is_flushed()
 
145
 
 
146
    def _read_header(self, s):
 
147
        if s == chr(len(protocol_name))+protocol_name:
 
148
            return 8, self.read_options
 
149
        return None
 
150
 
 
151
    def read_header(self, s):
 
152
        if self._read_header(s):
 
153
            if self.encrypted or self.Encoder.config['crypto_stealth']:
 
154
                return None
 
155
            return 8, self.read_options
 
156
        if self.locally_initiated and not self.encrypted:
 
157
            return None
 
158
        elif not self.Encoder.config['crypto_allowed']:
 
159
            return None
 
160
        if not self.encrypted:
 
161
            self.encrypted = True
 
162
            self.encrypter = Crypto(self.locally_initiated)
 
163
        self._write_buffer(s)
 
164
        return self.encrypter.keylength, self.read_crypto_header
 
165
 
 
166
    ################## ENCRYPTION SUPPORT ######################
 
167
 
 
168
    def _start_crypto(self):
 
169
        self.encrypter.setrawaccess(self._read,self._write)
 
170
        self.write = self.encrypter.write
 
171
        self.read = self.encrypter.read
 
172
        if self.buffer:
 
173
            self.buffer = self.encrypter.decrypt(self.buffer)
 
174
 
 
175
    def _end_crypto(self):
 
176
        self.read = self._read
 
177
        self.write = self._write
 
178
        self.encrypter = None
 
179
 
 
180
    def read_crypto_header(self, s):
 
181
        self.encrypter.received_key(s)
 
182
        self.encrypter.set_skey(self.Encoder.download_id)
 
183
        if self.locally_initiated:
 
184
            if self.Encoder.config['crypto_only']:
 
185
                cryptmode = '\x00\x00\x00\x02'    # full stream encryption
 
186
            else:
 
187
                cryptmode = '\x00\x00\x00\x03'    # header or full stream
 
188
            padc = self.encrypter.padding()
 
189
            self.write( self.encrypter.block3a
 
190
                      + self.encrypter.block3b
 
191
                      + self.encrypter.encrypt(
 
192
                            ('\x00'*8)            # VC
 
193
                          + cryptmode             # acceptable crypto modes
 
194
                          + tobinary16(len(padc))
 
195
                          + padc                  # PadC
 
196
                          + '\x00\x00' ) )        # no initial payload data
 
197
            self._max_search = 520
 
198
            return 1, self.read_crypto_block4a
 
199
        self.write(self.encrypter.pubkey+self.encrypter.padding())
 
200
        self._max_search = 520
 
201
        return 0, self.read_crypto_block3a
 
202
 
 
203
    def _search_for_pattern(self, s, pat):
 
204
        p = s.find(pat)
 
205
        if p < 0:
 
206
            if len(s) >= len(pat):
 
207
                self._max_search -= len(s)+1-len(pat)
 
208
            if self._max_search < 0:
 
209
                self.close()
 
210
                return False
 
211
            self._write_buffer(s[1-len(pat):])
 
212
            return False
 
213
        self._write_buffer(s[p+len(pat):])
 
214
        return True
 
215
 
 
216
    ### INCOMING CONNECTION ###
 
217
 
 
218
    def read_crypto_block3a(self, s):
 
219
        if not self._search_for_pattern(s,self.encrypter.block3a):
 
220
            return -1, self.read_crypto_block3a     # wait for more data
 
221
        return len(self.encrypter.block3b), self.read_crypto_block3b
 
222
 
 
223
    def read_crypto_block3b(self, s):
 
224
        if s != self.encrypter.block3b:
 
225
            return None
 
226
        self.Encoder.connecter.external_connection_made += 1
 
227
        self._start_crypto()
 
228
        return 14, self.read_crypto_block3c
 
229
 
 
230
    def read_crypto_block3c(self, s):
 
231
        if s[:8] != ('\x00'*8):             # check VC
 
232
            return None
 
233
        self.cryptmode = toint(s[8:12]) % 4
 
234
        if self.cryptmode == 0:
 
235
            return None                     # no encryption selected
 
236
        if ( self.cryptmode == 1            # only header encryption
 
237
             and self.Encoder.config['crypto_only'] ):
 
238
            return None
 
239
        padlen = (ord(s[12])<<8)+ord(s[13])
 
240
        if padlen > 512:
 
241
            return None
 
242
        return padlen+2, self.read_crypto_pad3
 
243
 
 
244
    def read_crypto_pad3(self, s):
 
245
        s = s[-2:]
 
246
        ialen = (ord(s[0])<<8)+ord(s[1])
 
247
        if ialen > 65535:
 
248
            return None
 
249
        if self.cryptmode == 1:
 
250
            cryptmode = '\x00\x00\x00\x01'    # header only encryption
 
251
        else:
 
252
            cryptmode = '\x00\x00\x00\x02'    # full stream encryption
 
253
        padd = self.encrypter.padding()
 
254
        self.write( ('\x00'*8)            # VC
 
255
                  + cryptmode             # encryption mode
 
256
                  + tobinary16(len(padd))
 
257
                  + padd )                # PadD
 
258
        if ialen:
 
259
            return ialen, self.read_crypto_ia
 
260
        return self.read_crypto_block3done()
 
261
 
 
262
    def read_crypto_ia(self, s):
 
263
        if DEBUG:
 
264
            self._log_start()
 
265
            self.log.write('r:'+b2a_hex(s)+'(ia)\n')
 
266
            if self.buffer:
 
267
                self.log.write('r:'+b2a_hex(self.buffer)+'(buffer)\n')
 
268
        return self.read_crypto_block3done(s)
 
269
 
 
270
    def read_crypto_block3done(self, ia=''):
 
271
        if DEBUG:
 
272
            if not self.log:
 
273
                self._log_start()
 
274
        if self.cryptmode == 1:     # only handshake encryption
 
275
            assert not self.buffer  # oops; check for exceptions to this
 
276
            self._end_crypto()
 
277
        if ia:
 
278
            self._write_buffer(ia)
 
279
        return 1+len(protocol_name), self.read_encrypted_header
 
280
 
 
281
    ### OUTGOING CONNECTION ###
 
282
 
 
283
    def read_crypto_block4a(self, s):
 
284
        if not self._search_for_pattern(s,self.encrypter.VC_pattern()):
 
285
            return -1, self.read_crypto_block4a     # wait for more data
 
286
        self._start_crypto()
 
287
        return 6, self.read_crypto_block4b
 
288
 
 
289
    def read_crypto_block4b(self, s):
 
290
        self.cryptmode = toint(s[:4]) % 4
 
291
        if self.cryptmode == 1:             # only header encryption
 
292
            if self.Encoder.config['crypto_only']:
 
293
                return None
 
294
        elif self.cryptmode != 2:
 
295
            return None                     # unknown encryption
 
296
        padlen = (ord(s[4])<<8)+ord(s[5])
 
297
        if padlen > 512:
 
298
            return None
 
299
        if padlen:
 
300
            return padlen, self.read_crypto_pad4
 
301
        return self.read_crypto_block4done()
 
302
 
 
303
    def read_crypto_pad4(self, s):
 
304
        # discard data
 
305
        return self.read_crypto_block4done()
 
306
 
 
307
    def read_crypto_block4done(self):
 
308
        if DEBUG:
 
309
            self._log_start()
 
310
        if self.cryptmode == 1:     # only handshake encryption
 
311
            if not self.buffer:  # oops; check for exceptions to this
 
312
                return None
 
313
            self._end_crypto()
 
314
        self.write(chr(len(protocol_name)) + protocol_name + 
 
315
            option_pattern + self.Encoder.download_id)
 
316
        return 1+len(protocol_name), self.read_encrypted_header
 
317
 
 
318
    ### START PROTOCOL OVER ENCRYPTED CONNECTION ###
 
319
 
 
320
    def read_encrypted_header(self, s):
 
321
        return self._read_header(s)
 
322
 
 
323
    ################################################
 
324
 
 
325
    def read_options(self, s):
 
326
        self.options = s
 
327
        return 20, self.read_download_id
 
328
 
 
329
    def read_download_id(self, s):
 
330
        if ( s != self.Encoder.download_id
 
331
             or not self.Encoder.check_ip(ip=self.get_ip()) ):
 
332
            return None
 
333
        if not self.locally_initiated:
 
334
            if not self.encrypted:
 
335
                self.Encoder.connecter.external_connection_made += 1
 
336
            self.write(chr(len(protocol_name)) + protocol_name + 
 
337
                option_pattern + self.Encoder.download_id + self.Encoder.my_id)
 
338
        return 20, self.read_peer_id
 
339
 
 
340
    def read_peer_id(self, s):
 
341
        if not self.encrypted and self.Encoder.config['crypto_only']:
 
342
            return None     # allows older trackers to ping,
 
343
                            # but won't proceed w/ connections
 
344
        if not self.id:
 
345
            self.id = s
 
346
            self.readable_id = make_readable(s)
 
347
        else:
 
348
            if s != self.id:
 
349
                return None
 
350
        self.complete = self.Encoder.got_id(self)
 
351
        if not self.complete:
 
352
            return None
 
353
        if self.locally_initiated:
 
354
            self.write(self.Encoder.my_id)
 
355
            incompletecounter.decrement()
 
356
        self._switch_to_read2()
 
357
        c = self.Encoder.connecter.connection_made(self)
 
358
        self.keepalive = c.send_keepalive
 
359
        return 4, self.read_len
 
360
 
 
361
    def read_len(self, s):
 
362
        l = toint(s)
 
363
        if l > self.Encoder.max_len:
 
364
            return None
 
365
        return l, self.read_message
 
366
 
 
367
    def read_message(self, s):
 
368
        if s != '':
 
369
            self.connecter.got_message(self, s)
 
370
        return 4, self.read_len
 
371
 
 
372
    def read_dead(self, s):
 
373
        return None
 
374
 
 
375
    def _auto_close(self):
 
376
        if not self.complete:
 
377
            self.close()
 
378
 
 
379
    def close(self):
 
380
        if not self.closed:
 
381
            self.connection.close()
 
382
            self.sever()
 
383
 
 
384
    def sever(self):
 
385
        if self.log:
 
386
            self.log.write('closed\n')
 
387
            self.log.close()
 
388
        self.closed = True
 
389
        del self.Encoder.connections[self.connection]
 
390
        if self.complete:
 
391
            self.connecter.connection_lost(self)
 
392
        elif self.locally_initiated:
 
393
            incompletecounter.decrement()
 
394
 
 
395
    def send_message_raw(self, message):
 
396
        self.write(message)
 
397
 
 
398
    def _write(self, message):
 
399
        if not self.closed:
 
400
            self.connection.write(message)
 
401
 
 
402
    def data_came_in(self, connection, s):
 
403
        self.read(s)
 
404
 
 
405
    def _write_buffer(self, s):
 
406
        self.buffer = s+self.buffer
 
407
 
 
408
    def _read(self, s):
 
409
        if self.log:
 
410
            self.log.write('r:'+b2a_hex(s)+'\n')
 
411
        self.Encoder.measurefunc(len(s))
 
412
        self.buffer += s
 
413
        while True:
 
414
            if self.closed:
 
415
                return
 
416
            # self.next_len = # of characters function expects
 
417
            # or 0 = all characters in the buffer
 
418
            # or -1 = wait for next read, then all characters in the buffer
 
419
            # not compatible w/ keepalives, switch out after all negotiation complete
 
420
            if self.next_len <= 0:
 
421
                m = self.buffer
 
422
                self.buffer = ''
 
423
            elif len(self.buffer) >= self.next_len:
 
424
                m = self.buffer[:self.next_len]
 
425
                self.buffer = self.buffer[self.next_len:]
 
426
            else:
 
427
                return
 
428
            try:
 
429
                x = self.next_func(m)
 
430
            except:
 
431
                self.next_len, self.next_func = 1, self.read_dead
 
432
                raise
 
433
            if x is None:
 
434
                self.close()
 
435
                return
 
436
            self.next_len, self.next_func = x
 
437
            if self.next_len < 0:  # already checked buffer
 
438
                return             # wait for additional data
 
439
            if self.bufferlen is not None:
 
440
                self._read2('')
 
441
                return
 
442
 
 
443
    def _switch_to_read2(self):
 
444
        self._write_buffer = None
 
445
        if self.encrypter:
 
446
            self.encrypter.setrawaccess(self._read2,self._write)
 
447
        else:
 
448
            self.read = self._read2
 
449
        self.bufferlen = len(self.buffer)
 
450
        self.buffer = [self.buffer]
 
451
 
 
452
    def _read2(self, s):    # more efficient, requires buffer['',''] & bufferlen
 
453
        if self.log:
 
454
            self.log.write('r:'+b2a_hex(s)+'\n')
 
455
        self.Encoder.measurefunc(len(s))
 
456
        while True:
 
457
            if self.closed:
 
458
                return
 
459
            p = self.next_len-self.bufferlen
 
460
            if self.next_len == 0:
 
461
                m = ''
 
462
            elif s:
 
463
                if p > len(s):
 
464
                    self.buffer.append(s)
 
465
                    self.bufferlen += len(s)
 
466
                    return
 
467
                self.bufferlen = len(s)-p
 
468
                self.buffer.append(s[:p])
 
469
                m = ''.join(self.buffer)
 
470
                if p == len(s):
 
471
                    self.buffer = []
 
472
                else:
 
473
                    self.buffer=[s[p:]]
 
474
                s = ''
 
475
            elif p <= 0:
 
476
                # assert len(self.buffer) == 1
 
477
                s = self.buffer[0]
 
478
                self.bufferlen = len(s)-self.next_len
 
479
                m = s[:self.next_len]
 
480
                if p == 0:
 
481
                    self.buffer = []
 
482
                else:
 
483
                    self.buffer = [s[self.next_len:]]
 
484
                s = ''
 
485
            else:
 
486
                return
 
487
            try:
 
488
                x = self.next_func(m)
 
489
            except:
 
490
                self.next_len, self.next_func = 1, self.read_dead
 
491
                raise
 
492
            if x is None:
 
493
                self.close()
 
494
                return
 
495
            self.next_len, self.next_func = x
 
496
            if self.next_len < 0:  # already checked buffer
 
497
                return             # wait for additional data
 
498
            
 
499
 
 
500
    def connection_flushed(self, connection):
 
501
        if self.complete:
 
502
            self.connecter.connection_flushed(self)
 
503
 
 
504
    def connection_lost(self, connection):
 
505
        if self.Encoder.connections.has_key(connection):
 
506
            self.sever()
 
507
 
 
508
 
 
509
class _dummy_banlist:
 
510
    def includes(self, x):
 
511
        return False
 
512
 
 
513
class Encoder:
 
514
    def __init__(self, connecter, raw_server, my_id, max_len,
 
515
            schedulefunc, keepalive_delay, download_id, 
 
516
            measurefunc, config, bans=_dummy_banlist() ):
 
517
        self.raw_server = raw_server
 
518
        self.connecter = connecter
 
519
        self.my_id = my_id
 
520
        self.max_len = max_len
 
521
        self.schedulefunc = schedulefunc
 
522
        self.keepalive_delay = keepalive_delay
 
523
        self.download_id = download_id
 
524
        self.measurefunc = measurefunc
 
525
        self.config = config
 
526
        self.connections = {}
 
527
        self.banned = {}
 
528
        self.external_bans = bans
 
529
        self.to_connect = []
 
530
        self.paused = False
 
531
        if self.config['max_connections'] == 0:
 
532
            self.max_connections = 2 ** 30
 
533
        else:
 
534
            self.max_connections = self.config['max_connections']
 
535
        schedulefunc(self.send_keepalives, keepalive_delay)
 
536
 
 
537
    def send_keepalives(self):
 
538
        self.schedulefunc(self.send_keepalives, self.keepalive_delay)
 
539
        if self.paused:
 
540
            return
 
541
        for c in self.connections.values():
 
542
            c.keepalive()
 
543
 
 
544
    def start_connections(self, list):
 
545
        if not self.to_connect:
 
546
            self.raw_server.add_task(self._start_connection_from_queue)
 
547
        self.to_connect = list
 
548
 
 
549
    def _start_connection_from_queue(self):
 
550
        if self.connecter.external_connection_made:
 
551
            max_initiate = self.config['max_initiate']
 
552
        else:
 
553
            max_initiate = int(self.config['max_initiate']*1.5)
 
554
        cons = len(self.connections)
 
555
        if cons >= self.max_connections or cons >= max_initiate:
 
556
            delay = 60
 
557
        elif self.paused or incompletecounter.toomany():
 
558
            delay = 1
 
559
        else:
 
560
            delay = 0
 
561
            dns, id, encrypted = self.to_connect.pop(0)
 
562
            self.start_connection(dns, id, encrypted)
 
563
        if self.to_connect:
 
564
            self.raw_server.add_task(self._start_connection_from_queue, delay)
 
565
 
 
566
    def start_connection(self, dns, id, encrypted = None):
 
567
        if ( self.paused
 
568
             or len(self.connections) >= self.max_connections
 
569
             or id == self.my_id
 
570
             or not self.check_ip(ip=dns[0]) ):
 
571
            return True
 
572
        if self.config['crypto_only']:
 
573
            if encrypted is None or encrypted:  # fails on encrypted = 0
 
574
                encrypted = True
 
575
            else:
 
576
                return True
 
577
        for v in self.connections.values():
 
578
            if v is None:
 
579
                continue
 
580
            if id and v.id == id:
 
581
                return True
 
582
            ip = v.get_ip(True)
 
583
            if self.config['security'] and ip != 'unknown' and ip == dns[0]:
 
584
                return True
 
585
        try:
 
586
            c = self.raw_server.start_connection(dns)
 
587
            con = Connection(self, c, id, encrypted = encrypted)
 
588
            self.connections[c] = con
 
589
            c.set_handler(con)
 
590
        except socketerror:
 
591
            return False
 
592
        return True
 
593
 
 
594
    def _start_connection(self, dns, id, encrypted = None):
 
595
        def foo(self=self, dns=dns, id=id, encrypted=encrypted):
 
596
            self.start_connection(dns, id, encrypted)
 
597
        self.schedulefunc(foo, 0)
 
598
 
 
599
    def check_ip(self, connection=None, ip=None):
 
600
        if not ip:
 
601
            ip = connection.get_ip(True)
 
602
        if self.config['security'] and self.banned.has_key(ip):
 
603
            return False
 
604
        if self.external_bans.includes(ip):
 
605
            return False
 
606
        return True
 
607
 
 
608
    def got_id(self, connection):
 
609
        if connection.id == self.my_id:
 
610
            self.connecter.external_connection_made -= 1
 
611
            return False
 
612
        ip = connection.get_ip(True)
 
613
        for v in self.connections.values():
 
614
            if connection is not v:
 
615
                if connection.id == v.id:
 
616
                    if ip == v.get_ip(True):
 
617
                        v.close()
 
618
                    else:
 
619
                        return False
 
620
                if self.config['security'] and ip != 'unknown' and ip == v.get_ip(True):
 
621
                    v.close()
 
622
        return True
 
623
 
 
624
    def external_connection_made(self, connection):
 
625
        if self.paused or len(self.connections) >= self.max_connections:
 
626
            connection.close()
 
627
            return False
 
628
        con = Connection(self, connection, None)
 
629
        self.connections[connection] = con
 
630
        connection.set_handler(con)
 
631
        return True
 
632
 
 
633
    def externally_handshaked_connection_made(self, connection, options,
 
634
                                              already_read, encrypted = None):
 
635
        if ( self.paused
 
636
             or len(self.connections) >= self.max_connections
 
637
             or not self.check_ip(connection=connection) ):
 
638
            connection.close()
 
639
            return False
 
640
        con = Connection(self, connection, None,
 
641
                ext_handshake = True, encrypted = encrypted, options = options)
 
642
        self.connections[connection] = con
 
643
        connection.set_handler(con)
 
644
        if already_read:
 
645
            con.data_came_in(con, already_read)
 
646
        return True
 
647
 
 
648
    def close_all(self):
 
649
        for c in self.connections.values():
 
650
            c.close()
 
651
        self.connections = {}
 
652
 
 
653
    def ban(self, ip):
 
654
        self.banned[ip] = 1
 
655
 
 
656
    def pause(self, flag):
 
657
        self.paused = flag