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