Created
February 13, 2016 13:08
-
-
Save Karry/b770c8d9f3c56399fd9c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.netty.resolver.dns; | |
import io.netty.buffer.ByteBuf; | |
import io.netty.buffer.Unpooled; | |
import io.netty.channel.AddressedEnvelope; | |
import io.netty.channel.EventLoopGroup; | |
import io.netty.channel.nio.NioEventLoopGroup; | |
import io.netty.channel.socket.nio.NioDatagramChannel; | |
import io.netty.handler.codec.dns.*; | |
import io.netty.util.concurrent.Future; | |
import io.netty.util.internal.StringUtil; | |
import scala.Array; | |
import java.net.InetSocketAddress; | |
import java.util.concurrent.ExecutionException; | |
import java.util.concurrent.TimeUnit; | |
import io.netty.handler.codec.dns.DefaultDnsRawRecord; | |
import io.netty.handler.codec.dns.DnsRecordType; | |
public class EdnsClientSubnetTest { | |
public static int MAX_PAYLOAD_SIZE = 4096; | |
public static final DnsRecordType EDNS_CLIENT_SUBNET_CODE = new DnsRecordType(0x0008, "CSUBNET"); // old code: 0x50fa newer code should be 0x0008 | |
// http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml | |
public static byte IPv4_FAMILY = 1; | |
public static byte IPv6_FAMILY = 2; | |
/** | |
* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 | |
*/ | |
static class EdnsClientSubnet extends DefaultDnsRawRecord { | |
public EdnsClientSubnet(ByteBuf content) { | |
super(StringUtil.EMPTY_STRING, DnsRecordType.OPT, MAX_PAYLOAD_SIZE, 0, content); | |
} | |
} | |
public static EdnsClientSubnet buildEDnsClientSubnetRecord(int sourceNetMask, byte[] address) { | |
byte family; | |
if (address == null) | |
throw new IllegalArgumentException("address"); | |
if (sourceNetMask < 0) | |
throw new IllegalArgumentException("invalid net mask"); | |
if (address.length == 4) { | |
family = IPv4_FAMILY; | |
if (sourceNetMask > 32) | |
throw new IllegalArgumentException("invalid net mask"); | |
} else if (address.length == 16) { | |
family = IPv6_FAMILY; | |
if (sourceNetMask > 128) | |
throw new IllegalArgumentException("invalid net mask"); | |
} else { | |
throw new IllegalArgumentException("undefined address family"); | |
} | |
/** | |
* +0 (MSB) +1 (LSB) | |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | |
* 0: | OPTION-CODE | | |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | |
* 2: | OPTION-LENGTH | | |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | |
* 4: | FAMILY | | |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | |
* 6: | SOURCE NETMASK | SCOPE NETMASK | | |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | |
* 7: | ADDRESS... / | |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | |
* | |
*/ | |
byte[] buf = new byte[8 + address.length]; | |
buf[0] = (byte) ((EDNS_CLIENT_SUBNET_CODE.intValue() >> 8) & 0xff); | |
buf[1] = (byte) (EDNS_CLIENT_SUBNET_CODE.intValue() & 0xff); | |
buf[3] = (byte) (4 + address.length); | |
buf[5] = family; | |
buf[6] = (byte) sourceNetMask; | |
Array.copy(address, 0, buf, 8, address.length); | |
return new EdnsClientSubnet(Unpooled.wrappedBuffer(buf)); | |
} | |
public static int DNSPort = 53; | |
public static void main(String[] args) throws ExecutionException, InterruptedException { | |
EventLoopGroup group = new NioEventLoopGroup(1); | |
DnsServerAddresses nameServerAddresses = DnsServerAddresses.rotational( | |
new InetSocketAddress("prg18.ff.avast.com", DNSPort) | |
); | |
DnsNameResolver resolver = new DnsNameResolverBuilder(group.next()) | |
.channelType(NioDatagramChannel.class) | |
.nameServerAddresses(nameServerAddresses ) | |
.queryTimeoutMillis(TimeUnit.HOURS.toMillis(1)) | |
.build(); | |
DefaultDnsQuestion q = new DefaultDnsQuestion("su.ff.avast.com", DnsRecordType.A, DnsRecord.CLASS_IN); | |
EdnsClientSubnet a = buildEDnsClientSubnetRecord(32, new byte[]{103, (byte) 240, (byte) 252, 0}); | |
Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> f = resolver.query( | |
q, | |
java.util.Collections.<DnsRecord>singletonList(a)); | |
AddressedEnvelope<DnsResponse, InetSocketAddress> res = f.get(); | |
System.out.println(res); | |
resolver.close(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment