Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Jun 2007 10:32:24 GMT
From:      Fredrik Lindberg <fli@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 122020 for review
Message-ID:  <200706201032.l5KAWOqq085458@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=122020

Change 122020 by fli@fli_genesis on 2007/06/20 10:32:06

	- Remove utf8_{encode,decode} from this file.
	- mdns_t_* => mdns_in_*
	- Follow buffer changes. 
	- Add resource encoding and decoding on IN types that needs it.

Affected files ...

.. //depot/projects/soc2007/fli-mdns_sd/mdnsd/stack_packet.c#6 edit

Differences ...

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

@@ -40,13 +40,13 @@
 #include "stack_mdns.h"
 #include "hash.h"
 
-static ssize_t utf8_encode(wchar_t *, char *, size_t);
-static ssize_t utf8_decode(char *, size_t, wchar_t *, size_t);
 static inline char * skipname(char *, char *);
 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 res_encode(struct hashtbl *, char *, uint16_t, char *,
+    size_t *, int);
 
 static inline void free_pkg(struct mdns_packet *, struct mdns_bufpool *);
 
@@ -88,15 +88,15 @@
 		md->md_pkgtotal++;
 	}
 
-	if (pc->pc_unlock != NULL)
-		pc->pc_unlock(pc->pc_lockarg);
+	bzero(pkg, sizeof(struct mdns_packet));
+	pkg->p_pc = pc;
+	pc->pc_pkg = pkg;
 
-	bzero(pkg, sizeof(struct mdns_packet));
-	mdns_buf_alloc(bp, &pkg->p_buflist, 0, 0);
 	TAILQ_INSERT_TAIL(&pc->pc_head, pkg, p_list);
-	pc->pc_pkg = pkg;
 	pc->pc_list_len++;
-	pkg->p_pc = pc;
+
+	if (pc->pc_unlock != NULL)
+		pc->pc_unlock(pc->pc_lockarg);
 
 	return (pkg);
 error:
@@ -148,7 +148,6 @@
 	/* Return buffers allocated to this packet */
 	while (!TAILQ_EMPTY(&pkg->p_buflist.bh_list)) {
 		buf = TAILQ_FIRST(&pkg->p_buflist.bh_list);
-		TAILQ_REMOVE(&pkg->p_buflist.bh_list, buf, b_list);
 		mdns_buf_free(bp, &pkg->p_buflist, buf, 1);
 	}
 
