libsmb/conncache.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003 
00004    Winbind daemon connection manager
00005 
00006    Copyright (C) Tim Potter             2001
00007    Copyright (C) Andrew Bartlett        2002
00008    Copyright (C) Gerald (Jerry) Carter  2003
00009    
00010    This program is free software; you can redistribute it and/or modify
00011    it under the terms of the GNU General Public License as published by
00012    the Free Software Foundation; either version 2 of the License, or
00013    (at your option) any later version.
00014    
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019    
00020    You should have received a copy of the GNU General Public License
00021    along with this program; if not, write to the Free Software
00022    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00023 */
00024 
00025 
00026 #include "includes.h"
00027 
00028 #define CONNCACHE_ADDR          1
00029 #define CONNCACHE_NAME          2
00030 
00031 /* cache entry contains either a server name **or** and IP address as 
00032    the key.  This means that a server could have two entries (one for each key) */
00033    
00034 struct failed_connection_cache {
00035         fstring         domain_name;
00036         fstring         controller;
00037         time_t          lookup_time;
00038         NTSTATUS        nt_status;
00039         struct failed_connection_cache *prev, *next;
00040 };
00041 
00042 static struct failed_connection_cache *failed_connection_cache;
00043 
00044 /**********************************************************************
00045  Check for a previously failed connection.
00046  failed_cache_timeout is an a absolute number of seconds after which
00047  we should time this out. If failed_cache_timeout == 0 then time out
00048  immediately. If failed_cache_timeout == -1 then never time out.
00049 **********************************************************************/
00050 
00051 NTSTATUS check_negative_conn_cache_timeout( const char *domain, const char *server, unsigned int failed_cache_timeout )
00052 {
00053         struct failed_connection_cache *fcc;
00054         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00055         
00056         /* can't check if we don't have strings */
00057         
00058         if ( !domain || !server )
00059                 return NT_STATUS_OK;
00060 
00061         for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
00062         
00063                 if (!(strequal(domain, fcc->domain_name) && strequal(server, fcc->controller))) {
00064                         continue; /* no match; check the next entry */
00065                 }
00066                 
00067                 /* we have a match so see if it is still current */
00068                 if (failed_cache_timeout != (unsigned int)-1) {
00069                         if (failed_cache_timeout == 0 ||
00070                                         (time(NULL) - fcc->lookup_time) > (time_t)failed_cache_timeout) {
00071                                 /* Cache entry has expired, delete it */
00072 
00073                                 DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n", 
00074                                         domain, server ));
00075 
00076                                 DLIST_REMOVE(failed_connection_cache, fcc);
00077                                 SAFE_FREE(fcc);
00078 
00079                                 return NT_STATUS_OK;
00080                         }
00081                 }
00082 
00083                 /* The timeout hasn't expired yet so return false */
00084 
00085                 DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n", 
00086                         domain, server ));
00087 
00088                 result = fcc->nt_status;
00089                 return result;
00090         }
00091 
00092         /* end of function means no cache entry */      
00093         return NT_STATUS_OK;
00094 }
00095 
00096 NTSTATUS check_negative_conn_cache( const char *domain, const char *server)
00097 {
00098         return check_negative_conn_cache_timeout(domain, server, FAILED_CONNECTION_CACHE_TIMEOUT);
00099 }
00100 
00101 /**********************************************************************
00102  Add an entry to the failed conneciton cache (aither a name of dotted 
00103  decimal IP
00104 **********************************************************************/
00105 
00106 void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result) 
00107 {
00108         struct failed_connection_cache *fcc;
00109 
00110         SMB_ASSERT(!NT_STATUS_IS_OK(result));
00111 
00112         /* Check we already aren't in the cache.  We always have to have 
00113            a domain, but maybe not a specific DC name. */
00114 
00115         for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {                     
00116                 if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) {
00117                         DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n",
00118                                    domain, server ));
00119                         /* Update the failed time. */
00120                         fcc->lookup_time = time(NULL);
00121                         return;
00122                 }
00123         }
00124 
00125         /* Create negative lookup cache entry for this domain and controller */
00126 
00127         if ( !(fcc = SMB_MALLOC_P(struct failed_connection_cache)) ) {
00128                 DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
00129                 return;
00130         }
00131         
00132         ZERO_STRUCTP(fcc);
00133         
00134         fstrcpy( fcc->domain_name, domain );
00135         fstrcpy( fcc->controller, server );
00136         fcc->lookup_time = time(NULL);
00137         fcc->nt_status = result;
00138         
00139         DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n",
00140                 domain, server ));
00141         
00142         DLIST_ADD(failed_connection_cache, fcc);
00143 }
00144 
00145 /****************************************************************************
00146 ****************************************************************************/
00147  
00148 void flush_negative_conn_cache( void )
00149 {
00150         struct failed_connection_cache *fcc;
00151         
00152         fcc = failed_connection_cache;
00153 
00154         while (fcc) {
00155                 struct failed_connection_cache *fcc_next;
00156 
00157                 fcc_next = fcc->next;
00158                 DLIST_REMOVE(failed_connection_cache, fcc);
00159                 free(fcc);
00160 
00161                 fcc = fcc_next;
00162         }
00163 
00164 }
00165 
00166 /****************************************************************************
00167  Remove all negative entries for a domain. Used when going to online state in
00168  winbindd.
00169 ****************************************************************************/
00170  
00171 void flush_negative_conn_cache_for_domain(const char *domain)
00172 {
00173         struct failed_connection_cache *fcc;
00174         
00175         fcc = failed_connection_cache;
00176 
00177         while (fcc) {
00178                 struct failed_connection_cache *fcc_next;
00179 
00180                 fcc_next = fcc->next;
00181 
00182                 if (strequal(fcc->domain_name, domain)) {
00183                         DEBUG(10,("flush_negative_conn_cache_for_domain: removed server %s "
00184                                 " from failed cache for domain %s\n",
00185                                 fcc->controller, domain));
00186                         DLIST_REMOVE(failed_connection_cache, fcc);
00187                         free(fcc);
00188                 }
00189 
00190                 fcc = fcc_next;
00191         }
00192 }

Sambaに対してSat Aug 29 21:23:05 2009に生成されました。  doxygen 1.4.7