]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/libs/DnsSrvDiscoverer.php
MediaWiki 1.30.2
[autoinstalls/mediawiki.git] / includes / libs / DnsSrvDiscoverer.php
1 <?php
2 /**
3  * Service discovery using DNS SRV records
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  * http://www.gnu.org/copyleft/gpl.html
19  *
20  * @file
21  */
22
23 /**
24  * @since 1.29
25  */
26 class DnsSrvDiscoverer {
27         /**
28          * @var string
29          */
30         private $domain;
31
32         /**
33          * @param string $domain
34          */
35         public function __construct( $domain ) {
36                 $this->domain = $domain;
37         }
38
39         /**
40          * Fetch the servers with a DNS SRV request
41          *
42          * @return array
43          */
44         public function getServers() {
45                 $result = [];
46                 foreach ( $this->getDnsRecords() as $record ) {
47                         $result[] = [
48                                 'target' => $record['target'],
49                                 'port' => $record['port'],
50                                 'pri' => $record['pri'],
51                                 'weight' => $record['weight'],
52                         ];
53                 }
54
55                 return $result;
56         }
57
58         /**
59          * Pick a server according to the priority fields.
60          * Note that weight is currently ignored.
61          *
62          * @param array $servers from getServers
63          * @return array|bool
64          */
65         public function pickServer( array $servers ) {
66                 if ( !$servers ) {
67                         return false;
68                 }
69
70                 $srvsByPrio = [];
71                 foreach ( $servers as $server ) {
72                         $srvsByPrio[$server['pri']][] = $server;
73                 }
74
75                 $min = min( array_keys( $srvsByPrio ) );
76                 if ( count( $srvsByPrio[$min] ) == 1 ) {
77                         return $srvsByPrio[$min][0];
78                 } else {
79                         // Choose randomly
80                         $rand = mt_rand( 0, count( $srvsByPrio[$min] ) - 1 );
81
82                         return $srvsByPrio[$min][$rand];
83                 }
84         }
85
86         /**
87          * @param array $server
88          * @param array $servers
89          * @return array[]
90          */
91         public function removeServer( $server, array $servers ) {
92                 foreach ( $servers as $i => $srv ) {
93                         if ( $srv['target'] === $server['target'] && $srv['port'] === $server['port'] ) {
94                                 unset( $servers[$i] );
95                                 break;
96                         }
97                 }
98
99                 return array_values( $servers );
100         }
101
102         /**
103          * @return array[]
104          */
105         protected function getDnsRecords() {
106                 return dns_get_record( $this->domain, DNS_SRV );
107         }
108 }