MediaWiki master
DnsSrvDiscoverer.php
Go to the documentation of this file.
1<?php
9namespace Wikimedia;
10
18 private $service;
19
23 private $protocol;
24
28 private $domain;
29
33 private $resolver;
34
46 public function __construct(
47 string $service,
48 string $protocol = 'tcp',
49 ?string $domain = null,
50 ?callable $resolver = null
51 ) {
52 $this->service = $service;
53 $this->protocol = $protocol;
54 $this->domain = $domain;
55
56 $this->resolver = $resolver ?? static function ( $srv ) {
57 return dns_get_record( $srv, DNS_SRV );
58 };
59 }
60
68 public function getRecords() {
69 $result = [];
70
71 $records = ( $this->resolver )( $this->getSrvName() );
72
73 // Respect RFC 2782 with regard to a single '.' entry denoting a valid
74 // empty response
75 if (
76 !$records
77 || ( count( $records ) === 1 && $records[0]['target'] === '.' )
78 ) {
79 return $result;
80 }
81
82 foreach ( $records as $record ) {
83 $result[] = [
84 'target' => $record['target'],
85 'port' => (int)$record['port'],
86 'pri' => (int)$record['pri'],
87 'weight' => (int)$record['weight'],
88 ];
89 }
90
91 return $result;
92 }
93
101 public function getServers() {
102 $records = $this->getRecords();
103
104 usort( $records, static fn ( $a, $b ) =>
105 $a['pri'] <=> $b['pri'] ?:
106 ( mt_rand( 0, 1 ) ? 1 : -1 )
107 );
108
109 $serversAndPorts = [];
110
111 foreach ( $records as $record ) {
112 $serversAndPorts[] = [ $record['target'], $record['port'] ];
113 }
114
115 return $serversAndPorts;
116 }
117
121 public function getSrvName(): string {
122 $srv = "_{$this->service}._{$this->protocol}";
123
124 if ( $this->domain === null || $this->domain === '' ) {
125 return $srv;
126 }
127
128 return "$srv.{$this->domain}";
129 }
130}
131
133class_alias( DnsSrvDiscoverer::class, 'DnsSrvDiscoverer' );
__construct(string $service, string $protocol='tcp', ?string $domain=null, ?callable $resolver=null)
Construct a new discoverer for the given domain, service, and protocol.
getServers()
Performs discovery for the domain, service, and protocol, and returns a list of resolved server name/...
getRecords()
Queries the resolver for an SRV resource record matching the service, protocol, and domain and return...
getSrvName()
Returns the SRV resource record name.