Date: Thu, 16 Aug 2007 19:51:11 GMT From: Fredrik Lindberg <fli@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 125234 for review Message-ID: <200708161951.l7GJpBgH011518@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125234 Change 125234 by fli@fli_nexus on 2007/08/16 19:50:49 - Add mdns_freerrset(), free resources allocated to a rrset. - Add mdns_db_name_{add,del}() and mdns_db_res_{add,del}() which allows manipulation of the record database. - Make it possible to specify the default location of the daemon pipe at compile time. - General cleanup. Affected files ... .. //depot/projects/soc2007/fli-mdns_sd/libmdns/libmdns.c#2 edit .. //depot/projects/soc2007/fli-mdns_sd/libmdns/libmdns.h#2 edit .. //depot/projects/soc2007/fli-mdns_sd/libmdns/mdns.h#2 edit Differences ... ==== //depot/projects/soc2007/fli-mdns_sd/libmdns/libmdns.c#2 (text+ko) ==== @@ -35,6 +35,7 @@ #include <assert.h> #include <errno.h> #include <fcntl.h> +#include <stdarg.h> #include <stdlib.h> #include <string.h> #include <strings.h> @@ -44,20 +45,22 @@ #include "libmdns.h" #include "mdnsd_ipc.h" -#include "../mdnsd/debug.h" - -#define MDNSD_PIPE "/var/run/mdnsd.pipe" - static int sock_open(struct mdns *); static void sock_close(struct mdns *); static inline int sock_verify(struct mdns *); static int sock_reconnect(struct mdns *); +static int doquery(struct mdns *, int, int, int, int, int, int, wchar_t *); static struct mdns_msg * sock_read(struct mdns *, int, struct timeval *); static struct mdns_msg * msg_wait(struct mdns *, int, struct timeval *); static void msg_free(struct mdns_msg *); struct mdns_wait * in_wqueue(struct mdns *, int); +static inline int ipc_sethdr(struct mdns *, struct mipc_head *, int); +static ssize_t utf8_decode(char *, size_t, wchar_t *, size_t); +static int docmd(struct mdns *, int, int, ...); +static int errormsg(struct mdns_msg *); -static inline int ipc_sethdr(struct mdns *, struct mipc_head *, int); +extern struct ctmap class_map[]; +extern int class_map_size; /* * Open a handle to the daemon @@ -66,6 +69,7 @@ mdns_open(void) { struct mdns *m; + int error; m = malloc(sizeof(struct mdns)); if (m == NULL) @@ -74,7 +78,11 @@ TAILQ_INIT(&m->m_recv); TAILQ_INIT(&m->m_wait); - sock_open(m); + error = sock_open(m); + if (error < 0) { + free(m); + return (NULL); + } MDNS_SETCOOKIE(m); return (m); } @@ -86,84 +94,29 @@ mdns_close(struct mdns *m) { struct mdns_msg *mm, *mm2; + struct mdns_wait *mw, *mw2; if (m == NULL) return; MDNS_ASSERT(m); + if (sock_verify(m)) + close(m->m_sock); + TAILQ_FOREACH_SAFE(mm, &m->m_recv, mm_next, mm2) { TAILQ_REMOVE(&m->m_recv, mm, mm_next); msg_free(mm); } + TAILQ_FOREACH_SAFE(mw, &m->m_wait, mw_next, mw2) { + TAILQ_REMOVE(&m->m_wait, mw, mw_next); + free(mw); + } MDNS_UNSETCOOKIE(m); free(m); } -/* - * Submit a query to the daemon - */ -static int -doquery(struct mdns *m, int cmd, int fam, int ifidx, int tmo, int class, - int type, wchar_t *rec) -{ - size_t rlen; - int n, mid, retval = 0; - struct mdns_msg *mm; - struct mdns_wait *mw; - struct mipc_head mih; - struct mipc_query miq; - struct iovec iov[3]; - - rlen = wcslen(rec); - if (rlen >= MDNS_NAME_LEN) - return (-1); - - mid = ipc_sethdr(m, &mih, MIM_QUERY); - miq.miq_cmd = cmd; - miq.miq_len = rlen; - miq.miq_timeout = tmo; - miq.miq_fam = fam; - miq.miq_ifidx = ifidx; - miq.miq_class = class; - miq.miq_type = type; - iov[0].iov_base = &mih; - iov[0].iov_len = sizeof(struct mipc_head); - iov[1].iov_base = &miq; - iov[1].iov_len = sizeof(struct mipc_query); - iov[2].iov_base = rec; - iov[2].iov_len = rlen * sizeof(wchar_t); - mih.mih_msglen += sizeof(struct mipc_query) + (rlen * sizeof(wchar_t)); - - do { - n = writev(m->m_sock, iov, 3); - } while (n < 0 && errno == EINTR); - - if (n < 0) - return (-1); - - retval = mid; - mm = sock_read(m, mid, NULL); - if (mm->mm_msgtype == MIM_ERROR) - retval = -1; - msg_free(mm); - - if (retval >= 0 && (cmd == MIQ_CMD_CREG || cmd == MIQ_CMD_ONESHOT)) { - mw = malloc(sizeof(struct mdns_wait)); - mw->mw_seqid = mid; - mw->mw_msgtype = MIM_QUERY; - mw->mw_rrset.mr_class = class; - mw->mw_rrset.mr_type = type; - mw->mw_rrset.mr_ifidx = ifidx; - mw->mw_rrset.mr_family = fam; - wcscpy(mw->mw_rrset.mr_name, rec); - TAILQ_INSERT_TAIL(&m->m_wait, mw, mw_next); - } - - return (retval); -} - /* * Dispatch a query to the daemon */ @@ -231,6 +184,8 @@ char *p; size_t len; + MDNS_ASSERT(m); + again: do { mm = msg_wait(m, mid, tv); @@ -286,6 +241,585 @@ return (rmid); } +void +mdns_freerrset(struct mdns_rrset *mr) +{ + + free(mr->mr_res); +} + +/* + * Array to class (integer) translation + */ +int +mdns_atoc(const char *class) +{ + int i; + + for (i = 0; i < class_map_size; i++) { + if (strcasecmp(class_map[i].ctm_str, class) == 0) + return (class_map[i].ctm_int); + } + return (-1); +} + +/* + * Class to array translation + */ +const char * +mdns_ctoa(int class) +{ + int i; + + for (i = 0; i < class_map_size; i++) { + if (class == class_map[i].ctm_int) + return (class_map[i].ctm_str); + } + return (NULL); +} + + +/* + * Array to type (integer) translation + */ +int +mdns_atot(int class, const char *type) +{ + int i; + struct ctmap *type_map = NULL; + + for (i = 0; i < class_map_size; i++) { + if (class == class_map[i].ctm_int) { + type_map = class_map[i].ctm_child; + break; + } + } + + if (type_map == NULL) + return (-1); + + for (i = 0; type_map[i].ctm_int != -1; i++) { + if (strcasecmp(type_map[i].ctm_str, type) == 0) + return (type_map[i].ctm_int); + } + return (-1); +} + +/* + * Type to array translation + */ +const char * +mdns_ttoa(int class, int type) +{ + int i; + struct ctmap *type_map = NULL; + + for (i = 0; i < class_map_size; i++) { + if (class == class_map[i].ctm_int) { + type_map = class_map[i].ctm_child; + break; + } + } + + if (type_map == NULL) + return (NULL); + + for (i = 0; type_map[i].ctm_int != -1; i++) { + if (type_map[i].ctm_int == type) + return (type_map[i].ctm_str); + } + return (NULL); +} + +/* + * Auto-convert the given resource set into a more readable format. The + * returned pointer must be passed to mdns_free_resource() + */ +void * +mdns_get_resource(struct mdns_rrset *mr) +{ + int error; + + if (mr->mr_class != mdns_c_in) + return (mr->mr_res); + else if (mr->mr_reslen == 0 || mr->mr_res == NULL) + return (NULL); + + switch (mr->mr_type) { + case mdns_in_a: + if (mr->mr_reslen != sizeof(struct in_addr)) + return (NULL); + return (mr->mr_res); + case mdns_in_aaaa: + if (mr->mr_reslen != sizeof(struct in6_addr)) + return (NULL); + return (mr->mr_res); + case mdns_in_ptr: + case mdns_in_cname: { + wchar_t *nam; + + nam = malloc((mr->mr_reslen + 1) * sizeof(wchar_t)); + if (nam == NULL) + return (NULL); + error = utf8_decode(mr->mr_res, mr->mr_reslen, nam, + mr->mr_reslen + 1); + if (error <= 0) { + free(nam); + return (NULL); + } + return (nam); + break; + } + case mdns_in_txt: { + char *p, *q, **txt; + size_t len; + uint8_t slen; + int num; + + num = 2; + txt = malloc(sizeof(char *) * num); + if (txt == NULL) + return (NULL); + + len = mr->mr_reslen; + p = mr->mr_res; + while (len != 0 && p < (mr->mr_res + mr->mr_reslen)) { + memcpy(&slen, p++, sizeof(uint8_t)); + if (slen > --len) { + free(txt); + return (NULL); + } + + q = malloc(slen + 1); + memcpy(q, p, slen); + q[slen] = '\0'; + txt[num - 2] = q; + txt[num - 1] = NULL; + txt = realloc(txt, sizeof(char *) * ++num); + p += slen; + len -= slen; + } + return (txt); + break; + } + case mdns_in_srv: { + struct mdns_res_in_srv *srv; + char *p; + uint16_t tmp; + size_t len; + + if (mr->mr_reslen < 6) + return (NULL); + + srv = malloc(sizeof(struct mdns_res_in_srv)); + if (srv == NULL) + return (NULL); + p = mr->mr_res; + len = mr->mr_reslen; + memcpy(&tmp, p, sizeof(uint16_t)); + p += sizeof(uint16_t); + srv->srv_pri = htons(tmp); + + memcpy(&tmp, p, sizeof(uint16_t)); + p += sizeof(uint16_t); + srv->srv_wei = htons(tmp); + + memcpy(&tmp, p, sizeof(uint16_t)); + p += sizeof(uint16_t); + srv->srv_prt = htons(tmp); + + len -= sizeof(uint16_t) * 3; + srv->srv_nam = malloc((len + 1) * sizeof(wchar_t)); + error = utf8_decode(p, len, srv->srv_nam, len + 1); + if (error <= 0) { + free(srv->srv_nam); + free(srv); + return (NULL); + } + return (srv); + } + default: + return (mr->mr_res); + } + return (NULL); +} + +/* + * Free readable resource format created by mdns_get_resource() + */ +void +mdns_free_resource(struct mdns_rrset *mr, void *res) +{ + + if (mr->mr_class != mdns_c_in) + return; + else if (res == NULL) + return; + + switch (mr->mr_type) { + case mdns_in_ptr: + case mdns_in_cname: + free(res); + break; + case mdns_in_txt: { + char **p; + int i; + + for (p = res, i = 0; p[i] != NULL; i++) + free(p[i]); + free(res); + break; + } + case mdns_in_srv: { + struct mdns_res_in_srv *srv; + + srv = res; + free(srv->srv_nam); + free(srv); + break; + } + default: + break; + } +} + +int +mdns_db_name_add(struct mdns *m, const char *ident, unsigned int ifidx, + int flags, const wchar_t *nam) +{ + int mid, error; + size_t ilen, nlen; + struct mdns_msg *mm; + struct mipc_dbident mii; + struct mipc_dbi_name miin; + + MDNS_ASSERT(m); + + ilen = strlen(ident); + if (ilen == 0) + return (-1); + nlen = wcslen(nam); + if (nlen == 0) + return (-1); + + mii.mii_ifidx = ifidx; + mii.mii_len = ilen; + if (flags & MDNS_NAM_SHARED) + mii.mii_shared = 1; + mii.mii_zero = 0; + mid = docmd(m, MIM_IDENT_ADD, 2, &mii, + sizeof(struct mipc_dbident), ident, ilen); + if (mid < 0) + return (-1); + mm = msg_wait(m, mid, NULL); + if (mm == NULL) + return (-1); + + if (mm->mm_msgtype == MIM_ERROR) { + if (errormsg(mm) != MIE_EXISTS) { + msg_free(mm); + return (-1); + } + } + msg_free(mm); + + miin.miin_ifidx = ifidx; + miin.miin_ilen = ilen; + miin.miin_len = nlen; + miin.miin_elen = 0; + miin.miin_active = 0; + miin.miin_zero = 0; + mid = docmd(m, MIM_IDENT_NAME_ADD, 3, &miin, + sizeof(struct mipc_dbi_name), ident, ilen, nam, + nlen * sizeof(wchar_t)); + if (mid < 0) + return (-1); + + mm = msg_wait(m, mid, NULL); + if (mm == NULL) + return (-1); + + error = errormsg(mm); + msg_free(mm); + if (error >= 0) + return (-1); + return (0); +} + +int +mdns_db_name_del(struct mdns *m, const char *ident, unsigned int ifidx, + const wchar_t *nam) +{ + size_t ilen, nlen; + int mid, error; + struct mdns_msg *mm; + struct mipc_dbi_name miin; + + MDNS_ASSERT(m); + + ilen = strlen(ident); + if (ilen == 0) + return (-1); + nlen = wcslen(nam); + if (nlen == 0) + return (-1); + + miin.miin_ifidx = ifidx; + miin.miin_ilen = ilen; + miin.miin_len = nlen; + miin.miin_elen = 0; + miin.miin_active = 0; + miin.miin_zero = 0; + mid = docmd(m, MIM_IDENT_NAME_DEL, 3, &miin, + sizeof(struct mipc_dbi_name), ident, ilen, nam, + nlen * sizeof(wchar_t)); + + mm = msg_wait(m, mid, NULL); + if (mm == NULL) + return (-1); + + error = errormsg(mm); + msg_free(mm); + if (error >= 0) + return (-1); + + /* FIXME Auto remove ident if this was the last name */ + + return (0); +} + +int +mdns_db_res_add(struct mdns *m, const char *ident, unsigned int ifidx, + uint16_t class, uint16_t type, uint32_t ttl, int rhint, const void *res) +{ + size_t ilen, rlen; + int mid, error, ptr; + struct mdns_msg *mm; + struct mipc_dbident mii; + struct mipc_dbi_res_set mirs; + + ilen = strlen(ident); + if (ilen == 0) + return (-1); + + if (rhint == MDNS_RES_DEFAULT) { + mirs.mirs_rlen = wcslen((const wchar_t *)res); + rlen = mirs.mirs_rlen * sizeof(wchar_t); + ptr = 0; + } + else if (rhint == MDNS_RES_POINTER) { + rlen = strlen((const char *)res); + mirs.mirs_rlen = rlen; + ptr = 1; + } + else + return (-1); + + mii.mii_ifidx = ifidx; + mii.mii_len = ilen; + mid = docmd(m, MIM_IDENT_ADD, 2, &mii, + sizeof(struct mipc_dbident), ident, ilen); + if (mid < 0) + return (-1); + mm = msg_wait(m, mid, NULL); + if (mm == NULL) + return (-1); + + if (mm->mm_msgtype == MIM_ERROR) { + if (errormsg(mm) != MIE_EXISTS) { + msg_free(mm); + return (-1); + } + } + msg_free(mm); + + mirs.mirs_ifidx = ifidx; + mirs.mirs_class = class; + mirs.mirs_type = type; + mirs.mirs_ttl = ttl; + mirs.mirs_ilen = ilen; + mirs.mirs_pointer = ptr; + mirs.mirs_zero = 0; + + mid = docmd(m, MIM_IDENT_RES_ADD, 3, + &mirs, sizeof(struct mipc_dbi_res_set), + ident, ilen, res, rlen); + if (mid < 0) + return (-1); + + mm = msg_wait(m, mid, NULL); + if (mm == NULL) + return (-1); + + error = errormsg(mm); + msg_free(mm); + if (error >= 0) + return (-1); + return (0); +} + +int +mdns_db_res_del(struct mdns *m, const char *ident, unsigned int ifidx, + uint16_t class, uint16_t type, int rhint, const void *res) +{ + size_t ilen, rlen; + int mid, error, ptr; + struct mdns_msg *mm; + struct mipc_dbi_res_set mirs; + + ilen = strlen(ident); + if (ilen == 0) + return (-1); + + if (rhint == MDNS_RES_DEFAULT) { + mirs.mirs_rlen = wcslen((const wchar_t *)res); + rlen = mirs.mirs_rlen * sizeof(wchar_t); + ptr = 0; + } + else if (rhint == MDNS_RES_POINTER) { + rlen = strlen((const char *)res); + mirs.mirs_rlen = rlen; + ptr = 1; + } + else + return (-1); + + mirs.mirs_ifidx = ifidx; + mirs.mirs_class = class; + mirs.mirs_type = type; + mirs.mirs_ttl = 0; + mirs.mirs_ilen = ilen; + mirs.mirs_pointer = ptr; + mirs.mirs_zero = 0; + + mid = docmd(m, MIM_IDENT_RES_DEL, 3, + &mirs, sizeof(struct mipc_dbi_res_set), + ident, ilen, res, rlen); + + mm = msg_wait(m, mid, NULL); + if (mm == NULL) + return (-1); + + error = errormsg(mm); + msg_free(mm); + if (error >= 0) + return (-1); + return (0); +} + +static int +errormsg(struct mdns_msg *mm) +{ + struct mipc_error *mie; + + if (mm->mm_msgtype != MIM_ERROR) + return (-1); + + mie = (struct mipc_error *)mm->mm_buf; + return (mie->mie_code); +} + +static int +docmd(struct mdns *m, int cmd, int count, ...) +{ + va_list ap; + int mid, i, n; + void *payload; + size_t plen, msglen; + struct mipc_head mih; + + msglen = sizeof(struct mipc_head); + + va_start(ap, count); + for (i = 0; i < count; i++) { + payload = va_arg(ap, void *); + plen = va_arg(ap, size_t); + msglen += plen; + } + va_end(ap); + + mid = ipc_sethdr(m, &mih, cmd); + mih.mih_msglen = msglen; + do { + n = write(m->m_sock, &mih, sizeof(struct mipc_head)); + } while (n < 0 && errno == EINTR); + if (n <= 0) + return (-1); + + va_start(ap, count); + for (i = 0; i < count; i++) { + payload = va_arg(ap, void *); + plen = va_arg(ap, size_t); + n = write(m->m_sock, payload, plen); + } + va_end(ap); + return (mid); +} + +/* + * Submit a query to the daemon + */ +static int +doquery(struct mdns *m, int cmd, int fam, int ifidx, int tmo, int class, + int type, wchar_t *rec) +{ + size_t rlen; + int n, mid, retval = 0; + struct mdns_msg *mm; + struct mdns_wait *mw; + struct mipc_head mih; + struct mipc_query miq; + struct iovec iov[3]; + + rlen = wcslen(rec); + if (rlen >= MDNS_NAME_LEN) + return (-1); + + mid = ipc_sethdr(m, &mih, MIM_QUERY); + miq.miq_cmd = cmd; + miq.miq_len = rlen; + miq.miq_timeout = tmo; + miq.miq_fam = fam; + miq.miq_ifidx = ifidx; + miq.miq_class = class; + miq.miq_type = type; + + iov[0].iov_base = &mih; + iov[0].iov_len = sizeof(struct mipc_head); + iov[1].iov_base = &miq; + iov[1].iov_len = sizeof(struct mipc_query); + iov[2].iov_base = rec; + iov[2].iov_len = rlen * sizeof(wchar_t); + mih.mih_msglen += sizeof(struct mipc_query) + (rlen * sizeof(wchar_t)); + + do { + n = writev(m->m_sock, iov, 3); + } while (n < 0 && errno == EINTR); + + if (n < 0) + return (-1); + + retval = mid; + mm = sock_read(m, mid, NULL); + if (mm->mm_msgtype == MIM_ERROR) + retval = -1; + msg_free(mm); + + if (retval >= 0 && (cmd == MIQ_CMD_CREG || cmd == MIQ_CMD_ONESHOT)) { + mw = malloc(sizeof(struct mdns_wait)); + mw->mw_seqid = mid; + mw->mw_msgtype = MIM_QUERY; + mw->mw_rrset.mr_class = class; + mw->mw_rrset.mr_type = type; + mw->mw_rrset.mr_ifidx = ifidx; + mw->mw_rrset.mr_family = fam; + wcscpy(mw->mw_rrset.mr_name, rec); + TAILQ_INSERT_TAIL(&m->m_wait, mw, mw_next); + } + + return (retval); +} + static void msg_free(struct mdns_msg *mm) { @@ -503,92 +1037,8 @@ return (mih->mih_id); } -extern struct ctmap class_map[]; -extern int class_map_size; - -/* - * Array to class (integer) translation - */ -int -mdns_atoc(const char *class) -{ - int i; - - for (i = 0; i < class_map_size; i++) { - if (strcasecmp(class_map[i].ctm_str, class) == 0) - return (class_map[i].ctm_int); - } - return (-1); -} - -/* - * Class to array translation - */ -const char * -mdns_ctoa(int class) -{ - int i; - - for (i = 0; i < class_map_size; i++) { - if (class == class_map[i].ctm_int) - return (class_map[i].ctm_str); - } - return (NULL); -} -/* - * Array to type (integer) translation - */ -int -mdns_atot(int class, const char *type) -{ - int i; - struct ctmap *type_map = NULL; - - for (i = 0; i < class_map_size; i++) { - if (class == class_map[i].ctm_int) { - type_map = class_map[i].ctm_child; - break; - } - } - - if (type_map == NULL) - return (-1); - - for (i = 0; type_map[i].ctm_int != -1; i++) { - if (strcasecmp(type_map[i].ctm_str, type) == 0) - return (type_map[i].ctm_int); - } - return (-1); -} - -/* - * Type to array translation - */ -const char * -mdns_ttoa(int class, int type) -{ - int i; - struct ctmap *type_map = NULL; - - for (i = 0; i < class_map_size; i++) { - if (class == class_map[i].ctm_int) { - type_map = class_map[i].ctm_child; - break; - } - } - - if (type_map == NULL) - return (NULL); - - for (i = 0; type_map[i].ctm_int != -1; i++) { - if (type_map[i].ctm_int == type) - return (type_map[i].ctm_str); - } - return (NULL); -} - static ssize_t utf8_decode(char *src, size_t slen, wchar_t *dst, size_t dlen) { @@ -633,147 +1083,3 @@ return (len); } -void * -mdns_get_resource(struct mdns_rrset *mr) -{ - int error; - - if (mr->mr_class != mdns_c_in) - return (mr->mr_res); - else if (mr->mr_reslen == 0 || mr->mr_res == NULL) - return (NULL); - - switch (mr->mr_type) { - case mdns_in_a: - if (mr->mr_reslen != sizeof(struct in_addr)) - return (NULL); - return (mr->mr_res); - case mdns_in_aaaa: - if (mr->mr_reslen != sizeof(struct in6_addr)) - return (NULL); - return (mr->mr_res); - case mdns_in_ptr: - case mdns_in_cname: { - wchar_t *nam; - - nam = malloc((mr->mr_reslen + 1) * sizeof(wchar_t)); - if (nam == NULL) - return (NULL); - error = utf8_decode(mr->mr_res, mr->mr_reslen, nam, - mr->mr_reslen + 1); - if (error <= 0) { - free(nam); - return (NULL); - } - return (nam); - break; - } - case mdns_in_txt: { - char *p, *q, **txt; - size_t len; - uint8_t slen; - int num; - - num = 2; - txt = malloc(sizeof(char *) * num); - if (txt == NULL) - return (NULL); - - len = mr->mr_reslen; - p = mr->mr_res; - while (len != 0 && p < (mr->mr_res + mr->mr_reslen)) { - memcpy(&slen, p++, sizeof(uint8_t)); - if (slen > --len) { - free(txt); - return (NULL); - } - - q = malloc(slen + 1); - memcpy(q, p, slen); - q[slen] = '\0'; - txt[num - 2] = q; - txt[num - 1] = NULL; - txt = realloc(txt, sizeof(char *) * ++num); - p += slen; - len -= slen; - } - return (txt); - break; - } - case mdns_in_srv: { - struct mdns_res_in_srv *srv; - char *p; - uint16_t tmp; - size_t len; - - if (mr->mr_reslen < 6) - return (NULL); - - srv = malloc(sizeof(struct mdns_res_in_srv)); - if (srv == NULL) - return (NULL); - p = mr->mr_res; - len = mr->mr_reslen; - memcpy(&tmp, p, sizeof(uint16_t)); - p += sizeof(uint16_t); - srv->srv_pri = htons(tmp); - - memcpy(&tmp, p, sizeof(uint16_t)); - p += sizeof(uint16_t); - srv->srv_wei = htons(tmp); - - memcpy(&tmp, p, sizeof(uint16_t)); - p += sizeof(uint16_t); - srv->srv_prt = htons(tmp); - - len -= sizeof(uint16_t) * 3; - srv->srv_nam = malloc((len + 1) * sizeof(wchar_t)); - error = utf8_decode(p, len, srv->srv_nam, len + 1); - if (error <= 0) { - free(srv->srv_nam); - free(srv); - return (NULL); - } - return (srv); - } - default: - return (mr->mr_res); - } - return (NULL); -} - -void -mdns_free_resource(struct mdns_rrset *mr, void *res) -{ - - if (mr->mr_class != mdns_c_in) - return; - else if (res == NULL) - return; - - switch (mr->mr_type) { - case mdns_in_ptr: - case mdns_in_cname: - free(res); - break; - case mdns_in_txt: { - char **p; - int i; - - for (p = res, i = 0; p[i] != NULL; i++) - free(p[i]); - free(res); - break; - } - case mdns_in_srv: { - struct mdns_res_in_srv *srv; - - srv = res; - free(srv->srv_nam); - free(srv); - break; >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708161951.l7GJpBgH011518>