Ejemplo n.º 1
0
 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);
 }
Ejemplo n.º 2
0
 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;
 }
Ejemplo n.º 3
0
 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;
 }
Ejemplo n.º 4
0
 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;
 }