Signal temporary host lookup errors in nscd as such to the requester.
[platform/upstream/glibc.git] / nscd / hstcache.c
1 /* Cache handling for host lookup.
2    Copyright (C) 1998-2008, 2009, 2011 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published
8    by the Free Software Foundation; version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software Foundation,
18    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include <alloca.h>
21 #include <assert.h>
22 #include <errno.h>
23 #include <error.h>
24 #include <libintl.h>
25 #include <netdb.h>
26 #include <stdbool.h>
27 #include <stddef.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <time.h>
32 #include <unistd.h>
33 #include <arpa/inet.h>
34 #include <arpa/nameser.h>
35 #include <sys/mman.h>
36 #include <stackinfo.h>
37
38 #include "nscd.h"
39 #include "dbg_log.h"
40 #ifdef HAVE_SENDFILE
41 # include <kernel-features.h>
42 #endif
43
44
45 /* This is the standard reply in case the service is disabled.  */
46 static const hst_response_header disabled =
47 {
48   .version = NSCD_VERSION,
49   .found = -1,
50   .h_name_len = 0,
51   .h_aliases_cnt = 0,
52   .h_addrtype = -1,
53   .h_length = -1,
54   .h_addr_list_cnt = 0,
55   .error = NETDB_INTERNAL
56 };
57
58 /* This is the struct describing how to write this record.  */
59 const struct iovec hst_iov_disabled =
60 {
61   .iov_base = (void *) &disabled,
62   .iov_len = sizeof (disabled)
63 };
64
65
66 /* This is the standard reply in case we haven't found the dataset.  */
67 static const hst_response_header notfound =
68 {
69   .version = NSCD_VERSION,
70   .found = 0,
71   .h_name_len = 0,
72   .h_aliases_cnt = 0,
73   .h_addrtype = -1,
74   .h_length = -1,
75   .h_addr_list_cnt = 0,
76   .error = HOST_NOT_FOUND
77 };
78
79
80 /* This is the standard reply in case there are temporary problems.  */
81 static const hst_response_header tryagain =
82 {
83   .version = NSCD_VERSION,
84   .found = 0,
85   .h_name_len = 0,
86   .h_aliases_cnt = 0,
87   .h_addrtype = -1,
88   .h_length = -1,
89   .h_addr_list_cnt = 0,
90   .error = TRY_AGAIN
91 };
92
93
94 static void
95 cache_addhst (struct database_dyn *db, int fd, request_header *req,
96               const void *key, struct hostent *hst, uid_t owner,
97               struct hashentry *const he, struct datahead *dh, int errval,
98               int32_t ttl)
99 {
100   bool all_written = true;
101   time_t t = time (NULL);
102
103   /* We allocate all data in one memory block: the iov vector,
104      the response header and the dataset itself.  */
105   struct dataset
106   {
107     struct datahead head;
108     hst_response_header resp;
109     char strdata[0];
110   } *dataset;
111
112   assert (offsetof (struct dataset, resp) == offsetof (struct datahead, data));
113
114   if (hst == NULL)
115     {
116       if (he != NULL && errval == EAGAIN)
117         {
118           /* If we have an old record available but cannot find one
119              now because the service is not available we keep the old
120              record and make sure it does not get removed.  */
121           if (reload_count != UINT_MAX)
122             /* Do not reset the value if we never not reload the record.  */
123             dh->nreloads = reload_count - 1;
124         }
125       else
126         {
127           /* We have no data.  This means we send the standard reply for this
128              case.  Possibly this is only temporary.  */
129           ssize_t total = sizeof (notfound);
130           assert (sizeof (notfound) == sizeof (tryagain));
131
132           const hst_response_header *resp = (errval == EAGAIN
133                                              ? &tryagain : &notfound);
134
135           if (fd != -1 &&
136               TEMP_FAILURE_RETRY (send (fd, resp, total,
137                                         MSG_NOSIGNAL)) != total)
138             all_written = false;
139
140           dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
141                                    1);
142           /* If we cannot permanently store the result, so be it.  */
143           if (dataset != NULL)
144             {
145               dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
146               dataset->head.recsize = total;
147               dataset->head.notfound = true;
148               dataset->head.nreloads = 0;
149               dataset->head.usable = true;
150
151               /* Compute the timeout time.  */
152               dataset->head.timeout = t + (ttl == INT32_MAX
153                                            ? db->negtimeout : ttl);
154
155               /* This is the reply.  */
156               memcpy (&dataset->resp, resp, total);
157
158               /* Copy the key data.  */
159               memcpy (dataset->strdata, key, req->key_len);
160
161               /* If necessary, we also propagate the data to disk.  */
162               if (db->persistent)
163                 {
164                   // XXX async OK?
165                   uintptr_t pval = (uintptr_t) dataset & ~pagesize_m1;
166                   msync ((void *) pval,
167                          ((uintptr_t) dataset & pagesize_m1)
168                          + sizeof (struct dataset) + req->key_len, MS_ASYNC);
169                 }
170
171               (void) cache_add (req->type, &dataset->strdata, req->key_len,
172                                 &dataset->head, true, db, owner, he == NULL);
173
174               pthread_rwlock_unlock (&db->lock);
175
176               /* Mark the old entry as obsolete.  */
177               if (dh != NULL)
178                 dh->usable = false;
179             }
180         }
181     }
182   else
183     {
184       /* Determine the I/O structure.  */
185       size_t h_name_len = strlen (hst->h_name) + 1;
186       size_t h_aliases_cnt;
187       uint32_t *h_aliases_len;
188       size_t h_addr_list_cnt;
189       int addr_list_type;
190       char *addresses;
191       char *aliases;
192       char *key_copy = NULL;
193       char *cp;
194       size_t cnt;
195       ssize_t total;
196
197       /* Determine the number of aliases.  */
198       h_aliases_cnt = 0;
199       for (cnt = 0; hst->h_aliases[cnt] != NULL; ++cnt)
200         ++h_aliases_cnt;
201       /* Determine the length of all aliases.  */
202       h_aliases_len = (uint32_t *) alloca (h_aliases_cnt * sizeof (uint32_t));
203       total = 0;
204       for (cnt = 0; cnt < h_aliases_cnt; ++cnt)
205         {
206           h_aliases_len[cnt] = strlen (hst->h_aliases[cnt]) + 1;
207           total += h_aliases_len[cnt];
208         }
209
210       /* Determine the number of addresses.  */
211       h_addr_list_cnt = 0;
212       while (hst->h_addr_list[h_addr_list_cnt] != NULL)
213         ++h_addr_list_cnt;
214
215       if (h_addr_list_cnt == 0)
216         /* Invalid entry.  */
217         return;
218
219       total += (sizeof (struct dataset)
220                 + h_name_len
221                 + h_aliases_cnt * sizeof (uint32_t)
222                 + h_addr_list_cnt * hst->h_length);
223
224       /* If we refill the cache, first assume the reconrd did not
225          change.  Allocate memory on the cache since it is likely
226          discarded anyway.  If it turns out to be necessary to have a
227          new record we can still allocate real memory.  */
228       bool alloca_used = false;
229       dataset = NULL;
230
231       /* If the record contains more than one IP address (used for
232          load balancing etc) don't cache the entry.  This is something
233          the current cache handling cannot handle and it is more than
234          questionable whether it is worthwhile complicating the cache
235          handling just for handling such a special case. */
236       if (he == NULL && h_addr_list_cnt == 1)
237         dataset = (struct dataset *) mempool_alloc (db, total + req->key_len,
238                                                     1);
239
240       if (dataset == NULL)
241         {
242           /* We cannot permanently add the result in the moment.  But
243              we can provide the result as is.  Store the data in some
244              temporary memory.  */
245           dataset = (struct dataset *) alloca (total + req->key_len);
246
247           /* We cannot add this record to the permanent database.  */
248           alloca_used = true;
249         }
250
251       dataset->head.allocsize = total + req->key_len;
252       dataset->head.recsize = total - offsetof (struct dataset, resp);
253       dataset->head.notfound = false;
254       dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
255       dataset->head.usable = true;
256
257       /* Compute the timeout time.  */
258       dataset->head.timeout = t + (ttl == INT32_MAX ? db->postimeout : ttl);
259
260       dataset->resp.version = NSCD_VERSION;
261       dataset->resp.found = 1;
262       dataset->resp.h_name_len = h_name_len;
263       dataset->resp.h_aliases_cnt = h_aliases_cnt;
264       dataset->resp.h_addrtype = hst->h_addrtype;
265       dataset->resp.h_length = hst->h_length;
266       dataset->resp.h_addr_list_cnt = h_addr_list_cnt;
267       dataset->resp.error = NETDB_SUCCESS;
268
269       /* Make sure there is no gap.  */
270       assert ((char *) (&dataset->resp.error + 1) == dataset->strdata);
271
272       cp = dataset->strdata;
273
274       cp = mempcpy (cp, hst->h_name, h_name_len);
275       cp = mempcpy (cp, h_aliases_len, h_aliases_cnt * sizeof (uint32_t));
276
277       /* The normal addresses first.  */
278       addresses = cp;
279       for (cnt = 0; cnt < h_addr_list_cnt; ++cnt)
280         cp = mempcpy (cp, hst->h_addr_list[cnt], hst->h_length);
281
282       /* Then the aliases.  */
283       aliases = cp;
284       for (cnt = 0; cnt < h_aliases_cnt; ++cnt)
285         cp = mempcpy (cp, hst->h_aliases[cnt], h_aliases_len[cnt]);
286
287       assert (cp
288               == dataset->strdata + total - offsetof (struct dataset,
289                                                       strdata));
290
291       /* If we are adding a GETHOSTBYNAME{,v6} entry we must be prepared
292          that the answer we get from the NSS does not contain the key
293          itself.  This is the case if the resolver is used and the name
294          is extended by the domainnames from /etc/resolv.conf.  Therefore
295          we explicitly add the name here.  */
296       key_copy = memcpy (cp, key, req->key_len);
297
298       assert ((char *) &dataset->resp + dataset->head.recsize == cp);
299
300       /* Now we can determine whether on refill we have to create a new
301          record or not.  */
302       if (he != NULL)
303         {
304           assert (fd == -1);
305
306           if (total + req->key_len == dh->allocsize
307               && total - offsetof (struct dataset, resp) == dh->recsize
308               && memcmp (&dataset->resp, dh->data,
309                          dh->allocsize - offsetof (struct dataset, resp)) == 0)
310             {
311               /* The data has not changed.  We will just bump the
312                  timeout value.  Note that the new record has been
313                  allocated on the stack and need not be freed.  */
314               assert (h_addr_list_cnt == 1);
315               dh->timeout = dataset->head.timeout;
316               ++dh->nreloads;
317             }
318           else
319             {
320               if (h_addr_list_cnt == 1)
321                 {
322                   /* We have to create a new record.  Just allocate
323                      appropriate memory and copy it.  */
324                   struct dataset *newp
325                     = (struct dataset *) mempool_alloc (db,
326                                                         total + req->key_len,
327                                                         1);
328                   if (newp != NULL)
329                     {
330                       /* Adjust pointers into the memory block.  */
331                       addresses = (char *) newp + (addresses
332                                                    - (char *) dataset);
333                       aliases = (char *) newp + (aliases - (char *) dataset);
334                       assert (key_copy != NULL);
335                       key_copy = (char *) newp + (key_copy - (char *) dataset);
336
337                       dataset = memcpy (newp, dataset, total + req->key_len);
338                       alloca_used = false;
339                     }
340                 }
341
342               /* Mark the old record as obsolete.  */
343               dh->usable = false;
344             }
345         }
346       else
347         {
348           /* We write the dataset before inserting it to the database
349              since while inserting this thread might block and so would
350              unnecessarily keep the receiver waiting.  */
351           assert (fd != -1);
352
353 #ifdef HAVE_SENDFILE
354           if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
355             {
356               assert (db->wr_fd != -1);
357               assert ((char *) &dataset->resp > (char *) db->data);
358               assert ((char *) dataset - (char *) db->head
359                       + total
360                       <= (sizeof (struct database_pers_head)
361                           + db->head->module * sizeof (ref_t)
362                           + db->head->data_size));
363               ssize_t written = sendfileall (fd, db->wr_fd,
364                                              (char *) &dataset->resp
365                                              - (char *) db->head,
366                                              dataset->head.recsize);
367               if (written != dataset->head.recsize)
368                 {
369 # ifndef __ASSUME_SENDFILE
370                   if (written == -1 && errno == ENOSYS)
371                     goto use_write;
372 # endif
373                   all_written = false;
374                 }
375             }
376           else
377 # ifndef __ASSUME_SENDFILE
378           use_write:
379 # endif
380 #endif
381             if (writeall (fd, &dataset->resp, dataset->head.recsize)
382                 != dataset->head.recsize)
383               all_written = false;
384         }
385
386       /* Add the record to the database.  But only if it has not been
387          stored on the stack.
388
389          If the record contains more than one IP address (used for
390          load balancing etc) don't cache the entry.  This is something
391          the current cache handling cannot handle and it is more than
392          questionable whether it is worthwhile complicating the cache
393          handling just for handling such a special case. */
394       if (! alloca_used)
395         {
396           /* If necessary, we also propagate the data to disk.  */
397           if (db->persistent)
398             {
399               // XXX async OK?
400               uintptr_t pval = (uintptr_t) dataset & ~pagesize_m1;
401               msync ((void *) pval,
402                      ((uintptr_t) dataset & pagesize_m1)
403                      + total + req->key_len, MS_ASYNC);
404             }
405
406           addr_list_type = (hst->h_length == NS_INADDRSZ
407                             ? GETHOSTBYADDR : GETHOSTBYADDRv6);
408
409           /* NB: the following code is really complicated.  It has
410              seemlingly duplicated code paths which do the same.  The
411              problem is that we always must add the hash table entry
412              with the FIRST flag set first.  Otherwise we get dangling
413              pointers in case memory allocation fails.  */
414           assert (hst->h_addr_list[1] == NULL);
415
416           /* Avoid adding names if more than one address is available.  See
417              above for more info.  */
418           assert (req->type == GETHOSTBYNAME
419                   || req->type == GETHOSTBYNAMEv6
420                   || req->type == GETHOSTBYADDR
421                   || req->type == GETHOSTBYADDRv6);
422
423           (void) cache_add (req->type, key_copy, req->key_len,
424                             &dataset->head, true, db, owner, he == NULL);
425
426           pthread_rwlock_unlock (&db->lock);
427         }
428     }
429
430   if (__builtin_expect (!all_written, 0) && debug_level > 0)
431     {
432       char buf[256];
433       dbg_log (_("short write in %s: %s"),  __FUNCTION__,
434                strerror_r (errno, buf, sizeof (buf)));
435     }
436 }
437
438
439 static int
440 lookup (int type, void *key, struct hostent *resultbufp, char *buffer,
441         size_t buflen, struct hostent **hst, int32_t *ttlp)
442 {
443   if (type == GETHOSTBYNAME)
444     return __gethostbyname3_r (key, AF_INET, resultbufp, buffer, buflen, hst,
445                                &h_errno, ttlp, NULL);
446   if (type == GETHOSTBYNAMEv6)
447     return __gethostbyname3_r (key, AF_INET6, resultbufp, buffer, buflen, hst,
448                                &h_errno, ttlp, NULL);
449   if (type == GETHOSTBYADDR)
450     return __gethostbyaddr2_r (key, NS_INADDRSZ, AF_INET, resultbufp, buffer,
451                                buflen, hst, &h_errno, ttlp);
452   return __gethostbyaddr2_r (key, NS_IN6ADDRSZ, AF_INET6, resultbufp, buffer,
453                              buflen, hst, &h_errno, ttlp);
454 }
455
456
457 static void
458 addhstbyX (struct database_dyn *db, int fd, request_header *req,
459            void *key, uid_t uid, struct hashentry *he, struct datahead *dh)
460 {
461   /* Search for the entry matching the key.  Please note that we don't
462      look again in the table whether the dataset is now available.  We
463      simply insert it.  It does not matter if it is in there twice.  The
464      pruning function only will look at the timestamp.  */
465   int buflen = 1024;
466   char *buffer = (char *) alloca (buflen);
467   struct hostent resultbuf;
468   struct hostent *hst;
469   bool use_malloc = false;
470   int errval = 0;
471   int32_t ttl = INT32_MAX;
472
473   if (__builtin_expect (debug_level > 0, 0))
474     {
475       const char *str;
476       char buf[INET6_ADDRSTRLEN + 1];
477       if (req->type == GETHOSTBYNAME || req->type == GETHOSTBYNAMEv6)
478         str = key;
479       else
480         str = inet_ntop (req->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
481                          key, buf, sizeof (buf));
482
483       if (he == NULL)
484         dbg_log (_("Haven't found \"%s\" in hosts cache!"), (char *) str);
485       else
486         dbg_log (_("Reloading \"%s\" in hosts cache!"), (char *) str);
487     }
488
489   while (lookup (req->type, key, &resultbuf, buffer, buflen, &hst, &ttl) != 0
490          && h_errno == NETDB_INTERNAL
491          && (errval = errno) == ERANGE)
492     {
493       errno = 0;
494
495       if (__builtin_expect (buflen > 32768, 0))
496         {
497           char *old_buffer = buffer;
498           buflen *= 2;
499           buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
500           if (buffer == NULL)
501             {
502               /* We ran out of memory.  We cannot do anything but
503                  sending a negative response.  In reality this should
504                  never happen.  */
505               hst = NULL;
506               buffer = old_buffer;
507
508               /* We set the error to indicate this is (possibly) a
509                  temporary error and that it does not mean the entry
510                  is not available at all.  */
511               h_errno = TRY_AGAIN;
512               errval = EAGAIN;
513               break;
514             }
515           use_malloc = true;
516         }
517       else
518         /* Allocate a new buffer on the stack.  If possible combine it
519            with the previously allocated buffer.  */
520         buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
521     }
522
523   cache_addhst (db, fd, req, key, hst, uid, he, dh,
524                 h_errno == TRY_AGAIN ? errval : 0, ttl);
525
526   if (use_malloc)
527     free (buffer);
528 }
529
530
531 void
532 addhstbyname (struct database_dyn *db, int fd, request_header *req,
533               void *key, uid_t uid)
534 {
535   addhstbyX (db, fd, req, key, uid, NULL, NULL);
536 }
537
538
539 void
540 readdhstbyname (struct database_dyn *db, struct hashentry *he,
541                 struct datahead *dh)
542 {
543   request_header req =
544     {
545       .type = GETHOSTBYNAME,
546       .key_len = he->len
547     };
548
549   addhstbyX (db, -1, &req, db->data + he->key, he->owner, he, dh);
550 }
551
552
553 void
554 addhstbyaddr (struct database_dyn *db, int fd, request_header *req,
555               void *key, uid_t uid)
556 {
557   addhstbyX (db, fd, req, key, uid, NULL, NULL);
558 }
559
560
561 void
562 readdhstbyaddr (struct database_dyn *db, struct hashentry *he,
563                 struct datahead *dh)
564 {
565   request_header req =
566     {
567       .type = GETHOSTBYADDR,
568       .key_len = he->len
569     };
570
571   addhstbyX (db, -1, &req, db->data + he->key, he->owner, he, dh);
572 }
573
574
575 void
576 addhstbynamev6 (struct database_dyn *db, int fd, request_header *req,
577                 void *key, uid_t uid)
578 {
579   addhstbyX (db, fd, req, key, uid, NULL, NULL);
580 }
581
582
583 void
584 readdhstbynamev6 (struct database_dyn *db, struct hashentry *he,
585                   struct datahead *dh)
586 {
587   request_header req =
588     {
589       .type = GETHOSTBYNAMEv6,
590       .key_len = he->len
591     };
592
593   addhstbyX (db, -1, &req, db->data + he->key, he->owner, he, dh);
594 }
595
596
597 void
598 addhstbyaddrv6 (struct database_dyn *db, int fd, request_header *req,
599                 void *key, uid_t uid)
600 {
601   addhstbyX (db, fd, req, key, uid, NULL, NULL);
602 }
603
604
605 void
606 readdhstbyaddrv6 (struct database_dyn *db, struct hashentry *he,
607                   struct datahead *dh)
608 {
609   request_header req =
610     {
611       .type = GETHOSTBYADDRv6,
612       .key_len = he->len
613     };
614
615   addhstbyX (db, -1, &req, db->data + he->key, he->owner, he, dh);
616 }