我正在尝试使用netty编写一个小的自定义DNS服务器。以下代码有效,但我有两个问题:
有没有比使用DefaultDnsRawRecord
创建DNS应答部分更好的方法?还有一些其他DNS记录,例如DefaultDnsOptEcsRecord
或DefaultDnsPtrRecord
,但它们似乎用于DNS响应的其他部分。
我是否应该使用netty内部方法io.netty.util.internal.SocketUtils.addressByName()
为固定IP地址创建InetAdress
对象,而无需在我的情况下查询DNS?是否有标准的Java方法?
设置管道:
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();
}
}
答案 0 :(得分:1)
由于netty本身并没有为服务器端指定编码器/解码器,DefaultDnsRawRecord
可能是您目前最好的选择。
您不应该使用.internal.
包中抵制的类,因为这些类用于netty的内部使用,并且可以随时更改或删除(因为这些不被视为公共API)。只有在你真正知道自己在做什么而不关心破损时才使用这些。