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

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

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

public class MyDefaultNameResolver extends DefaultNameResolver {
    private Map> hostMap;

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

    @Override
    protected void doResolve(String inetHost, Promise 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 ctrlMap = hostMap.get("ctrlMap");
                setResolverIpAddress(ctrlMap,promise,inetHost);
                return;
            }
            if (checkGatewayIsIp()){
                Map gatewayMap = hostMap.get("gatewayMap");
                setResolverIpAddress(gatewayMap,promise,inetHost);
                return;
            }
            promise.setSuccess(SocketUtils.addressByName(inetHost));


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

    private void setResolverIpAddress(Map dataMap,Promise 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 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 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> promise) throws Exception {
        try {
            promise.setSuccess(Arrays.asList(SocketUtils.allAddressesByName(inetHost)));
        } catch (UnknownHostException e) {
            promise.setFailure(e);
        }
    }
}

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

public class MyAddressResolverGroup  extends AddressResolverGroup {

    private static  MyAddressResolverGroup INSTANCE;
    private Map> hostMap;

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

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

    protected AddressResolver 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));

你可能感兴趣的:(android)