Ejemplo n.º 1
0
void querycb(struct confirm_query *q)/*{{{*/
{
	char *dstaddr = sockaddr_tostr(&q->dst);
	char *ipaddr = sockaddr_tostr(&q->ip);
	printf("dst %s ttl %d ip %s\n", dstaddr, (int)q->ttl, ipaddr);
	free(dstaddr);
	free(ipaddr);
	confirm_query_destroy(q);
}/*}}}*/
Ejemplo n.º 2
0
static void rrl_log_state(const struct sockaddr_storage *ss, uint16_t flags, uint8_t cls)
{
#ifdef RRL_ENABLE_LOG
    char addr_str[SOCKADDR_STRLEN] = {0};
    sockaddr_tostr(addr_str, sizeof(addr_str), ss);

    const char *what = "leaves";
    if (flags & RRL_BF_ELIMIT) {
        what = "enters";
    }

    log_notice("rate limiting, address '%s' class '%s' %s limiting",
               addr_str, rrl_clsstr(cls), what);
#endif
}
Ejemplo n.º 3
0
static void rrl_log_state(const sockaddr_t *a, uint16_t flags, uint8_t cls)
{
#ifdef RRL_ENABLE_LOG
	char saddr[SOCKADDR_STRLEN];
	memset(saddr, 0, sizeof(saddr));
	sockaddr_tostr(a, saddr, sizeof(saddr));
	const char *what = "leaves";
	if (flags & RRL_BF_ELIMIT) {
		what = "enters";
	}

	log_server_notice("Address '%s' %s rate-limiting (class '%s').\n",
	                  saddr, what, rrl_clsstr(cls));
#endif
}
Ejemplo n.º 4
0
/*! \brief Sweep TCP connection. */
static enum fdset_sweep_state tcp_sweep(fdset_t *set, int i, void *data)
{
	UNUSED(data);
	assert(set && i < set->n && i >= 0);
	int fd = set->pfd[i].fd;

	/* Best-effort, name and shame. */
	struct sockaddr_storage ss;
	socklen_t len = sizeof(struct sockaddr_storage);
	if (getpeername(fd, (struct sockaddr*)&ss, &len) == 0) {
		char addr_str[SOCKADDR_STRLEN] = {0};
		sockaddr_tostr(addr_str, sizeof(addr_str), &ss);
		log_notice("TCP, terminated inactive client, address '%s'", addr_str);
	}

	close(fd);

	return FDSET_SWEEP;
}
Ejemplo n.º 5
0
/*! \brief Sweep TCP connection. */
static enum fdset_sweep_state tcp_sweep(fdset_t *set, int i, void *data)
{
	UNUSED(data);
	assert(set && i < set->n && i >= 0);

	int fd = set->pfd[i].fd;

	struct sockaddr_storage ss;
	socklen_t len = sizeof(struct sockaddr_storage);
	memset(&ss, 0, len);
	if (getpeername(fd, (struct sockaddr*)&ss, &len) < 0) {
		dbg_net("tcp: sweep getpeername() on invalid socket=%d\n", fd);
		return FDSET_SWEEP;
	}

	/* Translate */
	char addr_str[SOCKADDR_STRLEN] = {0};
	sockaddr_tostr(addr_str, sizeof(addr_str), &ss);

	log_notice("connection terminated due to inactivity, address '%s'", addr_str);
	close(fd);
	return FDSET_SWEEP;
}
Ejemplo n.º 6
0
/*!
 * \brief TCP event handler function.
 */
static int tcp_handle(tcp_context_t *tcp, int fd,
                      struct iovec *rx, struct iovec *tx)
{
	/* Create query processing parameter. */
	struct sockaddr_storage ss;
	memset(&ss, 0, sizeof(struct sockaddr_storage));
	struct process_query_param param = {0};
	param.socket = fd;
	param.remote = &ss;
	param.server = tcp->server;
	param.thread_id = tcp->thread_id;
	rx->iov_len = KNOT_WIRE_MAX_PKTSIZE;
	tx->iov_len = KNOT_WIRE_MAX_PKTSIZE;

