spf-discuss
[Top] [All Lists]

Re: Standard Authentication Query

2005-03-29 14:54:05


Todd Herr wrote:
On Tue, 29 Mar 2005, at 12:25, David MacQuigg wrote:


I can even see a large ISP clustering all their servers so their SPF record
might be nothing but a few masks.  As long as spammers can't get access to
the addresses within the mask blocks, the masks alone are good enough.

A typical top record might look like this one for rr.com:
v=spf1
m=24.30.203/24,24.28.200/24,24.28.204/24,24.30.218/24,24.93.47/24,24.25.9/24,
65.24.5/24,24.94.166/24,24.29.109/24,66.75.162/24,24.24.2/24,65.32.5/24 ...
-all
The ... redirects and such might never be needed if rr.com decides it can
clean out the zombies in each of those /24 blocks.

I have two points to make:

1. Masks are only useful for records that *must* span multiple TXT records any way. Otherwise, for single-record policies, they will *not* be added.

2. Only a compiler should be trusted to make best use of the available number of bytes for a mask. If a policy compiles to 600 bytes of IPs, it must therefore span 2 packets, which leaves 300bytes available for a mask in the first record. (assuming 450-bytes payload per packet). Only a compiler should be trusted to use any balanced-binary-tree algorithms necessary to find the best mask.


Let's pick a more realistic example. I picked the rr.com SPF record:
compiling it without masks gives:

rr.com               300 TXT "v=spf1 ip4:24.30.203.0/24
ip4:24.28.200.0/24 ip4:24.28.204.0/24 ip4:24.30.218.0/24
ip4:24.93.47.0/24 ip4:24.25.9.0/24 ip4:65.24.5.0/24
ip4:24.94.166.0/24 ip4:24.29.109.0/24 ip4:66.75.162.0/24
ip4:24.24.2.0/24 ip4:65.32.5.0/24 ip4:66.75.160.130
ip4:66.75.160.136 ip4:66.75.160.12 ip4:66.75.160.13
ip4:65.24.7.10 ip4:65.24.7.11 ip4:65.24.7.12 ip4:65.24.7.13
ip4:66.75.160.128 ip4:66.75.160.129 ip4:65.32.1.38 ip4:65.32.1.42
ip4:65.32.1.49 redirect=_s0.%{o}"

_s0.rr.com           300 TXT "v=spf1 ip4:24.28.193.148
ip4:24.28.193.149 ip4:24.30.200.18 ip4:24.29.99.40
ip4:24.29.99.41 ip4:24.92.226.25 ip4:24.92.226.31
ip4:24.92.226.159 ip4:24.92.226.164 ip4:24.94.163.190
ip4:24.94.165.190  ip4:24.93.40.210 ip4:24.93.40.211
ip4:24.93.40.212 ip4:24.93.40.214 ip4:24.25.4.95 ip4:24.25.4.96
ip4:24.25.4.97 ~all"

Note that my compiler does not yet sort the IP entries. When I add the masks, sorting will make a huge difference. Then all the one-off IP addresses will be put at rr.com, and all the addresses that are clumped closely will be left for the second record, as that will make the mask even more narrow.

In the above output, the first record has 443 bytes. The second has 336 bytes. Thus, the mask-capable compiler would move approx 114 bytes from the first record to the second (_s0.rr.com).

Then, it would have 121-bytes available in the firs record for a mask to represent an approximation of the second record.

For instance, without the shuffle, the second record's mask might be:

m=~24.24/14,24.92/14

In practice, it will be more narrow, as the above didn't use close to the 121 bytes available for a better mask.

So, with only 20 bytes, the compiler communicated that all the addreses in _s0.rr.com pertain to a range of addresses of only 2^19. Compared to the total IP space of 2^32, this represents 0.0122% of the total available IP space. This means that for a complex record like RR's, The mask saves the second query 99.988% of the time. In actuality, the savings will be even more impressive, if the compiler would use the entire available 121 bytes to specify the most narrow mask possible.

There's no reason to worry about the argument that the routable IP space is actually 2^32-2^23-2^16. The percentages would not change much.

At the same time, the mask has communicated that the second record ends with ~all.

Radu.