Home | History | Annotate | Download | only in sockfs
      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 */
    200