home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.6)
-
- import logging
- log = logging.getLogger('msn.p2p.data2')
- import struct
- import util
- import P2PData
- from P2PData import flagged
-
- class Flags:
- names = {
- 0: 'none',
- 1: 'syn',
- 2: 'r_ack' }
- NONE = 0
- ONE = 1
- UNKNOWN = ONE
- SYNC = ONE
- SYN = ONE
- R_ACK = 2
-
-
- class TFlags:
- names = {
- 0: 'protocol_more',
- 1: 'protocol_start',
- 4: 'msno_more',
- 5: 'msno_start',
- 6: 'file_more',
- 7: 'file_start' }
- PROTO_MORE = 0
- PROTO_START = 1
- MSNO_MORE = 4
- MSNO_START = 5
- FILE_MORE = 6
- FILE_START = 7
-
-
- class P2PManager(P2PData.P2PManager):
-
- def _on_recv_data(self, transport, sender, data, has_footer = True):
- log.info('Recv data: %r, %r, %r', transport, sender, data)
- packet = MSNC12Packet.unpack(data, has_footer = has_footer)
- if has_footer:
- footer = struct.unpack('>L', packet.footer)[0]
- else:
- footer = 0
- ack_id = packet.tlvs.get(2, None)
- if ack_id is not None:
- self._last_acked = ack_id
- self._process_ack(ack_id)
-
- if flagged(packet.flags, Flags.SYNC):
- transport.peer_info = packet.tlvs[1]
-
- if flagged(packet.tf_combo, TFlags.PROTO_START):
- log.info('Got new message')
- msg = self._process_new(sender, packet)
- transport.p2p_clients += 1
- else:
- msg = self._incoming[packet.package_id]
- if flagged(packet.tf_combo, TFlags.MSNO_MORE):
- msg.write(data)
-
- self.event('recv_data')
- if flagged(packet.tf_combo, TFlags.MSNO_MORE) and struct.unpack('>Q', packet.tlvs.get(1, '\x00\x00\x00\x00\x00\x00\x00\x00'))[0] == 0:
- log.info('Received message (transferred = %r)', msg.transferred)
- transport.p2p_clients -= 1
- self._process_msg(packet)
- elif flagged(packet.flags, Flags.R_ACK):
- self.send_ack(transport, sender, packet)
-
-
-
- def send_ack(self, transport, sender, packet):
-
- try:
- id = self._last_acked + 1
- except:
- id = randid()
- finally:
- self._last_acked = None
-
- ack_msg = MSNC12Packet(**vars(packet))
- ack_msg.payload = ''
- ack_msg.tlvs = {
- 2: struct.pack('>I', packet.seqnum + len(packet.payload)) }
- ack_msg.flags = 0
- log.info('ack msg: %r', vars(ack_msg))
- self.send_message(ack_msg)
-
-
- def _process_new(self, sender, packet):
- msg = P2PMessage(sender, None, header.msgid, header.flags, header.session, footer, header.total, content)
- msg = None
- self._incoming[packet.package_id] = msg
- self.event('recv_msg_start', None)
- return msg
-
-
-
- class P2PTransport(P2PData.P2PTransport):
- pass
-
-
- class MSNC12Packet(object):
-
- def __init__(self, **kws):
- util.autoassign(self, kws)
-
-
- def pack(self):
- tlvs2_packed = self.pack_tlvs(self.tlvs2)
- inner_header_len = len(self.tlvs2) + 8
- inner = struct.pack('>BBHI', inner_header_len, self.tf_combo, self.package_id, self.session_id) + tlvs2_packed + self.payload
- tlvs_packed = self.pack_tlvs(self.tlvs)
- outer_header_len = len(self.tlvs) + 8
- outer = struct.pack('>BBHI', outer_header_len, self.flags, len(inner), self.seqnum) + tlvs_packed + inner + self.footer
- return outer
-
-
- def unpack(cls, data, has_footer = True):
- _data = data
- (header_len, opcode, data_len, seqnum) = struct.unpack('>BBHI', data[:8])
- data = data[8:]
- tlvs = data[:header_len - 8]
- data = data[header_len - 8:]
- payload = data[:data_len]
- data = data[data_len:]
- if has_footer:
- footer = data
- else:
- footer = ''
- data = payload
- (header2_len, tf_combo, package_id, session_id) = struct.unpack('>BBHI', data[:8])
- data = data[8:]
- tlvs2 = data[:header2_len - 8]
- data = data[header2_len - 8:]
- payload = data
- return cls(flags = opcode, seqnum = seqnum, tlvs = cls.unpack_tlvs(tlvs), footer = footer, tf_combo = tf_combo, package_id = package_id, session_id = session_id, tlvs2 = cls.unpack_tlvs(tlvs2), payload = payload)
-
- unpack = classmethod(unpack)
-
- def unpack_tlvs(data):
- _data = data
- tlvs = { }
- while data:
- if data[0] == '\x00':
- data = ''
- break
-
- (t, l) = struct.unpack('>BB', data[:2])
- data = data[2:]
- v = data[:l]
- data = data[l:]
- tlvs[t] = v
- return tlvs
-
- unpack_tlvs = staticmethod(unpack_tlvs)
-
- def pack_tlvs(tlvs):
- data = []
- for k, v in tlvs.items():
- data.append(struct.pack('>BB', k, len(v)))
- data.append(v)
-
- data = ''.join(data)
- datalen = len(data)
- missing = 4 - datalen % 4
- if datalen != 4:
- data += missing * '\x00'
-
- return data
-
- pack_tlvs = staticmethod(pack_tlvs)
-
- def __repr__(self):
- return '<%s %s>' % (type(self).__name__, ' '.join((lambda .0: for i in .0:
- '%s=%r' % i)(vars(self).items())))
-
-
-