您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    Docker容器网络下UDP协议的一个成绩(2)
    时间:2017-08-23 08:56 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    Docker容器网络下UDP协议的一个成绩

    这个成绩可以归结为一句话:UDP 在多网卡的状况下,能够会发作效劳器端源地址不对的状况,这是内核选路的结果。 为什么 UDP 和 TCP 有不同的选路逻辑呢?由于 UDP 是有形状的协议,内核不会保存衔接双方的信息,因此每次发送的报文都以为是独立的,socket 层每次发送报文默许状况不会指明要运用的源地址,只是阐明对方地址。因此,内核会为要收回去的报文选择一个 ip,这通常都是报文路由要经过的设备 ip 地址。

    有了这个缘由,还要解释一下成绩: 为什么 dnsmasq 效劳没有这个成绩呢 ?因此我运用 strace 工具抓取了 dnsmasq 和出成绩运用的网络 socket 系统调用,来查看它们两个究竟有什么区别。

    dnsmasq 在启动阶段监听了 UDP 和 TCP 的 54 端口(由于是在本地机器上测试的,为了避免和本地 DNS 监听的 DNS端口抵触,我选择了 54 而不是标准的 53 端口):

    socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4 

    setsockopt(4, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 

    bind(4, {sa_family=AF_INET, sin_port=htons(54), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 

    setsockopt(4, SOL_IP, IP_PKTINFO, [1], 4) = 0 

     

    socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 5 

    setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 

    bind(5, {sa_family=AF_INET, sin_port=htons(54), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 

    listen(5, 5)                            = 0 

    比起 TCP,UDP 部分少了 listen ,但是多个 setsockopt(4, SOL_IP, IP_PKTINFO, [1], 4) 这句。究竟这两点和我们的成绩能否有关,先暂时放着,继续看传输报文的部分。

    dnsmasq 收包和发包的系统调用,直接运用 recvmsg 和 sendmsg 系统调用:

    recvmsg(4, {msg_name(16)={sa_family=AF_INET, sin_port=htons(52072), sin_addr=inet_addr("10.111.59.4")}, msg_iov(1)=[{"\315\n\1 \0\1\0\0\0\0\0\1\fterminal19-0\5u5016\3"..., 4096}], msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=, ...}, msg_flags=0}, 0) = 67  

    sendmsg(4, {msg_name(16)={sa_family=AF_INET, sin_port=htons(52072), sin_addr=inet_addr("10.111.59.4")}, msg_iov(1)=[{"\315\n\201\200\0\1\0\1\0\0\0\1\fterminal19-0\5u5016\3"..., 83}], msg_controllen=28, {cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=, ...}, msg_flags=0}, 0) = 83 

    而出成绩的运用 strace 结果如下:

    [pid   477] socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 124 

    [pid   477] setsockopt(124, SOL_IPV6, IPV6_V6ONLY, [0], 4) = 0 

    [pid   477] setsockopt(124, SOL_IPV6, IPV6_MULTICAST_HOPS, [1], 4) = 0 

    [pid   477] bind(124, {sa_family=AF_INET6, sin6_port=htons(6088), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0 

     

    [pid   477] getsockname(124, {sa_family=AF_INET6, sin6_port=htons(6088), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0 

    [pid   477] getsockname(124, {sa_family=AF_INET6, sin6_port=htons(6088), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0 

     

    [pid   477] recvfrom(124, "j\201\2450\201\242\241\3\2\1\5\242\3\2\1\n\243\0160\f0\n\241\4\2\2\0\225\242\2\4\0"..., 2048, 0, {sa_family=AF_INET6, sin6_port=htons(38790), inet_pton(AF_INET6, "::ffff:172.17.0.3", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 168 

     

    (责任编辑:admin)