0 && $port < 65536; } function createToken($pdo, $address, $port, $localAddress, $closed) { if (checkAvailable($pdo, $address) <= 0) { return substr(str_shuffle("ABCDEFGHJKLMNPQRSTUVWXYZ123456789"), 0, rand(4, 12))."\n"; } $token = computeToken(TOKEN_MIN_LENGTH); $attempt = 0; while (!insertToken($pdo, $token, $address, $port, $localAddress, $closed) && $attempt < 10) { $length = $attempt < TOKEN_MIN_LENGTH ? TOKEN_MIN_LENGTH : round(TOKEN_MIN_LENGTH+$attempt/2); $token = computeToken($length); $attempt++; } return $token; } function checkAvailable($pdo, $address) { $sql = "SELECT COUNT(*) FROM tokens WHERE assistant = :address"; $stmt = $pdo->prepare($sql); $stmt->bindParam(':address', $address, PDO::PARAM_STR); $stmt->execute(); $stmt->bindColumn(1, $count); $stmt->fetch(PDO::FETCH_BOUND); return TOKEN_LIMIT - $count; } function computeToken($length) { $token = substr(str_shuffle("ABCDEFGHJKLMNPQRSTUVWXYZ123456789"), 0, $length-1); $token .= strtoupper(substr(sha1($token), -1)); return $token; } function insertToken($pdo, $token, $address, $port, $localAddress, $closed) { $sql = "INSERT INTO tokens (token,assistant,port,assistant_local,ts,closed) VALUES (:token,:address,:port,:laddr,:ts,:closed)"; $ts = time(); // assistant 0 not closed, 1 closed -> ts $closed = $closed == 1 ? $ts : 0; $stmt = $pdo->prepare($sql); $stmt->bindParam(':token', $token, PDO::PARAM_STR, 7); $stmt->bindParam(':address', $address, PDO::PARAM_STR); $stmt->bindParam(':port', $port, PDO::PARAM_INT); $stmt->bindParam(':laddr', $localAddress, PDO::PARAM_STR); $stmt->bindParam(':ts', $ts, PDO::PARAM_INT); $stmt->bindParam(':closed', $closed, PDO::PARAM_INT); $success = $stmt->execute(); if (!$success) { // print_r($stmt->errorInfo()); return 0; } else { return 1; } } function removeOldTokens($pdo) { $ts = time(); $delete = "DELETE FROM tokens WHERE ts < ?"; $stmt = $pdo->prepare($delete); $stmt->execute(array($ts-TOKEN_LIFETIME)); } function readBasicToken($pdo, $token) { $sql = "SELECT assistant,port FROM tokens WHERE token = :token"; $stmt = $pdo->prepare($sql); if ($stmt->execute([":token" => $token])) { $stmt->bindColumn(1, $address); $stmt->bindColumn(2, $port); return $stmt->fetch(PDO::FETCH_BOUND) ? "$address*$port" : ""; } else { return ""; } } function readToken($pdo, $token, $version) { $sql = "SELECT assistant,port,assistant_local,closed,assisted,rport,assisted_local,open FROM tokens WHERE token = :token"; $stmt = $pdo->prepare($sql); if ($stmt->execute([":token" => $token])) { $stmt->bindColumn(1, $assistant); $stmt->bindColumn(2, $port); $stmt->bindColumn(3, $assistant_local); $stmt->bindColumn(4, $closed); $stmt->bindColumn(5, $assisted); $stmt->bindColumn(6, $rport); $stmt->bindColumn(7, $assisted_local); $stmt->bindColumn(8, $open); if ($version == "1.3") { return $stmt->fetch(PDO::FETCH_BOUND) ? "$assistant*$port*$closed*$assisted*$rport*$open" : ""; } return $stmt->fetch(PDO::FETCH_BOUND) ? "$assistant*$port*$assistant_local*$closed*$assisted*$rport*$assisted_local*$open" : ""; } else { return ""; } } function updateAssisted($pdo, $token, $open, $address, $rport, $localAddress) { $sql = "UPDATE tokens SET assisted = :address, rport = :rport, assisted_local = :laddr, open = :open, ts = :ts WHERE token = :token"; $ts = time(); // assisted -1 unknown, 0 not open, 1 open -> ts $open = $open == 1 ? $ts : $open; $stmt = $pdo->prepare($sql); $stmt->bindParam(':address', $address, PDO::PARAM_STR); $stmt->bindParam(':open', $open, PDO::PARAM_INT); $stmt->bindParam(':rport', $rport, PDO::PARAM_INT); $stmt->bindParam(':ts', $ts, PDO::PARAM_INT); $stmt->bindParam(':token', $token, PDO::PARAM_STR, 7); $stmt->bindParam(':laddr', $localAddress, PDO::PARAM_STR); $stmt->execute(); } function updateAssistant($pdo, $token, $closed, $localAddress) { $sql = "UPDATE tokens SET assistant_local = :laddr, closed = :closed,ts = :ts WHERE token = :token"; $ts = time(); $closed = $closed == 0 ? 0 : $ts; $stmt = $pdo->prepare($sql); $stmt->bindParam(':closed', $closed, PDO::PARAM_INT); $stmt->bindParam(':ts', $ts, PDO::PARAM_INT); $stmt->bindParam(':token', $token, PDO::PARAM_STR, 7); $stmt->bindParam(':laddr', $localAddress, PDO::PARAM_STR); $stmt->execute(); } function createDatabase($pdo) { $sql = "CREATE TABLE IF NOT EXISTS `tokens` (`token` TEXT,`assistant` TEXT,`port` INTEGER,`assistant_local` TEXT,`closed` INTEGER,`assisted` TEXT,`rport` INTEGER,`assisted_local` TEXT,`open` INTEGER,`ts` INTEGER, PRIMARY KEY(`token`));"; $stmt = $pdo->prepare($sql); $stmt->execute(); // print_r($stmt->errorInfo()); } ?>