亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 1857 | 回復(fù): 0
打印 上一主題 下一主題

內(nèi)核中的TCP的追蹤分析-16-TCP(IPV4)的客戶端與服務(wù)器端socket連接過(guò)程-3 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2008-11-21 11:20 |只看該作者 |倒序?yàn)g覽

在上面15節(jié)處我們最后跟蹤到了內(nèi)核的tcp_v4_rcv()函數(shù)處,它在/net/ipv4/tcp_ipv4.c中的1601行處,我們分段來(lái)看
int tcp_v4_rcv(struct sk_buff *skb)
{
    const struct iphdr *iph;
    struct tcphdr *th;
    struct sock *sk;
    int ret;
    if (skb->pkt_type != PACKET_HOST)
        goto discard_it;
    /* Count it even if it's bad */
    TCP_INC_STATS_BH(TCP_MIB_INSEGS);
    if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
        goto discard_it;
    th = tcp_hdr(skb);
    if (th->doff  sizeof(struct tcphdr) / 4)
        goto bad_packet;
    if (!pskb_may_pull(skb, th->doff * 4))
        goto discard_it;
    /* An explanation is required here, I think.
     * Packet length and doff are validated by header prediction,
     * provided case of th->doff==0 is eliminated.
     * So, we defer the checks. */
    if (!skb_csum_unnecessary(skb) && tcp_v4_checksum_init(skb))
        goto bad_packet;
    th = tcp_hdr(skb);
    iph = ip_hdr(skb);
    TCP_SKB_CB(skb)->seq = ntohl(th->seq);
    TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
                 skb->len - th->doff * 4);
    TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
    TCP_SKB_CB(skb)->when     = 0;
    TCP_SKB_CB(skb)->flags     = iph->tos;
    TCP_SKB_CB(skb)->sacked     = 0;
    sk = __inet_lookup(dev_net(skb->dev), &tcp_hashinfo, iph->saddr,
            th->source, iph->daddr, th->dest, inet_iif(skb));
    if (!sk)
        goto no_tcp_socket;
函數(shù)開頭首先是檢查一下數(shù)據(jù)包的類型是否是PACKET_HOST,即是否是發(fā)給本機(jī)的數(shù)據(jù)包,如果不是就要跳轉(zhuǎn)到標(biāo)號(hào)discard_it處丟掉數(shù)據(jù)包。TCP_INC_STATS_BH是一個(gè)宏
#define TCP_INC_STATS_BH(field)        SNMP_INC_STATS_BH(tcp_statistics, field)
#define SNMP_INC_STATS_BH(mib, field)     \
    (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]++)
我們這里看到了tcp_statistics它是在/net/ipv4/tcp.c中聲明的
DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics) __read_mostly;
這里涉及到了SNMP的統(tǒng)計(jì)信息,SNMP(Simple Network Management Protocol,簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議)的前身是簡(jiǎn)單網(wǎng)關(guān)監(jiān)控協(xié)議(SGMP),用來(lái)對(duì)
通信
線路進(jìn)行管理。具體的解釋請(qǐng)朋友們看
http://baike.baidu.com/view/2899.htm
  我們可以在/include/net/snmp.h中看到關(guān)于snmp的這個(gè)宏
#define DEFINE_SNMP_STAT(type, name)    \
    __typeof__(type) *name[2]