	/* Receive peer name. */
	socklen_t addrlen = sizeof(struct sockaddr_storage);
	if (getpeername(fd, (struct sockaddr *)&ss, &addrlen) < 0) {
		;
	}

	/* Timeout. */
	rcu_read_lock();
	conf_val_t *val = &conf()->cache.srv_tcp_reply_timeout;
	int timeout = conf_int(val) * 1000;
	rcu_read_unlock();

	/* Receive data. */
	int ret = net_dns_tcp_recv(fd, rx->iov_base, rx->iov_len, timeout);
	if (ret <= 0) {
		if (ret == KNOT_EAGAIN) {
			char addr_str[SOCKADDR_STRLEN] = {0};
			sockaddr_tostr(addr_str, sizeof(addr_str), &ss);
			log_warning("TCP, connection timed out, address '%s'",
			            addr_str);
		}
		return KNOT_ECONNREFUSED;
	} else {
		rx->iov_len = ret;
	}

	knot_mm_t *mm = tcp->overlay.mm;

	/* Initialize processing overlay. */
	ret = knot_overlay_init(&tcp->overlay, mm);
	if (ret != KNOT_EOK) {
		return ret;
	}
	ret = knot_overlay_add(&tcp->overlay, NS_PROC_QUERY, &param);
	if (ret != KNOT_EOK) {
		return ret;
	}

	/* Create packets. */
	knot_pkt_t *ans = knot_pkt_new(tx->iov_base, tx->iov_len, mm);
	knot_pkt_t *query = knot_pkt_new(rx->iov_base, rx->iov_len, mm);

	/* Input packet. */
	(void) knot_pkt_parse(query, 0);
	int state = knot_overlay_consume(&tcp->overlay, query);

	/* Resolve until NOOP or finished. */
	ret = KNOT_EOK;
	while (state & (KNOT_STATE_PRODUCE|KNOT_STATE_FAIL)) {
		state = knot_overlay_produce(&tcp->overlay, ans);

		/* Send, if response generation passed and wasn't ignored. */
		if (ans->size > 0 && !(state & (KNOT_STATE_FAIL|KNOT_STATE_NOOP))) {
			if (net_dns_tcp_send(fd, ans->wire, ans->size, timeout) != ans->size) {
				ret = KNOT_ECONNREFUSED;
				break;
			}
		}
	}

	/* Reset after processing. */
	knot_overlay_finish(&tcp->overlay);
	knot_overlay_deinit(&tcp->overlay);

	/* Cleanup. */
	knot_pkt_free(&query);
	knot_pkt_free(&ans);

	return ret;
}
Ejemplo n.º 7
0
/*!
 * \brief TCP event handler function.
 */
static int tcp_handle(tcp_context_t *tcp, int fd,
                      struct iovec *rx, struct iovec *tx)
{
	/* Create query processing parameter. */
	struct sockaddr_storage ss;
	memset(&ss, 0, sizeof(struct sockaddr_storage));
	struct process_query_param param = {0};
	param.socket = fd;
	param.remote = &ss;
	param.server = tcp->server;
	param.thread_id = tcp->thread_id;
	rx->iov_len = KNOT_WIRE_MAX_PKTSIZE;
	tx->iov_len = KNOT_WIRE_MAX_PKTSIZE;

	/* Receive peer name. */
	socklen_t addrlen = sizeof(struct sockaddr_storage);
	if (getpeername(fd, (struct sockaddr *)&ss, &addrlen) < 0) {
		;
	}

	/* Timeout. */
	struct timeval tmout = { conf()->max_conn_reply, 0 };

