Skip to content

Commit d44e380

Browse files
committed
add change for recurse, cd & ad
1 parent f6229c5 commit d44e380

2 files changed

Lines changed: 117 additions & 7 deletions

File tree

src/Resolver.php

Lines changed: 102 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ArrayAccess\DnsRecord\Packet\RequestData;
1818
use ArrayAccess\DnsRecord\Packet\Response;
1919
use ArrayAccess\DnsRecord\ResourceRecord\Definitions\QClass\IN;
20+
use ArrayAccess\DnsRecord\ResourceRecord\RRTypes\OPT;
2021
use ArrayAccess\DnsRecord\Traits\PacketSenderTrait;
2122
use ArrayAccess\DnsRecord\Utils\Lookup;
2223
use Throwable;
@@ -27,12 +28,72 @@ class Resolver
2728
{
2829
use PacketSenderTrait;
2930

31+
protected bool $cdFlag = false;
32+
33+
protected bool $adFlag = true;
34+
35+
/**
36+
* request DNSSEC values, by setting the DO flag to 1; this actually makes
37+
* the resolver add an OPT RR to the additional section, and sets the DO flag
38+
* in this RR to 1
39+
*/
40+
protected bool $dnsSec = false;
41+
42+
/**
43+
* if we should set the recursion desired bit to 1 or 0.
44+
*
45+
* by default, this is set to true, the DNS server to perform a recursive
46+
* request. If set to false, the RD bit will be set to 0, and the server will
47+
* not perform recursion on the request.
48+
*/
49+
public bool $recurse = true;
50+
3051
public function __construct(
3152
protected ?DnsServerStorage $dnsServerStorage = null,
3253
protected ?CacheStorageInterface $cache = null
3354
) {
3455
}
3556

57+
public function isCdFlag(): bool
58+
{
59+
return $this->cdFlag;
60+
}
61+
62+
public function setCdFlag(bool $cdFlag): void
63+
{
64+
$this->cdFlag = $cdFlag;
65+
}
66+
67+
public function isAdFlag(): bool
68+
{
69+
return $this->adFlag;
70+
}
71+
72+
public function setAdFlag(bool $adFlag): void
73+
{
74+
$this->adFlag = $adFlag;
75+
}
76+
77+
public function isDnsSec(): bool
78+
{
79+
return $this->dnsSec;
80+
}
81+
82+
public function setDnsSec(bool $dnsSec): void
83+
{
84+
$this->dnsSec = $dnsSec;
85+
}
86+
87+
public function isRecurse(): bool
88+
{
89+
return $this->recurse;
90+
}
91+
92+
public function setRecurse(bool $recurse): void
93+
{
94+
$this->recurse = $recurse;
95+
}
96+
3697
public function getCache(): CacheStorageInterface
3798
{
3899
if (!isset($this->cache)) {
@@ -64,18 +125,37 @@ public function setDnsServerStorage(DnsServerStorage $dnsServerStorage): void
64125
* @param string $name
65126
* @param string $type
66127
* @param string $class
128+
* @param ?bool $adFlag
129+
* @param ?bool $cdFlag
130+
* @param ?bool $dnsSec
131+
* @param ?bool $recurse
67132
* @param string ...$server
68133
* @return PacketRequestDataInterface
69134
*/
70-
protected function createQueryOpcode(
135+
public function createQueryOpcode(
71136
int|string|ResourceRecordOpcodeInterface $opcode,
72137
string $name,
73138
string $type = 'A',
74-
string $class = 'IN',
139+
string $class = IN::NAME,
140+
?bool $adFlag = null,
141+
?bool $cdFlag = null,
142+
?bool $dnsSec = null,
143+
?bool $recurse = null,
75144
string ...$server
76145
) : PacketRequestDataInterface {
146+
$adFlag ??= $this->isAdFlag();
147+
$cdFlag ??= $this->isCdFlag();
148+
$dnsSec ??= $this->isDnsSec();
149+
$recurse ??= $this->isRecurse();
150+
77151
// IN as default
78-
$class = trim($class?:'IN')?:'IN';
152+
$class = trim($class?:IN::NAME)?:IN::NAME;
153+
$class = Lookup::resourceClass($class);
154+
$type = Lookup::resourceType($type);
155+
$isOpt = $type->getName() === OPT::TYPE;
156+
if ($isOpt) { // if is OPT fallback to A
157+
$type = 'A';
158+
}
79159
$question = new Question($name, $type, $class);
80160
$dns = $this->getDnsServerStorage();
81161
if (!empty($server)) {
@@ -85,11 +165,18 @@ protected function createQueryOpcode(
85165
}
86166
$dns = new DnsServerStorage(...$ss);
87167
}
88-
return new RequestData(
89-
Header::createQueryHeader($opcode),
168+
$requestData = new RequestData(
169+
Header::createQueryHeader($opcode, null, $adFlag, $cdFlag, $recurse),
90170
$dns,
91-
$question,
171+
$question
92172
);
173+
174+
if ($isOpt || $dnsSec) {
175+
$requestData
176+
->getAdditionalRecords()
177+
->add(OPT::create($question->getType()->getValue()));
178+
}
179+
return $requestData;
93180
}
94181

95182
/**
@@ -110,6 +197,8 @@ public function query(
110197
$name,
111198
$type,
112199
$class,
200+
$this->isAdFlag(),
201+
$this->isCdFlag(),
113202
...$server
114203
);
115204
}
@@ -132,6 +221,8 @@ public function iQuery(
132221
$name,
133222
$type,
134223
$class,
224+
$this->isAdFlag(),
225+
$this->isCdFlag(),
135226
...$server
136227
);
137228
}
@@ -154,7 +245,11 @@ public function lookups(
154245
}
155246

156247
$requests = [];
157-
$header = Header::createQueryHeader();
248+
$header = Header::createQueryHeader(
249+
adFlag: $this->adFlag,
250+
cdFlag: $this->cdFlag,
251+
rdFlag: $this->recurse
252+
);
158253
$dns = $this->getDnsServerStorage();
159254
foreach ($types as $key => $type) {
160255
$requests[$key] = new RequestData($header, $dns, new Question(

tests/ResolverTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ArrayAccess\DnsRecord\ResourceRecord\Definitions\Opcode\Query;
1818
use ArrayAccess\DnsRecord\ResourceRecord\Definitions\QClass\IN;
1919
use ArrayAccess\DnsRecord\ResourceRecord\RRTypes\A;
20+
use ArrayAccess\DnsRecord\ResourceRecord\RRTypes\OPT;
2021
use PHPUnit\Framework\TestCase;
2122
use Throwable;
2223
use function sprintf;
@@ -121,6 +122,7 @@ public function testGetCache()
121122
)
122123
);
123124
}
125+
124126
public function testQuery()
125127
{
126128
$resolver = new Resolver();
@@ -143,6 +145,19 @@ public function testQuery()
143145
Query::class
144146
)
145147
);
148+
// default use dnssec
149+
$this->assertNull(
150+
$query->getAdditionalRecords()->getFilteredType('OPT', true),
151+
'dnssec disable by default'
152+
);
153+
// set dns sec to true
154+
$resolver->setDnsSec(true);
155+
$query = $resolver->query('example.com');
156+
$this->assertInstanceOf(
157+
OPT::class,
158+
$query->getAdditionalRecords()->getFilteredType('OPT', true),
159+
'Enable dnssec and additional question contain OPT'
160+
);
146161
}
147162

148163
public function testIQuery()

0 commit comments

Comments
 (0)