使用netty的自定义DNS服务器 - 编写“答案”部分

时间:2018-01-04 14:05:59

标签: java dns netty

我正在尝试使用netty编写一个小的自定义DNS服务器。以下代码有效,但我有两个问题:

  1. 有没有比使用DefaultDnsRawRecord创建DNS应答部分更好的方法?还有一些其他DNS记录,例如DefaultDnsOptEcsRecordDefaultDnsPtrRecord,但它们似乎用于DNS响应的其他部分。

  2. 我是否应该使用netty内部方法io.netty.util.internal.SocketUtils.addressByName()为固定IP地址创建InetAdress对象,而无需在我的情况下查询DNS?是否有标准的Java方法?

  3. 设置管道:

            bootstrap.group(group)
                    .channel(NioDatagramChannel.class)
                    .handler(new ChannelInitializer<NioDatagramChannel>() {
                        @Override
                        protected void initChannel(NioDatagramChannel nioDatagramChannel) throws Exception {
                            nioDatagramChannel.pipeline().addLast(new DatagramDnsQueryDecoder());
                            nioDatagramChannel.pipeline().addLast(new DatagramDnsResponseEncoder());
                            nioDatagramChannel.pipeline().addLast(new DnsHandler());
                        }
                    })
                    .option(ChannelOption.SO_BROADCAST, true)
                    .localAddress("127.0.0.1", 40053);
    

    DnsHandler

    public class DnsHandler extends SimpleChannelInboundHandler<DatagramDnsQuery> {
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramDnsQuery query) throws Exception {
        DatagramDnsResponse response = new DatagramDnsResponse(query.recipient(), query.sender(), query.id());
    
        DefaultDnsQuestion dnsQuestion = query.recordAt(DnsSection.QUESTION);
        response.addRecord(DnsSection.QUESTION, dnsQuestion);
    
        byte[] address = SocketUtils.addressByName("127.0.0.1").getAddress();
        DefaultDnsRawRecord queryAnswer = new DefaultDnsRawRecord(dnsQuestion.name(),
                DnsRecordType.A, 3600, Unpooled.wrappedBuffer(address));
        response.addRecord(DnsSection.ANSWER, queryAnswer);
    
        ctx.writeAndFlush(response);
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
    }
    }
    

1 个答案:

答案 0 :(得分:1)

由于netty本身并没有为服务器端指定编码器/解码器,DefaultDnsRawRecord可能是您目前最好的选择。

您不应该使用.internal.包中抵制的类,因为这些类用于netty的内部使用,并且可以随时更改或删除(因为这些不被视为公共API)。只有在你真正知道自己在做什么而不关心破损时才使用这些。