Ejemplo n.º 1
0
static int notify_check_and_schedule(knot_nameserver_t *nameserver,
                                     const knot_zone_t *zone,
                                     sockaddr_t *from)
{
	if (zone == NULL || from == NULL || knot_zone_data(zone) == NULL) {
		return KNOT_EINVAL;
	}

	/* Check ACL for notify-in. */
	zonedata_t *zd = (zonedata_t *)knot_zone_data(zone);
	if (from) {
		if (acl_match(zd->notify_in, from, 0) == ACL_DENY) {
			/* rfc1996: Ignore request and report incident. */
			return KNOT_EDENIED;
		}
	}

	/* Cancel REFRESH/RETRY timer. */
	evsched_t *sched = ((server_t *)knot_ns_get_data(nameserver))->sched;
	event_t *refresh_ev = zd->xfr_in.timer;
	if (refresh_ev) {
		dbg_notify("notify: expiring REFRESH timer\n");
		evsched_cancel(sched, refresh_ev);

		/* Set REFRESH timer for now. */
		evsched_schedule(sched, refresh_ev, 0);
	}

	return KNOT_EOK;
}
Ejemplo n.º 2
0
static void* dbgs(void* arg) {
  EXPECT_EQ(0, sem_wait(&dbg_lock));

  uint saved_lvl = fbi_get_debug();
  fbi_set_debug(UINT_MAX);

  long unsigned exp_tid = (long unsigned) pthread_self();
  long unsigned tid = 0;

#define TID_SCAN_STR "%20lu%*[^\n]"
  dbg_critical("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  dbg_error("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  dbg_warning("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  dbg_notify("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  dbg_info("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  dbg_debug("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  dbg_spew("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  dbg_low("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  dbg_medium("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  dbg_high("Test dbg");
  EXPECT_EQ(1, fscanf(redir, TID_SCAN_STR, &tid));
  EXPECT_EQ(exp_tid, tid);

  fbi_set_debug(saved_lvl);
  EXPECT_EQ(0, sem_post(&dbg_lock));
  return nullptr;
}
Ejemplo n.º 3
0
int notify_create_response(knot_packet_t *request, uint8_t *buffer,
                           size_t *size)
{
	knot_packet_t *response =
		knot_packet_new(KNOT_PACKET_PREALLOC_QUERY);
	CHECK_ALLOC_LOG(response, KNOT_ENOMEM);

	/* Set maximum packet size. */
	int rc = knot_packet_set_max_size(response, *size);
	if (rc == KNOT_EOK) {
		rc = knot_response_init_from_query(response, request, 1);
	}

	/* Aggregated result check. */
	if (rc != KNOT_EOK) {
		dbg_notify("%s: failed to init response packet: %s",
			   "notify_create_response", knot_strerror(rc));
		knot_packet_free(&response);
		return KNOT_EINVAL;
	}

	// TODO: copy the SOA in Answer section
	uint8_t *wire = NULL;
	size_t wire_size = 0;
	rc = knot_packet_to_wire(response, &wire, &wire_size);
	if (rc != KNOT_EOK) {
		knot_packet_free(&response);
		return rc;
	}

	if (wire_size > *size) {
		knot_packet_free(&response);
		return KNOT_ESPACE;
	}

	memcpy(buffer, wire, wire_size);
	*size = wire_size;

	knot_packet_dump(response);
	knot_packet_free(&response);

	return KNOT_EOK;
}
Ejemplo n.º 4
0
int notify_process_request(knot_nameserver_t *ns,
                           knot_packet_t *notify,
                           sockaddr_t *from,
                           uint8_t *buffer, size_t *size)
{
	/*! \todo Most of this function is identical to xfrin_transfer_needed()
	 *        - it will be fine to merge the code somehow.
	 */

	if (notify == NULL || ns == NULL || buffer == NULL
	    || size == NULL || from == NULL) {
		dbg_notify("notify: invalid parameters for %s()\n",
		           "notify_process_request");
		return KNOT_EINVAL;
	}

	int ret = KNOT_EOK;

	dbg_notify("notify: parsing rest of the packet\n");
	if (notify->parsed < notify->size) {
		if (knot_packet_parse_rest(notify, 0) != KNOT_EOK) {
			dbg_notify("notify: failed to parse NOTIFY query\n");
			knot_ns_error_response_from_query(ns, notify,
			                                  KNOT_RCODE_FORMERR,
			                                  buffer, size);
			return KNOT_EOK;
		}
	}

	// check if it makes sense - if the QTYPE is SOA
	if (knot_packet_qtype(notify) != KNOT_RRTYPE_SOA) {
		// send back FORMERR
		knot_ns_error_response_from_query(ns, notify,
		                                  KNOT_RCODE_FORMERR, buffer,
		                                  size);
		return KNOT_EOK;
	}

	// create NOTIFY response
	dbg_notify("notify: creating response\n");
	ret = notify_create_response(notify, buffer, size);
	if (ret != KNOT_EOK) {
		dbg_notify("notify: failed to create NOTIFY response\n");
		knot_ns_error_response_from_query(ns, notify,
		                                  KNOT_RCODE_SERVFAIL, buffer,
		                                  size);
		return KNOT_EOK;
	}

	/* Process notification. */
	ret = KNOT_ENOZONE;
	unsigned serial = 0;
	const knot_dname_t *qname = knot_packet_qname(notify);
	rcu_read_lock(); /* z */
	const knot_zone_t *z = knot_zonedb_find_zone_for_name(ns->zone_db, qname);
	if (z != NULL) {
		ret = notify_check_and_schedule(ns, z, from);
		const knot_rrset_t *soa_rr = NULL;
		soa_rr = knot_packet_answer_rrset(notify, 0);
		if (soa_rr && knot_rrset_type(soa_rr) == KNOT_RRTYPE_SOA) {
			serial = knot_rrset_rdata_soa_serial(soa_rr);
		}
	}
	rcu_read_unlock();

	int rcode = KNOT_RCODE_NOERROR;
	switch (ret) {
	case KNOT_ENOZONE: rcode = KNOT_RCODE_NOTAUTH; break;
	case KNOT_EACCES:  rcode = KNOT_RCODE_REFUSED; break;
	default: break;
	}

	/* Format resulting log message. */
	char *qstr = knot_dname_to_str(qname);
	char *fromstr = xfr_remote_str(from, NULL);
	if (rcode != KNOT_RCODE_NOERROR) {
		knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_REFUSED,
		                                  buffer, size);
		log_server_warning(NOTIFY_MSG "%s\n", qstr, fromstr, knot_strerror(ret));
		ret = KNOT_EOK; /* Send response. */
	} else {
		log_server_info(NOTIFY_MSG NOTIFY_XMSG "\n", qstr, fromstr, serial);
	}
	free(qstr);
	free(fromstr);

	return ret;
}