From 4690bc85b37a3cefe93462cb62ffebf83540aaf3 Mon Sep 17 00:00:00 2001 From: wujiawei <12345678> Date: Sat, 8 Mar 2025 23:16:32 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90fix=E3=80=91=20add=20dns=20module;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LazyDNS.puml | 61 ++++++++++ pom.xml | 1 + wu-lazy-cloud-heartbeat-dns/pom.xml | 59 ++++++++++ .../dns/EnableDnsAutoConfiguration.java | 12 ++ .../dns/config/DnsAutoConfiguration.java | 11 ++ .../dns/config/DnsFlowConfiguration.java | 15 +++ .../NettyDnsSocketApplicationListener.java | 25 ++++ .../heartbeat/dns/init/InitDnsSocket.java | 22 ++++ .../main/resources/META-INF/spring.factories | 6 + ...ot.autoconfigure.AutoConfiguration.imports | 4 + .../network/heartbeat/dns/DnsServer.java | 52 +++++++++ .../heartbeat/dns/DnsServerHandler.java | 37 ++++++ .../network/heartbeat/dns/demo/DnsServer.java | 108 ++++++++++++++++++ .../network/heartbeat/dns/demo/ProxyUdp.java | 80 +++++++++++++ 14 files changed, 493 insertions(+) create mode 100644 LazyDNS.puml create mode 100644 wu-lazy-cloud-heartbeat-dns/pom.xml create mode 100644 wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/EnableDnsAutoConfiguration.java create mode 100644 wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/config/DnsAutoConfiguration.java create mode 100644 wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/config/DnsFlowConfiguration.java create mode 100644 wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/context/NettyDnsSocketApplicationListener.java create mode 100644 wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/init/InitDnsSocket.java create mode 100644 wu-lazy-cloud-heartbeat-dns/src/main/resources/META-INF/spring.factories create mode 100644 wu-lazy-cloud-heartbeat-dns/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/DnsServer.java create mode 100644 wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/DnsServerHandler.java create mode 100644 wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/demo/DnsServer.java create mode 100644 wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/demo/ProxyUdp.java diff --git a/LazyDNS.puml b/LazyDNS.puml new file mode 100644 index 0000000..8c3708d --- /dev/null +++ b/LazyDNS.puml @@ -0,0 +1,61 @@ + + +@startuml + +title 动态DNS + +actor 访客 as User + +package "服务端(公网)" as dns_server_{ + component [服务端私有网络A]{ + [mysql:(172.1.1.4:3306)] as dns_server_remote_local_ + [clickhouse:(172.1.1.5:3306)] + } + component [服务端私有网络B]{ + [mysql:(172.1.2.4:3306)] + [clickhouse:(172.1.2.5:3306)] + } + +} + +package "客户端(私有网络)" as dns_remote_local_{ + + component [客户端私有网络A]{ + [mysql:(162.1.1.4:3306)] as dns_client_remote_local_ + [clickhouse:(162.1.1.5:3306)] + } + component [客户端私有网络B]{ + [mysql:(162.1.2.4:3306)] + [clickhouse:(162.1.2.5:3306)] + } +} + + +package "客户端(用户本地)" as dns_local_ { + +} + + + +note "用户本地网络" as local_net_ +note "服务端网络" as server_net_ +note "客户端私有网络" as remote_net_ + +'(User) .... local_condition_ +'local_condition_ ... (target) + +[User] ...right...> dns_local_: DNS连接到本地 +dns_local_ ...right...> local_net_: 访问本地网络(本地DNS) +dns_local_ ...up...> dns_server_remote_local_: 远程DNS解析 + +dns_server_ ...up...> server_net_: server本地的网络 +dns_server_ ...down...> dns_remote_local_: 访问的地址在远程的客户端中 +dns_remote_local_ ...down...> dns_client_remote_local_: 远程客户端所在的私有网络 +dns_remote_local_ ...down...> remote_net_: 远程客户端中的其他网络 + + + + + +@enduml + diff --git a/pom.xml b/pom.xml index 548f817..322864c 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,7 @@ wu-lazy-cloud-heartbeat-server-cluster wu-lazy-cloud-heartbeat-client wu-lazy-cloud-heartbeat-common + wu-lazy-cloud-heartbeat-dns wu-lazy-cloud-heartbeat-start diff --git a/wu-lazy-cloud-heartbeat-dns/pom.xml b/wu-lazy-cloud-heartbeat-dns/pom.xml new file mode 100644 index 0000000..23892b8 --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/pom.xml @@ -0,0 +1,59 @@ + + + + top.wu2020 + wu-lazy-cloud-network + 1.3.0-JDK17-SNAPSHOT + + + 4.0.0 + + wu-lazy-cloud-heartbeat-dns + 云上心跳服务dns + + + 17 + 17 + + + + + top.wu2020 + wu-framework-web + + + + top.wu2020 + wu-lazy-cloud-heartbeat-common + + + + mysql + mysql-connector-java + 8.0.33 + + + + top.wu2020 + wu-database-lazy-plus-starter + + + com.alibaba + fastjson + 2.0.50 + + + io.swagger.core.v3 + swagger-annotations-jakarta + 2.2.21 + + + top.wu2020 + wu-framework-lazy-orm-spring-starter + + + + + \ No newline at end of file diff --git a/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/EnableDnsAutoConfiguration.java b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/EnableDnsAutoConfiguration.java new file mode 100644 index 0000000..5a6f52a --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/EnableDnsAutoConfiguration.java @@ -0,0 +1,12 @@ +package org.framework.lazy.cloud.network.heartbeat.dns; + +import org.springframework.context.annotation.ComponentScan; +import org.wu.framework.lazy.orm.core.stereotype.LazyScan; + +@LazyScan(scanBasePackages = { + "org.framework.lazy.cloud.network.heartbeat.dns.standalone.infrastructure.entity", + "org.framework.lazy.cloud.network.heartbeat.dns.cluster.infrastructure.entity" +}) +@ComponentScan(basePackages = "org.framework.lazy.cloud.network.heartbeat.dns") +public class EnableDnsAutoConfiguration { +} diff --git a/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/config/DnsAutoConfiguration.java b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/config/DnsAutoConfiguration.java new file mode 100644 index 0000000..dc850f3 --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/config/DnsAutoConfiguration.java @@ -0,0 +1,11 @@ +package org.framework.lazy.cloud.network.heartbeat.dns.config; + + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Role; + + +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) +public class DnsAutoConfiguration { + +} diff --git a/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/config/DnsFlowConfiguration.java b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/config/DnsFlowConfiguration.java new file mode 100644 index 0000000..be33aa7 --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/config/DnsFlowConfiguration.java @@ -0,0 +1,15 @@ +package org.framework.lazy.cloud.network.heartbeat.dns.config; + +import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter; +import org.framework.lazy.cloud.network.heartbeat.common.advanced.flow.HandleChannelFlowAdvanced; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Role; + +/** + * @see ChannelFlowAdapter + * @see HandleChannelFlowAdvanced + */ +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) +public class DnsFlowConfiguration { + +} diff --git a/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/context/NettyDnsSocketApplicationListener.java b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/context/NettyDnsSocketApplicationListener.java new file mode 100644 index 0000000..8fcaa55 --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/context/NettyDnsSocketApplicationListener.java @@ -0,0 +1,25 @@ +package org.framework.lazy.cloud.network.heartbeat.dns.context; + +import lombok.extern.slf4j.Slf4j; +import org.framework.lazy.cloud.network.heartbeat.common.context.SocketApplicationListener; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyDnsSocketApplicationListener implements SocketApplicationListener { + + /** + * 运行 + * + * @throws InterruptedException + */ + @Override + public void doRunning() throws Exception { + + } + + @Override + public void destroy() throws Exception { + + } +} \ No newline at end of file diff --git a/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/init/InitDnsSocket.java b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/init/InitDnsSocket.java new file mode 100644 index 0000000..0ee461b --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/main/java/org/framework/lazy/cloud/network/heartbeat/dns/init/InitDnsSocket.java @@ -0,0 +1,22 @@ +package org.framework.lazy.cloud.network.heartbeat.dns.init; + + +import lombok.extern.slf4j.Slf4j; +import org.framework.lazy.cloud.network.heartbeat.dns.context.NettyDnsSocketApplicationListener; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + + +/** + * description 初始化服务端 + * + * @author 吴佳伟 + * @date 2023/09/12 18:22 + */ +@Slf4j +@Configuration +@Import({NettyDnsSocketApplicationListener.class}) +public class InitDnsSocket { + + +} diff --git a/wu-lazy-cloud-heartbeat-dns/src/main/resources/META-INF/spring.factories b/wu-lazy-cloud-heartbeat-dns/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..f9b6772 --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/main/resources/META-INF/spring.factories @@ -0,0 +1,6 @@ +# Auto Configure +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.framework.lazy.cloud.network.heartbeat.dns.EnableDnsAutoConfiguration,\ +org.framework.lazy.cloud.network.heartbeat.dns.config.DnsAutoConfiguration,\ +org.framework.lazy.cloud.network.heartbeat.dns.init.InitDnsSocket,\ +org.framework.lazy.cloud.network.heartbeat.dns.config.DnsFlowConfiguration diff --git a/wu-lazy-cloud-heartbeat-dns/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/wu-lazy-cloud-heartbeat-dns/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..70b5eaa --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.framework.lazy.cloud.network.heartbeat.dns.EnableDnsAutoConfiguration +org.framework.lazy.cloud.network.heartbeat.dns.config.DnsAutoConfiguration +org.framework.lazy.cloud.network.heartbeat.dns.init.InitDnsSocket +org.framework.lazy.cloud.network.heartbeat.dns.config.DnsFlowConfiguration diff --git a/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/DnsServer.java b/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/DnsServer.java new file mode 100644 index 0000000..3e69d6c --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/DnsServer.java @@ -0,0 +1,52 @@ +package org.framework.lazy.cloud.network.heartbeat.dns; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.handler.codec.dns.DatagramDnsQueryDecoder; +import io.netty.handler.codec.dns.DatagramDnsResponseEncoder; + +public class DnsServer { + + private final int port; + + public DnsServer(int port) { + this.port = port; + } + + public void run() throws Exception { + EventLoopGroup group = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioDatagramChannel.class) + .option(ChannelOption.SO_BROADCAST, true) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(DatagramChannel ch) throws Exception { + ch.pipeline().addLast( + new DatagramDnsQueryDecoder(), + new DatagramDnsResponseEncoder(), + new DnsServerHandler() + ); + } + }); + + // 绑定端口 + ChannelFuture f = b.bind(port).sync(); + System.out.println("DNS server started and listening on port " + port); + f.channel().closeFuture().await(); + } finally { + group.shutdownGracefully(); + } + } + + public static void main(String[] args) throws Exception { + new DnsServer(53).run(); + } +} \ No newline at end of file diff --git a/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/DnsServerHandler.java b/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/DnsServerHandler.java new file mode 100644 index 0000000..a7775e9 --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/DnsServerHandler.java @@ -0,0 +1,37 @@ +package org.framework.lazy.cloud.network.heartbeat.dns; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.codec.dns.*; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class DnsServerHandler extends SimpleChannelInboundHandler { + + @Override + protected void channelRead0(ChannelHandlerContext ctx, DatagramDnsQuery query) throws Exception { + log.info("query:{}", query); + // 创建DNS响应 + DatagramDnsResponse response = new DatagramDnsResponse(query.recipient(), query.sender(), query.id()); + // 处理每个查询问题 + for (int i = 0; i < query.count(DnsSection.QUESTION); i++) { + DnsQuestion question = query.recordAt(DnsSection.QUESTION, i); + response.addRecord(DnsSection.QUESTION, question); + + // 简单示例:返回一个固定的A记录 + if (question.type() == DnsRecordType.A) { + DefaultDnsRawRecord answer = new DefaultDnsRawRecord( + question.name(), DnsRecordType.A, 3600, + io.netty.buffer.Unpooled.wrappedBuffer(new byte[]{127, 0, 0, 1})); + } + } + // 发送响应 + ctx.writeAndFlush(response); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} \ No newline at end of file diff --git a/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/demo/DnsServer.java b/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/demo/DnsServer.java new file mode 100644 index 0000000..055cf4e --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/demo/DnsServer.java @@ -0,0 +1,108 @@ +package org.framework.lazy.cloud.network.heartbeat.dns.demo; + + +import com.github.xiaoymin.knife4j.core.util.StrUtil; +import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.handler.codec.dns.*; +import io.netty.util.AttributeKey; +import lombok.extern.slf4j.Slf4j; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public final class DnsServer { + + private static final List BLACK_LIST_DOMAIN = new ArrayList<>(); + + static { + + String s; + try (InputStream is = DnsServer.class.getClassLoader().getResourceAsStream("black_list.txt"); + BufferedReader br = new BufferedReader(new InputStreamReader(is))) { + while (StrUtil.isNotBlank(s = br.readLine())) { + BLACK_LIST_DOMAIN.add(s); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + + public static void main(String[] args) throws Exception { + ProxyUdp proxyUdp = new ProxyUdp(); + proxyUdp.init(); + final int[] num = {0}; + final NioEventLoopGroup group = new NioEventLoopGroup(); + Bootstrap bootstrap = new Bootstrap(); + bootstrap.group(group).channel(NioDatagramChannel.class) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(NioDatagramChannel nioDatagramChannel) { + nioDatagramChannel.pipeline().addLast(new DatagramDnsQueryDecoder()); + nioDatagramChannel.pipeline().addLast(new SimpleChannelInboundHandler() { + + @Override + protected void channelRead0(ChannelHandlerContext ctx, DatagramDnsQuery msg) { + try { + DefaultDnsQuestion dnsQuestion = msg.recordAt(DnsSection.QUESTION); + String name = dnsQuestion.name(); + log.info(name + ++num[0]); + Channel channel = ctx.channel(); + int id = msg.id(); + channel.attr(AttributeKey.valueOf(String.valueOf(id))).set(msg); + if (BLACK_LIST_DOMAIN.contains(name)) { + DnsQuestion question = msg.recordAt(DnsSection.QUESTION); + DatagramDnsResponse dnsResponse = getDatagramDnsResponse(msg, id, question); + channel.writeAndFlush(dnsResponse); + return; + } + proxyUdp.send(name, msg.id(), channel); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + + private DatagramDnsResponse getDatagramDnsResponse(DatagramDnsQuery msg, int id, DnsQuestion question) { + DatagramDnsResponse dnsResponse = new DatagramDnsResponse(msg.recipient(), msg.sender(), id); + dnsResponse.addRecord(DnsSection.QUESTION, question); + + // just print the IP after query + DefaultDnsRawRecord queryAnswer = new DefaultDnsRawRecord( + question.name(), + DnsRecordType.A, 600, Unpooled.wrappedBuffer(new byte[]{(byte) 192, (byte) 168, 1, 1})); + dnsResponse.addRecord(DnsSection.ANSWER, queryAnswer); + return dnsResponse; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) { + log.error(e.getMessage(), e); + } + }); + nioDatagramChannel.pipeline().addLast(new DatagramDnsResponseEncoder()); + + } + }).option(ChannelOption.SO_BROADCAST, true); + + int port = 53; + ChannelFuture future = bootstrap.bind(port).addListener(future1 -> { + log.info("server listening port:{}", port); + }); + + future.channel().closeFuture().addListener(future1 -> { + if (future.isSuccess()) { + log.info(future.channel().toString()); + } + }); + } +} + diff --git a/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/demo/ProxyUdp.java b/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/demo/ProxyUdp.java new file mode 100644 index 0000000..ac4f377 --- /dev/null +++ b/wu-lazy-cloud-heartbeat-dns/src/test/java/org/framework/lazy/cloud/network/heartbeat/dns/demo/ProxyUdp.java @@ -0,0 +1,80 @@ +package org.framework.lazy.cloud.network.heartbeat.dns.demo; + +import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.handler.codec.dns.*; +import io.netty.util.AttributeKey; +import lombok.extern.slf4j.Slf4j; + +import java.net.InetSocketAddress; + +@Slf4j +class ProxyUdp { + private Channel localChannel; + private Channel proxyChannel; + + public void init() throws InterruptedException { + EventLoopGroup proxyGroup = new NioEventLoopGroup(); + Bootstrap b = new Bootstrap(); + b.group(proxyGroup) + .channel(NioDatagramChannel.class) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(DatagramChannel ch) { + ChannelPipeline p = ch.pipeline(); + p.addLast(new DatagramDnsQueryEncoder()) + .addLast(new DatagramDnsResponseDecoder()) + .addLast(new SimpleChannelInboundHandler() { + @Override + public void channelActive(ChannelHandlerContext ctx) { + log.info(ctx.channel().toString()); + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, DatagramDnsResponse msg) { + DatagramDnsQuery dnsQuery = localChannel.attr(AttributeKey.valueOf(String.valueOf(msg.id()))).get(); + DnsQuestion question = msg.recordAt(DnsSection.QUESTION); + DatagramDnsResponse dnsResponse = new DatagramDnsResponse(dnsQuery.recipient(), dnsQuery.sender(), msg.id()); + dnsResponse.addRecord(DnsSection.QUESTION, question); + + for (int i = 0, count = msg.count(DnsSection.ANSWER); i < count; i++) { + DnsRecord record = msg.recordAt(DnsSection.ANSWER, i); + if (record.type() == DnsRecordType.A) { + // just print the IP after query + DnsRawRecord raw = (DnsRawRecord) record; + DefaultDnsRawRecord queryAnswer = new DefaultDnsRawRecord( + question.name(), + DnsRecordType.A, 600, Unpooled.wrappedBuffer(ByteBufUtil.getBytes(raw.content()))); + dnsResponse.addRecord(DnsSection.ANSWER, queryAnswer); + } + } + + localChannel.writeAndFlush(dnsResponse); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) { + log.error(e.getMessage(), e); + } + }); + + } + }); + proxyChannel = b.bind(0).sync().addListener(future1 -> { + log.info("绑定成功"); + }).channel(); + } + + public void send(String domain, int id, Channel localChannel) { + this.localChannel = localChannel; + DnsQuery query = new DatagramDnsQuery(null, new InetSocketAddress("114.114.114.114", 53), id).setRecord( + DnsSection.QUESTION, + new DefaultDnsQuestion(domain, DnsRecordType.A)); + this.proxyChannel.writeAndFlush(query); + } +} \ No newline at end of file