PERFORCE change 120770 for review

Fredrik Lindberg fli at FreeBSD.org
Sat Jun 2 12:11:10 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=120770

Change 120770 by fli at fli_genesis on 2007/06/02 12:10:09

	- No need to to UTF8 {en,de}coding during packet {de}construction, it
	  can be deferred until later.
	- Make sure to do name decompression on resource data that needs it,
	  such as PTR, CNAME and SRV.
	- Fix some comments.
	- Follow debug changes.

Affected files ...

.. //depot/projects/soc2007/fli-mdns_sd/mdnsd/mdns.h#4 edit
.. //depot/projects/soc2007/fli-mdns_sd/mdnsd/stack_packet.c#5 edit

Differences ...

==== //depot/projects/soc2007/fli-mdns_sd/mdnsd/mdns.h#4 (text+ko) ====

@@ -41,7 +41,7 @@
  */
 struct mdns_packet;
 struct mdns {
-	uint32_t md_magic;
+	MAGIC(md_magic);
 	char md_ifnam[IFNAMSIZ + 1];
 	int md_ifindex;
 	int md_flags;
@@ -116,7 +116,7 @@
 typedef int (*md_lock)(void *);
 typedef int (*md_unlock)(void *);
 struct mdns_pkgchain {
-	uint32_t pc_magic;
+	MAGIC(pc_magic);
 	TAILQ_HEAD(, mdns_packet) pc_head; /* packet list */
 	int pc_list_len; /* packet list length */
 	int pc_flags;
@@ -183,23 +183,23 @@
  * MDNS resource set
  */
 struct mdns_rrset {
+	char r_name[MDNS_RECORD_LEN + 1]; /* rrset name */
 	uint16_t r_class; /* rrset class */
 	uint16_t r_type; /* Record type */
+	int r_cflush; /* cache flush */
 	uint32_t r_ttl;  /* Time to live */
 	uint16_t r_datalen; /* Length of resource data */
-	int r_cflush; /* cache flush */
 	char *r_data; /* Resource data */
-	wchar_t r_name[MDNS_RECORD_LEN + 1]; /* rrset name */
 };
 
 /*
  * MDNS question/query set
  */
 struct mdns_qset {
+	char q_name[MDNS_RECORD_LEN + 1]; /* qname */
 	uint16_t q_class; /* qset class */
 	uint16_t q_type;  /* query type */
 	int	q_unicast; /* unicast desired */
-	wchar_t q_name[MDNS_RECORD_LEN + 1]; /* qname */
 };
 
 int mdns_init(struct mdns *, struct mdns_bufpool *, const char *);

==== //depot/projects/soc2007/fli-mdns_sd/mdnsd/stack_packet.c#5 (text+ko) ====

@@ -46,6 +46,7 @@
 static int name_compress(struct hashtbl *, char *, size_t, char *,
 	size_t *, int);
 static int name_decompress(char *, char *, size_t, char *, size_t);
+static inline char * res_decode(char *, uint16_t *, uint16_t, char *, size_t);
 
 static inline void free_pkg(struct mdns_packet *, struct mdns_bufpool *);
 
@@ -373,7 +374,6 @@
 	i = 0;
 	/*
 	 * Turn into a normal DNS label without compression.
-	 * ``rdst'' will contain the same name but with label pointers reversed.
 	 */
 	while (p != str) {
 		if (*p == '.') {
@@ -409,7 +409,7 @@
 			break;
 
 		offset = pkg_offset;
-		hashtbl_add(ht, p, q - p, (void *)(int)offset);
+		hashtbl_add(ht, p, q - p, (void *)(int)offset, 0);
 		pkg_offset += (*p + 1);
 		p += *p + 1;
 	}
@@ -472,6 +472,53 @@
 }
 
 /*
+ * Some resource types requires special attention as their resource data
+ * contains names that might have been name compressed.
+ */
+static inline char *
+res_decode(char *res, uint16_t *reslen, uint16_t type, char *buf, size_t pkglen)
+{
+	int error;
+	char *p;
+
+	if ((res + *reslen) > (buf + pkglen))
+		return (NULL);
+
+	switch (type) {
+	case mdns_t_srv:
+		p = malloc(MDNS_RECORD_LEN + 6);
+		if (p == NULL)
+			return (NULL);
+		memcpy(p, res, 6);
+		error = name_decompress(res + 6, p + 6, MDNS_RECORD_LEN, buf, pkglen);
+		if (error != 0) {
+			free(p);
+			return (NULL);
+		}
+		*reslen = strlen(p + 6) + 6;
+		break;
+	case mdns_t_ptr:
+	case mdns_t_cname:
+		p = malloc(MDNS_RECORD_LEN);
+		if (p == NULL)
+			return (NULL);
+		error = name_decompress(res, p, MDNS_RECORD_LEN, buf, pkglen);
+		if (error != 0) {
+			free(p);
+			return (NULL);
+		}
+		*reslen = strlen(p);
+		break;
+	default:
+		p = malloc(*reslen);
+		if (p == NULL)
+			return (NULL);
+		memcpy(p, res, *reslen);
+	}
+	return (p);
+}
+
+/*
  * Set DNS header on the current chain
  *   pc  - Package chain
  *   id  - Transaction id (only non-zero with legacy unicast clients)
@@ -561,13 +608,13 @@
 mdns_pkg_addquestion(struct mdns_pkgchain *pc, struct mdns_qset *qs,
     int unicast)
 {
-	char nam[MDNS_RECORD_LEN + 1], namc[MDNS_RECORD_LEN];
+	char namc[MDNS_RECORD_LEN];
 	struct mdns_packet *pkg, *hpkg;
 	struct mdns_bufpool *bp;
 	struct mdns_buf *buf;
 	struct mdns_header *h;
 	struct mdns_qsec qsec;
-	ssize_t qname_len, namlen, namlen2;
+	size_t namlen, namclen;
 	int i, error, flags;
 	uint16_t class;
 
@@ -584,8 +631,8 @@
 	}
 	buf = pkg->p_bufseg(p_questions);
 
-	qname_len = wcslen(qs->q_name);
-	i = qname_len + 1 + MDNS_QSET_HLEN;
+	namlen = strlen(qs->q_name);
+	i = namlen + 1 + MDNS_QSET_HLEN;
 
 	/*
 	 * Expand packet chains, buffer chains and buffers if needed
@@ -619,24 +666,16 @@
 		}
 	}
 
-	namlen = utf8_encode(qs->q_name, nam, MDNS_RECORD_LEN);	
-	if (namlen < 0) {
-		errno = EINVAL;
-		return (-1);
-	}
-
 	if (pkg->p_nc_tbl == NULL) {
 		pkg->p_nc_tbl = malloc(sizeof(struct hashtbl));
-		hashtbl_init(pkg->p_nc_tbl, 128);
+		hashtbl_init(pkg->p_nc_tbl, 8, 256, 5);
 	}
 
-	namlen2 = MDNS_RECORD_LEN;
-	error = name_compress(pkg->p_nc_tbl, nam, namlen, namc, &namlen2,
+	namclen = MDNS_RECORD_LEN;
+	error = name_compress(pkg->p_nc_tbl, qs->q_name, namlen, namc, &namclen,
 		pkg->p_len);
-	if (error != 0) {
+	if (error != 0)
 		return (-1);
-	}
-	namlen = namlen2;
 
 	memcpy(MDNS_BUFPOS(buf), namc, namlen);
 	MDNS_BUFLEN(buf) += namlen;
@@ -711,18 +750,19 @@
 static int
 addres(struct mdns_pkgchain *pc, int section, struct mdns_rrset *rs, int flush)
 {
-	char nam[MDNS_RECORD_LEN + 1], namc[MDNS_RECORD_LEN];
+	char namc[MDNS_RECORD_LEN];
 	struct mdns_packet *pkg;
 	struct mdns_bufpool *bp;
 	struct mdns_buf *buf;
 	struct mdns_header *h;
-	ssize_t namlen, namlen2;
+	size_t namlen, namclen;
 	int i, error, flags;
 	uint16_t class;
 	struct mdns_rsec rsec;
 
 	pkg = pc->pc_pkg;
-	namlen = wcslen(rs->r_name);
+
+	namlen = strlen(rs->r_name);
 	i = namlen + 1 + MDNS_RRSET_HLEN + rs->r_datalen;
 	bp = pc->pc_md->md_bp;
 
@@ -802,25 +842,18 @@
 		}
 	}
 
-	namlen = utf8_encode(rs->r_name, nam, MDNS_RECORD_LEN);	
-	if (namlen < 0) {
-		errno = EINVAL;
-		return (-1);
-	}
-
 	if (pkg->p_nc_tbl == NULL) {
 		pkg->p_nc_tbl = malloc(sizeof(struct hashtbl));
-		hashtbl_init(pkg->p_nc_tbl, 128);
+		hashtbl_init(pkg->p_nc_tbl, 8, 256, 5);
 	}
 
-	namlen2 = MDNS_RECORD_LEN;
-	error = name_compress(pkg->p_nc_tbl, nam, namlen, namc, &namlen2,
+	namclen = MDNS_RECORD_LEN;
+	error = name_compress(pkg->p_nc_tbl, rs->r_name, namlen, namc, &namclen,
 		pkg->p_len);
 	if (error != 0) {
 		errno = EINVAL;
 		return (-1);
 	}
-	namlen = namlen2;
 
 	memcpy(MDNS_BUFPOS(buf), namc, namlen);
 	MDNS_BUFLEN(buf) += namlen;
@@ -870,7 +903,6 @@
 static int
 getres(struct mdns_packet *pkg, int section, int entry, void *set)
 {
-	char nam[MDNS_RECORD_LEN + 1];
 	struct mdns_rsec rsec;
 	struct mdns_qsec qsec;
 	struct mdns_header *h;
@@ -879,9 +911,8 @@
 	struct mdns_qset *qs = (struct mdns_qset *)set;
 	char *p, ***offsets, **offset, *end;
 	int error, i, j, *last_offset, entries;
-	ssize_t namlen;
 	uint16_t tmp[3], rlen;
-	wchar_t *wp;
+	char *wp;
 
 	if (pkg->p_bufseg(p_hdr) == NULL) {
 		hbuf = MDNS_BUFH(&pkg->p_buflist);
@@ -1025,21 +1056,16 @@
 		}
 	}
 
+	wp = (p_isrrset(section)) ? rs->r_name : qs->q_name;
+
 	/*
 	 * This routine asumes that the packet is available in one single buffer
 	 */
-	error = name_decompress(p, nam, MDNS_RECORD_LEN,
+	error = name_decompress(p, wp, MDNS_RECORD_LEN,
 		MDNS_BUF(buf), MDNS_BUFLEN(buf));
 	if (error != 0)
 		goto invalidpkg;
 
-	wp = (p_isrrset(section)) ? rs->r_name : qs->q_name;
-	namlen = strlen(nam); /* XXX: should be merged with name_decompress */
-
-	namlen = utf8_decode(nam, namlen, wp, MDNS_RECORD_LEN);	
-	if (namlen < 0)
-		goto invalidpkg;
-
 	end = MDNS_BUF(buf) + MDNS_BUFLEN(buf);
 	p = skipname(p, end);
 	if (p == NULL)
@@ -1057,12 +1083,13 @@
 		rs->r_ttl = ntohl(rsec.rs_ttl);
 		rs->r_datalen = ntohs(rsec.rs_rdlen);
 
-		if (p + rs->r_datalen > end)
+		p += MDNS_RRSET_HLEN;
+		rs->r_data = res_decode(p, &rs->r_datalen, rs->r_type,
+		    MDNS_BUF(buf), MDNS_BUFLEN(buf));
+		if (rs->r_data == NULL) {
+			rs->r_datalen = 0;
 			goto invalidpkg;
-		rs->r_data = malloc(rs->r_datalen);
-		if (rs->r_data == NULL)
-			goto invalidpkg;
-		memcpy(rs->r_data, p, rs->r_datalen);
+		}
 	}
 	else {
 		if (p + MDNS_QSET_HLEN > end)


More information about the p4-projects mailing list