thank you very much for your reply.
I still have some problems on the listen queue and need your help.
The sys_listen() use the inet_csk_listen_start() to allocate a listen queue (in reqsk_queue_alloc(&icsk->icsk_accept_queue, nr_table_entries);). But it seems that no place use the 'request_sock' structure in the icsk->icsk_accept_queue. Instead, when the client connect request arrived, the tcp_rcv_state_process() invokes tcp_v4_conn_request(), which again allocates a new 'request_sock' structure (reqsk_alloc( &tcp_request_sock_ops);) for it and links it to the icsk->icsk_accept_queue queue. And it seems that it does not release the structure allocate before.
What is wrong? Maybe I misunderstand something somewhere.
Waiting for your reply.
thanks.
R.wen
2007/4/28, Alan Menegotto <
macnish@xxxxxxxxx>:
On 4/16/07, R. wen < rwen2012@xxxxxxxxx> wrote:
> HI, guys :
>
> The implement of the 3 way handshaking confuse me:
>
> This is what the tcp_v4_do_rcv() mainly do:
>
>
> if (sk->sk_state == TCP_LISTEN) {
> struct sock *nsk = tcp_v4_hnd_req(sk, skb);
> ...
> if (nsk != sk) {
> if (tcp_child_process(sk, nsk, skb)) {
> ...
> }
> return 0;
> }
> }
> ...
> if (tcp_rcv_state_process(sk, skb, skb-> h.th, skb->len)) {
> ...
> }
> It seems that, if the server is in the LISTEN state, it execs the line 2,
> which is tcp_v4_hnd_req(sk, skb); , That is the function really confuse me:
>
>
>
> static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
> {
> struct tcphdr *th = skb-> h.th;
> struct iphdr *iph = skb->nh.iph;
> struct sock *nsk;
> struct request_sock **prev;
The comment talk for itself
> /* Find possible connection requests. */
> struct request_sock *req = inet_csk_search_req(sk, &prev, th->source,
> iph->saddr, iph->daddr);
If found some req with same th->source, iph->saddr and iph->daddr,
check for if isn't already a established session.
> if (req)
> return tcp_check_req(sk, skb, req, prev);
> nsk = inet_lookup_established(&tcp_hashinfo,
> skb->nh.iph- >saddr,
> th->source, skb-> nh.iph->daddr,
> th->dest, inet_iif(skb));
// if is an already established, session, check if isn't a socket in
timewait state.
> if (nsk) {
// if not, lock the child socket and return
> if (nsk->sk_state != TCP_TIME_WAIT) {
> bh_lock_sock(nsk);
> return nsk;
> }
> inet_twsk_put(inet_twsk(nsk));
> return NULL;
> }
> #ifdef CONFIG_SYN_COOKIES
> if (!th->rst && !th->syn && th->ack)
> sk = cookie_v4_check(sk, skb, &(IPCB(skb)->opt));
> #endif
// else return sk
> return sk;
> }
>
> Because the server is running just now and at the LISTEN state, so there
> is nothing in the listen queue's request_sock array. So the return value of
> the Line 8 -- inet_csk_search_req() should be NULL, and then the " return
> tcp_check_req(sk, skb, req, prev);" at Line 11 should NOT be executed.
> IS that Right? Could you please explain this function for me? I am very
> grateful.
>
> R.wen
>
If you have more doubts please feel free to contact me, I worked
almost one year and a half with the tcp subsystem.
--
Best Regards
Alan Menegotto