所以上面實(shí)際上是聲明了一個(gè)struct tcp_mib的結(jié)構(gòu)變量tcp_statistics,我們會(huì)在snmp.h中同時(shí)看到
struct tcp_mib {
    unsigned long    mibs[TCP_MIB_MAX];
} __SNMP_MIB_ALIGN__;
相關(guān)于具體的snmp在內(nèi)核的原理請(qǐng)朋友們參考
http://blog.chinaunix.net/u/12313/showart_172685.html
,我們這里就不再具體分析了,但是從函數(shù)中調(diào)用字面上來(lái)看是增加了tcp_statistics中的mibs關(guān)于TCP_MIB_INSEGS的計(jì)數(shù)。我們繼續(xù)往下看tcp_v4_rcv()函數(shù),代碼中接著調(diào)用了
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
    if (likely(len = skb_headlen(skb)))
        return 1;
    if (unlikely(len > skb->len))
        return 0;
    return __pskb_pull_tail(skb, len-skb_headlen(skb)) != NULL;
}
很明顯是對(duì)數(shù)據(jù)包頭的長(zhǎng)度檢測(cè),如果數(shù)據(jù)包頭的長(zhǎng)度大于或等于struct tcphdr的tcp的頭結(jié)構(gòu)長(zhǎng)度的話也會(huì)丟掉數(shù)據(jù)包。檢測(cè)長(zhǎng)度通過(guò)后,就會(huì)取得數(shù)據(jù)包skb中的tcp頭結(jié)構(gòu),關(guān)于struct tcphdr我們?cè)诒绢愔械?1節(jié)
http://blog.chinaunix.net/u2/64681/showart.php?id=1415963
已經(jīng)列出了,朋友們可以回過(guò)頭去看一下,代碼中接著對(duì)這個(gè)tcp頭結(jié)構(gòu)進(jìn)行檢測(cè),看是否匹配要求,doff是指示頭長(zhǎng)度的變量值,如果doff小于tcp的標(biāo)準(zhǔn)頭部結(jié)構(gòu)的四分之一就會(huì)跳轉(zhuǎn)到bad_packet標(biāo)號(hào)處,增加tcp_statistics的TCP_MIB_INERRS關(guān)于出錯(cuò)的snmp統(tǒng)計(jì)信息,然后丟掉數(shù)據(jù)包。接下來(lái)再次以doff為參考查看數(shù)據(jù)包頭部是否越界了,接下來(lái)根據(jù)數(shù)據(jù)包的ip頭部和tcp的頭部結(jié)構(gòu)計(jì)算數(shù)據(jù)包中的關(guān)于tcp_skb_cb結(jié)構(gòu)的初始化操作。TCP_SKB_CB宏我們?cè)诒绢惖牡?0節(jié)看到了
http://blog.chinaunix.net/u2/64681/showart.php?id=1414314
這里我們就不具體解釋結(jié)構(gòu)變量的作用和意義了,我和具體的協(xié)議要求相關(guān),我們重點(diǎn)關(guān)心的是追蹤的關(guān)鍵過(guò)程,我們看到函數(shù)接著進(jìn)入了__inet_lookup()函數(shù)中
static inline struct sock *__inet_lookup(struct net *net,
                     struct inet_hashinfo *hashinfo,
                     const __be32 saddr, const __be16 sport,
                     const __be32 daddr, const __be16 dport,
                     const int dif)
{
    u16 hnum = ntohs(dport);
    struct sock *sk = __inet_lookup_established(net, hashinfo,
                saddr, sport, daddr, hnum, dif);
    return sk ? : __inet_lookup_listener(net, hashinfo, daddr, hnum, dif);
}
注意傳遞進(jìn)這個(gè)函數(shù)的參數(shù)除了數(shù)據(jù)包中的信息還有一個(gè)struct inet_hashinfo全局的結(jié)構(gòu)變量tcp_hashinfo,這個(gè)結(jié)構(gòu)在第6節(jié)中看到了
http://blog.chinaunix.net/u2/64681/showart.php?id=1404050
我們看到在__inet_lookup中,首先通過(guò)__inet_lookup_established()函數(shù)來(lái)查找已經(jīng)處于連接的sock結(jié)構(gòu)。
struct sock * __inet_lookup_established(struct net *net,
                 struct inet_hashinfo *hashinfo,
                 const __be32 saddr, const __be16 sport,
                 const __be32 daddr, const u16 hnum,
                 const int dif)
{
    INET_ADDR_COOKIE(acookie, saddr, daddr)
    const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
    struct sock *sk;
    const struct hlist_node *node;
    /* Optimize here for direct hit, only listening connections can
     * have wildcards anyways.
     */
    unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
    struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
    rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
    prefetch(head->chain.first);
    read_lock(lock);
    sk_for_each(sk, node, &head->chain) {
        if (INET_MATCH(sk, net, hash, acookie,
                    saddr, daddr, ports, dif))
            goto hit; /* You sunk my battleship! */
    }
    /* Must check for a TIME_WAIT'er before going to listener hash. */
    sk_for_each(sk, node, &head->twchain) {
        if (INET_TW_MATCH(sk, net, hash, acookie,
                    saddr, daddr, ports, dif))
            goto hit;
    }
    sk = NULL;
out:
    read_unlock(lock);
    return sk;
hit:
    sock_hold(sk);
    goto out;
}
這個(gè)函數(shù)我們暫且不具體解釋了,相關(guān)的hash表和hash桶的內(nèi)容已經(jīng)在第5節(jié)地址綁定那節(jié)中我們看到了,但是如果想看明白上面的代碼還需要了解關(guān)于hash表的過(guò)程,比較原理資料介紹在
http://www.fish888.com/linux-t168886
  這篇文章是針對(duì)2.4的內(nèi)核但是其原理對(duì)于朋友們?cè)敿?xì)了解內(nèi)核中的這個(gè)hash表有很好的學(xué)習(xí)作用。我們?nèi)绻貞浺幌略诒O(jiān)聽那節(jié)分析中,曾經(jīng)進(jìn)入了__inet_hash()函數(shù)中,將sock掛入到hash表的操作時(shí)
