1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
/****************************************************************************
* Copyright (C) 1998 WIDE Project. All rights reserved.
* Copyright (C) 1999,2000,2001,2002 University of Tromso. All rights reserved.
* Copyright (C) 2002 Invenia Innovation AS. All rights reserved.
*
* Author: Feike W. Dillema, feico@pasta.cs.uit.no.
* based on newbie code by Yusuke DOI, Keio Univ. Murai Lab.
****************************************************************************/
/*
* <$Id: context.c,v 3.32 2002/03/04 12:34:10 dillema Exp $>
*/
#include "totd.h"
int context_timeout_handler (Ev_TO_Data *td) {
if (td->type != EV_TIMEOUT_CONTEXT)
return -1;
td->data.cont->tout = NULL;
/* call and return from retry routine */
return td->data.cont->retry (td->data.cont);
}
int context_timeout_register (Context *cont, int timeout) {
const char *fn = "context_timeout_register()";
Ev_TO_Data *edtp;
if (T.debug > 2)
syslog (LOG_DEBUG, "%s: start", fn);
if (cont->tout && cont->tout->handler) {
syslog (LOG_INFO, "%s: duplicate timeout. ignoring", fn);
return -1;
}
edtp = malloc (sizeof (Ev_TO_Data));
if (!edtp)
return -1;
edtp->at = time (NULL) + timeout;
edtp->handler = context_timeout_handler;
edtp->type = EV_TIMEOUT_CONTEXT;
edtp->data.cont = cont;
if (ev_to_register (edtp) < 0) {
free (edtp);
return (-1);
}
cont->tout = edtp;
if (T.debug > 2)
syslog (LOG_DEBUG, "%s: scheduled in %d", fn, (int) edtp->at);
/* SUCCESS */
return 0;
}
Context *context_create (void) {
const char *fn = "context_create()";
Context *cont;
cont = malloc (sizeof (Context));
if (!cont)
return NULL;
syslog (LOG_DEBUG, "%s: %p", fn, (void *) cont);
memset (cont, 0, sizeof (Context));
cont->current_ns = NULL;
cont->conn_sock = -1;
cont->an_list = list_init ();
cont->ns_list = list_init ();
cont->ar_list = list_init ();
if (!cont->an_list || !cont->ns_list || !cont->ar_list)
return context_destroy(cont);
cont->peer = malloc (sizeof (struct sockaddr_storage));
if (!cont->peer)
return context_destroy(cont);
memset (cont->peer, 0, sizeof (struct sockaddr_storage));
return cont;
}
void *context_destroy (Context *cont) {
const char *fn = "context_destroy()";
syslog (LOG_DEBUG, "%s: %p", fn, (void *) cont);
if (!cont)
return NULL;
/* anybody referencing us? */
if (cont->parent)
cont->parent->child = NULL;
if (cont->child)
cont->child->parent = NULL;
if (cont->an_list)
list_destroy (cont->an_list, rrset_freev);
if (cont->ns_list)
list_destroy (cont->ns_list, rrset_freev);
if (cont->ar_list)
list_destroy (cont->ar_list, rrset_freev);
if (cont->nameservers)
list_destroy(cont->nameservers, free);
if (cont->mesg.p)
free (cont->mesg.p);
if (cont->tout)
cont->tout->handler = NULL;
/* in case of TCP */
if (cont->conn_sock >= 0) {
/* first close the connection */
shutdown (cont->conn_sock, SHUT_RDWR);
close (cont->conn_sock);
/* then cleanup events and free memory */
ev_tcp_out_remove (cont->conn_sock);
ev_tcp_conn_in_remove (cont->conn_sock);
}
/* in case of UDP */
if (cont->conn_sock < 0 && cont->peer && cont->peer->sa_family)
ev_udp_in_remove (cont->peer, cont->q_id);
if (cont->peer)
free (cont->peer);
/* in case of UDP response */
if (cont->netifaddr)
nia_free (cont->netifaddr, 0);
free (cont);
return NULL;
}
|