Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 41053 Details for
Bug 66295
Patch for glibc adding multicast dns support (mdns rendezvous support)
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
The glibc patch from suse (glibc-2.3.3-mdns-resolver)
glibc-2.3.3-mdns-resolver.diff (text/plain), 10.14 KB, created by
Sébastien ESTIENNE
on 2004-10-04 03:43:31 UTC
(
hide
)
Description:
The glibc patch from suse (glibc-2.3.3-mdns-resolver)
Filename:
MIME Type:
Creator:
Sébastien ESTIENNE
Created:
2004-10-04 03:43:31 UTC
Size:
10.14 KB
patch
obsolete
>--- resolv/res_query.c.orig 2004-02-07 16:20:17.000000000 +0000 >+++ resolv/res_query.c 2004-03-11 15:25:57.000000000 +0000 >@@ -272,6 +272,11 @@ > *domain && !done; > domain++) { > >+ /* don't add "local" domain if query contains a dot */ >+ if (dots && (!__strcasecmp(*domain, "local") || >+ !__strcasecmp(*domain, "local."))) >+ continue; >+ > if (domain[0][0] == '\0' || > (domain[0][0] == '.' && domain[0][1] == '\0')) > root_on_list++; >--- resolv/res_send.c.orig 2004-02-07 16:21:17.000000000 +0000 >+++ resolv/res_send.c 2004-03-11 15:43:19.000000000 +0000 >@@ -86,6 +86,9 @@ > #include <arpa/nameser.h> > #include <arpa/inet.h> > #include <sys/ioctl.h> >+#if defined(_LIBC) && defined(linux) >+#include <net/if.h> >+#endif > > #include <errno.h> > #include <netdb.h> >@@ -188,6 +191,9 @@ > static int send_dg(res_state, const u_char *, int, > u_char **, int *, int *, int, > int *, int *, u_char **); >+static int send_dg_mdns(res_state, const u_char *, int, >+ u_char **, int *, int *, struct sockaddr_in6 *, >+ int *, int *, u_char **); > #ifdef DEBUG > static void Aerror(const res_state, FILE *, const char *, int, > struct sockaddr_in); >@@ -366,6 +372,34 @@ > u_char *ans, int anssiz, u_char **ansp) > { > int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; >+ int usemdns; >+ HEADER *qhp = (HEADER *) buf; >+ >+ usemdns = 0; >+ if (qhp->qr == 0 && qhp->opcode == QUERY && qhp->qdcount == htons(1)) { >+ /* got one simple query */ >+ const u_char *bp, *be; >+ be = buf + buflen; >+ for (bp = buf + NS_HFIXEDSZ; bp < be; ) >+ if ((*bp & NS_CMPRSFLGS) != 0) >+ break; >+ else if (*bp) { >+ if (*bp == 5 && !strncasecmp(bp, "\005local\000", 7)) { >+ usemdns = 1; >+ break; >+ } >+ if (*bp == 3 && !strncasecmp(bp, "\003254\003169\007in-addr\004arpa\000", 22)) { >+ usemdns = 1; >+ break; >+ } >+ if (*bp == 1 && !strncasecmp(bp, "\0010\0018\001e\001f\003ip6\004arpa\000", 18)) { >+ usemdns = 2; >+ break; >+ } >+ bp += *bp + 1; >+ } else >+ break; >+ } > > if (statp->nscount == 0) { > __set_errno (ESRCH); >@@ -524,13 +558,28 @@ > */ > for (try = 0; try < statp->retry; try++) { > #ifdef _LIBC >- for (ns = 0; ns < MAXNS; ns++) >+ for (ns = 0; ns < (usemdns ? 1 : MAXNS); ns++) > #else > for (ns = 0; ns < statp->nscount; ns++) > #endif > { > #ifdef _LIBC > struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns]; >+ if (usemdns == 1) { >+ static struct sockaddr_in mdns4; >+ mdns4.sin_family = AF_INET; >+ mdns4.sin_port = htons(5353); >+ mdns4.sin_addr.s_addr = htonl(0xe00000fb); >+ nsap = (struct sockaddr_in6 *)&mdns4; >+ } >+ if (usemdns == 2) { >+ static struct sockaddr_in6 mdns6; >+ mdns6.sin6_family = AF_INET6; >+ mdns6.sin6_port = htons(5353); >+ mdns6.sin6_addr.s6_addr32[0] = htonl(0xff020000); >+ mdns6.sin6_addr.s6_addr32[3] = htonl(0x000000fb); >+ nsap = &mdns6; >+ } > > if (nsap == NULL) > goto next_ns; >@@ -592,8 +641,11 @@ > resplen = n; > } else { > /* Use datagrams. */ >- n = send_dg(statp, buf, buflen, &ans, &anssiz, &terrno, >- ns, &v_circuit, &gotsomewhere, ansp); >+ if (usemdns) >+ n = send_dg_mdns(statp, buf, buflen, &ans, &anssiz, &terrno, nsap, &v_circuit, &gotsomewhere, ansp); >+ else >+ n = send_dg(statp, buf, buflen, &ans, &anssiz, &terrno, >+ ns, &v_circuit, &gotsomewhere, ansp); > if (n < 0) > return (-1); > if (n == 0) >@@ -665,8 +717,15 @@ > if (!v_circuit) { > if (!gotsomewhere) > __set_errno (ECONNREFUSED); /* no nameservers found */ >- else >+ else if (!usemdns) { > __set_errno (ETIMEDOUT); /* no answer obtained */ >+ } else { >+ /* treat timeout as host not found */ >+ HEADER *anhp = (HEADER *) ans; >+ memset(ans, 0, HFIXEDSZ); >+ anhp->rcode = NXDOMAIN; >+ return HFIXEDSZ; >+ } > } else > __set_errno (terrno); > return (-1); >@@ -1127,6 +1186,255 @@ > return (resplen); > } > >+static int >+send_dg_mdns(res_state statp, >+ const u_char *buf, int buflen, u_char **ansp, int *anssizp, >+ int *terrno, struct sockaddr_in6 *nsap, int *v_circuit, int *gotsomewhere, u_char **anscp) >+{ >+ const HEADER *hp = (HEADER *) buf; >+ u_char *ans = *ansp; >+ int anssiz = *anssizp; >+ HEADER *anhp = (HEADER *) ans; >+ struct timespec now, timeout, finish; >+ struct pollfd pfd[32]; >+ int ptimeout; >+ int fromlen, resplen, seconds, n, s; >+ int on = 1; >+ struct msghdr mhdr; >+ struct iovec iov; >+ u_char cmsgbuf[CMSG_SPACE(sizeof(int))]; >+ struct cmsghdr *cmsg; >+ int ttl; >+ struct ifconf ifconf; >+ struct ifreq ifreq[64]; >+ int ifreqn; >+ int i, j; >+ int ifidx[32], ifidxn; >+ struct ip_mreqn mreqn; >+ >+ s = socket(nsap->sin6_family == AF_INET ? PF_INET : PF_INET6, SOCK_DGRAM, 0); >+ if (s < 0) { >+ *terrno = errno; >+ Perror(statp, stderr, "socket(dg)", errno); >+ return (-1); >+ } >+ ifconf.ifc_len = sizeof(ifreq); >+ ifconf.ifc_req = ifreq; >+ ifidxn = 0; >+ if (ioctl(s, SIOCGIFCONF, &ifconf) == 0) { >+ ifreqn = ifconf.ifc_len / sizeof(*ifreq); >+ for (i = 0 ; i < ifreqn; i++) { >+ if (ioctl(s, SIOCGIFFLAGS, ifreq + i)) >+ continue; >+ if (!(ifreq[i].ifr_flags & IFF_MULTICAST)) >+ continue; >+ if (ioctl(s, SIOCGIFINDEX, ifreq + i)) >+ continue; >+ for (j = 0; j < ifidxn; j++) >+ if (ifidx[j] == ifreq[i].ifr_ifindex) >+ break; >+ if (j < ifidxn) >+ continue; >+ ifidx[ifidxn++] = ifreq[i].ifr_ifindex; >+ if (ifidxn == sizeof(ifidx)/sizeof(*ifidx)) >+ break; >+ } >+ } >+ j = 0; >+ for (i = 0; i < (ifidxn ? ifidxn : 1); i++) { >+ if (i) { >+ s = socket(nsap->sin6_family == AF_INET ? PF_INET : PF_INET6, SOCK_DGRAM, 0); >+ if (!s) >+ continue; >+ } >+ if (setsockopt(s, SOL_IP, IP_RECVTTL, &on, sizeof(on))) { >+ *terrno = errno; >+ Perror(statp, stderr, "IP_RECVTTL(dg)", errno); >+ close(s); >+ continue; >+ } >+ if (ifidxn) { >+ memset(&mreqn, 0, sizeof(mreqn)); >+ mreqn.imr_ifindex = ifidx[i]; >+ if (setsockopt(s, SOL_IP, IP_MULTICAST_IF, &mreqn, sizeof(mreqn))) { >+ *terrno = errno; >+ Perror(statp, stderr, "IP_MULTICAST_IF", errno); >+ close(s); >+ continue; >+ } >+ } >+ if (sendto(s, (char*)buf, buflen, 0, >+ (struct sockaddr *)nsap, sizeof *nsap) != buflen) { >+ Aerror(statp, stderr, "sendto", errno, *(struct sockaddr_in *)nsap); >+ close(s); >+ continue; >+ } >+ pfd[j].fd = s; >+ pfd[j].events = POLLIN; >+ j++; >+ } >+ /* >+ * Wait for reply. >+ */ >+ seconds = statp->retrans; >+ if (seconds <= 0) >+ seconds = 1; >+ evNowTime(&now); >+ evConsTime(&timeout, seconds, 0); >+ evAddTime(&finish, &now, &timeout); >+ wait: >+ if (j == 0) { >+ return (0); >+ } >+ >+ /* Convert struct timespec in milliseconds. */ >+ ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000; >+ n = __poll (pfd, j, ptimeout); >+ if (n == 0) { >+ Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n")); >+ *gotsomewhere = 1; >+ for (i = 0; i < j; i++) >+ close(pfd[i].fd); >+ return (0); >+ } >+ if (n < 0) { >+ if (errno == EINTR) { >+ evNowTime(&now); >+ if (evCmpTime(finish, now) > 0) { >+ evSubTime(&timeout, &finish, &now); >+ goto wait; >+ } >+ } >+ Perror(statp, stderr, "select", errno); >+ for (i = 0; i < j; i++) >+ close(pfd[i].fd); >+ res_nclose(statp); >+ return (0); >+ } >+ for (i = 0; i < j - 1; i++) >+ if (pfd[j].revents == POLLIN) >+ break; >+ s = pfd[i].fd; >+ __set_errno (0); >+ fromlen = sizeof(struct sockaddr_in6); >+ if (anssiz < MAXPACKET >+ && anscp >+ && (ioctl (s, FIONREAD, &resplen) < 0 >+ || anssiz < resplen)) { >+ ans = malloc (MAXPACKET); >+ if (ans == NULL) >+ ans = *ansp; >+ else { >+ anssiz = MAXPACKET; >+ *anssizp = MAXPACKET; >+ *ansp = ans; >+ *anscp = ans; >+ anhp = (HEADER *) ans; >+ } >+ } >+ iov.iov_base = ans; >+ iov.iov_len = anssiz; >+ mhdr.msg_name = 0; >+ mhdr.msg_namelen = 0; >+ mhdr.msg_iov = &iov; >+ mhdr.msg_iovlen = 1; >+ mhdr.msg_control = cmsgbuf; >+ mhdr.msg_controllen = sizeof(cmsgbuf); >+ mhdr.msg_flags = 0; >+ resplen = recvmsg(s, &mhdr, 0); >+ if (resplen <= 0) { >+ if (errno == EAGAIN) >+ goto wait; >+ Perror(statp, stderr, "recvfrom", errno); >+wait2: >+ close(s); >+ if (i < j) >+ memmove(pfd + i, pfd + i + 1, sizeof(*pfd) * (j - i)); >+ j--; >+ goto wait; >+ } >+ cmsg = CMSG_FIRSTHDR(&mhdr); >+ for (cmsg = CMSG_FIRSTHDR(&mhdr); cmsg; CMSG_NXTHDR(&mhdr, cmsg)) >+ if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) >+ break; >+ if (!cmsg) { >+ Dprint(statp->options & RES_DEBUG, >+ (stdout, ";; no TTL found\n")); >+ goto wait2; >+ } >+ ttl = *(int *)CMSG_DATA(cmsg); >+ if (ttl != 255) { >+ Dprint(statp->options & RES_DEBUG, >+ (stdout, ";; answer with bad TTL: %d \n", ttl)); >+ goto wait; >+ } >+ *gotsomewhere = 1; >+ if (resplen < HFIXEDSZ) { >+ /* >+ * Undersized message. >+ */ >+ Dprint(statp->options & RES_DEBUG, >+ (stdout, ";; undersized: %d\n", >+ resplen)); >+ *terrno = EMSGSIZE; >+ goto wait; >+ } >+ if (hp->id != anhp->id) { >+ /* >+ * response from old query, ignore it. >+ * XXX - potential security hazard could >+ * be detected here. >+ */ >+ DprintQ((statp->options & RES_DEBUG) || >+ (statp->pfcode & RES_PRF_REPLY), >+ (stdout, ";; old answer:\n"), >+ ans, (resplen > anssiz) ? anssiz : resplen); >+ goto wait; >+ } >+ if (!(statp->options & RES_INSECURE2) && >+ !res_queriesmatch(buf, buf + buflen, >+ ans, ans + anssiz)) { >+ /* >+ * response contains wrong query? ignore it. >+ * XXX - potential security hazard could >+ * be detected here. >+ */ >+ DprintQ((statp->options & RES_DEBUG) || >+ (statp->pfcode & RES_PRF_REPLY), >+ (stdout, ";; wrong query name:\n"), >+ ans, (resplen > anssiz) ? anssiz : resplen); >+ goto wait; >+ } >+ if (anhp->rcode == SERVFAIL || >+ anhp->rcode == NOTIMP || >+ anhp->rcode == REFUSED) { >+ DprintQ(statp->options & RES_DEBUG, >+ (stdout, "server rejected query:\n"), >+ ans, (resplen > anssiz) ? anssiz : resplen); >+ goto wait; >+ } >+ for (i = 0; i < j; i++) >+ close(pfd[i].fd); >+#if 0 >+ if (!(statp->options & RES_IGNTC) && anhp->tc) { >+ /* >+ * To get the rest of answer, >+ * use TCP with same server. >+ */ >+ Dprint(statp->options & RES_DEBUG, >+ (stdout, ";; truncated answer\n")); >+ *v_circuit = 1; >+ res_nclose(statp); >+ return (1); >+ } >+#endif >+ /* >+ * All is well, or the error is fatal. Signal that the >+ * next nameserver ought not be tried. >+ */ >+ return (resplen); >+} >+ > #ifdef DEBUG > static void > Aerror(const res_state statp, FILE *file, const char *string, int error,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 66295
: 41053 |
45422