http://blog.chinaunix.net/u2/64681/showart.php?id=1404050
可以在那篇文章中__inet_hash()函數(shù)首先判斷sock的狀態(tài)是否是TCP_LISTEN ,如果不是的話就會(huì)調(diào)用__inet_hash_nolisten(),函數(shù)我們可以在這個(gè)函數(shù)中看到
void __inet_hash_nolisten(struct sock *sk)
{
    struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
    struct hlist_head *list;
    rwlock_t *lock;
    struct inet_ehash_bucket *head;
    BUG_TRAP(sk_unhashed(sk));
    sk->sk_hash = inet_sk_ehashfn(sk);
    head = inet_ehash_bucket(hashinfo, sk->sk_hash);
    list = &head->chain;
    lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
    write_lock(lock);
    __sk_add_node(sk, list);
    sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
    write_unlock(lock);
}
上面是調(diào)用了inet_ehash_bucket()來(lái)掛入我們的全局的tcp_hashinfo中的ehash的雜湊隊(duì)列中了,而__inet_lookup_established()則中再次調(diào)用inet_ehash_bucket()找到這個(gè)ehash雜湊隊(duì)列頭
static inline struct inet_ehash_bucket *inet_ehash_bucket(
    struct inet_hashinfo *hashinfo,
    unsigned int hash)
{
    return &hashinfo->ehash[hash & (hashinfo->ehash_size - 1)];
}
反之我們?cè)诒O(jiān)聽那節(jié)文章中講到我們的服務(wù)器socket是啟動(dòng)監(jiān)聽過(guò)程的,所以會(huì)在__inet_hash()函數(shù)中掛入tcp_hashinfo的listening_hash雜湊隊(duì)列中。這些過(guò)程請(qǐng)朋友們回過(guò)頭去看一下
http://blog.chinaunix.net/u2/64681/showart.php?id=1404050
那里的服務(wù)器端的監(jiān)聽過(guò)程了。我們看__inet_lookup_established()在上面的代碼中會(huì)通過(guò)INET_MATCH來(lái)查找我們?cè)诜⻊?wù)器端匹配數(shù)據(jù)包的要求的地址和端口的sock結(jié)構(gòu),這里我們知道數(shù)據(jù)包已經(jīng)根據(jù)路由改變了相應(yīng)的要查找的地址和端口,這些是在前面章節(jié)中路由過(guò)程中設(shè)置的,只是我們?cè)谀抢餂](méi)有詳細(xì)的對(duì)路由過(guò)程描述。我們以后會(huì)補(bǔ)上這段詳細(xì)的路由過(guò)程,因?yàn)槲覀冊(cè)诒O(jiān)聽分析過(guò)程知道了服務(wù)器端的sock處于監(jiān)聽狀態(tài)并沒(méi)有掛入ehash雜湊隊(duì)列所以__inet_lookup_established()沒(méi)有找到想要的sock結(jié)構(gòu)。所以回到__inet_lookup()函數(shù)會(huì)執(zhí)行__inet_lookup_listener函數(shù)在listening_hash的監(jiān)聽的雜湊隊(duì)列中查找
struct sock *__inet_lookup_listener(struct net *net,
                 struct inet_hashinfo *hashinfo,
                 const __be32 daddr, const unsigned short hnum,
                 const int dif)
{
    struct sock *sk = NULL;
    const struct hlist_head *head;
    read_lock(&hashinfo->lhash_lock);
    head = &hashinfo->listening_hash[inet_lhashfn(hnum)];
    if (!hlist_empty(head)) {
        const struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
        if (inet->num == hnum && !sk->sk_node.next &&
         (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
         (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
         !sk->sk_bound_dev_if && net_eq(sock_net(sk), net))
            goto sherry_cache;
        sk = inet_lookup_listener_slow(net, head, daddr, hnum, dif);
    }
    if (sk) {
sherry_cache:
        sock_hold(sk);
    }
    read_unlock(&hashinfo->lhash_lock);
    return sk;
}
這個(gè)函數(shù)我們就不用多解釋了,在這個(gè)函數(shù)中我們找到了已經(jīng)創(chuàng)建并處于監(jiān)聽狀態(tài)的sock結(jié)構(gòu),這是我們?cè)诘?節(jié)中講述的。在那篇文章結(jié)尾有些未解的問(wèn)題現(xiàn)在已經(jīng)對(duì)接清楚了。
http://blog.chinaunix.net/u2/64681/showart.php?id=1404050
。
回到tcp_v4_rcv()函數(shù)中我們繼續(xù)往下看代碼
process:
    if (sk->sk_state == TCP_TIME_WAIT)
        goto do_time_wait;
    if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
        goto discard_and_relse;
    nf_reset(skb);
    if (sk_filter(sk, skb))
        goto discard_and_relse;
    skb->dev = NULL;
    bh_lock_sock_nested(sk);
    ret = 0;
    if (!sock_owned_by_user(sk)) {
#ifdef CONFIG_NET_DMA
        struct tcp_sock *tp = tcp_sk(sk);
        if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
            tp->ucopy.dma_chan = get_softnet_dma();
        if (tp->ucopy.dma_chan)
            ret = tcp_v4_do_rcv(sk, skb);
        else
#endif
        {
            if (!tcp_prequeue(sk, skb))
            ret = tcp_v4_do_rcv(sk, skb);
        }
    } else
        sk_add_backlog(sk, skb);
    bh_unlock_sock(sk);
    sock_put(sk);
    return ret;
no_tcp_socket:
    if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
        goto discard_it;
    if (skb->len  (th->doff  2) || tcp_checksum_complete(skb)) {
bad_packet:
        TCP_INC_STATS_BH(TCP_MIB_INERRS);
    } else {
        tcp_v4_send_reset(NULL, skb);
    }
discard_it:
    /* Discard frame. */
    kfree_skb(skb);
    return 0;
discard_and_relse:
    sock_put(sk);
    goto discard_it;
do_time_wait:
    if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
        inet_twsk_put(inet_twsk(sk));
        goto discard_it;
    }
    if (skb->len  (th->doff  2) || tcp_checksum_complete(skb)) {
        TCP_INC_STATS_BH(TCP_MIB_INERRS);
        inet_twsk_put(inet_twsk(sk));
        goto discard_it;
    }
    switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
    case TCP_TW_SYN: {
        struct sock *sk2 = inet_lookup_listener(dev_net(skb->dev),
                            &tcp_hashinfo,
                            iph->daddr, th->dest,
                            inet_iif(skb));
        if (sk2) {
            inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
            inet_twsk_put(inet_twsk(sk));
            sk = sk2;
            goto process;
        }
        /* Fall through to ACK */
    }
    case TCP_TW_ACK:
        tcp_v4_timewait_ack(sk, skb);
        break;
    case TCP_TW_RST:
        goto no_tcp_socket;
    case TCP_TW_SUCCESS:;
    }
    goto discard_it;
}
接下來(lái)要檢查服務(wù)器端的這個(gè)sock結(jié)構(gòu)是否處于TCP_TIME_WAIT狀態(tài)延時(shí)狀態(tài),如果是的話就要跳到do_time_wait標(biāo)號(hào)處等待了,我們不看這個(gè)過(guò)程了,我們也跳過(guò)對(duì)IPSEC規(guī)則的檢測(cè)函數(shù)xfrm4_policy_check(),象在第8節(jié)
http://blog.chinaunix.net/u2/64681/showart.php?id=1408613
中說(shuō)的那樣,具體的分析放在后續(xù)工作中。接下來(lái)進(jìn)入最關(guān)鍵的過(guò)程
            if (!tcp_prequeue(sk, skb))
            ret = tcp_v4_do_rcv(sk, skb);
