mirror of
https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network.git
synced 2025-06-03 03:47:55 +08:00
【fix】 add dns module;
This commit is contained in:
parent
2389a25e11
commit
4690bc85b3
61
LazyDNS.puml
Normal file
61
LazyDNS.puml
Normal file
@ -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
|
||||||
|
|
1
pom.xml
1
pom.xml
@ -23,6 +23,7 @@
|
|||||||
<module>wu-lazy-cloud-heartbeat-server-cluster</module>
|
<module>wu-lazy-cloud-heartbeat-server-cluster</module>
|
||||||
<module>wu-lazy-cloud-heartbeat-client</module>
|
<module>wu-lazy-cloud-heartbeat-client</module>
|
||||||
<module>wu-lazy-cloud-heartbeat-common</module>
|
<module>wu-lazy-cloud-heartbeat-common</module>
|
||||||
|
<module>wu-lazy-cloud-heartbeat-dns</module>
|
||||||
|
|
||||||
<!-- 样例 -->
|
<!-- 样例 -->
|
||||||
<module>wu-lazy-cloud-heartbeat-start</module>
|
<module>wu-lazy-cloud-heartbeat-start</module>
|
||||||
|
59
wu-lazy-cloud-heartbeat-dns/pom.xml
Normal file
59
wu-lazy-cloud-heartbeat-dns/pom.xml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<groupId>top.wu2020</groupId>
|
||||||
|
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||||
|
<version>1.3.0-JDK17-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>wu-lazy-cloud-heartbeat-dns</artifactId>
|
||||||
|
<description>云上心跳服务dns</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.wu2020</groupId>
|
||||||
|
<artifactId>wu-framework-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- 通用心跳包 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.wu2020</groupId>
|
||||||
|
<artifactId>wu-lazy-cloud-heartbeat-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- 数据库 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.33</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.wu2020</groupId>
|
||||||
|
<artifactId>wu-database-lazy-plus-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>2.0.50</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger.core.v3</groupId>
|
||||||
|
<artifactId>swagger-annotations-jakarta</artifactId>
|
||||||
|
<version>2.2.21</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.wu2020</groupId>
|
||||||
|
<artifactId>wu-framework-lazy-orm-spring-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@ -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 {
|
||||||
|
}
|
@ -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 {
|
||||||
|
|
||||||
|
}
|
@ -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 {
|
||||||
|
|
||||||
|
}
|
@ -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 {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -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 {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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
|
@ -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
|
@ -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<DatagramChannel>() {
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
}
|
@ -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<DatagramDnsQuery> {
|
||||||
|
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
}
|
@ -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<String> 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<NioDatagramChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(NioDatagramChannel nioDatagramChannel) {
|
||||||
|
nioDatagramChannel.pipeline().addLast(new DatagramDnsQueryDecoder());
|
||||||
|
nioDatagramChannel.pipeline().addLast(new SimpleChannelInboundHandler<DatagramDnsQuery>() {
|
||||||
|
|
||||||
|
@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.<DatagramDnsQuery>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());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<DatagramChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(DatagramChannel ch) {
|
||||||
|
ChannelPipeline p = ch.pipeline();
|
||||||
|
p.addLast(new DatagramDnsQueryEncoder())
|
||||||
|
.addLast(new DatagramDnsResponseDecoder())
|
||||||
|
.addLast(new SimpleChannelInboundHandler<DatagramDnsResponse>() {
|
||||||
|
@Override
|
||||||
|
public void channelActive(ChannelHandlerContext ctx) {
|
||||||
|
log.info(ctx.channel().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void channelRead0(ChannelHandlerContext ctx, DatagramDnsResponse msg) {
|
||||||
|
DatagramDnsQuery dnsQuery = localChannel.attr(AttributeKey.<DatagramDnsQuery>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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user