Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

当机器同时存在内网和外网IP时,无法发布内网IP服务 #3802

Closed
nevin9939 opened this issue Apr 3, 2019 · 7 comments
Closed
Labels
help wanted Everything needs help from contributors
Milestone

Comments

@nevin9939
Copy link

Environment

  • Dubbo version: 2.7.1
  • Operating System version: xxx
  • Java version: 1.8.181

Steps to reproduce this issue

  1. 服务都是部署在阿里云的ECS上
  2. hosts中修改机器名执行本机的内网IP
  3. dubbo注册到zookeeper的服务IP是外网IP
  4. 原整个环境的dubbo服务均提供内网服务,禁止外网的服务和请求进入,造成服务调不通

查看源代码发现在 request #3520 中调整为优先获取外网IP,造成了当机器同时存在内网IP和外网IP时,期望只提供内网IP服务时就无法做到,个人认为最好有个配置开关,有用户决定是提供内网服务还是外网服务

@ralf0131
Copy link
Contributor

ralf0131 commented Apr 4, 2019

+1 to you proposal, would you like to send a pull request to fix this?

@ralf0131 ralf0131 added the help wanted Everything needs help from contributors label Apr 4, 2019
@nevin9939
Copy link
Author

I can try it, not a lot of spare time.

@lexburner
Copy link
Contributor

@nevin9939 I send a pull request, could you pls review it and try it to see whether meet your requirement? Thanks.

@nevin9939
Copy link
Author

nevin9939 commented Apr 10, 2019

@lexburner
我也写完了 (T_T) , 看了下我跟你的区别主要在首选网卡的选择,跟操作系统同步,这样可以防止优先获取到虚拟机和蓝牙桥接网卡,你可以加进去。还有,我认为默认值应该是false,因为照原来的逻辑,获取的都是内网IP,这样用户就不会受升级的变化而困扰,去添加额外的配置

    private static InetAddress getLocalAddress0() {
        InetAddress candidateAddress = null;
        int interfacesIndex = 0;
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            if (null != interfaces) {
                while (interfaces.hasMoreElements()) {
                    try {
                        NetworkInterface network = interfaces.nextElement();
                        // Remove loopback interface, subinterface, not running interface
                        if (network.isLoopback() || network.isVirtual() || !network.isUp()) {
                            continue;
                        }
                        Enumeration<InetAddress> addresses = network.getInetAddresses();
                        while (addresses.hasMoreElements()) {
                            try {
                                Optional<InetAddress> addressOp = toValidAddress(addresses.nextElement());
                                if (addressOp.isPresent()) {
                                    InetAddress tempAddress = addressOp.get();
                                    if (candidateAddress == null || interfacesIndex > network.getIndex()) {
                                        // Priority is given to the network card with a small index value,
                                        // which can exclude the IP of the self-built virtual machine.
                                        candidateAddress = tempAddress;
                                        interfacesIndex = network.getIndex();
                                    }
                                }
                            } catch (Throwable e) {
                                logger.warn(e);
                            }
                        }
                    } catch (Throwable e) {
                        logger.warn(e);
                    }
                }
            }
            if(candidateAddress == null){
                InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
                if (jdkSuppliedAddress == null) {
                    throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
                }
                Optional<InetAddress> addressOp = toValidAddress(jdkSuppliedAddress);
                if (addressOp.isPresent()) {
                    candidateAddress = addressOp.get();
                }
            }
        } catch (Throwable e) {
            logger.warn(e);
        }
        return candidateAddress;
    }

@lexburner
Copy link
Contributor

Looks good to me, I will take it as consideration.

@beiwei30
Copy link
Member

this sounds like a solid solution to filter out the network interfaces first:

if (network.isLoopback() || network.isVirtual() || !network.isUp()) {
                            continue;
                        }

And, it looks we should either rollback the logic 'isSiteLocalAddress()' or add a flag for it.

@beiwei30 beiwei30 added this to the 2.7.2 milestone Apr 26, 2019
@cvictory cvictory closed this as completed May 6, 2019
@cvictory cvictory reopened this May 6, 2019
@beiwei30
Copy link
Member

beiwei30 commented May 6, 2019

#3953 enhanced this issue.

@beiwei30 beiwei30 closed this as completed May 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Everything needs help from contributors
Projects
None yet
Development

No branches or pull requests

5 participants