握手4

最后看一下这个函数

/* Send a crossed SYN-ACK during socket establishment.
 * WARNING: This routine must only be called when we have already sent
 * a SYN packet that crossed the incoming SYN that caused this routine
 * to get called. If this assumption fails then the initial rcv_wnd
 * and rcv_wscale values will not be correct.
 */
int tcp_send_synack(struct sock *sk)
{
    struct sk_buff *skb;

    skb = tcp_write_queue_head(sk);
    if (skb == NULL || !(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)) {
        pr_debug("%s: wrong queue state\n", __func__);
        return -EFAULT;
    }
    if (!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_ACK)) {
        if (skb_cloned(skb)) {
            struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
            if (nskb == NULL)
                return -ENOMEM;
            tcp_unlink_write_queue(skb, sk);
            __skb_header_release(nskb);
            __tcp_add_write_queue_head(sk, nskb);
            sk_wmem_free_skb(sk, skb);
            sk->sk_wmem_queued += nskb->truesize;
            sk_mem_charge(sk, nskb->truesize);
            skb = nskb;
        }

        TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ACK;
        tcp_ecn_send_synack(sk, skb);
    }
    return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
}

将客户端发起连接请求的报文修改一下,发回给客户端。

猜你喜欢

转载自www.cnblogs.com/guoyu1024/p/10591425.html