⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 update.c

📁 此dns服务器是在mydns基础上改写
💻 C
📖 第 1 页 / 共 4 页
字号:
			return 0;		case DNS_QTYPE_HINFO:			{				char data1[DNS_MAXPACKETLEN_UDP], data2[DNS_MAXPACKETLEN_UDP], *c;				int  data1sp, data2sp;				if (!(src = text_retrieve(src, end, data1, sizeof(data1), 1)))					return dnserror(t, DNS_RCODE_FORMERR, ERR_INVALID_DATA);				if (!(src = text_retrieve(src, end, data2, sizeof(data2), 1)))					return dnserror(t, DNS_RCODE_FORMERR, ERR_INVALID_DATA);				/* See if either value contains spaces, so we can enclose it with quotes */				for (c = data1, data1sp = 0; *c && !data1sp; c++)					if (isspace(*c)) data1sp = 1;				for (c = data2, data2sp = 0; *c && !data2sp; c++)					if (isspace(*c)) data2sp = 1;				snprintf(data, datalen, "%s%s%s %s%s%s",					data1sp ? "\"" : "", data1, data1sp ? "\"" : "",					data2sp ? "\"" : "", data2, data2sp ? "\"" : "");			}			return 0;		case DNS_QTYPE_MX:			DNS_GET16(*aux, src);			if (!(src = name_unencode(t->query, t->len, src, data, datalen)))				return formerr(t, DNS_RCODE_FORMERR, (task_error_t)data[0], NULL);			return 0;		case DNS_QTYPE_NS:			if (!(src = name_unencode(t->query, t->len, src, data, datalen)))				return formerr(t, DNS_RCODE_FORMERR, (task_error_t)data[0], NULL);			return 0;		case DNS_QTYPE_TXT:			if (!(src = text_retrieve(src, end, data, datalen, 0)))				return dnserror(t, DNS_RCODE_FORMERR, ERR_INVALID_DATA);			return 0;		case DNS_QTYPE_PTR:			return dnserror(t, DNS_RCODE_SERVFAIL, ERR_UNSUPPORTED_TYPE);			return 0;		case DNS_QTYPE_RP:			{				char data1[DNS_MAXPACKETLEN_UDP], data2[DNS_MAXPACKETLEN_UDP];				if (!(src = name_unencode(t->query, t->len, src, data1, sizeof(data1))))					return formerr(t, DNS_RCODE_FORMERR, (task_error_t)data1[0], NULL);				if (!(src = name_unencode(t->query, t->len, src, data2, sizeof(data2))))					return formerr(t, DNS_RCODE_FORMERR, (task_error_t)data2[0], NULL);				snprintf(data, datalen, "%s %s", data1, data2);			}			return 0;		case DNS_QTYPE_SRV:			{				uint16_t weight, port;				char data1[DNS_MAXPACKETLEN_UDP];				DNS_GET16(*aux, src);				DNS_GET16(weight, src);				DNS_GET16(port, src);				if (!(src = name_unencode(t->query, t->len, src, data1, sizeof(data1))))					return formerr(t, DNS_RCODE_FORMERR, (task_error_t)data1[0], NULL);				snprintf(data, datalen, "%u %u %s", weight, port, data1);			}			return 0;		default:			snprintf(data, datalen, "Unknown type %s", mydns_qtype_str(rr->type));			break;	}	return (-1);}/*--- update_get_rr_data() ----------------------------------------------------------------------*//**************************************************************************************************	UPDATE_IN_ZONE	Checks to see if 'name' is within 'origin'.	Returns 1 if it is, 0 if it's not.**************************************************************************************************/static intupdate_in_zone(TASK *t, char *name, char *origin){	char nbuf[DNS_MAXNAMELEN+1], obuf[DNS_MAXNAMELEN+1];	strncpy(nbuf, name, sizeof(nbuf)-1);	strtolower(nbuf);	strncpy(obuf, origin, sizeof(obuf)-1);	strtolower(obuf);	if (strlen(obuf) > strlen(nbuf))		return 0;	if (strcmp(obuf, nbuf + strlen(nbuf) - strlen(obuf)))		return 0;	return 1;}/*--- update_in_zone() --------------------------------------------------------------------------*//**************************************************************************************************	UPDATE_ZONE_HAS_NAME	Check to see that there is at least one RR in the zone whose name is the same as the	prerequisite RR.	Returns 1 if the name exists, 0 if not, -1 on error.**************************************************************************************************/static intupdate_zone_has_name(TASK *t, MYDNS_SOA *soa, UQ *q, UQRR *rr){	SQL_RES	*res = NULL;	SQL_ROW	row;	char		query[512];	size_t	querylen;	char		*xname = NULL;	int		found = 0;#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: update_zone_has_name: does [%s] have an RR for [%s]?", desctask(t),			soa->origin, rr->name);#endif   if (!(xname = calloc(strlen(rr->name) * 2 + 1, sizeof(char))))      Err(_("out of memory"));	sql_escstr(sql, xname, rr->name, strlen(rr->name));	querylen = snprintf(query, sizeof(query),		"SELECT id FROM %s WHERE zone=%u AND name='%s' LIMIT 1",		mydns_rr_table_name, soa->id, xname);#if DEBUG_UPDATE_SQL	Verbose("%s: DNS UPDATE: %s", desctask(t), query);#endif	if (!(res = sql_query(sql, query, querylen)))	{		WarnSQL(sql, "%s: %s", desctask(t), _("error searching name for DNS UPDATE"));		return dnserror(t, DNS_RCODE_SERVFAIL, ERR_DB_ERROR);	}	if (sql_num_rows(res) > 0)		found = 1;	Free(xname);	sql_free(res);	return (found);}/*--- update_zone_has_name() --------------------------------------------------------------------*//**************************************************************************************************	UPDATE_ZONE_HAS_RRSET	Check to see that there is an RRset in the zone whose name and type are the same as the	prerequisite RR.	Returns 1 if the name exists, 0 if not, -1 on error.**************************************************************************************************/static intupdate_zone_has_rrset(TASK *t, MYDNS_SOA *soa, UQ *q, UQRR *rr){	SQL_RES	*res = NULL;	SQL_ROW	row;	char		query[512];	size_t	querylen;	char		*xname = NULL;	int		found = 0;#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: update_zone_has_rrset: does [%s] have an RR for [%s] with type %s?", desctask(t),			soa->origin, rr->name, mydns_qtype_str(rr->type));#endif   if (!(xname = calloc(strlen(rr->name) * 2 + 1, sizeof(char))))      Err(_("out of memory"));	sql_escstr(sql, xname, rr->name, strlen(rr->name));	querylen = snprintf(query, sizeof(query),		"SELECT id FROM %s WHERE zone=%u AND name='%s' AND type='%s' LIMIT 1",		mydns_rr_table_name, soa->id, xname, mydns_qtype_str(rr->type));#if DEBUG_UPDATE_SQL	Verbose("%s: DNS UPDATE: %s", desctask(t), query);#endif	if (!(res = sql_query(sql, query, querylen)))	{		WarnSQL(sql, "%s: %s", desctask(t), _("error searching name/type for DNS UPDATE"));		return dnserror(t, DNS_RCODE_SERVFAIL, ERR_DB_ERROR);	}	if (sql_num_rows(res) > 0)		found = 1;	Free(xname);	sql_free(res);	return (found);	return 1;}/*--- update_zone_has_rrset() -------------------------------------------------------------------*//**************************************************************************************************	CHECK_PREREQUISITE	Check the specified prerequisite as described in RFC 2136 3.2.	Returns 0 on success, -1 on error.**************************************************************************************************/static intcheck_prerequisite(TASK *t, MYDNS_SOA *soa, UQ *q, UQRR *rr){	static char data[DNS_MAXPACKETLEN_UDP] = "";	uint32_t	aux = 0;	int n, rv;#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: check_prerequsisite: rr->name=[%s]", desctask(t), rr->name);	Debug("%s: DNS UPDATE: check_prerequsisite: rr->class=%s", desctask(t), mydns_class_str(rr->class));	Debug("%s: DNS UPDATE: check_prerequsisite: q->class=%s", desctask(t), mydns_class_str(q->class));	Debug("%s: DNS UPDATE: check_prerequsisite: rr->type=%s", desctask(t), mydns_qtype_str(rr->type));	Debug("%s: DNS UPDATE: check_prerequsisite: rr->rdlength=%u", desctask(t), rr->rdlength);#endif	/* Get aux/data */	update_get_rr_data(t, soa, q, rr, data, sizeof(data), &aux);		/* Ignore error */#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: check_prerequsisite: aux=%u", desctask(t), aux);	Debug("%s: DNS UPDATE: check_prerequsisite: data=[%s]", desctask(t), data);#endif	/* TTL must be zero */	if (rr->ttl)	{#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: check_prerequisite failed: TTL nonzero", desctask(t));#endif		return dnserror(t, DNS_RCODE_FORMERR, ERR_INVALID_TTL);		}	/* rr->name bust be in-zone */	if (!update_in_zone(t, rr->name, soa->origin))	{#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: check_prerequisite failed: name (%s) not in zone (%s)", desctask(t), rr->name, soa->origin);#endif		return dnserror(t, DNS_RCODE_NOTZONE, ERR_INVALID_DATA);	}	/* Following pseudocode from section 3.2.5... */	if (rr->class == DNS_CLASS_ANY)	{		if (rr->rdlength)		{#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: check_prerequisite failed: class is ANY but rdlength is nonzero", desctask(t));#endif			return dnserror(t, DNS_RCODE_FORMERR, ERR_INVALID_DATA);			}		if (rr->type == DNS_QTYPE_ANY)		{			if ((rv = update_zone_has_name(t, soa, q, rr)) != 1)			{				if (!rv)				{#if DEBUG_ENABLED && DEBUG_UPDATE					Debug("%s: DNS UPDATE: check_prerequisite failed: zone contains no names matching [%s]",							desctask(t), rr->name);#endif					return dnserror(t, DNS_RCODE_NXDOMAIN, ERR_PREREQUISITE_FAILED);				}				else					return -1;			}		}		else if ((rv = update_zone_has_rrset(t, soa, q, rr)) != 1)		{			if (!rv)			{#if DEBUG_ENABLED && DEBUG_UPDATE				Debug("%s: DNS UPDATE: check_prerequisite failed: zone contains no names matching [%s] with type %s",						desctask(t), rr->name, mydns_qtype_str(rr->type));#endif				return dnserror(t, DNS_RCODE_NXRRSET, ERR_PREREQUISITE_FAILED);			}			else				return -1;		}	}	else if (rr->class == DNS_CLASS_NONE)	{		if (rr->rdlength != 0)		{#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: check_prerequisite failed: class is NONE but rdlength is zero", desctask(t));#endif			return dnserror(t, DNS_RCODE_FORMERR, ERR_INVALID_DATA);			}		if (rr->type == DNS_QTYPE_ANY)		{			if ((rv = update_zone_has_name(t, soa, q, rr)) != 0)			{				if (rv == 1)				{#if DEBUG_ENABLED && DEBUG_UPDATE					Debug("%s: DNS UPDATE: check_prerequisite failed: zone contains a name matching [%s]",							desctask(t), rr->name);#endif					return dnserror(t, DNS_RCODE_YXDOMAIN, ERR_PREREQUISITE_FAILED);				}				else					return -1;			}		}		else if ((rv = update_zone_has_rrset(t, soa, q, rr)) != 0)		{			if (rv == 1)			{#if DEBUG_ENABLED && DEBUG_UPDATE				Debug("%s: DNS UPDATE: check_prerequisite failed: zone contains a name matching [%s] with type %s",						desctask(t), rr->name, mydns_qtype_str(rr->type));#endif				return dnserror(t, DNS_RCODE_YXRRSET, ERR_PREREQUISITE_FAILED);			}			else				return -1;		}	}	else if (rr->class == q->class)	{		int		unique;											/* Is this rrset element unique? */		char		data[DNS_MAXPACKETLEN_UDP + 1];			/* Parsed rrset data */		uint32_t	aux = 0;											/* 'aux' value for parsed data */#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: want to add %s/%s to tmprr", desctask(t), rr->name, mydns_qtype_str(rr->type));#endif		/* Get the RR data */		if (update_get_rr_data(t, soa, q, rr, data, sizeof(data)-1, &aux) < 0)			return dnserror(t, DNS_RCODE_FORMERR, ERR_INVALID_DATA);	#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: for tmprr, data=[%s], aux=%u", desctask(t), data, aux);#endif		/* Add this name/type to the "tmprr" list (in the UQRR struct) */		/* First, check to make sure it's unique */		for (n = 0, unique = 1; n < q->num_tmprr && unique; n++)			if (q->tmprr[n]->type == rr->type && !strcasecmp(q->tmprr[n]->name, rr->name)				 && !strcasecmp(q->tmprr[n]->data, data) && q->tmprr[n]->aux == aux)				unique = 0;		if (unique)		{			if (!q->num_tmprr)				q->tmprr = calloc(1, sizeof(TMPRR *));			else				q->tmprr = realloc(q->tmprr, sizeof(TMPRR *) * (q->num_tmprr + 1));			if (!q->tmprr)				Err(_("out of memory"));			/* Add this stuff to the new tmprr */			if (!(q->tmprr[q->num_tmprr] = malloc(sizeof(TMPRR))))				Err(_("out of memory"));			strncpy(q->tmprr[q->num_tmprr]->name, rr->name, sizeof(q->tmprr[q->num_tmprr]->name) - 1);			q->tmprr[q->num_tmprr]->type = rr->type;			strncpy(q->tmprr[q->num_tmprr]->data, data, sizeof(q->tmprr[q->num_tmprr]->data) - 1);			q->tmprr[q->num_tmprr]->aux = aux;			q->tmprr[q->num_tmprr]->checked = 0;			q->num_tmprr++;		}	}	else		return dnserror(t, DNS_RCODE_FORMERR, ERR_INVALID_DATA);		return 0;}/*--- check_prerequisite() ----------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -