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
33extern "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
73typedef 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
106typedef 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
115typedef 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
125typedef 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
163typedef 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
170typedef 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