netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Zhikui Chen <zhikui.chen@rus.uni-stuttgart.de>
To: hadi@cyberus.ca
Cc: dccp@ietf.org, netdev@oss.sgi.com, acme@conectiva.com.br
Subject: Re: HELP for dccp implementation.
Date: Wed, 01 Sep 2004 12:23:38 +0200	[thread overview]
Message-ID: <4135A32A.4030901@rus.uni-stuttgart.de> (raw)
In-Reply-To: <1093454747.1034.85.camel@jzny.localdomain>

Hi, all

If I assign a value such as 0x ee9fbc00 to sk in dccp_rcv (before lookup 
calling), and comment lookkup calling, I get a error report from 
bh_lock_sock(sk) calling inside dccp_rcv, which error report is  
spin_is_locked on uninitialized spinlock ee9fbc00, and spin_lock 
(<NULL>:ee9fbc00) already locked by <NULL>/73.

Do you know its reason? Thanks,

Best regards,

Zhikui




i there,

>Could you please work with 
>Arnaldo Carvalho de Melo <acme@conectiva.com.br> since he is
>already working on this - this way we could have a coherent
>implementation.
>He is quiet knowledgeable on the internals of Linux and you could bring
>in the protocol expertise.
>
>cheers,
>jamal
>
>On Wed, 2004-08-25 at 12:46, Zhikui Chen wrote:
>  
>
>>Hi, dear all
>>
>>I could not assign __sk_head(head) value to sk in lookup_listen.
>>
>>I have writen the partial code for receive the request packet at server 
>>accodring to kernel TCP stuff, which is almost closed to TCP stuff.
>>
>>Anyone can tell me the reason or any hints? Thanks in advance.
>>
>>The details is following:
>>
>>The server for receiveing request packet firstly has following steps:
>>1. Initialize dccp sock,
>>2. dccp bind
>>3. get_port
>>3. hash
>>4. accpet and waiting packet
>>5. calling dccp_rcv to get packet ( I have checked dccp_rcv got the 
>>request packet).
>>6. to get sk value by call dccp_lookup
>>7 ....
>>
>>My problem is still in geting sk value, The follwing is my printing out:
>>
>>Aug 25 09:28:38 localhost kernel: DCCP: Hash tables configured 
>>(established 262144 bind 65536)
>>
>>dccp_init_sock:
>>dccp_sock_init_common:
>>allocated cctp successfully
>>allocated pkt vectors successfully
>>dccp_bind.
>>New dccp_get_port start.65536
>>New dccp_get_port start.else:start
>>db not found.
>>bind hash add:sk:ee9fbc00,node:0,snum:7000
>>New dccp_get_port start.OK. sk:ee9fbc00,node:0
>>New dccp_get_port start.65536
>>New dccp_get_port start.else:start
>>hlist_empty(&db->owners) not empty.
>>New dccp_get_port start.OK. sk:ee9fbc00,node:ee5a0444
>>__dccp_v4_hash, list:c04eb670,num:7000,c0558780
>>__dccp_v4_hash, list:c04eb670,sk:ee9fbc00
>>dccp_accept start.7000,sk->sk_family=2,sk->sk_state=1,sk:ee9fbc00
>>dccp_accept 1 ..flags=2
>>dccp_accept 2 ..
>>dccp_accept 3 ..timeo=2147483647,sk:ee9fbc00
>>wait_for_incoming_connection:
>>dccp wait for connect start!sk:ee9fbc00
>>dccp wait for connect start!..sk:ee9fbc00
>>dccp_rcv start.ee9d3580
>>dccp_rcv: sk->sk_state=0, type=0,dh->dport=22555
>>dccp_v4_lookup
>>__dccp_v4_lookup.
>>dccp_v4_lookup_connection.
>>hash 13291
>>dccp_v4_lookup_connection. head:f7619f58,node:eeaf5834,sk:ee9d3580
>>dccp_v4_lookup_connection. head:f7619f58,node:,sk:0
>>dccp_bhash_size: 65536,ntohs(dport):7000
>>first of head is not empty
>>dccp_v4_lookup_listen: head: c04eb670,c0558780,__sk_head(head):ee9fbc00
>>dccp_v4_lookup_listen:sk: 0
>>dccp_rcv: unable to find socket()
>>
>>At print out, dccp_bind did not call get_port and inet_sk(sk) is 
>>assigned a port number  which is 7000 from application.
>>
>>For printing __sk_head(head):ee9fbc00, I let sk = NULL in the 
>>dccp_v4_lookup_listen.
>>HASH_TABLE = 32 or 128 I have the same result.
>>And the source code is enclosed.
>>
>>Best regards,
>>
>>Zhikui
>>
>>------------------------------------------------------------------------
>>
>>struct dccp_hashinfo __cacheline_aligned dccp_hashinfo = {
>>	.__dccp_lhash_lock	=	RW_LOCK_UNLOCKED,
>>	.__dccp_lhash_users	=	ATOMIC_INIT(0),
>>	.__dccp_lhash_wait
>>	  = __WAIT_QUEUE_HEAD_INITIALIZER(dccp_hashinfo.__dccp_lhash_wait),
>>	.__dccp_portalloc_lock	=	SPIN_LOCK_UNLOCKED
>>};
>>
>>
>>
>>
>>struct sockaddr_dccp {
>>	struct sockaddr_in in;
>>	__u32		   service;
>>};
>>
>>static __inline__ int dccp_hashfn(__u32 laddr, __u16 lport,
>>				 __u32 faddr, __u16 fport)
>>{
>>	int h = (laddr ^ lport) ^ (faddr ^ fport);
>>	h ^= h >> 16;
>>	h ^= h >> 8;
>>	return h & (dccp_ehash_size - 1);;
>>}
>>
>>static __inline__ int dccp_sk_hashfn(struct sock *sk)
>>{
>>	struct inet_opt *inet = inet_sk(sk);
>>	__u32 laddr = inet->rcv_saddr;
>>	__u16 lport = inet->num;
>>	__u32 faddr = inet->daddr;
>>	__u16 fport = inet->dport;
>>
>>	return dccp_hashfn(laddr, lport, faddr, fport);
>>}
>>
>>kmem_cache_t *dccp_bucket_cachep;
>>
>>struct dccp_bind_bucket *dccp_bucket_create(struct dccp_bind_hashbucket *head,
>>					  unsigned short snum)
>>{
>>	struct dccp_bind_bucket *db = kmem_cache_alloc(dccp_bucket_cachep,
>>						      SLAB_ATOMIC);
>>	if (db) {
>>		db->port = snum;
>>		db->fastreuse = 0;
>>		INIT_HLIST_HEAD(&db->owners);
>>		hlist_add_head(&db->node, &head->chain);
>>	}
>>	return db;
>>}
>>
>>void dccp_bucket_destroy(struct dccp_bind_bucket *db)
>>{
>>	if (hlist_empty(&db->owners)) {
>>		__hlist_del(&db->node);
>>		kmem_cache_free(dccp_bucket_cachep, db);
>>	}
>>}
>>
>>/******************************************************************************/
>>
>>static int parse_uaddr(struct sockaddr *uaddr, int addr_len, struct sockaddr_in **iaddr, struct sockaddr_dccp **dccp_addr){
>>	if(addr_len < sizeof(struct sockaddr_in)) return -1;
>>	if(addr_len >= sizeof(struct sockaddr_dccp)){
>>		*dccp_addr = (struct sockaddr_dccp *)uaddr;
>>		*iaddr     = &((*dccp_addr)->in);
>>	}else{
>>		*dccp_addr = NULL;
>>		*iaddr     = (struct sockaddr_in *)uaddr;
>>	}
>>	return 0;
>>}
>>
>>/******************************************************************************/
>>/* refer to net/ipv4/af_inet.c:inet_bind() */
>>static int dccp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len){
>>  printk("dccp_bind.\n");
>>	struct sockaddr_in   *iaddr;
>>	struct sockaddr_dccp *dccp_addr;
>>	struct inet_opt *inet = inet_sk(sk);
>>	int		      addr_type;
>>	int		      err;
>>	unsigned short	      port;
>>
>>	if(parse_uaddr(uaddr, addr_len, &iaddr, &dccp_addr)) return -EINVAL;
>>
>>	addr_type = inet_addr_type(iaddr->sin_addr.s_addr);
>>	if(   inet->freebind == 0
>>	   && iaddr->sin_addr.s_addr != INADDR_ANY && addr_type != RTN_LOCAL
>>	   && addr_type != RTN_MULTICAST && addr_type != RTN_BROADCAST)
>>		                return -EADDRNOTAVAIL;
>>
>>	port = ntohs(iaddr->sin_port);
>>	if(port && port < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
>>		return -EACCES;
>>
>>	lock_sock(sk);
>>
>>	if(sk->sk_state != DCCP_STATE_CLOSED) ERR(-EISCONN);
>>
>>	if(inet->num) ERR(-EINVAL);
>>
>>	inet->rcv_saddr = inet->saddr = iaddr->sin_addr.s_addr;
>>	if(addr_type == RTN_MULTICAST || addr_type == RTN_BROADCAST)
>>		inet->saddr = 0;
>>
>>	if(dccp_addr) dccp_sk(sk)->service = dccp_addr->service;
>>	else          dccp_sk(sk)->service = 0;
>>/*Note if we comment sk_port->getport() function calling, we should assign a local listen port number for building a listen hash and adding hash to node.*/  
>>/*
>>	if(sk->sk_prot->get_port(sk, port) != 0){
>>		inet->saddr = inet->rcv_saddr = 0;
>>		ERR(-EADDRINUSE);
>>	}
>>*/
>>	if(inet->rcv_saddr) sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
>>	if(port)          sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
>>  inet->num = port;/*added 24.08.04, Note if we comment sk_port->getport() function calling, we should assign a local listen port number for building a listen hash and adding hash to node.*/  
>>	inet->dport = inet->daddr = 0;	
>>	sk_dst_reset(sk); 			
>>	err = 0;
>>out:
>>	release_sock(sk);       
>>	return err;
>>}
>>
>>void dccp_bind_hash(struct sock *sk, struct dccp_bind_bucket *db,
>>		   unsigned short snum)
>>{
>>	inet_sk(sk)->num = snum;
>>	sk_add_bind_node(sk, &db->owners);
>>	dccp_sk(sk)->bind_hash = db;
>>}
>>
>>static inline int dccp_bind_conflict(struct sock *sk, struct dccp_bind_bucket *db)
>>{
>>  printk("dccp_bind_conflict is called.\n");
>>  const u32 sk_rcv_saddr = dccp_v4_rcv_saddr(sk);
>>	struct sock *sk2;
>>	struct hlist_node *node;
>>	int reuse = sk->sk_reuse;
>>
>>	sk_for_each_bound(sk2, node, &db->owners) {
>>		if (sk != sk2 &&
>>		    !dccp_v6_ipv6only(sk2) &&
>>		    (!sk->sk_bound_dev_if ||
>>		     !sk2->sk_bound_dev_if ||
>>		     sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
>>			if (!reuse || !sk2->sk_reuse ||
>>			    sk2->sk_state == DCCP_STATE_LISTEN) {
>>				const u32 sk2_rcv_saddr = dccp_v4_rcv_saddr(sk2);
>>				if (!sk2_rcv_saddr || !sk_rcv_saddr ||
>>				    sk2_rcv_saddr == sk_rcv_saddr)
>>					break;
>>			}
>>		}
>>	}
>>	return node != NULL;
>>}
>>
>>/* Obtain a reference to a local port for the given sock,
>> * if snum is zero it means select any available local port.
>> */
>>static int dccp_get_port(struct sock *sk, unsigned short snum)
>>{
>>  printk("New dccp_get_port start.%d, inet_sk(sk)->num=%d\n",dccp_bhash_size,inet_sk(sk)->num);
>>  struct dccp_bind_hashbucket *head;
>>
>>  struct hlist_node *node;
>>	struct dccp_bind_bucket *db;
>>	int ret;
>>
>>  if(inet_sk(sk)->num !=snum)
>>     snum=inet_sk(sk)->num;
>>	local_bh_disable();
>>	if (!snum) {
>>		int low = sysctl_local_port_range[0];
>>		int high = sysctl_local_port_range[1];
>>		int remaining = (high - low) + 1;
>>		int rover;
>>
>>		spin_lock(&dccp_portalloc_lock);
>>		rover = dccp_port_rover;
>>		do {
>>      printk("New dccp_get_port start.rover:%d\n",rover);
>>			rover++;
>>			if (rover < low || rover > high)
>>				rover = low;
>>			head = &dccp_bhash[dccp_bhashfn(rover)];
>>			spin_lock(&head->lock);
>>			db_for_each(db, node, &head->chain)
>>				if (db->port == rover)
>>					goto next;
>>			break;
>>		next:
>>			spin_unlock(&head->lock);
>>		} while (--remaining > 0);
>>		dccp_port_rover = rover;
>>		spin_unlock(&dccp_portalloc_lock);
>>
>>		/* Exhausted local port range during search? */
>>		ret = 1;
>>		if (remaining <= 0)
>>			goto fail;
>>
>>		/* OK, here is the one we will use.  HEAD is
>>		 * non-NULL and we hold it's mutex.
>>		 */
>>    printk("New dccp_get_port start.if:OK\n");
>>		snum = rover;
>>	} else {
>>    printk("New dccp_get_port start.else:start\n");
>>		head = &dccp_bhash[dccp_bhashfn(snum)];
>>		spin_lock(&head->lock);
>>		db_for_each(db, node, &head->chain)
>>			if (db->port == snum)
>>				goto db_found;
>>	}
>>	db = NULL;
>>	goto db_not_found;
>>db_found:
>>	if (!hlist_empty(&db->owners)) {
>>    printk("hlist_empty(&db->owners) not empty.\n");
>>		if (sk->sk_reuse > 1)
>>			goto success;
>>		if (db->fastreuse > 0 &&
>>		    sk->sk_reuse && sk->sk_state != DCCP_STATE_LISTEN) {
>>			goto success;
>>		} else {
>>			ret = 1;
>>			if (dccp_bind_conflict(sk, db))
>>				goto fail_unlock;
>>		}
>>	}
>>db_not_found:
>>    printk("db not found.\n");
>>	ret = 1;
>>	if (!db && (db = dccp_bucket_create(head, snum)) == NULL)
>>		goto fail_unlock;
>>	if (hlist_empty(&db->owners)) {
>>		if (sk->sk_reuse && sk->sk_state != DCCP_STATE_LISTEN)
>>			db->fastreuse = 1;
>>		else
>>			db->fastreuse = 0;
>>	} else if (db->fastreuse &&
>>		   (!sk->sk_reuse || sk->sk_state == DCCP_STATE_LISTEN))
>>		db->fastreuse = 0;
>>success:
>>	if (!dccp_sk(sk)->bind_hash){
>>		dccp_bind_hash(sk, db, snum);
>>    printk("bind hash add:sk:%x,node:%x,snum:%d\n",sk,node,snum);
>>    }
>>	BUG_TRAP(dccp_sk(sk)->bind_hash == db);
>> 	ret = 0;
>>
>>fail_unlock:
>>	spin_unlock(&head->lock);
>>fail:
>>	local_bh_enable();
>>    printk("New dccp_get_port start.OK. sk:%x,node:%x\n",sk,node);
>>	return ret;
>>}
>>/*****************************************************************************/
>>static int wait_for_incoming_connection(struct sock *sk, long timeo)
>>{
>>    printk("wait_for_incoming_connection: \n");
>>	DECLARE_WAITQUEUE(wait, current);
>>	int 			err;
>>	struct dccp_opt *tp = dccp_sk(sk);
>>
>>	/*
>>	 * True wake-one mechanism for incoming connections: only
>>	 * one process gets woken up, not the 'whole herd'.
>>	 * Since we do not 'race & poll' for established sockets
>>	 * anymore, the common case will execute the loop only once.
>>	 *
>>	 * Subtle issue: "add_wait_queue_exclusive()" will be added
>>	 * after any current non-exclusive waiters, and we know that
>>	 * it will always _stay_ after any new non-exclusive waiters
>>	 * because all non-exclusive waiters are added at the
>>	 * beginning of the wait-queue. As such, it's ok to "drop"
>>	 * our exclusiveness temporarily when we get woken up without
>>	 * having to remove and re-insert us on the wait queue.
>>	 */
>>	add_wait_queue_exclusive(sk->sk_sleep, &wait);
>>     printk("dccp wait for connect start!sk:%x\n",sk);
>>	for (;;) {
>>		current->state = TASK_INTERRUPTIBLE;
>>		release_sock(sk);
>>     printk("dccp wait for connect start!..sk:%x\n",sk);
>>		if (tp->accept_queue == NULL){
>>			timeo = schedule_timeout(timeo);
>>		}
>>     printk("dccp wait for connect start .1!sk_state=%d, sk_family=%d\n",sk->sk_state,sk->sk_family);
>>		lock_sock(sk);
>>		err = 0;
>>		if (tp->accept_queue){
>>			break;
>>		}
>>		err = -EINVAL;
>>     printk("dccp wait for connect start .1!sk_state=%d, sk_family=%d\n",sk->sk_state,sk->sk_family);
>>		if (sk->sk_state != DCCP_STATE_LISTEN){
>>     printk("dccp wait for connect start .01!sk_state=%d\n",sk->sk_state);
>>			break;
>>		}
>>		err = sock_intr_errno(timeo);
>>     printk("dccp wait for connect start .2!\n");
>>		if (signal_pending(current)){
>>			break;
>>		}
>>		err = -EAGAIN;
>>		if (!timeo)
>>			break;
>>	}
>>     printk("dccp wait for connect end!\n");
>>	current->state = TASK_RUNNING;
>>	remove_wait_queue(sk->sk_sleep, &wait);
>>     printk("dccp wait for connect end ok err=%d\n",err);
>>	return err;
>>}
>>
>>struct sock *dccp_accept(struct sock *sk, int flags, int *err){
>>	struct dccp_opt *tp = dccp_sk(sk);
>>	int              error;
>>	struct sock          *newsk = NULL;
>>
>>	lock_sock(sk);
>>
>>   printk("dccp_accept start.%d,sk->sk_family=%d,sk->sk_state=%d,sk:%x\n",inet_sk(sk)->num,sk->sk_family,sk->sk_state,sk);
>>	/* this socket must be listening */
>>  error = -EINVAL;
>>  printk("dccp_accept 1 ..flags=%d\n",flags);
>>	if(sk->sk_state != DCCP_STATE_LISTEN)
>>    goto out;
>>  printk("dccp_accept 2 ..\n");
>>
>>	/* Find already established connection */
>>	if(!tp->accept_queue){
>>		long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
>>  printk("dccp_accept 3 ..timeo=%d,sk:%x\n",timeo,sk);
>>
>>    error = -EAGAIN;
>>    if(!timeo)
>>      goto out;
>>
>>		error = wait_for_incoming_connection(sk, timeo);
>>//		error = wait_for_connection(sk, timeo);
>>  printk("dccp_accept 4 ..\n");
>>  //sleep(1000);
>>		if(error) goto out;
>>		BUG_TRAP(tp->accept_queue);
>>	}
>>  printk("dccp_accept 5 ..\n");
>>	newsk = tp->accept_queue;
>>	tp->accept_queue = sk_next(newsk);//newsk->sk_bind_next;
>>	if(tp->accept_queue == NULL) tp->accept_queue_tail = NULL;
>>	BUG_TRAP(sk->sk_ack_backlog);
>>	sk->sk_ack_backlog -- ;	/* since we are removing one */
>>	dccp_sk(newsk)->flag_hashandle = 1;
>>#if 0
>>	/* remove from accept queue, will be referenced by socket */
>>	sock_put(newsk);		/* removed from the queue */
>>	sock_hold(newsk);
>>#endif
>>
>>	error = 0;
>>out:
>>  printk("dccp_accept 6 ..err=%d\n",err);
>>	release_sock(sk);
>>	*err = error;
>>	return newsk;
>>}
>>
>>void dccp_listen_wlock(void)
>>{
>>	write_lock(&dccp_lhash_lock);
>>
>>	if (atomic_read(&dccp_lhash_users)) {
>>		DEFINE_WAIT(wait);
>>
>>		for (;;) {
>>			prepare_to_wait_exclusive(&dccp_lhash_wait,
>>						&wait, TASK_UNINTERRUPTIBLE);
>>			if (!atomic_read(&dccp_lhash_users))
>>				break;
>>			write_unlock_bh(&dccp_lhash_lock);
>>			schedule();
>>			write_lock_bh(&dccp_lhash_lock);
>>		}
>>
>>		finish_wait(&dccp_lhash_wait, &wait);
>>	}
>>}
>>
>>static __inline__ void __dccp_v4_hash(struct sock *sk, const int listen_possible)
>>{
>>	struct hlist_head *list;
>>	rwlock_t *lock;
>>
>>	BUG_TRAP(sk_unhashed(sk));
>>	if (listen_possible && sk->sk_state == DCCP_STATE_LISTEN) {
>>		list = &dccp_listening_hash[dccp_sk_listen_hashfn(sk)];
>> 
>>    printk("__dccp_v4_hash, list:%x,num:%d,%x\n",list,inet_sk(sk)->num,&dccp_hash[inet_sk(sk)->num & (DCCP_HTABLE_SIZE - 1)]);
>>		lock = &dccp_lhash_lock;
>>		dccp_listen_wlock();
>>	} else {
>>		list = &dccp_ehash[(sk->sk_hashent = dccp_sk_hashfn(sk))].chain;
>>		lock = &dccp_ehash[sk->sk_hashent].lock;
>>		write_lock(lock);
>>	}
>>	__sk_add_node(sk, list);
>>	sock_prot_inc_use(sk->sk_prot);
>>	write_unlock(lock);
>>	if (listen_possible && sk->sk_state == DCCP_STATE_LISTEN)
>>		wake_up(&dccp_lhash_wait);
>>  printk("__dccp_v4_hash, list:%x,sk:%x\n",list,sk);
>>}
>>
>>static void dccp_v4_hash(struct sock *sk)
>>{
>>	if (sk->sk_state != DCCP_STATE_CLOSED) {
>>		local_bh_disable();
>>		__dccp_v4_hash(sk, 1);
>>		local_bh_enable();
>>	}
>>}
>>
>>void dccp_unhash(struct sock *sk)
>>{
>>	rwlock_t *lock;
>>
>>	if (sk_unhashed(sk))
>>		goto ende;
>>
>>	if (sk->sk_state == DCCP_STATE_LISTEN) {
>>		local_bh_disable();
>>		dccp_listen_wlock();
>>		lock = &dccp_lhash_lock;
>>	} else {
>>		struct dccp_ehash_bucket *head = &dccp_ehash[sk->sk_hashent];
>>		lock = &head->lock;
>>		write_lock_bh(&head->lock);
>>	}
>>
>>	if (__sk_del_node_init(sk))
>>		sock_prot_dec_use(sk->sk_prot);
>>	write_unlock_bh(lock);
>>
>> ende:
>>	if (sk->sk_state == DCCP_STATE_LISTEN)
>>		wake_up(&dccp_lhash_wait);
>>}
>>
>>/*****************************************************************************/
>>static struct sock *__dccp_v4_lookup_listen(struct hlist_head *head, u32 daddr,
>>					     unsigned short hnum, int dif)
>>{
>>	struct sock *result = NULL, *sk;
>>	struct hlist_node *node;
>>	int score, hiscore;
>>
>>  printk("__dccp_v4_lookup_listen: sk:%x,node:%x,head:%x,sk_state:%d\n",sk,node,head,sk->sk_state);
>>	hiscore=-1;
>>	sk_for_each(sk, node, head) {
>>		struct inet_opt *inet = inet_sk(sk);
>>
>>		if (inet->num == hnum && !ipv6_only_sock(sk)) {
>>			__u32 rcv_saddr = inet->rcv_saddr;
>>
>>			score = (sk->sk_family == PF_INET ? 1 : 0);
>>			if (rcv_saddr) {
>>				if (rcv_saddr != daddr)
>>					continue;
>>				score+=2;
>>			}
>>			if (sk->sk_bound_dev_if) {
>>				if (sk->sk_bound_dev_if != dif)
>>					continue;
>>				score+=2;
>>			}
>>			if (score == 5)
>>				return sk;
>>			if (score > hiscore) {
>>				hiscore = score;
>>				result = sk;
>>			}
>>		}
>>	}
>>  printk("dccp_v4_lookup_listen:sk:%x,result:%x\n",sk,result);
>>	return result;
>>}
>>
>>/* Optimize the common listener case. */
>>inline struct sock *dccp_v4_lookup_listen(u32 daddr, u16 hnum,int dif)
>>{
>>	struct sock *sk = NULL;
>>	struct hlist_head *head;
>>
>>	read_lock(&dccp_lhash_lock);
>>  printk("dccp_bhash_size: %d,ntohs(dport):%d\n",dccp_bhash_size,hnum);
>>	head = &dccp_listening_hash[dccp_lhashfn(hnum)];
>>
>>  if(head->first)
>>  printk("first of head is not empty\n");
>>
>>  printk("dccp_v4_lookup_listen: head: %x,%x,__sk_head(head):%x\n",head,&dccp_hash[hnum & (DCCP_HTABLE_SIZE - 1)],__sk_head(head));
>>	
>>	if (!hlist_empty(head)) {
>>		struct inet_opt *inet = inet_sk((sk = __sk_head(head)));
>>    printk("dccp_v4_lookup_listen:sk: %x\n",sk);
>>
>>		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)
>>			goto sherry_cache;
>>		sk = __dccp_v4_lookup_listen(head, daddr, hnum, dif);
>>	}
>>  else
>>  printk("hlist_empty(head) is empty.\n");
>>	if (sk) {
>>sherry_cache:
>>		sock_hold(sk);
>>	}
>>  printk("dccp_v4_lookup_listen:sk: %x\n",sk);
>>	read_unlock(&dccp_lhash_lock);
>>	return sk;
>>}
>>
>>
>>/*****************************************************************************/
>>
>>static inline struct sock *dccp_v4_lookup_connection(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif){
>>  printk("dccp_v4_lookup_connection.\n");
>>	struct dccp_ehash_bucket *head;
>>	DCCP_V4_ADDR_COOKIE(acookie, saddr, daddr)
>>	__u32 ports = DCCP_COMBINED_PORTS(sport, hnum);
>>	struct sock *sk;
>>	struct hlist_node *node;
>>	int hash = dccp_hashfn(daddr, hnum, saddr, sport);
>>  printk("hash %d\n",hash);
>>	head = &dccp_ehash[hash];
>>  printk("dccp_v4_lookup_connection. head:%x,node:%x,sk:%x\n",head,node,sk);
>>	read_lock(&head->lock);
>>	sk_for_each(sk, node, &head->chain) {
>>		if (DCCP_IPV4_MATCH(sk, acookie, saddr, daddr, ports, dif))
>>			goto hit; 
>>	}
>>
>>	sk_for_each(sk, node, &(head + dccp_ehash_size)->chain) {
>>		if (DCCP_IPV4_DW_MATCH(sk, acookie, saddr, daddr, ports, dif))
>>			goto hit;
>>	}
>>	sk = NULL;
>>out:
>>	read_unlock(&head->lock);
>>  printk("dccp_v4_lookup_connection. head:%x,node:,sk:%x\n",head,sk);
>>	return sk;
>>hit:
>>	sock_hold(sk);
>>	goto out;
>>}
>>
>>/*****************************************************************************/
>>
>>static inline struct sock *__dccp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport,int dif){
>>  printk("__dccp_v4_lookup.\n");
>>
>>	struct sock *sk = dccp_v4_lookup_connection(saddr, sport, daddr, ntohs(dport), dif);
>>	return sk ? : dccp_v4_lookup_listen(daddr, ntohs(dport),dif);
>>}
>>
>>inline struct sock *dccp_v4_lookup(u32 saddr, u16 sport, u32 daddr,
>>				  u16 dport, int dif)
>>{
>>  printk("dccp_v4_lookup\n");
>>  struct sock *sk;
>>
>>	local_bh_disable();
>>	sk = __dccp_v4_lookup(saddr, sport, daddr, dport, dif);
>>	local_bh_enable();
>>
>>	return sk;
>>}
>>
>>Best regards,
>>
>>Zhikui
>>
>>
>>
>>    
>>
>
>
>  
>

  parent reply	other threads:[~2004-09-01 10:23 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-08-25 16:46 HELP for dccp implementation Zhikui Chen
2004-08-25 17:25 ` jamal
2004-08-25 19:11   ` Arnaldo Carvalho de Melo
2004-09-01 10:23   ` Zhikui Chen [this message]
2004-09-01 20:37     ` David S. Miller
2004-09-02  2:48       ` Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4135A32A.4030901@rus.uni-stuttgart.de \
    --to=zhikui.chen@rus.uni-stuttgart.de \
    --cc=acme@conectiva.com.br \
    --cc=dccp@ietf.org \
    --cc=hadi@cyberus.ca \
    --cc=netdev@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).