2 Unix SMB/CIFS implementation.
4 NetBIOS name cache module.
6 Copyright (C) Tim Potter, 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 static BOOL done_namecache_init
;
26 static BOOL enable_namecache
;
27 static TDB_CONTEXT
*namecache_tdb
;
30 time_t expiry
; /* When entry expires */
31 int count
; /* Number of addresses */
32 struct in_addr ip_list
[1]; /* Address list */
35 /* Initialise namecache system */
37 BOOL
namecache_enable(void)
39 /* Check if we have been here before, or name caching disabled
40 by setting the name cache timeout to zero. */
42 if (done_namecache_init
)
45 done_namecache_init
= True
;
47 if (lp_name_cache_timeout() == 0) {
48 DEBUG(5, ("namecache_init: disabling netbios name cache\n"));
52 /* Open namecache tdb in read/write or readonly mode */
54 namecache_tdb
= tdb_open_log(
55 lock_path("namecache.tdb"), 0,
56 TDB_DEFAULT
, O_RDWR
| O_CREAT
, 0644);
59 DEBUG(5, ("namecache_init: could not open %s\n",
60 lock_path("namecache.tdb")));
64 DEBUG(5, ("namecache_init: enabling netbios namecache, timeout %d "
65 "seconds\n", lp_name_cache_timeout()));
67 enable_namecache
= True
;
72 /* Return a key for a name and name type. The caller must free
73 retval.dptr when finished. */
75 static TDB_DATA
namecache_key(const char *name
, int name_type
)
80 asprintf(&keystr
, "%s#%02X", strupper_static(name
), name_type
);
82 retval
.dsize
= strlen(keystr
) + 1;
88 /* Return a data value for an IP list. The caller must free
89 retval.dptr when finished. */
91 static TDB_DATA
namecache_value(struct in_addr
*ip_list
, int num_names
,
95 struct nc_value
*value
;
96 int size
= sizeof(struct nc_value
);
99 size
+= sizeof(struct in_addr
) * (num_names
-1);
101 value
= (struct nc_value
*)malloc(size
);
103 memset(value
, 0, size
);
105 value
->expiry
= expiry
;
106 value
->count
= num_names
;
109 memcpy(value
->ip_list
, ip_list
, sizeof(struct in_addr
) * num_names
);
111 retval
.dptr
= (char *)value
;
117 /* Store a name in the name cache */
119 void namecache_store(const char *name
, int name_type
,
120 int num_names
, struct in_addr
*ip_list
)
126 if (!enable_namecache
)
129 DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ",
130 num_names
, num_names
== 1 ? "": "es", name
, name_type
));
132 for (i
= 0; i
< num_names
; i
++)
133 DEBUGADD(5, ("%s%s", inet_ntoa(ip_list
[i
]),
134 i
== (num_names
- 1) ? "" : ", "));
138 key
= namecache_key(name
, name_type
);
140 /* Cache pdc location or dc lists for only a little while
141 otherwise if we lock on to a bad DC we can potentially be
142 out of action for the entire cache timeout time! */
144 if (name_type
!= 0x1b || name_type
!= 0x1c)
145 expiry
= time(NULL
) + 10;
147 expiry
= time(NULL
) + lp_name_cache_timeout();
149 value
= namecache_value(ip_list
, num_names
, expiry
);
151 tdb_store(namecache_tdb
, key
, value
, TDB_REPLACE
);
157 /* Look up a name in the name cache. Return a mallocated list of IP
158 addresses if the name is contained in the cache. */
160 BOOL
namecache_fetch(const char *name
, int name_type
, struct in_addr
**ip_list
,
164 struct nc_value
*data
;
171 if (!enable_namecache
)
176 key
= namecache_key(name
, name_type
);
178 value
= tdb_fetch(namecache_tdb
, key
);
181 DEBUG(5, ("namecache_fetch: %s#%02x not found\n",
186 data
= (struct nc_value
*)value
.dptr
;
188 /* Check expiry time */
192 if (now
> data
->expiry
) {
194 DEBUG(5, ("namecache_fetch: entry for %s#%02x expired\n",
197 tdb_delete(namecache_tdb
, key
);
204 if ((data
->expiry
- now
) > lp_name_cache_timeout()) {
206 /* Someone may have changed the system time on us */
208 DEBUG(5, ("namecache_fetch: entry for %s#%02x has bad expiry\n",
211 tdb_delete(namecache_tdb
, key
);
218 /* Extract and return namelist */
220 DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ",
221 data
->count
, data
->count
== 1 ? "" : "es", name
, name_type
));
225 *ip_list
= (struct in_addr
*)malloc(
226 sizeof(struct in_addr
) * data
->count
);
228 memcpy(*ip_list
, data
->ip_list
, sizeof(struct in_addr
) * data
->count
);
230 *num_names
= data
->count
;
232 for (i
= 0; i
< *num_names
; i
++)
233 DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list
)[i
]),
234 i
== (*num_names
- 1) ? "" : ", "));
242 SAFE_FREE(value
.dptr
);
244 return value
.dsize
> 0;
247 /* Flush all names from the name cache */
249 void namecache_flush(void)
256 result
= tdb_traverse(namecache_tdb
, tdb_traverse_delete_fn
, NULL
);
259 DEBUG(5, ("namecache_flush: error deleting cache entries\n"));
261 DEBUG(5, ("namecache_flush: deleted %d cache entr%s\n",
262 result
, result
== 1 ? "y" : "ies"));