示例#1
0
文件: dns.c 项目: jintwo/sns
void make_reply(dns_question_t *question, char *addr, bool use_compression, dns_record_t *answer)
{
    answer->use_compression = use_compression;
    if (use_compression) {
        answer->cptr = "\xc0\x0c";
    } else {
        answer->label = question->label;
    }
    answer->rtype = question->qtype;
    answer->rclass = question->qclass;
    answer->ttl = 86400;
    answer->rdlength = 4;
    answer->rdata = encode_ip_address(addr);
}
示例#2
0
/****************************************************************************\
 * Name          : ncs_logmsg_int
 *
 * Description   : This function is use for Message Logging.
 *
 * Arguments     : svc_id       : Service ID.
 *                 fmat_id      : Format ID.
 *                 str_table_id : String tabel ID.
 *                 category     : Message category.
 *                 severity     : Message Severity.
 *                 fmat_type    : Format type to be used for logging.
 *
 * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
 *
 * Notes         : None.
\*****************************************************************************/
uns32 ncs_logmsg_int(SS_SVC_ID svc_id,
		     uns32 inst_id,
		     uns8 fmat_id, uns8 str_table_id, uns32 category, uns8 severity, char *fmat_type, va_list argp)
{
	uns32 i = 0, length = 0;
	DTA_CB *inst = &dta_cb;
	DTSV_MSG *msg;
	NCSFL_HDR *hdr;
	REG_TBL_ENTRY *svc;
	NCS_UBAID *uba = NULL;
	uns8 *data;
	uns32 send_pri;
	int warning_rmval = 0;

    /*************************************************************************\
    * As different fields of the log-message are encoded, the minimum DTS     
    * required to understand the message may change.
    \*************************************************************************/
	uns32 act_dts_ver;	/* Active dts's version. */
	uns32 min_dts_ver;	/* Minimum DTS version that understands message */

	DTA_LOG_BUFFER *list = &inst->log_buffer;
	DTA_BUFFERED_LOG *buf = NULL;

	/* Check if DTA is created. Continue logging if DTA is created */
	if (inst->created == FALSE) {
		return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE,
					  "ncs_logmsg: DTA does not exist. First create DTA before logging.", svc_id);
	}

	m_DTA_LK(&inst->lock);

	/* 
	 * Check whether DTS exist. If DTS does not exist then there is no 
	 * point in logging message. Return failure.
	 * Changed as of 15th June 2006. 
	 * If FLS doesn't exist & number of buffer msgs is more than DTA_BUF_LIMIT
	 * then drop the message and return failure.
	 */
	if ((inst->dts_exist == FALSE) && (list->num_of_logs >= DTA_BUF_LIMIT)) {
		m_DTA_UNLK(&inst->lock);
		return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE,
					  "ncs_logmsg: DTS does not exist & DTA log buffer is full. Log message is dropped.",
					  svc_id);
	}

	/*
	 * Check whether the Sevice is registered with the DTSv. If not already
	 * bound return failure.
	 */
	if (((svc = (REG_TBL_ENTRY *)ncs_patricia_tree_get(&inst->reg_tbl, (const uns8 *)&svc_id)) == NULL)) {
		m_DTA_UNLK(&inst->lock);
		return NCSCC_RC_FAILURE;
	}
#if (DTA_FLOW == 1)
	/* Check whether logging is enabled beyond default level for this service 
	 * i.e. INFO or DEBUG levels are enabled or not. 
	 * If logging levels are increased to INFO/DEBUG, don't apply DTA message
	 * thresholding. Otherwise DTA defines MAX threshold of 2000 messages after
	 * which all messages will be dropped. In such cases, check the rate of 
	 * logging for such processes.
	 */
	if (svc->severity_bit_map > 0xFC) {
		/* Don't apply thresholding of messages here */
	} else {
		/* Else apply thresholding */
		if (inst->msg_count > DTA_MAX_THRESHOLD) {
			m_DTA_UNLK(&inst->lock);
			warning_rmval =
			    m_DTA_DBG_SINK(NCSCC_RC_FAILURE,
					   "ncs_logmsg: DTA queued msgs exceeds 2000. Message will be dropped.");
			return NCSCC_RC_FAILURE;
		}
	}

	/* Drop INFO/DEBUG messages at source during congestion */
	if ((inst->dts_congested == TRUE) && (severity < NCSFL_SEV_NOTICE)) {
		m_DTA_UNLK(&inst->lock);
		return NCSCC_RC_FAILURE;
	}
