home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / BitTorrent / NatCheck.py < prev    next >
Encoding:
Python Source  |  2003-09-13  |  2.6 KB  |  90 lines

  1. # Written by Bram Cohen
  2. # see LICENSE.txt for license information
  3.  
  4. from cStringIO import StringIO
  5. from socket import error as socketerror
  6.  
  7. protocol_name = 'BitTorrent protocol'
  8.  
  9. # header, reserved, download id, my id, [length, message]
  10.  
  11. class NatCheck:
  12.     def __init__(self, resultfunc, downloadid, peerid, ip, port, rawserver):
  13.         self.resultfunc = resultfunc
  14.         self.downloadid = downloadid
  15.         self.peerid = peerid
  16.         self.ip = ip
  17.         self.port = port
  18.         self.closed = False
  19.         self.buffer = StringIO()
  20.         self.next_len = 1
  21.         self.next_func = self.read_header_len
  22.         try:
  23.             self.connection = rawserver.start_connection((ip, port), self)
  24.             self.connection.write(chr(len(protocol_name)) + protocol_name +
  25.                 (chr(0) * 8) + downloadid)
  26.         except socketerror:
  27.             self.answer(False)
  28.         except IOError:
  29.             self.answer(False)
  30.  
  31.     def answer(self, result):
  32.         self.closed = True
  33.         try:
  34.             self.connection.close()
  35.         except AttributeError:
  36.             pass
  37.         self.resultfunc(result, self.downloadid, self.peerid, self.ip, self.port)
  38.  
  39.     def read_header_len(self, s):
  40.         if ord(s) != len(protocol_name):
  41.             return None
  42.         return len(protocol_name), self.read_header
  43.  
  44.     def read_header(self, s):
  45.         if s != protocol_name:
  46.             return None
  47.         return 8, self.read_reserved
  48.  
  49.     def read_reserved(self, s):
  50.         return 20, self.read_download_id
  51.  
  52.     def read_download_id(self, s):
  53.         if s != self.downloadid:
  54.             return None
  55.         return 20, self.read_peer_id
  56.  
  57.     def read_peer_id(self, s):
  58.         if s != self.peerid:
  59.             return None
  60.         self.answer(True)
  61.         return None
  62.  
  63.     def data_came_in(self, connection, s):
  64.         while True:
  65.             if self.closed:
  66.                 return
  67.             i = self.next_len - self.buffer.tell()
  68.             if i > len(s):
  69.                 self.buffer.write(s)
  70.                 return
  71.             self.buffer.write(s[:i])
  72.             s = s[i:]
  73.             m = self.buffer.getvalue()
  74.             self.buffer.reset()
  75.             self.buffer.truncate()
  76.             x = self.next_func(m)
  77.             if x is None:
  78.                 if not self.closed:
  79.                     self.answer(False)
  80.                 return
  81.             self.next_len, self.next_func = x
  82.  
  83.     def connection_lost(self, connection):
  84.         if not self.closed:
  85.             self.closed = True
  86.             self.resultfunc(False, self.downloadid, self.peerid, self.ip, self.port)
  87.  
  88.     def connection_flushed(self, connection):
  89.         pass
  90.