Remove Linux kernel version ambiguity in comment added by previous commit.
[platform/upstream/glibc.git] / nscd / nscd-client.h
1 /* Copyright (c) 1998-2013 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 /* This file defines everything that client code should need to
20    know to talk to the nscd daemon.  */
21
22 #ifndef _NSCD_CLIENT_H
23 #define _NSCD_CLIENT_H  1
24
25 #include <stdbool.h>
26 #include <stdint.h>
27 #include <sys/types.h>
28 #include <atomic.h>
29 #include <nscd-types.h>
30 #include <sys/uio.h>
31
32
33 /* Version number of the daemon interface */
34 #define NSCD_VERSION 2
35
36 /* Path of the file where the PID of the running system is stored.  */
37 #define _PATH_NSCDPID    "/var/run/nscd/nscd.pid"
38
39 /* Path for the Unix domain socket.  */
40 #define _PATH_NSCDSOCKET "/var/run/nscd/socket"
41
42 /* Path for the configuration file.  */
43 #define _PATH_NSCDCONF   "/etc/nscd.conf"
44
45 /* Maximum allowed length for the key.  */
46 #define MAXKEYLEN 1024
47
48
49 /* Available services.  */
50 typedef enum
51 {
52   GETPWBYNAME,
53   GETPWBYUID,
54   GETGRBYNAME,
55   GETGRBYGID,
56   GETHOSTBYNAME,
57   GETHOSTBYNAMEv6,
58   GETHOSTBYADDR,
59   GETHOSTBYADDRv6,
60   SHUTDOWN,             /* Shut the server down.  */
61   GETSTAT,              /* Get the server statistic.  */
62   INVALIDATE,           /* Invalidate one special cache.  */
63   GETFDPW,
64   GETFDGR,
65   GETFDHST,
66   GETAI,
67   INITGROUPS,
68   GETSERVBYNAME,
69   GETSERVBYPORT,
70   GETFDSERV,
71   GETNETGRENT,
72   INNETGR,
73   GETFDNETGR,
74   LASTREQ
75 } request_type;
76
77
78 /* Header common to all requests */
79 typedef struct
80 {
81   int32_t version;      /* Version number of the daemon interface.  */
82   request_type type;    /* Service requested.  */
83   int32_t key_len;      /* Key length.  */
84 } request_header;
85
86
87 /* Structure sent in reply to password query.  Note that this struct is
88    sent also if the service is disabled or there is no record found.  */
89 typedef struct
90 {
91   int32_t version;
92   int32_t found;
93   nscd_ssize_t pw_name_len;
94   nscd_ssize_t pw_passwd_len;
95   uid_t pw_uid;
96   gid_t pw_gid;
97   nscd_ssize_t pw_gecos_len;
98   nscd_ssize_t pw_dir_len;
99   nscd_ssize_t pw_shell_len;
100 } pw_response_header;
101
102
103 /* Structure sent in reply to group query.  Note that this struct is
104    sent also if the service is disabled or there is no record found.  */
105 typedef struct
106 {
107   int32_t version;
108   int32_t found;
109   nscd_ssize_t gr_name_len;
110   nscd_ssize_t gr_passwd_len;
111   gid_t gr_gid;
112   nscd_ssize_t gr_mem_cnt;
113 } gr_response_header;
114
115
116 /* Structure sent in reply to host query.  Note that this struct is
117    sent also if the service is disabled or there is no record found.  */
118 typedef struct
119 {
120   int32_t version;
121   int32_t found;
122   nscd_ssize_t h_name_len;
123   nscd_ssize_t h_aliases_cnt;
124   int32_t h_addrtype;
125   int32_t h_length;
126   nscd_ssize_t h_addr_list_cnt;
127   int32_t error;
128 } hst_response_header;
129
130
131 /* Structure sent in reply to addrinfo query.  Note that this struct is
132    sent also if the service is disabled or there is no record found.  */
133 typedef struct
134 {
135   int32_t version;
136   int32_t found;
137   nscd_ssize_t naddrs;
138   nscd_ssize_t addrslen;
139   nscd_ssize_t canonlen;
140   int32_t error;
141 } ai_response_header;
142
143 /* Structure filled in by __nscd_getai.  */
144 struct nscd_ai_result
145 {
146   int naddrs;
147   char *canon;
148   uint8_t *family;
149   char *addrs;
150 };
151
152 /* Structure sent in reply to initgroups query.  Note that this struct is
153    sent also if the service is disabled or there is no record found.  */
154 typedef struct
155 {
156   int32_t version;
157   int32_t found;
158   nscd_ssize_t ngrps;
159 } initgr_response_header;
160
161
162 /* Structure sent in reply to services query.  Note that this struct is
163    sent also if the service is disabled or there is no record found.  */
164 typedef struct
165 {
166   int32_t version;
167   int32_t found;
168   nscd_ssize_t s_name_len;
169   nscd_ssize_t s_proto_len;
170   nscd_ssize_t s_aliases_cnt;
171   int32_t s_port;
172 } serv_response_header;
173
174
175 /* Structure send in reply to netgroup query.  Note that this struct is
176    sent also if the service is disabled or there is no record found.  */
177 typedef struct
178 {
179   int32_t version;
180   int32_t found;
181   nscd_ssize_t nresults;
182   nscd_ssize_t result_len;
183 } netgroup_response_header;
184
185 typedef struct
186 {
187   int32_t version;
188   int32_t found;
189   int32_t result;
190 } innetgroup_response_header;
191
192
193 /* Type for offsets in data part of database.  */
194 typedef uint32_t ref_t;
195 /* Value for invalid/no reference.  */
196 #define ENDREF  UINT32_MAX
197
198 /* Timestamp type.  */
199 typedef uint64_t nscd_time_t;
200
201 /* Maximum timestamp.  */
202 #define MAX_TIMEOUT_VALUE \
203   (sizeof (time_t) == sizeof (long int) ? LONG_MAX : INT_MAX)
204
205 /* Alignment requirement of the beginning of the data region.  */
206 #define ALIGN 16
207
208
209 /* Head of record in data part of database.  */
210 struct datahead
211 {
212   nscd_ssize_t allocsize;       /* Allocated Bytes.  */
213   nscd_ssize_t recsize;         /* Size of the record.  */
214   nscd_time_t timeout;          /* Time when this entry becomes invalid.  */
215   uint8_t notfound;             /* Nonzero if data has not been found.  */
216   uint8_t nreloads;             /* Reloads without use.  */
217   uint8_t usable;               /* False if the entry must be ignored.  */
218   uint8_t unused;               /* Unused.  */
219   uint32_t ttl;                 /* TTL value used.  */
220
221   /* We need to have the following element aligned for the response
222      header data types and their use in the 'struct dataset' types
223      defined in the XXXcache.c files.  */
224   union
225   {
226     pw_response_header pwdata;
227     gr_response_header grdata;
228     hst_response_header hstdata;
229     ai_response_header aidata;
230     initgr_response_header initgrdata;
231     serv_response_header servdata;
232     netgroup_response_header netgroupdata;
233     innetgroup_response_header innetgroupdata;
234     nscd_ssize_t align1;
235     nscd_time_t align2;
236   } data[0];
237 };
238
239
240 /* Structure for one hash table entry.  */
241 struct hashentry
242 {
243   request_type type:8;          /* Which type of dataset.  */
244   bool first;                   /* True if this was the original key.  */
245   nscd_ssize_t len;             /* Length of key.  */
246   ref_t key;                    /* Pointer to key.  */
247   int32_t owner;                /* If secure table, this is the owner.  */
248   ref_t next;                   /* Next entry in this hash bucket list.  */
249   ref_t packet;                 /* Records for the result.  */
250   union
251   {
252     struct hashentry *dellist;  /* Next record to be deleted.  This can be a
253                                    pointer since only nscd uses this field.  */
254     ref_t *prevp;               /* Pointer to field containing forward
255                                    reference.  */
256   };
257 };
258
259
260 /* Current persistent database version.  */
261 #define DB_VERSION      2
262
263 /* Maximum time allowed between updates of the timestamp.  */
264 #define MAPPING_TIMEOUT (5 * 60)
265
266
267 /* Used indices for the EXTRA_DATA element of 'database_pers_head'.
268    Each database has its own indices.  */
269 #define NSCD_HST_IDX_CONF_TIMESTAMP     0
270
271
272 /* Header of persistent database file.  */
273 struct database_pers_head
274 {
275   int32_t version;
276   int32_t header_size;
277   volatile int32_t gc_cycle;
278   volatile int32_t nscd_certainly_running;
279   volatile nscd_time_t timestamp;
280   /* Room for extensions.  */
281   volatile uint32_t extra_data[4];
282
283   nscd_ssize_t module;
284   nscd_ssize_t data_size;
285
286   nscd_ssize_t first_free;      /* Offset of first free byte in data area.  */
287
288   nscd_ssize_t nentries;
289   nscd_ssize_t maxnentries;
290   nscd_ssize_t maxnsearched;
291
292   uint64_t poshit;
293   uint64_t neghit;
294   uint64_t posmiss;
295   uint64_t negmiss;
296
297   uint64_t rdlockdelayed;
298   uint64_t wrlockdelayed;
299
300   uint64_t addfailed;
301
302   ref_t array[0];
303 };
304
305
306 /* Mapped database record.  */
307 struct mapped_database
308 {
309   const struct database_pers_head *head;
310   const char *data;
311   size_t mapsize;
312   int counter;          /* > 0 indicates it is usable.  */
313   size_t datasize;
314 };
315 #define NO_MAPPING ((struct mapped_database *) -1l)
316
317 struct locked_map_ptr
318 {
319   int lock;
320   struct mapped_database *mapped;
321 };
322 #define libc_locked_map_ptr(class, name) class struct locked_map_ptr name
323
324 /* Try acquiring lock for mapptr, returns true if it succeeds, false
325    if not.  */
326 static inline bool
327 __nscd_acquire_maplock (volatile struct locked_map_ptr *mapptr)
328 {
329   int cnt = 0;
330   while (__builtin_expect (atomic_compare_and_exchange_val_acq (&mapptr->lock,
331                                                                 1, 0) != 0, 0))
332     {
333       // XXX Best number of rounds?
334       if (__builtin_expect (++cnt > 5, 0))
335         return false;
336
337       atomic_delay ();
338     }
339
340   return true;
341 }
342
343
344 /* Open socket connection to nscd server.  */
345 extern int __nscd_open_socket (const char *key, size_t keylen,
346                                request_type type, void *response,
347                                size_t responselen) attribute_hidden;
348
349 /* Try to get a file descriptor for the shared meory segment
350    containing the database.  */
351 extern struct mapped_database *__nscd_get_mapping (request_type type,
352                                                    const char *key,
353                                                    struct mapped_database **mappedp) attribute_hidden;
354
355 /* Get reference of mapping.  */
356 extern struct mapped_database *__nscd_get_map_ref (request_type type,
357                                                    const char *name,
358                                                    volatile struct locked_map_ptr *mapptr,
359                                                    int *gc_cyclep);
360
361 /* Unmap database.  */
362 extern void __nscd_unmap (struct mapped_database *mapped);
363
364 /* Drop reference of mapping.  */
365 static int
366 __attribute__ ((unused))
367 __nscd_drop_map_ref (struct mapped_database *map, int *gc_cycle)
368 {
369   if (map != NO_MAPPING)
370     {
371       int now_cycle = map->head->gc_cycle;
372       if (__builtin_expect (now_cycle != *gc_cycle, 0))
373         {
374           /* We might have read inconsistent data.  */
375           *gc_cycle = now_cycle;
376           return -1;
377         }
378
379       if (atomic_decrement_val (&map->counter) == 0)
380         __nscd_unmap (map);
381     }
382
383   return 0;
384 }
385
386
387 /* Search the mapped database.  */
388 extern struct datahead *__nscd_cache_search (request_type type,
389                                              const char *key,
390                                              size_t keylen,
391                                              const struct mapped_database *mapped,
392                                              size_t datalen);
393
394 /* Wrappers around read, readv and write that only read/write less than LEN
395    bytes on error or EOF.  */
396 extern ssize_t __readall (int fd, void *buf, size_t len)
397   attribute_hidden;
398 extern ssize_t __readvall (int fd, const struct iovec *iov, int iovcnt)
399   attribute_hidden;
400 extern ssize_t writeall (int fd, const void *buf, size_t len)
401   attribute_hidden;
402 extern ssize_t sendfileall (int tofd, int fromfd, off_t off, size_t len)
403   attribute_hidden;
404
405 /* Get netlink timestamp counter from mapped area or zero.  */
406 extern uint32_t __nscd_get_nl_timestamp (void);
407
408 #endif /* nscd.h */