socket.h revision 135446
1135446Strhodes/*
2135446Strhodes * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 1998-2002  Internet Software Consortium.
4135446Strhodes *
5135446Strhodes * Permission to use, copy, modify, and distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18135446Strhodes/* $Id: socket.h,v 1.54.12.4 2004/03/08 09:04:53 marka Exp $ */
19135446Strhodes
20135446Strhodes#ifndef ISC_SOCKET_H
21135446Strhodes#define ISC_SOCKET_H 1
22135446Strhodes
23135446Strhodes/*****
24135446Strhodes ***** Module Info
25135446Strhodes *****/
26135446Strhodes
27135446Strhodes/*
28135446Strhodes * Sockets
29135446Strhodes *
30135446Strhodes * Provides TCP and UDP sockets for network I/O.  The sockets are event
31135446Strhodes * sources in the task system.
32135446Strhodes *
33135446Strhodes * When I/O completes, a completion event for the socket is posted to the
34135446Strhodes * event queue of the task which requested the I/O.
35135446Strhodes *
36135446Strhodes * MP:
37135446Strhodes *	The module ensures appropriate synchronization of data structures it
38135446Strhodes *	creates and manipulates.
39135446Strhodes *
40135446Strhodes *	Clients of this module must not be holding a socket's task's lock when
41135446Strhodes *	making a call that affects that socket.  Failure to follow this rule
42135446Strhodes *	can result in deadlock.
43135446Strhodes *
44135446Strhodes *	The caller must ensure that isc_socketmgr_destroy() is called only
45135446Strhodes *	once for a given manager.
46135446Strhodes *
47135446Strhodes * Reliability:
48135446Strhodes *	No anticipated impact.
49135446Strhodes *
50135446Strhodes * Resources:
51135446Strhodes *	<TBS>
52135446Strhodes *
53135446Strhodes * Security:
54135446Strhodes *	No anticipated impact.
55135446Strhodes *
56135446Strhodes * Standards:
57135446Strhodes *	None.
58135446Strhodes */
59135446Strhodes
60135446Strhodes/***
61135446Strhodes *** Imports
62135446Strhodes ***/
63135446Strhodes
64135446Strhodes#include <isc/lang.h>
65135446Strhodes#include <isc/types.h>
66135446Strhodes#include <isc/event.h>
67135446Strhodes#include <isc/eventclass.h>
68135446Strhodes#include <isc/time.h>
69135446Strhodes#include <isc/region.h>
70135446Strhodes#include <isc/sockaddr.h>
71135446Strhodes
72135446StrhodesISC_LANG_BEGINDECLS
73135446Strhodes
74135446Strhodes/***
75135446Strhodes *** Constants
76135446Strhodes ***/
77135446Strhodes
78135446Strhodes/*
79135446Strhodes * Maximum number of buffers in a scatter/gather read/write.  The operating
80135446Strhodes * system in use must support at least this number (plus one on some.)
81135446Strhodes */
82135446Strhodes#define ISC_SOCKET_MAXSCATTERGATHER	8
83135446Strhodes
84135446Strhodes/***
85135446Strhodes *** Types
86135446Strhodes ***/
87135446Strhodes
88135446Strhodesstruct isc_socketevent {
89135446Strhodes	ISC_EVENT_COMMON(isc_socketevent_t);
90135446Strhodes	isc_result_t		result;		/* OK, EOF, whatever else */
91135446Strhodes	unsigned int		minimum;	/* minimum i/o for event */
92135446Strhodes	unsigned int		n;		/* bytes read or written */
93135446Strhodes	unsigned int		offset;		/* offset into buffer list */
94135446Strhodes	isc_region_t		region;		/* for single-buffer i/o */
95135446Strhodes	isc_bufferlist_t	bufferlist;	/* list of buffers */
96135446Strhodes	isc_sockaddr_t		address;	/* source address */
97135446Strhodes	isc_time_t		timestamp;	/* timestamp of packet recv */
98135446Strhodes	struct in6_pktinfo	pktinfo;	/* ipv6 pktinfo */
99135446Strhodes	isc_uint32_t		attributes;	/* see below */
100135446Strhodes};
101135446Strhodes
102135446Strhodestypedef struct isc_socket_newconnev isc_socket_newconnev_t;
103135446Strhodesstruct isc_socket_newconnev {
104135446Strhodes	ISC_EVENT_COMMON(isc_socket_newconnev_t);
105135446Strhodes	isc_socket_t *		newsocket;
106135446Strhodes	isc_result_t		result;		/* OK, EOF, whatever else */
107135446Strhodes	isc_sockaddr_t		address;	/* source address */
108135446Strhodes};
109135446Strhodes
110135446Strhodestypedef struct isc_socket_connev isc_socket_connev_t;
111135446Strhodesstruct isc_socket_connev {
112135446Strhodes	ISC_EVENT_COMMON(isc_socket_connev_t);
113135446Strhodes	isc_result_t		result;		/* OK, EOF, whatever else */
114135446Strhodes};
115135446Strhodes
116135446Strhodes/*
117135446Strhodes * _ATTACHED:	Internal use only.
118135446Strhodes * _TRUNC:	Packet was truncated on receive.
119135446Strhodes * _CTRUNC:	Packet control information was truncated.  This can
120135446Strhodes *		indicate that the packet is not complete, even though
121135446Strhodes *		all the data is valid.
122135446Strhodes * _TIMESTAMP:	The timestamp member is valid.
123135446Strhodes * _PKTINFO:	The pktinfo member is valid.
124135446Strhodes * _MULTICAST:	The UDP packet was received via a multicast transmission.
125135446Strhodes */
126135446Strhodes#define ISC_SOCKEVENTATTR_ATTACHED		0x80000000U /* internal */
127135446Strhodes#define ISC_SOCKEVENTATTR_TRUNC			0x00800000U /* public */
128135446Strhodes#define ISC_SOCKEVENTATTR_CTRUNC		0x00400000U /* public */
129135446Strhodes#define ISC_SOCKEVENTATTR_TIMESTAMP		0x00200000U /* public */
130135446Strhodes#define ISC_SOCKEVENTATTR_PKTINFO		0x00100000U /* public */
131135446Strhodes#define ISC_SOCKEVENTATTR_MULTICAST		0x00080000U /* public */
132135446Strhodes
133135446Strhodes#define ISC_SOCKEVENT_ANYEVENT  (0)
134135446Strhodes#define ISC_SOCKEVENT_RECVDONE	(ISC_EVENTCLASS_SOCKET + 1)
135135446Strhodes#define ISC_SOCKEVENT_SENDDONE	(ISC_EVENTCLASS_SOCKET + 2)
136135446Strhodes#define ISC_SOCKEVENT_NEWCONN	(ISC_EVENTCLASS_SOCKET + 3)
137135446Strhodes#define ISC_SOCKEVENT_CONNECT	(ISC_EVENTCLASS_SOCKET + 4)
138135446Strhodes
139135446Strhodes/*
140135446Strhodes * Internal events.
141135446Strhodes */
142135446Strhodes#define ISC_SOCKEVENT_INTR	(ISC_EVENTCLASS_SOCKET + 256)
143135446Strhodes#define ISC_SOCKEVENT_INTW	(ISC_EVENTCLASS_SOCKET + 257)
144135446Strhodes
145135446Strhodestypedef enum {
146135446Strhodes	isc_sockettype_udp = 1,
147135446Strhodes	isc_sockettype_tcp = 2
148135446Strhodes} isc_sockettype_t;
149135446Strhodes
150135446Strhodes/*
151135446Strhodes * How a socket should be shutdown in isc_socket_shutdown() calls.
152135446Strhodes */
153135446Strhodes#define ISC_SOCKSHUT_RECV	0x00000001	/* close read side */
154135446Strhodes#define ISC_SOCKSHUT_SEND	0x00000002	/* close write side */
155135446Strhodes#define ISC_SOCKSHUT_ALL	0x00000003	/* close them all */
156135446Strhodes
157135446Strhodes/*
158135446Strhodes * What I/O events to cancel in isc_socket_cancel() calls.
159135446Strhodes */
160135446Strhodes#define ISC_SOCKCANCEL_RECV	0x00000001	/* cancel recv */
161135446Strhodes#define ISC_SOCKCANCEL_SEND	0x00000002	/* cancel send */
162135446Strhodes#define ISC_SOCKCANCEL_ACCEPT	0x00000004	/* cancel accept */
163135446Strhodes#define ISC_SOCKCANCEL_CONNECT	0x00000008	/* cancel connect */
164135446Strhodes#define ISC_SOCKCANCEL_ALL	0x0000000f	/* cancel everything */
165135446Strhodes
166135446Strhodes/*
167135446Strhodes * Flags for isc_socket_send() and isc_socket_recv() calls.
168135446Strhodes */
169135446Strhodes#define ISC_SOCKFLAG_IMMEDIATE	0x00000001	/* send event only if needed */
170135446Strhodes#define ISC_SOCKFLAG_NORETRY	0x00000002	/* drop failed UDP sends */
171135446Strhodes
172135446Strhodes/***
173135446Strhodes *** Socket and Socket Manager Functions
174135446Strhodes ***
175135446Strhodes *** Note: all Ensures conditions apply only if the result is success for
176135446Strhodes *** those functions which return an isc_result.
177135446Strhodes ***/
178135446Strhodes
179135446Strhodesisc_result_t
180135446Strhodesisc_socket_create(isc_socketmgr_t *manager,
181135446Strhodes		  int pf,
182135446Strhodes		  isc_sockettype_t type,
183135446Strhodes		  isc_socket_t **socketp);
184135446Strhodes/*
185135446Strhodes * Create a new 'type' socket managed by 'manager'.
186135446Strhodes *
187135446Strhodes * Note:
188135446Strhodes *
189135446Strhodes *	'pf' is the desired protocol family, e.g. PF_INET or PF_INET6.
190135446Strhodes *
191135446Strhodes * Requires:
192135446Strhodes *
193135446Strhodes *	'manager' is a valid manager
194135446Strhodes *
195135446Strhodes *	'socketp' is a valid pointer, and *socketp == NULL
196135446Strhodes *
197135446Strhodes * Ensures:
198135446Strhodes *
199135446Strhodes *	'*socketp' is attached to the newly created socket
200135446Strhodes *
201135446Strhodes * Returns:
202135446Strhodes *
203135446Strhodes *	ISC_R_SUCCESS
204135446Strhodes *	ISC_R_NOMEMORY
205135446Strhodes *	ISC_R_NORESOURCES
206135446Strhodes *	ISC_R_UNEXPECTED
207135446Strhodes */
208135446Strhodes
209135446Strhodesvoid
210135446Strhodesisc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
211135446Strhodes		  unsigned int how);
212135446Strhodes/*
213135446Strhodes * Cancel pending I/O of the type specified by "how".
214135446Strhodes *
215135446Strhodes * Note: if "task" is NULL, then the cancel applies to all tasks using the
216135446Strhodes * socket.
217135446Strhodes *
218135446Strhodes * Requires:
219135446Strhodes *
220135446Strhodes *	"socket" is a valid socket
221135446Strhodes *
222135446Strhodes *	"task" is NULL or a valid task
223135446Strhodes *
224135446Strhodes * "how" is a bitmask describing the type of cancelation to perform.
225135446Strhodes * The type ISC_SOCKCANCEL_ALL will cancel all pending I/O on this
226135446Strhodes * socket.
227135446Strhodes *
228135446Strhodes * ISC_SOCKCANCEL_RECV:
229135446Strhodes *	Cancel pending isc_socket_recv() calls.
230135446Strhodes *
231135446Strhodes * ISC_SOCKCANCEL_SEND:
232135446Strhodes *	Cancel pending isc_socket_send() and isc_socket_sendto() calls.
233135446Strhodes *
234135446Strhodes * ISC_SOCKCANCEL_ACCEPT:
235135446Strhodes *	Cancel pending isc_socket_accept() calls.
236135446Strhodes *
237135446Strhodes * ISC_SOCKCANCEL_CONNECT:
238135446Strhodes *	Cancel pending isc_socket_connect() call.
239135446Strhodes */
240135446Strhodes
241135446Strhodesvoid
242135446Strhodesisc_socket_shutdown(isc_socket_t *sock, unsigned int how);
243135446Strhodes/*
244135446Strhodes * Shutdown 'socket' according to 'how'.
245135446Strhodes *
246135446Strhodes * Requires:
247135446Strhodes *
248135446Strhodes *	'socket' is a valid socket.
249135446Strhodes *
250135446Strhodes *	'task' is NULL or is a valid task.
251135446Strhodes *
252135446Strhodes *	If 'how' is 'ISC_SOCKSHUT_RECV' or 'ISC_SOCKSHUT_ALL' then
253135446Strhodes *
254135446Strhodes *		The read queue must be empty.
255135446Strhodes *
256135446Strhodes *		No further read requests may be made.
257135446Strhodes *
258135446Strhodes *	If 'how' is 'ISC_SOCKSHUT_SEND' or 'ISC_SOCKSHUT_ALL' then
259135446Strhodes *
260135446Strhodes *		The write queue must be empty.
261135446Strhodes *
262135446Strhodes *		No further write requests may be made.
263135446Strhodes */
264135446Strhodes
265135446Strhodesvoid
266135446Strhodesisc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp);
267135446Strhodes/*
268135446Strhodes * Attach *socketp to socket.
269135446Strhodes *
270135446Strhodes * Requires:
271135446Strhodes *
272135446Strhodes *	'socket' is a valid socket.
273135446Strhodes *
274135446Strhodes *	'socketp' points to a NULL socket.
275135446Strhodes *
276135446Strhodes * Ensures:
277135446Strhodes *
278135446Strhodes *	*socketp is attached to socket.
279135446Strhodes */
280135446Strhodes
281135446Strhodesvoid
282135446Strhodesisc_socket_detach(isc_socket_t **socketp);
283135446Strhodes/*
284135446Strhodes * Detach *socketp from its socket.
285135446Strhodes *
286135446Strhodes * Requires:
287135446Strhodes *
288135446Strhodes *	'socketp' points to a valid socket.
289135446Strhodes *
290135446Strhodes *	If '*socketp' is the last reference to the socket,
291135446Strhodes *	then:
292135446Strhodes *
293135446Strhodes *		There must be no pending I/O requests.
294135446Strhodes *
295135446Strhodes * Ensures:
296135446Strhodes *
297135446Strhodes *	*socketp is NULL.
298135446Strhodes *
299135446Strhodes *	If '*socketp' is the last reference to the socket,
300135446Strhodes *	then:
301135446Strhodes *
302135446Strhodes *		The socket will be shutdown (both reading and writing)
303135446Strhodes *		for all tasks.
304135446Strhodes *
305135446Strhodes *		All resources used by the socket have been freed
306135446Strhodes */
307135446Strhodes
308135446Strhodesisc_result_t
309135446Strhodesisc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp);
310135446Strhodes/*
311135446Strhodes * Bind 'socket' to '*addressp'.
312135446Strhodes *
313135446Strhodes * Requires:
314135446Strhodes *
315135446Strhodes *	'socket' is a valid socket
316135446Strhodes *
317135446Strhodes *	'addressp' points to a valid isc_sockaddr.
318135446Strhodes *
319135446Strhodes * Returns:
320135446Strhodes *
321135446Strhodes *	ISC_R_SUCCESS
322135446Strhodes *	ISC_R_NOPERM
323135446Strhodes *	ISC_R_ADDRNOTAVAIL
324135446Strhodes *	ISC_R_ADDRINUSE
325135446Strhodes *	ISC_R_BOUND
326135446Strhodes *	ISC_R_UNEXPECTED
327135446Strhodes */
328135446Strhodes
329135446Strhodesisc_result_t
330135446Strhodesisc_socket_filter(isc_socket_t *sock, const char *filter);
331135446Strhodes/*
332135446Strhodes * Inform the kernel that it should perform accept filtering.
333135446Strhodes * If filter is NULL the current filter will be removed.:w
334135446Strhodes */
335135446Strhodes
336135446Strhodesisc_result_t
337135446Strhodesisc_socket_listen(isc_socket_t *sock, unsigned int backlog);
338135446Strhodes/*
339135446Strhodes * Set listen mode on the socket.  After this call, the only function that
340135446Strhodes * can be used (other than attach and detach) is isc_socket_accept().
341135446Strhodes *
342135446Strhodes * Notes:
343135446Strhodes *
344135446Strhodes *	'backlog' is as in the UNIX system call listen() and may be
345135446Strhodes *	ignored by non-UNIX implementations.
346135446Strhodes *
347135446Strhodes *	If 'backlog' is zero, a reasonable system default is used, usually
348135446Strhodes *	SOMAXCONN.
349135446Strhodes *
350135446Strhodes * Requires:
351135446Strhodes *
352135446Strhodes *	'socket' is a valid, bound TCP socket.
353135446Strhodes *
354135446Strhodes * Returns:
355135446Strhodes *
356135446Strhodes *	ISC_R_SUCCESS
357135446Strhodes *	ISC_R_UNEXPECTED
358135446Strhodes */
359135446Strhodes
360135446Strhodesisc_result_t
361135446Strhodesisc_socket_accept(isc_socket_t *sock,
362135446Strhodes		  isc_task_t *task, isc_taskaction_t action, const void *arg);
363135446Strhodes/*
364135446Strhodes * Queue accept event.  When a new connection is received, the task will
365135446Strhodes * get an ISC_SOCKEVENT_NEWCONN event with the sender set to the listen
366135446Strhodes * socket.  The new socket structure is sent inside the isc_socket_newconnev_t
367135446Strhodes * event type, and is attached to the task 'task'.
368135446Strhodes *
369135446Strhodes * REQUIRES:
370135446Strhodes *	'socket' is a valid TCP socket that isc_socket_listen() was called
371135446Strhodes *	on.
372135446Strhodes *
373135446Strhodes *	'task' is a valid task
374135446Strhodes *
375135446Strhodes *	'action' is a valid action
376135446Strhodes *
377135446Strhodes * RETURNS:
378135446Strhodes *	ISC_R_SUCCESS
379135446Strhodes *	ISC_R_NOMEMORY
380135446Strhodes *	ISC_R_UNEXPECTED
381135446Strhodes */
382135446Strhodes
383135446Strhodesisc_result_t
384135446Strhodesisc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addressp,
385135446Strhodes		   isc_task_t *task, isc_taskaction_t action,
386135446Strhodes		   const void *arg);
387135446Strhodes/*
388135446Strhodes * Connect 'socket' to peer with address *saddr.  When the connection
389135446Strhodes * succeeds, or when an error occurs, a CONNECT event with action 'action'
390135446Strhodes * and arg 'arg' will be posted to the event queue for 'task'.
391135446Strhodes *
392135446Strhodes * Requires:
393135446Strhodes *
394135446Strhodes *	'socket' is a valid TCP socket
395135446Strhodes *
396135446Strhodes *	'addressp' points to a valid isc_sockaddr
397135446Strhodes *
398135446Strhodes *	'task' is a valid task
399135446Strhodes *
400135446Strhodes *	'action' is a valid action
401135446Strhodes *
402135446Strhodes * Returns:
403135446Strhodes *
404135446Strhodes *	ISC_R_SUCCESS
405135446Strhodes *	ISC_R_NOMEMORY
406135446Strhodes *	ISC_R_UNEXPECTED
407135446Strhodes *
408135446Strhodes * Posted event's result code:
409135446Strhodes *
410135446Strhodes *	ISC_R_SUCCESS
411135446Strhodes *	ISC_R_TIMEDOUT
412135446Strhodes *	ISC_R_CONNREFUSED
413135446Strhodes *	ISC_R_NETUNREACH
414135446Strhodes *	ISC_R_UNEXPECTED
415135446Strhodes */
416135446Strhodes
417135446Strhodesisc_result_t
418135446Strhodesisc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp);
419135446Strhodes/*
420135446Strhodes * Get the name of the peer connected to 'socket'.
421135446Strhodes *
422135446Strhodes * Requires:
423135446Strhodes *
424135446Strhodes *	'socket' is a valid TCP socket.
425135446Strhodes *
426135446Strhodes * Returns:
427135446Strhodes *
428135446Strhodes *	ISC_R_SUCCESS
429135446Strhodes *	ISC_R_TOOSMALL
430135446Strhodes *	ISC_R_UNEXPECTED
431135446Strhodes */
432135446Strhodes
433135446Strhodesisc_result_t
434135446Strhodesisc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp);
435135446Strhodes/*
436135446Strhodes * Get the name of 'socket'.
437135446Strhodes *
438135446Strhodes * Requires:
439135446Strhodes *
440135446Strhodes *	'socket' is a valid socket.
441135446Strhodes *
442135446Strhodes * Returns:
443135446Strhodes *
444135446Strhodes *	ISC_R_SUCCESS
445135446Strhodes *	ISC_R_TOOSMALL
446135446Strhodes *	ISC_R_UNEXPECTED
447135446Strhodes */
448135446Strhodes
449135446Strhodesisc_result_t
450135446Strhodesisc_socket_recv(isc_socket_t *sock, isc_region_t *region,
451135446Strhodes		unsigned int minimum,
452135446Strhodes		isc_task_t *task, isc_taskaction_t action, const void *arg);
453135446Strhodesisc_result_t
454135446Strhodesisc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
455135446Strhodes		 unsigned int minimum,
456135446Strhodes		 isc_task_t *task, isc_taskaction_t action, const void *arg);
457135446Strhodes
458135446Strhodesisc_result_t
459135446Strhodesisc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
460135446Strhodes		 unsigned int minimum, isc_task_t *task,
461135446Strhodes		 isc_socketevent_t *event, unsigned int flags);
462135446Strhodes
463135446Strhodes/*
464135446Strhodes * Receive from 'socket', storing the results in region.
465135446Strhodes *
466135446Strhodes * Notes:
467135446Strhodes *
468135446Strhodes *	Let 'length' refer to the length of 'region' or to the sum of all
469135446Strhodes *	available regions in the list of buffers '*buflist'.
470135446Strhodes *
471135446Strhodes *	If 'minimum' is non-zero and at least that many bytes are read,
472135446Strhodes *	the completion event will be posted to the task 'task.'  If minimum
473135446Strhodes *	is zero, the exact number of bytes requested in the region must
474135446Strhodes * 	be read for an event to be posted.  This only makes sense for TCP
475135446Strhodes *	connections, and is always set to 1 byte for UDP.
476135446Strhodes *
477135446Strhodes *	The read will complete when the desired number of bytes have been
478135446Strhodes *	read, if end-of-input occurs, or if an error occurs.  A read done
479135446Strhodes *	event with the given 'action' and 'arg' will be posted to the
480135446Strhodes *	event queue of 'task'.
481135446Strhodes *
482135446Strhodes *	The caller may not modify 'region', the buffers which are passed
483135446Strhodes *	into this function, or any data they refer to until the completion
484135446Strhodes *	event is received.
485135446Strhodes *
486135446Strhodes *	For isc_socket_recvv():
487135446Strhodes *	On successful completion, '*buflist' will be empty, and the list of
488135446Strhodes *	all buffers will be returned in the done event's 'bufferlist'
489135446Strhodes *	member.  On error return, '*buflist' will be unchanged.
490135446Strhodes *
491135446Strhodes *	For isc_socket_recv2():
492135446Strhodes *	'event' is not NULL, and the non-socket specific fields are
493135446Strhodes *	expected to be initialized.
494135446Strhodes *
495135446Strhodes *	For isc_socket_recv2():
496135446Strhodes *	The only defined value for 'flags' is ISC_SOCKFLAG_IMMEDIATE.  If
497135446Strhodes *	set and the operation completes, the return value will be
498135446Strhodes *	ISC_R_SUCCESS and the event will be filled in and not sent.  If the
499135446Strhodes *	operation does not complete, the return value will be
500135446Strhodes *	ISC_R_INPROGRESS and the event will be sent when the operation
501135446Strhodes *	completes.
502135446Strhodes *
503135446Strhodes * Requires:
504135446Strhodes *
505135446Strhodes *	'socket' is a valid, bound socket.
506135446Strhodes *
507135446Strhodes *	For isc_socket_recv():
508135446Strhodes *	'region' is a valid region
509135446Strhodes *
510135446Strhodes *	For isc_socket_recvv():
511135446Strhodes *	'buflist' is non-NULL, and '*buflist' contain at least one buffer.
512135446Strhodes *
513135446Strhodes *	'task' is a valid task
514135446Strhodes *
515135446Strhodes *	For isc_socket_recv() and isc_socket_recvv():
516135446Strhodes *	action != NULL and is a valid action
517135446Strhodes *
518135446Strhodes *	For isc_socket_recv2():
519135446Strhodes *	event != NULL
520135446Strhodes *
521135446Strhodes * Returns:
522135446Strhodes *
523135446Strhodes *	ISC_R_SUCCESS
524135446Strhodes *	ISC_R_INPROGRESS
525135446Strhodes *	ISC_R_NOMEMORY
526135446Strhodes *	ISC_R_UNEXPECTED
527135446Strhodes *
528135446Strhodes * Event results:
529135446Strhodes *
530135446Strhodes *	ISC_R_SUCCESS
531135446Strhodes *	ISC_R_UNEXPECTED
532135446Strhodes *	XXX needs other net-type errors
533135446Strhodes */
534135446Strhodes
535135446Strhodesisc_result_t
536135446Strhodesisc_socket_send(isc_socket_t *sock, isc_region_t *region,
537135446Strhodes		isc_task_t *task, isc_taskaction_t action, const void *arg);
538135446Strhodesisc_result_t
539135446Strhodesisc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
540135446Strhodes		  isc_task_t *task, isc_taskaction_t action, const void *arg,
541135446Strhodes		  isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
542135446Strhodesisc_result_t
543135446Strhodesisc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
544135446Strhodes		 isc_task_t *task, isc_taskaction_t action, const void *arg);
545135446Strhodesisc_result_t
546135446Strhodesisc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
547135446Strhodes		   isc_task_t *task, isc_taskaction_t action, const void *arg,
548135446Strhodes		   isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
549135446Strhodesisc_result_t
550135446Strhodesisc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
551135446Strhodes		   isc_task_t *task,
552135446Strhodes		   isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
553135446Strhodes		   isc_socketevent_t *event, unsigned int flags);
554135446Strhodes
555135446Strhodes/*
556135446Strhodes * Send the contents of 'region' to the socket's peer.
557135446Strhodes *
558135446Strhodes * Notes:
559135446Strhodes *
560135446Strhodes *	Shutting down the requestor's task *may* result in any
561135446Strhodes *	still pending writes being dropped or completed, depending on the
562135446Strhodes *	underlying OS implementation.
563135446Strhodes *
564135446Strhodes *	If 'action' is NULL, then no completion event will be posted.
565135446Strhodes *
566135446Strhodes *	The caller may not modify 'region', the buffers which are passed
567135446Strhodes *	into this function, or any data they refer to until the completion
568135446Strhodes *	event is received.
569135446Strhodes *
570135446Strhodes *	For isc_socket_sendv() and isc_socket_sendtov():
571135446Strhodes *	On successful completion, '*buflist' will be empty, and the list of
572135446Strhodes *	all buffers will be returned in the done event's 'bufferlist'
573135446Strhodes *	member.  On error return, '*buflist' will be unchanged.
574135446Strhodes *
575135446Strhodes *	For isc_socket_sendto2():
576135446Strhodes *	'event' is not NULL, and the non-socket specific fields are
577135446Strhodes *	expected to be initialized.
578135446Strhodes *
579135446Strhodes *	For isc_socket_sendto2():
580135446Strhodes *	The only defined values for 'flags' are ISC_SOCKFLAG_IMMEDIATE
581135446Strhodes *	and ISC_SOCKFLAG_NORETRY.
582135446Strhodes *
583135446Strhodes *	If ISC_SOCKFLAG_IMMEDIATE is set and the operation completes, the
584135446Strhodes *	return value will be ISC_R_SUCCESS and the event will be filled
585135446Strhodes *	in and not sent.  If the operation does not complete, the return
586135446Strhodes *	value will be ISC_R_INPROGRESS and the event will be sent when
587135446Strhodes *	the operation completes.
588135446Strhodes *
589135446Strhodes *	ISC_SOCKFLAG_NORETRY can only be set for UDP sockets.  If set
590135446Strhodes *	and the send operation fails due to a transient error, the send
591135446Strhodes *	will not be retried and the error will be indicated in the event.
592135446Strhodes *	Using this option along with ISC_SOCKFLAG_IMMEDIATE allows the caller
593135446Strhodes *	to specify a region that is allocated on the stack.
594135446Strhodes *
595135446Strhodes * Requires:
596135446Strhodes *
597135446Strhodes *	'socket' is a valid, bound socket.
598135446Strhodes *
599135446Strhodes *	For isc_socket_send():
600135446Strhodes *	'region' is a valid region
601135446Strhodes *
602135446Strhodes *	For isc_socket_sendv() and isc_socket_sendtov():
603135446Strhodes *	'buflist' is non-NULL, and '*buflist' contain at least one buffer.
604135446Strhodes *
605135446Strhodes *	'task' is a valid task
606135446Strhodes *
607135446Strhodes *	For isc_socket_sendv(), isc_socket_sendtov(), isc_socket_send(), and
608135446Strhodes *	isc_socket_sendto():
609135446Strhodes *	action == NULL or is a valid action
610135446Strhodes *
611135446Strhodes *	For isc_socket_sendto2():
612135446Strhodes *	event != NULL
613135446Strhodes *
614135446Strhodes * Returns:
615135446Strhodes *
616135446Strhodes *	ISC_R_SUCCESS
617135446Strhodes *	ISC_R_INPROGRESS
618135446Strhodes *	ISC_R_NOMEMORY
619135446Strhodes *	ISC_R_UNEXPECTED
620135446Strhodes *
621135446Strhodes * Event results:
622135446Strhodes *
623135446Strhodes *	ISC_R_SUCCESS
624135446Strhodes *	ISC_R_UNEXPECTED
625135446Strhodes *	XXX needs other net-type errors
626135446Strhodes */
627135446Strhodes
628135446Strhodesisc_result_t
629135446Strhodesisc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
630135446Strhodes/*
631135446Strhodes * Create a socket manager.
632135446Strhodes *
633135446Strhodes * Notes:
634135446Strhodes *
635135446Strhodes *	All memory will be allocated in memory context 'mctx'.
636135446Strhodes *
637135446Strhodes * Requires:
638135446Strhodes *
639135446Strhodes *	'mctx' is a valid memory context.
640135446Strhodes *
641135446Strhodes *	'managerp' points to a NULL isc_socketmgr_t.
642135446Strhodes *
643135446Strhodes * Ensures:
644135446Strhodes *
645135446Strhodes *	'*managerp' is a valid isc_socketmgr_t.
646135446Strhodes *
647135446Strhodes * Returns:
648135446Strhodes *
649135446Strhodes *	ISC_R_SUCCESS
650135446Strhodes *	ISC_R_NOMEMORY
651135446Strhodes *	ISC_R_UNEXPECTED
652135446Strhodes */
653135446Strhodes
654135446Strhodesvoid
655135446Strhodesisc_socketmgr_destroy(isc_socketmgr_t **managerp);
656135446Strhodes/*
657135446Strhodes * Destroy a socket manager.
658135446Strhodes *
659135446Strhodes * Notes:
660135446Strhodes *
661135446Strhodes *	This routine blocks until there are no sockets left in the manager,
662135446Strhodes *	so if the caller holds any socket references using the manager, it
663135446Strhodes *	must detach them before calling isc_socketmgr_destroy() or it will
664135446Strhodes *	block forever.
665135446Strhodes *
666135446Strhodes * Requires:
667135446Strhodes *
668135446Strhodes *	'*managerp' is a valid isc_socketmgr_t.
669135446Strhodes *
670135446Strhodes *	All sockets managed by this manager are fully detached.
671135446Strhodes *
672135446Strhodes * Ensures:
673135446Strhodes *
674135446Strhodes *	*managerp == NULL
675135446Strhodes *
676135446Strhodes *	All resources used by the manager have been freed.
677135446Strhodes */
678135446Strhodes
679135446Strhodesisc_sockettype_t
680135446Strhodesisc_socket_gettype(isc_socket_t *sock);
681135446Strhodes/*
682135446Strhodes * Returns the socket type for "sock."
683135446Strhodes *
684135446Strhodes * Requires:
685135446Strhodes *
686135446Strhodes *	"sock" is a valid socket.
687135446Strhodes */
688135446Strhodes
689135446Strhodesisc_boolean_t
690135446Strhodesisc_socket_isbound(isc_socket_t *sock);
691135446Strhodes
692135446Strhodesvoid
693135446Strhodesisc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes);
694135446Strhodes/*
695135446Strhodes * If the socket is an IPv6 socket set/clear the IPV6_IPV6ONLY socket
696135446Strhodes * option if the host OS supports this option.
697135446Strhodes *
698135446Strhodes * Requires:
699135446Strhodes *	'sock' is a valid socket.
700135446Strhodes */
701135446Strhodes
702135446StrhodesISC_LANG_ENDDECLS
703135446Strhodes
704135446Strhodes#endif /* ISC_SOCKET_H */
705