]> git.pld-linux.org Git - packages/glibc.git/blob - glibc-getaddrinfo-workaround.patch
- ReleasE: 9
[packages/glibc.git] / glibc-getaddrinfo-workaround.patch
1 #! /bin/sh -e
2
3 # DP: Hack for some ordering in getaddrinfo lookups
4
5 if [ $# -ne 2 ]; then
6     echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
7     exit 1
8 fi
9 case "$1" in
10     -patch) patch -d "$2" -f --no-backup-if-mismatch -p1 < $0;;
11     -unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p1 < $0;;
12     *)
13         echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
14         exit 1
15 esac
16 exit 0
17
18 --- glibc/sysdeps/posix/getaddrinfo.c~  2000/11/18 08:30:02     1.34
19 +++ glibc/sysdeps/posix/getaddrinfo.c   2001/01/09 01:46:49
20 @@ -264,7 +264,7 @@
21    return 0;
22  }
23  
24 -#define gethosts(_family, _type)                               \
25 +#define gethosts(_family, _type, _name)                                \
26   {                                                             \
27    int i, herrno;                                               \
28    size_t tmpbuflen;                                            \
29 @@ -275,11 +275,12 @@
30    do {                                                         \
31      tmpbuflen *= 2;                                            \
32      tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
33 -    rc = __gethostbyname2_r (name, _family, &th, tmpbuf,       \
34 +    rc = __gethostbyname2_r (_name, _family, &th, tmpbuf,      \
35           tmpbuflen, &h, &herrno);                              \
36    } while (rc == ERANGE && herrno == NETDB_INTERNAL);          \
37    if (rc != 0)                                                 \
38      {                                                          \
39 +      succeeded--;                                             \
40        if (herrno == NETDB_INTERNAL)                            \
41         {                                                       \
42           __set_h_errno (herrno);                               \
43 @@ -307,6 +308,26 @@
44      }                                                          \
45   }
46  
47 +/* If we are looking for both IPv4 and IPv6 address we don't
48 +   want the lookup functions to automatically promote IPv4
49 +   addresses to IPv6 addresses.  Currently this is decided
50 +   by setting the RES_USE_INET6 bit in _res.options.  */
51 +#define tryname(__name)                                                \
52 +  {                                                            \
53 +    succeeded = req->ai_family == AF_UNSPEC ? 2 : 1;           \
54 +    if (req->ai_family == AF_UNSPEC)                           \
55 +      _res.options &= ~RES_USE_INET6;                          \
56 +    if (req->ai_family == AF_UNSPEC ||                         \
57 +       req->ai_family == AF_INET6)                             \
58 +      gethosts (AF_INET6, struct in6_addr, __name);            \
59 +    no_inet6_data = no_data;                                   \
60 +    if (req->ai_family == AF_UNSPEC)                           \
61 +      _res.options = old_res_options;                          \
62 +    if (req->ai_family == AF_UNSPEC ||                         \
63 +       req->ai_family == AF_INET)                              \
64 +    gethosts (AF_INET, struct in_addr, __name);                        \
65 +  }
66 +
67  static int
68  gaih_inet (const char *name, const struct gaih_service *service,
69            const struct addrinfo *req, struct addrinfo **pai)
70 @@ -316,6 +337,10 @@
71    struct gaih_addrtuple *at = NULL;
72    int rc;
73  
74 +  /* Make sure we are initialized now */
75 +  if (!(_res.options & RES_INIT))
76 +    res_ninit(&_res);
77 +
78    if (req->ai_protocol || req->ai_socktype)
79      {
80        ++tp;
81 @@ -489,34 +514,47 @@
82           struct gaih_addrtuple **pat = &at;
83           int no_data = 0;
84           int no_inet6_data;
85 +         int succeeded = -1;
86           int old_res_options = _res.options;
87  
88 -         /* If we are looking for both IPv4 and IPv6 address we don't
89 -            want the lookup functions to automatically promote IPv4
90 -            addresses to IPv6 addresses.  Currently this is decided
91 -            by setting the RES_USE_INET6 bit in _res.options.  */
92 -         if (req->ai_family == AF_UNSPEC)
93 -           _res.options &= ~RES_USE_INET6;
94 -
95 -         if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
96 -           gethosts (AF_INET6, struct in6_addr);
97 -         no_inet6_data = no_data;
98 +         /* If we have a dotted name, first try an absolute lookup.  This
99 +            avoids problem where the resolver will try to search domains
100 +            even though we may have a fqdn, which is bad since ipv6 lookups
101 +            are performed first.  */
102 +         if (strchr(name, '.') != NULL)
103 +           {
104 +             int namelen = strlen(name);
105 +             char *newname = __alloca(namelen + 2);
106  
107 -         if (req->ai_family == AF_UNSPEC)
108 -           _res.options = old_res_options;
109 +             strcpy(newname, name);
110 +             newname[namelen] = '.';
111 +             newname[namelen+1] = '\0';
112  
113 -         if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
114 -           gethosts (AF_INET, struct in_addr);
115 +             tryname(newname);
116 +           }
117  
118 -         if (no_data != 0 && no_inet6_data != 0)
119 +         /* If the previous didn't work, or we don't have a dotted name,
120 +            we try again like normal, letting the resolver manage domain
121 +            searching.  */
122 +         if (succeeded <= 0)
123             {
124 -             /* If both requests timed out report this.  */
125 -             if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
126 -               return -EAI_AGAIN;
127 -
128 -             /* We made requests but they turned out no data.  The name
129 -                is known, though.  */
130 -             return (GAIH_OKIFUNSPEC | -EAI_NODATA);
131 +             _res.options = old_res_options;
132 +
133 +             if (succeeded == 0) /* we've tried absolute, now try searches */
134 +               _res.ndots = 99;
135 +
136 +             tryname(name);
137 +
138 +             if (no_data != 0 && no_inet6_data != 0)
139 +               {
140 +                 /* If both requests timed out report this.  */
141 +                 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
142 +                   return -EAI_AGAIN;
143 +
144 +                 /* We made requests but they turned out no data.  The name
145 +                    is known, though.  */
146 +                 return (GAIH_OKIFUNSPEC | -EAI_NODATA);
147 +               }
148             }
149         }
150  
This page took 0.603059 seconds and 3 git commands to generate.