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); }/*}}}*/
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 }
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 }
/*! \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; }
/*! \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; }
/*! * \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, ¶m); 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; }
/*! * \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, ¶m); /* 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; }
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, ¶ms); if (params.ret != KNOT_EOK) { return params.ret; } // Dump NSEC3 zone records. knot_zone_contents_nsec3_apply_inorder(zone, node_dump_text, ¶ms); 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; }