From e13d28ecda74bc50de3dda89f5b90697082820bd Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Tue, 8 May 2018 11:08:34 +0000 Subject: [PATCH] More bugfixes --- server.php | 5 ++- src/Socket.php | 8 +++- src/danog/MadelineProto/Connection.php | 8 +++- src/danog/MadelineProto/Server/Proxy.php | 47 +++++++++++++++--------- 4 files changed, 46 insertions(+), 22 deletions(-) diff --git a/server.php b/server.php index db60e3b8..87d98f0d 100644 --- a/server.php +++ b/server.php @@ -1,6 +1,9 @@ AF_INET, 'protocol' => 0, 'address' => 'localhost', 'port' => 8002, 'handler' => '\danog\MadelineProto\Server\Proxy', 'extra' => ['madeline' => new \danog\MadelineProto\API(['app_info' => ['api_id' => 6, 'api_hash' => 'eb06d4abfb49dc3eeb1aeb98ae0f581e']]), 'secret' => 'pony']]); +$handler = new \danog\MadelineProto\Server(['type' => AF_INET, 'protocol' => 0, 'address' => '0.0.0.0', 'port' => 7777, 'handler' => '\danog\MadelineProto\Server\Proxy', 'extra' => ['madeline' => new \danog\MadelineProto\API('proxy.madeline', ['app_info' => ['api_id' => 6, 'api_hash' => 'eb06d4abfb49dc3eeb1aeb98ae0f581e']]), 'secret' => hex2bin($secret), 'timeout' => 30]]); $handler->start(); diff --git a/src/Socket.php b/src/Socket.php index 2521c35e..21c3573d 100644 --- a/src/Socket.php +++ b/src/Socket.php @@ -118,12 +118,14 @@ If not, see . public function read(int $length, int $flags = 0) { $packet = ''; + $try = 0; while (strlen($packet) < $length) { $read = stream_get_contents($this->sock, $length - strlen($packet)); - if ($read === false || strlen($read) === 0) { + if ($read === false || (strlen($read) === 0 && $try > 10)) { throw new \danog\MadelineProto\NothingInTheSocketException('Nothing in the socket!'); } $packet .= $read; + $try++; } return $packet; @@ -283,12 +285,14 @@ if (!extension_loaded('pthreads')) { public function read(int $length, int $flags = 0) { $packet = ''; + $try = 0; while (strlen($packet) < $length) { $read = socket_read($this->sock, $length - strlen($packet), $flags); - if ($read === false || strlen($read) === 0) { + if ($read === false || (strlen($read) === 0 && $try > 10)) { throw new \danog\MadelineProto\NothingInTheSocketException('Nothing in the socket!'); } $packet .= $read; + $try++; } return $packet; diff --git a/src/danog/MadelineProto/Connection.php b/src/danog/MadelineProto/Connection.php index da5535eb..7346451b 100644 --- a/src/danog/MadelineProto/Connection.php +++ b/src/danog/MadelineProto/Connection.php @@ -69,6 +69,11 @@ class Connection - https - udp */ + if ($proxy === '\\MTProxySocket') { + $proxy = '\\Socket'; + $protocol = 'obfuscated2'; + } + $this->protocol = $protocol; $this->timeout = $timeout; $this->ipv6 = $ipv6; @@ -76,7 +81,7 @@ class Connection $this->port = $port; $this->proxy = $proxy; $this->extra = $extra; - if (($has_proxy = $proxy !== '\\Socket') && !isset(class_implements($proxy)['danog\\MadelineProto\\Proxy'])) { + if (($has_proxy = !in_array($proxy, ['\\MTProxySocket', '\\Socket'])) && !isset(class_implements($proxy)['danog\\MadelineProto\\Proxy'])) { throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['proxy_class_invalid']); } switch ($this->protocol) { @@ -135,6 +140,7 @@ class Connection $random = $this->random(64); } while (in_array(substr($random, 0, 4), ['PVrG', 'GET ', 'POST', 'HEAD', str_repeat(chr(238), 4)]) || $random[0] === chr(0xef) || substr($random, 4, 4) === "\0\0\0\0"); $random[56] = $random[57] = $random[58] = $random[59] = chr(0xef); + $reversed = strrev(substr($random, 8, 48)); $this->obfuscated = ['encryption' => new \phpseclib\Crypt\AES('ctr'), 'decryption' => new \phpseclib\Crypt\AES('ctr')]; $this->obfuscated['encryption']->enableContinuousBuffer(); diff --git a/src/danog/MadelineProto/Server/Proxy.php b/src/danog/MadelineProto/Server/Proxy.php index c572a26c..8e4d5628 100644 --- a/src/danog/MadelineProto/Server/Proxy.php +++ b/src/danog/MadelineProto/Server/Proxy.php @@ -16,20 +16,20 @@ namespace danog\MadelineProto\Server; /* * Socket handler for server */ -class Handler extends \danog\MadelineProto\Connection +class Proxy extends \danog\MadelineProto\Connection { use \danog\MadelineProto\Tools; private $madeline; public function __magic_construct($socket, $extra, $ip, $port, $protocol, $timeout, $ipv6) { + \danog\MadelineProto\Logger::log('Got connection '.getmypid().'!'); \danog\MadelineProto\Magic::$pid = getmypid(); $this->sock = $socket; $this->sock->setBlocking(true); $this->must_open = false; - $timeout = 2; - $this->sock->setOption(\SOL_SOCKET, \SO_RCVTIMEO, $timeout); - $this->sock->setOption(\SOL_SOCKET, \SO_SNDTIMEO, $timeout); + $this->sock->setOption(\SOL_SOCKET, \SO_RCVTIMEO, $extra['timeout']); + $this->sock->setOption(\SOL_SOCKET, \SO_SNDTIMEO, $extra['timeout']); $this->logger = new \danog\MadelineProto\Logger(3); $this->extra = $extra; } @@ -46,39 +46,50 @@ class Handler extends \danog\MadelineProto\Connection $random = $this->sock->read(64); $reversed = strrev(substr($random, 8, 48)); + $key = substr($random, 8, 32); + $keyRev = substr($reversed, 0, 32); if (isset($this->extra['secret'])) { - $random = substr_replace($random, hash('sha256', $key.$this->extra['secret'], true), 32, 8); + $key = hash('sha256', $key.$this->extra['secret'], true); + $keyRev = hash('sha256', $keyRev.$this->extra['secret'], true); } $this->obfuscated = ['encryption' => new \phpseclib\Crypt\AES('ctr'), 'decryption' => new \phpseclib\Crypt\AES('ctr')]; $this->obfuscated['encryption']->enableContinuousBuffer(); $this->obfuscated['decryption']->enableContinuousBuffer(); - $this->obfuscated['decryption']->setKey(substr($random, 8, 32)); + $this->obfuscated['decryption']->setKey($key); $this->obfuscated['decryption']->setIV(substr($random, 40, 16)); - $this->obfuscated['encryption']->setKey(substr($reversed, 0, 32)); + $this->obfuscated['encryption']->setKey($keyRev); $this->obfuscated['encryption']->setIV(substr($reversed, 32, 16)); - $random = substr_replace($random, substr(@$this->obfuscated['encryption']->encrypt($random), 56, 8), 56, 8); - - $random[56] = $random[57] = $random[58] = $random[59] = chr(0xef); + $random = substr_replace($random, substr(@$this->obfuscated['decryption']->encrypt($random), 56, 8), 56, 8); if (substr($random, 56, 4) !== str_repeat(chr(0xef), 4)) { throw new \danog\MadelineProto\Exception('Wrong protocol version'); } - $socket = $this->extra['madeline']->API->datacenter->sockets[unpack('v', substr($random, 60, 2)[1]]; - $socket->close_and_reopen(); + $dc = abs(unpack('s', substr($random, 60, 2))[1]); + + $socket = $this->extra['madeline']->API->datacenter->sockets[$dc]; + $socket->__construct($socket->proxy, $socket->extra, $socket->ip, $socket->port, $socket->protocol, $this->extra['timeout'], $socket->ipv6); + + $write = []; + $except = []; while (true) { pcntl_signal_dispatch(); try { - $time = time(); - $socket->send_message($this->read_message()); + $read = [$this->getSocket(), $socket->getSocket()]; + \Socket::select($read, $write, $except, 2); + if (isset($read[0])) { + \danog\MadelineProto\Logger::log("Will write to DC $dc on ".\danog\MadelineProto\Magic::$pid); + $socket->send_message($this->read_message()); + } + if (isset($read[1])) { + \danog\MadelineProto\Logger::log("Will read from DC $dc on ".\danog\MadelineProto\Magic::$pid); + $this->send_message($socket->read_message()); + } } catch (\danog\MadelineProto\NothingInTheSocketException $e) { echo $e; - if (time() - $time < 2) { - exit(); - } - continue; + exit(); } } }