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
>>
>>
>>
>>
>>
>
>
>
>
next prev 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).