1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #ifndef _PER_DSTORE_H
  28 #define _PER_DSTORE_H
  29 
  30 #pragma ident   "%Z%%M% %I%     %E% SMI"
  31 
  32 #ifdef  __cplusplus
  33 extern "C" {
  34 #endif
  35 
  36 /*
  37  * per_dnet.h -- DHCP-datastore database definitions.
  38  */
  39 
  40 /*
  41  * DHCP thread deferred work structure. One per deferred client thread.
  42  *
  43  * Track clients who cannot be immediately serviced due
  44  * to a lack of available client threads. Locked by thr_mtx.
  45  */
  46 typedef struct dsvc_pending {
  47         uchar_t                 pnd_cid[DN_MAX_CID_LEN];        /* cid */
  48         uchar_t                 pnd_cid_len;                    /* cid length */
  49         struct dsvc_pending     *pnd_next;                      /* next */
  50 } dsvc_pendclnt_t;
  51 
  52 /*
  53  * DHCP thread structure. One per client thread.
  54  *
  55  * Performance: create and track each client thread, using
  56  * thr_suspend/thr_resume, rather than slower thread creation
  57  * and deletion. Locked by thr_mtx.
  58  */
  59 struct clnt;
  60 typedef struct dsvc_free {
  61         thread_t                thr_tid;        /* thread id */
  62         cond_t                  thr_cv;         /* suspend/resume cv */
  63         mutex_t                 thr_mtx;        /* suspend/resume mutex */
  64         uint_t                  thr_flags;      /* suspend/resume flags */
  65         struct clnt             *thr_pcd;       /* per client data struct */
  66         struct dsvc_free        *thr_next;      /* next */
  67 } dsvc_thr_t;
  68 
  69 /*
  70  * DHCP thread structure flags
  71  */
  72 #define DHCP_THR_LIST           0x1             /* Thread is on freelist */
  73 #define DHCP_THR_EXITING        0x2             /* Thread is exiting */
  74 
  75 /*
  76  * DHCP datastore table. One per active network or dhcptab datastore.
  77  *
  78  * Timestamps are used to age the datastore structure, and any cached
  79  * datastore free or lru records managed in select_offer().
  80  * The number of threads and clients can be controlled via MAX_THREADS
  81  * and MAX_CLIENTS server parameters.
  82  *
  83  * Client and offer hashes provide fast lookup/reservation.
  84  * Per-bucket rwlocks implemented in the hash routines reduce
  85  * lock contention between clients.
  86  *
  87  * To minimize expensive datastore activity, threads synchronize to
  88  * manage cached free and lru datastore records, which have the
  89  * same lifetime as cached offers, which can be controlled via
  90  * the OFFER_CACHE_TIMEOUT server parameter.
  91  */
  92 typedef struct dnet {
  93         hash_handle     hand;           /* hash insertion handle */
  94         time_t          free_mtime;     /* macro table purge time */
  95         time_t          free_stamp;     /* D_OFFER freerec purge time */
  96         time_t          lru_mtime;      /* macro table purge time */
  97         time_t          lru_stamp;      /* D_OFFER lrurec purge time */
  98         time_t          clnt_stamp;     /* D_OFFER client purge time */
  99         uint_t          flags;          /* dnet flags */
 100         struct in_addr  net;            /* network */
 101         struct in_addr  subnet;         /* subnet mask */
 102         int             naddrs;         /* # addrs owned by server */
 103         int             nthreads;       /* number of active threads */
 104         int             nclients;       /* number of active clients */
 105         hash_tbl        *ctable;        /* per client hash table */
 106         hash_tbl        *itable;        /* per ipaddr hash table */
 107         dsvc_thr_t      *thrhead;       /* free thread list */
 108         dsvc_thr_t      *thrtail;       /* free thread list tail */
 109         dsvc_pendclnt_t *workhead;      /* head of thread work list */
 110         dsvc_pendclnt_t *worktail;      /* tail of thread work list */
 111         dn_rec_list_t   *freerec;       /* free records head */
 112         dn_rec_list_t   *lrurec;        /* lru records head */
 113         dn_rec_list_t   **lrupage;      /* lru records sort area */
 114         size_t          lrusize;
 115 
 116         dsvc_handle_t   dh;             /* datastore handle */
 117         mutex_t         pnd_mtx;        /* open/close mutex */
 118         mutex_t         free_mtx;       /* lock for free records */
 119         mutex_t         lru_mtx;        /* lock for lru records */
 120         mutex_t         lrupage_mtx;    /* lock for lru page */
 121         mutex_t         thr_mtx;        /* lock for thread work list */
 122         cond_t          thr_cv;         /* cond var (nthreads == 0) */
 123         char            network[INET_ADDRSTRLEN];       /* display buffer */
 124 } dsvc_dnet_t;
 125 
 126 /*
 127  * DHCP datastore table flags
 128  */
 129 #define DHCP_PND_CLOSING        0x1             /* Dstore is closing */
 130 #define DHCP_PND_ERROR          0x2             /* Dstore experienced error */
 131 
 132 /*
 133  * DHCP datastore table macros
 134  */
 135 #define PND_FREE_TIMEOUT(pnd, now)      ((pnd)->free_stamp < (now) || \
 136                                             (pnd)->free_mtime != reinit_time)
 137 #define PND_LRU_TIMEOUT(pnd, now)       ((pnd)->lru_stamp < (now) || \
 138                                             (pnd)->lru_mtime != reinit_time)
 139 
 140 struct interfaces;
 141 
 142 /*
 143  * DHCP client. One per active client, per network.
 144  *
 145  * Timestamps are used to age the client structure, and any cached
 146  * offer, which can be controlled via the OFFER_CACHE_TIMEOUT server
 147  * parameter, and the -t option, and SIGHUP signal.
 148  *
 149  * The original datastore record is cached, along with offer information,
 150  * for use if the datastore record is modified.
 151  *
 152  * The clnt struct may appear on the client hash table, and offer hash table,
 153  * depending on the validity of the current offer. A different dsvc_clnt_t
 154  * is used for each link, to allow independent aging of client and offer.
 155  */
 156 typedef struct clnt {
 157         hash_handle     chand;          /* hash insertion handle: client hash */
 158         hash_handle     ihand;          /* hash insertion handle: inet hash */
 159         time_t          mtime;          /* macro table offer purge time */
 160         uint_t          flags;          /* Client flags */
 161         uint_t          state;          /* Client DHCP state */
 162         struct in_addr  off_ip;         /* Offered address */
 163         struct interfaces *ifp;         /* the ifp the packet arrived on */
 164         dsvc_dnet_t     *pnd;           /* the per network datastore */
 165         PKT_LIST        *pkthead;       /* head of client packet list */
 166         PKT_LIST        *pkttail;       /* tail of client packet list */
 167         uint_t          pending;        /* # of pkts on client packet list */
 168         lease_t         lease;          /* Offered lease time */
 169         dsvc_thr_t      *clnt_thread;   /* client thread */
 170 
 171         dn_rec_list_t   *dnlp;          /* Original datastore record */
 172         mutex_t         pcd_mtx;        /* overall struct lock */
 173         mutex_t         pkt_mtx;        /* lock for PKT_LIST */
 174         cond_t          pcd_cv;         /* cond var (clnt_thread == 0) */
 175         char            cidbuf[DHCP_MAX_OPT_SIZE]; /* display buffer */
 176         uchar_t         cid[DN_MAX_CID_LEN]; /* Offered cid */
 177         uchar_t         cid_len;        /* Offered cid length */
 178 } dsvc_clnt_t;
 179 
 180 /*
 181  * Per Client flags and indices
 182  */
 183 #define DHCP_HDR_CLIENT         0x0     /* clnt dsvc_clnt_t */
 184 #define DHCP_HDR_OFFER          0x1     /* offer dsvc_clnt_t */
 185 
 186 #define DHCP_PCD_OFFER          0x1     /* Offered ip addr is valid */
 187 #define DHCP_PCD_WORK           0x2     /* Client is on deferred work list */
 188 #define DHCP_PCD_CLOSING        0x4     /* Client thread should exit */
 189 
 190 /*
 191  * Per Client macros
 192  */
 193 #define PCD_OFFER_TIMEOUT(pcd, now)     (hash_Htime(pcd->ihand) < (now) || \
 194                                                 (pcd)->mtime != reinit_time)
 195 
 196 /*
 197  * Datastore hash table dynamic data free timeout values
 198  */
 199 #define DHCP_CLIENT_THRESHOLD   90      /* Time to free inactive clients */
 200 #define DHCP_NET_THRESHOLD      900     /* Time to free inactive nets */
 201 
 202 /*
 203  * Datastore database access routines.
 204  */
 205 extern int      open_dnet(dsvc_dnet_t **, struct in_addr *, struct in_addr *);
 206 extern void     close_dnet(dsvc_dnet_t *, boolean_t);
 207 
 208 /*
 209  * Per Client hash and utility routines.
 210  */
 211 extern int open_clnt(dsvc_dnet_t *, dsvc_clnt_t **, uchar_t *, uchar_t,
 212         boolean_t);
 213 extern void close_clnt(dsvc_clnt_t *, boolean_t);
 214 extern int clnt_netcmp(dsvc_clnt_t *, dsvc_clnt_t *);
 215 extern void close_clnts(void);
 216 extern void purge_offer(dsvc_clnt_t *, boolean_t, boolean_t);
 217 
 218 #ifdef  __cplusplus
 219 }
 220 #endif
 221 
 222 #endif  /* _PER_DSTORE_H */