1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * HTTP address list routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1997-2007 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
17*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_RESOLV_H
18*5e7646d2SAndroid Build Coastguard Worker # include <resolv.h>
19*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_RESOLV_H */
20*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_POLL
21*5e7646d2SAndroid Build Coastguard Worker # include <poll.h>
22*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_POLL */
23*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
24*5e7646d2SAndroid Build Coastguard Worker # include <fcntl.h>
25*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker
28*5e7646d2SAndroid Build Coastguard Worker /*
29*5e7646d2SAndroid Build Coastguard Worker * 'httpAddrConnect()' - Connect to any of the addresses in the list.
30*5e7646d2SAndroid Build Coastguard Worker *
31*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@ @exclude all@
32*5e7646d2SAndroid Build Coastguard Worker */
33*5e7646d2SAndroid Build Coastguard Worker
34*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t * /* O - Connected address or NULL on failure */
httpAddrConnect(http_addrlist_t * addrlist,int * sock)35*5e7646d2SAndroid Build Coastguard Worker httpAddrConnect(
36*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *addrlist, /* I - List of potential addresses */
37*5e7646d2SAndroid Build Coastguard Worker int *sock) /* O - Socket */
38*5e7646d2SAndroid Build Coastguard Worker {
39*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("httpAddrConnect(addrlist=%p, sock=%p)", (void *)addrlist, (void *)sock));
40*5e7646d2SAndroid Build Coastguard Worker
41*5e7646d2SAndroid Build Coastguard Worker return (httpAddrConnect2(addrlist, sock, 30000, NULL));
42*5e7646d2SAndroid Build Coastguard Worker }
43*5e7646d2SAndroid Build Coastguard Worker
44*5e7646d2SAndroid Build Coastguard Worker
45*5e7646d2SAndroid Build Coastguard Worker /*
46*5e7646d2SAndroid Build Coastguard Worker * 'httpAddrConnect2()' - Connect to any of the addresses in the list with a
47*5e7646d2SAndroid Build Coastguard Worker * timeout and optional cancel.
48*5e7646d2SAndroid Build Coastguard Worker *
49*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
50*5e7646d2SAndroid Build Coastguard Worker */
51*5e7646d2SAndroid Build Coastguard Worker
52*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t * /* O - Connected address or NULL on failure */
httpAddrConnect2(http_addrlist_t * addrlist,int * sock,int msec,int * cancel)53*5e7646d2SAndroid Build Coastguard Worker httpAddrConnect2(
54*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *addrlist, /* I - List of potential addresses */
55*5e7646d2SAndroid Build Coastguard Worker int *sock, /* O - Socket */
56*5e7646d2SAndroid Build Coastguard Worker int msec, /* I - Timeout in milliseconds */
57*5e7646d2SAndroid Build Coastguard Worker int *cancel) /* I - Pointer to "cancel" variable */
58*5e7646d2SAndroid Build Coastguard Worker {
59*5e7646d2SAndroid Build Coastguard Worker int val; /* Socket option value */
60*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
61*5e7646d2SAndroid Build Coastguard Worker int i, j, /* Looping vars */
62*5e7646d2SAndroid Build Coastguard Worker flags, /* Socket flags */
63*5e7646d2SAndroid Build Coastguard Worker result; /* Result from select() or poll() */
64*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
65*5e7646d2SAndroid Build Coastguard Worker int remaining; /* Remaining timeout */
66*5e7646d2SAndroid Build Coastguard Worker int nfds, /* Number of file descriptors */
67*5e7646d2SAndroid Build Coastguard Worker fds[100]; /* Socket file descriptors */
68*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *addrs[100]; /* Addresses */
69*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_POLL
70*5e7646d2SAndroid Build Coastguard Worker int max_fd = -1; /* Highest file descriptor */
71*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_POLL */
72*5e7646d2SAndroid Build Coastguard Worker #ifdef O_NONBLOCK
73*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_POLL
74*5e7646d2SAndroid Build Coastguard Worker struct pollfd pfds[100]; /* Polled file descriptors */
75*5e7646d2SAndroid Build Coastguard Worker # else
76*5e7646d2SAndroid Build Coastguard Worker fd_set input_set, /* select() input set */
77*5e7646d2SAndroid Build Coastguard Worker output_set, /* select() output set */
78*5e7646d2SAndroid Build Coastguard Worker error_set; /* select() error set */
79*5e7646d2SAndroid Build Coastguard Worker struct timeval timeout; /* Timeout */
80*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_POLL */
81*5e7646d2SAndroid Build Coastguard Worker #endif /* O_NONBLOCK */
82*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
83*5e7646d2SAndroid Build Coastguard Worker # ifndef _WIN32
84*5e7646d2SAndroid Build Coastguard Worker socklen_t len; /* Length of value */
85*5e7646d2SAndroid Build Coastguard Worker http_addr_t peer; /* Peer address */
86*5e7646d2SAndroid Build Coastguard Worker # endif /* !_WIN32 */
87*5e7646d2SAndroid Build Coastguard Worker char temp[256]; /* Temporary address string */
88*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
89*5e7646d2SAndroid Build Coastguard Worker
90*5e7646d2SAndroid Build Coastguard Worker
91*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("httpAddrConnect2(addrlist=%p, sock=%p, msec=%d, cancel=%p)", (void *)addrlist, (void *)sock, msec, (void *)cancel));
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker if (!sock)
94*5e7646d2SAndroid Build Coastguard Worker {
95*5e7646d2SAndroid Build Coastguard Worker errno = EINVAL;
96*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
97*5e7646d2SAndroid Build Coastguard Worker return (NULL);
98*5e7646d2SAndroid Build Coastguard Worker }
99*5e7646d2SAndroid Build Coastguard Worker
100*5e7646d2SAndroid Build Coastguard Worker if (cancel && *cancel)
101*5e7646d2SAndroid Build Coastguard Worker return (NULL);
102*5e7646d2SAndroid Build Coastguard Worker
103*5e7646d2SAndroid Build Coastguard Worker if (msec <= 0)
104*5e7646d2SAndroid Build Coastguard Worker msec = INT_MAX;
105*5e7646d2SAndroid Build Coastguard Worker
106*5e7646d2SAndroid Build Coastguard Worker /*
107*5e7646d2SAndroid Build Coastguard Worker * Loop through each address until we connect or run out of addresses...
108*5e7646d2SAndroid Build Coastguard Worker */
109*5e7646d2SAndroid Build Coastguard Worker
110*5e7646d2SAndroid Build Coastguard Worker nfds = 0;
111*5e7646d2SAndroid Build Coastguard Worker remaining = msec;
112*5e7646d2SAndroid Build Coastguard Worker
113*5e7646d2SAndroid Build Coastguard Worker while (remaining > 0)
114*5e7646d2SAndroid Build Coastguard Worker {
115*5e7646d2SAndroid Build Coastguard Worker if (cancel && *cancel)
116*5e7646d2SAndroid Build Coastguard Worker {
117*5e7646d2SAndroid Build Coastguard Worker while (nfds > 0)
118*5e7646d2SAndroid Build Coastguard Worker {
119*5e7646d2SAndroid Build Coastguard Worker nfds --;
120*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(NULL, fds[nfds]);
121*5e7646d2SAndroid Build Coastguard Worker }
122*5e7646d2SAndroid Build Coastguard Worker
123*5e7646d2SAndroid Build Coastguard Worker return (NULL);
124*5e7646d2SAndroid Build Coastguard Worker }
125*5e7646d2SAndroid Build Coastguard Worker
126*5e7646d2SAndroid Build Coastguard Worker if (addrlist && nfds < (int)(sizeof(fds) / sizeof(fds[0])))
127*5e7646d2SAndroid Build Coastguard Worker {
128*5e7646d2SAndroid Build Coastguard Worker /*
129*5e7646d2SAndroid Build Coastguard Worker * Create the socket...
130*5e7646d2SAndroid Build Coastguard Worker */
131*5e7646d2SAndroid Build Coastguard Worker
132*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2httpAddrConnect2: Trying %s:%d...", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), httpAddrPort(&(addrlist->addr))));
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker if ((fds[nfds] = (int)socket(httpAddrFamily(&(addrlist->addr)), SOCK_STREAM, 0)) < 0)
135*5e7646d2SAndroid Build Coastguard Worker {
136*5e7646d2SAndroid Build Coastguard Worker /*
137*5e7646d2SAndroid Build Coastguard Worker * Don't abort yet, as this could just be an issue with the local
138*5e7646d2SAndroid Build Coastguard Worker * system not being configured with IPv4/IPv6/domain socket enabled.
139*5e7646d2SAndroid Build Coastguard Worker *
140*5e7646d2SAndroid Build Coastguard Worker * Just skip this address...
141*5e7646d2SAndroid Build Coastguard Worker */
142*5e7646d2SAndroid Build Coastguard Worker
143*5e7646d2SAndroid Build Coastguard Worker addrlist = addrlist->next;
144*5e7646d2SAndroid Build Coastguard Worker continue;
145*5e7646d2SAndroid Build Coastguard Worker }
146*5e7646d2SAndroid Build Coastguard Worker
147*5e7646d2SAndroid Build Coastguard Worker /*
148*5e7646d2SAndroid Build Coastguard Worker * Set options...
149*5e7646d2SAndroid Build Coastguard Worker */
150*5e7646d2SAndroid Build Coastguard Worker
151*5e7646d2SAndroid Build Coastguard Worker val = 1;
152*5e7646d2SAndroid Build Coastguard Worker setsockopt(fds[nfds], SOL_SOCKET, SO_REUSEADDR, CUPS_SOCAST &val, sizeof(val));
153*5e7646d2SAndroid Build Coastguard Worker
154*5e7646d2SAndroid Build Coastguard Worker #ifdef SO_REUSEPORT
155*5e7646d2SAndroid Build Coastguard Worker val = 1;
156*5e7646d2SAndroid Build Coastguard Worker setsockopt(fds[nfds], SOL_SOCKET, SO_REUSEPORT, CUPS_SOCAST &val, sizeof(val));
157*5e7646d2SAndroid Build Coastguard Worker #endif /* SO_REUSEPORT */
158*5e7646d2SAndroid Build Coastguard Worker
159*5e7646d2SAndroid Build Coastguard Worker #ifdef SO_NOSIGPIPE
160*5e7646d2SAndroid Build Coastguard Worker val = 1;
161*5e7646d2SAndroid Build Coastguard Worker setsockopt(fds[nfds], SOL_SOCKET, SO_NOSIGPIPE, CUPS_SOCAST &val, sizeof(val));
162*5e7646d2SAndroid Build Coastguard Worker #endif /* SO_NOSIGPIPE */
163*5e7646d2SAndroid Build Coastguard Worker
164*5e7646d2SAndroid Build Coastguard Worker /*
165*5e7646d2SAndroid Build Coastguard Worker * Using TCP_NODELAY improves responsiveness, especially on systems
166*5e7646d2SAndroid Build Coastguard Worker * with a slow loopback interface...
167*5e7646d2SAndroid Build Coastguard Worker */
168*5e7646d2SAndroid Build Coastguard Worker
169*5e7646d2SAndroid Build Coastguard Worker val = 1;
170*5e7646d2SAndroid Build Coastguard Worker setsockopt(fds[nfds], IPPROTO_TCP, TCP_NODELAY, CUPS_SOCAST &val, sizeof(val));
171*5e7646d2SAndroid Build Coastguard Worker
172*5e7646d2SAndroid Build Coastguard Worker #ifdef FD_CLOEXEC
173*5e7646d2SAndroid Build Coastguard Worker /*
174*5e7646d2SAndroid Build Coastguard Worker * Close this socket when starting another process...
175*5e7646d2SAndroid Build Coastguard Worker */
176*5e7646d2SAndroid Build Coastguard Worker
177*5e7646d2SAndroid Build Coastguard Worker fcntl(fds[nfds], F_SETFD, FD_CLOEXEC);
178*5e7646d2SAndroid Build Coastguard Worker #endif /* FD_CLOEXEC */
179*5e7646d2SAndroid Build Coastguard Worker
180*5e7646d2SAndroid Build Coastguard Worker #ifdef O_NONBLOCK
181*5e7646d2SAndroid Build Coastguard Worker /*
182*5e7646d2SAndroid Build Coastguard Worker * Do an asynchronous connect by setting the socket non-blocking...
183*5e7646d2SAndroid Build Coastguard Worker */
184*5e7646d2SAndroid Build Coastguard Worker
185*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("httpAddrConnect2: Setting non-blocking connect()"));
186*5e7646d2SAndroid Build Coastguard Worker
187*5e7646d2SAndroid Build Coastguard Worker flags = fcntl(fds[nfds], F_GETFL, 0);
188*5e7646d2SAndroid Build Coastguard Worker fcntl(fds[nfds], F_SETFL, flags | O_NONBLOCK);
189*5e7646d2SAndroid Build Coastguard Worker #endif /* O_NONBLOCK */
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker /*
192*5e7646d2SAndroid Build Coastguard Worker * Then connect...
193*5e7646d2SAndroid Build Coastguard Worker */
194*5e7646d2SAndroid Build Coastguard Worker
195*5e7646d2SAndroid Build Coastguard Worker if (!connect(fds[nfds], &(addrlist->addr.addr), (socklen_t)httpAddrLength(&(addrlist->addr))))
196*5e7646d2SAndroid Build Coastguard Worker {
197*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1httpAddrConnect2: Connected to %s:%d...", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), httpAddrPort(&(addrlist->addr))));
198*5e7646d2SAndroid Build Coastguard Worker
199*5e7646d2SAndroid Build Coastguard Worker #ifdef O_NONBLOCK
200*5e7646d2SAndroid Build Coastguard Worker fcntl(fds[nfds], F_SETFL, flags);
201*5e7646d2SAndroid Build Coastguard Worker #endif /* O_NONBLOCK */
202*5e7646d2SAndroid Build Coastguard Worker
203*5e7646d2SAndroid Build Coastguard Worker *sock = fds[nfds];
204*5e7646d2SAndroid Build Coastguard Worker
205*5e7646d2SAndroid Build Coastguard Worker while (nfds > 0)
206*5e7646d2SAndroid Build Coastguard Worker {
207*5e7646d2SAndroid Build Coastguard Worker nfds --;
208*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(NULL, fds[nfds]);
209*5e7646d2SAndroid Build Coastguard Worker }
210*5e7646d2SAndroid Build Coastguard Worker
211*5e7646d2SAndroid Build Coastguard Worker return (addrlist);
212*5e7646d2SAndroid Build Coastguard Worker }
213*5e7646d2SAndroid Build Coastguard Worker
214*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
215*5e7646d2SAndroid Build Coastguard Worker if (WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK)
216*5e7646d2SAndroid Build Coastguard Worker #else
217*5e7646d2SAndroid Build Coastguard Worker if (errno != EINPROGRESS && errno != EWOULDBLOCK)
218*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
219*5e7646d2SAndroid Build Coastguard Worker {
220*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1httpAddrConnect2: Unable to connect to %s:%d: %s", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), httpAddrPort(&(addrlist->addr)), strerror(errno)));
221*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(NULL, fds[nfds]);
222*5e7646d2SAndroid Build Coastguard Worker addrlist = addrlist->next;
223*5e7646d2SAndroid Build Coastguard Worker continue;
224*5e7646d2SAndroid Build Coastguard Worker }
225*5e7646d2SAndroid Build Coastguard Worker
226*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
227*5e7646d2SAndroid Build Coastguard Worker fcntl(fds[nfds], F_SETFL, flags);
228*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_POLL
231*5e7646d2SAndroid Build Coastguard Worker if (fds[nfds] > max_fd)
232*5e7646d2SAndroid Build Coastguard Worker max_fd = fds[nfds];
233*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_POLL */
234*5e7646d2SAndroid Build Coastguard Worker
235*5e7646d2SAndroid Build Coastguard Worker addrs[nfds] = addrlist;
236*5e7646d2SAndroid Build Coastguard Worker nfds ++;
237*5e7646d2SAndroid Build Coastguard Worker addrlist = addrlist->next;
238*5e7646d2SAndroid Build Coastguard Worker }
239*5e7646d2SAndroid Build Coastguard Worker
240*5e7646d2SAndroid Build Coastguard Worker if (!addrlist && nfds == 0)
241*5e7646d2SAndroid Build Coastguard Worker {
242*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
243*5e7646d2SAndroid Build Coastguard Worker errno = WSAEHOSTDOWN;
244*5e7646d2SAndroid Build Coastguard Worker #else
245*5e7646d2SAndroid Build Coastguard Worker errno = EHOSTDOWN;
246*5e7646d2SAndroid Build Coastguard Worker #endif // _WIN32
247*5e7646d2SAndroid Build Coastguard Worker break;
248*5e7646d2SAndroid Build Coastguard Worker }
249*5e7646d2SAndroid Build Coastguard Worker
250*5e7646d2SAndroid Build Coastguard Worker /*
251*5e7646d2SAndroid Build Coastguard Worker * See if we can connect to any of the addresses so far...
252*5e7646d2SAndroid Build Coastguard Worker */
253*5e7646d2SAndroid Build Coastguard Worker
254*5e7646d2SAndroid Build Coastguard Worker #ifdef O_NONBLOCK
255*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1httpAddrConnect2: Finishing async connect()");
256*5e7646d2SAndroid Build Coastguard Worker
257*5e7646d2SAndroid Build Coastguard Worker do
258*5e7646d2SAndroid Build Coastguard Worker {
259*5e7646d2SAndroid Build Coastguard Worker if (cancel && *cancel)
260*5e7646d2SAndroid Build Coastguard Worker {
261*5e7646d2SAndroid Build Coastguard Worker /*
262*5e7646d2SAndroid Build Coastguard Worker * Close this socket and return...
263*5e7646d2SAndroid Build Coastguard Worker */
264*5e7646d2SAndroid Build Coastguard Worker
265*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1httpAddrConnect2: Canceled connect()");
266*5e7646d2SAndroid Build Coastguard Worker
267*5e7646d2SAndroid Build Coastguard Worker while (nfds > 0)
268*5e7646d2SAndroid Build Coastguard Worker {
269*5e7646d2SAndroid Build Coastguard Worker nfds --;
270*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(NULL, fds[nfds]);
271*5e7646d2SAndroid Build Coastguard Worker }
272*5e7646d2SAndroid Build Coastguard Worker
273*5e7646d2SAndroid Build Coastguard Worker *sock = -1;
274*5e7646d2SAndroid Build Coastguard Worker
275*5e7646d2SAndroid Build Coastguard Worker return (NULL);
276*5e7646d2SAndroid Build Coastguard Worker }
277*5e7646d2SAndroid Build Coastguard Worker
278*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_POLL
279*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < nfds; i ++)
280*5e7646d2SAndroid Build Coastguard Worker {
281*5e7646d2SAndroid Build Coastguard Worker pfds[i].fd = fds[i];
282*5e7646d2SAndroid Build Coastguard Worker pfds[i].events = POLLIN | POLLOUT;
283*5e7646d2SAndroid Build Coastguard Worker }
284*5e7646d2SAndroid Build Coastguard Worker
285*5e7646d2SAndroid Build Coastguard Worker result = poll(pfds, (nfds_t)nfds, addrlist ? 100 : remaining > 250 ? 250 : remaining);
286*5e7646d2SAndroid Build Coastguard Worker
287*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1httpAddrConnect2: poll() returned %d (%d)", result, errno));
288*5e7646d2SAndroid Build Coastguard Worker
289*5e7646d2SAndroid Build Coastguard Worker # else
290*5e7646d2SAndroid Build Coastguard Worker FD_ZERO(&input_set);
291*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < nfds; i ++)
292*5e7646d2SAndroid Build Coastguard Worker FD_SET(fds[i], &input_set);
293*5e7646d2SAndroid Build Coastguard Worker output_set = input_set;
294*5e7646d2SAndroid Build Coastguard Worker error_set = input_set;
295*5e7646d2SAndroid Build Coastguard Worker
296*5e7646d2SAndroid Build Coastguard Worker timeout.tv_sec = 0;
297*5e7646d2SAndroid Build Coastguard Worker timeout.tv_usec = (addrlist ? 100 : remaining > 250 ? 250 : remaining) * 1000;
298*5e7646d2SAndroid Build Coastguard Worker
299*5e7646d2SAndroid Build Coastguard Worker result = select(max_fd + 1, &input_set, &output_set, &error_set, &timeout);
300*5e7646d2SAndroid Build Coastguard Worker
301*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1httpAddrConnect2: select() returned %d (%d)", result, errno));
302*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_POLL */
303*5e7646d2SAndroid Build Coastguard Worker }
304*5e7646d2SAndroid Build Coastguard Worker # ifdef _WIN32
305*5e7646d2SAndroid Build Coastguard Worker while (result < 0 && (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK));
306*5e7646d2SAndroid Build Coastguard Worker # else
307*5e7646d2SAndroid Build Coastguard Worker while (result < 0 && (errno == EINTR || errno == EAGAIN));
308*5e7646d2SAndroid Build Coastguard Worker # endif /* _WIN32 */
309*5e7646d2SAndroid Build Coastguard Worker
310*5e7646d2SAndroid Build Coastguard Worker if (result > 0)
311*5e7646d2SAndroid Build Coastguard Worker {
312*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *connaddr = NULL; /* Connected address, if any */
313*5e7646d2SAndroid Build Coastguard Worker
314*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < nfds; i ++)
315*5e7646d2SAndroid Build Coastguard Worker {
316*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_POLL
317*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("pfds[%d].revents=%x\n", i, pfds[i].revents));
318*5e7646d2SAndroid Build Coastguard Worker if (pfds[i].revents && !(pfds[i].revents & (POLLERR | POLLHUP)))
319*5e7646d2SAndroid Build Coastguard Worker # else
320*5e7646d2SAndroid Build Coastguard Worker if (FD_ISSET(fds[i], &input_set) && !FD_ISSET(fds[i], &error_set))
321*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_POLL */
322*5e7646d2SAndroid Build Coastguard Worker {
323*5e7646d2SAndroid Build Coastguard Worker *sock = fds[i];
324*5e7646d2SAndroid Build Coastguard Worker connaddr = addrs[i];
325*5e7646d2SAndroid Build Coastguard Worker
326*5e7646d2SAndroid Build Coastguard Worker # ifdef DEBUG
327*5e7646d2SAndroid Build Coastguard Worker len = sizeof(peer);
328*5e7646d2SAndroid Build Coastguard Worker if (!getpeername(fds[i], (struct sockaddr *)&peer, &len))
329*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1httpAddrConnect2: Connected to %s:%d...", httpAddrString(&peer, temp, sizeof(temp)), httpAddrPort(&peer)));
330*5e7646d2SAndroid Build Coastguard Worker # endif /* DEBUG */
331*5e7646d2SAndroid Build Coastguard Worker
332*5e7646d2SAndroid Build Coastguard Worker break;
333*5e7646d2SAndroid Build Coastguard Worker }
334*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_POLL
335*5e7646d2SAndroid Build Coastguard Worker else if (pfds[i].revents & (POLLERR | POLLHUP))
336*5e7646d2SAndroid Build Coastguard Worker # else
337*5e7646d2SAndroid Build Coastguard Worker else if (FD_ISSET(fds[i], &error_set))
338*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_POLL */
339*5e7646d2SAndroid Build Coastguard Worker {
340*5e7646d2SAndroid Build Coastguard Worker /*
341*5e7646d2SAndroid Build Coastguard Worker * Error on socket, remove from the "pool"...
342*5e7646d2SAndroid Build Coastguard Worker */
343*5e7646d2SAndroid Build Coastguard Worker
344*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(NULL, fds[i]);
345*5e7646d2SAndroid Build Coastguard Worker nfds --;
346*5e7646d2SAndroid Build Coastguard Worker if (i < nfds)
347*5e7646d2SAndroid Build Coastguard Worker {
348*5e7646d2SAndroid Build Coastguard Worker memmove(fds + i, fds + i + 1, (size_t)(nfds - i) * (sizeof(fds[0])));
349*5e7646d2SAndroid Build Coastguard Worker memmove(addrs + i, addrs + i + 1, (size_t)(nfds - i) * (sizeof(addrs[0])));
350*5e7646d2SAndroid Build Coastguard Worker }
351*5e7646d2SAndroid Build Coastguard Worker i --;
352*5e7646d2SAndroid Build Coastguard Worker }
353*5e7646d2SAndroid Build Coastguard Worker }
354*5e7646d2SAndroid Build Coastguard Worker
355*5e7646d2SAndroid Build Coastguard Worker if (connaddr)
356*5e7646d2SAndroid Build Coastguard Worker {
357*5e7646d2SAndroid Build Coastguard Worker /*
358*5e7646d2SAndroid Build Coastguard Worker * Connected on one address, close all of the other sockets we have so
359*5e7646d2SAndroid Build Coastguard Worker * far and return...
360*5e7646d2SAndroid Build Coastguard Worker */
361*5e7646d2SAndroid Build Coastguard Worker
362*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < i; j ++)
363*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(NULL, fds[j]);
364*5e7646d2SAndroid Build Coastguard Worker
365*5e7646d2SAndroid Build Coastguard Worker for (j ++; j < nfds; j ++)
366*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(NULL, fds[j]);
367*5e7646d2SAndroid Build Coastguard Worker
368*5e7646d2SAndroid Build Coastguard Worker return (connaddr);
369*5e7646d2SAndroid Build Coastguard Worker }
370*5e7646d2SAndroid Build Coastguard Worker }
371*5e7646d2SAndroid Build Coastguard Worker #endif /* O_NONBLOCK */
372*5e7646d2SAndroid Build Coastguard Worker
373*5e7646d2SAndroid Build Coastguard Worker if (addrlist)
374*5e7646d2SAndroid Build Coastguard Worker remaining -= 100;
375*5e7646d2SAndroid Build Coastguard Worker else
376*5e7646d2SAndroid Build Coastguard Worker remaining -= 250;
377*5e7646d2SAndroid Build Coastguard Worker }
378*5e7646d2SAndroid Build Coastguard Worker
379*5e7646d2SAndroid Build Coastguard Worker if (remaining <= 0)
380*5e7646d2SAndroid Build Coastguard Worker errno = ETIMEDOUT;
381*5e7646d2SAndroid Build Coastguard Worker
382*5e7646d2SAndroid Build Coastguard Worker while (nfds > 0)
383*5e7646d2SAndroid Build Coastguard Worker {
384*5e7646d2SAndroid Build Coastguard Worker nfds --;
385*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(NULL, fds[nfds]);
386*5e7646d2SAndroid Build Coastguard Worker }
387*5e7646d2SAndroid Build Coastguard Worker
388*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
389*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, "Connection failed", 0);
390*5e7646d2SAndroid Build Coastguard Worker #else
391*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, strerror(errno), 0);
392*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
393*5e7646d2SAndroid Build Coastguard Worker
394*5e7646d2SAndroid Build Coastguard Worker return (NULL);
395*5e7646d2SAndroid Build Coastguard Worker }
396*5e7646d2SAndroid Build Coastguard Worker
397*5e7646d2SAndroid Build Coastguard Worker
398*5e7646d2SAndroid Build Coastguard Worker /*
399*5e7646d2SAndroid Build Coastguard Worker * 'httpAddrCopyList()' - Copy an address list.
400*5e7646d2SAndroid Build Coastguard Worker *
401*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
402*5e7646d2SAndroid Build Coastguard Worker */
403*5e7646d2SAndroid Build Coastguard Worker
404*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t * /* O - New address list or @code NULL@ on error */
httpAddrCopyList(http_addrlist_t * src)405*5e7646d2SAndroid Build Coastguard Worker httpAddrCopyList(
406*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *src) /* I - Source address list */
407*5e7646d2SAndroid Build Coastguard Worker {
408*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *dst = NULL, /* First list entry */
409*5e7646d2SAndroid Build Coastguard Worker *prev = NULL, /* Previous list entry */
410*5e7646d2SAndroid Build Coastguard Worker *current = NULL;/* Current list entry */
411*5e7646d2SAndroid Build Coastguard Worker
412*5e7646d2SAndroid Build Coastguard Worker
413*5e7646d2SAndroid Build Coastguard Worker while (src)
414*5e7646d2SAndroid Build Coastguard Worker {
415*5e7646d2SAndroid Build Coastguard Worker if ((current = malloc(sizeof(http_addrlist_t))) == NULL)
416*5e7646d2SAndroid Build Coastguard Worker {
417*5e7646d2SAndroid Build Coastguard Worker current = dst;
418*5e7646d2SAndroid Build Coastguard Worker
419*5e7646d2SAndroid Build Coastguard Worker while (current)
420*5e7646d2SAndroid Build Coastguard Worker {
421*5e7646d2SAndroid Build Coastguard Worker prev = current;
422*5e7646d2SAndroid Build Coastguard Worker current = current->next;
423*5e7646d2SAndroid Build Coastguard Worker
424*5e7646d2SAndroid Build Coastguard Worker free(prev);
425*5e7646d2SAndroid Build Coastguard Worker }
426*5e7646d2SAndroid Build Coastguard Worker
427*5e7646d2SAndroid Build Coastguard Worker return (NULL);
428*5e7646d2SAndroid Build Coastguard Worker }
429*5e7646d2SAndroid Build Coastguard Worker
430*5e7646d2SAndroid Build Coastguard Worker memcpy(current, src, sizeof(http_addrlist_t));
431*5e7646d2SAndroid Build Coastguard Worker
432*5e7646d2SAndroid Build Coastguard Worker current->next = NULL;
433*5e7646d2SAndroid Build Coastguard Worker
434*5e7646d2SAndroid Build Coastguard Worker if (prev)
435*5e7646d2SAndroid Build Coastguard Worker prev->next = current;
436*5e7646d2SAndroid Build Coastguard Worker else
437*5e7646d2SAndroid Build Coastguard Worker dst = current;
438*5e7646d2SAndroid Build Coastguard Worker
439*5e7646d2SAndroid Build Coastguard Worker prev = current;
440*5e7646d2SAndroid Build Coastguard Worker src = src->next;
441*5e7646d2SAndroid Build Coastguard Worker }
442*5e7646d2SAndroid Build Coastguard Worker
443*5e7646d2SAndroid Build Coastguard Worker return (dst);
444*5e7646d2SAndroid Build Coastguard Worker }
445*5e7646d2SAndroid Build Coastguard Worker
446*5e7646d2SAndroid Build Coastguard Worker
447*5e7646d2SAndroid Build Coastguard Worker /*
448*5e7646d2SAndroid Build Coastguard Worker * 'httpAddrFreeList()' - Free an address list.
449*5e7646d2SAndroid Build Coastguard Worker *
450*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
451*5e7646d2SAndroid Build Coastguard Worker */
452*5e7646d2SAndroid Build Coastguard Worker
453*5e7646d2SAndroid Build Coastguard Worker void
httpAddrFreeList(http_addrlist_t * addrlist)454*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(
455*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *addrlist) /* I - Address list to free */
456*5e7646d2SAndroid Build Coastguard Worker {
457*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *next; /* Next address in list */
458*5e7646d2SAndroid Build Coastguard Worker
459*5e7646d2SAndroid Build Coastguard Worker
460*5e7646d2SAndroid Build Coastguard Worker /*
461*5e7646d2SAndroid Build Coastguard Worker * Free each address in the list...
462*5e7646d2SAndroid Build Coastguard Worker */
463*5e7646d2SAndroid Build Coastguard Worker
464*5e7646d2SAndroid Build Coastguard Worker while (addrlist)
465*5e7646d2SAndroid Build Coastguard Worker {
466*5e7646d2SAndroid Build Coastguard Worker next = addrlist->next;
467*5e7646d2SAndroid Build Coastguard Worker
468*5e7646d2SAndroid Build Coastguard Worker free(addrlist);
469*5e7646d2SAndroid Build Coastguard Worker
470*5e7646d2SAndroid Build Coastguard Worker addrlist = next;
471*5e7646d2SAndroid Build Coastguard Worker }
472*5e7646d2SAndroid Build Coastguard Worker }
473*5e7646d2SAndroid Build Coastguard Worker
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker /*
476*5e7646d2SAndroid Build Coastguard Worker * 'httpAddrGetList()' - Get a list of addresses for a hostname.
477*5e7646d2SAndroid Build Coastguard Worker *
478*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
479*5e7646d2SAndroid Build Coastguard Worker */
480*5e7646d2SAndroid Build Coastguard Worker
481*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t * /* O - List of addresses or NULL */
httpAddrGetList(const char * hostname,int family,const char * service)482*5e7646d2SAndroid Build Coastguard Worker httpAddrGetList(const char *hostname, /* I - Hostname, IP address, or NULL for passive listen address */
483*5e7646d2SAndroid Build Coastguard Worker int family, /* I - Address family or AF_UNSPEC */
484*5e7646d2SAndroid Build Coastguard Worker const char *service) /* I - Service name or port number */
485*5e7646d2SAndroid Build Coastguard Worker {
486*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *first, /* First address in list */
487*5e7646d2SAndroid Build Coastguard Worker *addr, /* Current address in list */
488*5e7646d2SAndroid Build Coastguard Worker *temp; /* New address */
489*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals();
490*5e7646d2SAndroid Build Coastguard Worker /* Global data */
491*5e7646d2SAndroid Build Coastguard Worker
492*5e7646d2SAndroid Build Coastguard Worker
493*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
494*5e7646d2SAndroid Build Coastguard Worker _cups_debug_printf("httpAddrGetList(hostname=\"%s\", family=AF_%s, "
495*5e7646d2SAndroid Build Coastguard Worker "service=\"%s\")\n",
496*5e7646d2SAndroid Build Coastguard Worker hostname ? hostname : "(nil)",
497*5e7646d2SAndroid Build Coastguard Worker family == AF_UNSPEC ? "UNSPEC" :
498*5e7646d2SAndroid Build Coastguard Worker # ifdef AF_LOCAL
499*5e7646d2SAndroid Build Coastguard Worker family == AF_LOCAL ? "LOCAL" :
500*5e7646d2SAndroid Build Coastguard Worker # endif /* AF_LOCAL */
501*5e7646d2SAndroid Build Coastguard Worker # ifdef AF_INET6
502*5e7646d2SAndroid Build Coastguard Worker family == AF_INET6 ? "INET6" :
503*5e7646d2SAndroid Build Coastguard Worker # endif /* AF_INET6 */
504*5e7646d2SAndroid Build Coastguard Worker family == AF_INET ? "INET" : "???", service);
505*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
506*5e7646d2SAndroid Build Coastguard Worker
507*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_RES_INIT
508*5e7646d2SAndroid Build Coastguard Worker /*
509*5e7646d2SAndroid Build Coastguard Worker * STR #2920: Initialize resolver after failure in cups-polld
510*5e7646d2SAndroid Build Coastguard Worker *
511*5e7646d2SAndroid Build Coastguard Worker * If the previous lookup failed, re-initialize the resolver to prevent
512*5e7646d2SAndroid Build Coastguard Worker * temporary network errors from persisting. This *should* be handled by
513*5e7646d2SAndroid Build Coastguard Worker * the resolver libraries, but apparently the glibc folks do not agree.
514*5e7646d2SAndroid Build Coastguard Worker *
515*5e7646d2SAndroid Build Coastguard Worker * We set a flag at the end of this function if we encounter an error that
516*5e7646d2SAndroid Build Coastguard Worker * requires reinitialization of the resolver functions. We then call
517*5e7646d2SAndroid Build Coastguard Worker * res_init() if the flag is set on the next call here or in httpAddrLookup().
518*5e7646d2SAndroid Build Coastguard Worker */
519*5e7646d2SAndroid Build Coastguard Worker
520*5e7646d2SAndroid Build Coastguard Worker if (cg->need_res_init)
521*5e7646d2SAndroid Build Coastguard Worker {
522*5e7646d2SAndroid Build Coastguard Worker res_init();
523*5e7646d2SAndroid Build Coastguard Worker
524*5e7646d2SAndroid Build Coastguard Worker cg->need_res_init = 0;
525*5e7646d2SAndroid Build Coastguard Worker }
526*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_RES_INIT */
527*5e7646d2SAndroid Build Coastguard Worker
528*5e7646d2SAndroid Build Coastguard Worker /*
529*5e7646d2SAndroid Build Coastguard Worker * Lookup the address the best way we can...
530*5e7646d2SAndroid Build Coastguard Worker */
531*5e7646d2SAndroid Build Coastguard Worker
532*5e7646d2SAndroid Build Coastguard Worker first = addr = NULL;
533*5e7646d2SAndroid Build Coastguard Worker
534*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
535*5e7646d2SAndroid Build Coastguard Worker if (hostname && hostname[0] == '/')
536*5e7646d2SAndroid Build Coastguard Worker {
537*5e7646d2SAndroid Build Coastguard Worker /*
538*5e7646d2SAndroid Build Coastguard Worker * Domain socket address...
539*5e7646d2SAndroid Build Coastguard Worker */
540*5e7646d2SAndroid Build Coastguard Worker
541*5e7646d2SAndroid Build Coastguard Worker if ((first = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t))) != NULL)
542*5e7646d2SAndroid Build Coastguard Worker {
543*5e7646d2SAndroid Build Coastguard Worker addr = first;
544*5e7646d2SAndroid Build Coastguard Worker first->addr.un.sun_family = AF_LOCAL;
545*5e7646d2SAndroid Build Coastguard Worker strlcpy(first->addr.un.sun_path, hostname, sizeof(first->addr.un.sun_path));
546*5e7646d2SAndroid Build Coastguard Worker }
547*5e7646d2SAndroid Build Coastguard Worker }
548*5e7646d2SAndroid Build Coastguard Worker else
549*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
550*5e7646d2SAndroid Build Coastguard Worker if (!hostname || _cups_strcasecmp(hostname, "localhost"))
551*5e7646d2SAndroid Build Coastguard Worker {
552*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_GETADDRINFO
553*5e7646d2SAndroid Build Coastguard Worker struct addrinfo hints, /* Address lookup hints */
554*5e7646d2SAndroid Build Coastguard Worker *results, /* Address lookup results */
555*5e7646d2SAndroid Build Coastguard Worker *current; /* Current result */
556*5e7646d2SAndroid Build Coastguard Worker char ipv6[64], /* IPv6 address */
557*5e7646d2SAndroid Build Coastguard Worker *ipv6zone; /* Pointer to zone separator */
558*5e7646d2SAndroid Build Coastguard Worker int ipv6len; /* Length of IPv6 address */
559*5e7646d2SAndroid Build Coastguard Worker int error; /* getaddrinfo() error */
560*5e7646d2SAndroid Build Coastguard Worker
561*5e7646d2SAndroid Build Coastguard Worker
562*5e7646d2SAndroid Build Coastguard Worker /*
563*5e7646d2SAndroid Build Coastguard Worker * Lookup the address as needed...
564*5e7646d2SAndroid Build Coastguard Worker */
565*5e7646d2SAndroid Build Coastguard Worker
566*5e7646d2SAndroid Build Coastguard Worker memset(&hints, 0, sizeof(hints));
567*5e7646d2SAndroid Build Coastguard Worker hints.ai_family = family;
568*5e7646d2SAndroid Build Coastguard Worker hints.ai_flags = hostname ? 0 : AI_PASSIVE;
569*5e7646d2SAndroid Build Coastguard Worker hints.ai_socktype = SOCK_STREAM;
570*5e7646d2SAndroid Build Coastguard Worker
571*5e7646d2SAndroid Build Coastguard Worker if (hostname && *hostname == '[')
572*5e7646d2SAndroid Build Coastguard Worker {
573*5e7646d2SAndroid Build Coastguard Worker /*
574*5e7646d2SAndroid Build Coastguard Worker * Remove brackets from numeric IPv6 address...
575*5e7646d2SAndroid Build Coastguard Worker */
576*5e7646d2SAndroid Build Coastguard Worker
577*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(hostname, "[v1.", 4))
578*5e7646d2SAndroid Build Coastguard Worker {
579*5e7646d2SAndroid Build Coastguard Worker /*
580*5e7646d2SAndroid Build Coastguard Worker * Copy the newer address format which supports link-local addresses...
581*5e7646d2SAndroid Build Coastguard Worker */
582*5e7646d2SAndroid Build Coastguard Worker
583*5e7646d2SAndroid Build Coastguard Worker strlcpy(ipv6, hostname + 4, sizeof(ipv6));
584*5e7646d2SAndroid Build Coastguard Worker if ((ipv6len = (int)strlen(ipv6) - 1) >= 0 && ipv6[ipv6len] == ']')
585*5e7646d2SAndroid Build Coastguard Worker {
586*5e7646d2SAndroid Build Coastguard Worker ipv6[ipv6len] = '\0';
587*5e7646d2SAndroid Build Coastguard Worker hostname = ipv6;
588*5e7646d2SAndroid Build Coastguard Worker
589*5e7646d2SAndroid Build Coastguard Worker /*
590*5e7646d2SAndroid Build Coastguard Worker * Convert "+zone" in address to "%zone"...
591*5e7646d2SAndroid Build Coastguard Worker */
592*5e7646d2SAndroid Build Coastguard Worker
593*5e7646d2SAndroid Build Coastguard Worker if ((ipv6zone = strrchr(ipv6, '+')) != NULL)
594*5e7646d2SAndroid Build Coastguard Worker *ipv6zone = '%';
595*5e7646d2SAndroid Build Coastguard Worker }
596*5e7646d2SAndroid Build Coastguard Worker }
597*5e7646d2SAndroid Build Coastguard Worker else
598*5e7646d2SAndroid Build Coastguard Worker {
599*5e7646d2SAndroid Build Coastguard Worker /*
600*5e7646d2SAndroid Build Coastguard Worker * Copy the regular non-link-local IPv6 address...
601*5e7646d2SAndroid Build Coastguard Worker */
602*5e7646d2SAndroid Build Coastguard Worker
603*5e7646d2SAndroid Build Coastguard Worker strlcpy(ipv6, hostname + 1, sizeof(ipv6));
604*5e7646d2SAndroid Build Coastguard Worker if ((ipv6len = (int)strlen(ipv6) - 1) >= 0 && ipv6[ipv6len] == ']')
605*5e7646d2SAndroid Build Coastguard Worker {
606*5e7646d2SAndroid Build Coastguard Worker ipv6[ipv6len] = '\0';
607*5e7646d2SAndroid Build Coastguard Worker hostname = ipv6;
608*5e7646d2SAndroid Build Coastguard Worker }
609*5e7646d2SAndroid Build Coastguard Worker }
610*5e7646d2SAndroid Build Coastguard Worker }
611*5e7646d2SAndroid Build Coastguard Worker
612*5e7646d2SAndroid Build Coastguard Worker if ((error = getaddrinfo(hostname, service, &hints, &results)) == 0)
613*5e7646d2SAndroid Build Coastguard Worker {
614*5e7646d2SAndroid Build Coastguard Worker /*
615*5e7646d2SAndroid Build Coastguard Worker * Copy the results to our own address list structure...
616*5e7646d2SAndroid Build Coastguard Worker */
617*5e7646d2SAndroid Build Coastguard Worker
618*5e7646d2SAndroid Build Coastguard Worker for (current = results; current; current = current->ai_next)
619*5e7646d2SAndroid Build Coastguard Worker if (current->ai_family == AF_INET || current->ai_family == AF_INET6)
620*5e7646d2SAndroid Build Coastguard Worker {
621*5e7646d2SAndroid Build Coastguard Worker /*
622*5e7646d2SAndroid Build Coastguard Worker * Copy the address over...
623*5e7646d2SAndroid Build Coastguard Worker */
624*5e7646d2SAndroid Build Coastguard Worker
625*5e7646d2SAndroid Build Coastguard Worker temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
626*5e7646d2SAndroid Build Coastguard Worker if (!temp)
627*5e7646d2SAndroid Build Coastguard Worker {
628*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(first);
629*5e7646d2SAndroid Build Coastguard Worker freeaddrinfo(results);
630*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
631*5e7646d2SAndroid Build Coastguard Worker return (NULL);
632*5e7646d2SAndroid Build Coastguard Worker }
633*5e7646d2SAndroid Build Coastguard Worker
634*5e7646d2SAndroid Build Coastguard Worker if (current->ai_family == AF_INET6)
635*5e7646d2SAndroid Build Coastguard Worker memcpy(&(temp->addr.ipv6), current->ai_addr,
636*5e7646d2SAndroid Build Coastguard Worker sizeof(temp->addr.ipv6));
637*5e7646d2SAndroid Build Coastguard Worker else
638*5e7646d2SAndroid Build Coastguard Worker memcpy(&(temp->addr.ipv4), current->ai_addr,
639*5e7646d2SAndroid Build Coastguard Worker sizeof(temp->addr.ipv4));
640*5e7646d2SAndroid Build Coastguard Worker
641*5e7646d2SAndroid Build Coastguard Worker /*
642*5e7646d2SAndroid Build Coastguard Worker * Append the address to the list...
643*5e7646d2SAndroid Build Coastguard Worker */
644*5e7646d2SAndroid Build Coastguard Worker
645*5e7646d2SAndroid Build Coastguard Worker if (!first)
646*5e7646d2SAndroid Build Coastguard Worker first = temp;
647*5e7646d2SAndroid Build Coastguard Worker
648*5e7646d2SAndroid Build Coastguard Worker if (addr)
649*5e7646d2SAndroid Build Coastguard Worker addr->next = temp;
650*5e7646d2SAndroid Build Coastguard Worker
651*5e7646d2SAndroid Build Coastguard Worker addr = temp;
652*5e7646d2SAndroid Build Coastguard Worker }
653*5e7646d2SAndroid Build Coastguard Worker
654*5e7646d2SAndroid Build Coastguard Worker /*
655*5e7646d2SAndroid Build Coastguard Worker * Free the results from getaddrinfo()...
656*5e7646d2SAndroid Build Coastguard Worker */
657*5e7646d2SAndroid Build Coastguard Worker
658*5e7646d2SAndroid Build Coastguard Worker freeaddrinfo(results);
659*5e7646d2SAndroid Build Coastguard Worker }
660*5e7646d2SAndroid Build Coastguard Worker else
661*5e7646d2SAndroid Build Coastguard Worker {
662*5e7646d2SAndroid Build Coastguard Worker if (error == EAI_FAIL)
663*5e7646d2SAndroid Build Coastguard Worker cg->need_res_init = 1;
664*5e7646d2SAndroid Build Coastguard Worker
665*5e7646d2SAndroid Build Coastguard Worker # ifdef _WIN32 /* Really, Microsoft?!? */
666*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gai_strerrorA(error), 0);
667*5e7646d2SAndroid Build Coastguard Worker # else
668*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gai_strerror(error), 0);
669*5e7646d2SAndroid Build Coastguard Worker # endif /* _WIN32 */
670*5e7646d2SAndroid Build Coastguard Worker }
671*5e7646d2SAndroid Build Coastguard Worker
672*5e7646d2SAndroid Build Coastguard Worker #else
673*5e7646d2SAndroid Build Coastguard Worker if (hostname)
674*5e7646d2SAndroid Build Coastguard Worker {
675*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping vars */
676*5e7646d2SAndroid Build Coastguard Worker unsigned ip[4]; /* IPv4 address components */
677*5e7646d2SAndroid Build Coastguard Worker const char *ptr; /* Pointer into hostname */
678*5e7646d2SAndroid Build Coastguard Worker struct hostent *host; /* Result of lookup */
679*5e7646d2SAndroid Build Coastguard Worker struct servent *port; /* Port number for service */
680*5e7646d2SAndroid Build Coastguard Worker int portnum; /* Port number */
681*5e7646d2SAndroid Build Coastguard Worker
682*5e7646d2SAndroid Build Coastguard Worker
683*5e7646d2SAndroid Build Coastguard Worker /*
684*5e7646d2SAndroid Build Coastguard Worker * Lookup the service...
685*5e7646d2SAndroid Build Coastguard Worker */
686*5e7646d2SAndroid Build Coastguard Worker
687*5e7646d2SAndroid Build Coastguard Worker if (!service)
688*5e7646d2SAndroid Build Coastguard Worker portnum = 0;
689*5e7646d2SAndroid Build Coastguard Worker else if (isdigit(*service & 255))
690*5e7646d2SAndroid Build Coastguard Worker portnum = atoi(service);
691*5e7646d2SAndroid Build Coastguard Worker else if ((port = getservbyname(service, NULL)) != NULL)
692*5e7646d2SAndroid Build Coastguard Worker portnum = ntohs(port->s_port);
693*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "http"))
694*5e7646d2SAndroid Build Coastguard Worker portnum = 80;
695*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "https"))
696*5e7646d2SAndroid Build Coastguard Worker portnum = 443;
697*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "ipp") || !strcmp(service, "ipps"))
698*5e7646d2SAndroid Build Coastguard Worker portnum = 631;
699*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "lpd"))
700*5e7646d2SAndroid Build Coastguard Worker portnum = 515;
701*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "socket"))
702*5e7646d2SAndroid Build Coastguard Worker portnum = 9100;
703*5e7646d2SAndroid Build Coastguard Worker else
704*5e7646d2SAndroid Build Coastguard Worker return (NULL);
705*5e7646d2SAndroid Build Coastguard Worker
706*5e7646d2SAndroid Build Coastguard Worker /*
707*5e7646d2SAndroid Build Coastguard Worker * This code is needed because some operating systems have a
708*5e7646d2SAndroid Build Coastguard Worker * buggy implementation of gethostbyname() that does not support
709*5e7646d2SAndroid Build Coastguard Worker * IPv4 addresses. If the hostname string is an IPv4 address, then
710*5e7646d2SAndroid Build Coastguard Worker * sscanf() is used to extract the IPv4 components. We then pack
711*5e7646d2SAndroid Build Coastguard Worker * the components into an IPv4 address manually, since the
712*5e7646d2SAndroid Build Coastguard Worker * inet_aton() function is deprecated. We use the htonl() macro
713*5e7646d2SAndroid Build Coastguard Worker * to get the right byte order for the address.
714*5e7646d2SAndroid Build Coastguard Worker */
715*5e7646d2SAndroid Build Coastguard Worker
716*5e7646d2SAndroid Build Coastguard Worker for (ptr = hostname; isdigit(*ptr & 255) || *ptr == '.'; ptr ++);
717*5e7646d2SAndroid Build Coastguard Worker
718*5e7646d2SAndroid Build Coastguard Worker if (!*ptr)
719*5e7646d2SAndroid Build Coastguard Worker {
720*5e7646d2SAndroid Build Coastguard Worker /*
721*5e7646d2SAndroid Build Coastguard Worker * We have an IPv4 address; break it up and create an IPv4 address...
722*5e7646d2SAndroid Build Coastguard Worker */
723*5e7646d2SAndroid Build Coastguard Worker
724*5e7646d2SAndroid Build Coastguard Worker if (sscanf(hostname, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) == 4 &&
725*5e7646d2SAndroid Build Coastguard Worker ip[0] <= 255 && ip[1] <= 255 && ip[2] <= 255 && ip[3] <= 255)
726*5e7646d2SAndroid Build Coastguard Worker {
727*5e7646d2SAndroid Build Coastguard Worker first = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
728*5e7646d2SAndroid Build Coastguard Worker if (!first)
729*5e7646d2SAndroid Build Coastguard Worker return (NULL);
730*5e7646d2SAndroid Build Coastguard Worker
731*5e7646d2SAndroid Build Coastguard Worker first->addr.ipv4.sin_family = AF_INET;
732*5e7646d2SAndroid Build Coastguard Worker first->addr.ipv4.sin_addr.s_addr = htonl((((((((unsigned)ip[0] << 8) |
733*5e7646d2SAndroid Build Coastguard Worker (unsigned)ip[1]) << 8) |
734*5e7646d2SAndroid Build Coastguard Worker (unsigned)ip[2]) << 8) |
735*5e7646d2SAndroid Build Coastguard Worker (unsigned)ip[3]));
736*5e7646d2SAndroid Build Coastguard Worker first->addr.ipv4.sin_port = htons(portnum);
737*5e7646d2SAndroid Build Coastguard Worker }
738*5e7646d2SAndroid Build Coastguard Worker }
739*5e7646d2SAndroid Build Coastguard Worker else if ((host = gethostbyname(hostname)) != NULL &&
740*5e7646d2SAndroid Build Coastguard Worker # ifdef AF_INET6
741*5e7646d2SAndroid Build Coastguard Worker (host->h_addrtype == AF_INET || host->h_addrtype == AF_INET6))
742*5e7646d2SAndroid Build Coastguard Worker # else
743*5e7646d2SAndroid Build Coastguard Worker host->h_addrtype == AF_INET)
744*5e7646d2SAndroid Build Coastguard Worker # endif /* AF_INET6 */
745*5e7646d2SAndroid Build Coastguard Worker {
746*5e7646d2SAndroid Build Coastguard Worker for (i = 0; host->h_addr_list[i]; i ++)
747*5e7646d2SAndroid Build Coastguard Worker {
748*5e7646d2SAndroid Build Coastguard Worker /*
749*5e7646d2SAndroid Build Coastguard Worker * Copy the address over...
750*5e7646d2SAndroid Build Coastguard Worker */
751*5e7646d2SAndroid Build Coastguard Worker
752*5e7646d2SAndroid Build Coastguard Worker temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
753*5e7646d2SAndroid Build Coastguard Worker if (!temp)
754*5e7646d2SAndroid Build Coastguard Worker {
755*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(first);
756*5e7646d2SAndroid Build Coastguard Worker return (NULL);
757*5e7646d2SAndroid Build Coastguard Worker }
758*5e7646d2SAndroid Build Coastguard Worker
759*5e7646d2SAndroid Build Coastguard Worker # ifdef AF_INET6
760*5e7646d2SAndroid Build Coastguard Worker if (host->h_addrtype == AF_INET6)
761*5e7646d2SAndroid Build Coastguard Worker {
762*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv6.sin6_family = AF_INET6;
763*5e7646d2SAndroid Build Coastguard Worker memcpy(&(temp->addr.ipv6.sin6_addr), host->h_addr_list[i],
764*5e7646d2SAndroid Build Coastguard Worker sizeof(temp->addr.ipv6));
765*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv6.sin6_port = htons(portnum);
766*5e7646d2SAndroid Build Coastguard Worker }
767*5e7646d2SAndroid Build Coastguard Worker else
768*5e7646d2SAndroid Build Coastguard Worker # endif /* AF_INET6 */
769*5e7646d2SAndroid Build Coastguard Worker {
770*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv4.sin_family = AF_INET;
771*5e7646d2SAndroid Build Coastguard Worker memcpy(&(temp->addr.ipv4.sin_addr), host->h_addr_list[i],
772*5e7646d2SAndroid Build Coastguard Worker sizeof(temp->addr.ipv4));
773*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv4.sin_port = htons(portnum);
774*5e7646d2SAndroid Build Coastguard Worker }
775*5e7646d2SAndroid Build Coastguard Worker
776*5e7646d2SAndroid Build Coastguard Worker /*
777*5e7646d2SAndroid Build Coastguard Worker * Append the address to the list...
778*5e7646d2SAndroid Build Coastguard Worker */
779*5e7646d2SAndroid Build Coastguard Worker
780*5e7646d2SAndroid Build Coastguard Worker if (!first)
781*5e7646d2SAndroid Build Coastguard Worker first = temp;
782*5e7646d2SAndroid Build Coastguard Worker
783*5e7646d2SAndroid Build Coastguard Worker if (addr)
784*5e7646d2SAndroid Build Coastguard Worker addr->next = temp;
785*5e7646d2SAndroid Build Coastguard Worker
786*5e7646d2SAndroid Build Coastguard Worker addr = temp;
787*5e7646d2SAndroid Build Coastguard Worker }
788*5e7646d2SAndroid Build Coastguard Worker }
789*5e7646d2SAndroid Build Coastguard Worker else
790*5e7646d2SAndroid Build Coastguard Worker {
791*5e7646d2SAndroid Build Coastguard Worker if (h_errno == NO_RECOVERY)
792*5e7646d2SAndroid Build Coastguard Worker cg->need_res_init = 1;
793*5e7646d2SAndroid Build Coastguard Worker
794*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, hstrerror(h_errno), 0);
795*5e7646d2SAndroid Build Coastguard Worker }
796*5e7646d2SAndroid Build Coastguard Worker }
797*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_GETADDRINFO */
798*5e7646d2SAndroid Build Coastguard Worker }
799*5e7646d2SAndroid Build Coastguard Worker
800*5e7646d2SAndroid Build Coastguard Worker /*
801*5e7646d2SAndroid Build Coastguard Worker * Detect some common errors and handle them sanely...
802*5e7646d2SAndroid Build Coastguard Worker */
803*5e7646d2SAndroid Build Coastguard Worker
804*5e7646d2SAndroid Build Coastguard Worker if (!addr && (!hostname || !_cups_strcasecmp(hostname, "localhost")))
805*5e7646d2SAndroid Build Coastguard Worker {
806*5e7646d2SAndroid Build Coastguard Worker struct servent *port; /* Port number for service */
807*5e7646d2SAndroid Build Coastguard Worker int portnum; /* Port number */
808*5e7646d2SAndroid Build Coastguard Worker
809*5e7646d2SAndroid Build Coastguard Worker
810*5e7646d2SAndroid Build Coastguard Worker /*
811*5e7646d2SAndroid Build Coastguard Worker * Lookup the service...
812*5e7646d2SAndroid Build Coastguard Worker */
813*5e7646d2SAndroid Build Coastguard Worker
814*5e7646d2SAndroid Build Coastguard Worker if (!service)
815*5e7646d2SAndroid Build Coastguard Worker portnum = 0;
816*5e7646d2SAndroid Build Coastguard Worker else if (isdigit(*service & 255))
817*5e7646d2SAndroid Build Coastguard Worker portnum = atoi(service);
818*5e7646d2SAndroid Build Coastguard Worker else if ((port = getservbyname(service, NULL)) != NULL)
819*5e7646d2SAndroid Build Coastguard Worker portnum = ntohs(port->s_port);
820*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "http"))
821*5e7646d2SAndroid Build Coastguard Worker portnum = 80;
822*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "https"))
823*5e7646d2SAndroid Build Coastguard Worker portnum = 443;
824*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "ipp") || !strcmp(service, "ipps"))
825*5e7646d2SAndroid Build Coastguard Worker portnum = 631;
826*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "lpd"))
827*5e7646d2SAndroid Build Coastguard Worker portnum = 515;
828*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(service, "socket"))
829*5e7646d2SAndroid Build Coastguard Worker portnum = 9100;
830*5e7646d2SAndroid Build Coastguard Worker else
831*5e7646d2SAndroid Build Coastguard Worker {
832*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(first);
833*5e7646d2SAndroid Build Coastguard Worker
834*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown service name."), 1);
835*5e7646d2SAndroid Build Coastguard Worker return (NULL);
836*5e7646d2SAndroid Build Coastguard Worker }
837*5e7646d2SAndroid Build Coastguard Worker
838*5e7646d2SAndroid Build Coastguard Worker if (hostname && !_cups_strcasecmp(hostname, "localhost"))
839*5e7646d2SAndroid Build Coastguard Worker {
840*5e7646d2SAndroid Build Coastguard Worker /*
841*5e7646d2SAndroid Build Coastguard Worker * Unfortunately, some users ignore all of the warnings in the
842*5e7646d2SAndroid Build Coastguard Worker * /etc/hosts file and delete "localhost" from it. If we get here
843*5e7646d2SAndroid Build Coastguard Worker * then we were unable to resolve the name, so use the IPv6 and/or
844*5e7646d2SAndroid Build Coastguard Worker * IPv4 loopback interface addresses...
845*5e7646d2SAndroid Build Coastguard Worker */
846*5e7646d2SAndroid Build Coastguard Worker
847*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
848*5e7646d2SAndroid Build Coastguard Worker if (family != AF_INET)
849*5e7646d2SAndroid Build Coastguard Worker {
850*5e7646d2SAndroid Build Coastguard Worker /*
851*5e7646d2SAndroid Build Coastguard Worker * Add [::1] to the address list...
852*5e7646d2SAndroid Build Coastguard Worker */
853*5e7646d2SAndroid Build Coastguard Worker
854*5e7646d2SAndroid Build Coastguard Worker temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
855*5e7646d2SAndroid Build Coastguard Worker if (!temp)
856*5e7646d2SAndroid Build Coastguard Worker {
857*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
858*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(first);
859*5e7646d2SAndroid Build Coastguard Worker return (NULL);
860*5e7646d2SAndroid Build Coastguard Worker }
861*5e7646d2SAndroid Build Coastguard Worker
862*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv6.sin6_family = AF_INET6;
863*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv6.sin6_port = htons(portnum);
864*5e7646d2SAndroid Build Coastguard Worker # ifdef _WIN32
865*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv6.sin6_addr.u.Byte[15] = 1;
866*5e7646d2SAndroid Build Coastguard Worker # else
867*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv6.sin6_addr.s6_addr32[3] = htonl(1);
868*5e7646d2SAndroid Build Coastguard Worker # endif /* _WIN32 */
869*5e7646d2SAndroid Build Coastguard Worker
870*5e7646d2SAndroid Build Coastguard Worker if (!first)
871*5e7646d2SAndroid Build Coastguard Worker first = temp;
872*5e7646d2SAndroid Build Coastguard Worker
873*5e7646d2SAndroid Build Coastguard Worker addr = temp;
874*5e7646d2SAndroid Build Coastguard Worker }
875*5e7646d2SAndroid Build Coastguard Worker
876*5e7646d2SAndroid Build Coastguard Worker if (family != AF_INET6)
877*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
878*5e7646d2SAndroid Build Coastguard Worker {
879*5e7646d2SAndroid Build Coastguard Worker /*
880*5e7646d2SAndroid Build Coastguard Worker * Add 127.0.0.1 to the address list...
881*5e7646d2SAndroid Build Coastguard Worker */
882*5e7646d2SAndroid Build Coastguard Worker
883*5e7646d2SAndroid Build Coastguard Worker temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
884*5e7646d2SAndroid Build Coastguard Worker if (!temp)
885*5e7646d2SAndroid Build Coastguard Worker {
886*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
887*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(first);
888*5e7646d2SAndroid Build Coastguard Worker return (NULL);
889*5e7646d2SAndroid Build Coastguard Worker }
890*5e7646d2SAndroid Build Coastguard Worker
891*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv4.sin_family = AF_INET;
892*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv4.sin_port = htons(portnum);
893*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv4.sin_addr.s_addr = htonl(0x7f000001);
894*5e7646d2SAndroid Build Coastguard Worker
895*5e7646d2SAndroid Build Coastguard Worker if (!first)
896*5e7646d2SAndroid Build Coastguard Worker first = temp;
897*5e7646d2SAndroid Build Coastguard Worker
898*5e7646d2SAndroid Build Coastguard Worker if (addr)
899*5e7646d2SAndroid Build Coastguard Worker addr->next = temp;
900*5e7646d2SAndroid Build Coastguard Worker }
901*5e7646d2SAndroid Build Coastguard Worker }
902*5e7646d2SAndroid Build Coastguard Worker else if (!hostname)
903*5e7646d2SAndroid Build Coastguard Worker {
904*5e7646d2SAndroid Build Coastguard Worker /*
905*5e7646d2SAndroid Build Coastguard Worker * Provide one or more passive listening addresses...
906*5e7646d2SAndroid Build Coastguard Worker */
907*5e7646d2SAndroid Build Coastguard Worker
908*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
909*5e7646d2SAndroid Build Coastguard Worker if (family != AF_INET)
910*5e7646d2SAndroid Build Coastguard Worker {
911*5e7646d2SAndroid Build Coastguard Worker /*
912*5e7646d2SAndroid Build Coastguard Worker * Add [::] to the address list...
913*5e7646d2SAndroid Build Coastguard Worker */
914*5e7646d2SAndroid Build Coastguard Worker
915*5e7646d2SAndroid Build Coastguard Worker temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
916*5e7646d2SAndroid Build Coastguard Worker if (!temp)
917*5e7646d2SAndroid Build Coastguard Worker {
918*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
919*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(first);
920*5e7646d2SAndroid Build Coastguard Worker return (NULL);
921*5e7646d2SAndroid Build Coastguard Worker }
922*5e7646d2SAndroid Build Coastguard Worker
923*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv6.sin6_family = AF_INET6;
924*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv6.sin6_port = htons(portnum);
925*5e7646d2SAndroid Build Coastguard Worker
926*5e7646d2SAndroid Build Coastguard Worker if (!first)
927*5e7646d2SAndroid Build Coastguard Worker first = temp;
928*5e7646d2SAndroid Build Coastguard Worker
929*5e7646d2SAndroid Build Coastguard Worker addr = temp;
930*5e7646d2SAndroid Build Coastguard Worker }
931*5e7646d2SAndroid Build Coastguard Worker
932*5e7646d2SAndroid Build Coastguard Worker if (family != AF_INET6)
933*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
934*5e7646d2SAndroid Build Coastguard Worker {
935*5e7646d2SAndroid Build Coastguard Worker /*
936*5e7646d2SAndroid Build Coastguard Worker * Add 0.0.0.0 to the address list...
937*5e7646d2SAndroid Build Coastguard Worker */
938*5e7646d2SAndroid Build Coastguard Worker
939*5e7646d2SAndroid Build Coastguard Worker temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
940*5e7646d2SAndroid Build Coastguard Worker if (!temp)
941*5e7646d2SAndroid Build Coastguard Worker {
942*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
943*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(first);
944*5e7646d2SAndroid Build Coastguard Worker return (NULL);
945*5e7646d2SAndroid Build Coastguard Worker }
946*5e7646d2SAndroid Build Coastguard Worker
947*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv4.sin_family = AF_INET;
948*5e7646d2SAndroid Build Coastguard Worker temp->addr.ipv4.sin_port = htons(portnum);
949*5e7646d2SAndroid Build Coastguard Worker
950*5e7646d2SAndroid Build Coastguard Worker if (!first)
951*5e7646d2SAndroid Build Coastguard Worker first = temp;
952*5e7646d2SAndroid Build Coastguard Worker
953*5e7646d2SAndroid Build Coastguard Worker if (addr)
954*5e7646d2SAndroid Build Coastguard Worker addr->next = temp;
955*5e7646d2SAndroid Build Coastguard Worker }
956*5e7646d2SAndroid Build Coastguard Worker }
957*5e7646d2SAndroid Build Coastguard Worker }
958*5e7646d2SAndroid Build Coastguard Worker
959*5e7646d2SAndroid Build Coastguard Worker /*
960*5e7646d2SAndroid Build Coastguard Worker * Return the address list...
961*5e7646d2SAndroid Build Coastguard Worker */
962*5e7646d2SAndroid Build Coastguard Worker
963*5e7646d2SAndroid Build Coastguard Worker return (first);
964*5e7646d2SAndroid Build Coastguard Worker }
965