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

widebright的个人空间

// 编程和生活

 
 
 

日志

 
 

linux内核tcp实现源码阅读计划  

2013-09-20 15:08:04|  分类: 程序设计 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

先挖一个大坑,有时间看看。

?

TCP接收方存在3种队列:

1 Backlog Queue (sk->backlog)

2 Prequeue Queue (tp->ucopy.prequeue)

3 Receive Queue (sk->receive_queue)



http://lxr.linux.no/linux+v3.11/net/ipv4/tcp_ipv4.c

tcp_v4_rcv     //软中断上下文

  tcp_v4_do_rcv

    if (sk->sk_state == TCP_ESTABLISHED)  {

        tcp_rcv_established

    if (sk->sk_state == TCP_LISTEN) {

        tcp_child_process


socket_recvMsg

  tcp_recvmsg  //进程上下文



tcp_prequeue




http://lxr.linux.no/linux+v3.11/net/ipv4/inet_connection_sock.c

inet_csk_accept

inet_csk_wait_for_connect











tcp发送缓存限制相关

====================

http://lxr.linux.no/linux+v3.2/net/socket.c

http://lxr.linux.no/linux+v3.2/net/ipv4/tcp.c

http://lxr.linux.no/linux+v3.2/net/ipv4/tcp_ipv4.c

http://lxr.linux.no/linux+v3.2/net/ipv4/sysctl_net_ipv4.c      /proc/sys/net/ipv4/   sys文件接口,一些tcp参数设置

http://lxr.linux.no/linux+v3.2/include/net/sock.h

http://lxr.linux.no/linux+v3.2/net/core/stream.c


writev

aio_write

 sock_aio_write  

do_sock_write

__sock_sendmsg

__sock_sendmsg

   __sock_sendmsg_nosec

    struct proto tcp_prot  .sendmsg

tcp_sendmsg

          

tcp_sendmsg 里面会判断 发送缓存是不是已经超过/proc/sys/net/ipv4/tcp_wmem的设置


static inline int sk_stream_memory_free(struct sock *sk)

 {

         return sk->sk_wmem_queued < sk->sk_sndbuf;

 }



/*

 *      Default write policy as shown to user space via poll/select/SIGIO

 */

static inline int sock_writeable(const struct sock *sk) 

{

        return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf >> 1);

}


static int tcp_v4_init_sock(struct sock *sk)

sk->sk_sndbuf = sysctl_tcp_wmem[1]


 /**

 * sk_stream_wait_memory - Wait for more memory for a socket

 * @sk: socket to wait for memory

 * @timeo_p: for how long

 */

 nt sk_stream_wait_memory(struct sock *sk, long *timeo_p)

 

        int err = 0;

        long vm_wait = 0;

        long current_timeo = *timeo_p;

        DEFINE_WAIT(wait);

 

        if (sk_stream_memory_free(sk))

                current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2;

 

        while (1) {

                set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);

 

                prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);

 

                if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))

                        goto do_error;

                if (!*timeo_p)

                        goto do_nonblock;

                if (signal_pending(current))

                        goto do_interrupted;

                clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);

                if (sk_stream_memory_free(sk) && !vm_wait)

                        break;

 

                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);

                sk->sk_write_pending++;

                sk_wait_event(sk, &current_timeo, sk->sk_err ||

                                                  (sk->sk_shutdown & SEND_SHUTDOWN) ||

                                                  (sk_stream_memory_free(sk) &&

                                                  !vm_wait));

                sk->sk_write_pending--;

 

                if (vm_wait) {

                        vm_wait -= current_timeo;

                        current_timeo = *timeo_p;

                        if (current_timeo != MAX_SCHEDULE_TIMEOUT &&

                            (current_timeo -= vm_wait) < 0)

                                current_timeo = 0;

                        vm_wait = 0;

                }

                *timeo_p = current_timeo;

        }

 ut:

        finish_wait(sk_sleep(sk), &wait);

        return err;

 

 o_error:

        err = -EPIPE;

        goto out;

 o_nonblock:

        err = -EAGAIN;              ////////////writev返回没有内存可以使用??? 

        goto out;

 o_interrupted:

        err = sock_intr_errno(*timeo_p);

        goto out;

 

 XPORT_SYMBOL(sk_stream_wait_memory);






 /proc/net/tcp  的输出来自下面这两个函数

 http://lxr.linux.no/linux+v3.2/net/ipv4/tcp_ipv4.c

 tcp4_seq_show 

     get_tcp4_sock


 




  评论这张
 
阅读(752)| 评论(0)
推荐 转载

历史上的今天

评论

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

页脚

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