From owner-p4-projects@FreeBSD.ORG Wed Jun 20 10:32:25 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0959E16A46C; Wed, 20 Jun 2007 10:32:25 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id BA0D316A421 for ; Wed, 20 Jun 2007 10:32:24 +0000 (UTC) (envelope-from fli@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id AAB1413C45E for ; Wed, 20 Jun 2007 10:32:24 +0000 (UTC) (envelope-from fli@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l5KAWOBP085464 for ; Wed, 20 Jun 2007 10:32:24 GMT (envelope-from fli@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l5KAWOqq085458 for perforce@freebsd.org; Wed, 20 Jun 2007 10:32:24 GMT (envelope-from fli@FreeBSD.org) Date: Wed, 20 Jun 2007 10:32:24 GMT Message-Id: <200706201032.l5KAWOqq085458@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to fli@FreeBSD.org using -f From: Fredrik Lindberg To: Perforce Change Reviews Cc: Subject: PERFORCE change 122020 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Jun 2007 10:32:25 -0000 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 {