def _read_packet(self): """ Reads a packet from a socket """ socket_in = self._connection # Read the size of the packet psize = bytearray(3) socket_in.recv_into(psize, 3) size = getSize(psize) + 1 # Read the rest of the packet packet_payload = bytearray(size) socket_in.recv_into(packet_payload, size) # Combine the chunks psize.extend(packet_payload) packetType = getType(psize) if packetType == Flags.ERR: buf = ERR.loadFromPacket(psize) logger.error("error:", buf.errorCode, buf.sqlState, buf.errorMessage) self.close() exit(1) return psize
def init_upstream(self): conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = self.server.settings["server_host"] port = self.server.settings.getint("server_port") user = self.server.settings["server_user"] password = self.server.settings["server_password"] schema = "" conn.connect((host, port)) self.upstream = conn challenge = Challenge.loadFromPacket(self.upstream.recv(10240)) logger.debug("== Greeting ==") dump(challenge.toPacket()) challenge1 = challenge.challenge1 challenge2 = challenge.challenge2 scramble_password = scramble_native_password(password, challenge1 + challenge2) response = Response() response.sequenceId = 1 response.capabilityFlags = 33531397 response.characterSet = 33 response.maxPacketSize = 16777216 response.clientAttributes["_client_name"] = 'pymysql' response.clientAttributes["_pid"] = str(os.getpid()) response.clientAttributes["_client_version"] = '5.7' response.clientAttributes["program_name"] = 'mysql' response.pluginName = 'mysql_native_password' response.username = user response.schema = schema response.authResponse = scramble_password response.removeCapabilityFlag(Flags.CLIENT_COMPRESS) response.removeCapabilityFlag(Flags.CLIENT_SSL) response.removeCapabilityFlag(Flags.CLIENT_LOCAL_FILES) logger.debug("== Auth ==") dump(response.toPacket()) self.upstream.send(response.toPacket()) _packet = self.upstream.recv(10240) logger.debug("== Result ==") dump(_packet) packetType = getType(_packet) if packetType == Flags.ERR: buf = ERR.loadFromPacket(_packet) logger.error("Upstream error:", buf.errorCode, buf.sqlState, buf.errorMessage) self.upstream.close() self.finish() exit(1)
def read_packet(skt): while True: packet = read_server_packet(skt) sequenceId = getSequenceId(packet) print("read packet [%s]:" % (sequenceId, )) dump_my_packet(packet) packetType = getType(packet) if packetType == Flags.ERR: buf = ERR.loadFromPacket(packet) print("error:", buf.errorCode, buf.sqlState, buf.errorMessage) skt.close() exit(1) break if packetType == Flags.EOF or packetType == Flags.OK: break
def get_conn(self): conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = self._connection_settings["host"] port = self._connection_settings.getint("port") user = self._connection_settings["user"] password = self._connection_settings["password"] schema = "" conn.connect((host, port)) self._connection = conn challenge = Challenge.loadFromPacket(self._read_packet()) challenge1 = challenge.challenge1 challenge2 = challenge.challenge2 scramble_password = scramble_native_password(password, challenge1 + challenge2) response = Response() response.sequenceId = 1 response.capabilityFlags = 33531397 response.characterSet = 33 response.maxPacketSize = 16777216 response.clientAttributes["_client_name"] = 'pymysql' response.clientAttributes["_pid"] = str(os.getpid()) response.clientAttributes["_client_version"] = '5.7' response.clientAttributes["program_name"] = 'mysql' response.pluginName = 'mysql_native_password' response.username = user response.schema = schema response.authResponse = scramble_password response.removeCapabilityFlag(Flags.CLIENT_COMPRESS) response.removeCapabilityFlag(Flags.CLIENT_SSL) response.removeCapabilityFlag(Flags.CLIENT_LOCAL_FILES) self._send_packet(response.toPacket()) _packet = self._read_packet() packetType = getType(_packet) if packetType == Flags.ERR: buf = ERR.loadFromPacket(_packet) logger.error("error:", buf.errorCode, buf.sqlState, buf.errorMessage) self.close() exit(1)
def read_binlog(skt): while True: packet = read_server_packet(skt) sequenceId = getSequenceId(packet) packetType = getType(packet) # OK value # timestamp # event_type # server_id # log_pos # flags unpack = struct.unpack('<cIcIIIH', packet[6:26]) # Header timestamp = unpack[1] event_type = byte2int(unpack[2]) server_id = unpack[3] event_size = unpack[4] # position of the next event log_pos = unpack[5] flags = unpack[6] print('timestamp', 'event_type', 'server_id', 'event_size', 'log_pos') print(timestamp, event_type, server_id, event_size, log_pos) dump_my_packet(packet) if event_type == 16: ack = SemiAck("mysql-bin.000001", log_pos) ack.sequenceId = 0 packet = ack.toPacket() send_socket(skt, packet) if packetType == Flags.ERR: buf = ERR.loadFromPacket(packet) print("error:", buf.errorCode, buf.sqlState, buf.errorMessage) skt.close() exit(1) break if packetType == Flags.EOF or packetType == Flags.OK: break
def fetchone(self): while True: self._register_slave() packet = self._read_packet() sequenceId = getSequenceId(packet) packetType = getType(packet) unpack = struct.unpack('<IcIIIH', packet[self.__binlog_header_fix_length:self.__binlog_header_fix_length + 19]) # Header timestamp = unpack[0] event_type = byte2int(unpack[1]) server_id = unpack[2] event_size = unpack[3] log_pos = unpack[4] flags = unpack[5] # 跳过HEARTBEAT_EVENT if event_type == HEARTBEAT_EVENT: continue # 跳过重启后的第一个 FORMAT_DESCRIPTION_EVENT if event_type == FORMAT_DESCRIPTION_EVENT and log_pos == 0: continue # Send SemiAck after xid event if self._connection_settings["semi_sync"]: if event_type in (XID_EVENT, QUERY_EVENT): ack = SemiAck(self.__log_file, log_pos) ack.sequenceId = 0 acp_packet = ack.toPacket() self._send_packet(acp_packet) if packetType == Flags.ERR: buf = ERR.loadFromPacket(packet) logger.error("error:", buf.errorCode, buf.sqlState, buf.errorMessage) self.close() exit(1) return (timestamp, event_type, event_size, log_pos), packet[self.__binlog_header_fix_length:]