Skip to content

Commit 36b1604

Browse files
authored
Merge pull request #178 from clue-labs/spf-record
Add support for legacy SPF record type
2 parents 92a1727 + 6533500 commit 36b1604

File tree

5 files changed

+37
-2
lines changed

5 files changed

+37
-2
lines changed

src/Model/Message.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ final class Message
3434
* The OPT record uses the "ttl" field to store additional flags.
3535
*/
3636
const TYPE_OPT = 41;
37+
38+
/**
39+
* Sender Policy Framework (SPF) had a dedicated SPF type which has been
40+
* deprecated in favor of reusing the existing TXT type.
41+
*
42+
* @deprecated https://datatracker.ietf.org/doc/html/rfc7208#section-3.1
43+
* @see self::TYPE_TXT
44+
*/
45+
const TYPE_SPF = 99;
46+
3747
const TYPE_ANY = 255;
3848
const TYPE_CAA = 257;
3949

src/Protocol/BinaryDumper.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ private function recordsToBinary(array $records)
9292
$binary = $this->domainNameToBinary($record->data);
9393
break;
9494
case Message::TYPE_TXT:
95+
case Message::TYPE_SPF:
9596
$binary = $this->textsToBinary($record->data);
9697
break;
9798
case Message::TYPE_MX:

src/Protocol/Parser.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ private function parseRecord(Message $message)
171171
}
172172
} elseif (Message::TYPE_CNAME === $type || Message::TYPE_PTR === $type || Message::TYPE_NS === $type) {
173173
list($rdata, $consumed) = $this->readDomain($message->data, $consumed);
174-
} elseif (Message::TYPE_TXT === $type) {
174+
} elseif (Message::TYPE_TXT === $type || Message::TYPE_SPF === $type) {
175175
$rdata = array();
176176
while ($consumed < $expected) {
177177
$len = ord($message->data[$consumed]);

tests/Protocol/BinaryDumperTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ public function testToBinaryForResponseWithPTRRecordWithSpecialCharactersEscaped
385385
public function testToBinaryForResponseWithMultipleAnswerRecords()
386386
{
387387
$data = "";
388-
$data .= "72 62 01 00 00 01 00 06 00 00 00 00"; // header
388+
$data .= "72 62 01 00 00 01 00 07 00 00 00 00"; // header
389389
$data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
390390
$data .= "00 ff 00 01"; // question: type ANY, class IN
391391

@@ -401,6 +401,10 @@ public function testToBinaryForResponseWithMultipleAnswerRecords()
401401
$data .= "00 10 00 01 00 00 00 00 00 0c"; // answer: type TXT, class IN, TTL 0, 12 bytes
402402
$data .= "05 68 65 6c 6c 6f 05 77 6f 72 6c 64"; // answer: hello, world
403403

404+
$data .= "04 69 67 6f 72 02 69 6f 00"; // answer: igor.io
405+
$data .= "00 63 00 01 00 00 00 00 00 0c"; // answer: type SPF, class IN, TTL 0, 12 bytes
406+
$data .= "0b 76 3d 73 70 66 31 20 2d 61 6c 6c"; // answer: v=spf1 -all
407+
404408
$data .= "04 69 67 6f 72 02 69 6f 00"; // answer: igor.io
405409
$data .= "00 0f 00 01 00 00 00 00 00 03"; // answer: type MX, class IN, TTL 0, 3 bytes
406410
$data .= "00 00 00"; // answer: … priority 0, no target
@@ -430,6 +434,7 @@ public function testToBinaryForResponseWithMultipleAnswerRecords()
430434
$response->answers[] = new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 0, '127.0.0.1');
431435
$response->answers[] = new Record('igor.io', Message::TYPE_AAAA, Message::CLASS_IN, 0, '::1');
432436
$response->answers[] = new Record('igor.io', Message::TYPE_TXT, Message::CLASS_IN, 0, array('hello', 'world'));
437+
$response->answers[] = new Record('igor.io', Message::TYPE_SPF, Message::CLASS_IN, 0, array('v=spf1 -all'));
433438
$response->answers[] = new Record('igor.io', Message::TYPE_MX, Message::CLASS_IN, 0, array('priority' => 0, 'target' => ''));
434439
$response->answers[] = new Record('igor.io', Message::TYPE_CAA, Message::CLASS_IN, 0, array('flag' => 0, 'tag' => 'issue', 'value' => 'letsencrypt.org'));
435440
$response->answers[] = new Record('igor.io', Message::TYPE_SSHFP, Message::CLASS_IN, 0, array('algorithm' => 1, 'type' => '1', 'fingerprint' => '69ac090c'));

tests/Protocol/ParserTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,25 @@ public function testParseTXTResponse()
305305
$this->assertSame(array('hello'), $response->answers[0]->data);
306306
}
307307

308+
public function testParseSPFResponse()
309+
{
310+
$data = "";
311+
$data .= "04 69 67 6f 72 02 69 6f 00"; // answer: igor.io
312+
$data .= "00 63 00 01"; // answer: type SPF, class IN
313+
$data .= "00 01 51 80"; // answer: ttl 86400
314+
$data .= "00 06"; // answer: rdlength 6
315+
$data .= "05 68 65 6c 6c 6f"; // answer: rdata length 5: hello
316+
317+
$response = $this->parseAnswer($data);
318+
319+
$this->assertCount(1, $response->answers);
320+
$this->assertSame('igor.io', $response->answers[0]->name);
321+
$this->assertSame(Message::TYPE_SPF, $response->answers[0]->type);
322+
$this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
323+
$this->assertSame(86400, $response->answers[0]->ttl);
324+
$this->assertSame(array('hello'), $response->answers[0]->data);
325+
}
326+
308327
public function testParseTXTResponseMultiple()
309328
{
310329
$data = "";

0 commit comments

Comments
 (0)