@@ -208,126 +207,6 @@
 }
 
 /*
- * utf8_encode
- * Encodes a wide character string into an UTF-8 byte sequence
- * Arguments
- *   src  - Pointer to start of wide character string
- *   slen - Logical (not bytes) length of character string.
- *   dst  - Destination where the encoded string should be placed.
- *   dlen - Length of ``dst''
- * Return values
- *   The length of the encoded string is returned on success.
- *   On failure a number less than zero is returned, this absoute value of
- *   this number can be used as a hint if ``dst'' is too small.
- *
- * This function is partially based on code from libarchive by Tim Kientzle
- */
-static ssize_t
-utf8_encode(wchar_t *src, char *dst, size_t dlen)
-{
-	char *p;
-	wchar_t *wp, wc;
-	size_t len;
-
-	len = 0;
-	for (wp = src; *wp != L'\0'; wp++) {
-		wc = *wp;
-		if (wc <= 0x7f)
-			len++;
-        else if (wc <= 0x7ff)
-			len += 2;
-        else if (wc <= 0xffff)
-			len += 3;
-        else if (wc <= 0x10ffff)
-			len += 4;
-	}
-
-	if (len > dlen)
-		return (-len);
-
-	for (wp = src, p = dst; *wp != L'\0'; wp++) {
-		wc = *wp;
-		if (wc <= 0x7f) {
-			*p++ = (char)wc;
-		} else if (wc <= 0x7ff) {
-			p[0] = 0xc0 | ((wc >> 6) & 0x1f);
-			p[1] = 0x80 | (wc & 0x3f);
-			p += 2;
-		} else if (wc <= 0xffff) {
-			p[0] = 0xe0 | ((wc >> 12) & 0x0f);
-			p[1] = 0x80 | ((wc >> 6) & 0x3f);
-			p[2] = 0x80 | (wc & 0x3f);
-			p += 3;
-		} else if (wc <= 0x10ffff) {
-			p[0] = 0xf0 | ((wc >> 18) & 0x07);
-			p[1] = 0x80 | ((wc >> 12) & 0x3f);
-			p[2] = 0x80 | ((wc >> 6) & 0x3f);
-			p[3] = 0x80 | (wc & 0x3f);
-			p += 4;
-		}
-	}
-
-	*p = '\0';
-	return (len);
-}
-
-/*
- * utf8_decode
- * Decodes an UTF-8 byte sequence into a wide character string
- * Arguments
- *   src  - Pointer to start of UTF-8 string
- *   slen - Length of UTF-8 byte sequence
- *   dst  - Destination where the decoded string should be placed
- *   dlen - Size of ``dst'' (logical length, not byte length)
- * Return values
- *   Returns logical length of decoded string or -1 on failure
- */
-static ssize_t
-utf8_decode(char *src, size_t slen, wchar_t *dst, size_t dlen)
-{
-	size_t len;
-	char c, *p;
-	wchar_t *wp;
-
-	if (dlen < slen)
-		return (-1);
-
-	len = 0;
-	for (p = src, wp = dst; *p != '\0'; wp++) {
-		c = *p;	
-		if ((c & 0xf8) == 0xf0) {
-			*wp = (p[0] & 0x7) << 18;
-			*wp |= (p[1] & 0x3f) << 12;
-			*wp |= (p[2] & 0x3f) << 6;
-			*wp |= (p[3] & 0x3f);
-			p += 4;
-		}
-		else if ((c & 0xf0) == 0xe0) {
-			*wp = (p[0] & 0xf) << 12;
-			*wp |= (p[1] & 0x3f) << 6;
-			*wp |= (p[2] & 0x3f);
-			p += 3;
-		}
-		else if ((c & 0xe0) == 0xc0) {
-			*wp = (p[0] & 0x1f) << 6;
-			*wp |= (p[1] & 0x3f);
-			p += 2;
-		}
-		else if ((c & 0x80) == 0) {
-			*wp = c & 0x7f; 	
-			p++;
-		}
-		else {
-			return (-1);
-		}
-		len++;
-	}
-	*wp = L'\0';
-	
-	return (len);
-}
-
-/*
  * Returns a pointer to the last byte in a dns name
  *   str - Start of dns name
  *   end - End of buffer
@@ -485,7 +364,7 @@
 		return (NULL);
 
 	switch (type) {
-	case mdns_t_srv:
+	case mdns_in_srv:
 		p = malloc(MDNS_RECORD_LEN + 6);
 		if (p == NULL)
 			return (NULL);
@@ -497,8 +376,8 @@
 		}
 		*reslen = strlen(p + 6) + 6;
 		break;
-	case mdns_t_ptr:
-	case mdns_t_cname:
+	case mdns_in_ptr:
+	case mdns_in_cname:
 		p = malloc(MDNS_RECORD_LEN);
 		if (p == NULL)
 			return (NULL);
@@ -519,6 +398,25 @@
 }
 
 /*
+ * Labelize (and name compress) resource data that needs it
+ */
+static inline void 
+res_encode(struct hashtbl *ht, char *buf, uint16_t type, char *res,
+    size_t *rlen, int plen)
+{
+
+	switch (type) {
+	case mdns_in_ptr:
+	case mdns_in_cname:
+		name_compress(ht, res, *rlen, buf, rlen, plen); 
+		break;
+	default:
+		memcpy(buf, res, *rlen);
+		break;
+	}
+}
+
+/*
  * Set DNS header on the current chain
  *   pc  - Package chain
  *   id  - Transaction id (only non-zero with legacy unicast clients)
@@ -538,7 +436,7 @@
 
 	buf = MDNS_BUFH(&pkg->p_buflist);
 	if (buf == NULL)
-		buf = mdns_buf_alloc(pc->pc_md->md_bp, &pkg->p_buflist, 0, 1);
+		buf = mdns_buf_alloc(pc->pc_md->md_bp, &pkg->p_buflist, 0, 0);
 	
 	bzero(MDNS_BUF(buf), MDNS_HEADER_LEN);
 
@@ -756,7 +654,7 @@
 	struct mdns_buf *buf;
 	struct mdns_header *h;
 	size_t namlen, namclen;
-	int i, error, flags;
+	int i, error, flags, baflag = 0;
 	uint16_t class;
 	struct mdns_rsec rsec;
 
@@ -796,6 +694,15 @@
 				flags |= MDNS_HEAD_AA;
 			mdns_pkg_sethdr(pc, 0, flags);
 			buf = NULL;
+			/*
+			 * If the rrset does fit a "MTU sized" packet, make sure that
+			 * the next rrset will get a new packet as super-sized packets
+			 * only are allowed to carry one rrset.
+			 */
+			if (i > pc->pc_md->md_maxpkgsz) {
+				baflag = MDNS_BUF_HUGE;
+				pkg_alloc(pc);
+			}
 		}
 		else if (buf != NULL && (i + MDNS_BUFLEN(buf)) > MDNS_BUFSZ(buf)) {
 			error = mdns_buf_expand(buf, 0);
@@ -813,7 +720,7 @@
 		switch (section) {
 		case SEC_QUESTIONS:
 			if (pkg->p_bufseg(p_questions) == NULL) {
-				buf = mdns_buf_alloc(bp, &pkg->p_buflist, 0, 0);
+				buf = mdns_buf_alloc(bp, &pkg->p_buflist, 0, baflag);
 				pkg->p_bufseg(p_questions) = buf;
 				pkg->p_buf(p_questions) = MDNS_BUF(buf);
 				if (section == SEC_QUESTIONS)
@@ -821,7 +728,7 @@
 			}
 		case SEC_ANSWERS:
 			if (pkg->p_bufseg(p_answers) == NULL) {
-				buf = mdns_buf_alloc(bp, &pkg->p_buflist, 0, 0);
+				buf = mdns_buf_alloc(bp, &pkg->p_buflist, 0, baflag);
 				pkg->p_bufseg(p_answers) = buf;
 				pkg->p_buf(p_answers) = MDNS_BUF(buf);
 				if (section == SEC_ANSWERS)
@@ -829,7 +736,7 @@
 			}
 		case SEC_AUTHORITY:
 			if (pkg->p_bufseg(p_auths) == NULL) {
-				buf = mdns_buf_alloc(bp, &pkg->p_buflist, 0, 0);
+				buf = mdns_buf_alloc(bp, &pkg->p_buflist, 0, baflag);
 				pkg->p_bufseg(p_auths) = buf;
 				pkg->p_buf(p_auths) = MDNS_BUF(buf);
 				if (section == SEC_AUTHORITY)
@@ -869,8 +776,10 @@
 	memcpy(MDNS_BUFPOS(buf), &rsec, MDNS_RRSET_HLEN);
 	MDNS_BUFLEN(buf) += MDNS_RRSET_HLEN;
 
-	memcpy(MDNS_BUFPOS(buf), rs->r_data, rs->r_datalen);
-	MDNS_BUFLEN(buf) += rs->r_datalen;
+	namclen = rs->r_datalen;
+	res_encode(pkg->p_nc_tbl, MDNS_BUFPOS(buf), rs->r_type,
+	    rs->r_data, &namclen, pkg->p_len); 
+	MDNS_BUFLEN(buf) += namclen; 
 
 	pkg->p_len += namlen + MDNS_RRSET_HLEN + rs->r_datalen;
 
@@ -1084,11 +993,22 @@
 		rs->r_datalen = ntohs(rsec.rs_rdlen);
 
 		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;
+
+		if (rs->r_class == mdns_c_in) {
+			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;
+			}
+		}
+		else {
+			if (p + rs->r_datalen > (MDNS_BUF(buf) + MDNS_BUFLEN(buf))) {
+				rs->r_datalen = 0;
+				goto invalidpkg;
+			}
+			rs->r_data = malloc(rs->r_datalen);
+			memcpy(rs->r_data, p, rs->r_datalen);
 		}
 	}
 	else {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200706201032.l5KAWOqq085458>