#endif

	msg = m_MMGR_ALLOC_DTSV_MSG;
	if (msg == NULL) {
		m_DTA_UNLK(&inst->lock);
		return m_DTA_DBG_SINK(NCSCC_RC_FAILURE, "ncs_logmsg: Memory allocation failer for DTSV_MSG");
	}
	memset(msg, '\0', sizeof(DTSV_MSG));

	hdr = &msg->data.data.msg.log_msg.hdr;

	hdr->category = category;
	hdr->severity = severity;
	hdr->fmat_id = fmat_id;
	hdr->ss_id = svc_id;
	hdr->inst_id = inst_id;
	hdr->str_table_id = str_table_id;

	/* Apply the filter Policies. If the logging is disabled
	 * then return success. We are returning success here since it may 
	 * possible that logging is disabled by user.
	 */
	if (dta_svc_reg_log_en(svc, &msg->data.data.msg.log_msg) == NCSCC_RC_FAILURE) {
		m_DTA_UNLK(&inst->lock);
		m_MMGR_FREE_DTSV_MSG(msg);
		return NCSCC_RC_SUCCESS;
	}

	if (NCSCC_RC_SUCCESS != dta_copy_octets(&hdr->fmat_type, fmat_type, (uns16)(1 + strlen(fmat_type)))) {
		m_DTA_UNLK(&inst->lock);
		m_MMGR_FREE_DTSV_MSG(msg);
		return m_DTA_DBG_SINK(NCSCC_RC_FAILURE, "ncs_logmsg_int: Copy octet failed.");
	}

	/* Flexlog Agent fills in the TIME STAMP value */
	m_GET_MSEC_TIME_STAMP(&hdr->time.seconds, &hdr->time.millisecs);

	msg->vrid = inst->vrid;
	msg->msg_type = DTA_LOG_DATA;
	uba = &msg->data.data.msg.log_msg.uba;

	/* act_dts_ver needs to be recorded before inst->lock is unlocked  */
	act_dts_ver = inst->act_dts_ver;
	min_dts_ver = 1;	/* DTS should be at least this version to interpret the
				   encoded message. This directly determines the
				   message format vesion */

	m_DTA_UNLK(&inst->lock);

	memset(uba, '\0', sizeof(NCS_UBAID));

	if (ncs_enc_init_space(uba) != NCSCC_RC_SUCCESS) {
		m_MMGR_FREE_OCT(hdr->fmat_type);
		m_MMGR_FREE_DTSV_MSG(msg);
		return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE, "ncs_logmsg: Unable to init user buff", svc_id);
	}

	while (fmat_type[i] != '\0') {
		switch (fmat_type[i]) {
		case 'T':
			{
				break;
			}
		case 'I':
			{
				uns32 idx;
				idx = m_NCSFL_MAKE_IDX((uns32)str_table_id, (uns32)va_arg(argp, uns32));
				data = ncs_enc_reserve_space(uba, sizeof(uns32));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_32bit(&data, idx);
				ncs_enc_claim_space(uba, sizeof(uns32));
				break;
			}
		case 'L':
			{
				data = ncs_enc_reserve_space(uba, sizeof(uns32));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_32bit(&data, va_arg(argp, uns32));
				ncs_enc_claim_space(uba, sizeof(uns32));
				break;
			}

		case 'C':
			{
				char *str = va_arg(argp, char *);

				if (NULL == str) {
					if (uba->start != NULL)
						m_MMGR_FREE_BUFR_LIST(uba->start);
					m_MMGR_FREE_OCT(hdr->fmat_type);
					m_MMGR_FREE_DTSV_MSG(msg);
					return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE,
								  "ncs_logmsg: NULL string passed for format type 'C'",
								  svc_id);
				}

				length = strlen(str) + 1;

				if (length > (DTS_MAX_SIZE_DATA * 3)) {
					if (uba->start != NULL)
						m_MMGR_FREE_BUFR_LIST(uba->start);
					m_MMGR_FREE_OCT(hdr->fmat_type);
					m_MMGR_FREE_DTSV_MSG(msg);
					return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE,
								  "ncs_logmsg: Can not log string with more than 1536 characters",
								  svc_id);
				}

				data = ncs_enc_reserve_space(uba, sizeof(uns32));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_32bit(&data, length);
				ncs_enc_claim_space(uba, sizeof(uns32));

				ncs_encode_n_octets_in_uba(uba, (uns8 *)str, length);

				break;
			}
		case 'M':
			{
				data = ncs_enc_reserve_space(uba, sizeof(uns16));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_16bit(&data, (uns16)va_arg(argp, uns32));
				ncs_enc_claim_space(uba, sizeof(uns16));
				break;
			}
		case 'D':
			{
				NCSFL_MEM mem_d = va_arg(argp, NCSFL_MEM);

				if (mem_d.len > DTS_MAX_SIZE_DATA)
					mem_d.len = DTS_MAX_SIZE_DATA;

				/* Versioning & 64-bit compatibility changes - Encode the msg 
				 * for format 'D' after checking the version of the current 
				 * Active DTS.
				 * If Active DTS has MDS version 1 and DTA arch 64-bit then, 
				 * encode 32 bits with reserved bit-pattern 0x6464. 
				 * Else, if DTS has MDS version 2, then encode 64-bits of the 
				 * address.
				 * Also fill DTA_LOG_MSG structure with the DTS version as seen
				 * while encoding.
				 */

				/* The 'D' message is encoded at version 1 or 2 based on 
				   whether DTS is at version 1 or higher respectively. 

				 */
				/* Check for compatibility with receiving DTS version
				   and set the minimum DTS version required */
				if (act_dts_ver == 1) {
					/* Compatible DTS. Update minimum DTS version required */
					if (min_dts_ver < 1)
						min_dts_ver = 1;

					data = ncs_enc_reserve_space(uba, (sizeof(uns16) + sizeof(uns32)));
					if (data == NULL)
						goto reserve_error;
					ncs_encode_16bit(&data, mem_d.len);

					if (sizeof(inst) == 8) {
						/* Attempt to print 64-bit address on 32-bit DTS. 
						 * Print pre-defined bit pattern to indicate error. 
						 */
						ncs_encode_32bit(&data, (uns32)0x6464);
					} else if (sizeof(inst) == 4) {
						/* Do it the old way */
						ncs_encode_32bit(&data, NCS_PTR_TO_UNS32_CAST(mem_d.addr));
					}
					ncs_enc_claim_space(uba, (sizeof(uns16) + sizeof(uns32)));
				}
				/* Act DTS on version 2 or higher , then encode all 64-bits */
				else {
					/* Compatible DTS. Update minimum DTS version required */
					if (min_dts_ver < 2)
						min_dts_ver = 2;

					data = ncs_enc_reserve_space(uba, (sizeof(uns16) + sizeof(uns64)));
					if (data == NULL)
						goto reserve_error;
					ncs_encode_16bit(&data, mem_d.len);
					ncs_encode_64bit(&data, (uns64)(long)mem_d.addr);
					ncs_enc_claim_space(uba, (sizeof(uns16) + sizeof(uns64)));
				}

				ncs_encode_n_octets_in_uba(uba, (uns8 *)mem_d.dump, (uns32)mem_d.len);

				break;
			}
		case 'P':
			{
				NCSFL_PDU pdu = va_arg(argp, NCSFL_PDU);

				if (pdu.len > DTS_MAX_SIZE_DATA)
					pdu.len = DTS_MAX_SIZE_DATA;

				data = ncs_enc_reserve_space(uba, sizeof(uns16));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_16bit(&data, pdu.len);
				ncs_enc_claim_space(uba, sizeof(uns16));

				ncs_encode_n_octets_in_uba(uba, (uns8 *)pdu.dump, (uns32)pdu.len);

				break;
			}
		case 'A':
			{
				encode_ip_address(uba, va_arg(argp, NCS_IP_ADDR));
				break;
			}
		case 'S':
			{
				data = ncs_enc_reserve_space(uba, sizeof(uns8));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_8bit(&data, (uns8)va_arg(argp, uns32));
				ncs_enc_claim_space(uba, sizeof(uns8));

				break;
			}
			/* Added code for handling float values */
		case 'F':
			{
				char str[DTS_MAX_DBL_DIGITS] = "";
				int num_chars = sprintf(str, "%f", va_arg(argp, double));
				if (num_chars == 0) {
					warning_rmval =
					    m_DTA_DBG_SINK(NCSCC_RC_FAILURE,
							   "ncs_logmsg: Float to string conversion gives NULL");
					goto reserve_error;
				}
				length = strlen(str) + 1;
				data = ncs_enc_reserve_space(uba, sizeof(uns32));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_32bit(&data, length);
				ncs_enc_claim_space(uba, sizeof(uns32));

				ncs_encode_n_octets_in_uba(uba, (uns8 *)str, length);
				break;
			}
		case 'N':
			{
				char str[DTS_MAX_DBL_DIGITS] = "";
				int num_chars = 0;

				/* Check for compatibility with receiving DTS version
				   and set the minimum DTS version required */
				if (act_dts_ver == 1) {
					/* Incompatible DTS */
					goto reserve_error;
				} else {
					/* Compatible DTS. Update minimum DTS version required */
					if (min_dts_ver < 2)
						min_dts_ver = 2;
				}

				num_chars = sprintf(str, "%lld", va_arg(argp, long long));

                                if (num_chars == 0) {
					warning_rmval =
					    m_DTA_DBG_SINK(NCSCC_RC_FAILURE,
							   "ncs_logmsg: long long to string conversion gives NULL");
					goto reserve_error;
				}

				length = strlen(str) + 1;
				data = ncs_enc_reserve_space(uba, sizeof(uns32));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_32bit(&data, length);
				ncs_enc_claim_space(uba, sizeof(uns32));

				ncs_encode_n_octets_in_uba(uba, (uns8 *)str, length);
				break;
			}
		case 'U':
			{
				char str[DTS_MAX_DBL_DIGITS] = "";
				int num_chars = 0;

				/* Check for compatibility with receiving DTS version
				   and set the minimum DTS version required */
				if (act_dts_ver == 1) {
					/* Incompatible DTS */
					goto reserve_error;
				} else {
					/* Compatible DTS. Update minimum DTS version required */
					if (min_dts_ver < 2)
						min_dts_ver = 2;
				}

				num_chars = sprintf(str, "%llu", va_arg(argp, unsigned long long));
                                if (num_chars == 0) {
					warning_rmval =
					    m_DTA_DBG_SINK(NCSCC_RC_FAILURE,
							   "ncs_logmsg: unsigned long long to string conversion gives NULL");
					goto reserve_error;
				}

				length = strlen(str) + 1;
				data = ncs_enc_reserve_space(uba, sizeof(uns32));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_32bit(&data, length);
				ncs_enc_claim_space(uba, sizeof(uns32));

				ncs_encode_n_octets_in_uba(uba, (uns8 *)str, length);
				break;
			}
		case 'X':
			{
				char str[DTS_MAX_DBL_DIGITS] = "";
				int num_chars = 0;

				/* Check for compatibility with receiving DTS version
				   and set the minimum DTS version required */
				if (act_dts_ver == 1) {
					/* Incompatible DTS */
					goto reserve_error;
				} else {
					/* Compatible DTS. Update minimum DTS version required */
					if (min_dts_ver < 2)
						min_dts_ver = 2;
				}

				num_chars = sprintf(str, "Ox%016llx", va_arg(argp, long long));

                                if (num_chars == 0) {
					warning_rmval =
					    m_DTA_DBG_SINK(NCSCC_RC_FAILURE,
							   "ncs_logmsg: 64bit hex to string conversion gives NULL");
					goto reserve_error;
				}

				length = strlen(str) + 1;
				data = ncs_enc_reserve_space(uba, sizeof(uns32));
				if (data == NULL)
					goto reserve_error;
				ncs_encode_32bit(&data, length);
				ncs_enc_claim_space(uba, sizeof(uns32));

				ncs_encode_n_octets_in_uba(uba, (uns8 *)str, length);
				break;
			}
		default:
			{
				if (uba->start != NULL)
					m_MMGR_FREE_BUFR_LIST(uba->start);
				m_MMGR_FREE_OCT(hdr->fmat_type);
				m_MMGR_FREE_DTSV_MSG(msg);
				return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE,
							  "ncs_logmsg: Format Type Not accounted for", svc_id);
			}

		}

		i++;
	}

	/* Buffer log messgages if DTS is not up _or_ registration is not confirmed */
	if ((inst->dts_exist == FALSE) || (svc->log_msg == FALSE)) {
		m_DTA_LK(&inst->lock);
		buf = m_MMGR_ALLOC_DTA_BUFFERED_LOG;
		if (!buf) {
			if (msg->data.data.msg.log_msg.uba.start != NULL)
				m_MMGR_FREE_BUFR_LIST(msg->data.data.msg.log_msg.uba.start);
			m_MMGR_FREE_OCT(msg->data.data.msg.log_msg.hdr.fmat_type);
			if (0 != msg)
				m_MMGR_FREE_DTSV_MSG(msg);
			m_DTA_UNLK(&inst->lock);
			return m_DTA_DBG_SINK(NCSCC_RC_FAILURE, "Failed to allocate memory for log buffering");
		}

		/* Set the msg format version based on how it is encoded above. 
		   Usually it will be 1, because during DTS initialization, until
		   active DTS shows up (i.e until inst->dts_exist becomes TRUE)
		   active DTS version is assumed to be 1.
		 */
		msg->data.data.msg.msg_fmat_ver = min_dts_ver;

		memset(buf, '\0', sizeof(DTA_BUFFERED_LOG));
		buf->buf_msg = msg;
		buf->next = NULL;

		if (!list->head)
			list->head = buf;
		else
			list->tail->next = buf;

		list->tail = buf;
		list->num_of_logs++;
		m_DTA_UNLK(&inst->lock);
	} else {
		send_pri = NCS_IPC_PRIORITY_LOW;

		/* Set the msg format version to final value of min_dts_ver */
		msg->data.data.msg.msg_fmat_ver = min_dts_ver;

		/* Smik - We don't send the msg to MDS but to DTA's msgbox */
		if (m_DTA_SND_MSG(&gl_dta_mbx, msg, send_pri) != NCSCC_RC_SUCCESS) {
			if (uba->start != NULL)
				m_MMGR_FREE_BUFR_LIST(uba->start);
			m_MMGR_FREE_OCT(hdr->fmat_type);
			m_MMGR_FREE_DTSV_MSG(msg);
			/*if (dta_mds_async_send(&msg, inst) != NCSCC_RC_SUCCESS) */
			return m_DTA_DBG_SINK(NCSCC_RC_FAILURE, "ncs_logmsg: send to DTA msgbox failed");
		}
	}

	return NCSCC_RC_SUCCESS;

 reserve_error:
	if (uba->start != NULL)
		m_MMGR_FREE_BUFR_LIST(uba->start);
	m_MMGR_FREE_OCT(hdr->fmat_type);
	m_MMGR_FREE_DTSV_MSG(msg);
	return m_DTA_DBG_SINK(NCSCC_RC_FAILURE, "ncs_logmsg: Unable to reserve space in encode");
}