	/* Receive data. */
	int ret = tcp_recv_msg(fd, rx->iov_base, rx->iov_len, &tmout);
	if (ret <= 0) {
		dbg_net("tcp: client on fd=%d disconnected\n", fd);
		if (ret == KNOT_EAGAIN) {
			rcu_read_lock();
			char addr_str[SOCKADDR_STRLEN] = {0};
			sockaddr_tostr(addr_str, sizeof(addr_str), &ss);
			log_warning("connection timed out, address '%s', "
			            "timeout %d seconds",
			            addr_str, conf()->max_conn_idle);
			rcu_read_unlock();
		}
		return KNOT_ECONNREFUSED;
	} else {
		rx->iov_len = ret;
	}

	/* Create packets. */
	mm_ctx_t *mm = tcp->overlay.mm;
	knot_pkt_t *ans = knot_pkt_new(tx->iov_base, tx->iov_len, mm);
	knot_pkt_t *query = knot_pkt_new(rx->iov_base, rx->iov_len, mm);

	/* Initialize processing overlay. */
	knot_overlay_init(&tcp->overlay, mm);
	knot_overlay_add(&tcp->overlay, NS_PROC_QUERY, &param);

	/* Input packet. */
	int state = knot_overlay_in(&tcp->overlay, query);

	/* Resolve until NOOP or finished. */
	ret = KNOT_EOK;
	while (state & (KNOT_NS_PROC_FULL|KNOT_NS_PROC_FAIL)) {
		state = knot_overlay_out(&tcp->overlay, ans);

		/* Send, if response generation passed and wasn't ignored. */
		if (ans->size > 0 && !(state & (KNOT_NS_PROC_FAIL|KNOT_NS_PROC_NOOP))) {
			if (tcp_send_msg(fd, ans->wire, ans->size) != ans->size) {
				ret = KNOT_ECONNREFUSED;
				break;
			}
		}
	}

	/* Reset after processing. */
	knot_overlay_finish(&tcp->overlay);
	knot_overlay_deinit(&tcp->overlay);

	/* Cleanup. */
	knot_pkt_free(&query);
	knot_pkt_free(&ans);

	return ret;
}
Ejemplo n.º 8
0
int zone_dump_text(knot_zone_contents_t *zone, FILE *file)
{
    if (zone == NULL || file == NULL) {
        return KNOT_EINVAL;
    }

    // Allocate auxiliary buffer for dumping operations.
    char *buf = malloc(DUMP_BUF_LEN);
    if (buf == NULL) {
        ERR_ALLOC_FAILED;
        return KNOT_ENOMEM;
    }

    fprintf(file, ";; Zone dump (Knot DNS %s)\n", PACKAGE_VERSION);

    // Set structure with parameters.
    dump_params_t params;
    params.ret = KNOT_ERROR;
    params.file = file;
    params.buf = buf;
    params.buflen = DUMP_BUF_LEN;
    params.rr_count = 0;
    params.origin = knot_node_owner(knot_zone_contents_apex(zone));
    params.style = &KNOT_DUMP_STYLE_DEFAULT;

    // Dump standard zone records.
    knot_zone_contents_tree_apply_inorder(zone, node_dump_text, &params);
    if (params.ret != KNOT_EOK) {
        return params.ret;
    }

    // Dump NSEC3 zone records.
    knot_zone_contents_nsec3_apply_inorder(zone, node_dump_text, &params);
    if (params.ret != KNOT_EOK) {
        return params.ret;
    }

    // Create formated date-time string.
    time_t now = time(NULL);
    struct tm tm;
    localtime_r(&now, &tm);
    char date[64];
    strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S %Z", &tm);

    // Dump trailing statistics.
    fprintf(file, ";; Written %"PRIu64" records\n"
            ";; Time %s\n",
            params.rr_count, date);

    // Get master information.
    sockaddr_t *master = &((zonedata_t *)zone->zone->data)->xfr_in.master;

    int port = sockaddr_portnum(master);

    // If a master server is configured, dump info about it.
    if (port >= 0) {
        char addr[INET6_ADDRSTRLEN] = "NULL";
        sockaddr_tostr(master, addr, sizeof(addr));

        fprintf(file, ";; Transfered from %s#%i\n", addr, port);
    }

    free(buf);

    return KNOT_EOK;
}