注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

linux中绑定一个不存在的本地地址  

2012-09-13 00:06:42|  分类: Linux内核 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、bind一个非本地地址
这个问题看起来还是比较奇怪的,如果bind系统调用中绑定一个本地并不存在的IP地址会怎样呢?直观的反应就是绑定会失败,但是从内核的角度来看,这就要求内核在某个结构中保存有整个系统的所有的已经注册或者说设置过的IP地址。IP地址是inter网的基本概念,所以顺便看看内核中对于所有的网络地址的处理也是一个比较好的切入点。
二、bind的执行
大致看来,用户态的bind在内核中的对应实现叫做sys_bind,这一路走下来,走到我们感兴趣的一个地址,就是
sys_bind--->>>>sys_bind
就像教室里阴暗的角落里总会发出不和谐的声音一样,这个函数的开始也横亘着一个常常被我们忽略的一段代码
chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);

    /* Not specified by any standard per-se, however it breaks too
     * many applications when removed.  It is unfortunate since
     * allowing applications to make a non-local bind solves
     * several problems with systems using dynamic addressing.
     * (ie. your servers still start up even if your ISDN link
     *  is temporarily down)
     */
    err = -EADDRNOTAVAIL;
    if (!sysctl_ip_nonlocal_bind &&
        !inet->freebind &&
        addr->sin_addr.s_addr != INADDR_ANY &&
        chk_addr_ret != RTN_LOCAL &&
        chk_addr_ret != RTN_MULTICAST &&
        chk_addr_ret != RTN_BROADCAST)
        goto out;
内核代码的一个好处就是在于大家写代码比较随意,所以注释也比较随意,一些比较生僻的代码中都会包含一些比较有指导性的注释。在这个函数中,作者说了这段代码的意义:“这个功能在任何的标准文档中都没有描述过,只是如果说删除这些代码很多的应用程序将会挂掉。使用非本地地址绑定可以解决一些使用动态地址绑定的服务器程序,所以这个实现还是有实际意义的”。
从这里的代码看,如果一个非本地绑定可以成功,里面有两个标志置位即可。其中第一个sysctl_ip_nonlocal变量从命令看明显就是一个proc下的sysctl文件,通过查看代码可以知道,该proc文件位于
[tsecer@Harry template]$ cat /proc/sys/net/ipv4/ip_nonlocal_bind
0
[tsecer@Harry template]$
默认值为零,也就是不允许非本地地址的绑定。如果把该值修改为1,那么就可以通过bind来bind一个非本地网络地址了。而且还有一个freebind,这个是通过sec_sockopt来修改的,所以就不用管了。
执行了bind+listen之后,此时系统还是没有这个IP地址,但是这个并不影响问题。因为这个listen只是申请一个侦听的套接口结构,当网络的报文到达之后,它从内存中搜索这个数据结构,如果找到那么就把报文分配给它。如果这个机器本身并不拥有这个网络地址,那么这个过程可能性不大。以太网的报文首先要经过网卡的物理过滤(除非设置为杂收模式),然后还有本机的IP层路由。
三、系统中所有的IP地址
本地系统中地址的添加则是在下面的文件中完成的
(gdb) bt
#0  fib_magic (cmd=24, type=2, dst=3737888960, dst_len=32, ifa=0xcfed09e0)
    at net/ipv4/fib_frontend.c:637
#1  0xc077d252 in fib_add_ifaddr (ifa=0xcfed09e0)
    at net/ipv4/fib_frontend.c:680
#2  0xc077d8f2 in fib_inetaddr_event (this=0xc09e645c, event=1, ptr=0xcfed09e0)
    at net/ipv4/fib_frontend.c:847
#3  0xc08528f2 in notifier_call_chain (nl=0xc09e5048, val=1, v=0xcfed09e0)
    at kernel/sys.c:146
#4  0xc0157ede in blocking_notifier_call_chain (nh=0xc09e5038, val=1,
    v=0xcfed09e0) at kernel/sys.c:335
#5  0xc076d0d0 in __inet_insert_ifa (ifa=0xcfed09e0, nlh=0x0, pid=0)
    at net/ipv4/devinet.c:386
#6  0xc076d0f1 in inet_insert_ifa (ifa=0xcfed09e0) at net/ipv4/devinet.c:393
#7  0xc076d246 in inet_set_ifa (dev=0xcff11000, ifa=0xcfed09e0)
    at net/ipv4/devinet.c:416
#8  0xc076efca in devinet_ioctl (cmd=35094, arg=0xbf9b86f4)
    at net/ipv4/devinet.c:776
#9  0xc0772d2b in inet_ioctl (sock=0xcfbbf980, cmd=35094, arg=3214640884)
    at net/ipv4/af_inet.c:779
#10 0xc06d561f in sock_ioctl (file=0xc12763a0, cmd=35094, arg=3214640884)
    at net/socket.c:867
#11 0xc01d30f6 in do_ioctl (filp=0xc12763a0, cmd=35094, arg=3214640884)
    at fs/ioctl.c:28
---Type <return> to continue, or q <return> to quit---
#12 0xc01d3615 in vfs_ioctl (filp=0xc12763a0, fd=3, cmd=35094, arg=3214640884)
    at fs/ioctl.c:153
#13 0xc01d3692 in sys_ioctl (fd=3, cmd=35094, arg=3214640884) at fs/ioctl.c:173
在这个文件中设置fib_magic的类型为
    fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim);
这里大家终于汇合了,也算是满足了对于地址的绑定判断。
  评论这张
 
阅读(1135)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017