public function stdin($buf) { // from mysqld to client. if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log('MysqlProxy: Server --> Client: ' . Daemon::exportBytes($buf) . "\n\n"); } $this->downstream->write($buf); }
public function read($connId, $n) { if (!isset($this->buf[$connId])) { return FALSE; } if (isset($this->readEvents[$connId])) { if (Daemon::$useSockets) { $read = socket_read(Daemon::$worker->pool[$connId], $n); if ($read === FALSE) { $no = socket_last_error(Daemon::$worker->pool[$connId]); if ($no !== 11) { Daemon::log(get_class($this) . '::' . __METHOD__ . ': connId = ' . $connId . '. Socket error. (' . $no . '): ' . socket_strerror($no)); $this->onFailureEvent($connId, array()); } } } else { $read = fread(Daemon::$worker->pool[$connId], $n); } } else { $read = event_buffer_read($this->buf[$connId], $n); } if ($read === '' || $read === NULL || $read === FALSE) { if (Daemon::$settings['logreads']) { Daemon::log('read(' . $connId . ',' . $n . ') interrupted.'); } unset(Daemon::$worker->readPoolState[$connId]); return FALSE; } if (Daemon::$settings['logreads']) { Daemon::log('read(' . $connId . ',' . $n . ',[' . gettype($read) . '-' . ($read === FALSE ? 'false' : strlen($read)) . ':' . Daemon::exportBytes($read) . ']).'); } return $read; }
public function stdin($buf) { $this->buf .= $buf; if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log('Server --> Client: ' . Daemon::exportBytes($buf) . "\n\n"); } start: $this->buflen = strlen($this->buf); if (($packet = $this->getPacketHeader()) === FALSE) { return; } $this->seq = $packet[1] + 1; if ($this->cstate === 0) { if ($this->buflen < 4 + $packet[0]) { return; } // no whole packet yet $this->cstate = 1; $p = 4; $this->protover = ord(binarySubstr($this->buf, $p++, 1)); $this->serverver = ''; while ($p < $this->buflen) { $c = binarySubstr($this->buf, $p++, 1); if ($c === "") { break; } $this->serverver .= $c; } $this->threadId = $this->bytes2int(binarySubstr($this->buf, $p, 4)); $p += 4; $this->scramble = binarySubstr($this->buf, $p, 8); $p += 9; $this->serverCaps = $this->bytes2int(binarySubstr($this->buf, $p, 2)); $p += 2; $this->serverLang = ord(binarySubstr($this->buf, $p++, 1)); $this->serverStatus = $this->bytes2int(binarySubstr($this->buf, $p, 2)); $p += 2; $p += 13; $restScramble = binarySubstr($this->buf, $p, 12); $this->scramble .= $restScramble; $p += 13; $this->auth(); } else { if ($this->buflen < 4 + $packet[0]) { return; } // not whole packet yet $p = 4; $fieldCount = ord(binarySubstr($this->buf, $p, 1)); $p += 1; if ($fieldCount === 0xff) { $u = unpack('v', binarySubstr($this->buf, $p, 2)); $p += 2; $this->errno = $u[1]; $state = binarySubstr($this->buf, $p, 6); $p = +6; $this->errmsg = binarySubstr($this->buf, $p, $packet[0] + 4 - $p); $this->onError(); } elseif ($fieldCount === 0x0) { if ($this->cstate === 2) { $this->cstate = 4; } $this->affectedRows = $this->parseEncodedBinary($this->buf, $p); $this->insertId = $this->parseEncodedBinary($this->buf, $p); $u = unpack('v', binarySubstr($this->buf, $p, 2)); $p += 2; $this->serverStatus = $u[1]; $u = unpack('v', binarySubstr($this->buf, $p, 2)); $p += 2; $this->warnCount = $u[1]; $this->message = binarySubstr($this->buf, $p, $packet[0] + 4 - $p); $this->onResultDone(); } elseif ($fieldCount === 0xfe) { ++$this->instate; if ($this->instate === 3) { $this->onResultDone(); } } else { --$p; if ($this->instate === 0) { $extra = $this->parseEncodedBinary($this->buf, $p); ++$this->instate; } elseif ($this->instate === 1) { $field = array(); $field['catalog'] = $this->parseEncodedString($this->buf, $p); $field['db'] = $this->parseEncodedString($this->buf, $p); $field['table'] = $this->parseEncodedString($this->buf, $p); $field['org_table'] = $this->parseEncodedString($this->buf, $p); $field['name'] = $this->parseEncodedString($this->buf, $p); $field['org_name'] = $this->parseEncodedString($this->buf, $p); ++$p; // filler $u = unpack('v', binarySubstr($this->buf, $p, 2)); $p += 2; $field['charset'] = $u[1]; $u = unpack('V', binarySubstr($this->buf, $p, 4)); $p += 4; $field['length'] = $u[1]; $field['type'] = ord(binarySubstr($this->buf, $p, 1)); ++$p; $u = unpack('v', binarySubstr($this->buf, $p, 2)); $p += 2; $field['flags'] = $u[1]; $field['decimals'] = ord(binarySubstr($this->buf, $p, 1)); ++$p; $this->resultFields[] = $field; } elseif ($this->instate === 2) { $row = array(); for ($i = 0, $nf = sizeof($this->resultFields); $i < $nf; ++$i) { $row[$this->resultFields[$i]['name']] = $this->parseEncodedString($this->buf, $p); } $this->resultRows[] = $row; } } } $this->buf = binarySubstr($this->buf, 4 + $packet[0]); goto start; }
public function stdin($buf) { $this->buf .= $buf; if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log('Server --> Client: ' . Daemon::exportBytes($buf) . "\n\n"); } start: $this->buflen = strlen($this->buf); if ($this->buflen < 5) { return; } // Not enough data buffered yet $type = binarySubstr($this->buf, 0, 1); list(, $length) = unpack('N', binarySubstr($this->buf, 1, 4)); $length -= 4; if ($this->buflen < 5 + $length) { return; } // Not enough data buffered yet $packet = binarySubstr($this->buf, 5, $length); $this->buf = binarySubstr($this->buf, 5 + $length); if ($type === 'R') { list(, $authType) = unpack('N', $packet); if ($authType === 0) { if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log(__CLASS__ . ': auth. ok.'); } $this->cstate = 4; // Auth. ok foreach ($this->onConnected as $cb) { call_user_func($cb, $this, TRUE); } } elseif ($authType === 2) { Daemon::log(__CLASS__ . ': Unsupported authentication method: KerberosV5.'); $this->cstate = 3; // Auth. error $this->finish(); // Unsupported, finish } elseif ($authType === 3) { $this->sendPacket('p', $this->password); // Password Message $this->cstate = 2; // Auth. packet sent } elseif ($authType === 4) { $salt = binarySubstr($packet, 4, 2); $this->sendPacket('p', crypt($this->password, $this->user)); // Password Message $this->cstate = 2; // Auth. packet sent } elseif ($authType === 5) { $salt = binarySubstr($packet, 4, 4); $this->sendPacket('p', 'md5' . md5(md5($this->password, $this->user) . $salt)); // Password Message $this->cstate = 2; // Auth. packet sent } elseif ($authType === 6) { Daemon::log(__CLASS__ . ': Unsupported authentication method: SCM.'); $this->cstate = 3; // Auth. error $this->finish(); // Unsupported, finish } elseif ($authType == 9) { Daemon::log(__CLASS__ . ': Unsupported authentication method: GSS.'); $this->cstate = 3; // Auth. error $this->finish(); // Unsupported, finish } } elseif ($type === 'T') { list(, $numfields) = unpack('n', binarySubstr($packet, 0, 2)); $p = 2; for ($i = 0; $i < $numfields; ++$i) { list($name) = $this->decodeNULstrings($packet, 1, $p); $field = unpack('NtableOID/nattrNo/NdataType/ndataTypeSize/NtypeMod/nformat', binarySubstr($packet, $p, 18)); $p += 18; $field['name'] = $name; $this->resultFields[] = $field; } } elseif ($type === 'D') { list(, $numfields) = unpack('n', binarySubstr($packet, 0, 2)); $p = 2; $row = array(); for ($i = 0; $i < $numfields; ++$i) { list(, $length) = unpack('N', binarySubstr($packet, $p, 4)); $p += 4; if ($length === 4294967295.0) { $length = -1; } // hack if ($length === -1) { $value = NULL; } else { $value = binarySubstr($packet, $p, $length); $p += $length; } $row[$this->resultFields[$i]['name']] = $value; } $this->resultRows[] = $row; } elseif ($type === 'G') { // The backend is ready to copy data from the frontend to a table; see Section 45.2.5. if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log(__CLASS__ . ': Caught CopyInResponse'); } } elseif ($type === 'H') { // The backend is ready to copy data from a table to the frontend; see Section 45.2.5. if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log(__CLASS__ . ': Caught CopyOutResponse'); } } elseif ($type === 'C') { $type = binarySubstr($packet, 0, 1); if ($type === 'S' || $type === 'P') { list($name) = $this->decodeNULstrings(binarySubstr($packet, 1)); } else { $tag = $this->decodeNULstrings($packet); $tag = explode(' ', $tag[0]); if ($tag[0] === 'INSERT') { $this->insertId = $tag[1]; $this->insertNum = $tag[2]; } elseif ($tag[0] === 'DELETE' || $tag[0] === 'UPDATE' || $tag[0] === 'MOVE' || $tag[0] === 'FETCH' || $tag[0] === 'COPY') { $this->affectedRows = $tag[1]; } } $this->onResultDone(); } elseif ($type === 'n') { $this->onResultDone(); } elseif ($type === 'E') { $code = ord($packet); $message = ''; foreach ($this->decodeNULstrings(binarySubstr($packet, 1), 0xff) as $p) { if ($message !== '') { $message .= ' '; $p = binarySubstr($p, 1); } $message .= $p; } $this->errno = -1; $this->errmsg = $message; if ($this->cstate == 2) { foreach ($this->onConnected as $cb) { call_user_func($cb, $this, FALSE); } $this->cstate = 3; } $this->onError(); if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log(__CLASS__ . ': Error response caught (0x' . dechex($code) . '): ' . $message); } } elseif ($type === 'I') { $this->errno = -1; $this->errmsg = 'Query was empty'; $this->onError(); } elseif ($type === 'S') { if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log(__CLASS__ . ': Caught PortalSuspended'); } } elseif ($type === 'S') { $u = $this->decodeNULstrings($packet, 2); if (isset($u[0])) { $this->parameters[$u[0]] = isset($u[1]) ? $u[1] : NULL; if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log(__CLASS__ . ': Parameter ' . $u[0] . ' = \'' . $this->parameters[$u[0]] . '\''); } } } elseif ($type === 'K') { list(, $this->backendKey) = unpack('N', $packet); $this->backendKey = isset($u[1]) ? $u[1] : NULL; if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log(__CLASS__ . ': BackendKey is ' . $this->backendKey); } } elseif ($type === 'Z') { $this->status = $packet; if (Daemon::$settings['mod' . $this->appInstance->modname . 'protologging']) { Daemon::log(__CLASS__ . ': Ready For Query. Status: ' . $this->status); } } else { Daemon::log(__CLASS__ . ': Caught message with unsupported type - ' . $type); } goto start; }