sock_test.c revision f21dcf7d07476d850ecc9c1f81a4e1b3e91b08d8
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 1998, 1999 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Permission to use, copy, modify, and distribute this software for any
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * purpose with or without fee is hereby granted, provided that the above
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
15a44745412679c30a6d022733925af70a38b715David Lawrence * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
15a44745412679c30a6d022733925af70a38b715David Lawrence * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
15a44745412679c30a6d022733925af70a38b715David Lawrence * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15a44745412679c30a6d022733925af70a38b715David Lawrence * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15a44745412679c30a6d022733925af70a38b715David Lawrence * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15a44745412679c30a6d022733925af70a38b715David Lawrence * SOFTWARE.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson#include <config.h>
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <stdio.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <stdlib.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <unistd.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <string.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/assertions.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/error.h>
6028d1ce0380d0ba7f6c6ecd1ad20b31ddd1becbDavid Lawrence#include <isc/mem.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/task.h>
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#include <isc/thread.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/result.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <isc/socket.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <isc/timer.h>
7d823f705d9d3a8cb4d43fcf11249515e2845364Andreas Gustafsson
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson#include <sys/types.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <sys/socket.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <netinet/in.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington#include <arpa/inet.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtonisc_mem_t *mctx;
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellingtonisc_taskmgr_t *manager;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
75ec9bc9c7b4f2485647414330122e7b8e188097Andreas Gustafssonstatic void my_send(isc_task_t *task, isc_event_t *event);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleystatic void my_recv(isc_task_t *task, isc_event_t *event);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffstatic void
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleymy_shutdown(isc_task_t *task, isc_event_t *event)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley{
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley char *name = event->arg;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
f9df80f4348ef68043903efa08299480324f4823Michael Graff printf("shutdown %s (%p)\n", name, task);
f9df80f4348ef68043903efa08299480324f4823Michael Graff fflush(stdout);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_event_free(&event);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellingtonstatic void
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellingtonmy_recv(isc_task_t *task, isc_event_t *event)
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington{
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington isc_socket_t *sock;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer isc_socketevent_t *dev;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer isc_region_t region;
f9df80f4348ef68043903efa08299480324f4823Michael Graff char buf[1024];
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff sock = event->sender;
f9df80f4348ef68043903efa08299480324f4823Michael Graff dev = (isc_socketevent_t *)event;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff printf("Socket %s (sock %p, base %p, length %d, n %d, result %d)\n",
e223094b2248afa2697c531f75e6f84855638becMichael Graff (char *)(event->arg), sock,
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff dev->region.base, dev->region.length,
be066f0629a12e11bc17f27671036b3f451bd5eaBrian Wellington dev->n, dev->result);
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff printf("\tFrom: %s port %d\n",
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff inet_ntoa(dev->address.type.sin.sin_addr),
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff ntohs(dev->address.type.sin.sin_port));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (dev->result != ISC_R_SUCCESS) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_socket_detach(&sock);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_mem_put(mctx, dev->region.base,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dev->region.length);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_event_free(&event);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_task_shutdown(task);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer /*
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer * Echo the data back
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer */
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer if (strcmp(event->arg, "so2") != 0) {
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer region = dev->region;
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer sprintf(buf, "\r\nReceived: %.*s\r\n\r\n",
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer (int)region.length, (char *)region.base);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence region.base = isc_mem_get(mctx, strlen(buf) + 1);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer region.length = strlen(buf) + 1;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer strcpy((char *)region.base, buf); /* strcpy is safe */
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_socket_send(sock, &region, task, my_send, event->arg);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer } else {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer region = dev->region;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer printf("\r\nReceived: %.*s\r\n\r\n",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer (int)region.length, (char *)region.base);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_socket_recv(sock, &dev->region, ISC_FALSE,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer task, my_recv, event->arg);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_event_free(&event);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic void
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyermy_send(isc_task_t *task, isc_event_t *event)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer{
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_socket_t *sock;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_socketevent_t *dev;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer sock = event->sender;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dev = (isc_socketevent_t *)event;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer printf("my_send: %s task %p\n\t(sock %p, base %p, length %d, n %d, result %d)\n",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer (char *)(event->arg), task, sock,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dev->region.base, dev->region.length,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dev->n, dev->result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (dev->result != ISC_R_SUCCESS) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_socket_detach(&sock);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_task_shutdown(task);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_mem_put(mctx, dev->region.base, dev->region.length);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_event_free(&event);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic void
f9df80f4348ef68043903efa08299480324f4823Michael Graffmy_http_get(isc_task_t *task, isc_event_t *event)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_socket_t *sock;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_socketevent_t *dev;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff sock = event->sender;
f9df80f4348ef68043903efa08299480324f4823Michael Graff dev = (isc_socketevent_t *)event;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff printf("my_http_get: %s task %p\n\t(sock %p, base %p, length %d, n %d, result %d)\n",
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff (char *)(event->arg), task, sock,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff dev->region.base, dev->region.length,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff dev->n, dev->result);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (dev->result != ISC_R_SUCCESS) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_socket_detach(&sock);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_task_shutdown(task);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_event_free(&event);
f9df80f4348ef68043903efa08299480324f4823Michael Graff return;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_socket_recv(sock, &dev->region, ISC_FALSE, task, my_recv,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff event->arg);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_event_free(&event);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmy_connect(isc_task_t *task, isc_event_t *event)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff{
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_socket_t *sock;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_socket_connev_t *dev;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_region_t region;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff char buf[1024];
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff sock = event->sender;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff dev = (isc_socket_connev_t *)event;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff printf("%s: Connection result: %d\n", (char *)(event->arg),
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff dev->result);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (dev->result != ISC_R_SUCCESS) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_socket_detach(&sock);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_event_free(&event);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_task_shutdown(task);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff }
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff /*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Send a GET string, and set up to receive (and just display)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * the result.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff strcpy(buf, "GET /foo HTTP/1.1\r\nHost: www.flame.org\r\nConnection: Close\r\n\r\n");
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff region.base = isc_mem_get(mctx, strlen(buf) + 1);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff region.length = strlen(buf) + 1;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff strcpy((char *)region.base, buf); /* strcpy is safe */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_socket_send(sock, &region, task, my_http_get, event->arg);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
8c55a67a6d185de7036e39da30561a5c1637d22bAndreas Gustafsson isc_event_free(&event);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmy_listen(isc_task_t *task, isc_event_t *event)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff{
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff char *name = event->arg;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_socket_newconnev_t *dev;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_region_t region;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_socket_t *oldsock;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_task_t *newtask;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff dev = (isc_socket_newconnev_t *)event;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff printf("newcon %s (task %p, oldsock %p, newsock %p, result %d)\n",
f9df80f4348ef68043903efa08299480324f4823Michael Graff name, task, event->sender, dev->newsocket, dev->result);
f9df80f4348ef68043903efa08299480324f4823Michael Graff fflush(stdout);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (dev->result == ISC_R_SUCCESS) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff /*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * queue another listen on this socket
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_socket_accept(event->sender, task, my_listen, event->arg);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff region.base = isc_mem_get(mctx, 20);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff region.length = 20;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff /*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Create a new task for this socket, and queue up a
f9df80f4348ef68043903efa08299480324f4823Michael Graff * recv on it.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff newtask = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RUNTIME_CHECK(isc_task_create(manager, NULL, 0, &newtask)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff == ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_socket_recv(dev->newsocket, &region, ISC_FALSE,
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff newtask, my_recv, event->arg);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence isc_task_detach(&newtask);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff } else {
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff printf("detaching from socket %p\n", event->sender);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff oldsock = event->sender;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_socket_detach(&oldsock);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff isc_event_free(&event);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_task_shutdown(task);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_event_free(&event);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
4556681e191b7c1654639895ce719d98f2822ee2Michael Graffstatic void
d68838693666ba930ec4143f848c18bff2bfc244Michael Grafftimeout(isc_task_t *task, isc_event_t *event)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff{
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_socket_t *sock = event->arg;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff printf("Timeout, canceling IO on socket %p (task %p)\n", sock, task);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_ALL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_timer_detach((isc_timer_t **)&event->sender);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence isc_event_free(&event);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffint
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffmain(int argc, char *argv[])
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence{
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_task_t *t1, *t2;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_timermgr_t *timgr;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_time_t expires;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_interval_t interval;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_timer_t *ti1;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff unsigned int workers;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_socketmgr_t *socketmgr;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_socket_t *so1, *so2;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_sockaddr_t sockaddr;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff memset(&sockaddr, 0, sizeof(sockaddr));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff sockaddr.type.sin.sin_port = htons(5544);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff sockaddr.length = sizeof (struct sockaddr_in);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (argc > 1)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff workers = atoi(argv[1]);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff else
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff workers = 2;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff printf("%d workers\n", workers);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * EVERYTHING needs a memory context.
5e589b5356a4125b5af32605dead82ab8b467c88Mark Andrews */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff mctx = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * The task manager is independent (other than memory context)
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff manager = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) ==
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_R_SUCCESS);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Timer manager depends only on the memory context as well.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff timgr = NULL;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff RUNTIME_CHECK(isc_timermgr_create(mctx, &timgr) == ISC_R_SUCCESS);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff t1 = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RUNTIME_CHECK(isc_task_create(manager, NULL, 0, &t1) == ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff t2 = NULL;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff RUNTIME_CHECK(isc_task_create(manager, NULL, 0, &t2) == ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RUNTIME_CHECK(isc_task_onshutdown(t1, my_shutdown, "1") ==
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RUNTIME_CHECK(isc_task_onshutdown(t2, my_shutdown, "2") ==
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff printf("task 1 = %p\n", t1);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff printf("task 2 = %p\n", t2);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff socketmgr = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * open up a listener socket
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff so1 = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff memset(&sockaddr, 0, sizeof(sockaddr));
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington sockaddr.type.sin.sin_family = AF_INET;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington sockaddr.type.sin.sin_port = htons(5544);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington sockaddr.length = sizeof (struct sockaddr_in);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington RUNTIME_CHECK(isc_socket_create(socketmgr, isc_socket_tcp, &so1) ==
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_R_SUCCESS);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington RUNTIME_CHECK(isc_socket_bind(so1, &sockaddr) == ISC_R_SUCCESS);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington RUNTIME_CHECK(isc_socket_listen(so1, 0) == ISC_R_SUCCESS);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington /*
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington * queue up the first accept event
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington */
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington RUNTIME_CHECK(isc_socket_accept(so1, t1, my_listen,
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington "so1") == ISC_R_SUCCESS);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington isc_time_settoepoch(&expires);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington isc_interval_set(&interval, 10, 0);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ti1 = NULL;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_once, &expires,
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington &interval, t1, timeout, so1, &ti1) ==
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_R_SUCCESS);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington /*
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington * open up a socket that will connect to www.flame.org, port 80.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Why not. :)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
f9df80f4348ef68043903efa08299480324f4823Michael Graff so2 = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff memset(&sockaddr, 0, sizeof(sockaddr));
f9df80f4348ef68043903efa08299480324f4823Michael Graff sockaddr.type.sin.sin_port = htons(80);
f9df80f4348ef68043903efa08299480324f4823Michael Graff sockaddr.type.sin.sin_family = AF_INET;
e223094b2248afa2697c531f75e6f84855638becMichael Graff sockaddr.type.sin.sin_addr.s_addr = inet_addr("204.152.186.34");
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley sockaddr.length = sizeof (struct sockaddr_in);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RUNTIME_CHECK(isc_socket_create(socketmgr, isc_socket_tcp,
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley &so2) == ISC_R_SUCCESS);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence RUNTIME_CHECK(isc_socket_connect(so2, &sockaddr, t2,
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley my_connect, "so2") == ISC_R_SUCCESS);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Detaching these is safe, since the socket will attach to the
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff * task for any outstanding requests.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff isc_task_detach(&t1);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_task_detach(&t2);
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington /*
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * wait a short while.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley sleep(10);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff fprintf(stderr, "Destroying socket manager\n");
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_socketmgr_destroy(&socketmgr);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff fprintf(stderr, "Destroying timer manager\n");
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_timermgr_destroy(&timgr);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington fprintf(stderr, "Destroying task manager\n");
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_taskmgr_destroy(&manager);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
24694ab18a48bcc9c50304bd8b7eb6b9c7650129Brian Wellington isc_mem_stats(mctx, stdout);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_mem_destroy(&mctx);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (0);
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews}
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington