xref: /illumos-gate/usr/src/cmd/cmd-inet/usr.lib/inetd/inetd_impl.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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 _INETD_IMPL_H
28 #define	_INETD_IMPL_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 
33 /*
34  * Header file containing inetd's shared types/data structures and
35  * function declarations.
36  */
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <stdarg.h>
45 #include <rpc/rpc.h>
46 #include <assert.h>
47 #include <libscf.h>
48 #include <libinetutil.h>
49 #include <inetsvc.h>
50 #include <librestart.h>
51 #include <libuutil.h>
52 #include <wordexp.h>
53 
54 
55 /*
56  * Number of consecutive retries of a repository operation that failed due
57  * to a broken connection performed before giving up and failing.
58  */
59 #define	REP_OP_RETRIES 10
60 
61 /* retryable SMF method error */
62 #define	SMF_EXIT_ERR_OTHER 1
63 
64 /* inetd's syslog ident string */
65 #define	SYSLOG_IDENT    "inetd"
66 
67 /* Is this instance currently executing a method ? */
68 #define	INST_IN_TRANSITION(i)	((i)->next_istate != IIS_NONE)
69 
70 /* Names of properties that inetd uses to store instance state. */
71 #define	PR_NAME_NON_START_PID	"non_start_pid"
72 #define	PR_NAME_START_PIDS	"start_pids"
73 #define	PR_NAME_CUR_INT_STATE	"cur_state"
74 #define	PR_NAME_NEXT_INT_STATE	"next_state"
75 
76 /* Connection backlog applied to connection oriented services. */
77 #define	CONNECTION_BACKLOG	10
78 
79 /*
80  * Instance states used internal to svc.inetd.
81  * NOTE: The states table in cmd/cmd-inetd/inetd/inetd.c relies on the
82  * ordering of this enumeration, so take care if modifying it.
83  */
84 typedef enum {
85 	IIS_UNINITIALIZED,
86 	IIS_ONLINE,
87 	IIS_IN_ONLINE_METHOD,
88 	IIS_OFFLINE,
89 	IIS_IN_OFFLINE_METHOD,
90 	IIS_DISABLED,
91 	IIS_IN_DISABLE_METHOD,
92 	IIS_IN_REFRESH_METHOD,
93 	IIS_MAINTENANCE,
94 	IIS_OFFLINE_CONRATE,
95 	IIS_OFFLINE_BIND,
96 	IIS_OFFLINE_COPIES,
97 	IIS_DEGRADED,
98 	IIS_NONE
99 } internal_inst_state_t;
100 
101 /*
102  * inetd's instance methods.
103  * NOTE: The methods table in cmd/cmd-inetd/inetd/util.c relies on the
104  * ordering of this enumeration, so take care if modifying it.
105  */
106 typedef enum {
107 	IM_START,
108 	IM_ONLINE,
109 	IM_OFFLINE,
110 	IM_DISABLE,
111 	IM_REFRESH,
112 	NUM_METHODS,
113 	IM_NONE
114 } instance_method_t;
115 
116 /* Collection of information pertaining to a method */
117 typedef struct {
118 	char *exec_path;	/* path passed to exec() */
119 
120 	/*
121 	 * Structure returned from wordexp(3c) that contains an expansion of the
122 	 * exec property into a form suitable for exec(2).
123 	 */
124 	wordexp_t	exec_args_we;
125 
126 	/*
127 	 * Copy of the first argument of the above wordexp_t structure in the
128 	 * event that an alternate arg0 is provided, and we replace the first
129 	 * argument with the alternate arg0. This is necessary so the
130 	 * contents of the wordexp_t structure can be returned to their
131 	 * original form as returned from wordexp(3c), which is a requirement
132 	 * for calling wordfree(3c), wordexp()'s associated cleanup routine.
133 	 */
134 	const char	*wordexp_arg0_backup;
135 
136 	/* time a method can run for before being considered broken */
137 	int		timeout;
138 } method_info_t;
139 
140 typedef struct {
141 	basic_cfg_t	*basic;
142 	method_info_t	*methods[NUM_METHODS];
143 } instance_cfg_t;
144 
145 /*
146  * Structure used to construct a list of int64_t's and their associated
147  * scf values. Used to store lists of process ids, internal states, and to
148  * store the associated scf value used when writing the values back to the
149  * repository.
150  */
151 typedef struct {
152 	int64_t		val;
153 	scf_value_t	*scf_val;
154 	uu_list_node_t	link;
155 } rep_val_t;
156 
157 /* Structure containing the state and configuration of a service instance. */
158 typedef struct {
159 	char			*fmri;
160 
161 	/* fd we're going to take a connection on */
162 	int			conn_fd;
163 
164 	/* number of copies of this instance active */
165 	int64_t			copies;
166 
167 	/* connection rate counters */
168 	int64_t			conn_rate_count;
169 	time_t			conn_rate_start;
170 
171 	/* failure rate counters */
172 	int64_t			fail_rate_count;
173 	time_t			fail_rate_start;
174 	/* bind failure count */
175 	int64_t			bind_fail_count;
176 
177 	/* pids of currently running methods */
178 	uu_list_t		*non_start_pid;
179 	uu_list_t		*start_pids;
180 
181 	/* remote address, used for TCP tracing */
182 	struct sockaddr_storage	remote_addr;
183 
184 	internal_inst_state_t	cur_istate;
185 	internal_inst_state_t	next_istate;
186 
187 	/* repository compatible versions of the above 2 states */
188 	uu_list_t		*cur_istate_rep;
189 	uu_list_t		*next_istate_rep;
190 
191 	/*
192 	 * Current instance configuration resulting from its repository
193 	 * configuration.
194 	 */
195 	instance_cfg_t		*config;
196 
197 	/*
198 	 * Soon to be applied instance configuration. This configuration was
199 	 * read during a refresh when this instance was online, and the
200 	 * instance needed taking offline for this configuration to be applied.
201 	 * The instance is currently on its way offline, and this configuration
202 	 * will become the current configuration when it arrives there.
203 	 */
204 	instance_cfg_t		*new_config;
205 
206 	/* current pending conrate-offline/method timer; -1 if none pending */
207 	iu_timer_id_t		timer_id;
208 
209 	/* current pending bind retry timer; -1 if none pending */
210 	iu_timer_id_t		bind_timer_id;
211 
212 	/*
213 	 * Flags that assist in the fanout of an instance arriving in the
214 	 * offline state on-route to some other state.
215 	 */
216 	boolean_t		disable_req;
217 	boolean_t		maintenance_req;
218 	boolean_t		conn_rate_exceeded;
219 	boolean_t		bind_retries_exceeded;
220 
221 	/*
222 	 * Event waiting to be processed. RESTARTER_EVENT_TYPE_INVALID is used
223 	 * to mean no event waiting.
224 	 */
225 	restarter_event_type_t	pending_rst_event;
226 
227 	/* link to next instance in list */
228 	uu_list_node_t		link;
229 } instance_t;
230 
231 
232 /* Structure used to store information pertaining to instance method types. */
233 typedef struct {
234 	instance_method_t	method;
235 	const char		*name;
236 	internal_inst_state_t	dst_state;
237 } method_type_info_t;
238 
239 
240 extern uu_list_t *instance_list;
241 extern struct pollfd *poll_fds;
242 extern nfds_t num_pollfds;
243 extern method_type_info_t methods[];
244 extern iu_tq_t *timer_queue;
245 extern uu_list_pool_t *conn_ind_pool;
246 
247 /*
248  * util.c
249  */
250 extern void msg_init(void);
251 extern void msg_fini(void);
252 /* PRINTFLIKE1 */
253 extern void debug_msg(const char *, ...);
254 /* PRINTFLIKE1 */
255 extern void error_msg(const char *, ...);
256 /* PRINTFLIKE1 */
257 extern void warn_msg(const char *, ...);
258 extern void poll_fini(void);
259 extern boolean_t isset_pollfd(int);
260 extern void clear_pollfd(int);
261 extern int set_pollfd(int, uint16_t);
262 extern struct pollfd *find_pollfd(int);
263 extern int safe_read(int, void *, size_t);
264 extern boolean_t copies_limit_exceeded(instance_t *);
265 extern void cancel_inst_timer(instance_t *);
266 extern void cancel_bind_timer(instance_t *);
267 extern void enable_blocking(int);
268 extern void disable_blocking(int);
269 
270 /*
271  * tlx.c
272  */
273 extern rpc_info_t *create_rpc_info(const char *, const char *, const char *,
274     int, int);
275 extern void destroy_rpc_info(rpc_info_t *);
276 extern boolean_t rpc_info_equal(const rpc_info_t *, const rpc_info_t *);
277 extern int register_rpc_service(const char *, const rpc_info_t *);
278 extern void unregister_rpc_service(const char *, const rpc_info_t *);
279 extern int create_bound_endpoint(const char *, tlx_info_t *);
280 extern void close_net_fd(instance_t *, int);
281 extern int tlx_accept(const char *, tlx_info_t *, struct sockaddr_storage *);
282 extern struct t_call *dequeue_conind(uu_list_t *);
283 extern int queue_conind(uu_list_t *, struct t_call *);
284 extern void tlx_fini(void);
285 extern int tlx_init(void);
286 extern boolean_t tlx_info_equal(const tlx_info_t *, const tlx_info_t *,
287     boolean_t);
288 extern void consume_wait_data(instance_t *, int);
289 
290 /*
291  * config.c
292  */
293 extern int config_init(void);
294 extern void config_fini(void);
295 extern boolean_t socket_info_equal(const socket_info_t *, const socket_info_t *,
296     boolean_t);
297 extern boolean_t method_info_equal(const method_info_t *,
298     const method_info_t *);
299 extern struct method_context *read_method_context(const char *, const char *,
300     const char *, const char **);
301 extern void destroy_instance_cfg(instance_cfg_t *);
302 extern instance_cfg_t *read_instance_cfg(const char *);
303 extern boolean_t bind_config_equal(const basic_cfg_t *, const basic_cfg_t *);
304 extern int read_enable_merged(const char *, boolean_t *);
305 
306 /*
307  * repval.c
308  */
309 extern void repval_fini(void);
310 extern int repval_init(void);
311 extern uu_list_t *create_rep_val_list(void);
312 extern void destroy_rep_val_list(uu_list_t *);
313 extern scf_error_t store_rep_vals(uu_list_t *, const char *, const char *);
314 extern scf_error_t retrieve_rep_vals(uu_list_t *, const char *, const char *);
315 extern rep_val_t *find_rep_val(uu_list_t *, int64_t);
316 extern int set_single_rep_val(uu_list_t *, int64_t);
317 extern int64_t get_single_rep_val(uu_list_t *);
318 extern int add_rep_val(uu_list_t *, int64_t);
319 extern void remove_rep_val(uu_list_t *, int64_t);
320 extern void empty_rep_val_list(uu_list_t *);
321 extern int make_handle_bound(scf_handle_t *);
322 extern int add_remove_contract(const char *, boolean_t, ctid_t);
323 extern int iterate_repository_contracts(const char *, int);
324 
325 /*
326  * contracts.c
327  */
328 extern int contract_init(void);
329 extern void contract_fini(void);
330 void contract_postfork(void);
331 int contract_prefork(void);
332 extern int get_latest_contract(ctid_t *cid);
333 extern int adopt_contract(ctid_t, const char *);
334 extern int abandon_contract(ctid_t);
335 
336 /*
337  * inetd.c
338  */
339 extern void process_offline_inst(instance_t *);
340 extern void process_non_start_term(instance_t *, int);
341 extern void process_start_term(instance_t *);
342 extern void remove_method_ids(instance_t *, pid_t, ctid_t, instance_method_t);
343 
344 /*
345  * env.c
346  */
347 char **set_smf_env(struct method_context *, instance_t *, const char *);
348 
349 /*
350  * wait.c
351  */
352 extern int register_method(instance_t *, pid_t, ctid_t cid, instance_method_t);
353 extern int method_init(void);
354 extern void method_fini(void);
355 extern void process_terminated_methods(void);
356 extern void unregister_instance_methods(const instance_t *);
357 extern void method_preexec(void);
358 
359 #ifdef __cplusplus
360 }
361 #endif
362 
363 #endif /* _INETD_IMPL_H */
364