PERFORCE change 122020 for review
Fredrik Lindberg
fli at FreeBSD.org
Wed Jun 20 10:32:25 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=122020
Change 122020 by fli at 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 {
More information about the p4-projects
mailing list