首先是通過(guò)tcp_prequeue()將數(shù)據(jù)包先鏈入tcp_sock結(jié)構(gòu)中的預(yù)備隊(duì)列,這個(gè)函數(shù)的詳細(xì)解釋在
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxK&Number=138240&page=129&view=collapsed&sb=5&o=all
,我們進(jìn)入tcp_v4_do_rcv()函數(shù)
int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
{
    struct sock *rsk;
#ifdef CONFIG_TCP_MD5SIG
    /*
     * We really want to reject the packet as early as possible
     * if:
     * o We're expecting an MD5'd packet and this is no MD5 tcp option
     * o There is an MD5 option and we're not expecting one
     */
    if (tcp_v4_inbound_md5_hash(sk, skb))
        goto discard;
#endif
    if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
        TCP_CHECK_TIMER(sk);
        if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
            rsk = sk;
            goto reset;
        }
        TCP_CHECK_TIMER(sk);
        return 0;
    }
    if (skb->len  tcp_hdrlen(skb) || tcp_checksum_complete(skb))
        goto csum_err;
    if (sk->sk_state == TCP_LISTEN) {
        struct sock *nsk = tcp_v4_hnd_req(sk, skb);
        if (!nsk)
            goto discard;
        if (nsk != sk) {
            if (tcp_child_process(sk, nsk, skb)) {
                rsk = nsk;
                goto reset;
            }
            return 0;
        }
    }
    TCP_CHECK_TIMER(sk);
    if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) {
        rsk = sk;
        goto reset;
    }
    TCP_CHECK_TIMER(sk);
    return 0;
