jiufei19 发表于 2016-08-02 13:56

tcp_child_process()函数处理的一个疑问

本帖最后由 jiufei19 于 2016-08-02 13:56 编辑

内核版本2.6.23

707 int tcp_child_process(struct sock *parent,struct sock *child,
708                           struct sk_buff *skb)
709 {
710   int ret = 0;
711   int state = child->sk_state;
712
713   if (!sock_owned_by_user(child)) {
714         ret = tcp_rcv_state_process(child, skb,tcp_hdr(skb),
715                                          skb->len);

...       ...
   
对该函数的上面那句红色语句,我存在一个疑问,一直不太清楚其具体场景,child是在3次握手时服务器收到客户端发来的ack时由tcp_v4_hnd_req()函数创建好的,但是由于3次握手的全过程还在进行中,因此用户进程似乎此时并没有机会去使用该子套接字,那么为啥需要有此判断?

另外,由于child的所有属性几乎来自其parent套接字,也即监听套接字,而监听套接字的确可能正在被用户进程操作,那么对监听套接字而言,sock_owned_by_user的判断可能为真,因此child继承来的该属性似乎也会为真,但是似乎在child的创建过程中,又无法保持有用户进程已经对监听套接字进行占用的场景,所以我很困惑,请各位帮忙解答,谢谢!

jiufei19 发表于 2016-08-02 15:00

本帖最后由 jiufei19 于 2016-08-02 15:16 编辑

又仔细想了想,并结合代码,发现可能是在inet_accept的执行过程中,似乎有一点时机会出现这个现象,下面我解释下,看看是否有错

inet_accept
   |--inet_csk_accept
       |--inet_csk_wait_for_connect
            |--release_sock
               |--__release_sock
               |      |--bh_unlock_sock
               |    |--sk->sk_backlog_rcv()---> tcp_v4_do_rcv--->tcp_v4_hnd_req--->tcp_v4_syn_recv_sock-->tcp_create_openreq_child
               |
                |--sk->sk_lock.owner = NULL

可以看到,服务器方用户进程在执行完inet_listen后,假如紧接着执行inet_accept,则在进入休眠前会执行release_sock,此时假如收到了3次握手的ack分段,则我们再假定用户进程执行完bh_unlock_sock红色语句后,由于此时已经释放完对监听套接字的lock了,则TCP线程有机会在tcp_v4_rcv()中进行处理,但此时sk->sk_lock.owner=NULL还未执行,于是只能将此ack放入backlog队列中等待,恰恰此时用户进程执行蓝色字体语句,于是在 tcp_v4_do_rcv--->tcp_v4_hnd_req--->tcp_v4_syn_recv_sock-->tcp_create_openreq_child中clone监听套接字来创建child套接字时就出现了我之前提出的疑问。


请问各位,我的解释是否合理?
页: [1]
查看完整版本: tcp_child_process()函数处理的一个疑问