Skip to content

Instantly share code, notes, and snippets.

@masakielastic
Last active March 10, 2026 23:43
Show Gist options
  • Select an option

  • Save masakielastic/ff79ec78e844678f46529ff8edb0bbef to your computer and use it in GitHub Desktop.

Select an option

Save masakielastic/ff79ec78e844678f46529ff8edb0bbef to your computer and use it in GitHub Desktop.
Minimal ReactPHP example for querying and parsing HTTPS DNS records (type 65)
<?php
/*
Minimal ReactPHP example for querying HTTPS DNS Resource Records (type 65).
This script demonstrates how to:
1. Query HTTPS DNS records using ReactPHP DNS
2. Retrieve raw RDATA from the DNS response
3. Parse SVCB/HTTPS wire format
4. Extract ALPN values such as "h2" and "h3"
HTTPS DNS records are defined in RFC 9460 and are used by modern
web clients for service discovery, including HTTP/3 support.
Example DNS query:
dig HTTPS google.com
Example result:
google.com. IN HTTPS 1 . alpn="h2,h3"
Repository / reference implementation:
https://gist.github.com/masakielastic/524e2f123d7f7fefee43c4f9a28d92cf
Requirements:
- PHP
- react/event-loop
- react/dns
*/
require __DIR__ . '/vendor/autoload.php';
use React\EventLoop\Loop;
use React\Dns\Resolver\Factory;
$config = React\Dns\Config\Config::loadSystemConfigBlocking();
if (!$config->nameservers) {
$config->nameservers[] = '8.8.8.8';
}
$factory = new Factory();
$resolver = $factory->create($config);
$resolver->resolveAll('google.com', 65)->then(
function (array $records): void {
$data = $records[0];
$alpns = parseAlpn($data);
var_dump($alpns);
},
function (Throwable $e): void {
echo $e->getMessage() . PHP_EOL;
}
);
Loop::run();
function parseHttpsRR(string $data): array
{
$offset = 0;
$len = strlen($data);
// priority
$priority = unpack('n', substr($data, $offset, 2))[1];
$offset += 2;
// target name
$labelLen = ord($data[$offset]);
$offset++;
if ($labelLen === 0) {
$target = '.';
} else {
$target = substr($data, $offset, $labelLen);
$offset += $labelLen;
}
$params = [];
while ($offset < $len) {
$key = unpack('n', substr($data, $offset, 2))[1];
$offset += 2;
$paramLen = unpack('n', substr($data, $offset, 2))[1];
$offset += 2;
$value = substr($data, $offset, $paramLen);
$offset += $paramLen;
$params[$key] = $value;
}
return [
'priority' => $priority,
'target' => $target,
'params' => $params
];
}
function parseAlpn(string $value): array
{
$offset = 0;
$alpns = [];
while ($offset < strlen($value)) {
$l = ord($value[$offset]);
$offset++;
$alpns[] = substr($value, $offset, $l);
$offset += $l;
}
return $alpns;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment