]> git.sesse.net Git - vlc/blob - extras/contrib/src/Patches/live-getaddrinfo.patch
live: use getaddrinfo() instead of gethostbyname()
[vlc] / extras / contrib / src / Patches / live-getaddrinfo.patch
1 Copyright (C) 2010 RĂ©mi Denis-Courmont.
2 Licensed under GNU General Public License version 2 or higher.
3 diff -ru live.orig//groupsock/GroupsockHelper.cpp live//groupsock/GroupsockHelper.cpp
4 --- live.orig//groupsock/GroupsockHelper.cpp    2010-04-09 22:27:39.000000000 +0300
5 +++ live//groupsock/GroupsockHelper.cpp 2010-04-17 20:18:11.000000000 +0300
6 @@ -625,25 +625,29 @@
7  #include <hostLib.h>
8        if (ERROR == (ourAddress = hostGetByName( hostname ))) break;
9  #else
10 -      struct hostent* hstent
11 -       = (struct hostent*)gethostbyname(hostname);
12 -      if (hstent == NULL || hstent->h_length != 4) {
13 -       env.setResultErrMsg("initial gethostbyname() failed");
14 +      struct addrinfo hints, *res;
15 +      memset(&hints, 0, sizeof(hints));
16 +      hints.ai_family = AF_INET;
17 +      hints.ai_socktype = SOCK_DGRAM;
18 +      hints.ai_protocol = IPPROTO_UDP;
19 +      if (getaddrinfo(hostname, NULL, &hints, &res)) {
20 +       env.setResultErrMsg("initial getaddrinfo() failed");
21         break;
22        }
23        // Take the first address that's not bad
24        // (This code, like many others, won't handle IPv6)
25        netAddressBits addr = 0;
26 -      for (unsigned i = 0; ; ++i) {
27 -       char* addrPtr = hstent->h_addr_list[i];
28 -       if (addrPtr == NULL) break;
29 +      for (const struct addrinfo *p = res; p; p = p->ai_next) {
30 +        const struct in_addr in =
31 +          ((const struct sockaddr_in *)p->ai_addr)->sin_addr;
32  
33 -       netAddressBits a = *(netAddressBits*)addrPtr;
34 +       netAddressBits a = in.s_addr;
35         if (!badAddress(a)) {
36           addr = a;
37           break;
38         }
39        }
40 +      freeaddrinfo(res);
41        if (addr != 0) {
42         fromAddr.sin_addr.s_addr = addr;
43        } else {
44 diff -ru live.orig//groupsock/inet.c live//groupsock/inet.c
45 --- live.orig//groupsock/inet.c 2010-04-09 22:27:39.000000000 +0300
46 +++ live//groupsock/inet.c      2010-04-17 20:14:07.000000000 +0300
47 @@ -83,16 +83,6 @@
48  #define NULL 0
49  #endif
50  
51 -#if !defined(VXWORKS)
52 -struct hostent* our_gethostbyname(name)
53 -     char* name;
54 -{
55 -       if (!initializeWinsockIfNecessary()) return NULL;
56 -
57 -       return (struct hostent*) gethostbyname(name);
58 -}
59 -#endif
60 -
61  #ifndef USE_OUR_RANDOM
62  /* Use the system-supplied "random()" and "srandom()" functions */
63  #include <stdlib.h>
64 diff -ru live.orig//groupsock/NetAddress.cpp live//groupsock/NetAddress.cpp
65 --- live.orig//groupsock/NetAddress.cpp 2010-04-09 22:27:39.000000000 +0300
66 +++ live//groupsock/NetAddress.cpp      2010-04-17 20:13:29.000000000 +0300
67 @@ -83,15 +83,12 @@
68  
69  NetAddressList::NetAddressList(char const* hostname)
70    : fNumAddresses(0), fAddressArray(NULL) {
71 -    struct hostent* host;
72 +
73 +    struct addrinfo *res;
74  
75      // Check first whether "hostname" is an IP address string:
76      netAddressBits addr = our_inet_addr((char*)hostname);
77      if (addr != INADDR_NONE) { // yes it was an IP address string
78 -      //##### host = gethostbyaddr((char*)&addr, sizeof (netAddressBits), AF_INET);
79 -      host = NULL; // don't bother calling gethostbyaddr(); we only want 1 addr
80 -
81 -      if (host == NULL) {
82         // For some unknown reason, gethostbyaddr() failed, so just
83         // return a 1-element list with the address we were given:
84         fNumAddresses = 1;
85 @@ -101,41 +98,40 @@
86         fAddressArray[0] = new NetAddress((u_int8_t*)&addr,
87                                           sizeof (netAddressBits));
88         return;
89 -      }
90      } else { // Try resolving "hostname" as a real host name
91  
92 -#if defined(VXWORKS)
93 -      char hostentBuf[512];
94 -      host = (struct hostent*)resolvGetHostByName((char*)hostname,(char*)&hostentBuf,sizeof hostentBuf);
95 -#else
96 -      host = our_gethostbyname((char*)hostname);
97 -#endif
98 +      struct addrinfo hints;
99 +      memset(&hints, 0, sizeof(hints));
100 +      hints.ai_family = AF_INET;
101 +      hints.ai_socktype = SOCK_DGRAM; /* be sure to not get dups! */
102 +      hints.ai_protocol = IPPROTO_UDP;
103  
104 -      if (host == NULL) {
105 +      if (getaddrinfo(hostname, NULL, &hints, &res))
106         // It was a host name, and we couldn't resolve it.  We're SOL.
107         return;
108 -      }
109      }
110  
111 -    u_int8_t const** const hAddrPtr
112 -      = (u_int8_t const**)host->h_addr_list;
113 -    if (hAddrPtr != NULL) {
114 -      // First, count the number of addresses:
115 -      u_int8_t const** hAddrPtr1 = hAddrPtr;
116 -      while (*hAddrPtr1 != NULL) {
117 -       ++fNumAddresses;
118 -       ++hAddrPtr1;
119 -      }
120 -
121 -      // Next, set up the list:
122 -      fAddressArray = new NetAddress*[fNumAddresses];
123 -      if (fAddressArray == NULL) return;
124 -
125 -      for (unsigned i = 0; i < fNumAddresses; ++i) {
126 -       fAddressArray[i]
127 -         = new NetAddress(hAddrPtr[i], host->h_length);
128 -      }
129 +    // First, count the number of addresses:
130 +    for (const struct addrinfo *p = res; p; p = p->ai_next)
131 +      fNumAddresses++;
132 +
133 +    // Next, set up the list:
134 +    fAddressArray = new NetAddress*[fNumAddresses];
135 +
136 +    unsigned i = 0;
137 +    for (const struct addrinfo *p = res; p; p = p->ai_next) {
138 +      union
139 +      {
140 +       struct in_addr ip4;
141 +       uint8_t b[4];
142 +      } buf;
143 +      const struct sockaddr_in *sin =
144 +        (const struct sockaddr_in *)p->ai_addr;
145 +
146 +      buf.ip4 = sin->sin_addr;
147 +      fAddressArray[i++] = new NetAddress(buf.b, 4);
148      }
149 +    freeaddrinfo(res);
150  }
151  
152  NetAddressList::NetAddressList(NetAddressList const& orig) {