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:
wouter 2007-10-16 12:26:09 +00:00
parent b21244ba76
commit 8b95e7f068
12 changed files with 105 additions and 42 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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.");

View File

@ -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);

View File

@ -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))

View File

@ -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 */

View File

@ -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));
}

View File

@ -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.

View File

@ -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)
{

View File

@ -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.

View File

@ -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);