VPN 在Android中的通信三 (netty DNS 域名自解析)

文章介绍了如何在Netty中自定义DNS解析器MyDefaultNameResolver,用于将特定的域名解析到预设的IP地址,通过管理解析组MyAddressResolverGroup进行配置和绑定。
摘要由CSDN通过智能技术生成

        在使用场景中会遇到 需要netty socket的域名解析到指定IP地址,怎么做到呢,在我们的netty 中,提供了DNS域名解析(DefaultNameResolver)。

        一、自定义类MyDefaultNameResolver继承 DefaultNameResolver,实现doResolve方法,解析的相关逻辑在这里面处理

public class MyDefaultNameResolver extends DefaultNameResolver {
    private Map<String, Map<String, String>> hostMap;

    public MyDefaultNameResolver(EventExecutor executor, Map<String, Map<String, String>> hostMap) {
        super(executor);
        this.hostMap = hostMap;
    }

    @Override
    protected void doResolve(String inetHost, Promise<InetAddress> promise) throws Exception {
        try {
            if (TextUtils.equals(inetHost,SystemManager.ctrlServerAddress().split(":")[0])){
                if (!TextUtils.isEmpty(SystemManager.ctrlIpAddress())){
                    String [] ipAddress = SystemManager.ctrlIpAddress().split("\\.");
                    Inet4Address inet4Address = (Inet4Address) Inet4Address.getByAddress(inetHost, new byte[]{(byte) Integer.parseInt(ipAddress[0]), (byte) Integer.parseInt(ipAddress[1]), (byte)Integer.parseInt(ipAddress[2]), (byte) Integer.parseInt(ipAddress[3])});
                    promise.setSuccess(inet4Address);
                    return;
                }
                return;
            }
            if (!checkHostNameIsIp()) {
                promise.setSuccess(SocketUtils.addressByName(inetHost));
                return;
            }
            if (checkCtrlIsIp()) {
                Map<String, String> ctrlMap = hostMap.get("ctrlMap");
                setResolverIpAddress(ctrlMap,promise,inetHost);
                return;
            }
            if (checkGatewayIsIp()){
                Map<String, String> gatewayMap = hostMap.get("gatewayMap");
                setResolverIpAddress(gatewayMap,promise,inetHost);
                return;
            }
            promise.setSuccess(SocketUtils.addressByName(inetHost));


        } catch (UnknownHostException e) {
            promise.setFailure(e);
        }
    }

    private void setResolverIpAddress(Map<String, String> dataMap,Promise<InetAddress> promise,String inetHost) throws UnknownHostException {
        if (TextUtils.equals(dataMap.get("host"), inetHost)) {
            String [] ipAddress = dataMap.get("ipAddress").split("\\.");
            Inet4Address inet4Address = (Inet4Address) Inet4Address.getByAddress(inetHost, new byte[]{(byte) Integer.parseInt(ipAddress[0]), (byte) Integer.parseInt(ipAddress[1]), (byte)Integer.parseInt(ipAddress[2]), (byte) Integer.parseInt(ipAddress[3])});
            promise.setSuccess(inet4Address);
            return;
        }
        promise.setSuccess(SocketUtils.addressByName(inetHost));
    }

    private boolean checkHostNameIsIp() {
        if (hostMap == null) {
            return false;
        }
        if (hostMap.size() == 0) {
            return false;
        }
        return true;
    }

    private boolean checkCtrlIsIp() {
        try {
            if (!hostMap.containsKey("ctrlMap")) {
                return false;
            }
            Map<String, String> ctrlMap = hostMap.get("ctrlMap");
            if (ctrlMap.containsKey("host") && ctrlMap.containsKey("ipAddress") && ctrlMap.get("ipAddress").contains(".")) {
                return true;
            }
            return false;
        }catch (Exception e){
            return false;
        }
    }

    private boolean checkGatewayIsIp() {
        try {
            if (!hostMap.containsKey("ctrlMap")) {
                return false;
            }
            Map<String, String> ctrlMap = hostMap.get("ctrlMap");
            if (ctrlMap.containsKey("host") && ctrlMap.containsKey("ipAddress") && ctrlMap.get("ipAddress").contains(".")) {
                return true;
            }
            return false;
        }catch (Exception e){
            return false;
        }

    }

    @Override
    protected void doResolveAll(String inetHost, Promise<List<InetAddress>> promise) throws Exception {
        try {
            promise.setSuccess(Arrays.asList(SocketUtils.allAddressesByName(inetHost)));
        } catch (UnknownHostException e) {
            promise.setFailure(e);
        }
    }
}

二、需要解析组来进行管理MyDefaultNameResolver,新增解析组 MyAddressResolverGroup 继承AddressResolverGroup<InetSocketAddress> 在newResolver 方法绑MyDefaultNameResolver

public class MyAddressResolverGroup  extends AddressResolverGroup<InetSocketAddress> {

    private static  MyAddressResolverGroup INSTANCE;
    private Map<String, Map<String,String>> hostMap;

    public static MyAddressResolverGroup getInstance(Map<String, Map<String,String>> hostMap) {
        if (INSTANCE==null){
            INSTANCE = new MyAddressResolverGroup(hostMap);
        }
        return INSTANCE;
    }

    private MyAddressResolverGroup(Map<String, Map<String,String>> hostMap) {
        this.hostMap = hostMap;
    }

    protected AddressResolver<InetSocketAddress> newResolver(EventExecutor executor) throws Exception {
        return (new MyDefaultNameResolver(executor,this.hostMap)).asAddressResolver();
    }
}

三、在创建netty 中绑定这个域名解析器 即MyAddressResolverGroup

   bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
                    .resolver(MyAddressResolverGroup.getInstance(hostMap))
                    .option(ChannelOption.TCP_NODELAY, true)
                    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
                    .option(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT)
                    .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(5000, 5000, 80000))
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .handler(new SdpNettyHandler(sslContext, readQueue, writeQueue));

  • 23
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尚思app

您的鼓励是我最大的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值