/****************************************************************************
* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1