Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
3
namespace React\Dns\Model;
4
 
5
use React\Dns\Query\Query;
6
 
7
/**
8
 * This class represents an outgoing query message or an incoming response message
9
 *
10
 * @link https://tools.ietf.org/html/rfc1035#section-4.1.1
11
 */
12
final class Message
13
{
14
    const TYPE_A = 1;
15
    const TYPE_NS = 2;
16
    const TYPE_CNAME = 5;
17
    const TYPE_SOA = 6;
18
    const TYPE_PTR = 12;
19
    const TYPE_MX = 15;
20
    const TYPE_TXT = 16;
21
    const TYPE_AAAA = 28;
22
    const TYPE_SRV = 33;
23
    const TYPE_SSHFP = 44;
24
 
25
    /**
26
     * pseudo-type for EDNS0
27
     *
28
     * These are included in the additional section and usually not in answer section.
29
     * Defined in [RFC 6891](https://tools.ietf.org/html/rfc6891) (or older
30
     * [RFC 2671](https://tools.ietf.org/html/rfc2671)).
31
     *
32
     * The OPT record uses the "class" field to store the maximum size.
33
     *
34
     * The OPT record uses the "ttl" field to store additional flags.
35
     */
36
    const TYPE_OPT = 41;
37
    const TYPE_ANY = 255;
38
    const TYPE_CAA = 257;
39
 
40
    const CLASS_IN = 1;
41
 
42
    const OPCODE_QUERY = 0;
43
    const OPCODE_IQUERY = 1; // inverse query
44
    const OPCODE_STATUS = 2;
45
 
46
    const RCODE_OK = 0;
47
    const RCODE_FORMAT_ERROR = 1;
48
    const RCODE_SERVER_FAILURE = 2;
49
    const RCODE_NAME_ERROR = 3;
50
    const RCODE_NOT_IMPLEMENTED = 4;
51
    const RCODE_REFUSED = 5;
52
 
53
    /**
54
     * The edns-tcp-keepalive EDNS0 Option
55
     *
56
     * Option value contains a `?float` with timeout in seconds (in 0.1s steps)
57
     * for DNS response or `null` for DNS query.
58
     *
59
     * @link https://tools.ietf.org/html/rfc7828
60
     */
61
    const OPT_TCP_KEEPALIVE = 11;
62
 
63
    /**
64
     * The EDNS(0) Padding Option
65
     *
66
     * Option value contains a `string` with binary data (usually variable
67
     * number of null bytes)
68
     *
69
     * @link https://tools.ietf.org/html/rfc7830
70
     */
71
    const OPT_PADDING = 12;
72
 
73
    /**
74
     * Creates a new request message for the given query
75
     *
76
     * @param Query $query
77
     * @return self
78
     */
79
    public static function createRequestForQuery(Query $query)
80
    {
81
        $request = new Message();
82
        $request->id = self::generateId();
83
        $request->rd = true;
84
        $request->questions[] = $query;
85
 
86
        return $request;
87
    }
88
 
89
    /**
90
     * Creates a new response message for the given query with the given answer records
91
     *
92
     * @param Query    $query
93
     * @param Record[] $answers
94
     * @return self
95
     */
96
    public static function createResponseWithAnswersForQuery(Query $query, array $answers)
97
    {
98
        $response = new Message();
99
        $response->id = self::generateId();
100
        $response->qr = true;
101
        $response->rd = true;
102
 
103
        $response->questions[] = $query;
104
 
105
        foreach ($answers as $record) {
106
            $response->answers[] = $record;
107
        }
108
 
109
        return $response;
110
    }
111
 
112
    /**
113
     * generates a random 16 bit message ID
114
     *
115
     * This uses a CSPRNG so that an outside attacker that is sending spoofed
116
     * DNS response messages can not guess the message ID to avoid possible
117
     * cache poisoning attacks.
118
     *
119
     * The `random_int()` function is only available on PHP 7+ or when
120
     * https://github.com/paragonie/random_compat is installed. As such, using
121
     * the latest supported PHP version is highly recommended. This currently
122
     * falls back to a less secure random number generator on older PHP versions
123
     * in the hope that this system is properly protected against outside
124
     * attackers, for example by using one of the common local DNS proxy stubs.
125
     *
126
     * @return int
127
     * @see self::getId()
128
     * @codeCoverageIgnore
129
     */
130
    private static function generateId()
131
    {
132
        if (function_exists('random_int')) {
133
            return random_int(0, 0xffff);
134
        }
135
        return mt_rand(0, 0xffff);
136
    }
137
 
138
    /**
139
     * The 16 bit message ID
140
     *
141
     * The response message ID has to match the request message ID. This allows
142
     * the receiver to verify this is the correct response message. An outside
143
     * attacker may try to inject fake responses by "guessing" the message ID,
144
     * so this should use a proper CSPRNG to avoid possible cache poisoning.
145
     *
146
     * @var int 16 bit message ID
147
     * @see self::generateId()
148
     */
149
    public $id = 0;
150
 
151
    /**
152
     * @var bool Query/Response flag, query=false or response=true
153
     */
154
    public $qr = false;
155
 
156
    /**
157
     * @var int specifies the kind of query (4 bit), see self::OPCODE_* constants
158
     * @see self::OPCODE_QUERY
159
     */
160
    public $opcode = self::OPCODE_QUERY;
161
 
162
    /**
163
     *
164
     * @var bool Authoritative Answer
165
     */
166
    public $aa = false;
167
 
168
    /**
169
     * @var bool TrunCation
170
     */
171
    public $tc = false;
172
 
173
    /**
174
     * @var bool Recursion Desired
175
     */
176
    public $rd = false;
177
 
178
    /**
179
     * @var bool Recursion Available
180
     */
181
    public $ra = false;
182
 
183
    /**
184
     * @var int response code (4 bit), see self::RCODE_* constants
185
     * @see self::RCODE_OK
186
     */
187
    public $rcode = Message::RCODE_OK;
188
 
189
    /**
190
     * An array of Query objects
191
     *
192
     * ```php
193
     * $questions = array(
194
     *     new Query(
195
     *         'reactphp.org',
196
     *         Message::TYPE_A,
197
     *         Message::CLASS_IN
198
     *     )
199
     * );
200
     * ```
201
     *
202
     * @var Query[]
203
     */
204
    public $questions = array();
205
 
206
    /**
207
     * @var Record[]
208
     */
209
    public $answers = array();
210
 
211
    /**
212
     * @var Record[]
213
     */
214
    public $authority = array();
215
 
216
    /**
217
     * @var Record[]
218
     */
219
    public $additional = array();
220
}