home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / net / request_sock.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  6.6 KB  |  262 lines

  1. /*
  2.  * NET        Generic infrastructure for Network protocols.
  3.  *
  4.  *        Definitions for request_sock 
  5.  *
  6.  * Authors:    Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  7.  *
  8.  *         From code originally in include/net/tcp.h
  9.  *
  10.  *        This program is free software; you can redistribute it and/or
  11.  *        modify it under the terms of the GNU General Public License
  12.  *        as published by the Free Software Foundation; either version
  13.  *        2 of the License, or (at your option) any later version.
  14.  */
  15. #ifndef _REQUEST_SOCK_H
  16. #define _REQUEST_SOCK_H
  17.  
  18. #include <linux/slab.h>
  19. #include <linux/spinlock.h>
  20. #include <linux/types.h>
  21.  
  22. #include <net/sock.h>
  23.  
  24. struct request_sock;
  25. struct sk_buff;
  26. struct dst_entry;
  27. struct proto;
  28.  
  29. struct request_sock_ops {
  30.     int        family;
  31.     kmem_cache_t    *slab;
  32.     int        obj_size;
  33.     int        (*rtx_syn_ack)(struct sock *sk,
  34.                        struct request_sock *req,
  35.                        struct dst_entry *dst);
  36.     void        (*send_ack)(struct sk_buff *skb,
  37.                     struct request_sock *req);
  38.     void        (*send_reset)(struct sk_buff *skb);
  39.     void        (*destructor)(struct request_sock *req);
  40. };
  41.  
  42. /* struct request_sock - mini sock to represent a connection request
  43.  */
  44. struct request_sock {
  45.     struct request_sock        *dl_next; /* Must be first member! */
  46.     u16                mss;
  47.     u8                retrans;
  48.     u8                __pad;
  49.     /* The following two fields can be easily recomputed I think -AK */
  50.     u32                window_clamp; /* window clamp at creation time */
  51.     u32                rcv_wnd;      /* rcv_wnd offered first time */
  52.     u32                ts_recent;
  53.     unsigned long            expires;
  54.     struct request_sock_ops        *rsk_ops;
  55.     struct sock            *sk;
  56. };
  57.  
  58. static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops)
  59. {
  60.     struct request_sock *req = kmem_cache_alloc(ops->slab, SLAB_ATOMIC);
  61.  
  62.     if (req != NULL)
  63.         req->rsk_ops = ops;
  64.  
  65.     return req;
  66. }
  67.  
  68. static inline void __reqsk_free(struct request_sock *req)
  69. {
  70.     kmem_cache_free(req->rsk_ops->slab, req);
  71. }
  72.  
  73. static inline void reqsk_free(struct request_sock *req)
  74. {
  75.     req->rsk_ops->destructor(req);
  76.     __reqsk_free(req);
  77. }
  78.  
  79. extern int sysctl_max_syn_backlog;
  80.  
  81. /** struct listen_sock - listen state
  82.  *
  83.  * @max_qlen_log - log_2 of maximal queued SYNs/REQUESTs
  84.  */
  85. struct listen_sock {
  86.     u8            max_qlen_log;
  87.     /* 3 bytes hole, try to use */
  88.     int            qlen;
  89.     int            qlen_young;
  90.     int            clock_hand;
  91.     u32            hash_rnd;
  92.     u32            nr_table_entries;
  93.     struct request_sock    *syn_table[0];
  94. };
  95.  
  96. /** struct request_sock_queue - queue of request_socks
  97.  *
  98.  * @rskq_accept_head - FIFO head of established children
  99.  * @rskq_accept_tail - FIFO tail of established children
  100.  * @rskq_defer_accept - User waits for some data after accept()
  101.  * @syn_wait_lock - serializer
  102.  *
  103.  * %syn_wait_lock is necessary only to avoid proc interface having to grab the main
  104.  * lock sock while browsing the listening hash (otherwise it's deadlock prone).
  105.  *
  106.  * This lock is acquired in read mode only from listening_get_next() seq_file
  107.  * op and it's acquired in write mode _only_ from code that is actively
  108.  * changing rskq_accept_head. All readers that are holding the master sock lock
  109.  * don't need to grab this lock in read mode too as rskq_accept_head. writes
  110.  * are always protected from the main sock lock.
  111.  */
  112. struct request_sock_queue {
  113.     struct request_sock    *rskq_accept_head;
  114.     struct request_sock    *rskq_accept_tail;
  115.     rwlock_t        syn_wait_lock;
  116.     u8            rskq_defer_accept;
  117.     /* 3 bytes hole, try to pack */
  118.     struct listen_sock    *listen_opt;
  119. };
  120.  
  121. extern int reqsk_queue_alloc(struct request_sock_queue *queue,
  122.                  const int nr_table_entries);
  123.  
  124. static inline struct listen_sock *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue)
  125. {
  126.     struct listen_sock *lopt;
  127.  
  128.     write_lock_bh(&queue->syn_wait_lock);
  129.     lopt = queue->listen_opt;
  130.     queue->listen_opt = NULL;
  131.     write_unlock_bh(&queue->syn_wait_lock);
  132.  
  133.     return lopt;
  134. }
  135.  
  136. static inline void __reqsk_queue_destroy(struct request_sock_queue *queue)
  137. {
  138.     kfree(reqsk_queue_yank_listen_sk(queue));
  139. }
  140.  
  141. extern void reqsk_queue_destroy(struct request_sock_queue *queue);
  142.  
  143. static inline struct request_sock *
  144.     reqsk_queue_yank_acceptq(struct request_sock_queue *queue)
  145. {
  146.     struct request_sock *req = queue->rskq_accept_head;
  147.  
  148.     queue->rskq_accept_head = NULL;
  149.     return req;
  150. }
  151.  
  152. static inline int reqsk_queue_empty(struct request_sock_queue *queue)
  153. {
  154.     return queue->rskq_accept_head == NULL;
  155. }
  156.  
  157. static inline void reqsk_queue_unlink(struct request_sock_queue *queue,
  158.                       struct request_sock *req,
  159.                       struct request_sock **prev_req)
  160. {
  161.     write_lock(&queue->syn_wait_lock);
  162.     *prev_req = req->dl_next;
  163.     write_unlock(&queue->syn_wait_lock);
  164. }
  165.  
  166. static inline void reqsk_queue_add(struct request_sock_queue *queue,
  167.                    struct request_sock *req,
  168.                    struct sock *parent,
  169.                    struct sock *child)
  170. {
  171.     req->sk = child;
  172.     sk_acceptq_added(parent);
  173.  
  174.     if (queue->rskq_accept_head == NULL)
  175.         queue->rskq_accept_head = req;
  176.     else
  177.         queue->rskq_accept_tail->dl_next = req;
  178.  
  179.     queue->rskq_accept_tail = req;
  180.     req->dl_next = NULL;
  181. }
  182.  
  183. static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue *queue)
  184. {
  185.     struct request_sock *req = queue->rskq_accept_head;
  186.  
  187.     BUG_TRAP(req != NULL);
  188.  
  189.     queue->rskq_accept_head = req->dl_next;
  190.     if (queue->rskq_accept_head == NULL)
  191.         queue->rskq_accept_tail = NULL;
  192.  
  193.     return req;
  194. }
  195.  
  196. static inline struct sock *reqsk_queue_get_child(struct request_sock_queue *queue,
  197.                          struct sock *parent)
  198. {
  199.     struct request_sock *req = reqsk_queue_remove(queue);
  200.     struct sock *child = req->sk;
  201.  
  202.     BUG_TRAP(child != NULL);
  203.  
  204.     sk_acceptq_removed(parent);
  205.     __reqsk_free(req);
  206.     return child;
  207. }
  208.  
  209. static inline int reqsk_queue_removed(struct request_sock_queue *queue,
  210.                       struct request_sock *req)
  211. {
  212.     struct listen_sock *lopt = queue->listen_opt;
  213.  
  214.     if (req->retrans == 0)
  215.         --lopt->qlen_young;
  216.  
  217.     return --lopt->qlen;
  218. }
  219.  
  220. static inline int reqsk_queue_added(struct request_sock_queue *queue)
  221. {
  222.     struct listen_sock *lopt = queue->listen_opt;
  223.     const int prev_qlen = lopt->qlen;
  224.  
  225.     lopt->qlen_young++;
  226.     lopt->qlen++;
  227.     return prev_qlen;
  228. }
  229.  
  230. static inline int reqsk_queue_len(const struct request_sock_queue *queue)
  231. {
  232.     return queue->listen_opt != NULL ? queue->listen_opt->qlen : 0;
  233. }
  234.  
  235. static inline int reqsk_queue_len_young(const struct request_sock_queue *queue)
  236. {
  237.     return queue->listen_opt->qlen_young;
  238. }
  239.  
  240. static inline int reqsk_queue_is_full(const struct request_sock_queue *queue)
  241. {
  242.     return queue->listen_opt->qlen >> queue->listen_opt->max_qlen_log;
  243. }
  244.  
  245. static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
  246.                     u32 hash, struct request_sock *req,
  247.                     unsigned long timeout)
  248. {
  249.     struct listen_sock *lopt = queue->listen_opt;
  250.  
  251.     req->expires = jiffies + timeout;
  252.     req->retrans = 0;
  253.     req->sk = NULL;
  254.     req->dl_next = lopt->syn_table[hash];
  255.  
  256.     write_lock(&queue->syn_wait_lock);
  257.     lopt->syn_table[hash] = req;
  258.     write_unlock(&queue->syn_wait_lock);
  259. }
  260.  
  261. #endif /* _REQUEST_SOCK_H */
  262.