daemon->env->cfg = daemon->cfg;
daemon->env->alloc = &daemon->superalloc;
daemon->env->worker = NULL;
- daemon->env->send_packet = &worker_send_packet;
- daemon->env->send_query = &worker_send_query;
daemon->env->need_to_validate = 0; /* set by module init below */
for(i=0; i<daemon->num_modules; i++) {
log_info("init module %d: %s", i, daemon->modfunc[i]->name);
worker_send_cmd(daemon->workers[i],
daemon->workers[0]->front->udp_buff, worker_cmd_quit);
}
- /** wait for them to quit */
+ /* wait for them to quit */
for(i=1; i<daemon->num; i++) {
/* join it to make sure its dead */
verbose(VERB_ALGO, "join %d", i);
if(cfg->hide_identity)
return 0;
if(cfg->identity==NULL || cfg->identity[0]==0) {
- char buf[MAXHOSTNAMELEN];
- if (gethostname(buf, MAXHOSTNAMELEN) == 0)
+ char buf[MAXHOSTNAMELEN+1];
+ if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
+ buf[MAXHOSTNAMELEN] = 0;
chaos_replystr(pkt, buf, edns);
- else {
+ } else {
log_err("gethostname: %s", strerror(errno));
chaos_replystr(pkt, "no hostname", edns);
}
struct worker* worker = (struct worker*)arg;
switch(sig) {
case SIGHUP:
- log_info("caught signal SIGHUP");
+ verbose(VERB_DETAIL, "caught signal SIGHUP");
worker->need_to_restart = 1;
comm_base_exit(worker->base);
break;
case SIGINT:
- log_info("caught signal SIGINT");
+ verbose(VERB_DETAIL, "caught signal SIGINT");
worker->need_to_restart = 0;
comm_base_exit(worker->base);
break;
case SIGQUIT:
- log_info("caught signal SIGQUIT");
+ verbose(VERB_DETAIL, "caught signal SIGQUIT");
worker->need_to_restart = 0;
comm_base_exit(worker->base);
break;
case SIGTERM:
- log_info("caught signal SIGTERM");
+ verbose(VERB_DETAIL, "caught signal SIGTERM");
worker->need_to_restart = 0;
comm_base_exit(worker->base);
break;
worker->thread_num);
worker->env = *worker->daemon->env;
worker->env.worker = worker;
+ worker->env.send_packet = &worker_send_packet;
+ worker->env.send_query = &worker_send_query;
worker->env.alloc = &worker->alloc;
worker->env.rnd = worker->rndstate;
worker->env.scratch = worker->scratchpad;
+16 October 2007: Wouter
+ - no malloc in log_hex.
+ - assertions around system calls.
+ - protect against gethostname without ending zero.
+
15 October 2007: Wouter
- nicer warning.
- fix IP6 TCP, wrong definition check. With test package.
if(q1->qbuflen > q2->qbuflen)
return 1;
log_assert(q1->qbuflen == q2->qbuflen);
- /* FIXME: will not detect alternate casing of qname */
+ /* will not detect alternate casing of qname */
if((r = memcmp(q1->qbuf, q2->qbuf, q1->qbuflen)) != 0)
return r;
if(q1->dnssec != q2->dnssec) {
int s;
log_assert(pend);
log_assert(pkt);
+ log_assert(w->addrlen > 0);
/* open socket */
#ifdef INET6
if(addr_is_ip6(&w->addr, w->addrlen))
p = (struct pending*)rbtree_search(outnet->pending, &key);
if(!p) {
verbose(VERB_DETAIL, "received unwanted or unsolicited udp reply dropped.");
- if(verbosity >= VERB_ALGO)
- log_hex("dropped message",
- ldns_buffer_begin(c->buffer),
- ldns_buffer_limit(c->buffer));
+ log_buf(VERB_ALGO, "dropped message", c->buffer);
return 0;
}
verbose(VERB_ALGO, "received udp reply.");
- if(verbosity >= VERB_ALGO)
- log_hex("udp message", ldns_buffer_begin(c->buffer),
- ldns_buffer_limit(c->buffer));
+ log_buf(VERB_ALGO, "udp message", c->buffer);
if(p->c != c) {
verbose(VERB_DETAIL, "received reply id,addr on wrong port. "
"dropped.");
int roundtime = (now.tv_sec - sq->last_sent_time.tv_sec)*1000
+ ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000;
verbose(VERB_ALGO, "measured roundtrip at %d msec", roundtime);
+ log_assert(roundtime >= 0);
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
roundtime, (time_t)now.tv_sec))
log_err("out of memory noting rtt.");
s1 = ldns_buffer2pkt_wire(&p1, pkt);
s2 = ldns_buffer2pkt_wire(&p2, out);
if(vbmp) {
- log_hex("orig in hex", ldns_buffer_begin(pkt),
- ldns_buffer_limit(pkt));
- log_hex("unbound out in hex", ldns_buffer_begin(out),
- ldns_buffer_limit(out));
+ log_buf(0, "orig in hex", pkt);
+ log_buf(0, "unbound out in hex", out);
printf("\npacket from unbound (%d):\n",
(int)ldns_buffer_limit(out));
ldns_pkt_print(stdout, p2);
/*
verbose(VERB_DETAIL, "Packet contains rrset data in "
"multiple sections, dropped last part.");
- log_hex("packet was: ", ldns_buffer_begin(pkt),
- ldns_buffer_limit(pkt));
+ log_buf(VERB_DETAIL, "packet was", pkt);
*/
/* forwards */
if(!skip_ttl_rdata(pkt))
if((err=thr_sigsetmask(SIG_UNBLOCK, &sigset, NULL)))
fatal_exit("thr_sigsetmask: %s", strerror(err));
# else
- /* have nothing, do nothing */
+ /* have nothing, do single thread case */
if((err=sigprocmask(SIG_UNBLOCK, &sigset, NULL)))
fatal_exit("sigprocmask: %s", strerror(errno));
# endif /* HAVE_SOLARIS_THREADS */
|| log_to_syslog
#endif
)
- verbose(VERB_DETAIL, "switching log to %s",
+ verbose(VERB_DETAIL, "switching log to %s",
use_syslog?"syslog":(filename&&filename[0]?filename:"stderr"));
if(logfile && logfile != stderr)
fclose(logfile);
void
log_hex(const char* msg, void* data, size_t length)
{
- size_t i;
+ size_t i, j;
uint8_t* data8 = (uint8_t*)data;
const char* hexchar = "0123456789ABCDEF";
- char* buf = malloc(length*2 + 1); /* alloc hex chars + \0 */
- size_t blocksize = 1024;
- for(i=0; i<length; i++) {
- buf[i*2] = hexchar[ data8[i] >> 4 ];
- buf[i*2 + 1] = hexchar[ data8[i] & 0xF ];
+ char buf[1024+1]; /* alloc blocksize hex chars + \0 */
+ const size_t blocksize = 1024;
+ size_t len;
+
+ if(length == 0) {
+ log_info("%s[%u]", msg, (unsigned)length);
+ return;
}
- buf[length*2] = 0;
- if(length < blocksize/2)
- log_info("%s[%u] %s", msg, (unsigned)length, buf);
- else {
- for(i=0; i<length*2; i+=blocksize) {
- log_info("%s[%u:%u] %.*s", msg, (unsigned)length,
- (unsigned)i/2, (int)blocksize, buf+i);
+
+ for(i=0; i<length; i+=blocksize/2) {
+ len = blocksize/2;
+ if(length - i < blocksize/2)
+ len = length - i;
+ for(j=0; j<len; j++) {
+ buf[j*2] = hexchar[ data8[i+j] >> 4 ];
+ buf[j*2 + 1] = hexchar[ data8[i+j] & 0xF ];
}
+ buf[len*2] = 0;
+ log_info("%s[%u:%u] %.*s", msg, (unsigned)length,
+ (unsigned)i, (int)len*2, buf);
}
- free(buf);
+}
+
+void log_buf(enum verbosity_value level, const char* msg, ldns_buffer* buf)
+{
+ if(verbosity < level)
+ return;
+ log_hex(msg, ldns_buffer_begin(buf), ldns_buffer_limit(buf));
}
*/
void log_hex(const char* msg, void* data, size_t length);
+/**
+ * Easy alternative for log_hex, takes a ldns_buffer.
+ * @param level: verbosity level for this message, compared to global
+ * verbosity setting.
+ * @param msg: string desc to print
+ * @param buf: the buffer.
+ */
+void log_buf(enum verbosity_value level, const char* msg, ldns_buffer* buf);
+
/**
* Log fatal error message, and exit the current process.
* Pass printf formatted arguments. No trailing newline is needed.
const char* data = (const char*)buf;
size_t total_count = 0;
+ fd_set_block(s);
while (total_count < size) {
ssize_t count
= write(s, data + total_count, size - total_count);
if (count == -1) {
if (errno != EAGAIN && errno != EINTR) {
+ fd_set_nonblock(s);
return 0;
} else {
continue;
}
total_count += count;
}
+ fd_set_nonblock(s);
return 1;
}
return 1;
}
+int
+fd_set_block(int s)
+{
+ int flag;
+ if((flag = fcntl(s, F_GETFL)) == -1) {
+ log_err("cannot fcntl F_GETFL: %s", strerror(errno));
+ flag = 0;
+ }
+ flag &= ~O_NONBLOCK;
+ if(fcntl(s, F_SETFL, flag) == -1) {
+ log_err("cannot fcntl F_SETFL: %s", strerror(errno));
+ return 0;
+ }
+ return 1;
+}
+
int
is_pow2(size_t num)
{
/**
* Write (blocking) to a nonblocking socket.
- * @param s: fd.
+ * @param s: fd. Is set to be nonblocking at exit.
* @param buf: data buffer.
* @param size: length of data to send.
* @return: 0 on error. errno is set.
*/
int fd_set_nonblock(int s);
+/**
+ * Set fd (back to) blocking.
+ * @param s: file descriptor.
+ * @return: 0 on error (error is printed to log).
+ */
+int fd_set_block(int s);
+
/**
* See if number is a power of 2.
* @param num: the value.
struct sockaddr* addr, socklen_t addrlen)
{
ssize_t sent;
+ log_assert(c->fd != -1);
+ log_assert(ldns_buffer_remaining(packet) > 0);
+ log_assert(addr && addrlen > 0);
sent = sendto(c->fd, ldns_buffer_begin(packet),
ldns_buffer_remaining(packet), 0,
addr, addrlen);
log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
ldns_buffer_clear(rep.c->buffer);
rep.addrlen = (socklen_t)sizeof(rep.addr);
+ log_assert(fd != -1);
+ log_assert(ldns_buffer_remaining(rep.c->buffer) > 0);
recv = recvfrom(fd, ldns_buffer_begin(rep.c->buffer),
ldns_buffer_remaining(rep.c->buffer), 0,
(struct sockaddr*)&rep.addr, &rep.addrlen);
/* accept incoming connection. */
rep.c = NULL;
rep.addrlen = (socklen_t)sizeof(rep.addr);
+ log_assert(fd != -1);
new_fd = accept(fd, (struct sockaddr*)&rep.addr, &rep.addrlen);
if(new_fd == -1) {
/* EINTR is signal interrupt. others are closed connection. */
&& errno != EPROTO
#endif /* EPROTO */
)
- log_err("accept failed: %s", strerror(errno));
+ return;
+ log_err("accept failed: %s", strerror(errno));
return;
}
/* find free tcp handler. */
if(!c->tcp_is_reading)
return 0;
+ log_assert(fd != -1);
if(c->tcp_byte_count < sizeof(uint16_t)) {
/* read length bytes */
r = read(fd, ldns_buffer_at(c->buffer, c->tcp_byte_count),
(int)ldns_buffer_limit(c->buffer));
}
+ log_assert(ldns_buffer_remaining(c->buffer) > 0);
r = read(fd, ldns_buffer_current(c->buffer),
ldns_buffer_remaining(c->buffer));
if(r == 0) {
log_assert(c->type == comm_tcp);
if(c->tcp_is_reading)
return 0;
+ log_assert(fd != -1);
if(c->tcp_byte_count == 0 && c->tcp_check_nb_connect) {
/* check for pending error from nonblocking connect */
/* from Stevens, unix network programming, vol1, 3rd ed, p450*/
iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
iov[1].iov_base = ldns_buffer_begin(c->buffer);
iov[1].iov_len = ldns_buffer_limit(c->buffer);
+ log_assert(iov[0].iov_len > 0);
+ log_assert(iov[1].iov_len > 0);
r = writev(fd, iov, 2);
if(r == -1) {
if(errno == EINTR || errno == EAGAIN)
}
return 1;
}
+ log_assert(ldns_buffer_remaining(c->buffer) > 0);
r = write(fd, ldns_buffer_current(c->buffer),
ldns_buffer_remaining(c->buffer));
if(r == -1) {
size_t iovlen)
{
log_assert(repinfo && repinfo->c);
+ log_assert(repinfo->c->fd != -1);
+ log_assert(repinfo->addrlen > 0);
if(repinfo->c->type == comm_udp) {
struct msghdr hdr;
memset(&hdr, 0, sizeof(hdr));
void
comm_timer_set(struct comm_timer* timer, struct timeval* tv)
{
+ log_assert(tv);
if(timer->ev_timer->enabled)
comm_timer_disable(timer);
evtimer_add(&timer->ev_timer->ev, tv);