def build_packets(self, session_id, action, byte_data, redundancy=False): """ :param session_id: :param action: :param byte_data: :param redundancy:是否开启UDP数据冗余 :return: """ if len(session_id) != 16: raise proto_utils.ProtoError("the size of session_id must be 16") data_len = len(byte_data) if data_len > self.__max_pkt_size: raise proto_utils.ProtoError("the size of byte data muse be less than %s" % self.__max_pkt_size + 1) data_seq = [] tmp_t = self.__get_sent_raw_data(data_len, byte_data, redundancy=redundancy) tot_seq = len(tmp_t) md5_hash = proto_utils.calc_content_md5(byte_data) seq = 1 for block in tmp_t: size = len(block) base_header = self.__build_proto_header(session_id, md5_hash, data_len, size, tot_seq, seq, action) e_hdr = self.wrap_header(base_header) e_body = self.wrap_body(size, block) data_seq.append(b"".join((e_hdr, e_body,))) seq += 1 return data_seq
def build_packet(self, session_id, action, byte_data): if len(session_id) != 16: raise proto_utils.ProtoError("the size of session_id must be 16") seq = [] a, b = ( 0, 60000, ) while 1: _byte_data = byte_data[a:b] if not _byte_data: break rand_length, rand_bytes = self.gen_rand_bytes() pkt_len = len(_byte_data) tot_len = self.get_payload_length(pkt_len) + rand_length base_hdr = self.__build_proto_headr(session_id, rand_length, tot_len, pkt_len, action) e_hdr = self.wrap_header(base_hdr) e_body = b"".join( [rand_bytes, self.wrap_body(pkt_len, _byte_data)]) seq.append(b"".join(( e_hdr, e_body, ))) a, b = ( b, b + 60000, ) return b"".join(seq)
def set_max_pkt_size(self, size): """单个UDP数据包所能传输的数据大小""" min_size = 1000 + self.__fixed_header_size if size < min_size: raise proto_utils.ProtoError( "the value of size must not be less than %s" % min_size) self.__block_size = size
def build_packets(self, session_id, action, byte_data): if len(session_id) != 16: raise proto_utils.ProtoError("the size of session_id must be 16") data_len = len(byte_data) data_seq = [] tmp_t = self.__get_sent_raw_data(data_len, byte_data) tot_seq = len(tmp_t) md5_hash = proto_utils.calc_content_md5(byte_data) seq = 1 for block in tmp_t: size = len(block) base_header = self.__build_proto_header(session_id, md5_hash, data_len, size, tot_seq, seq, action) e_hdr = self.wrap_header(base_header) e_body = self.wrap_body(size, block) data_seq.append(b"".join(( e_hdr, e_body, ))) seq += 1 return data_seq
def parse(self): size = self.__reader.size() if self.__header_ok: if size < self.__tot_length: return e_body = self.__reader.read(self.__tot_length) body = self.unwrap_body(self.__real_length, e_body) if proto_utils.calc_content_md5(body) != self.__payload_md5: raise proto_utils.ProtoError("data has been modified") self.__results.append(( self.__session_id, self.__action, body, )) self.reset() return if self.__reader.size() < self.__fixed_hdr_size: return hdr = self.unwrap_header(self.__reader.read(self.__fixed_hdr_size)) if not hdr: self.reset() return self.__session_id, self.__payload_md5, \ self.__action, self.__tot_length, self.__real_length = self.__parse_header(hdr) self.__header_ok = True
def __init__(self, fixed_header_size): if fixed_header_size < MIN_FIXED_HEADER_SIZE: raise proto_utils.ProtoError( "the header size can not less than %s" % MIN_FIXED_HEADER_SIZE) self.__fixed_header_size = fixed_header_size self.__wait_fill_seq = [] self.__data_area = {}
def unwrap_header(self, header_data): self.__iv = header_data[self.__iv_begin_pos:self.__iv_end_pos] cipher = AES.new(self.__key, AES.MODE_CFB, self.__iv) data = cipher.decrypt(header_data[self.__iv_end_pos:FIXED_HEADER_SIZE]) real_hdr = data[0:tunnel.MIN_FIXED_HEADER_SIZE] # 丢弃误码的包 if self.__const_fill != data[tunnel.MIN_FIXED_HEADER_SIZE:]: raise proto_utils.ProtoError("data wrong") return real_hdr
def build_packet(self, session_id, action, byte_data): if len(session_id) != 16: raise proto_utils.ProtoError("the size of session_id must be 16") pkt_len = len(byte_data) tot_len = self.get_payload_length(pkt_len) payload_md5 = proto_utils.calc_content_md5(byte_data) base_hdr = self.__build_proto_headr(session_id, payload_md5, tot_len, pkt_len, action) e_hdr = self.wrap_header(base_hdr) e_body = self.wrap_body(pkt_len, byte_data) return b"".join((e_hdr, e_body,))
def unwrap_header(self, header_data): self.__iv = header_data[self.__iv_begin_pos:self.__iv_end_pos] data = aes_cfb.decrypt( self.__key, self.__iv, header_data[self.__iv_end_pos:FIXED_HEADER_SIZE]) real_hdr = data[0:tunnel.MIN_FIXED_HEADER_SIZE] # 丢弃误码的包 if self.__const_fill != data[tunnel.MIN_FIXED_HEADER_SIZE:]: raise proto_utils.ProtoError("data wrong") return real_hdr
def __get_pkt(self, pkt): if len(pkt) < self.__pkt_len: raise proto_utils.ProtoError("wrong packet length") return pkt[0:self.__pkt_len]