reset:
    tcp_v4_send_reset(rsk, skb);
discard:
    kfree_skb(skb);
    /* Be careful here. If this function gets more complicated and
     * gcc suffers from register pressure on the x86, sk (in %ebx)
     * might be destroyed here. This current version compiles correctly,
     * but you have been warned.
     */
    return 0;
csum_err:
    TCP_INC_STATS_BH(TCP_MIB_INERRS);
    goto discard;
}
上面的代碼中因?yàn)槲覀冋业降膕ock已經(jīng)是處于監(jiān)聽狀態(tài)的,所以只會(huì)執(zhí)行這段代碼
    if (sk->sk_state == TCP_LISTEN) {
        struct sock *nsk = tcp_v4_hnd_req(sk, skb);
        if (!nsk)
            goto discard;
        if (nsk != sk) {
            if (tcp_child_process(sk, nsk, skb)) {
                rsk = nsk;
                goto reset;
            }
            return 0;
        }
    }
tcp_v4_hnd_req()函數(shù)我們下一節(jié)論述,這是個(gè)很重要的函數(shù),因?yàn)槲覀兪恰暗谝淮挝帐帧保赃@個(gè)函數(shù)會(huì)再次取得我們的sock結(jié)構(gòu),如果與原來(lái)的sock不同就進(jìn)入了tcp_child_process()函數(shù)
int tcp_child_process(struct sock *parent, struct sock *child,
         struct sk_buff *skb)
{
    int ret = 0;
    int state = child->sk_state;
    if (!sock_owned_by_user(child)) {
        ret = tcp_rcv_state_process(child, skb, tcp_hdr(skb),
                     skb->len);
        /* Wakeup parent, send SIGIO */
        if (state == TCP_SYN_RECV && child->sk_state != state)
            parent->sk_data_ready(parent, 0);
    } else {
        /* Alas, it is possible again, because we do lookup
         * in main socket hash table and lock on listening
         * socket does not protect us more.
         */
        sk_add_backlog(child, skb);
    }
    bh_unlock_sock(child);
    sock_put(child);
    return ret;
}
注意sock_owned_by_user()是檢查是否正在釋放sock結(jié)構(gòu),當(dāng)然我們服務(wù)器端并沒(méi)有釋放操作,所以會(huì)執(zhí)行tcp_rcv_state_process()函數(shù),函數(shù)很長(zhǎng)但是我們只關(guān)心與我們追蹤的線索有關(guān)的過(guò)程
int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
             struct tcphdr *th, unsigned len)
{
。。。。。。
case TCP_LISTEN:
        if (th->ack)
            return 1;
        if (th->rst)
            goto discard;
        if (th->syn) {
            if (icsk->icsk_af_ops->conn_request(sk, skb)  0)
                return 1;
            /* Now we have several options: In theory there is
             * nothing else in the frame. KA9Q has an option to
             * send data with the syn, BSD accepts data with the
             * syn up to the [to be] advertised window and
             * Solaris 2.1 gives you a protocol error. For now
             * we just ignore it, that fits the spec precisely
             * and avoids incompatibilities. It would be nice in
             * future to drop through and process the data.
             *
             * Now that TTCP is starting to be used we ought to
             * queue this data.
             * But, this leaves one open to an easy denial of
             * service attack, and SYN cookies can't defend
             * against this problem. So, we drop the data
             * in the interest of security over speed unless
             * it's still in use.
             */
            kfree_skb(skb);
            return 0;
        }
。。。。。。
}
我們知道客戶端傳遞過(guò)來(lái)的是SYN包,所以會(huì)執(zhí)行icsk->icsk_af_ops->conn_request(sk, skb),這里我們?cè)诜治龇⻊?wù)器端的socket創(chuàng)建文章時(shí)
http://blog.chinaunix.net/u2/64681/showart_1360583.html
在tcp_v4_init_sock()函數(shù)中看到
icsk->icsk_af_ops = &ipv4_specific;
也就是會(huì)執(zhí)行鉤子結(jié)構(gòu)ipv4_specific中的conn_request()
struct inet_connection_sock_af_ops ipv4_specific = {
    .queue_xmit     = ip_queue_xmit,
    .send_check     = tcp_v4_send_check,
    .rebuild_header     = inet_sk_rebuild_header,
    .conn_request     = tcp_v4_conn_request,
    .syn_recv_sock     = tcp_v4_syn_recv_sock,
    .remember_stamp     = tcp_v4_remember_stamp,
    .net_header_len     = sizeof(struct iphdr),
    .setsockopt     = ip_setsockopt,
    .getsockopt     = ip_getsockopt,
    .addr2sockaddr     = inet_csk_addr2sockaddr,
    .sockaddr_len     = sizeof(struct sockaddr_in),
    .bind_conflict     = inet_csk_bind_conflict,
#ifdef CONFIG_COMPAT
    .compat_setsockopt = compat_ip_setsockopt,
    .compat_getsockopt = compat_ip_getsockopt,
#endif
};
很明顯進(jìn)入了tcp_v4_conn_request()函數(shù),時(shí)間關(guān)系,我們明天繼續(xù)追蹤這個(gè)函數(shù)


本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u2/64681/showart_1656780.html
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP