#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
+#if HAVE_BACKTRACE
+#include <execinfo.h>
+#endif
#include <libcitadel.h>
#include "citadel.h"
ev_io_stop(event_base, &IO->conn_event);
ev_io_stop(event_base, &IO->send_event);
ev_io_stop(event_base, &IO->recv_event);
- close(IO->SendBuf.fd);
+
+ if (IO->SendBuf.fd != 0) {
+ close(IO->SendBuf.fd);
+ }
IO->SendBuf.fd = 0;
IO->RecvBuf.fd = 0;
}
if (IO->DNS.Channel != NULL) {
ares_destroy(IO->DNS.Channel);
+ EV_DNS_LOG_STOP(DNS.recv_event);
+ EV_DNS_LOG_STOP(DNS.send_event);
ev_io_stop(event_base, &IO->DNS.recv_event);
ev_io_stop(event_base, &IO->DNS.send_event);
IO->DNS.Channel = NULL;
case eAbort:
switch (IO->DNS.Fail(IO)) {
case eAbort:
+//// StopClientWatchers(IO);
ShutDownCLient(IO);
default:
break;
StrBufPrintf(IO->ErrMsg,
"Failed to create socket: %s",
strerror(errno));
+ IO->SendBuf.fd = IO->RecvBuf.fd = 0;
return eAbort;
}
fdflags = fcntl(IO->SendBuf.fd, F_GETFL);
StrBufPrintf(IO->ErrMsg,
"Failed to get socket flags: %s",
strerror(errno));
+ close(IO->SendBuf.fd);
+ IO->SendBuf.fd = IO->RecvBuf.fd = 0;
return eAbort;
}
fdflags = fdflags | O_NONBLOCK;
"Failed to set socket flags: %s",
strerror(errno));
close(IO->SendBuf.fd);
- IO->SendBuf.fd = IO->RecvBuf.fd = -1;
+ IO->SendBuf.fd = IO->RecvBuf.fd = 0;
return eAbort;
}
/* TODO: maye we could use offsetof() to calc the position of data...
IO->SendBuf.Buf = NewStrBufPlain(NULL, 1024);
IO->RecvBuf.Buf = NewStrBufPlain(NULL, 1024);
IO->IOBuf = NewStrBuf();
+ EV_syslog(LOG_DEBUG,
+ "EVENT: Session lives at %p IO at %p \n",
+ Data, IO);
}
return evcurl_init(IO);
}
+
+void EV_backtrace(AsyncIO *IO)
+{
+#ifdef HAVE_BACKTRACE
+ void *stack_frames[50];
+ size_t size, i;
+ char **strings;
+
+
+ size = backtrace(stack_frames, sizeof(stack_frames) / sizeof(void*));
+ strings = backtrace_symbols(stack_frames, size);
+ for (i = 0; i < size; i++) {
+ if (strings != NULL)
+ EV_syslog(LOG_ALERT, " BT %s\n", strings[i]);
+ else
+ EV_syslog(LOG_ALERT, " BT %p\n", stack_frames[i]);
+ }
+ free(strings);
+#endif
+}
#define EVNCM_syslog(LEVEL, FORMAT) syslog(LEVEL, "IO[%ld]" FORMAT, IO->ID)
+#ifdef DEBUG_CARES
+#define EV_DNS_LOG_START(a) \
+ syslog(LOG_DEBUG, "IO[%ld]CC[%d] + Starting " #a " %p FD %d", IO->ID, CCID, &IO->a, IO->a.fd); \
+ EV_backtrace(IO);
+
+#define EV_DNS_LOG_STOP(a) \
+ syslog(LOG_DEBUG, "IO[%ld]CC[%d] - Stopping " #a " %p FD %d", IO->ID, CCID, &IO->a, IO->a.fd); \
+ EV_backtrace(IO);
+
+#define EV_DNS_LOG_INIT(a) \
+ syslog(LOG_DEBUG, "IO[%ld]CC[%d] * Init " #a " %p FD %d", IO->ID, CCID, &IO->a, IO->a.fd); \
+ EV_backtrace(IO);
+
+#define EV_DNS_LOGT_START(a) \
+ syslog(LOG_DEBUG, "IO[%ld]CC[%d] + Starting " #a " %p", IO->ID, CCID, &IO->a); \
+ EV_backtrace(IO);
+
+#define EV_DNS_LOGT_STOP(a) \
+ syslog(LOG_DEBUG, "IO[%ld]CC[%d] - Stopping " #a " %p", IO->ID, CCID, &IO->a); \
+ EV_backtrace(IO);
+
+#define EV_DNS_LOGT_INIT(a) \
+ syslog(LOG_DEBUG, "IO[%ld]CC[%d] * Init " #a " %p", IO->ID, CCID, &IO->a); \
+ EV_backtrace(IO);
+#else
+#define EV_DNS_LOG_START(a)
+#define EV_DNS_LOG_STOP(a)
+#define EV_DNS_LOG_INIT(a)
+#define EV_DNS_LOGT_START(a)
+#define EV_DNS_LOGT_STOP(a)
+#define EV_DNS_LOGT_INIT(a)
+#endif
+
void FreeAsyncIOContents(AsyncIO *IO);
eNextState NextDBOperation(AsyncIO *IO, IO_CallBack CB);
void *pData,
int ReadFirst);
+void EV_backtrace(AsyncIO *IO);
+
#endif /* __EVENT_CLIENT_H__ */
AsyncIO *IO = data;
#ifdef DEBUG_CARES
EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+ EV_DNS_LOGT_STOP(DNS.timeout);
#endif
ev_timer_stop (event_base, &IO->DNS.timeout);
AsyncIO *IO = arg;
#ifdef DEBUG_CARES
EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+ EV_DNS_LOGT_STOP(DNS.timeout);
#endif
ev_timer_stop (event_base, &IO->DNS.timeout);
ev_idle_init(&IO->unwind_stack,
IO_postdns_callback);
IO->unwind_stack.data = IO;
+ EV_DNS_LOGT_INIT(unwind_stack);
+ EV_DNS_LOGT_START(unwind_stack);
ev_idle_start(event_base, &IO->unwind_stack);
}
{
#ifdef DEBUG_CARES
EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+ EV_DNS_LOGT_STOP(DNS.timeout);
#endif
ev_idle_stop(event_base, &IO->unwind_stack);
ev_idle_init(&IO->unwind_stack,
IO_postdns_callback);
IO->unwind_stack.data = IO;
+ EV_DNS_LOGT_INIT(unwind_stack);
+ EV_DNS_LOGT_START(unwind_stack);
ev_idle_start(event_base, &IO->unwind_stack);
}
InitC_ares_dns(IO);
ev_timer_init(&IO->DNS.timeout, DNStimeouttrigger_callback, 10, 1);
+ EV_DNS_LOGT_INIT(DNS.timeout);
IO->DNS.timeout.data = IO;
ares_gethostbyname(IO->DNS.Channel,
Hostname,
AF_INET6, /* it falls back to ipv4 in doubt... */
QueueGetHostByNameDone,
IO);
+ EV_DNS_LOGT_START(DNS.timeout);
ev_timer_start(event_base, &IO->DNS.timeout);
}
ev_timer_init(&IO->DNS.timeout, DNStimeouttrigger_callback, 10, 1);
IO->DNS.timeout.data = IO;
+ EV_DNS_LOGT_INIT(DNS.timeout);
switch(Type) {
case ns_t_a:
family,
HostByAddrCb,
IO);
+ EV_DNS_LOGT_START(DNS.timeout);
ev_timer_start(event_base, &IO->DNS.timeout);
#ifdef DEBUG_CARES
EV_syslog(LOG_DEBUG, "C-ARES: %s X1\n", __FUNCTION__);
EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
#endif
ares_query(IO->DNS.Channel, name, ns_c_in, Type, QueryCb, IO);
+ EV_DNS_LOGT_START(DNS.timeout);
ev_timer_start(event_base, &IO->DNS.timeout);
return 1;
}
if (read) {
if ((IO->DNS.recv_event.fd != sock) &&
(IO->DNS.recv_event.fd != 0)) {
+ EV_DNS_LOG_STOP(DNS.recv_event);
ev_io_stop(event_base, &IO->DNS.recv_event);
}
IO->DNS.recv_event.fd = sock;
DNS_recv_callback,
IO->DNS.recv_event.fd,
EV_READ);
+ EV_DNS_LOG_INIT(DNS.recv_event);
IO->DNS.recv_event.data = IO;
+ EV_DNS_LOG_START(DNS.recv_event);
ev_io_start(event_base, &IO->DNS.recv_event);
}
if (write) {
if ((IO->DNS.send_event.fd != sock) &&
(IO->DNS.send_event.fd != 0)) {
+ EV_DNS_LOG_STOP(DNS.send_event);
ev_io_stop(event_base, &IO->DNS.send_event);
}
IO->DNS.send_event.fd = sock;
IO->DNS.send_event.fd,
EV_WRITE);
IO->DNS.send_event.data = IO;
+ EV_DNS_LOG_INIT(DNS.send_event);
+ EV_DNS_LOG_START(DNS.send_event);
ev_io_start(event_base, &IO->DNS.send_event);
}
if ((read == 0) && (write == 0)) {
+ EV_DNS_LOG_STOP(DNS.recv_event);
+ EV_DNS_LOG_STOP(DNS.send_event);
ev_io_stop(event_base, &IO->DNS.recv_event);
ev_io_stop(event_base, &IO->DNS.send_event);
}
void DeleteSmtpOutMsg(void *v)
{
SmtpOutMsg *Msg = v;
+ AsyncIO *IO = &Msg->IO;
+ EV_syslog(LOG_DEBUG, "SMTP: %s Aborting\n", __FUNCTION__);
/* these are kept in our own space and free'd below */
Msg->IO.ConnectMe = NULL;
FreeURL(&Msg->Relay);
FreeStrBuf(&Msg->msgtext);
FreeAsyncIOContents(&Msg->IO);
- memset (Msg, 0, sizeof(SmtpOutMsg)); /* just to be shure... */
+/// memset (Msg, 0, sizeof(SmtpOutMsg)); /* just to be shure... */
free(Msg);
}
* - one of the mx'es
*/
+ InitC_ares_dns(IO);
+
EVS_syslog(LOG_DEBUG, "SMTP: %s\n", __FUNCTION__);
EVS_syslog(LOG_DEBUG,
if (serviceptr->tcp_port > 0)
{
- syslog(LOG_INFO, "Closing listener on port %d\n",
- serviceptr->tcp_port);
+ syslog(LOG_INFO, "Closing %d listener on port %d\n",
+ serviceptr->msock,
+ serviceptr->tcp_port);
serviceptr->tcp_port = 0;
}
if (serviceptr->sockpath != NULL)
- syslog(LOG_INFO, "Closing listener on '%s'\n",
- serviceptr->sockpath);
-
- close(serviceptr->msock);
+ syslog(LOG_INFO, "Closing %d listener on '%s'\n",
+ serviceptr->msock,
+ serviceptr->sockpath);
+ if (serviceptr->msock != -1)
+ close(serviceptr->msock);
/* If it's a Unix domain socket, remove the file. */
if (serviceptr->sockpath != NULL) {
unlink(serviceptr->sockpath);