VerifyLoginTask optimisation: do not copy the entire LoginPacket into the worker thread

this is especially bad considering the fact that the cached buffer is copied. That said, it's only a few kilobytes so it's not a huge problem, but nonetheless...
This commit is contained in:
Dylan K. Taylor 2020-06-17 17:46:22 +01:00
parent 57a310230a
commit 09771849ae

View File

@ -35,10 +35,12 @@ use function json_decode;
use function ltrim; use function ltrim;
use function openssl_verify; use function openssl_verify;
use function ord; use function ord;
use function serialize;
use function str_split; use function str_split;
use function strlen; use function strlen;
use function strtr; use function strtr;
use function time; use function time;
use function unserialize;
use function wordwrap; use function wordwrap;
use const OPENSSL_ALGO_SHA384; use const OPENSSL_ALGO_SHA384;
@ -48,8 +50,10 @@ class VerifyLoginTask extends AsyncTask{
private const CLOCK_DRIFT_MAX = 60; private const CLOCK_DRIFT_MAX = 60;
/** @var LoginPacket */ /** @var string */
private $packet; private $chainJwts;
/** @var string */
private $clientDataJwt;
/** /**
* @var string|null * @var string|null
@ -66,23 +70,25 @@ class VerifyLoginTask extends AsyncTask{
private $authenticated = false; private $authenticated = false;
public function __construct(Player $player, LoginPacket $packet){ public function __construct(Player $player, LoginPacket $packet){
$this->storeLocal($player); $this->storeLocal([$player, $packet]);
$this->packet = $packet; $this->chainJwts = serialize($packet->chainData["chain"]);
$this->clientDataJwt = $packet->clientDataJwt;
} }
public function onRun(){ public function onRun(){
$packet = $this->packet; //Get it in a local variable to make sure it stays unserialized /** @var string[] $chainJwts */
$chainJwts = unserialize($this->chainJwts); //Get it in a local variable to make sure it stays unserialized
try{ try{
$currentKey = null; $currentKey = null;
$first = true; $first = true;
foreach($packet->chainData["chain"] as $jwt){ foreach($chainJwts as $jwt){
$this->validateToken($jwt, $currentKey, $first); $this->validateToken($jwt, $currentKey, $first);
$first = false; $first = false;
} }
$this->validateToken($packet->clientDataJwt, $currentKey); $this->validateToken($this->clientDataJwt, $currentKey);
$this->error = null; $this->error = null;
}catch(VerifyLoginException $e){ }catch(VerifyLoginException $e){
@ -160,12 +166,15 @@ class VerifyLoginTask extends AsyncTask{
} }
public function onCompletion(Server $server){ public function onCompletion(Server $server){
/** @var Player $player */ /**
$player = $this->fetchLocal(); * @var Player $player
* @var LoginPacket $packet
*/
[$player, $packet] = $this->fetchLocal();
if(!$player->isConnected()){ if(!$player->isConnected()){
$server->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified"); $server->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified");
}else{ }else{
$player->onVerifyCompleted($this->packet, $this->error, $this->authenticated); $player->onVerifyCompleted($packet, $this->error, $this->authenticated);
} }
} }
} }