xref: /minix3/external/bsd/bind/dist/bin/tests/sock_test.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: sock_test.c,v 1.8 2014/12/10 04:37:53 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2007, 2008, 2012-2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1998-2001  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: sock_test.c,v 1.55 2008/07/23 23:27:54 marka Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek #include <config.h>
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <stdlib.h>
25*00b67f09SDavid van Moolenbroek #include <string.h>
26*00b67f09SDavid van Moolenbroek #include <unistd.h>
27*00b67f09SDavid van Moolenbroek 
28*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
29*00b67f09SDavid van Moolenbroek #include <isc/print.h>
30*00b67f09SDavid van Moolenbroek #include <isc/task.h>
31*00b67f09SDavid van Moolenbroek #include <isc/socket.h>
32*00b67f09SDavid van Moolenbroek #include <isc/timer.h>
33*00b67f09SDavid van Moolenbroek #include <isc/util.h>
34*00b67f09SDavid van Moolenbroek 
35*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
36*00b67f09SDavid van Moolenbroek isc_taskmgr_t *manager;
37*00b67f09SDavid van Moolenbroek 
38*00b67f09SDavid van Moolenbroek static void
my_shutdown(isc_task_t * task,isc_event_t * event)39*00b67f09SDavid van Moolenbroek my_shutdown(isc_task_t *task, isc_event_t *event) {
40*00b67f09SDavid van Moolenbroek 	char *name = event->ev_arg;
41*00b67f09SDavid van Moolenbroek 
42*00b67f09SDavid van Moolenbroek 	printf("shutdown %s (%p)\n", name, task);
43*00b67f09SDavid van Moolenbroek 	fflush(stdout);
44*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
45*00b67f09SDavid van Moolenbroek }
46*00b67f09SDavid van Moolenbroek 
47*00b67f09SDavid van Moolenbroek static void
my_send(isc_task_t * task,isc_event_t * event)48*00b67f09SDavid van Moolenbroek my_send(isc_task_t *task, isc_event_t *event) {
49*00b67f09SDavid van Moolenbroek 	isc_socket_t *sock;
50*00b67f09SDavid van Moolenbroek 	isc_socketevent_t *dev;
51*00b67f09SDavid van Moolenbroek 
52*00b67f09SDavid van Moolenbroek 	sock = event->ev_sender;
53*00b67f09SDavid van Moolenbroek 	dev = (isc_socketevent_t *)event;
54*00b67f09SDavid van Moolenbroek 
55*00b67f09SDavid van Moolenbroek 	printf("my_send: %s task %p\n\t(sock %p, base %p, length %d, n %d, "
56*00b67f09SDavid van Moolenbroek 	       "result %d)\n",
57*00b67f09SDavid van Moolenbroek 	       (char *)(event->ev_arg), task, sock,
58*00b67f09SDavid van Moolenbroek 	       dev->region.base, dev->region.length,
59*00b67f09SDavid van Moolenbroek 	       dev->n, dev->result);
60*00b67f09SDavid van Moolenbroek 
61*00b67f09SDavid van Moolenbroek 	if (dev->result != ISC_R_SUCCESS) {
62*00b67f09SDavid van Moolenbroek 		isc_socket_detach(&sock);
63*00b67f09SDavid van Moolenbroek 		isc_task_shutdown(task);
64*00b67f09SDavid van Moolenbroek 	}
65*00b67f09SDavid van Moolenbroek 
66*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, dev->region.base, dev->region.length);
67*00b67f09SDavid van Moolenbroek 
68*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
69*00b67f09SDavid van Moolenbroek }
70*00b67f09SDavid van Moolenbroek 
71*00b67f09SDavid van Moolenbroek static void
my_recv(isc_task_t * task,isc_event_t * event)72*00b67f09SDavid van Moolenbroek my_recv(isc_task_t *task, isc_event_t *event) {
73*00b67f09SDavid van Moolenbroek 	isc_socket_t *sock;
74*00b67f09SDavid van Moolenbroek 	isc_socketevent_t *dev;
75*00b67f09SDavid van Moolenbroek 	isc_region_t region;
76*00b67f09SDavid van Moolenbroek 	char buf[1024];
77*00b67f09SDavid van Moolenbroek 	char host[256];
78*00b67f09SDavid van Moolenbroek 
79*00b67f09SDavid van Moolenbroek 	sock = event->ev_sender;
80*00b67f09SDavid van Moolenbroek 	dev = (isc_socketevent_t *)event;
81*00b67f09SDavid van Moolenbroek 
82*00b67f09SDavid van Moolenbroek 	printf("Socket %s (sock %p, base %p, length %d, n %d, result %d)\n",
83*00b67f09SDavid van Moolenbroek 	       (char *)(event->ev_arg), sock,
84*00b67f09SDavid van Moolenbroek 	       dev->region.base, dev->region.length,
85*00b67f09SDavid van Moolenbroek 	       dev->n, dev->result);
86*00b67f09SDavid van Moolenbroek 	if (dev->address.type.sa.sa_family == AF_INET6) {
87*00b67f09SDavid van Moolenbroek 		inet_ntop(AF_INET6, &dev->address.type.sin6.sin6_addr,
88*00b67f09SDavid van Moolenbroek 			  host, sizeof(host));
89*00b67f09SDavid van Moolenbroek 		printf("\tFrom: %s port %d\n", host,
90*00b67f09SDavid van Moolenbroek 		       ntohs(dev->address.type.sin6.sin6_port));
91*00b67f09SDavid van Moolenbroek 	} else {
92*00b67f09SDavid van Moolenbroek 		inet_ntop(AF_INET, &dev->address.type.sin.sin_addr,
93*00b67f09SDavid van Moolenbroek 			  host, sizeof(host));
94*00b67f09SDavid van Moolenbroek 		printf("\tFrom: %s port %d\n", host,
95*00b67f09SDavid van Moolenbroek 		       ntohs(dev->address.type.sin.sin_port));
96*00b67f09SDavid van Moolenbroek 	}
97*00b67f09SDavid van Moolenbroek 
98*00b67f09SDavid van Moolenbroek 	if (dev->result != ISC_R_SUCCESS) {
99*00b67f09SDavid van Moolenbroek 		isc_socket_detach(&sock);
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, dev->region.base,
102*00b67f09SDavid van Moolenbroek 			    dev->region.length);
103*00b67f09SDavid van Moolenbroek 		isc_event_free(&event);
104*00b67f09SDavid van Moolenbroek 
105*00b67f09SDavid van Moolenbroek 		isc_task_shutdown(task);
106*00b67f09SDavid van Moolenbroek 		return;
107*00b67f09SDavid van Moolenbroek 	}
108*00b67f09SDavid van Moolenbroek 
109*00b67f09SDavid van Moolenbroek 	/*
110*00b67f09SDavid van Moolenbroek 	 * Echo the data back.
111*00b67f09SDavid van Moolenbroek 	 */
112*00b67f09SDavid van Moolenbroek 	if (strcmp(event->ev_arg, "so2") != 0) {
113*00b67f09SDavid van Moolenbroek 		region = dev->region;
114*00b67f09SDavid van Moolenbroek 		sprintf(buf, "\r\nReceived: %.*s\r\n\r\n",
115*00b67f09SDavid van Moolenbroek 			(int)dev->n, (char *)region.base);
116*00b67f09SDavid van Moolenbroek 		region.base = isc_mem_get(mctx, strlen(buf) + 1);
117*00b67f09SDavid van Moolenbroek 		region.length = strlen(buf) + 1;
118*00b67f09SDavid van Moolenbroek 		strcpy((char *)region.base, buf);  /* strcpy is safe */
119*00b67f09SDavid van Moolenbroek 		isc_socket_send(sock, &region, task, my_send, event->ev_arg);
120*00b67f09SDavid van Moolenbroek 	} else {
121*00b67f09SDavid van Moolenbroek 		region = dev->region;
122*00b67f09SDavid van Moolenbroek 		printf("\r\nReceived: %.*s\r\n\r\n",
123*00b67f09SDavid van Moolenbroek 		       (int)dev->n, (char *)region.base);
124*00b67f09SDavid van Moolenbroek 	}
125*00b67f09SDavid van Moolenbroek 
126*00b67f09SDavid van Moolenbroek 	isc_socket_recv(sock, &dev->region, 1, task, my_recv, event->ev_arg);
127*00b67f09SDavid van Moolenbroek 
128*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
129*00b67f09SDavid van Moolenbroek }
130*00b67f09SDavid van Moolenbroek 
131*00b67f09SDavid van Moolenbroek static void
my_http_get(isc_task_t * task,isc_event_t * event)132*00b67f09SDavid van Moolenbroek my_http_get(isc_task_t *task, isc_event_t *event) {
133*00b67f09SDavid van Moolenbroek 	isc_socket_t *sock;
134*00b67f09SDavid van Moolenbroek 	isc_socketevent_t *dev;
135*00b67f09SDavid van Moolenbroek 
136*00b67f09SDavid van Moolenbroek 	sock = event->ev_sender;
137*00b67f09SDavid van Moolenbroek 	dev = (isc_socketevent_t *)event;
138*00b67f09SDavid van Moolenbroek 
139*00b67f09SDavid van Moolenbroek 	printf("my_http_get: %s task %p\n\t(sock %p, base %p, length %d, "
140*00b67f09SDavid van Moolenbroek 	       "n %d, result %d)\n",
141*00b67f09SDavid van Moolenbroek 	       (char *)(event->ev_arg), task, sock,
142*00b67f09SDavid van Moolenbroek 	       dev->region.base, dev->region.length,
143*00b67f09SDavid van Moolenbroek 	       dev->n, dev->result);
144*00b67f09SDavid van Moolenbroek 
145*00b67f09SDavid van Moolenbroek 	if (dev->result != ISC_R_SUCCESS) {
146*00b67f09SDavid van Moolenbroek 		isc_socket_detach(&sock);
147*00b67f09SDavid van Moolenbroek 		isc_task_shutdown(task);
148*00b67f09SDavid van Moolenbroek 		isc_event_free(&event);
149*00b67f09SDavid van Moolenbroek 		return;
150*00b67f09SDavid van Moolenbroek 	}
151*00b67f09SDavid van Moolenbroek 
152*00b67f09SDavid van Moolenbroek 	isc_socket_recv(sock, &dev->region, 1, task, my_recv, event->ev_arg);
153*00b67f09SDavid van Moolenbroek 
154*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
155*00b67f09SDavid van Moolenbroek }
156*00b67f09SDavid van Moolenbroek 
157*00b67f09SDavid van Moolenbroek static void
my_connect(isc_task_t * task,isc_event_t * event)158*00b67f09SDavid van Moolenbroek my_connect(isc_task_t *task, isc_event_t *event) {
159*00b67f09SDavid van Moolenbroek 	isc_socket_t *sock;
160*00b67f09SDavid van Moolenbroek 	isc_socket_connev_t *dev;
161*00b67f09SDavid van Moolenbroek 	isc_region_t region;
162*00b67f09SDavid van Moolenbroek 	char buf[1024];
163*00b67f09SDavid van Moolenbroek 
164*00b67f09SDavid van Moolenbroek 	sock = event->ev_sender;
165*00b67f09SDavid van Moolenbroek 	dev = (isc_socket_connev_t *)event;
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek 	printf("%s: Connection result:  %d\n", (char *)(event->ev_arg),
168*00b67f09SDavid van Moolenbroek 	       dev->result);
169*00b67f09SDavid van Moolenbroek 
170*00b67f09SDavid van Moolenbroek 	if (dev->result != ISC_R_SUCCESS) {
171*00b67f09SDavid van Moolenbroek 		isc_socket_detach(&sock);
172*00b67f09SDavid van Moolenbroek 		isc_event_free(&event);
173*00b67f09SDavid van Moolenbroek 		isc_task_shutdown(task);
174*00b67f09SDavid van Moolenbroek 		return;
175*00b67f09SDavid van Moolenbroek 	}
176*00b67f09SDavid van Moolenbroek 
177*00b67f09SDavid van Moolenbroek 	/*
178*00b67f09SDavid van Moolenbroek 	 * Send a GET string, and set up to receive (and just display)
179*00b67f09SDavid van Moolenbroek 	 * the result.
180*00b67f09SDavid van Moolenbroek 	 */
181*00b67f09SDavid van Moolenbroek 	strcpy(buf, "GET / HTTP/1.1\r\nHost: www.flame.org\r\n"
182*00b67f09SDavid van Moolenbroek 	       "Connection: Close\r\n\r\n");
183*00b67f09SDavid van Moolenbroek 	region.base = isc_mem_get(mctx, strlen(buf) + 1);
184*00b67f09SDavid van Moolenbroek 	region.length = strlen(buf) + 1;
185*00b67f09SDavid van Moolenbroek 	strcpy((char *)region.base, buf);  /* This strcpy is safe. */
186*00b67f09SDavid van Moolenbroek 
187*00b67f09SDavid van Moolenbroek 	isc_socket_send(sock, &region, task, my_http_get, event->ev_arg);
188*00b67f09SDavid van Moolenbroek 
189*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
190*00b67f09SDavid van Moolenbroek }
191*00b67f09SDavid van Moolenbroek 
192*00b67f09SDavid van Moolenbroek static void
my_listen(isc_task_t * task,isc_event_t * event)193*00b67f09SDavid van Moolenbroek my_listen(isc_task_t *task, isc_event_t *event) {
194*00b67f09SDavid van Moolenbroek 	char *name = event->ev_arg;
195*00b67f09SDavid van Moolenbroek 	isc_socket_newconnev_t *dev;
196*00b67f09SDavid van Moolenbroek 	isc_region_t region;
197*00b67f09SDavid van Moolenbroek 	isc_socket_t *oldsock;
198*00b67f09SDavid van Moolenbroek 	isc_task_t *newtask;
199*00b67f09SDavid van Moolenbroek 
200*00b67f09SDavid van Moolenbroek 	dev = (isc_socket_newconnev_t *)event;
201*00b67f09SDavid van Moolenbroek 
202*00b67f09SDavid van Moolenbroek 	printf("newcon %s (task %p, oldsock %p, newsock %p, result %d)\n",
203*00b67f09SDavid van Moolenbroek 	       name, task, event->ev_sender, dev->newsocket, dev->result);
204*00b67f09SDavid van Moolenbroek 	fflush(stdout);
205*00b67f09SDavid van Moolenbroek 
206*00b67f09SDavid van Moolenbroek 	if (dev->result == ISC_R_SUCCESS) {
207*00b67f09SDavid van Moolenbroek 		/*
208*00b67f09SDavid van Moolenbroek 		 * Queue another listen on this socket.
209*00b67f09SDavid van Moolenbroek 		 */
210*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(isc_socket_accept(event->ev_sender, task,
211*00b67f09SDavid van Moolenbroek 						my_listen, event->ev_arg)
212*00b67f09SDavid van Moolenbroek 			      == ISC_R_SUCCESS);
213*00b67f09SDavid van Moolenbroek 
214*00b67f09SDavid van Moolenbroek 		region.base = isc_mem_get(mctx, 20);
215*00b67f09SDavid van Moolenbroek 		region.length = 20;
216*00b67f09SDavid van Moolenbroek 
217*00b67f09SDavid van Moolenbroek 		/*
218*00b67f09SDavid van Moolenbroek 		 * Create a new task for this socket, and queue up a
219*00b67f09SDavid van Moolenbroek 		 * recv on it.
220*00b67f09SDavid van Moolenbroek 		 */
221*00b67f09SDavid van Moolenbroek 		newtask = NULL;
222*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(isc_task_create(manager, 0, &newtask)
223*00b67f09SDavid van Moolenbroek 			      == ISC_R_SUCCESS);
224*00b67f09SDavid van Moolenbroek 		isc_socket_recv(dev->newsocket, &region, 1,
225*00b67f09SDavid van Moolenbroek 				newtask, my_recv, event->ev_arg);
226*00b67f09SDavid van Moolenbroek 		isc_task_detach(&newtask);
227*00b67f09SDavid van Moolenbroek 	} else {
228*00b67f09SDavid van Moolenbroek 		printf("detaching from socket %p\n", event->ev_sender);
229*00b67f09SDavid van Moolenbroek 		oldsock = event->ev_sender;
230*00b67f09SDavid van Moolenbroek 
231*00b67f09SDavid van Moolenbroek 		isc_socket_detach(&oldsock);
232*00b67f09SDavid van Moolenbroek 
233*00b67f09SDavid van Moolenbroek 		isc_event_free(&event);
234*00b67f09SDavid van Moolenbroek 		isc_task_shutdown(task);
235*00b67f09SDavid van Moolenbroek 		return;
236*00b67f09SDavid van Moolenbroek 	}
237*00b67f09SDavid van Moolenbroek 
238*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
239*00b67f09SDavid van Moolenbroek }
240*00b67f09SDavid van Moolenbroek 
241*00b67f09SDavid van Moolenbroek static void
timeout(isc_task_t * task,isc_event_t * event)242*00b67f09SDavid van Moolenbroek timeout(isc_task_t *task, isc_event_t *event) {
243*00b67f09SDavid van Moolenbroek 	isc_socket_t *sock = event->ev_arg;
244*00b67f09SDavid van Moolenbroek 
245*00b67f09SDavid van Moolenbroek 	printf("Timeout, canceling IO on socket %p (task %p)\n", sock, task);
246*00b67f09SDavid van Moolenbroek 
247*00b67f09SDavid van Moolenbroek 	isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_ALL);
248*00b67f09SDavid van Moolenbroek 	isc_timer_detach((isc_timer_t **)&event->ev_sender);
249*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
250*00b67f09SDavid van Moolenbroek }
251*00b67f09SDavid van Moolenbroek 
252*00b67f09SDavid van Moolenbroek static char one[] = "1";
253*00b67f09SDavid van Moolenbroek static char two[] = "2";
254*00b67f09SDavid van Moolenbroek static char xso1[] = "so1";
255*00b67f09SDavid van Moolenbroek static char xso2[] = "so2";
256*00b67f09SDavid van Moolenbroek 
257*00b67f09SDavid van Moolenbroek int
main(int argc,char * argv[])258*00b67f09SDavid van Moolenbroek main(int argc, char *argv[]) {
259*00b67f09SDavid van Moolenbroek 	isc_task_t *t1, *t2;
260*00b67f09SDavid van Moolenbroek 	isc_timermgr_t *timgr;
261*00b67f09SDavid van Moolenbroek 	isc_time_t expires;
262*00b67f09SDavid van Moolenbroek 	isc_interval_t interval;
263*00b67f09SDavid van Moolenbroek 	isc_timer_t *ti1;
264*00b67f09SDavid van Moolenbroek 	unsigned int workers;
265*00b67f09SDavid van Moolenbroek 	isc_socketmgr_t *socketmgr;
266*00b67f09SDavid van Moolenbroek 	isc_socket_t *so1, *so2;
267*00b67f09SDavid van Moolenbroek 	isc_sockaddr_t sockaddr;
268*00b67f09SDavid van Moolenbroek 	struct in_addr ina;
269*00b67f09SDavid van Moolenbroek 	struct in6_addr in6a;
270*00b67f09SDavid van Moolenbroek 	isc_result_t result;
271*00b67f09SDavid van Moolenbroek 	int pf;
272*00b67f09SDavid van Moolenbroek 
273*00b67f09SDavid van Moolenbroek 	if (argc > 1) {
274*00b67f09SDavid van Moolenbroek 		workers = atoi(argv[1]);
275*00b67f09SDavid van Moolenbroek 		if (workers < 1)
276*00b67f09SDavid van Moolenbroek 			workers = 1;
277*00b67f09SDavid van Moolenbroek 		if (workers > 8192)
278*00b67f09SDavid van Moolenbroek 			workers = 8192;
279*00b67f09SDavid van Moolenbroek 	} else
280*00b67f09SDavid van Moolenbroek 		workers = 2;
281*00b67f09SDavid van Moolenbroek 	printf("%d workers\n", workers);
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek 	if (isc_net_probeipv6() == ISC_R_SUCCESS)
284*00b67f09SDavid van Moolenbroek 		pf = PF_INET6;
285*00b67f09SDavid van Moolenbroek 	else
286*00b67f09SDavid van Moolenbroek 		pf = PF_INET;
287*00b67f09SDavid van Moolenbroek 
288*00b67f09SDavid van Moolenbroek 	/*
289*00b67f09SDavid van Moolenbroek 	 * EVERYTHING needs a memory context.
290*00b67f09SDavid van Moolenbroek 	 */
291*00b67f09SDavid van Moolenbroek 	mctx = NULL;
292*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
293*00b67f09SDavid van Moolenbroek 
294*00b67f09SDavid van Moolenbroek 	/*
295*00b67f09SDavid van Moolenbroek 	 * The task manager is independent (other than memory context)
296*00b67f09SDavid van Moolenbroek 	 */
297*00b67f09SDavid van Moolenbroek 	manager = NULL;
298*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) ==
299*00b67f09SDavid van Moolenbroek 		      ISC_R_SUCCESS);
300*00b67f09SDavid van Moolenbroek 
301*00b67f09SDavid van Moolenbroek 	/*
302*00b67f09SDavid van Moolenbroek 	 * Timer manager depends only on the memory context as well.
303*00b67f09SDavid van Moolenbroek 	 */
304*00b67f09SDavid van Moolenbroek 	timgr = NULL;
305*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_timermgr_create(mctx, &timgr) == ISC_R_SUCCESS);
306*00b67f09SDavid van Moolenbroek 
307*00b67f09SDavid van Moolenbroek 	t1 = NULL;
308*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_task_create(manager, 0, &t1) == ISC_R_SUCCESS);
309*00b67f09SDavid van Moolenbroek 	t2 = NULL;
310*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_task_create(manager, 0, &t2) == ISC_R_SUCCESS);
311*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_task_onshutdown(t1, my_shutdown, one) ==
312*00b67f09SDavid van Moolenbroek 		      ISC_R_SUCCESS);
313*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_task_onshutdown(t2, my_shutdown, two) ==
314*00b67f09SDavid van Moolenbroek 		      ISC_R_SUCCESS);
315*00b67f09SDavid van Moolenbroek 
316*00b67f09SDavid van Moolenbroek 	printf("task 1 = %p\n", t1);
317*00b67f09SDavid van Moolenbroek 	printf("task 2 = %p\n", t2);
318*00b67f09SDavid van Moolenbroek 
319*00b67f09SDavid van Moolenbroek 	socketmgr = NULL;
320*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);
321*00b67f09SDavid van Moolenbroek 
322*00b67f09SDavid van Moolenbroek 	/*
323*00b67f09SDavid van Moolenbroek 	 * Open up a listener socket.
324*00b67f09SDavid van Moolenbroek 	 */
325*00b67f09SDavid van Moolenbroek 	so1 = NULL;
326*00b67f09SDavid van Moolenbroek 
327*00b67f09SDavid van Moolenbroek 	if (pf == PF_INET6) {
328*00b67f09SDavid van Moolenbroek 		in6a = in6addr_any;
329*00b67f09SDavid van Moolenbroek 		isc_sockaddr_fromin6(&sockaddr, &in6a, 5544);
330*00b67f09SDavid van Moolenbroek 	} else {
331*00b67f09SDavid van Moolenbroek 		ina.s_addr = INADDR_ANY;
332*00b67f09SDavid van Moolenbroek 		isc_sockaddr_fromin(&sockaddr, &ina, 5544);
333*00b67f09SDavid van Moolenbroek 	}
334*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_socket_create(socketmgr, pf, isc_sockettype_tcp,
335*00b67f09SDavid van Moolenbroek 					&so1) == ISC_R_SUCCESS);
336*00b67f09SDavid van Moolenbroek 	result = isc_socket_bind(so1, &sockaddr, ISC_SOCKET_REUSEADDRESS);
337*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
338*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_socket_listen(so1, 0) == ISC_R_SUCCESS);
339*00b67f09SDavid van Moolenbroek 
340*00b67f09SDavid van Moolenbroek 	/*
341*00b67f09SDavid van Moolenbroek 	 * Queue up the first accept event.
342*00b67f09SDavid van Moolenbroek 	 */
343*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_socket_accept(so1, t1, my_listen, xso1)
344*00b67f09SDavid van Moolenbroek 		      == ISC_R_SUCCESS);
345*00b67f09SDavid van Moolenbroek 	isc_time_settoepoch(&expires);
346*00b67f09SDavid van Moolenbroek 	isc_interval_set(&interval, 10, 0);
347*00b67f09SDavid van Moolenbroek 	ti1 = NULL;
348*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_once, &expires,
349*00b67f09SDavid van Moolenbroek 				       &interval, t1, timeout, so1, &ti1) ==
350*00b67f09SDavid van Moolenbroek 		      ISC_R_SUCCESS);
351*00b67f09SDavid van Moolenbroek 
352*00b67f09SDavid van Moolenbroek 	/*
353*00b67f09SDavid van Moolenbroek 	 * Open up a socket that will connect to www.flame.org, port 80.
354*00b67f09SDavid van Moolenbroek 	 * Why not.  :)
355*00b67f09SDavid van Moolenbroek 	 */
356*00b67f09SDavid van Moolenbroek 	so2 = NULL;
357*00b67f09SDavid van Moolenbroek 	ina.s_addr = inet_addr("204.152.184.97");
358*00b67f09SDavid van Moolenbroek 	if (0 && pf == PF_INET6)
359*00b67f09SDavid van Moolenbroek 		isc_sockaddr_v6fromin(&sockaddr, &ina, 80);
360*00b67f09SDavid van Moolenbroek 	else
361*00b67f09SDavid van Moolenbroek 		isc_sockaddr_fromin(&sockaddr, &ina, 80);
362*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_socket_create(socketmgr, isc_sockaddr_pf(&sockaddr),
363*00b67f09SDavid van Moolenbroek 					isc_sockettype_tcp,
364*00b67f09SDavid van Moolenbroek 					&so2) == ISC_R_SUCCESS);
365*00b67f09SDavid van Moolenbroek 
366*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_socket_connect(so2, &sockaddr, t2,
367*00b67f09SDavid van Moolenbroek 					 my_connect, xso2) == ISC_R_SUCCESS);
368*00b67f09SDavid van Moolenbroek 
369*00b67f09SDavid van Moolenbroek 	/*
370*00b67f09SDavid van Moolenbroek 	 * Detaching these is safe, since the socket will attach to the
371*00b67f09SDavid van Moolenbroek 	 * task for any outstanding requests.
372*00b67f09SDavid van Moolenbroek 	 */
373*00b67f09SDavid van Moolenbroek 	isc_task_detach(&t1);
374*00b67f09SDavid van Moolenbroek 	isc_task_detach(&t2);
375*00b67f09SDavid van Moolenbroek 
376*00b67f09SDavid van Moolenbroek 	/*
377*00b67f09SDavid van Moolenbroek 	 * Wait a short while.
378*00b67f09SDavid van Moolenbroek 	 */
379*00b67f09SDavid van Moolenbroek #ifndef WIN32
380*00b67f09SDavid van Moolenbroek 	sleep(10);
381*00b67f09SDavid van Moolenbroek #else
382*00b67f09SDavid van Moolenbroek 	Sleep(10000);
383*00b67f09SDavid van Moolenbroek #endif
384*00b67f09SDavid van Moolenbroek 
385*00b67f09SDavid van Moolenbroek 	fprintf(stderr, "Destroying socket manager\n");
386*00b67f09SDavid van Moolenbroek 	isc_socketmgr_destroy(&socketmgr);
387*00b67f09SDavid van Moolenbroek 
388*00b67f09SDavid van Moolenbroek 	fprintf(stderr, "Destroying timer manager\n");
389*00b67f09SDavid van Moolenbroek 	isc_timermgr_destroy(&timgr);
390*00b67f09SDavid van Moolenbroek 
391*00b67f09SDavid van Moolenbroek 	fprintf(stderr, "Destroying task manager\n");
392*00b67f09SDavid van Moolenbroek 	isc_taskmgr_destroy(&manager);
393*00b67f09SDavid van Moolenbroek 
394*00b67f09SDavid van Moolenbroek 	isc_mem_stats(mctx, stdout);
395*00b67f09SDavid van Moolenbroek 	isc_mem_destroy(&mctx);
396*00b67f09SDavid van Moolenbroek 
397*00b67f09SDavid van Moolenbroek 	return (0);
398*00b67f09SDavid van Moolenbroek }
399