summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Provos <provos@gmail.com>2007-07-31 03:58:10 +0000
committerNiels Provos <provos@gmail.com>2007-07-31 03:58:10 +0000
commit540800fc18a7a5ec8be39872792520c25d017a77 (patch)
treebffccc3cb875c7dcec5645a5d083ce81b861414b
parent87aad0ebdb4877c31172167ab59b0173d6488219 (diff)
downloadlibevent-540800fc18a7a5ec8be39872792520c25d017a77.tar.gz
merge from trunk
svn:r380
-rw-r--r--README2
-rw-r--r--WIN32-Code/win32.c8
-rw-r--r--buffer.c20
-rw-r--r--configure.in12
-rw-r--r--devpoll.c27
-rw-r--r--epoll.c28
-rw-r--r--evdns.c794
-rw-r--r--evdns.h4
-rw-r--r--event-internal.h5
-rw-r--r--event.348
-rw-r--r--event.c168
-rw-r--r--event.h41
-rwxr-xr-xevent_rpcgen.py39
-rw-r--r--event_tagging.c66
-rw-r--r--evhttp.h5
-rw-r--r--evport.c33
-rw-r--r--evsignal.h13
-rw-r--r--http.c90
-rw-r--r--kqueue.c17
-rw-r--r--poll.c29
-rw-r--r--rtsig.c40
-rw-r--r--sample/Makefile.am3
-rw-r--r--sample/event-test.c4
-rw-r--r--select.c25
-rw-r--r--signal.c85
-rw-r--r--test/regress.c167
-rw-r--r--test/regress_dns.c4
-rw-r--r--test/regress_http.c13
-rw-r--r--test/test-eof.c4
-rw-r--r--test/test-init.c4
-rw-r--r--test/test-time.c4
-rw-r--r--test/test-weof.c4
32 files changed, 1099 insertions, 707 deletions
diff --git a/README b/README
index 9fc8648d..b9940107 100644
--- a/README
+++ b/README
@@ -41,7 +41,7 @@ fixing bugs:
Andrey Matveev
Richard Nyberg
Jon Oberheide
- Phil Oelson
+ Phil Oleson
Dave Pacheco
Tassilo von Parseval
Pierre Phaneuf
diff --git a/WIN32-Code/win32.c b/WIN32-Code/win32.c
index 867d1f22..c051c943 100644
--- a/WIN32-Code/win32.c
+++ b/WIN32-Code/win32.c
@@ -81,12 +81,12 @@ struct win32op {
struct event **events;
};
-void *win32_init (void);
+void *win32_init (struct event_base *);
int win32_insert (void *, struct event *);
int win32_del (void *, struct event *);
int win32_recalc (struct event_base *base, void *, int);
int win32_dispatch (struct event_base *base, void *, struct timeval *);
-void win32_dealloc (void *);
+void win32_dealloc (struct event_base *, void *);
struct eventop win32ops = {
"win32",
@@ -167,7 +167,7 @@ do_fd_clear(struct win32op *op, SOCKET s, int read)
#define NEVENT 64
void *
-win32_init(void)
+win32_init(struct event_base *)
{
struct win32op *winop;
size_t size;
@@ -376,7 +376,7 @@ win32_dispatch(struct event_base *base, void *op,
}
void
-win32_dealloc(void *arg)
+win32_dealloc(struct event_base *, void *arg)
{
struct win32op *win32op = arg;
diff --git a/buffer.c b/buffer.c
index 77efd0cf..0a57dda3 100644
--- a/buffer.c
+++ b/buffer.c
@@ -44,6 +44,7 @@
#include <sys/ioctl.h>
#endif
+#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -134,9 +135,13 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
int sz;
va_list aq;
+ /* make sure that at least some space is available */
+ evbuffer_expand(buf, 64);
for (;;) {
+ size_t used = buf->misalign + buf->off;
buffer = (char *)buf->buffer + buf->off;
- space = buf->totallen - buf->misalign - buf->off;
+ assert(buf->totallen >= used);
+ space = buf->totallen - used;
#ifndef va_copy
#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list))
@@ -152,7 +157,7 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
va_end(aq);
- if (sz == -1)
+ if (sz < 0)
return (-1);
if (sz < space) {
buf->off += sz;
@@ -244,7 +249,7 @@ evbuffer_readline(struct evbuffer *buffer)
/* Adds data to an event buffer */
-static inline void
+static void
evbuffer_align(struct evbuffer *buf)
{
memmove(buf->orig_buffer, buf->buffer, buf->off);
@@ -431,13 +436,12 @@ evbuffer_write(struct evbuffer *buffer, int fd)
u_char *
evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len)
{
- size_t remain = buffer->off;
- u_char *search = buffer->buffer;
+ u_char *search = buffer->buffer, *end = search + buffer->off;
u_char *p;
- while ((p = memchr(search, *what, remain)) != NULL) {
- remain = buffer->off - (size_t)(search - buffer->buffer);
- if (remain < len)
+ while (search < end &&
+ (p = memchr(search, *what, end - search)) != NULL) {
+ if (p + len > end)
break;
if (memcmp(p, what, len) == 0)
return (p);
diff --git a/configure.in b/configure.in
index 0dc254f6..9fc76c7a 100644
--- a/configure.in
+++ b/configure.in
@@ -35,10 +35,12 @@ AC_ARG_WITH(rtsig,
dnl Checks for libraries.
AC_CHECK_LIB(socket, socket)
+AC_CHECK_LIB(resolv, inet_aton)
+AC_CHECK_LIB(rt, clock_gettime)
dnl Checks for header files.
AC_HEADER_STDC
-AC_CHECK_HEADERS(fcntl.h stdarg.h inttypes.h stdint.h poll.h signal.h unistd.h sys/epoll.h sys/time.h sys/queue.h sys/event.h sys/ioctl.h sys/devpoll.h port.h netinet/in6.h)
+AC_CHECK_HEADERS(fcntl.h stdarg.h inttypes.h stdint.h poll.h signal.h unistd.h sys/epoll.h sys/time.h sys/queue.h sys/event.h sys/ioctl.h sys/select.h sys/devpoll.h port.h netinet/in6.h)
if test "x$ac_cv_header_sys_queue_h" = "xyes"; then
AC_MSG_CHECKING(for TAILQ_FOREACH in sys/queue.h)
AC_EGREP_CPP(yes,
@@ -335,10 +337,10 @@ fi
AC_TYPE_PID_T
AC_TYPE_SIZE_T
-AC_CHECK_TYPE(u_int64_t, unsigned long long)
-AC_CHECK_TYPE(u_int32_t, unsigned int)
-AC_CHECK_TYPE(u_int16_t, unsigned short)
-AC_CHECK_TYPE(u_int8_t, unsigned char)
+AC_CHECK_TYPE(uint64_t, unsigned long long)
+AC_CHECK_TYPE(uint32_t, unsigned int)
+AC_CHECK_TYPE(uint16_t, unsigned short)
+AC_CHECK_TYPE(uint8_t, unsigned char)
AC_CHECK_TYPES([struct in6_addr], , ,
[#ifdef WIN32
#include <winsock2.h>
diff --git a/devpoll.c b/devpoll.c
index db897a9d..d1327e55 100644
--- a/devpoll.c
+++ b/devpoll.c
@@ -36,6 +36,7 @@
#include <sys/_time.h>
#endif
#include <sys/queue.h>
+#include <sys/tree.h>
#include <sys/devpoll.h>
#include <signal.h>
#include <stdio.h>
@@ -47,11 +48,10 @@
#include <assert.h>
#include "event.h"
+#include "event-internal.h"
#include "evsignal.h"
#include "log.h"
-extern volatile sig_atomic_t evsignal_caught;
-
/* due to limitations in the devpoll interface, we need to keep track of
* all file descriptors outself.
*/
@@ -70,12 +70,12 @@ struct devpollop {
int nchanges;
};
-void *devpoll_init (void);
+void *devpoll_init (struct event_base *);
int devpoll_add (void *, struct event *);
int devpoll_del (void *, struct event *);
int devpoll_recalc (struct event_base *, void *, int);
int devpoll_dispatch (struct event_base *, void *, struct timeval *);
-void devpoll_dealloc (void *);
+void devpoll_dealloc (struct event_base *, void *);
struct eventop devpollops = {
"devpoll",
@@ -126,7 +126,7 @@ devpoll_queue(struct devpollop *devpollop, int fd, int events) {
}
void *
-devpoll_init(void)
+devpoll_init(struct event_base *base)
{
int dpfd, nfiles = NEVENT;
struct rlimit rl;
@@ -179,7 +179,7 @@ devpoll_init(void)
return (NULL);
}
- evsignal_init();
+ evsignal_init(base);
return (devpollop);
}
@@ -218,12 +218,13 @@ devpoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
struct pollfd *events = devpollop->events;
struct dvpoll dvp;
struct evdevpoll *evdp;
- int i, res, timeout;
+ int i, res, timeout = -1;
if (devpollop->nchanges)
devpoll_commit(devpollop);
- timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
+ if (tv != NULL)
+ timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
dvp.dp_fds = devpollop->events;
dvp.dp_nfds = devpollop->nevents;
@@ -237,10 +238,11 @@ devpoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
return (-1);
}
- evsignal_process();
+ evsignal_process(base);
return (0);
- } else if (evsignal_caught)
- evsignal_process();
+ } else if (base->sig.evsignal_caught) {
+ evsignal_process(base);
+ }
event_debug(("%s: devpoll_wait reports %d", __func__, res));
@@ -398,10 +400,11 @@ devpoll_del(void *arg, struct event *ev)
}
void
-devpoll_dealloc(void *arg)
+devpoll_dealloc(struct event_base *base, void *arg)
{
struct devpollop *devpollop = arg;
+ evsignal_dealloc(base);
if (devpollop->fds)
free(devpollop->fds);
if (devpollop->events)
diff --git a/epoll.c b/epoll.c
index e089e23d..2be06d6d 100644
--- a/epoll.c
+++ b/epoll.c
@@ -30,6 +30,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <sys/tree.h>
#include <sys/resource.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
@@ -49,11 +50,10 @@
#endif
#include "event.h"
+#include "event-internal.h"
#include "evsignal.h"
#include "log.h"
-extern volatile sig_atomic_t evsignal_caught;
-
/* due to limitations in the epoll interface, we need to keep track of
* all file descriptors outself.
*/
@@ -70,12 +70,12 @@ struct epollop {
int epfd;
};
-void *epoll_init (void);
+void *epoll_init (struct event_base *);
int epoll_add (void *, struct event *);
int epoll_del (void *, struct event *);
int epoll_recalc (struct event_base *, void *, int);
int epoll_dispatch (struct event_base *, void *, struct timeval *);
-void epoll_dealloc (void *);
+void epoll_dealloc (struct event_base *, void *);
struct eventop epollops = {
"epoll",
@@ -99,7 +99,7 @@ struct eventop epollops = {
#define NEVENT 32000
void *
-epoll_init(void)
+epoll_init(struct event_base *base)
{
int epfd, nfiles = NEVENT;
struct rlimit rl;
@@ -149,7 +149,7 @@ epoll_init(void)
}
epollop->nfds = nfiles;
- evsignal_init();
+ evsignal_init(base);
return (epollop);
}
@@ -187,9 +187,11 @@ epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
struct epollop *epollop = arg;
struct epoll_event *events = epollop->events;
struct evepoll *evep;
- int i, res, timeout;
+ int i, res, timeout = -1;
+
+ if (tv != NULL)
+ timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
- timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout);
if (res == -1) {
@@ -198,10 +200,11 @@ epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
return (-1);
}
- evsignal_process();
+ evsignal_process(base);
return (0);
- } else if (evsignal_caught)
- evsignal_process();
+ } else if (base->sig.evsignal_caught) {
+ evsignal_process(base);
+ }
event_debug(("%s: epoll_wait reports %d", __func__, res));
@@ -346,10 +349,11 @@ epoll_del(void *arg, struct event *ev)
}
void
-epoll_dealloc(void *arg)
+epoll_dealloc(struct event_base *base, void *arg)
{
struct epollop *epollop = arg;
+ evsignal_dealloc(base);
if (epollop->fds)
free(epollop->fds);
if (epollop->events)
diff --git a/evdns.c b/evdns.c
index b1e0644e..e8317d3d 100644
--- a/evdns.c
+++ b/evdns.c
@@ -43,7 +43,7 @@
#include "misc.h"
#endif
-//#define NDEBUG
+/* #define NDEBUG */
#ifndef DNS_USE_CPU_CLOCK_FOR_ID
#ifndef DNS_USE_GETTIMEOFDAY_FOR_ID
@@ -54,7 +54,7 @@
#endif
#endif
-// #define _POSIX_C_SOURCE 200507
+/* #define _POSIX_C_SOURCE 200507 */
#define _GNU_SOURCE
#ifdef DNS_USE_CPU_CLOCK_FOR_ID
@@ -128,7 +128,7 @@ typedef int socklen_t;
#define MIN(a,b) ((a)<(b)?(a):(b))
#ifdef __USE_ISOC99B
-// libevent doesn't work without this
+/* libevent doesn't work without this */
typedef uint8_t u_char;
typedef unsigned int uint;
#endif
@@ -139,8 +139,8 @@ typedef unsigned int uint;
#define u16 uint16_t
#define u8 uint8_t
-#define MAX_ADDRS 4 // maximum number of addresses from a single packet
-// which we bother recording
+#define MAX_ADDRS 4 /* maximum number of addresses from a single packet */
+/* which we bother recording */
#define TYPE_A EVDNS_TYPE_A
#define TYPE_CNAME 5
@@ -150,29 +150,29 @@ typedef unsigned int uint;
#define CLASS_INET EVDNS_CLASS_INET
struct request {
- u8 *request; // the dns packet data
+ u8 *request; /* the dns packet data */
unsigned int request_len;
int reissue_count;
- int tx_count; // the number of times that this packet has been sent
- unsigned int request_type; // TYPE_PTR or TYPE_A
- void *user_pointer; // the pointer given to us for this request
+ int tx_count; /* the number of times that this packet has been sent */
+ unsigned int request_type; /* TYPE_PTR or TYPE_A */
+ void *user_pointer; /* the pointer given to us for this request */
evdns_callback_type user_callback;
- struct nameserver *ns; // the server which we last sent it
+ struct nameserver *ns; /* the server which we last sent it */
- // elements used by the searching code
+ /* elements used by the searching code */
int search_index;
struct search_state *search_state;
- char *search_origname; // needs to be free()ed
+ char *search_origname; /* needs to be free()ed */
int search_flags;
- // these objects are kept in a circular list
+ /* these objects are kept in a circular list */
struct request *next, *prev;
struct event timeout_event;
- u16 trans_id; // the transaction id
- char request_appended; // true if the request pointer is data which follows this struct
- char transmit_me; // needs to be transmitted
+ u16 trans_id; /* the transaction id */
+ char request_appended; /* true if the request pointer is data which follows this struct */
+ char transmit_me; /* needs to be transmitted */
};
#ifndef HAVE_STRUCT_IN6_ADDR
@@ -200,115 +200,113 @@ struct reply {
};
struct nameserver {
- int socket; // a connected UDP socket
+ int socket; /* a connected UDP socket */
u32 address;
- int failed_times; // number of times which we have given this server a chance
- int timedout; // number of times in a row a request has timed out
+ int failed_times; /* number of times which we have given this server a chance */
+ int timedout; /* number of times in a row a request has timed out */
struct event event;
- // these objects are kept in a circular list
+ /* these objects are kept in a circular list */
struct nameserver *next, *prev;
- struct event timeout_event; // used to keep the timeout for
- // when we next probe this server.
- // Valid if state == 0
- char state; // zero if we think that this server is down
- char choked; // true if we have an EAGAIN from this server's socket
- char write_waiting; // true if we are waiting for EV_WRITE events
+ struct event timeout_event; /* used to keep the timeout for */
+ /* when we next probe this server. */
+ /* Valid if state == 0 */
+ char state; /* zero if we think that this server is down */
+ char choked; /* true if we have an EAGAIN from this server's socket */
+ char write_waiting; /* true if we are waiting for EV_WRITE events */
};
static struct request *req_head = NULL, *req_waiting_head = NULL;
static struct nameserver *server_head = NULL;
-// Represents a local port where we're listening for DNS requests. Right now,
-// only UDP is supported.
+/* Represents a local port where we're listening for DNS requests. Right now, */
+/* only UDP is supported. */
struct evdns_server_port {
- int socket; // socket we use to read queries and write replies.
- int refcnt; // reference count.
- char choked; // Are we currently blocked from writing?
- char closing; // Are we trying to close this port, pending writes?
- evdns_request_callback_fn_type user_callback; // Fn to handle requests
- void *user_data; // Opaque pointer passed to user_callback
- struct event event; // Read/write event
- // circular list of replies that we want to write.
+ int socket; /* socket we use to read queries and write replies. */
+ int refcnt; /* reference count. */
+ char choked; /* Are we currently blocked from writing? */
+ char closing; /* Are we trying to close this port, pending writes? */
+ evdns_request_callback_fn_type user_callback; /* Fn to handle requests */
+ void *user_data; /* Opaque pointer passed to user_callback */
+ struct event event; /* Read/write event */
+ /* circular list of replies that we want to write. */
struct server_request *pending_replies;
};
-// Represents part of a reply being built. (That is, a single RR.)
+/* Represents part of a reply being built. (That is, a single RR.) */
struct server_reply_item {
- struct server_reply_item *next; // next item in sequence.
- char *name; // name part of the RR
- u16 type : 16; // The RR type
- u16 class : 16; // The RR class (usually CLASS_INET)
- u32 ttl; // The RR TTL
- char is_name; // True iff data is a label
- u16 datalen; // Length of data; -1 if data is a label
- void *data; // The contents of the RR
+ struct server_reply_item *next; /* next item in sequence. */
+ char *name; /* name part of the RR */
+ u16 type : 16; /* The RR type */
+ u16 class : 16; /* The RR class (usually CLASS_INET) */
+ u32 ttl; /* The RR TTL */
+ char is_name; /* True iff data is a label */
+ u16 datalen; /* Length of data; -1 if data is a label */
+ void *data; /* The contents of the RR */
};
-// Represents a request that we've received as a DNS server, and holds
-// the components of the reply as we're constructing it.
+/* Represents a request that we've received as a DNS server, and holds */
+/* the components of the reply as we're constructing it. */
struct server_request {
- // Pointers to the next and previous entries on the list of replies
- // that we're waiting to write. Only set if we have tried to respond
- // and gotten EAGAIN.
+ /* Pointers to the next and previous entries on the list of replies */
+ /* that we're waiting to write. Only set if we have tried to respond */
+ /* and gotten EAGAIN. */
struct server_request *next_pending;
struct server_request *prev_pending;
- u16 trans_id; // Transaction id.
- struct evdns_server_port *port; // Which port received this request on?
- struct sockaddr_storage addr; // Where to send the response
- socklen_t addrlen; // length of addr
+ u16 trans_id; /* Transaction id. */
+ struct evdns_server_port *port; /* Which port received this request on? */
+ struct sockaddr_storage addr; /* Where to send the response */
+ socklen_t addrlen; /* length of addr */
- int n_answer; // how many answer RRs have been set?
- int n_authority; // how many authority RRs have been set?
- int n_additional; // how many additional RRs have been set?
+ int n_answer; /* how many answer RRs have been set? */
+ int n_authority; /* how many authority RRs have been set? */
+ int n_additional; /* how many additional RRs have been set? */
- struct server_reply_item *answer; // linked list of answer RRs
- struct server_reply_item *authority; // linked list of authority RRs
- struct server_reply_item *additional; // linked list of additional RRs
+ struct server_reply_item *answer; /* linked list of answer RRs */
+ struct server_reply_item *authority; /* linked list of authority RRs */
+ struct server_reply_item *additional; /* linked list of additional RRs */
- // Constructed response. Only set once we're ready to send a reply.
- // Once this is set, the RR fields are cleared, and no more should be set.
+ /* Constructed response. Only set once we're ready to send a reply. */
+ /* Once this is set, the RR fields are cleared, and no more should be set. */
char *response;
size_t response_len;
- // Caller-visible fields: flags, questions.
+ /* Caller-visible fields: flags, questions. */
struct evdns_server_request base;
};
-// helper macro
+/* helper macro */
#define OFFSET_OF(st, member) ((off_t) (((char*)&((st*)0)->member)-(char*)0))
-// Given a pointer to an evdns_server_request, get the corresponding
-// server_request.
+/* Given a pointer to an evdns_server_request, get the corresponding */
+/* server_request. */
#define TO_SERVER_REQUEST(base_ptr) \
((struct server_request*) \
(((char*)(base_ptr) - OFFSET_OF(struct server_request, base))))
-// The number of good nameservers that we have
+/* The number of good nameservers that we have */
static int global_good_nameservers = 0;
-// inflight requests are contained in the req_head list
-// and are actually going out across the network
+/* inflight requests are contained in the req_head list */
+/* and are actually going out across the network */
static int global_requests_inflight = 0;
-// requests which aren't inflight are in the waiting list
-// and are counted here
+/* requests which aren't inflight are in the waiting list */
+/* and are counted here */
static int global_requests_waiting = 0;
static int global_max_requests_inflight = 64;
-static struct timeval global_timeout = {5, 0}; // 5 seconds
-static int global_max_reissues = 1; // a reissue occurs when we get some errors from the server
-static int global_max_retransmits = 3; // number of times we'll retransmit a request which timed out
-// number of timeouts in a row before we consider this server to be down
+static struct timeval global_timeout = {5, 0}; /* 5 seconds */
+static int global_max_reissues = 1; /* a reissue occurs when we get some errors from the server */
+static int global_max_retransmits = 3; /* number of times we'll retransmit a request which timed out */
+/* number of timeouts in a row before we consider this server to be down */
static int global_max_nameserver_timeout = 3;
-// These are the timeout values for nameservers. If we find a nameserver is down
-// we try to probe it at intervals as given below. Values are in seconds.
+/* These are the timeout values for nameservers. If we find a nameserver is down */
+/* we try to probe it at intervals as given below. Values are in seconds. */
static const struct timeval global_nameserver_timeouts[] = {{10, 0}, {60, 0}, {300, 0}, {900, 0}, {3600, 0}};
static const int global_nameserver_timeouts_length = sizeof(global_nameserver_timeouts)/sizeof(struct timeval);
-static const char *const evdns_error_strings[] = {"no error", "The name server was unable to interpret the query", "The name server suffered an internal error", "The requested domain name does not exist", "The name server refused to reply to the request"};
-
static struct nameserver *nameserver_pick(void);
static void evdns_request_insert(struct request *req, struct request **head);
static void nameserver_ready_callback(int fd, short events, void *arg);
@@ -425,9 +423,9 @@ _evdns_log(int warn, const char *fmt, ...)
#define log _evdns_log
-// This walks the list of inflight requests to find the
-// one with a matching transaction id. Returns NULL on
-// failure
+/* This walks the list of inflight requests to find the */
+/* one with a matching transaction id. Returns NULL on */
+/* failure */
static struct request *
request_find_from_trans_id(u16 trans_id) {
struct request *req = req_head, *const started_at = req_head;
@@ -442,8 +440,8 @@ request_find_from_trans_id(u16 trans_id) {
return NULL;
}
-// a libevent callback function which is called when a nameserver
-// has gone down and we want to test if it has came back to life yet
+/* a libevent callback function which is called when a nameserver */
+/* has gone down and we want to test if it has came back to life yet */
static void
nameserver_prod_callback(int fd, short events, void *arg) {
struct nameserver *const ns = (struct nameserver *) arg;
@@ -453,16 +451,16 @@ nameserver_prod_callback(int fd, short events, void *arg) {
nameserver_send_probe(ns);
}
-// a libevent callback which is called when a nameserver probe (to see if
-// it has come back to life) times out. We increment the count of failed_times
-// and wait longer to send the next probe packet.
+/* a libevent callback which is called when a nameserver probe (to see if */
+/* it has come back to life) times out. We increment the count of failed_times */
+/* and wait longer to send the next probe packet. */
static void
nameserver_probe_failed(struct nameserver *const ns) {
const struct timeval * timeout;
(void) evtimer_del(&ns->timeout_event);
if (ns->state == 1) {
- // This can happen if the nameserver acts in a way which makes us mark
- // it as bad and then starts sending good replies.
+ /* This can happen if the nameserver acts in a way which makes us mark */
+ /* it as bad and then starts sending good replies. */
return;
}
@@ -476,17 +474,17 @@ nameserver_probe_failed(struct nameserver *const ns) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
debug_ntoa(ns->address));
- // ???? Do more?
+ /* ???? Do more? */
}
}
-// called when a nameserver has been deemed to have failed. For example, too
-// many packets have timed out etc
+/* called when a nameserver has been deemed to have failed. For example, too */
+/* many packets have timed out etc */
static void
nameserver_failed(struct nameserver *const ns, const char *msg) {
struct request *req, *started_at;
- // if this nameserver has already been marked as failed
- // then don't do anything
+ /* if this nameserver has already been marked as failed */
+ /* then don't do anything */
if (!ns->state) return;
log(EVDNS_LOG_WARN, "Nameserver %s has failed: %s",
@@ -505,15 +503,15 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
debug_ntoa(ns->address));
- // ???? Do more?
+ /* ???? Do more? */
}
- // walk the list of inflight requests to see if any can be reassigned to
- // a different server. Requests in the waiting queue don't have a
- // nameserver assigned yet
+ /* walk the list of inflight requests to see if any can be reassigned to */
+ /* a different server. Requests in the waiting queue don't have a */
+ /* nameserver assigned yet */
- // if we don't have *any* good nameservers then there's no point
- // trying to reassign requests to one
+ /* if we don't have *any* good nameservers then there's no point */
+ /* trying to reassign requests to one */
if (!global_good_nameservers) return;
req = req_head;
@@ -521,8 +519,8 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
if (req) {
do {
if (req->tx_count == 0 && req->ns == ns) {
- // still waiting to go out, can be moved
- // to another server
+ /* still waiting to go out, can be moved */
+ /* to another server */
req->ns = nameserver_pick();
}
req = req->next;
@@ -548,14 +546,14 @@ request_trans_id_set(struct request *const req, const u16 trans_id) {
*((u16 *) req->request) = htons(trans_id);
}
-// Called to remove a request from a list and dealloc it.
-// head is a pointer to the head of the list it should be
-// removed from or NULL if the request isn't in a list.
+/* Called to remove a request from a list and dealloc it. */
+/* head is a pointer to the head of the list it should be */
+/* removed from or NULL if the request isn't in a list. */
static void
request_finished(struct request *const req, struct request **head) {
if (head) {
if (req->next == req) {
- // only item in the list
+ /* only item in the list */
*head = NULL;
} else {
req->next->prev = req->prev;
@@ -572,11 +570,11 @@ request_finished(struct request *const req, struct request **head) {
global_requests_inflight--;
if (!req->request_appended) {
- // need to free the request data on it's own
+ /* need to free the request data on it's own */
free(req->request);
} else {
- // the request data is appended onto the header
- // so everything gets free()ed when we:
+ /* the request data is appended onto the header */
+ /* so everything gets free()ed when we: */
}
free(req);
@@ -584,23 +582,23 @@ request_finished(struct request *const req, struct request **head) {
evdns_requests_pump_waiting_queue();
}
-// This is called when a server returns a funny error code.
-// We try the request again with another server.
-//
-// return:
-// 0 ok
-// 1 failed/reissue is pointless
+/* This is called when a server returns a funny error code. */
+/* We try the request again with another server. */
+/* */
+/* return: */
+/* 0 ok */
+/* 1 failed/reissue is pointless */
static int
request_reissue(struct request *req) {
const struct nameserver *const last_ns = req->ns;
- // the last nameserver should have been marked as failing
- // by the caller of this function, therefore pick will try
- // not to return it
+ /* the last nameserver should have been marked as failing */
+ /* by the caller of this function, therefore pick will try */
+ /* not to return it */
req->ns = nameserver_pick();
if (req->ns == last_ns) {
- // ... but pick did return it
- // not a lot of point in trying again with the
- // same server
+ /* ... but pick did return it */
+ /* not a lot of point in trying again with the */
+ /* same server */
return 1;
}
@@ -611,17 +609,17 @@ request_reissue(struct request *req) {
return 0;
}
-// this function looks for space on the inflight queue and promotes
-// requests from the waiting queue if it can.
+/* this function looks for space on the inflight queue and promotes */
+/* requests from the waiting queue if it can. */
static void
evdns_requests_pump_waiting_queue(void) {
while (global_requests_inflight < global_max_requests_inflight &&
global_requests_waiting) {
struct request *req;
- // move a request from the waiting queue to the inflight queue
+ /* move a request from the waiting queue to the inflight queue */
assert(req_waiting_head);
if (req_waiting_head->next == req_waiting_head) {
- // only one item in the queue
+ /* only one item in the queue */
req = req_waiting_head;
req_waiting_head = NULL;
} else {
@@ -678,14 +676,14 @@ reply_callback(struct request *const req, u32 ttl, u32 err, struct reply *reply)
assert(0);
}
-// this processes a parsed reply packet
+/* this processes a parsed reply packet */
static void
reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply) {
int error;
static const int error_codes[] = {DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, DNS_ERR_NOTIMPL, DNS_ERR_REFUSED};
if (flags & 0x020f || !reply || !reply->have_answer) {
- // there was an error
+ /* there was an error */
if (flags & 0x0200) {
error = DNS_ERR_TRUNCATED;
} else {
@@ -698,10 +696,9 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
}
switch(error) {
- case DNS_ERR_SERVERFAILED:
case DNS_ERR_NOTIMPL:
case DNS_ERR_REFUSED:
- // we regard these errors as marking a bad nameserver
+ /* we regard these errors as marking a bad nameserver */
if (req->reissue_count < global_max_reissues) {
char msg[64];
snprintf(msg, sizeof(msg), "Bad response %d (%s)",
@@ -710,50 +707,59 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
if (!request_reissue(req)) return;
}
break;
+ case DNS_ERR_SERVERFAILED:
+ /* rcode 2 (servfailed) sometimes means "we are broken" and
+ * sometimes (with some binds) means "that request was very
+ * confusing." Treat this as a timeout, not a failure.
+ */
+ log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
+ "will allow the request to time out.",
+ debug_ntoa(req->ns->address));
+ break;
default:
- // we got a good reply from the nameserver
+ /* we got a good reply from the nameserver */
nameserver_up(req->ns);
}
if (req->search_state && req->request_type != TYPE_PTR) {
- // if we have a list of domains to search in, try the next one
+ /* if we have a list of domains to search in, try the next one */
if (!search_try_next(req)) {
- // a new request was issued so this request is finished and
- // the user callback will be made when that request (or a
- // child of it) finishes.
+ /* a new request was issued so this request is finished and */
+ /* the user callback will be made when that request (or a */
+ /* child of it) finishes. */
request_finished(req, &req_head);
return;
}
}
- // all else failed. Pass the failure up
+ /* all else failed. Pass the failure up */
reply_callback(req, 0, error, NULL);
request_finished(req, &req_head);
} else {
- // all ok, tell the user
+ /* all ok, tell the user */
reply_callback(req, ttl, 0, reply);
nameserver_up(req->ns);
request_finished(req, &req_head);
}
}
-static inline int
+static int
name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
int name_end = -1;
int j = *idx;
int ptr_count = 0;
-#define GET32(x) do { if (j + 4 > length) goto err; memcpy(&_t32, packet + j, 4); j += 4; x = ntohl(_t32); } while(0);
-#define GET16(x) do { if (j + 2 > length) goto err; memcpy(&_t, packet + j, 2); j += 2; x = ntohs(_t); } while(0);
-#define GET8(x) do { if (j >= length) goto err; x = packet[j++]; } while(0);
+#define GET32(x) do { if (j + 4 > length) goto err; memcpy(&_t32, packet + j, 4); j += 4; x = ntohl(_t32); } while(0)
+#define GET16(x) do { if (j + 2 > length) goto err; memcpy(&_t, packet + j, 2); j += 2; x = ntohs(_t); } while(0)
+#define GET8(x) do { if (j >= length) goto err; x = packet[j++]; } while(0)
char *cp = name_out;
const char *const end = name_out + name_out_len;
- // Normally, names are a series of length prefixed strings terminated
- // with a length of 0 (the lengths are u8's < 63).
- // However, the length can start with a pair of 1 bits and that
- // means that the next 14 bits are a pointer within the current
- // packet.
+ /* Normally, names are a series of length prefixed strings terminated */
+ /* with a length of 0 (the lengths are u8's < 63). */
+ /* However, the length can start with a pair of 1 bits and that */
+ /* means that the next 14 bits are a pointer within the current */
+ /* packet. */
for(;;) {
u8 label_len;
@@ -793,18 +799,19 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
return -1;
}
-// parses a raw request from a nameserver
+/* parses a raw request from a nameserver */
static int
reply_parse(u8 *packet, int length) {
- int j = 0; // index into packet
- u16 _t; // used by the macros
- u32 _t32; // used by the macros
- char tmp_name[256]; // used by the macros
+ int j = 0; /* index into packet */
+ u16 _t; /* used by the macros */
+ u32 _t32; /* used by the macros */
+ char tmp_name[256]; /* used by the macros */
- u16 trans_id, flags, questions, answers, authority, additional, datalength;
+ u16 trans_id, questions, answers, authority, additional, datalength;
+ u16 flags = 0;
u32 ttl, ttl_r = 0xffffffff;
struct reply reply;
- struct request *req;
+ struct request *req = NULL;
unsigned int i;
GET16(trans_id);
@@ -818,19 +825,18 @@ reply_parse(u8 *packet, int length) {
req = request_find_from_trans_id(trans_id);
if (!req) return -1;
- // XXXX should the other return points also call reply_handle? -NM
memset(&reply, 0, sizeof(reply));
- if (!(flags & 0x8000)) return -1; // must be an answer
+ /* If it's not an answer, it doesn't correspond to any request. */
+ if (!(flags & 0x8000)) return -1; /* must be an answer */
if (flags & 0x020f) {
- // there was an error
- reply_handle(req, flags, 0, NULL);
- return -1;
+ /* there was an error */
+ goto err;
}
- // if (!answers) return; // must have an answer of some form
+ /* if (!answers) return; */ /* must have an answer of some form */
- // This macro skips a name in the DNS reply.
+ /* This macro skips a name in the DNS reply. */
#define SKIP_NAME \
do { tmp_name[0] = '\0'; \
if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0) \
@@ -839,17 +845,19 @@ reply_parse(u8 *packet, int length) {
reply.type = req->request_type;
- // skip over each question in the reply
+ /* skip over each question in the reply */
for (i = 0; i < questions; ++i) {
- // the question looks like
- // <label:name><u16:type><u16:class>
+ /* the question looks like
+ * <label:name><u16:type><u16:class>
+ */
SKIP_NAME;
j += 4;
- if (j >= length) return -1;
+ if (j >= length) goto err;
}
- // now we have the answer section which looks like
- // <label:name><u16:type><u16:class><u32:ttl><u16:len><data...>
+ /* now we have the answer section which looks like
+ * <label:name><u16:type><u16:class><u32:ttl><u16:len><data...>
+ */
for (i = 0; i < answers; ++i) {
u16 type, class;
@@ -866,13 +874,13 @@ reply_parse(u8 *packet, int length) {
j += datalength; continue;
}
if ((datalength & 3) != 0) /* not an even number of As. */
- return -1;
+ goto err;
addrcount = datalength >> 2;
addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, (unsigned)addrcount);
ttl_r = MIN(ttl_r, ttl);
- // we only bother with the first four addresses.
- if (j + 4*addrtocopy > length) return -1;
+ /* we only bother with the first four addresses. */
+ if (j + 4*addrtocopy > length) goto err;
memcpy(&reply.data.a.addresses[reply.data.a.addrcount],
packet + j, 4*addrtocopy);
j += 4*addrtocopy;
@@ -885,7 +893,7 @@ reply_parse(u8 *packet, int length) {
}
if (name_parse(packet, length, &j, reply.data.ptr.name,
sizeof(reply.data.ptr.name))<0)
- return -1;
+ goto err;
ttl_r = MIN(ttl_r, ttl);
reply.have_answer = 1;
break;
@@ -895,13 +903,13 @@ reply_parse(u8 *packet, int length) {
j += datalength; continue;
}
if ((datalength & 15) != 0) /* not an even number of AAAAs. */
- return -1;
- addrcount = datalength >> 4; // each address is 16 bytes long
+ goto err;
+ addrcount = datalength >> 4; /* each address is 16 bytes long */
addrtocopy = MIN(MAX_ADDRS - reply.data.aaaa.addrcount, (unsigned)addrcount);
ttl_r = MIN(ttl_r, ttl);
- // we only bother with the first four addresses.
- if (j + 16*addrtocopy > length) return -1;
+ /* we only bother with the first four addresses. */
+ if (j + 16*addrtocopy > length) goto err;
memcpy(&reply.data.aaaa.addresses[reply.data.aaaa.addrcount],
packet + j, 16*addrtocopy);
reply.data.aaaa.addrcount += addrtocopy;
@@ -909,7 +917,7 @@ reply_parse(u8 *packet, int length) {
reply.have_answer = 1;
if (reply.data.aaaa.addrcount == MAX_ADDRS) break;
} else {
- // skip over any other type of resource
+ /* skip over any other type of resource */
j += datalength;
}
}
@@ -917,24 +925,26 @@ reply_parse(u8 *packet, int length) {
reply_handle(req, flags, ttl_r, &reply);
return 0;
err:
+ if (req)
+ reply_handle(req, flags, 0, NULL);
return -1;
}
-// Parse a raw request (packet,length) sent to a nameserver port (port) from
-// a DNS client (addr,addrlen), and if it's well-formed, call the corresponding
-// callback.
+/* Parse a raw request (packet,length) sent to a nameserver port (port) from */
+/* a DNS client (addr,addrlen), and if it's well-formed, call the corresponding */
+/* callback. */
static int
request_parse(u8 *packet, int length, struct evdns_server_port *port, struct sockaddr *addr, socklen_t addrlen)
{
- int j = 0; // index into packet
- u16 _t; // used by the macros
- char tmp_name[256]; // used by the macros
+ int j = 0; /* index into packet */
+ u16 _t; /* used by the macros */
+ char tmp_name[256]; /* used by the macros */
int i;
u16 trans_id, flags, questions, answers, authority, additional;
struct server_request *server_req = NULL;
- // Get the header fields
+ /* Get the header fields */
GET16(trans_id);
GET16(flags);
GET16(questions);
@@ -942,9 +952,9 @@ request_parse(u8 *packet, int length, struct evdns_server_port *port, struct soc
GET16(authority);
GET16(additional);
- if (flags & 0x8000) return -1; // Must not be an answer.
- if (flags & 0x7800) return -1; // only standard queries are supported
- flags &= 0x0300; // Only TC and RD get preserved.
+ if (flags & 0x8000) return -1; /* Must not be an answer. */
+ if (flags & 0x7800) return -1; /* only standard queries are supported */
+ flags &= 0x0300; /* Only TC and RD get preserved. */
server_req = malloc(sizeof(struct server_request));
if (server_req == NULL) return -1;
@@ -978,7 +988,7 @@ request_parse(u8 *packet, int length, struct evdns_server_port *port, struct soc
server_req->base.questions[server_req->base.nquestions++] = q;
}
- // Ignore answers, authority, and additional.
+ /* Ignore answers, authority, and additional. */
server_req->port = port;
port->refcnt++;
@@ -1002,7 +1012,7 @@ err:
#undef GET8
}
-// Try to choose a strong transaction id which isn't already in flight
+/* Try to choose a strong transaction id which isn't already in flight */
static u16
transaction_id_pick(void) {
for (;;) {
@@ -1029,8 +1039,8 @@ transaction_id_pick(void) {
#ifdef DNS_USE_OPENSSL_FOR_ID
u16 trans_id;
if (RAND_pseudo_bytes((u8 *) &trans_id, 2) == -1) {
- /* // in the case that the RAND call fails we back
- // down to using gettimeofday.
+ /* in the case that the RAND call fails we back */
+ /* down to using gettimeofday. */
struct timeval tv;
gettimeofday(&tv, NULL);
trans_id = tv.tv_usec & 0xffff; */
@@ -1039,7 +1049,7 @@ transaction_id_pick(void) {
#endif
if (trans_id == 0xffff) continue;
- // now check to see if that id is already inflight
+ /* now check to see if that id is already inflight */
req = started_at = req_head;
if (req) {
do {
@@ -1047,30 +1057,30 @@ transaction_id_pick(void) {
req = req->next;
} while (req != started_at);
}
- // we didn't find it, so this is a good id
+ /* we didn't find it, so this is a good id */
if (req == started_at) return trans_id;
}
}
-// choose a namesever to use. This function will try to ignore
-// nameservers which we think are down and load balance across the rest
-// by updating the server_head global each time.
+/* choose a namesever to use. This function will try to ignore */
+/* nameservers which we think are down and load balance across the rest */
+/* by updating the server_head global each time. */
static struct nameserver *
nameserver_pick(void) {
struct nameserver *started_at = server_head, *picked;
if (!server_head) return NULL;
- // if we don't have any good nameservers then there's no
- // point in trying to find one.
+ /* if we don't have any good nameservers then there's no */
+ /* point in trying to find one. */
if (!global_good_nameservers) {
server_head = server_head->next;
return server_head;
}
- // remember that nameservers are in a circular list
+ /* remember that nameservers are in a circular list */
for (;;) {
if (server_head->state) {
- // we think this server is currently good
+ /* we think this server is currently good */
picked = server_head;
server_head = server_head->next;
return picked;
@@ -1078,9 +1088,9 @@ nameserver_pick(void) {
server_head = server_head->next;
if (server_head == started_at) {
- // all the nameservers seem to be down
- // so we just return this one and hope for the
- // best
+ /* all the nameservers seem to be down */
+ /* so we just return this one and hope for the */
+ /* best */
assert(global_good_nameservers == 0);
picked = server_head;
server_head = server_head->next;
@@ -1089,7 +1099,7 @@ nameserver_pick(void) {
}
}
-// this is called when a namesever socket is ready for reading
+/* this is called when a namesever socket is ready for reading */
static void
nameserver_read(struct nameserver *ns) {
u8 packet[1500];
@@ -1107,8 +1117,8 @@ nameserver_read(struct nameserver *ns) {
}
}
-// Read a packet from a DNS client on a server port s, parse it, and
-// act accordingly.
+/* Read a packet from a DNS client on a server port s, parse it, and */
+/* act accordingly. */
static void
server_port_read(struct evdns_server_port *s) {
u8 packet[1500];
@@ -1131,7 +1141,7 @@ server_port_read(struct evdns_server_port *s) {
}
}
-// Try to write all pending replies on a given DNS server port.
+/* Try to write all pending replies on a given DNS server port. */
static void
server_port_flush(struct evdns_server_port *port)
{
@@ -1146,24 +1156,24 @@ server_port_flush(struct evdns_server_port *port)
log(EVDNS_LOG_WARN, "Error %s (%d) while writing response to port; dropping", strerror(err), err);
}
if (server_request_free(req)) {
- // we released the last reference to req->port.
+ /* we released the last reference to req->port. */
return;
}
}
- // We have no more pending requests; stop listening for 'writeable' events.
+ /* We have no more pending requests; stop listening for 'writeable' events. */
(void) event_del(&port->event);
event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
server_port_ready_callback, port);
if (event_add(&port->event, NULL) < 0) {
log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server.");
- // ???? Do more?
+ /* ???? Do more? */
}
}
-// set if we are waiting for the ability to write to this server.
-// if waiting is true then we ask libevent for EV_WRITE events, otherwise
-// we stop these events.
+/* set if we are waiting for the ability to write to this server. */
+/* if waiting is true then we ask libevent for EV_WRITE events, otherwise */
+/* we stop these events. */
static void
nameserver_write_waiting(struct nameserver *ns, char waiting) {
if (ns->write_waiting == waiting) return;
@@ -1175,12 +1185,12 @@ nameserver_write_waiting(struct nameserver *ns, char waiting) {
if (event_add(&ns->event, NULL) < 0) {
log(EVDNS_LOG_WARN, "Error from libevent when adding event for %s",
debug_ntoa(ns->address));
- // ???? Do more?
+ /* ???? Do more? */
}
}
-// a callback function. Called by libevent when the kernel says that
-// a nameserver socket is ready for writing or reading
+/* a callback function. Called by libevent when the kernel says that */
+/* a nameserver socket is ready for writing or reading */
static void
nameserver_ready_callback(int fd, short events, void *arg) {
struct nameserver *ns = (struct nameserver *) arg;
@@ -1197,8 +1207,8 @@ nameserver_ready_callback(int fd, short events, void *arg) {
}
}
-// a callback function. Called by libevent when the kernel says that
-// a server socket is ready for writing or reading.
+/* a callback function. Called by libevent when the kernel says that */
+/* a server socket is ready for writing or reading. */
static void
server_port_ready_callback(int fd, short events, void *arg) {
struct evdns_server_port *port = (struct evdns_server_port *) arg;
@@ -1216,22 +1226,22 @@ server_port_ready_callback(int fd, short events, void *arg) {
/* This is an inefficient representation; only use it via the dnslabel_table_*
* functions, so that is can be safely replaced with something smarter later. */
#define MAX_LABELS 128
-// Structures used to implement name compression
-struct dnslabel_entry { char *v; int pos; };
+/* Structures used to implement name compression */
+struct dnslabel_entry { char *v; off_t pos; };
struct dnslabel_table {
- int n_labels; // number of current entries
- // map from name to position in message
+ int n_labels; /* number of current entries */
+ /* map from name to position in message */
struct dnslabel_entry labels[MAX_LABELS];
};
-// Initialize dnslabel_table.
+/* Initialize dnslabel_table. */
static void
dnslabel_table_init(struct dnslabel_table *table)
{
table->n_labels = 0;
}
-// Free all storage held by table, but not the table itself.
+/* Free all storage held by table, but not the table itself. */
static void
dnslabel_clear(struct dnslabel_table *table)
{
@@ -1241,8 +1251,8 @@ dnslabel_clear(struct dnslabel_table *table)
table->n_labels = 0;
}
-// return the position of the label in the current message, or -1 if the label
-// hasn't been used yet.
+/* return the position of the label in the current message, or -1 if the label */
+/* hasn't been used yet. */
static int
dnslabel_table_get_pos(const struct dnslabel_table *table, const char *label)
{
@@ -1254,9 +1264,9 @@ dnslabel_table_get_pos(const struct dnslabel_table *table, const char *label)
return -1;
}
-// remember that we've used the label at position pos
+/* remember that we've used the label at position pos */
static int
-dnslabel_table_add(struct dnslabel_table *table, const char *label, int pos)
+dnslabel_table_add(struct dnslabel_table *table, const char *label, off_t pos)
{
char *v;
int p;
@@ -1272,17 +1282,17 @@ dnslabel_table_add(struct dnslabel_table *table, const char *label, int pos)
return (0);
}
-// Converts a string to a length-prefixed set of DNS labels, starting
-// at buf[j]. name and buf must not overlap. name_len should be the length
-// of name. table is optional, and is used for compression.
-//
-// Input: abc.def
-// Output: <3>abc<3>def<0>
-//
-// Returns the first index after the encoded name, or negative on error.
-// -1 label was > 63 bytes
-// -2 name too long to fit in buffer.
-//
+/* Converts a string to a length-prefixed set of DNS labels, starting */
+/* at buf[j]. name and buf must not overlap. name_len should be the length */
+/* of name. table is optional, and is used for compression. */
+/* */
+/* Input: abc.def */
+/* Output: <3>abc<3>def<0> */
+/* */
+/* Returns the first index after the encoded name, or negative on error. */
+/* -1 label was > 63 bytes */
+/* -2 name too long to fit in buffer. */
+/* */
static off_t
dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j,
const char *name, const int name_len,
@@ -1326,7 +1336,7 @@ dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j,
j += end - start;
break;
} else {
- // append length of the label.
+ /* append length of the label. */
const unsigned int label_len = name - start;
if (label_len > 63) return -1;
if ((size_t)(j+label_len+1) > buf_len) return -2;
@@ -1335,47 +1345,47 @@ dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j,
memcpy(buf + j, start, name - start);
j += name - start;
- // hop over the '.'
+ /* hop over the '.' */
name++;
}
}
- // the labels must be terminated by a 0.
- // It's possible that the name ended in a .
- // in which case the zero is already there
+ /* the labels must be terminated by a 0. */
+ /* It's possible that the name ended in a . */
+ /* in which case the zero is already there */
if (!j || buf[j-1]) buf[j++] = 0;
return j;
overflow:
return (-2);
}
-// Finds the length of a dns request for a DNS name of the given
-// length. The actual request may be smaller than the value returned
-// here
+/* Finds the length of a dns request for a DNS name of the given */
+/* length. The actual request may be smaller than the value returned */
+/* here */
static int
evdns_request_len(const int name_len) {
- return 96 + // length of the DNS standard header
+ return 96 + /* length of the DNS standard header */
name_len + 2 +
- 4; // space for the resource type
+ 4; /* space for the resource type */
}
-// build a dns request packet into buf. buf should be at least as long
-// as evdns_request_len told you it should be.
-//
-// Returns the amount of space used. Negative on error.
+/* build a dns request packet into buf. buf should be at least as long */
+/* as evdns_request_len told you it should be. */
+/* */
+/* Returns the amount of space used. Negative on error. */
static int
evdns_request_data_build(const char *const name, const int name_len,
const u16 trans_id, const u16 type, const u16 class,
u8 *const buf, size_t buf_len) {
- off_t j = 0; // current offset into buf
- u16 _t; // used by the macros
+ off_t j = 0; /* current offset into buf */
+ u16 _t; /* used by the macros */
APPEND16(trans_id);
- APPEND16(0x0100); // standard query, recusion needed
- APPEND16(1); // one question
- APPEND16(0); // no answers
- APPEND16(0); // no authority
- APPEND16(0); // no additional
+ APPEND16(0x0100); /* standard query, recusion needed */
+ APPEND16(1); /* one question */
+ APPEND16(0); /* no answers */
+ APPEND16(0); /* no authority */
+ APPEND16(0); /* no additional */
j = dnsname_to_labels(buf, buf_len, j, name, name_len, NULL);
if (j < 0) {
@@ -1390,7 +1400,7 @@ evdns_request_data_build(const char *const name, const int name_len,
return (-1);
}
-// exported function
+/* exported function */
struct evdns_server_port *
evdns_add_server_port(int socket, int is_tcp, evdns_request_callback_fn_type cb, void *user_data)
{
@@ -1399,7 +1409,7 @@ evdns_add_server_port(int socket, int is_tcp, evdns_request_callback_fn_type cb,
return NULL;
memset(port, 0, sizeof(struct evdns_server_port));
- assert(!is_tcp); // TCP sockets not yet implemented
+ assert(!is_tcp); /* TCP sockets not yet implemented */
port->socket = socket;
port->refcnt = 1;
port->choked = 0;
@@ -1410,11 +1420,11 @@ evdns_add_server_port(int socket, int is_tcp, evdns_request_callback_fn_type cb,
event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
server_port_ready_callback, port);
- event_add(&port->event, NULL); // check return.
+ event_add(&port->event, NULL); /* check return. */
return port;
}
-// exported function
+/* exported function */
void
evdns_close_server_port(struct evdns_server_port *port)
{
@@ -1423,7 +1433,7 @@ evdns_close_server_port(struct evdns_server_port *port)
port->closing = 1;
}
-// exported function
+/* exported function */
int
evdns_server_request_add_reply(struct evdns_server_request *_req, int section, const char *name, int type, int class, int ttl, int datalen, int is_name, const char *data)
{
@@ -1474,7 +1484,7 @@ evdns_server_request_add_reply(struct evdns_server_request *_req, int section, c
free(item);
return -1;
}
- item->datalen = -1;
+ item->datalen = (u16)-1;
} else {
if (!(item->data = malloc(datalen))) {
free(item->name);
@@ -1491,7 +1501,7 @@ evdns_server_request_add_reply(struct evdns_server_request *_req, int section, c
return 0;
}
-// exported function
+/* exported function */
int
evdns_server_request_add_a_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
{
@@ -1500,7 +1510,7 @@ evdns_server_request_add_a_reply(struct evdns_server_request *req, const char *n
ttl, n*4, 0, addrs);
}
-// exported function
+/* exported function */
int
evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
{
@@ -1509,7 +1519,7 @@ evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char
ttl, n*16, 0, addrs);
}
-// exported function
+/* exported function */
int
evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl)
{
@@ -1531,7 +1541,7 @@ evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_a
ttl, -1, 1, hostname);
}
-// exported function
+/* exported function */
int
evdns_server_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl)
{
@@ -1638,7 +1648,7 @@ overflow:
return (0);
}
-// exported function
+/* exported function */
int
evdns_server_request_respond(struct evdns_server_request *_req, int err)
{
@@ -1681,13 +1691,13 @@ evdns_server_request_respond(struct evdns_server_request *_req, int err)
if (server_request_free(req))
return 0;
- if (req->port->pending_replies)
+ if (port->pending_replies)
server_port_flush(port);
return 0;
}
-// Free all storage held by RRs in req.
+/* Free all storage held by RRs in req. */
static void
server_request_free_answers(struct server_request *req)
{
@@ -1714,8 +1724,8 @@ server_request_free_answers(struct server_request *req)
}
}
-// Free all storage held by req, and remove links to it.
-// return true iff we just wound up freeing the server_port.
+/* Free all storage held by req, and remove links to it. */
+/* return true iff we just wound up freeing the server_port. */
static int
server_request_free(struct server_request *req)
{
@@ -1755,7 +1765,7 @@ server_request_free(struct server_request *req)
return (0);
}
-// Free all storage held by an evdns_server_port. Only called when
+/* Free all storage held by an evdns_server_port. Only called when */
static void
server_port_free(struct evdns_server_port *port)
{
@@ -1767,10 +1777,10 @@ server_port_free(struct evdns_server_port *port)
port->socket = -1;
}
(void) event_del(&port->event);
- // XXXX actually free the port? -NM
+ /* XXXX actually free the port? -NM */
}
-// exported function
+/* exported function */
int
evdns_server_request_drop(struct evdns_server_request *_req)
{
@@ -1779,11 +1789,22 @@ evdns_server_request_drop(struct evdns_server_request *_req)
return 0;
}
+/* exported function */
+int
+evdns_server_request_get_requesting_addr(struct evdns_server_request *_req, struct sockaddr *sa, int addr_len)
+{
+ struct server_request *req = TO_SERVER_REQUEST(_req);
+ if (addr_len < (int)req->addrlen)
+ return -1;
+ memcpy(sa, &(req->addr), req->addrlen);
+ return req->addrlen;
+}
+
#undef APPEND16
#undef APPEND32
-// this is a libevent callback function which is called when a request
-// has timed out.
+/* this is a libevent callback function which is called when a request */
+/* has timed out. */
static void
evdns_request_timeout_callback(int fd, short events, void *arg) {
struct request *const req = (struct request *) arg;
@@ -1800,21 +1821,21 @@ evdns_request_timeout_callback(int fd, short events, void *arg) {
(void) evtimer_del(&req->timeout_event);
if (req->tx_count >= global_max_retransmits) {
- // this request has failed
+ /* this request has failed */
reply_callback(req, 0, DNS_ERR_TIMEOUT, NULL);
request_finished(req, &req_head);
} else {
- // retransmit it
+ /* retransmit it */
evdns_request_transmit(req);
}
}
-// try to send a request to a given server.
-//
-// return:
-// 0 ok
-// 1 temporary failure
-// 2 other failure
+/* try to send a request to a given server. */
+/* */
+/* return: */
+/* 0 ok */
+/* 1 temporary failure */
+/* 2 other failure */
static int
evdns_request_transmit_to(struct request *req, struct nameserver *server) {
const int r = send(server->socket, req->request, req->request_len, 0);
@@ -1824,46 +1845,46 @@ evdns_request_transmit_to(struct request *req, struct nameserver *server) {
nameserver_failed(req->ns, strerror(err));
return 2;
} else if (r != (int)req->request_len) {
- return 1; // short write
+ return 1; /* short write */
} else {
return 0;
}
}
-// try to send a request, updating the fields of the request
-// as needed
-//
-// return:
-// 0 ok
-// 1 failed
+/* try to send a request, updating the fields of the request */
+/* as needed */
+/* */
+/* return: */
+/* 0 ok */
+/* 1 failed */
static int
evdns_request_transmit(struct request *req) {
int retcode = 0, r;
- // if we fail to send this packet then this flag marks it
- // for evdns_transmit
+ /* if we fail to send this packet then this flag marks it */
+ /* for evdns_transmit */
req->transmit_me = 1;
if (req->trans_id == 0xffff) abort();
if (req->ns->choked) {
- // don't bother trying to write to a socket
- // which we have had EAGAIN from
+ /* don't bother trying to write to a socket */
+ /* which we have had EAGAIN from */
return 1;
}
r = evdns_request_transmit_to(req, req->ns);
switch (r) {
case 1:
- // temp failure
+ /* temp failure */
req->ns->choked = 1;
nameserver_write_waiting(req->ns, 1);
return 1;
case 2:
- // failed in some other way
+ /* failed in some other way */
retcode = 1;
- // fall through
+ /* fall through */
default:
- // all ok
+ /* all ok */
log(EVDNS_LOG_DEBUG,
"Setting timeout for request %lx", (unsigned long) req);
evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
@@ -1871,7 +1892,7 @@ evdns_request_transmit(struct request *req) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer for request %lx",
(unsigned long) req);
- // ???? Do more?
+ /* ???? Do more? */
}
req->tx_count++;
req->transmit_me = 0;
@@ -1888,7 +1909,7 @@ nameserver_probe_callback(int result, char type, int count, int ttl, void *addre
(void) addresses;
if (result == DNS_ERR_NONE || result == DNS_ERR_NOTEXIST) {
- // this is a good reply
+ /* this is a good reply */
nameserver_up(ns);
} else nameserver_probe_failed(ns);
}
@@ -1896,29 +1917,29 @@ nameserver_probe_callback(int result, char type, int count, int ttl, void *addre
static void
nameserver_send_probe(struct nameserver *const ns) {
struct request *req;
- // here we need to send a probe to a given nameserver
- // in the hope that it is up now.
+ /* here we need to send a probe to a given nameserver */
+ /* in the hope that it is up now. */
log(EVDNS_LOG_DEBUG, "Sending probe to %s", debug_ntoa(ns->address));
req = request_new(TYPE_A, "www.google.com", DNS_QUERY_NO_SEARCH, nameserver_probe_callback, ns);
if (!req) return;
- // we force this into the inflight queue no matter what
+ /* we force this into the inflight queue no matter what */
request_trans_id_set(req, transaction_id_pick());
req->ns = ns;
request_submit(req);
}
-// returns:
-// 0 didn't try to transmit anything
-// 1 tried to transmit something
+/* returns: */
+/* 0 didn't try to transmit anything */
+/* 1 tried to transmit something */
static int
evdns_transmit(void) {
char did_try_to_transmit = 0;
if (req_head) {
struct request *const started_at = req_head, *req = req_head;
- // first transmit all the requests which are currently waiting
+ /* first transmit all the requests which are currently waiting */
do {
if (req->transmit_me) {
did_try_to_transmit = 1;
@@ -1932,7 +1953,7 @@ evdns_transmit(void) {
return did_try_to_transmit;
}
-// exported function
+/* exported function */
int
evdns_count_nameservers(void)
{
@@ -1947,7 +1968,7 @@ evdns_count_nameservers(void)
return n;
}
-// exported function
+/* exported function */
int
evdns_clear_nameservers_and_suspend(void)
{
@@ -1974,7 +1995,7 @@ evdns_clear_nameservers_and_suspend(void)
struct request *next = req->next;
req->tx_count = req->reissue_count = 0;
req->ns = NULL;
- // ???? What to do about searches?
+ /* ???? What to do about searches? */
(void) evtimer_del(&req->timeout_event);
req->trans_id = 0;
req->transmit_me = 0;
@@ -1998,7 +2019,7 @@ evdns_clear_nameservers_and_suspend(void)
}
-// exported function
+/* exported function */
int
evdns_resume(void)
{
@@ -2008,7 +2029,7 @@ evdns_resume(void)
static int
_evdns_nameserver_add_impl(unsigned long int address, int port) {
- // first check to see if we already have this nameserver
+ /* first check to see if we already have this nameserver */
const struct nameserver *server = server_head, *const started_at = server_head;
struct nameserver *ns;
@@ -2054,7 +2075,7 @@ _evdns_nameserver_add_impl(unsigned long int address, int port) {
log(EVDNS_LOG_DEBUG, "Added nameserver %s", debug_ntoa(address));
- // insert this nameserver into the list of them
+ /* insert this nameserver into the list of them */
if (!server_head) {
ns->next = ns->prev = ns;
server_head = ns;
@@ -2079,13 +2100,13 @@ out1:
return err;
}
-// exported function
+/* exported function */
int
evdns_nameserver_add(unsigned long int address) {
return _evdns_nameserver_add_impl(address, 53);
}
-// exported function
+/* exported function */
int
evdns_nameserver_ip_add(const char *ip_as_string) {
struct in_addr ina;
@@ -2114,7 +2135,7 @@ evdns_nameserver_ip_add(const char *ip_as_string) {
return _evdns_nameserver_add_impl(ina.s_addr, port);
}
-// insert into the tail of the queue
+/* insert into the tail of the queue */
static void
evdns_request_insert(struct request *req, struct request **head) {
if (!*head) {
@@ -2148,7 +2169,7 @@ request_new(int type, const char *name, int flags,
const int name_len = strlen(name);
const int request_max_len = evdns_request_len(name_len);
const u16 trans_id = issuing_now ? transaction_id_pick() : 0xffff;
- // the request data is alloced in a single block with the header
+ /* the request data is alloced in a single block with the header */
struct request *const req =
(struct request *) malloc(sizeof(struct request) + request_max_len);
int rlen;
@@ -2157,9 +2178,9 @@ request_new(int type, const char *name, int flags,
if (!req) return NULL;
memset(req, 0, sizeof(struct request));
- // request data lives just after the header
+ /* request data lives just after the header */
req->request = ((u8 *) req) + sizeof(struct request);
- // denotes that the request data shouldn't be free()ed
+ /* denotes that the request data shouldn't be free()ed */
req->request_appended = 1;
rlen = evdns_request_data_build(name, name_len, trans_id,
type, CLASS_INET, req->request, request_max_len);
@@ -2183,8 +2204,8 @@ err1:
static void
request_submit(struct request *const req) {
if (req->ns) {
- // if it has a nameserver assigned then this is going
- // straight into the inflight queue
+ /* if it has a nameserver assigned then this is going */
+ /* straight into the inflight queue */
evdns_request_insert(req, &req_head);
global_requests_inflight++;
evdns_request_transmit(req);
@@ -2194,7 +2215,7 @@ request_submit(struct request *const req) {
}
}
-// exported function
+/* exported function */
int evdns_resolve_ipv4(const char *name, int flags,
evdns_callback_type callback, void *ptr) {
log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
@@ -2210,7 +2231,7 @@ int evdns_resolve_ipv4(const char *name, int flags,
}
}
-// exported function
+/* exported function */
int evdns_resolve_ipv6(const char *name, int flags,
evdns_callback_type callback, void *ptr) {
log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
@@ -2267,23 +2288,23 @@ int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_ty
return 0;
}
-/////////////////////////////////////////////////////////////////////
-// Search support
-//
-// the libc resolver has support for searching a number of domains
-// to find a name. If nothing else then it takes the single domain
-// from the gethostname() call.
-//
-// It can also be configured via the domain and search options in a
-// resolv.conf.
-//
-// The ndots option controls how many dots it takes for the resolver
-// to decide that a name is non-local and so try a raw lookup first.
+/*/////////////////////////////////////////////////////////////////// */
+/* Search support */
+/* */
+/* the libc resolver has support for searching a number of domains */
+/* to find a name. If nothing else then it takes the single domain */
+/* from the gethostname() call. */
+/* */
+/* It can also be configured via the domain and search options in a */
+/* resolv.conf. */
+/* */
+/* The ndots option controls how many dots it takes for the resolver */
+/* to decide that a name is non-local and so try a raw lookup first. */
struct search_domain {
int len;
struct search_domain *next;
- // the text string is appended to this structure
+ /* the text string is appended to this structure */
};
struct search_state {
@@ -2327,7 +2348,7 @@ search_postfix_clear(void) {
global_search_state = search_state_new();
}
-// exported function
+/* exported function */
void
evdns_search_clear(void) {
search_postfix_clear();
@@ -2353,8 +2374,8 @@ search_postfix_add(const char *domain) {
global_search_state->head = sdomain;
}
-// reverse the order of members in the postfix list. This is needed because,
-// when parsing resolv.conf we push elements in the wrong order
+/* reverse the order of members in the postfix list. This is needed because, */
+/* when parsing resolv.conf we push elements in the wrong order */
static void
search_reverse(void) {
struct search_domain *cur, *prev = NULL, *next;
@@ -2369,13 +2390,13 @@ search_reverse(void) {
global_search_state->head = prev;
}
-// exported function
+/* exported function */
void
evdns_search_add(const char *domain) {
search_postfix_add(domain);
}
-// exported function
+/* exported function */
void
evdns_search_ndots_set(const int ndots) {
if (!global_search_state) global_search_state = search_state_new();
@@ -2394,7 +2415,7 @@ search_set_from_hostname(void) {
search_postfix_add(domainname);
}
-// warning: returns malloced string
+/* warning: returns malloced string */
static char *
search_make_new(const struct search_state *const state, int n, const char *const base_name) {
const int base_len = strlen(base_name);
@@ -2403,8 +2424,8 @@ search_make_new(const struct search_state *const state, int n, const char *const
for (dom = state->head; dom; dom = dom->next) {
if (!n--) {
- // this is the postfix we want
- // the actual postfix string is kept at the end of the structure
+ /* this is the postfix we want */
+ /* the actual postfix string is kept at the end of the structure */
const u8 *const postfix = ((u8 *) dom) + sizeof(struct search_domain);
const int postfix_len = dom->len;
char *const newname = (char *) malloc(base_len + need_to_append_dot + postfix_len + 1);
@@ -2417,7 +2438,7 @@ search_make_new(const struct search_state *const state, int n, const char *const
}
}
- // we ran off the end of the list and still didn't find the requested string
+ /* we ran off the end of the list and still didn't find the requested string */
abort();
return NULL; /* unreachable; stops warnings in some compilers. */
}
@@ -2428,7 +2449,7 @@ search_request_new(int type, const char *const name, int flags, evdns_callback_t
if ( ((flags & DNS_QUERY_NO_SEARCH) == 0) &&
global_search_state &&
global_search_state->num_domains) {
- // we have some domains to search
+ /* we have some domains to search */
struct request *req;
if (string_num_dots(name) >= global_search_state->ndots) {
req = request_new(type, name, flags, user_callback, user_arg);
@@ -2456,23 +2477,23 @@ search_request_new(int type, const char *const name, int flags, evdns_callback_t
}
}
-// this is called when a request has failed to find a name. We need to check
-// if it is part of a search and, if so, try the next name in the list
-// returns:
-// 0 another request has been submitted
-// 1 no more requests needed
+/* this is called when a request has failed to find a name. We need to check */
+/* if it is part of a search and, if so, try the next name in the list */
+/* returns: */
+/* 0 another request has been submitted */
+/* 1 no more requests needed */
static int
search_try_next(struct request *const req) {
if (req->search_state) {
- // it is part of a search
+ /* it is part of a search */
char *new_name;
struct request *newreq;
req->search_index++;
if (req->search_index >= req->search_state->num_domains) {
- // no more postfixes to try, however we may need to try
- // this name without a postfix
+ /* no more postfixes to try, however we may need to try */
+ /* this name without a postfix */
if (string_num_dots(req->search_origname) < req->search_state->ndots) {
- // yep, we need to try it raw
+ /* yep, we need to try it raw */
struct request *const newreq = request_new(req->request_type, req->search_origname, req->search_flags, req->user_callback, req->user_pointer);
log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", req->search_origname);
if (newreq) {
@@ -2513,12 +2534,12 @@ search_request_finished(struct request *const req) {
}
}
-/////////////////////////////////////////////////////////////////////
-// Parsing resolv.conf files
+/*/////////////////////////////////////////////////////////////////// */
+/* Parsing resolv.conf files */
static void
evdns_resolv_set_defaults(int flags) {
- // if the file isn't found then we assume a local resolver
+ /* if the file isn't found then we assume a local resolver */
if (flags & DNS_OPTION_SEARCH) search_set_from_hostname();
if (flags & DNS_OPTION_NAMESERVERS) evdns_nameserver_ip_add("127.0.0.1");
}
@@ -2530,7 +2551,7 @@ strtok_r(char *s, const char *delim, char **state) {
}
#endif
-// helper version of atoi which returns -1 on error
+/* helper version of atoi which returns -1 on error */
static int
strtoint(const char *const str) {
char *endptr;
@@ -2539,7 +2560,7 @@ strtoint(const char *const str) {
return r;
}
-// helper version of atoi that returns -1 on error and clips to bounds.
+/* helper version of atoi that returns -1 on error and clips to bounds. */
static int
strtoint_clipped(const char *const str, int min, int max)
{
@@ -2554,7 +2575,7 @@ strtoint_clipped(const char *const str, int min, int max)
return r;
}
-// exported function
+/* exported function */
int
evdns_set_option(const char *option, const char *val, int flags)
{
@@ -2611,7 +2632,7 @@ resolv_conf_parse_line(char *const start, int flags) {
struct in_addr ina;
if (inet_aton(nameserver, &ina)) {
- // address is valid
+ /* address is valid */
evdns_nameserver_add(ina.s_addr);
}
} else if (!strcmp(first_token, "domain") && (flags & DNS_OPTION_SEARCH)) {
@@ -2638,18 +2659,18 @@ resolv_conf_parse_line(char *const start, int flags) {
#undef NEXT_TOKEN
}
-// exported function
-// returns:
-// 0 no errors
-// 1 failed to open file
-// 2 failed to stat file
-// 3 file too large
-// 4 out of memory
-// 5 short read from file
+/* exported function */
+/* returns: */
+/* 0 no errors */
+/* 1 failed to open file */
+/* 2 failed to stat file */
+/* 3 file too large */
+/* 4 out of memory */
+/* 5 short read from file */
int
evdns_resolv_conf_parse(int flags, const char *const filename) {
struct stat st;
- int fd;
+ int fd, n, r;
u8 *resolv;
char *start;
int err = 0;
@@ -2668,15 +2689,20 @@ evdns_resolv_conf_parse(int flags, const char *const filename) {
err = (flags & DNS_OPTION_NAMESERVERS) ? 6 : 0;
goto out1;
}
- if (st.st_size > 65535) { err = 3; goto out1; } // no resolv.conf should be any bigger
+ if (st.st_size > 65535) { err = 3; goto out1; } /* no resolv.conf should be any bigger */
resolv = (u8 *) malloc((size_t)st.st_size + 1);
if (!resolv) { err = 4; goto out1; }
- if (read(fd, resolv, (size_t)st.st_size) != st.st_size) {
- err = 5; goto out2;
- }
- resolv[st.st_size] = 0; // we malloced an extra byte
+ n = 0;
+ while ((r = read(fd, resolv+n, (size_t)st.st_size-n)) > 0) {
+ n += r;
+ if (n == st.st_size)
+ break;
+ assert(n < st.st_size);
+ }
+ if (r < 0) { err = 5; goto out2; }
+ resolv[n] = 0; /* we malloced an extra byte; this should be fine. */
start = (char *) resolv;
for (;;) {
@@ -2692,7 +2718,7 @@ evdns_resolv_conf_parse(int flags, const char *const filename) {
}
if (!server_head && (flags & DNS_OPTION_NAMESERVERS)) {
- // no nameservers were configured.
+ /* no nameservers were configured. */
evdns_nameserver_ip_add("127.0.0.1");
err = 6;
}
@@ -2708,7 +2734,7 @@ out1:
}
#ifdef WIN32
-// Add multiple nameservers from a space-or-comma-separated list.
+/* Add multiple nameservers from a space-or-comma-separated list. */
static int
evdns_nameserver_ip_add_line(const char *ips) {
const char *addr;
@@ -2733,12 +2759,12 @@ evdns_nameserver_ip_add_line(const char *ips) {
typedef DWORD(WINAPI *GetNetworkParams_fn_t)(FIXED_INFO *, DWORD*);
-// Use the windows GetNetworkParams interface in iphlpapi.dll to
-// figure out what our nameservers are.
+/* Use the windows GetNetworkParams interface in iphlpapi.dll to */
+/* figure out what our nameservers are. */
static int
load_nameservers_with_getnetworkparams(void)
{
- // Based on MSDN examples and inspection of c-ares code.
+ /* Based on MSDN examples and inspection of c-ares code. */
FIXED_INFO *fixed;
HMODULE handle = 0;
ULONG size = sizeof(FIXED_INFO);
@@ -2954,6 +2980,8 @@ evdns_shutdown(int fail_requests)
if (server->socket >= 0)
CLOSE_SOCKET(server->socket);
(void) event_del(&server->event);
+ if (server->state == 0)
+ (void) event_del(&server->timeout_event);
free(server);
if (server_next == server_head)
break;
diff --git a/evdns.h b/evdns.h
index 0c4547c8..af7962e1 100644
--- a/evdns.h
+++ b/evdns.h
@@ -361,5 +361,7 @@ int evdns_server_request_add_cname_reply(struct evdns_server_request *req, const
int evdns_server_request_respond(struct evdns_server_request *req, int err);
int evdns_server_request_drop(struct evdns_server_request *req);
+struct sockaddr;
+int evdns_server_request_get_requesting_addr(struct evdns_server_request *_req, struct sockaddr *sa, int addr_len);
-#endif // !EVENTDNS_H
+#endif /* !EVENTDNS_H */
diff --git a/event-internal.h b/event-internal.h
index becb6691..7fd4b6c6 100644
--- a/event-internal.h
+++ b/event-internal.h
@@ -31,6 +31,8 @@
extern "C" {
#endif
+#include "evsignal.h"
+
struct event_base {
const struct eventop *evsel;
void *evbase;
@@ -43,6 +45,9 @@ struct event_base {
struct event_list **activequeues;
int nactivequeues;
+ /* signal handling info */
+ struct evsignal_info sig;
+
struct event_list eventqueue;
struct timeval event_tv;
diff --git a/event.3 b/event.3
index 132c30f0..a6648e9a 100644
--- a/event.3
+++ b/event.3
@@ -39,9 +39,11 @@
.Nm event_base_loop ,
.Nm event_base_loopexit ,
.Nm event_base_set ,
+.Nm event_base_free ,
.Nm event_add ,
.Nm event_del ,
.Nm event_once ,
+.Nm event_base_once ,
.Nm event_pending ,
.Nm event_initialized ,
.Nm event_priority_init ,
@@ -83,9 +85,9 @@
.Fd #include <sys/time.h>
.Fd #include <event.h>
.Ft "struct event_base *"
-.Fn "event_init"
+.Fn "event_init" "void"
.Ft int
-.Fn "event_dispatch"
+.Fn "event_dispatch" "void"
.Ft int
.Fn "event_loop" "int flags"
.Ft int
@@ -100,6 +102,8 @@
.Fn "event_base_loopexit" "struct event_base *base" "struct timeval *tv"
.Ft int
.Fn "event_base_set" "struct event_base *base" "struct event *"
+.Ft void
+.Fn "event_base_free" "struct event_base *base"
.Ft int
.Fn "event_add" "struct event *ev" "struct timeval *tv"
.Ft int
@@ -107,6 +111,8 @@
.Ft int
.Fn "event_once" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv"
.Ft int
+.Fn "event_base_once" "struct event_base *base" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv"
+.Ft int
.Fn "event_pending" "struct event *ev" "short event" "struct timeval *tv"
.Ft int
.Fn "event_initialized" "struct event *ev"
@@ -157,11 +163,11 @@
.Ft void
.Fn "evbuffer_free" "struct evbuffer *buf"
.Ft int
-.Fn "evbuffer_add" "struct evbuffer *buf" "u_char *data" "size_t size"
+.Fn "evbuffer_add" "struct evbuffer *buf" "const void *data" "size_t size"
.Ft int
.Fn "evbuffer_add_buffer" "struct evbuffer *dst" "struct evbuffer *src"
.Ft int
-.Fn "evbuffer_add_printf" "struct evbuffer *buf" "char *fmt" "..."
+.Fn "evbuffer_add_printf" "struct evbuffer *buf" "const char *fmt" "..."
.Ft int
.Fn "evbuffer_add_vprintf" "struct evbuffer *buf" "const char *fmt" "va_list ap"
.Ft void
@@ -171,7 +177,7 @@
.Ft int
.Fn "evbuffer_read" "struct evbuffer *buf" "int fd" "int size"
.Ft "u_char *"
-.Fn "evbuffer_find" "struct evbuffer *buf" "u_char *data" "size_t size"
+.Fn "evbuffer_find" "struct evbuffer *buf" "const u_char *data" "size_t size"
.Ft "char *"
.Fn "evbuffer_readline" "struct evbuffer *buf"
.Ft "struct evhttp *"
@@ -180,7 +186,7 @@
.Fn "evhttp_free" "struct evhttp* http"
.Ft int
.Fa (*event_sigcb)(void) ;
-.Ft int
+.Ft volatile sig_atomic_t
.Fa event_gotsig ;
.Sh DESCRIPTION
The
@@ -217,7 +223,7 @@ After the signal handler sets
.Nm event_dispatch
will execute the callback function to process received signals.
The callback returns 1 when no events are registered any more.
-It can return -1 to indicate an error to the
+It can return \-1 to indicate an error to the
.Nm event
library, causing
.Fn event_dispatch
@@ -453,8 +459,9 @@ This event base can be used in conjunction with calls to
.Fn event_base_dispatch ,
.Fn event_base_loop ,
.Fn event_base_loopexit ,
+.Fn bufferevent_base_set
and
-.Fn bufferevent_base_set .
+.Fn event_base_free .
.Fn event_base_set
should be called after preparing an event with
.Fn event_set ,
@@ -464,6 +471,9 @@ assigns the provided event to the most recently created event base.
.Fn bufferevent_base_set
should be called after preparing a bufferevent with
.Fn bufferevent_new .
+.Fn event_base_free
+should be used to free memory associated with the event base
+when it is no longer needed.
.Sh BUFFERED EVENTS
.Nm libevent
provides an abstraction on top of the regular event callbacks.
@@ -497,14 +507,15 @@ Both the read and the write callback may be NULL.
The error callback has to be always provided.
.Pp
Once initialized, the bufferevent structure can be used repeatedly with
-bufferevent_enable() and bufferevent_disable(). The flags parameter can
-be a combination of
+bufferevent_enable() and bufferevent_disable().
+The flags parameter can be a combination of
.Va EV_READ
and
.Va EV_WRITE .
-When read enabled the bufferevent will try to read from the file
-descriptor and call the read callback. The write callback is executed
-whenever the output buffer is drained below the write low watermark,
+When read enabled the bufferevent will try to read from the file
+descriptor and call the read callback.
+The write callback is executed
+whenever the output buffer is drained below the write low watermark,
which is
.Va 0
by default.
@@ -514,10 +525,12 @@ The
function can be used to write data to the file descriptor.
The data is appended to the output buffer and written to the descriptor
automatically as it becomes available for writing.
+.Fn bufferevent_write
+returns 0 on success or \-1 on failure.
The
.Fn bufferevent_read
-function is used to read data from the input buffer.
-Both functions return the amount of data written or read.
+function is used to read data from the input buffer,
+returning the amount of data read.
.Pp
If multiple bases are in use, bufferevent_base_set() must be called before
enabling the bufferevent for the first time.
@@ -537,9 +550,9 @@ This can be done by calling
The second argument is the URI for which a callback is being registered.
The corresponding callback will receive an
.Va struct evhttp_request
-object that contains all information about the request.
+object that contains all information about the request.
.Pp
-This section does not document all the possible function calls, please
+This section does not document all the possible function calls; please
check
.Va event.h
for the public interfaces.
@@ -555,6 +568,7 @@ set to indicate the error.
.Xr kqueue 2 ,
.Xr poll 2 ,
.Xr select 2 ,
+.Xr evdns 3 ,
.Xr timeout 9
.Sh HISTORY
The
diff --git a/event.c b/event.c
index f6d2b1cc..2af11a7d 100644
--- a/event.c
+++ b/event.c
@@ -51,6 +51,7 @@
#include <signal.h>
#include <string.h>
#include <assert.h>
+#include <time.h>
#include "event.h"
#include "event-internal.h"
@@ -111,9 +112,9 @@ const struct eventop *eventops[] = {
};
/* Global state */
-struct event_list signalqueue;
-
struct event_base *current_base = NULL;
+extern struct event_base *evsignal_base;
+static int use_monotonic;
/* Handle signals - This is a deprecated interface */
int (*event_sigcb)(void); /* Signal callback when gotsig is set */
@@ -126,7 +127,7 @@ static int event_haveevents(struct event_base *);
static void event_process_active(struct event_base *);
-static int timeout_next(struct event_base *, struct timeval *);
+static int timeout_next(struct event_base *, struct timeval **);
static void timeout_process(struct event_base *);
static void timeout_correct(struct event_base *, struct timeval *);
@@ -144,25 +145,34 @@ compare(struct event *a, struct event *b)
return (0);
}
+static void
+detect_monotonic(void)
+{
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ struct timespec ts;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
+ use_monotonic = 1;
+#endif
+}
+
static int
gettime(struct timeval *tp)
{
-#ifdef HAVE_CLOCK_GETTIME
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
struct timespec ts;
-#ifdef HAVE_CLOCK_MONOTONIC
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
-#else
- if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
-#endif
- return (-1);
- tp->tv_sec = ts.tv_sec;
- tp->tv_usec = ts.tv_nsec / 1000;
-#else
- gettimeofday(tp, NULL);
+ if (use_monotonic) {
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
+ return (-1);
+
+ tp->tv_sec = ts.tv_sec;
+ tp->tv_usec = ts.tv_nsec / 1000;
+ return (0);
+ }
#endif
- return (0);
+ return (gettimeofday(tp, NULL));
}
RB_PROTOTYPE(event_tree, event, ev_timeout_node, compare);
@@ -174,36 +184,42 @@ void *
event_init(void)
{
int i;
+ struct event_base *base;
- if ((current_base = calloc(1, sizeof(struct event_base))) == NULL)
+ if ((base = calloc(1, sizeof(struct event_base))) == NULL)
event_err(1, "%s: calloc");
event_sigcb = NULL;
event_gotsig = 0;
- gettime(&current_base->event_tv);
+
+ detect_monotonic();
+ gettime(&base->event_tv);
- RB_INIT(&current_base->timetree);
- TAILQ_INIT(&current_base->eventqueue);
- TAILQ_INIT(&signalqueue);
+ RB_INIT(&base->timetree);
+ TAILQ_INIT(&base->eventqueue);
+ TAILQ_INIT(&base->sig.signalqueue);
+ base->sig.ev_signal_pair[0] = -1;
+ base->sig.ev_signal_pair[1] = -1;
- current_base->evbase = NULL;
- for (i = 0; eventops[i] && !current_base->evbase; i++) {
- current_base->evsel = eventops[i];
+ base->evbase = NULL;
+ for (i = 0; eventops[i] && !base->evbase; i++) {
+ base->evsel = eventops[i];
- current_base->evbase = current_base->evsel->init();
+ base->evbase = base->evsel->init(base);
}
- if (current_base->evbase == NULL)
+ if (base->evbase == NULL)
event_errx(1, "%s: no event mechanism available", __func__);
if (getenv("EVENT_SHOW_METHOD"))
event_msgx("libevent using: %s\n",
- current_base->evsel->name);
+ base->evsel->name);
/* allocate a single active event queue */
- event_base_priority_init(current_base, 1);
+ event_base_priority_init(base, 1);
- return (current_base);
+ current_base = base;
+ return (base);
}
void
@@ -217,7 +233,8 @@ event_base_free(struct event_base *base)
current_base = NULL;
assert(base);
- assert(TAILQ_EMPTY(&base->eventqueue));
+ if (base->evsel->dealloc != NULL)
+ base->evsel->dealloc(base, base->evbase);
for (i=0; i < base->nactivequeues; ++i)
assert(TAILQ_EMPTY(base->activequeues[i]));
@@ -227,8 +244,7 @@ event_base_free(struct event_base *base)
free(base->activequeues[i]);
free(base->activequeues);
- if (base->evsel->dealloc != NULL)
- base->evsel->dealloc(base->evbase);
+ assert(TAILQ_EMPTY(&base->eventqueue));
free(base);
}
@@ -343,7 +359,6 @@ event_loopexit_cb(int fd, short what, void *arg)
}
/* not thread safe */
-
int
event_loopexit(struct timeval *tv)
{
@@ -354,7 +369,7 @@ event_loopexit(struct timeval *tv)
int
event_base_loopexit(struct event_base *event_base, struct timeval *tv)
{
- return (event_once(-1, EV_TIMEOUT, event_loopexit_cb,
+ return (event_base_once(event_base, -1, EV_TIMEOUT, event_loopexit_cb,
event_base, tv));
}
@@ -372,8 +387,11 @@ event_base_loop(struct event_base *base, int flags)
const struct eventop *evsel = base->evsel;
void *evbase = base->evbase;
struct timeval tv;
+ struct timeval *tv_p;
int res, done;
+ if(!TAILQ_EMPTY(&base->sig.signalqueue))
+ evsignal_base = base;
done = 0;
while (!done) {
/* Calculate the initial events that we are waiting for */
@@ -398,21 +416,18 @@ event_base_loop(struct event_base *base, int flags)
}
}
- /* Check if time is running backwards */
- gettime(&tv);
- if (timercmp(&tv, &base->event_tv, <)) {
- struct timeval off;
- event_debug(("%s: time is running backwards, corrected",
- __func__));
- timersub(&base->event_tv, &tv, &off);
- timeout_correct(base, &off);
- }
- base->event_tv = tv;
+ timeout_correct(base, &tv);
- if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK))
- timeout_next(base, &tv);
- else
+ tv_p = &tv;
+ if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK)) {
+ timeout_next(base, &tv_p);
+ } else {
+ /*
+ * if we have active events, we just poll new events
+ * without waiting.
+ */
timerclear(&tv);
+ }
/* If we have no events, we just exit */
if (!event_haveevents(base)) {
@@ -420,7 +435,8 @@ event_base_loop(struct event_base *base, int flags)
return (1);
}
- res = evsel->dispatch(base, evbase, &tv);
+ res = evsel->dispatch(base, evbase, tv_p);
+
if (res == -1)
return (-1);
@@ -459,12 +475,19 @@ event_once_cb(int fd, short events, void *arg)
free(eonce);
}
-/* Schedules an event once */
-
+/* not threadsafe, event scheduled once. */
int
event_once(int fd, short events,
void (*callback)(int, short, void *), void *arg, struct timeval *tv)
{
+ return event_base_once(current_base, fd, events, callback, arg, tv);
+}
+
+/* Schedules an event once */
+int
+event_base_once(struct event_base *base, int fd, short events,
+ void (*callback)(int, short, void *), void *arg, struct timeval *tv)
+{
struct event_once *eonce;
struct timeval etv;
int res;
@@ -496,7 +519,9 @@ event_once(int fd, short events,
return (-1);
}
- res = event_add(&eonce->ev, tv);
+ res = event_base_set(base, &eonce->ev);
+ if (res == 0)
+ res = event_add(&eonce->ev, tv);
if (res != 0) {
free(eonce);
return (res);
@@ -516,12 +541,14 @@ event_set(struct event *ev, int fd, short events,
ev->ev_arg = arg;
ev->ev_fd = fd;
ev->ev_events = events;
+ ev->ev_res = 0;
ev->ev_flags = EVLIST_INIT;
ev->ev_ncalls = 0;
ev->ev_pncalls = NULL;
/* by default, we put new events into the middle priority */
- ev->ev_pri = current_base->nactivequeues/2;
+ if(current_base)
+ ev->ev_pri = current_base->nactivequeues/2;
}
int
@@ -710,16 +737,16 @@ event_active(struct event *ev, int res, short ncalls)
event_queue_insert(ev->ev_base, ev, EVLIST_ACTIVE);
}
-int
-timeout_next(struct event_base *base, struct timeval *tv)
+static int
+timeout_next(struct event_base *base, struct timeval **tv_p)
{
- struct timeval dflt = TIMEOUT_DEFAULT;
-
struct timeval now;
struct event *ev;
+ struct timeval *tv = *tv_p;
if ((ev = RB_MIN(event_tree, &base->timetree)) == NULL) {
- *tv = dflt;
+ /* if no time-based events are active wait for I/O */
+ *tv_p = NULL;
return (0);
}
@@ -740,17 +767,38 @@ timeout_next(struct event_base *base, struct timeval *tv)
return (0);
}
+/*
+ * Determines if the time is running backwards by comparing the current
+ * time against the last time we checked. Not needed when using clock
+ * monotonic.
+ */
+
static void
-timeout_correct(struct event_base *base, struct timeval *off)
+timeout_correct(struct event_base *base, struct timeval *tv)
{
struct event *ev;
+ struct timeval off;
+
+ if (use_monotonic)
+ return;
+
+ /* Check if time is running backwards */
+ gettime(tv);
+ if (timercmp(tv, &base->event_tv, >=)) {
+ base->event_tv = *tv;
+ return;
+ }
+
+ event_debug(("%s: time is running backwards, corrected",
+ __func__));
+ timersub(&base->event_tv, tv, &off);
/*
* We can modify the key element of the node without destroying
* the key, beause we apply it to all in the right order.
*/
RB_FOREACH(ev, event_tree, &base->timetree)
- timersub(&ev->ev_timeout, off, &ev->ev_timeout);
+ timersub(&ev->ev_timeout, &off, &ev->ev_timeout);
}
void
@@ -801,7 +849,7 @@ event_queue_remove(struct event_base *base, struct event *ev, int queue)
ev, ev_active_next);
break;
case EVLIST_SIGNAL:
- TAILQ_REMOVE(&signalqueue, ev, ev_signal_next);
+ TAILQ_REMOVE(&base->sig.signalqueue, ev, ev_signal_next);
break;
case EVLIST_TIMEOUT:
RB_REMOVE(event_tree, &base->timetree, ev);
@@ -843,7 +891,7 @@ event_queue_insert(struct event_base *base, struct event *ev, int queue)
ev,ev_active_next);
break;
case EVLIST_SIGNAL:
- TAILQ_INSERT_TAIL(&signalqueue, ev, ev_signal_next);
+ TAILQ_INSERT_TAIL(&base->sig.signalqueue, ev, ev_signal_next);
break;
case EVLIST_TIMEOUT: {
struct event *tmp = RB_INSERT(event_tree, &base->timetree, ev);
diff --git a/event.h b/event.h
index 3f2032dd..4c39939c 100644
--- a/event.h
+++ b/event.h
@@ -31,6 +31,8 @@
extern "C" {
#endif
+#include <sys/time.h>
+#include <stdint.h>
#include <stdarg.h>
#ifdef WIN32
@@ -131,16 +133,14 @@ TAILQ_HEAD (evkeyvalq, evkeyval);
struct eventop {
char *name;
- void *(*init)(void);
+ void *(*init)(struct event_base *);
int (*add)(void *, struct event *);
int (*del)(void *, struct event *);
int (*recalc)(struct event_base *, void *, int);
int (*dispatch)(struct event_base *, void *, struct timeval *);
- void (*dealloc)(void *);
+ void (*dealloc)(struct event_base *, void *);
};
-#define TIMEOUT_DEFAULT {5, 0}
-
void *event_init(void);
int event_dispatch(void);
int event_base_dispatch(struct event_base *);
@@ -184,6 +184,7 @@ int event_base_loopexit(struct event_base *, struct timeval *);
void event_set(struct event *, int, short, void (*)(int, short, void *), void *);
int event_once(int, short, void (*)(int, short, void *), void *, struct timeval *);
+int event_base_once(struct event_base *, int, short, void (*)(int, short, void *), void *, struct timeval *);
int event_add(struct event *, struct timeval *);
int event_del(struct event *);
@@ -299,39 +300,37 @@ void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_
void evtag_init(void);
-void evtag_marshal(struct evbuffer *evbuf, u_int8_t tag, const void *data,
- u_int32_t len);
+void evtag_marshal(struct evbuffer *evbuf, uint8_t tag, const void *data,
+ uint32_t len);
-void encode_int(struct evbuffer *evbuf, u_int32_t number);
+void encode_int(struct evbuffer *evbuf, uint32_t number);
-void evtag_marshal_int(struct evbuffer *evbuf, u_int8_t tag,
- u_int32_t integer);
+void evtag_marshal_int(struct evbuffer *evbuf, uint8_t tag, uint32_t integer);
-void evtag_marshal_string(struct evbuffer *buf, u_int8_t tag,
+void evtag_marshal_string(struct evbuffer *buf, uint8_t tag,
const char *string);
-void evtag_marshal_timeval(struct evbuffer *evbuf, u_int8_t tag,
+void evtag_marshal_timeval(struct evbuffer *evbuf, uint8_t tag,
struct timeval *tv);
void evtag_test(void);
-int evtag_unmarshal(struct evbuffer *src, u_int8_t *ptag,
- struct evbuffer *dst);
-int evtag_peek(struct evbuffer *evbuf, u_int8_t *ptag);
-int evtag_peek_length(struct evbuffer *evbuf, u_int32_t *plength);
-int evtag_payload_length(struct evbuffer *evbuf, u_int32_t *plength);
+int evtag_unmarshal(struct evbuffer *src, uint8_t *ptag, struct evbuffer *dst);
+int evtag_peek(struct evbuffer *evbuf, uint8_t *ptag);
+int evtag_peek_length(struct evbuffer *evbuf, uint32_t *plength);
+int evtag_payload_length(struct evbuffer *evbuf, uint32_t *plength);
int evtag_consume(struct evbuffer *evbuf);
-int evtag_unmarshal_int(struct evbuffer *evbuf, u_int8_t need_tag,
- u_int32_t *pinteger);
+int evtag_unmarshal_int(struct evbuffer *evbuf, uint8_t need_tag,
+ uint32_t *pinteger);
-int evtag_unmarshal_fixed(struct evbuffer *src, u_int8_t need_tag, void *data,
+int evtag_unmarshal_fixed(struct evbuffer *src, uint8_t need_tag, void *data,
size_t len);
-int evtag_unmarshal_string(struct evbuffer *evbuf, u_int8_t need_tag,
+int evtag_unmarshal_string(struct evbuffer *evbuf, uint8_t need_tag,
char **pstring);
-int evtag_unmarshal_timeval(struct evbuffer *evbuf, u_int8_t need_tag,
+int evtag_unmarshal_timeval(struct evbuffer *evbuf, uint8_t need_tag,
struct timeval *ptv);
#ifdef __cplusplus
diff --git a/event_rpcgen.py b/event_rpcgen.py
index b8e1f9e6..41f0a016 100755
--- a/event_rpcgen.py
+++ b/event_rpcgen.py
@@ -82,7 +82,7 @@ class Struct:
self.PrintIdented(file, ' ', dcl)
print >>file, ''
for entry in self._entries:
- print >>file, ' u_int8_t %s_set;' % entry.Name()
+ print >>file, ' uint8_t %s_set;' % entry.Name()
print >>file, '};\n'
print >>file, (
@@ -95,9 +95,9 @@ class Struct:
self._name, self._name) +
'int %s_complete(struct %s *);' % (self._name, self._name)
)
- print >>file, ('void evtag_marshal_%s(struct evbuffer *, u_int8_t, '
+ print >>file, ('void evtag_marshal_%s(struct evbuffer *, uint8_t, '
'const struct %s *);') % ( self._name, self._name)
- print >>file, ('int evtag_unmarshal_%s(struct evbuffer *, u_int8_t, '
+ print >>file, ('int evtag_unmarshal_%s(struct evbuffer *, uint8_t, '
'struct %s *);') % ( self._name, self._name)
# Write a setting function of every variable
@@ -198,7 +198,7 @@ class Struct:
' struct evbuffer *evbuf)\n' % (
self._name, self._name) +
'{\n'
- ' u_int8_t tag;\n'
+ ' uint8_t tag;\n'
' while (EVBUFFER_LENGTH(evbuf) > 0) {\n'
' if (evtag_peek(evbuf, &tag) == -1)\n'
' return (-1);\n'
@@ -247,12 +247,12 @@ class Struct:
# Complete message unmarshaling
print >>file, (
'int\n'
- 'evtag_unmarshal_%s(struct evbuffer *evbuf, u_int8_t need_tag, '
+ 'evtag_unmarshal_%s(struct evbuffer *evbuf, uint8_t need_tag, '
' struct %s *msg)'
) % (self._name, self._name)
print >>file, (
'{\n'
- ' u_int8_t tag;\n'
+ ' uint8_t tag;\n'
' int res = -1;\n'
'\n'
' struct evbuffer *tmp = evbuffer_new();\n'
@@ -274,7 +274,7 @@ class Struct:
# Complete message marshaling
print >>file, (
'void\n'
- 'evtag_marshal_%s(struct evbuffer *evbuf, u_int8_t tag, '
+ 'evtag_marshal_%s(struct evbuffer *evbuf, uint8_t tag, '
'const struct %s *msg)\n' % (self._name, self._name) +
'{\n'
' struct evbuffer *_buf = evbuffer_new();\n'
@@ -425,7 +425,7 @@ class EntryBytes(Entry):
Entry.__init__(self, type, name, tag)
self._length = length
- self._ctype = 'u_int8_t'
+ self._ctype = 'uint8_t'
def GetDeclaration(self, funcname):
code = [ 'int %s(struct %s *, %s **);' % (
@@ -438,7 +438,7 @@ class EntryBytes(Entry):
return code
def Declaration(self):
- dcl = ['u_int8_t %s_data[%s];' % (self._name, self._length)]
+ dcl = ['uint8_t %s_data[%s];' % (self._name, self._length)]
return dcl
@@ -513,7 +513,7 @@ class EntryInt(Entry):
# Init base class
Entry.__init__(self, type, name, tag)
- self._ctype = 'u_int32_t'
+ self._ctype = 'uint32_t'
def CodeUnmarshal(self, buf, tag_name, var_name):
code = ['if (evtag_unmarshal_int(%s, %s, &%s->%s_data) == -1) {' % (
@@ -530,7 +530,7 @@ class EntryInt(Entry):
return code
def Declaration(self):
- dcl = ['u_int32_t %s_data;' % self._name]
+ dcl = ['uint32_t %s_data;' % self._name]
return dcl
@@ -744,15 +744,15 @@ class EntryVarBytes(Entry):
# Init base class
Entry.__init__(self, type, name, tag)
- self._ctype = 'u_int8_t *'
+ self._ctype = 'uint8_t *'
def GetDeclaration(self, funcname):
- code = [ 'int %s(struct %s *, %s *, u_int32_t *);' % (
+ code = [ 'int %s(struct %s *, %s *, uint32_t *);' % (
funcname, self._struct.Name(), self._ctype ) ]
return code
def AssignDeclaration(self, funcname):
- code = [ 'int %s(struct %s *, const %s, u_int32_t);' % (
+ code = [ 'int %s(struct %s *, const %s, uint32_t);' % (
funcname, self._struct.Name(), self._ctype ) ]
return code
@@ -760,7 +760,7 @@ class EntryVarBytes(Entry):
name = self._name
code = [ 'int',
'%s_%s_assign(struct %s *msg, '
- 'const %s value, u_int32_t len)' % (
+ 'const %s value, uint32_t len)' % (
self._struct.Name(), name,
self._struct.Name(), self._ctype),
'{',
@@ -779,7 +779,7 @@ class EntryVarBytes(Entry):
def CodeGet(self):
name = self._name
code = [ 'int',
- '%s_%s_get(struct %s *msg, %s *value, u_int32_t *plen)' % (
+ '%s_%s_get(struct %s *msg, %s *value, uint32_t *plen)' % (
self._struct.Name(), name,
self._struct.Name(), self._ctype),
'{',
@@ -841,8 +841,8 @@ class EntryVarBytes(Entry):
return code
def Declaration(self):
- dcl = ['u_int8_t *%s_data;' % self._name,
- 'u_int32_t %s_length;' % self._name]
+ dcl = ['uint8_t *%s_data;' % self._name,
+ 'uint32_t %s_length;' % self._name]
return dcl
@@ -1295,6 +1295,9 @@ def HeaderPreamble(name):
'#define %s\n\n' ) % (
name, guard, guard)
+ # insert stdint.h - let's hope everyone has it
+ pre += '#include <stdint.h>\n'
+
for statement in headerdirect:
pre += '%s\n' % statement
if headerdirect:
diff --git a/event_tagging.c b/event_tagging.c
index 6b127243..3266d543 100644
--- a/event_tagging.c
+++ b/event_tagging.c
@@ -58,7 +58,7 @@
#include "event.h"
#include "log.h"
-int decode_int(u_int32_t *pnumber, struct evbuffer *evbuf);
+int decode_int(uint32_t *pnumber, struct evbuffer *evbuf);
static struct evbuffer *_buf; /* not thread safe */
@@ -79,10 +79,10 @@ evtag_init()
*/
void
-encode_int(struct evbuffer *evbuf, u_int32_t number)
+encode_int(struct evbuffer *evbuf, uint32_t number)
{
int off = 1, nibbles = 0;
- u_int8_t data[5];
+ uint8_t data[5];
memset(data, 0, sizeof(data));
while (number) {
@@ -111,8 +111,8 @@ encode_int(struct evbuffer *evbuf, u_int32_t number)
*/
void
-evtag_marshal(struct evbuffer *evbuf, u_int8_t tag,
- const void *data, u_int32_t len)
+evtag_marshal(struct evbuffer *evbuf, uint8_t tag,
+ const void *data, uint32_t len)
{
evbuffer_add(evbuf, &tag, sizeof(tag));
encode_int(evbuf, len);
@@ -121,7 +121,7 @@ evtag_marshal(struct evbuffer *evbuf, u_int8_t tag,
/* Marshaling for integers */
void
-evtag_marshal_int(struct evbuffer *evbuf, u_int8_t tag, u_int32_t integer)
+evtag_marshal_int(struct evbuffer *evbuf, uint8_t tag, uint32_t integer)
{
evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
encode_int(_buf, integer);
@@ -132,13 +132,13 @@ evtag_marshal_int(struct evbuffer *evbuf, u_int8_t tag, u_int32_t integer)
}
void
-evtag_marshal_string(struct evbuffer *buf, u_int8_t tag, const char *string)
+evtag_marshal_string(struct evbuffer *buf, uint8_t tag, const char *string)
{
evtag_marshal(buf, tag, string, strlen(string));
}
void
-evtag_marshal_timeval(struct evbuffer *evbuf, u_int8_t tag, struct timeval *tv)
+evtag_marshal_timeval(struct evbuffer *evbuf, uint8_t tag, struct timeval *tv)
{
evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
@@ -149,11 +149,11 @@ evtag_marshal_timeval(struct evbuffer *evbuf, u_int8_t tag, struct timeval *tv)
EVBUFFER_LENGTH(_buf));
}
-static int __inline
-decode_int_internal(u_int32_t *pnumber, struct evbuffer *evbuf, int dodrain)
+static int
+decode_int_internal(uint32_t *pnumber, struct evbuffer *evbuf, int dodrain)
{
- u_int32_t number = 0;
- u_int8_t *data = EVBUFFER_DATA(evbuf);
+ uint32_t number = 0;
+ uint8_t *data = EVBUFFER_DATA(evbuf);
int len = EVBUFFER_LENGTH(evbuf);
int nibbles = 0, off;
@@ -184,13 +184,13 @@ decode_int_internal(u_int32_t *pnumber, struct evbuffer *evbuf, int dodrain)
}
int
-decode_int(u_int32_t *pnumber, struct evbuffer *evbuf)
+decode_int(uint32_t *pnumber, struct evbuffer *evbuf)
{
return (decode_int_internal(pnumber, evbuf, 1) == -1 ? -1 : 0);
}
int
-evtag_peek(struct evbuffer *evbuf, u_int8_t *ptag)
+evtag_peek(struct evbuffer *evbuf, uint8_t *ptag)
{
if (EVBUFFER_LENGTH(evbuf) < 2)
return (-1);
@@ -200,7 +200,7 @@ evtag_peek(struct evbuffer *evbuf, u_int8_t *ptag)
}
int
-evtag_peek_length(struct evbuffer *evbuf, u_int32_t *plength)
+evtag_peek_length(struct evbuffer *evbuf, uint32_t *plength)
{
struct evbuffer tmp;
int res;
@@ -222,7 +222,7 @@ evtag_peek_length(struct evbuffer *evbuf, u_int32_t *plength)
}
int
-evtag_payload_length(struct evbuffer *evbuf, u_int32_t *plength)
+evtag_payload_length(struct evbuffer *evbuf, uint32_t *plength)
{
struct evbuffer tmp;
int res;
@@ -244,7 +244,7 @@ evtag_payload_length(struct evbuffer *evbuf, u_int32_t *plength)
int
evtag_consume(struct evbuffer *evbuf)
{
- u_int32_t len;
+ uint32_t len;
evbuffer_drain(evbuf, 1);
if (decode_int(&len, evbuf) == -1)
return (-1);
@@ -256,11 +256,11 @@ evtag_consume(struct evbuffer *evbuf)
/* Reads the data type from an event buffer */
int
-evtag_unmarshal(struct evbuffer *src, u_int8_t *ptag, struct evbuffer *dst)
+evtag_unmarshal(struct evbuffer *src, uint8_t *ptag, struct evbuffer *dst)
{
- u_int8_t tag;
- u_int32_t len;
- u_int32_t integer;
+ uint8_t tag;
+ uint32_t len;
+ uint32_t integer;
if (evbuffer_remove(src, &tag, sizeof(tag)) != sizeof(tag))
return (-1);
@@ -283,12 +283,12 @@ evtag_unmarshal(struct evbuffer *src, u_int8_t *ptag, struct evbuffer *dst)
/* Marshaling for integers */
int
-evtag_unmarshal_int(struct evbuffer *evbuf, u_int8_t need_tag,
- u_int32_t *pinteger)
+evtag_unmarshal_int(struct evbuffer *evbuf, uint8_t need_tag,
+ uint32_t *pinteger)
{
- u_int8_t tag;
- u_int32_t len;
- u_int32_t integer;
+ uint8_t tag;
+ uint32_t len;
+ uint32_t integer;
if (evbuffer_remove(evbuf, &tag, sizeof(tag)) != sizeof(tag) ||
tag != need_tag)
@@ -312,10 +312,10 @@ evtag_unmarshal_int(struct evbuffer *evbuf, u_int8_t need_tag,
/* Unmarshal a fixed length tag */
int
-evtag_unmarshal_fixed(struct evbuffer *src, u_int8_t need_tag, void *data,
+evtag_unmarshal_fixed(struct evbuffer *src, uint8_t need_tag, void *data,
size_t len)
{
- u_int8_t tag;
+ uint8_t tag;
/* Initialize this event buffer so that we can read into it */
evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
@@ -332,10 +332,10 @@ evtag_unmarshal_fixed(struct evbuffer *src, u_int8_t need_tag, void *data,
}
int
-evtag_unmarshal_string(struct evbuffer *evbuf, u_int8_t need_tag,
+evtag_unmarshal_string(struct evbuffer *evbuf, uint8_t need_tag,
char **pstring)
{
- u_int8_t tag;
+ uint8_t tag;
evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
@@ -351,11 +351,11 @@ evtag_unmarshal_string(struct evbuffer *evbuf, u_int8_t need_tag,
}
int
-evtag_unmarshal_timeval(struct evbuffer *evbuf, u_int8_t need_tag,
+evtag_unmarshal_timeval(struct evbuffer *evbuf, uint8_t need_tag,
struct timeval *ptv)
{
- u_int8_t tag;
- u_int32_t integer;
+ uint8_t tag;
+ uint32_t integer;
evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
if (evtag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag)
diff --git a/evhttp.h b/evhttp.h
index 162a796a..16744163 100644
--- a/evhttp.h
+++ b/evhttp.h
@@ -75,6 +75,9 @@ void evhttp_free(struct evhttp* http);
void evhttp_set_cb(struct evhttp *, const char *,
void (*)(struct evhttp_request *, void *), void *);
+/* Removes the callback for a specified URI */
+int evhttp_del_cb(struct evhttp *, const char *);
+
/* Set a callback for all requests that are not caught by specific callbacks */
void evhttp_set_gencb(struct evhttp *,
void (*)(struct evhttp_request *, void *), void *);
@@ -155,6 +158,8 @@ struct evhttp_request {
*/
struct evhttp_request *evhttp_request_new(
void (*cb)(struct evhttp_request *, void *), void *arg);
+
+/* enable delivery of chunks to requestor */
void evhttp_request_set_chunked_cb(struct evhttp_request *,
void (*cb)(struct evhttp_request *, void *));
diff --git a/evport.c b/evport.c
index 89bbd1ed..7d6f2d26 100644
--- a/evport.c
+++ b/evport.c
@@ -81,8 +81,6 @@
#include "log.h"
#include "evsignal.h"
-extern volatile sig_atomic_t evsignal_caught;
-
/*
* Default value for ed_nevents, which is the maximum file descriptor number we
@@ -123,11 +121,12 @@ struct evport_data {
struct fd_info *ed_pending[EVENTS_PER_GETN];
};
-static void* evport_init (void);
+static void* evport_init (struct event_base *);
static int evport_add (void *, struct event *);
static int evport_del (void *, struct event *);
static int evport_recalc (struct event_base *, void *, int);
static int evport_dispatch (struct event_base *, void *, struct timeval *);
+static void evport_dealloc (struct event_base *, void *);
const struct eventop evportops = {
"event ports",
@@ -135,7 +134,8 @@ const struct eventop evportops = {
evport_add,
evport_del,
evport_recalc,
- evport_dispatch
+ evport_dispatch,
+ evport_dealloc
};
/*
@@ -143,7 +143,7 @@ const struct eventop evportops = {
*/
static void*
-evport_init(void)
+evport_init(struct event_base *base)
{
struct evport_data *evpd;
/*
@@ -172,7 +172,7 @@ evport_init(void)
evpd->ed_nevents = DEFAULT_NFDS;
memset(&evpd->ed_pending, 0, EVENTS_PER_GETN * sizeof(struct fd_info*));
- evsignal_init();
+ evsignal_init(base);
return (evpd);
}
@@ -330,9 +330,9 @@ evport_dispatch(struct event_base *base, void *arg, struct timeval *tv)
}
if ((res = port_getn(epdp->ed_port, pevtlist, EVENTS_PER_GETN,
- &nevents, &ts)) == -1) {
+ (unsigned int *) &nevents, &ts)) == -1) {
if (errno == EINTR) {
- evsignal_process();
+ evsignal_process(base);
return (0);
} else if (errno == ETIME) {
if (nevents == 0)
@@ -341,8 +341,8 @@ evport_dispatch(struct event_base *base, void *arg, struct timeval *tv)
perror("port_getn");
return (-1);
}
- } else if (evsignal_caught) {
- evsignal_process();
+ } else if (base->sig.evsignal_caught) {
+ evsignal_process(base);
}
event_debug(("%s: port_getn reports %d events", __func__, nevents));
@@ -498,3 +498,16 @@ evport_del(void *arg, struct event *ev)
}
+static void
+evport_dealloc(struct event_base *base, void *arg)
+{
+ struct evport_data *evpd = arg;
+
+ evsignal_dealloc(base);
+
+ close(evpd->ed_port);
+
+ if (evpd->ed_fds)
+ free(evpd->ed_fds);
+ free(evpd);
+}
diff --git a/evsignal.h b/evsignal.h
index 5b92bd6e..7efbcabe 100644
--- a/evsignal.h
+++ b/evsignal.h
@@ -27,9 +27,18 @@
#ifndef _EVSIGNAL_H_
#define _EVSIGNAL_H_
-void evsignal_init(void);
-void evsignal_process(void);
+struct evsignal_info {
+ struct event_list signalqueue;
+ struct event ev_signal;
+ int ev_signal_pair[2];
+ int ev_signal_added;
+ volatile sig_atomic_t evsignal_caught;
+ sig_atomic_t evsigcaught[NSIG];
+};
+void evsignal_init(struct event_base *);
+void evsignal_process(struct event_base *);
int evsignal_add(struct event *);
int evsignal_del(struct event *);
+void evsignal_dealloc(struct event_base *);
#endif /* _EVSIGNAL_H_ */
diff --git a/http.c b/http.c
index d79119a1..942c6ca7 100644
--- a/http.c
+++ b/http.c
@@ -573,12 +573,13 @@ void
evhttp_connection_done(struct evhttp_connection *evcon)
{
struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
-
+ int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
+
/*
* if this is an incoming connection, we need to leave the request
* on the connection, so that we can reply to it.
*/
- if (evcon->flags & EVHTTP_CON_OUTGOING) {
+ if (con_outgoing) {
int need_close;
TAILQ_REMOVE(&evcon->requests, req, next);
req->evcon = NULL;
@@ -614,7 +615,7 @@ evhttp_connection_done(struct evhttp_connection *evcon)
(*req->cb)(req, req->cb_arg);
/* if this was an outgoing request, we own and it's done. so free it */
- if (evcon->flags & EVHTTP_CON_OUTGOING) {
+ if (con_outgoing) {
evhttp_request_free(req);
}
}
@@ -640,8 +641,10 @@ evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
if (p == NULL)
break;
/* the last chunk is on a new line? */
- if (strlen(p) == 0)
+ if (strlen(p) == 0) {
+ free(p);
continue;
+ }
req->ntoread = strtol(p, &endp, 16);
error = *p == '\0' || (*endp != '\0' && *endp != ' ');
free(p);
@@ -1114,10 +1117,16 @@ evhttp_remove_header(struct evkeyvalq *headers, const char *key)
}
int
-evhttp_add_header(struct evkeyvalq *headers, const char *key, const char *value)
+evhttp_add_header(struct evkeyvalq *headers,
+ const char *key, const char *value)
{
struct evkeyval *header;
+ if (strchr(value, "\r") != NULL || strchr(value, "\n") != NULL) {
+ /* drop illegal headers */
+ return (-1);
+ }
+
header = calloc(1, sizeof(struct evkeyval));
if (header == NULL) {
event_warn("%s: calloc", __func__);
@@ -1240,7 +1249,7 @@ evhttp_get_body_length(struct evhttp_request *req)
event_debug(("%s: bytes to read: %d (in buffer %d)\n",
__func__, req->ntoread,
- EVBUFFER_LENGTH(evcon->input_buffer)));
+ EVBUFFER_LENGTH(req->evcon->input_buffer)));
return (0);
}
@@ -1569,7 +1578,7 @@ evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
/* Requires that headers and response code are already set up */
-static __inline void
+static inline void
evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
{
struct evhttp_connection *evcon = req->evcon;
@@ -1734,8 +1743,8 @@ evhttp_decode_uri(const char *uri)
in_query = 1;
} else if (c == '+' && in_query) {
c = ' ';
- } else if (c == '%' && isxdigit(uri[i+1]) &&
- isxdigit(uri[i+2])) {
+ } else if (c == '%' && isxdigit((unsigned char)uri[i+1]) &&
+ isxdigit((unsigned char)uri[i+2])) {
char tmp[] = { uri[i+1], uri[i+2], '\0' };
c = (char)strtol(tmp, NULL, 16);
i += 2;
@@ -1795,30 +1804,41 @@ evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
free(line);
}
-void
-evhttp_handle_request(struct evhttp_request *req, void *arg)
+static struct evhttp_cb *
+evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
{
- struct evhttp *http = arg;
struct evhttp_cb *cb;
- if (req->uri == NULL) {
- evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
- return;
- }
-
/* Test for different URLs */
- TAILQ_FOREACH(cb, &http->callbacks, next) {
+ char *p = strchr(req->uri, '?');
+ TAILQ_FOREACH(cb, callbacks, next) {
int res;
- char *p = strchr(req->uri, '?');
if (p == NULL)
res = strcmp(cb->what, req->uri) == 0;
else
res = strncmp(cb->what, req->uri,
(size_t)(p - req->uri)) == 0;
- if (res) {
- (*cb->cb)(req, cb->cbarg);
- return;
- }
+ if (res)
+ return (cb);
+ }
+
+ return (NULL);
+}
+
+void
+evhttp_handle_request(struct evhttp_request *req, void *arg)
+{
+ struct evhttp *http = arg;
+ struct evhttp_cb *cb = NULL;
+
+ if (req->uri == NULL) {
+ evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
+ return;
+ }
+
+ if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
+ (*cb->cb)(req, cb->cbarg);
+ return;
}
/* Generic call back */
@@ -1861,7 +1881,7 @@ accept_socket(int fd, short what, void *arg)
event_warn("%s: bad accept", __func__);
return;
}
- if (event_make_socket_nonblocking(fd) < 0)
+ if (event_make_socket_nonblocking(nfd) < 0)
return;
evhttp_get_request(http, nfd, (struct sockaddr *)&ss, addrlen);
@@ -1964,6 +1984,25 @@ evhttp_set_cb(struct evhttp *http, const char *uri,
TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
}
+int
+evhttp_del_cb(struct evhttp *http, const char *uri)
+{
+ struct evhttp_cb *http_cb;
+
+ TAILQ_FOREACH(http_cb, &http->callbacks, next) {
+ if (strcmp(http_cb->what, uri) == 0)
+ break;
+ }
+ if (http_cb == NULL)
+ return (-1);
+
+ TAILQ_REMOVE(&http->callbacks, http_cb, next);
+ free(http_cb->what);
+ free(http_cb);
+
+ return (0);
+}
+
void
evhttp_set_gencb(struct evhttp *http,
void (*cb)(struct evhttp_request *, void *), void *cbarg)
@@ -2147,7 +2186,7 @@ evhttp_get_request(struct evhttp *http, int fd,
* Network helper functions that we do not want to export to the rest of
* the world.
*/
-
+#if 0 /* Unused */
static struct addrinfo *
addr_from_name(char *address)
{
@@ -2172,6 +2211,7 @@ addr_from_name(char *address)
return NULL; // XXXXX Use gethostbyname, if this function is ever used.
#endif
}
+#endif
static void
name_from_addr(struct sockaddr *sa, socklen_t salen,
diff --git a/kqueue.c b/kqueue.c
index 08369c6d..c5478062 100644
--- a/kqueue.c
+++ b/kqueue.c
@@ -69,13 +69,13 @@ struct kqop {
int kq;
};
-void *kq_init (void);
+void *kq_init (struct event_base *);
int kq_add (void *, struct event *);
int kq_del (void *, struct event *);
int kq_recalc (struct event_base *, void *, int);
int kq_dispatch (struct event_base *, void *, struct timeval *);
int kq_insert (struct kqop *, struct kevent *);
-void kq_dealloc (void *);
+void kq_dealloc (struct event_base *, void *);
const struct eventop kqops = {
"kqueue",
@@ -88,7 +88,7 @@ const struct eventop kqops = {
};
void *
-kq_init(void)
+kq_init(struct event_base *base)
{
int kq;
struct kqop *kqueueop;
@@ -212,13 +212,16 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv)
struct kevent *changes = kqop->changes;
struct kevent *events = kqop->events;
struct event *ev;
- struct timespec ts;
+ struct timespec ts, *ts_p = NULL;
int i, res;
- TIMEVAL_TO_TIMESPEC(tv, &ts);
+ if (tv != NULL) {
+ TIMEVAL_TO_TIMESPEC(tv, &ts);
+ ts_p = &ts;
+ }
res = kevent(kqop->kq, changes, kqop->nchanges,
- events, kqop->nevents, &ts);
+ events, kqop->nevents, ts_p);
kqop->nchanges = 0;
if (res == -1) {
if (errno != EINTR) {
@@ -398,7 +401,7 @@ kq_del(void *arg, struct event *ev)
}
void
-kq_dealloc(void *arg)
+kq_dealloc(struct event_base *base, void *arg)
{
struct kqop *kqop = arg;
diff --git a/poll.c b/poll.c
index 14ca8453..123d36a5 100644
--- a/poll.c
+++ b/poll.c
@@ -54,8 +54,6 @@
#include "evsignal.h"
#include "log.h"
-extern volatile sig_atomic_t evsignal_caught;
-
struct pollop {
int event_count; /* Highest number alloc */
int nfds; /* Size of event_* */
@@ -68,12 +66,12 @@ struct pollop {
* "no entry." */
};
-void *poll_init (void);
+void *poll_init (struct event_base *);
int poll_add (void *, struct event *);
int poll_del (void *, struct event *);
int poll_recalc (struct event_base *, void *, int);
int poll_dispatch (struct event_base *, void *, struct timeval *);
-void poll_dealloc (void *);
+void poll_dealloc (struct event_base *, void *);
const struct eventop pollops = {
"poll",
@@ -86,7 +84,7 @@ const struct eventop pollops = {
};
void *
-poll_init(void)
+poll_init(struct event_base *base)
{
struct pollop *pollop;
@@ -97,7 +95,7 @@ poll_init(void)
if (!(pollop = calloc(1, sizeof(struct pollop))))
return (NULL);
- evsignal_init();
+ evsignal_init(base);
return (pollop);
}
@@ -150,13 +148,16 @@ poll_check_ok(struct pollop *pop)
int
poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
{
- int res, i, sec, nfds;
+ int res, i, msec = -1, nfds;
struct pollop *pop = arg;
poll_check_ok(pop);
- sec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
+
+ if (tv != NULL)
+ msec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
+
nfds = pop->nfds;
- res = poll(pop->event_set, nfds, sec);
+ res = poll(pop->event_set, nfds, msec);
if (res == -1) {
if (errno != EINTR) {
@@ -164,10 +165,11 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
return (-1);
}
- evsignal_process();
+ evsignal_process(base);
return (0);
- } else if (evsignal_caught)
- evsignal_process();
+ } else if (base->sig.evsignal_caught) {
+ evsignal_process(base);
+ }
event_debug(("%s: poll reports %d", __func__, res));
@@ -370,10 +372,11 @@ poll_del(void *arg, struct event *ev)
}
void
-poll_dealloc(void *arg)
+poll_dealloc(struct event_base *base, void *arg)
{
struct pollop *pop = arg;
+ evsignal_dealloc(base);
if (pop->event_set)
free(pop->event_set);
if (pop->event_r_back)
diff --git a/rtsig.c b/rtsig.c
index 29aade69..e0e55afc 100644
--- a/rtsig.c
+++ b/rtsig.c
@@ -223,7 +223,7 @@ struct rtdata {
int poll_position;
};
-void *rtsig_init(void);
+void *rtsig_init(struct event_base *);
int rtsig_add(void *, struct event *);
int rtsig_del(void *, struct event *);
int rtsig_recalc(struct event_base *, void *, int);
@@ -544,7 +544,7 @@ activate(struct event *ev, int flags)
} while (0)
void *
-rtsig_init(void)
+rtsig_init(struct event_base *)
{
struct rtsigop *op;
int sockets[2];
@@ -750,7 +750,7 @@ rtsig_recalc(struct event_base *base, void *arg, int max)
*/
static inline int
-do_poll(struct rtsigop *op, struct timespec *ts)
+do_poll(struct rtsigop *op, struct timespec *ts, struct timespec **ts_p)
{
int res = 0;
int i = 0;
@@ -758,7 +758,11 @@ do_poll(struct rtsigop *op, struct timespec *ts)
if (op->cur > 1) {
/* non-empty poll set (modulo the signalfd) */
if (op->nonsock) {
- int timeout = ts->tv_nsec / 1000000 + ts->tv_sec * 1000;
+ int timeout = -1;
+
+ if (*ts_p != NULL)
+ timeout = (*ts_p)->tv_nsec / 1000000
+ + (*ts_p)->tv_sec * 1000;
sigprocmask(SIG_UNBLOCK, &(op->sigs), NULL);
@@ -768,6 +772,7 @@ do_poll(struct rtsigop *op, struct timespec *ts)
ts->tv_sec = 0;
ts->tv_nsec = 0;
+ *ts_p = ts;
} else {
res = poll(op->poll, op->cur, 0);
}
@@ -777,6 +782,7 @@ do_poll(struct rtsigop *op, struct timespec *ts)
} else if (res) {
ts->tv_sec = 0;
ts->tv_nsec = 0;
+ *ts_p = ts;
}
i = 0;
@@ -894,17 +900,18 @@ do_siginfo_dispatch(struct event_base *base, struct rtsigop *op,
* return -1 on error
*/
static inline int
-do_sigwait(struct event_base *base, struct rtsigop *op, struct timespec *ts,
- sigset_t *sigs)
+do_sigwait(struct event_base *base, struct rtsigop *op,
+ struct timespec *ts, struct timespec **ts_p, sigset_t *sigs)
{
for (;;) {
siginfo_t info;
int signum;
- signum = sigtimedwait(sigs, &info, ts);
+ signum = sigtimedwait(sigs, &info, *ts_p);
ts->tv_sec = 0;
ts->tv_nsec = 0;
+ *ts_p = ts;
if (signum == -1) {
if (errno == EAGAIN || errno == EINTR)
@@ -920,7 +927,7 @@ do_sigwait(struct event_base *base, struct rtsigop *op, struct timespec *ts,
static inline int
do_signals_from_socket(struct event_base *base, struct rtsigop *op,
- struct timespec *ts)
+ struct timespec *ts, struct timespec **ts_p)
{
int fd = op->signal_recv_fd;
siginfo_t info;
@@ -937,6 +944,7 @@ do_signals_from_socket(struct event_base *base, struct rtsigop *op,
} else {
ts->tv_sec = 0;
ts->tv_nsec = 0;
+ *ts_p = ts;
if (1 == do_siginfo_dispatch(base, op, &info))
return (1);
}
@@ -948,17 +956,21 @@ int
rtsig_dispatch(struct event_base *base, void *arg, struct timeval *tv)
{
struct rtsigop *op = (struct rtsigop *) arg;
- struct timespec ts;
+ struct timespec ts, *ts_p = NULL;
int res;
sigset_t sigs;
- ts.tv_sec = tv->tv_sec;
- ts.tv_nsec = tv->tv_usec * 1000;
+ if (tv != NULL) {
+ ts.tv_sec = tv->tv_sec;
+ ts.tv_nsec = tv->tv_usec * 1000;
+ *ts_p = ts;
+ }
poll_for_level:
- res = do_poll(op, &ts); /* ts can be modified in do_XXX() */
+ /* ts and ts_p can be modified in do_XXX() */
+ res = do_poll(op, &ts, &ts_p);
- res = do_signals_from_socket(base, op, &ts);
+ res = do_signals_from_socket(base, op, &ts, &ts_p);
if (res == 1)
goto poll_for_level;
else if (res == -1)
@@ -973,7 +985,7 @@ rtsig_dispatch(struct event_base *base, void *arg, struct timeval *tv)
signotset(&sigs);
sigorset(&sigs, &sigs, &op->sigs);
- res = do_sigwait(base, op, &ts, &sigs);
+ res = do_sigwait(base, op, &ts, &ts_p, &sigs);
if (res == 1)
goto poll_for_level;
diff --git a/sample/Makefile.am b/sample/Makefile.am
index b749b806..d4a113ce 100644
--- a/sample/Makefile.am
+++ b/sample/Makefile.am
@@ -1,8 +1,7 @@
AUTOMAKE_OPTIONS = foreign no-dependencies
LDADD = ../libevent.la
-CPPFPLAGS = -I..
-CFLAGS = -I../compat
+AM_CFLAGS = -I../compat
noinst_PROGRAMS = event-test time-test signal-test
diff --git a/sample/event-test.c b/sample/event-test.c
index 965984d4..db3ba31e 100644
--- a/sample/event-test.c
+++ b/sample/event-test.c
@@ -3,6 +3,10 @@
* cc -I/usr/local/include -o event-test event-test.c -L/usr/local/lib -levent
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>
#ifndef WIN32
diff --git a/select.c b/select.c
index 6ce81a23..d645f1a3 100644
--- a/select.c
+++ b/select.c
@@ -36,6 +36,9 @@
#else
#include <sys/_time.h>
#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
#include <sys/queue.h>
#include <sys/tree.h>
#include <signal.h>
@@ -57,8 +60,6 @@
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
-extern volatile sig_atomic_t evsignal_caught;
-
struct selectop {
int event_fds; /* Highest fd in fd set */
int event_fdsz;
@@ -70,12 +71,12 @@ struct selectop {
struct event **event_w_by_fd;
};
-void *select_init (void);
+void *select_init (struct event_base *);
int select_add (void *, struct event *);
int select_del (void *, struct event *);
int select_recalc (struct event_base *, void *, int);
int select_dispatch (struct event_base *, void *, struct timeval *);
-void select_dealloc (void *);
+void select_dealloc (struct event_base *, void *);
const struct eventop selectops = {
"select",
@@ -90,7 +91,7 @@ const struct eventop selectops = {
static int select_resize(struct selectop *sop, int fdsz);
void *
-select_init(void)
+select_init(struct event_base *base)
{
struct selectop *sop;
@@ -103,7 +104,7 @@ select_init(void)
select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
- evsignal_init();
+ evsignal_init(base);
return (sop);
}
@@ -113,7 +114,7 @@ static void
check_selectop(struct selectop *sop)
{
int i;
- for (i=0;i<=sop->event_fds;++i) {
+ for (i = 0; i <= sop->event_fds; ++i) {
if (FD_ISSET(i, sop->event_readset_in)) {
assert(sop->event_r_by_fd[i]);
assert(sop->event_r_by_fd[i]->ev_events & EV_READ);
@@ -174,10 +175,11 @@ select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
return (-1);
}
- evsignal_process();
+ evsignal_process(base);
return (0);
- } else if (evsignal_caught)
- evsignal_process();
+ } else if (base->sig.evsignal_caught) {
+ evsignal_process(base);
+ }
event_debug(("%s: select reports %d", __func__, res));
@@ -348,10 +350,11 @@ select_del(void *arg, struct event *ev)
}
void
-select_dealloc(void *arg)
+select_dealloc(struct event_base *base, void *arg)
{
struct selectop *sop = arg;
+ evsignal_dealloc(base);
if (sop->event_readset_in)
free(sop->event_readset_in);
if (sop->event_writeset_in)
diff --git a/signal.c b/signal.c
index 71bcffcb..6c0953d9 100644
--- a/signal.c
+++ b/signal.c
@@ -31,6 +31,7 @@
#endif
#include <sys/types.h>
+#include <sys/tree.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
@@ -47,19 +48,14 @@
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#include <assert.h>
#include "event.h"
+#include "event-internal.h"
#include "evsignal.h"
#include "log.h"
-extern struct event_list signalqueue;
-
-static sig_atomic_t evsigcaught[NSIG];
-volatile sig_atomic_t evsignal_caught = 0;
-
-static struct event ev_signal;
-static int ev_signal_pair[2];
-static int ev_signal_added;
+struct event_base *evsignal_base = NULL;
static void evsignal_handler(int sig);
@@ -87,24 +83,27 @@ evsignal_cb(int fd, short what, void *arg)
#endif
void
-evsignal_init(void)
+evsignal_init(struct event_base *base)
{
/*
* Our signal handler is going to write to one end of the socket
* pair to wake up our event loop. The event loop then scans for
* signals that got delivered.
*/
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, ev_signal_pair) == -1)
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
event_err(1, "%s: socketpair", __func__);
- FD_CLOSEONEXEC(ev_signal_pair[0]);
- FD_CLOSEONEXEC(ev_signal_pair[1]);
+ FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
+ FD_CLOSEONEXEC(base->sig.ev_signal_pair[1]);
+ base->sig.evsignal_caught = 0;
+ memset(&base->sig.evsigcaught, 0, sizeof(sig_atomic_t)*NSIG);
- fcntl(ev_signal_pair[0], F_SETFL, O_NONBLOCK);
+ fcntl(base->sig.ev_signal_pair[0], F_SETFL, O_NONBLOCK);
- event_set(&ev_signal, ev_signal_pair[1], EV_READ,
- evsignal_cb, &ev_signal);
- ev_signal.ev_flags |= EVLIST_INTERNAL;
+ event_set(&base->sig.ev_signal, base->sig.ev_signal_pair[1], EV_READ,
+ evsignal_cb, &base->sig.ev_signal);
+ base->sig.ev_signal.ev_base = base;
+ base->sig.ev_signal.ev_flags |= EVLIST_INTERNAL;
}
int
@@ -112,6 +111,7 @@ evsignal_add(struct event *ev)
{
int evsignal;
struct sigaction sa;
+ struct event_base *base = ev->ev_base;
if (ev->ev_events & (EV_READ|EV_WRITE))
event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
@@ -121,29 +121,23 @@ evsignal_add(struct event *ev)
sa.sa_handler = evsignal_handler;
sigfillset(&sa.sa_mask);
sa.sa_flags |= SA_RESTART;
+ /* catch signals if they happen quickly */
+ evsignal_base = base;
if (sigaction(evsignal, &sa, NULL) == -1)
return (-1);
- if (!ev_signal_added) {
- ev_signal_added = 1;
- event_add(&ev_signal, NULL);
+ if (!base->sig.ev_signal_added) {
+ base->sig.ev_signal_added = 1;
+ event_add(&base->sig.ev_signal, NULL);
}
return (0);
}
-/*
- * Nothing to be done here.
- */
-
int
evsignal_del(struct event *ev)
{
- int evsignal;
-
- evsignal = EVENT_SIGNAL(ev);
-
return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
}
@@ -152,29 +146,50 @@ evsignal_handler(int sig)
{
int save_errno = errno;
- evsigcaught[sig]++;
- evsignal_caught = 1;
+ if(evsignal_base == NULL) {
+ event_warn(
+ "%s: received signal %s, but have no base configured",
+ __func__, sig);
+ return;
+ }
+
+ evsignal_base->sig.evsigcaught[sig]++;
+ evsignal_base->sig.evsignal_caught = 1;
/* Wake up our notification mechanism */
- write(ev_signal_pair[0], "a", 1);
+ write(evsignal_base->sig.ev_signal_pair[0], "a", 1);
errno = save_errno;
}
void
-evsignal_process(void)
+evsignal_process(struct event_base *base)
{
struct event *ev;
sig_atomic_t ncalls;
- evsignal_caught = 0;
- TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
- ncalls = evsigcaught[EVENT_SIGNAL(ev)];
+ base->sig.evsignal_caught = 0;
+ TAILQ_FOREACH(ev, &base->sig.signalqueue, ev_signal_next) {
+ ncalls = base->sig.evsigcaught[EVENT_SIGNAL(ev)];
if (ncalls) {
if (!(ev->ev_events & EV_PERSIST))
event_del(ev);
event_active(ev, EV_SIGNAL, ncalls);
- evsigcaught[EVENT_SIGNAL(ev)] = 0;
+ base->sig.evsigcaught[EVENT_SIGNAL(ev)] = 0;
}
}
}
+void
+evsignal_dealloc(struct event_base *base)
+{
+ if(base->sig.ev_signal_added) {
+ event_del(&base->sig.ev_signal);
+ base->sig.ev_signal_added = 0;
+ }
+ assert(TAILQ_EMPTY(&base->sig.signalqueue));
+
+ close(base->sig.ev_signal_pair[0]);
+ base->sig.ev_signal_pair[0] = -1;
+ close(base->sig.ev_signal_pair[1]);
+ base->sig.ev_signal_pair[1] = -1;
+}
diff --git a/test/regress.c b/test/regress.c
index 622c6a88..368b6997 100644
--- a/test/regress.c
+++ b/test/regress.c
@@ -35,6 +35,7 @@
#endif
#include <sys/types.h>
+#include <sys/tree.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
@@ -47,12 +48,14 @@
#endif
#include <netdb.h>
#include <fcntl.h>
+#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "event.h"
+#include "event-internal.h"
#include "log.h"
#include "regress.h"
@@ -465,6 +468,96 @@ test_immediatesignal(void)
signal_del(&ev);
cleanup_test();
}
+
+void
+test_signal_dealloc(void)
+{
+ /* make sure that signal_event is event_del'ed and pipe closed */
+ struct event ev;
+ struct event_base *base = event_init();
+ printf("Signal dealloc: ");
+ signal_set(&ev, SIGUSR1, signal_cb, &ev);
+ signal_add(&ev, NULL);
+ signal_del(&ev);
+ event_base_free(base);
+ errno = EINTR;
+ if (base->sig.ev_signal_added) {
+ printf("ev_signal not removed (evsignal_dealloc needed) ");
+ test_ok = 0;
+ } else if (close(base->sig.ev_signal_pair[0]) != -1 ||
+ errno != EBADF) {
+ /* fd must be closed, so second close gives -1, EBADF */
+ printf("signal pipe still open (evsignal_dealloc needed) ");
+ test_ok = 0;
+ } else {
+ test_ok = 1;
+ }
+ cleanup_test();
+}
+
+void
+test_signal_pipeloss(void)
+{
+ /* make sure that the base1 pipe is closed correctly. */
+ struct event_base *base1, *base2;
+ int pipe1;
+ printf("Signal pipeloss: ");
+ base1 = event_init();
+ pipe1 = base1->sig.ev_signal_pair[0];
+ base2 = event_init();
+ event_base_free(base2);
+ event_base_free(base1);
+ if (close(pipe1) != -1 || errno!=EBADF) {
+ /* fd must be closed, so second close gives -1, EBADF */
+ printf("signal pipe not closed. ");
+ test_ok = 0;
+ } else {
+ test_ok = 1;
+ }
+ cleanup_test();
+}
+
+/*
+ * make two bases to catch signals, use both of them. this only works
+ * for event mechanisms that use our signal pipe trick. kqueue handles
+ * signals internally, and it looks like the first kqueue always gets the
+ * signal.
+ */
+void
+test_signal_switchbase(void)
+{
+ struct event ev1, ev2;
+ struct event_base *base1, *base2;
+ printf("Signal switchbase: ");
+ base1 = event_init();
+ base2 = event_init();
+ signal_set(&ev1, SIGUSR1, signal_cb, &ev1);
+ signal_set(&ev2, SIGUSR1, signal_cb, &ev2);
+ if (event_base_set(base1, &ev1) ||
+ event_base_set(base2, &ev2) ||
+ event_add(&ev1, NULL) ||
+ event_add(&ev2, NULL)) {
+ fprintf(stderr, "%s: cannot set base, add\n", __func__);
+ exit(1);
+ }
+
+ test_ok = 0;
+ /* can handle signal before loop is called */
+ raise(SIGUSR1);
+ event_base_loop(base2, EVLOOP_NONBLOCK);
+ event_base_loop(base1, EVLOOP_NONBLOCK);
+ if (test_ok) {
+ test_ok = 0;
+ /* set base1 to handle signals */
+ event_base_loop(base1, EVLOOP_NONBLOCK);
+ raise(SIGUSR1);
+ event_base_loop(base1, EVLOOP_NONBLOCK);
+ event_base_loop(base2, EVLOOP_NONBLOCK);
+ }
+ event_base_free(base1);
+ event_base_free(base2);
+ cleanup_test();
+}
#endif
void
@@ -499,9 +592,9 @@ test_loopexit(void)
void
test_evbuffer(void) {
- setup_test("Evbuffer: ");
struct evbuffer *evb = evbuffer_new();
+ setup_test("Evbuffer: ");
evbuffer_add_printf(evb, "%s/%d", "hello", 1);
@@ -513,6 +606,61 @@ test_evbuffer(void) {
}
void
+test_evbuffer_find(void)
+{
+ u_char* p;
+ char* test1 = "1234567890\r\n";
+ char* test2 = "1234567890\r";
+#define EVBUFFER_INITIAL_LENGTH 256
+ char test3[EVBUFFER_INITIAL_LENGTH];
+ unsigned int i;
+ struct evbuffer * buf = evbuffer_new();
+
+ /* make sure evbuffer_find doesn't match past the end of the buffer */
+ fprintf(stdout, "Testing evbuffer_find 1: ");
+ evbuffer_add(buf, (u_char*)test1, strlen(test1));
+ evbuffer_drain(buf, strlen(test1));
+ evbuffer_add(buf, (u_char*)test2, strlen(test2));
+ p = evbuffer_find(buf, (u_char*)"\r\n", 2);
+ if (p == NULL) {
+ fprintf(stdout, "OK\n");
+ } else {
+ fprintf(stdout, "FAILED\n");
+ exit(1);
+ }
+
+ /*
+ * drain the buffer and do another find; in r309 this would
+ * read past the allocated buffer causing a valgrind error.
+ */
+ fprintf(stdout, "Testing evbuffer_find 2: ");
+ evbuffer_drain(buf, strlen(test2));
+ for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
+ test3[i] = 'a';
+ test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
+ evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH);
+ p = evbuffer_find(buf, (u_char *)"xy", 2);
+ if (p == NULL) {
+ printf("OK\n");
+ } else {
+ fprintf(stdout, "FAILED\n");
+ exit(1);
+ }
+
+ /* simple test for match at end of allocated buffer */
+ fprintf(stdout, "Testing evbuffer_find 3: ");
+ p = evbuffer_find(buf, (u_char *)"ax", 2);
+ if (p != NULL && strncmp(p, "ax", 2) == 0) {
+ printf("OK\n");
+ } else {
+ fprintf(stdout, "FAILED\n");
+ exit(1);
+ }
+
+ evbuffer_free(buf);
+}
+
+void
readcb(struct bufferevent *bev, void *arg)
{
if (EVBUFFER_LENGTH(bev->input) == 8333) {
@@ -896,6 +1044,11 @@ main (int argc, char **argv)
/* Initalize the event library */
event_base = event_init();
+ test_evbuffer();
+ test_evbuffer_find();
+
+ test_bufferevent();
+
http_suite();
dns_suite();
@@ -917,10 +1070,6 @@ main (int argc, char **argv)
#endif
test_loopexit();
- test_evbuffer();
-
- test_bufferevent();
-
test_priorities(1);
test_priorities(2);
test_priorities(3);
@@ -928,11 +1077,17 @@ main (int argc, char **argv)
test_multiple_events_for_same_fd();
test_want_only_once();
-
+
evtag_test();
rpc_test();
+#ifndef WIN32
+ test_signal_dealloc();
+ test_signal_pipeloss();
+ test_signal_switchbase();
+#endif
+
return (0);
}
diff --git a/test/regress_dns.c b/test/regress_dns.c
index c65d3570..35313b53 100644
--- a/test/regress_dns.c
+++ b/test/regress_dns.c
@@ -179,7 +179,7 @@ dns_server_request_cb(struct evdns_server_request *req, void *data)
const char TEST_ARPA[] = "11.11.168.192.in-addr.arpa";
for (i = 0; i < req->nquestions; ++i) {
struct in_addr ans;
- ans.s_addr = htonl(0xc0a80b0bUL); // 192.168.11.11
+ ans.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
if (req->questions[i]->type == EVDNS_TYPE_A &&
req->questions[i]->class == EVDNS_CLASS_INET &&
!strcmp(req->questions[i]->name, "zz.example.com")) {
@@ -325,7 +325,7 @@ dns_server()
dns_server_gethostbyname_cb, NULL);
evdns_resolve_ipv6("zz.example.com", DNS_QUERY_NO_SEARCH,
dns_server_gethostbyname_cb, NULL);
- resolve_addr.s_addr = htonl(0xc0a80b0bUL); // 192.168.11.11
+ resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
evdns_resolve_reverse(&resolve_addr, 0,
dns_server_gethostbyname_cb, NULL);
diff --git a/test/regress_http.c b/test/regress_http.c
index f2346ca6..a7956a04 100644
--- a/test/regress_http.c
+++ b/test/regress_http.c
@@ -130,8 +130,10 @@ http_readcb(struct bufferevent *bev, void *arg)
if (evbuffer_find(bev->input, (const unsigned char*) what, strlen(what)) != NULL) {
struct evhttp_request *req = evhttp_request_new(NULL, NULL);
+ int done;
+
req->kind = EVHTTP_RESPONSE;
- int done = evhttp_parse_lines(req, bev->input);
+ done = evhttp_parse_lines(req, bev->input);
if (done == 1 &&
evhttp_find_header(req->input_headers,
@@ -163,9 +165,9 @@ http_errorcb(struct bufferevent *bev, short what, void *arg)
void
http_basic_cb(struct evhttp_request *req, void *arg)
{
- event_debug(("%s: called\n", __func__));
struct evbuffer *evb = evbuffer_new();
+ event_debug(("%s: called\n", __func__));
evbuffer_add_printf(evb, "This is funny");
evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb);
@@ -380,6 +382,7 @@ http_post_test(void)
void
http_post_cb(struct evhttp_request *req, void *arg)
{
+ struct evbuffer *evb;
event_debug(("%s: called\n", __func__));
/* Yes, we are expecting a post request */
@@ -389,7 +392,7 @@ http_post_cb(struct evhttp_request *req, void *arg)
}
if (EVBUFFER_LENGTH(req->input_buffer) != strlen(POST_DATA)) {
- fprintf(stdout, "FAILED (length: %ld vs %ld)\n",
+ fprintf(stdout, "FAILED (length: %zu vs %zu)\n",
EVBUFFER_LENGTH(req->input_buffer), strlen(POST_DATA));
exit(1);
}
@@ -402,7 +405,7 @@ http_post_cb(struct evhttp_request *req, void *arg)
exit(1);
}
- struct evbuffer *evb = evbuffer_new();
+ evb = evbuffer_new();
evbuffer_add_printf(evb, "This is funny");
evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb);
@@ -427,7 +430,7 @@ http_postrequest_done(struct evhttp_request *req, void *arg)
}
if (EVBUFFER_LENGTH(req->input_buffer) != strlen(what)) {
- fprintf(stderr, "FAILED (length %ld vs %ld)\n",
+ fprintf(stderr, "FAILED (length %zu vs %zu)\n",
EVBUFFER_LENGTH(req->input_buffer), strlen(what));
exit(1);
}
diff --git a/test/test-eof.c b/test/test-eof.c
index 020c6611..4b1883c2 100644
--- a/test/test-eof.c
+++ b/test/test-eof.c
@@ -2,6 +2,10 @@
* Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/test/test-init.c b/test/test-init.c
index 32806baa..7d22de55 100644
--- a/test/test-init.c
+++ b/test/test-init.c
@@ -2,6 +2,10 @@
* Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/test/test-time.c b/test/test-time.c
index a26c973e..e21e8e0f 100644
--- a/test/test-time.c
+++ b/test/test-time.c
@@ -2,6 +2,10 @@
* Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/test/test-weof.c b/test/test-weof.c
index 5f3be277..19f591e2 100644
--- a/test/test-weof.c
+++ b/test/test-weof.c
@@ -2,6 +2,10 @@
* Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>