• 握手5


    当发现 tcp 头部的 ACK 为 1 ,则进入下面函数处理 ,重点看一下:tcp_finish_connect

    void tcp_finish_connect(struct sock *sk, struct sk_buff *skb)
    {
        struct tcp_sock *tp = tcp_sk(sk);
        struct inet_connection_sock *icsk = inet_csk(sk);
    
        tcp_set_state(sk, TCP_ESTABLISHED);// 设置 sock 的状态 为 TCP_ESTABLISHED 
    
        if (skb != NULL) {
            icsk->icsk_af_ops->sk_rx_dst_set(sk, skb);
            security_inet_conn_established(sk, skb);
        }
    
        /* Make sure socket is routed, for correct metrics.  */
        icsk->icsk_af_ops->rebuild_header(sk);
    
        tcp_init_metrics(sk);
    
        tcp_init_congestion_control(sk);
    
        /* Prevent spurious tcp_cwnd_restart() on first data
         * packet.
         */
        tp->lsndtime = tcp_time_stamp;
    
        tcp_init_buffer_space(sk);
    
        if (sock_flag(sk, SOCK_KEEPOPEN))
            inet_csk_reset_keepalive_timer(sk, keepalive_time_when(tp));
    
        if (!tp->rx_opt.snd_wscale)
            __tcp_fast_path_on(tp, tp->snd_wnd);
        else
            tp->pred_flags = 0;
    
        if (!sock_flag(sk, SOCK_DEAD)) {
            sk->sk_state_change(sk);//默认函数为 sock_def_wakeup
    1. sock状态改变时调用,比如从TCP_SYN_SENT或TCP_SYN_RECV变为TCP_ESTABLISHED, 
    2. * 导致connect()的唤醒。比如从TCP_ESTABLISHED变为TCP_CLOSE_WAIT
    
            sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);// 用来将SIGIO或SIGURG信号发送给在该套接口上的进程,通知该进程可以对该文件进行读或写.
        }
    }

    对 sock 的状态修改完后 会效用如下函数

    void tcp_send_ack(struct sock *sk)
    {
        struct sk_buff *buff;
    
        /* If we have been reset, we may not send again. */
        if (sk->sk_state == TCP_CLOSE)
            return;
    
        tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK);
    
        /* We are not putting this on the write queue, so
         * tcp_transmit_skb() will set the ownership to this
         * sock.
         */
        buff = alloc_skb(MAX_TCP_HEADER, sk_gfp_atomic(sk, GFP_ATOMIC));
        if (buff == NULL) {
            inet_csk_schedule_ack(sk);
            inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN;
            inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
                          TCP_DELACK_MAX, TCP_RTO_MAX);
            return;
        }
    
        /* Reserve space for headers and prepare control bits. */
        skb_reserve(buff, MAX_TCP_HEADER);
        tcp_init_nondata_skb(buff, tcp_acceptable_seq(sk), TCPHDR_ACK);
    
        /* Send it off, this clears delayed acks for us. */
        skb_mstamp_get(&buff->skb_mstamp);
        tcp_transmit_skb(sk, buff, 0, sk_gfp_atomic(sk, GFP_ATOMIC));
    }

    构造一个 tcp 报文发送给服务器端。

  • 相关阅读:
    Aapache Tomcat AJP 文件包含漏洞(CVE-2020-1938)
    Tomcat 任意文件上传漏洞(CVE-2017-12615)
    Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)
    Redis 4.x/5.x 未授权访问漏洞
    mysql 5.7关于group by显示多列的一个潜坑
    Python
    购物车作业
    Lesson2
    a good website to test OTP
    利用fidder发送request
  • 原文地址:https://www.cnblogs.com/guoyu1024/p/10597066.html
Copyright © 2020-2023  润新知