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