node.js - NodeJS“http”localAddress 不能在多个网络接口上使用相同的子网
问题描述
我在一个使用 2 个硬件以太网接口的嵌入式系统(Ubuntu 14.04)上工作,这两个接口都有一个链接本地地址别名,如您在此处看到的(使用ip a
):
eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 3000
link/ether 00:1e:2d:00:40:6d brd ff:ff:ff:ff:ff:ff
inet 10.251.25.206/24 brd 10.251.25.255 scope global eth1
valid_lft forever preferred_lft forever
inet 169.254.11.1/16 scope global eth1
valid_lft forever preferred_lft forever
eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb qlen 3000
link/ether 00:1e:2d:00:40:6c brd ff:ff:ff:ff:ff:ff
inet 192.43.182.23/20 brd 192.43.191.255 scope global eth0
valid_lft forever preferred_lft forever
inet 169.254.10.1/16 scope global eth0
valid_lft forever preferred_lft forever
一些相机连接在两个接口上,每个接口都有一个本地链接地址,我需要向所有相机发送 http 请求,但是我无法使用http
NodeJS 的官方模块向这些相机发送 http 请求(实际上我也试过了request module
,但它不起作用)。request
调用的函数的一个选项localAddress
允许使用正确的接口/地址,但是,当两个接口具有相同的子网(此处为链接本地)时,它不起作用。
假设我的系统没有链接本地别名,并且每个接口上连接了 1 个摄像头:
- camera0:连接到地址为 169.254.10.50 的 eth0
- camera1:连接到地址为 169.254.11.50 的 eth1
现在让我们按照以下步骤操作:
- 由于我不在同一个子网中,因此我无法与摄像机通信。
- 我将别名 169.254.10.1/16 添加到 eth0。
- => 现在我可以向 camera0 发送请求(设置选项
localAddress
是否为 169.254.10.1 是一样的,它足够聪明找到它) - 我将别名 169.254.11.1/16 添加到 eth1
- => 我仍然可以向 camera0 发送请求(设置
localAddress
与否),但是,我无法向 camera1 发送请求,即使我设置localAddress
为 169.254.11.1 - 接下来,我删除 eth0 上的别名,然后重新创建它
- => 现在我可以向 camera1 发送请求,无论 的值如何
localAddress
,但我无法再访问 camera0,即使我设置localAddress
为 169.254.10.1
出现的错误是 EHOSTUNREACH。
难道我做错了什么 ?那是一个错误吗?它是 Linux/IP 的限制吗?我怎样才能在不必删除/创建别名的情况下向两个 eth 发送请求?
使用 tcpdump 我看到谁有没有回答的请求:
08:54:31.236974 ARP, Request who-has 169.254.11.50 tell 169.254.11.1, length 28
08:54:32.283507 ARP, Request who-has 169.254.11.50 tell 169.254.11.1, length 28
08:54:33.307486 ARP, Request who-has 169.254.11.50 tell 169.254.11.1, length 28
08:55:02.383014 ARP, Request who-has 169.254.11.50 tell 169.254.11.1, length 28
08:55:03.387588 ARP, Request who-has 169.254.11.50 tell 169.254.11.1, length 28
08:55:04.411586 ARP, Request who-has 169.254.11.50 tell 169.254.11.1, length 28
但是ping -I eth0 169.254.10.50
,ping -I eth1 169.254.11.50
同时使用在网络接口中设置的两个别名。
谢谢
解决方案
我找到了通过修改路由表/规则使其工作的方法。
这是我为使其工作所做的工作:
- 首先,我添加了 2 个表
lla_eth0
和lla_eth1
('lla' 代表链接本地地址):
# echo -e "1\tlla_eth0" >> /etc/iproute2/rt_tables
# echo -e "2\tlla_eth1" >> /etc/iproute2/rt_tables
请注意,数字“1”和“2”是表的 ID,它们应该是唯一的,在我的情况下它们没有被使用。
- 然后在每个表上,我想将网络 169.254.0.0/16 中的每个目标地址路由到它们相应的接口:
# ip route add 169.254.0.0/16 dev eth0 table lla_eth0
# ip route add 169.254.0.0/16 dev eth1 table lla_eth1
- 最后,我设置了两条规则,每次使用源 169.254.10.1 时,我们使用表 lla_eth0,同样使用 169.254.11.1 和 lla_eth1:
# ip rule add from 169.254.10.1 table lla_eth0
# ip rule add from 169.254.11.1 table lla_eth1
推荐阅读
- python - 是否有更 Pythonic 的方式通过字符串名称访问函数?
- c# - Xamarin 窗体 WebView 滑动
- java - 如何转到 Thymleaf 中的 th:text 中的下一行?
- hadoop - 我们如何才能从 hdfs 联邦的一个命名空间中排除一些数据节点?
- java - 有没有办法使用java检查和释放数据库锁?
- c# - 统一:全方位的重力
- c++ - 如何将 stderr 与输出流相关联
- r - R Markdown:knitr选项结果='隐藏'不起作用
- c# - 如何使用向导在 Visual Studio 2017 中添加项目模板
- .net - MVC .NET CORE - DataAnnotation 的Required(ErrorMessage="Err") 不会出现在服务器端验证中