Pav*_*l_K 2 networking linux ip
据我了解,0.0.0.0 表示该主机的所有网络接口(包括 127.0.0.1)。
假设我在某个主机(Linux 操作系统)上有三个接口 192.0.2.40、203.0.113.150 和 127.0.0.1。
在 192.0.2.40:777,我有 ServerA。在 203.0.113.150:777,我有 ServerB。操作系统如何解决连接到 0.0.0.0 的请求?我的意思是当同一个端口(777)在不同的接口上侦听什么服务器(服务器A或服务器B)以及为什么当我在this主机终端上做时会连接telnet 0.0.0.0 777
它仅表示作为源地址(即当将套接字绑定到本地接口时)。作为目标地址,它没有这个含义——从技术上讲,它是一个非法地址。
然而,似乎最初 BSD 将其视为环回连接,而 Linux 则继续进行。
对于 IPv4,net/ipv4/route.c在路由查找时处理全零目标:
struct rtable *ip_route_output_key_hash_rcu(...) {
...
if (!fl4->daddr) {
fl4->daddr = fl4->saddr;
if (!fl4->daddr)
fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
dev_out = net->loopback_dev;
fl4->flowi4_oif = LOOPBACK_IFINDEX;
res->type = RTN_LOCAL;
flags |= RTCF_LOCAL;
goto make_route;
}
...
}
Run Code Online (Sandbox Code Playgroud)
这意味着“如果目的地为空,则用 127.0.0.1 填充它并通过lo接口路由”。操作系统假装您尝试连接到本地主机。
IPv6 中的相同处理在协议级别(分别由 TCP 和 UDP)处理。例如,net/ipv6/tcp_ipv6.c包含:
static int tcp_v6_connect(...) {
...
/*
* connect() to INADDR_ANY means loopback (BSD'ism).
*/
if (ipv6_addr_any(&usin->sin6_addr)) {
if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
&usin->sin6_addr);
else
usin->sin6_addr = in6addr_loopback;
}
...
}
Run Code Online (Sandbox Code Playgroud)
同时在net/ipv6/udp.c:
int udpv6_sendmsg(...) {
...
if (!ipv6_addr_any(daddr))
fl6.daddr = *daddr;
else
fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
960 次 |
| 最近记录: |