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 (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #ifndef _SYS_SOCKFS_NL7CURI_H
  28 #define _SYS_SOCKFS_NL7CURI_H
  29 
  30 #pragma ident   "%Z%%M% %I%     %E% SMI"
  31 
  32 #ifdef  __cplusplus
  33 extern "C" {
  34 #endif
  35 
  36 #include <sys/types.h>
  37 #include <sys/atomic.h>
  38 #include <sys/cmn_err.h>
  39 #include <sys/stropts.h>
  40 #include <sys/socket.h>
  41 #include <sys/socketvar.h>
  42 
  43 #undef  PROMIF_DEBUG
  44 
  45 /*
  46  * Some usefull chararcter macros:
  47  */
  48 
  49 #ifndef tolower
  50 #define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) | 0x20 : (c))
  51 #endif
  52 
  53 #ifndef isdigit
  54 #define isdigit(c) ((c) >= '0' && (c) <= '9')
  55 #endif
  56 
  57 #ifndef isalpha
  58 #define isalpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
  59 #endif
  60 
  61 #ifndef isspace
  62 #define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || \
  63                 (c) == '\r' || (c) == '\f' || (c) == '\013')
  64 #endif
  65 
  66 /*
  67  * ref_t - reference type, ...
  68  *
  69  * Note, all struct's must contain a single ref_t, all must use
  70  * kmem_cache, all must use the REF_* macros for free.
  71  */
  72 
  73 typedef struct ref_s {
  74         uint32_t        cnt;            /* Reference count */
  75         void            (*last)(void *); /* Call-back for last ref */
  76         kmem_cache_t    *kmc;           /* Container allocator cache */
  77 } ref_t;
  78 
  79 #define REF_INIT(container, count, inactive, kmem) {                    \
  80         (container)->ref.cnt = (count);                                      \
  81         (container)->ref.last = (void (*)(void *))((inactive));              \
  82         (container)->ref.kmc = (kmem);                                       \
  83 }
  84 
  85 #define REF_HOLD(container) {                                           \
  86         atomic_add_32(&(container)->ref.cnt, 1);                 \
  87         ASSERT((container)->ref.cnt != 0);                           \
  88 }
  89 
  90 #define REF_RELE(container) {                                           \
  91         if (atomic_add_32_nv(&(container)->ref.cnt, -1) == 0) {          \
  92                 (container)->ref.last((container));                  \
  93                 kmem_cache_free((container)->ref.kmc, (container));  \
  94         }                                                               \
  95 }
  96 
  97 #define REF_COUNT(container) (container)->ref.cnt
  98 
  99 #define REF_ASSERT(container, count)                                    \
 100         ASSERT((container)->ref.cnt == (count));
 101 
 102 /*
 103  * str_t - string type, used to access a an arbitrary span of a char[].
 104  */
 105 
 106 typedef struct str_s {
 107         char    *cp;                    /* Char pointer current char */
 108         char    *ep;                    /* Char pointer past end of string */
 109 } str_t;
 110 
 111 /*
 112  * uri_*_t - URI descriptor, used to describe a cached URI object.
 113  */
 114 
 115 typedef struct uri_rd_s {
 116         size_t          sz;             /* Size of data */
 117         offset_t        off;            /* Offset into file or -1 for kmem */
 118         union {                         /* Response data */
 119                 char    *kmem;          /* Data in kmem */
 120                 vnode_t *vnode;         /* Data in vnode */
 121         } data;
 122         struct uri_rd_s *next;          /* Next response descriptor */
 123 } uri_rd_t;
 124 
 125 typedef struct uri_desc_s {
 126         struct uri_desc_s *hash;        /* Hash *next */
 127         uint64_t        hit;            /* Hit counter */
 128         clock_t         expire;         /* URI lbolt expires on (-1 = NEVER) */
 129 #ifdef notyet
 130         void            *sslctx;        /* SSL context */
 131 #endif
 132         boolean_t       nocache;        /* URI no cache */
 133         boolean_t       conditional;    /* Conditional response */
 134         uint32_t        hvalue;         /* Hashed value */
 135 
 136         mblk_t          *reqmp;         /* Request mblk_t */
 137         str_t           path;           /* Path name of response  */
 138         str_t           auth;           /* Authority for response */
 139         ssize_t         resplen;        /* Response length */
 140         ssize_t         respclen;       /* Response chunk length */
 141         char            *eoh;           /* End of header pointer */
 142         void            *scheme;        /* Scheme private state */
 143 
 144         ref_t           ref;            /* Reference stuff */
 145 
 146         size_t          count;          /* rd_t chain byte count */
 147         uri_rd_t        *tail;          /* Last response descriptor */
 148         uri_rd_t        response;       /* First response descriptor */
 149 
 150         struct sonode   *proc;          /* Socket processing this uri */
 151         kcondvar_t      waiting;        /* Socket(s) waiting for processing */
 152         kmutex_t        proclock;       /* Lock for proc and waiting */
 153 } uri_desc_t;
 154 
 155 /* Hash the (char)c to the hash accumulator (uint32_t)hv */
 156 #define CHASH(hv, c) (hv) = ((hv) << 5) + (hv) + c; (hv) &= 0x7FFFFFFF
 157 
 158 #define URI_TEMP (uri_desc_t *)-1       /* Temp (nocache) uri_t.hash pointer */
 159 
 160 #define URI_LEN_NOVALUE -1              /* Length (int) counter no value yet */
 161 #define URI_LEN_CONSUMED -2             /* Length (int) counter consumed */
 162 
 163 typedef struct uri_segmap_s {
 164         ref_t           ref;            /* Reference, one per uri_desb_t */
 165         caddr_t         base;           /* Base addr of segmap mapping */
 166         size_t          len;            /* Length of segmap mapping */
 167         vnode_t         *vp;            /* Vnode mapped */
 168 } uri_segmap_t;
 169 
 170 typedef struct uri_desb_s {
 171         frtn_t          frtn;           /* For use by esballoc() and freinds */
 172         uri_desc_t      *uri;           /* Containing URI of REF_HOLD() */
 173         uri_segmap_t    *segmap;        /* If segmap mapped else NULL */
 174 } uri_desb_t;
 175 
 176 /*
 177  * Add (and create if need be) a new uri_rd_t to a uri.
 178  *
 179  * Note, macro can block, must be called from a blockable context.
 180  */
 181 #define URI_RD_ADD(uri, rdp, size, offset) {                            \
 182         if ((uri)->tail == NULL) {                                   \
 183                 (rdp) = &(uri)->response;                                \
 184         } else {                                                        \
 185                 (rdp) = kmem_cache_alloc(nl7c_uri_rd_kmc, KM_SLEEP);    \
 186                 (uri)->tail->next = (rdp);                                \
 187         }                                                               \
 188         (rdp)->sz = size;                                            \
 189         (rdp)->off = offset;                                         \
 190         (rdp)->next = NULL;                                          \
 191         (uri)->tail = rdp;                                           \
 192         (uri)->count += size;                                                \
 193 }
 194 
 195 #ifdef  __cplusplus
 196 }
 197 #endif
 198 
 199 #endif  /* _SYS_SOCKFS_NL7CURI_H */