assertions, zero termination for gethostname, log_hex without malloc.
git-svn-id: https://unbound.nlnetlabs.nl/svn/trunk@679 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
b21244ba76
commit
8b95e7f068
@ -269,8 +269,6 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
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);
|
||||
@ -384,7 +382,7 @@ daemon_stop_others(struct daemon* daemon)
|
||||
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);
|
||||
|
@ -624,10 +624,11 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
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);
|
||||
}
|
||||
@ -797,22 +798,22 @@ worker_sighandler(int sig, void* arg)
|
||||
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;
|
||||
@ -949,6 +950,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
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;
|
||||
|
@ -1,3 +1,8 @@
|
||||
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.
|
||||
|
@ -91,7 +91,7 @@ serviced_cmp(const void* key1, const void* key2)
|
||||
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) {
|
||||
@ -122,6 +122,7 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
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))
|
||||
@ -249,17 +250,12 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||
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.");
|
||||
@ -1125,6 +1121,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
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.");
|
||||
|
@ -206,10 +206,8 @@ test_buffers(ldns_buffer* pkt, ldns_buffer* out)
|
||||
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);
|
||||
|
@ -701,8 +701,7 @@ add_rr_to_rrset(struct rrset_parse* rrset, ldns_buffer* pkt,
|
||||
/*
|
||||
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))
|
||||
|
@ -81,7 +81,7 @@ void ub_thread_sig_unblock(int sig)
|
||||
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 */
|
||||
|
42
util/log.c
42
util/log.c
@ -83,7 +83,7 @@ log_init(const char* filename, int use_syslog)
|
||||
|| 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);
|
||||
@ -218,23 +218,35 @@ verbose(enum verbosity_value level, const char* format, ...)
|
||||
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));
|
||||
}
|
||||
|
@ -125,6 +125,15 @@ void log_warn(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
|
||||
*/
|
||||
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.
|
||||
|
@ -61,11 +61,13 @@ write_socket(int s, const void *buf, size_t size)
|
||||
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;
|
||||
@ -73,6 +75,7 @@ write_socket(int s, const void *buf, size_t size)
|
||||
}
|
||||
total_count += count;
|
||||
}
|
||||
fd_set_nonblock(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -92,6 +95,22 @@ fd_set_nonblock(int s)
|
||||
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)
|
||||
{
|
||||
|
@ -98,7 +98,7 @@ int str_is_ip6(const char* str);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -113,6 +113,13 @@ write_socket(int s, const void *buf, size_t size);
|
||||
*/
|
||||
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.
|
||||
|
@ -161,6 +161,9 @@ comm_point_send_udp_msg(struct comm_point *c, ldns_buffer* packet,
|
||||
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);
|
||||
@ -189,6 +192,8 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||
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);
|
||||
@ -234,6 +239,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
|
||||
/* 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. */
|
||||
@ -244,7 +250,8 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
|
||||
&& errno != EPROTO
|
||||
#endif /* EPROTO */
|
||||
)
|
||||
log_err("accept failed: %s", strerror(errno));
|
||||
return;
|
||||
log_err("accept failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
/* find free tcp handler. */
|
||||
@ -330,6 +337,7 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
|
||||
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),
|
||||
@ -361,6 +369,7 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
|
||||
(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) {
|
||||
@ -391,6 +400,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
||||
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*/
|
||||
@ -414,6 +424,8 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
||||
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)
|
||||
@ -431,6 +443,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
||||
}
|
||||
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) {
|
||||
@ -832,6 +845,8 @@ comm_point_send_reply_iov(struct comm_reply* repinfo, struct iovec* iov,
|
||||
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));
|
||||
@ -1005,6 +1020,7 @@ comm_timer_disable(struct comm_timer* timer)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user