int TIMEOUT = DEFAULT_TIMEOUT;
-edg_wll_GssCred cred_handle = NULL;
+cred_handle_t *cred_handle = NULL;
pthread_mutex_t cred_handle_lock = PTHREAD_MUTEX_INITIALIZER;
+pthread_key_t cred_handle_key;
time_t key_mtime = 0, cert_mtime = 0;
killflg++;
}
+
+/* this is called when thread exists */
+void cred_handle_destroy(void *handle) {
+ cred_handle_t *h = (cred_handle_t*)handle;
+ if(!h)
+ return;
+ il_log(LOG_DEBUG, "Thread exiting, releasing credentials.\n");
+ if(pthread_mutex_lock(&cred_handle_lock) < 0)
+ abort();
+ if(--(h->counter) == 0) {
+ edg_wll_gss_release_cred(&h->creds, NULL);
+ free(h);
+ il_log(LOG_DEBUG, "Freed credentials, not used anymore.\n");
+ }
+ if(pthread_mutex_unlock(&cred_handle_lock) < 0)
+ abort();
+}
+
+
int
main (int argc, char **argv)
{
il_log(LOG_DEBUG, " using lazy mode when closing connections, timeout %d\n",
default_close_timeout);
+ /* initialize credential key and get credentials */
+ /* IMPORTANT: no other threads may run at the time, the key initialization
+ has to be done exactly once */
+ if(pthread_key_create(&cred_handle_key, cred_handle_destroy) < 0)
+ abort();
if (CAcert_dir)
setenv("X509_CERT_DIR", CAcert_dir, 1);
-
edg_wll_gss_watch_creds(cert_file,&cert_mtime);
- ret = edg_wll_gss_acquire_cred_gsi(cert_file, key_file, &cred_handle, &gss_stat);
+ cred_handle = malloc(sizeof(*cred_handle));
+ if(cred_handle == NULL) {
+ il_log(LOG_CRIT, "Failed to allocate structure for credentials.\n");
+ exit(EXIT_FAILURE);
+ }
+ cred_handle->creds = NULL;
+ cred_handle->counter = 0;
+ ret = edg_wll_gss_acquire_cred_gsi(cert_file, key_file, &cred_handle->creds, &gss_stat);
if (ret) {
char *gss_err = NULL;
char *str;
extern int TIMEOUT;
#define INPUT_TIMEOUT (60)
-
-extern edg_wll_GssCred cred_handle;
+typedef struct cred_handle {
+ edg_wll_GssCred creds;
+ int counter;
+} cred_handle_t;
+extern cred_handle_t *cred_handle;
extern pthread_mutex_t cred_handle_lock;
+extern pthread_key_t cred_handle_key;
extern char *cert_file;
extern char *key_file;
extern char *CAcert_dir;
};
+/* credential destructor */
+void cred_handle_destroy(void *);
+
/* server msg methods */
struct server_msg *server_msg_create(il_octet_string_t *, long);
struct server_msg *server_msg_copy(struct server_msg *);
exit(1);
}
il_log(LOG_INFO, "Reloading certificate...\n");
- if(pthread_mutex_lock(&cred_handle_lock) < 0)
- abort();
if (edg_wll_gss_watch_creds(cert_file, &cert_mtime) > 0) {
- edg_wll_GssCred new_cred_handle = NULL;
+ edg_wll_GssCred new_creds = NULL;
int ret;
ret = edg_wll_gss_acquire_cred_gsi(cert_file,key_file,
- &new_cred_handle, NULL);
- if (new_cred_handle != NULL) {
- edg_wll_gss_release_cred(&cred_handle, NULL);
- cred_handle = new_cred_handle;
+ &new_creds, NULL);
+ if (new_creds != NULL) {
+ if(pthread_mutex_lock(&cred_handle_lock) < 0)
+ abort();
+ cred_handle = malloc(sizeof(*cred_handle));
+ if(cred_handle == NULL) {
+ il_log(LOG_CRIT, "Failed to allocate structure for credentials.\n");
+ exit(EXIT_FAILURE);
+ }
+ cred_handle->creds = new_creds;
+ cred_handle->counter = 0;
+ if(pthread_mutex_unlock(&cred_handle_lock) < 0)
+ abort();
il_log(LOG_INFO, "New certificate found and deployed.\n");
}
}
- if(pthread_mutex_unlock(&cred_handle_lock) < 0)
- abort();
sleep(INPUT_TIMEOUT);
}
}
int ret;
struct timeval tv;
edg_wll_GssStatus gss_stat;
+ cred_handle_t *local_cred_handle;
assert(eq != NULL);
tv.tv_sec = TIMEOUT;
tv.tv_usec = 0;
+ /* get thread specific pointer to credentials */
+ local_cred_handle = pthread_getspecific(cred_handle_key);
+ /* check if there are new credentials */
if(pthread_mutex_lock(&cred_handle_lock) < 0)
abort();
- il_log(LOG_DEBUG, " trying to connect to %s:%d\n", eq->dest_name, eq->dest_port);
- ret = edg_wll_gss_connect(cred_handle, eq->dest_name, eq->dest_port, &tv, &eq->gss, &gss_stat);
- if(pthread_mutex_unlock(&cred_handle_lock) < 0)
+ if(local_cred_handle != cred_handle) {
+ il_log(LOG_DEBUG, " new credentials were found, discarding old\n");
+ /* decrement counter in credentials, if it goes to zero, deallocate */
+ if(--(local_cred_handle->counter) == 0) {
+ edg_wll_gss_release_cred(&local_cred_handle->creds, &gss_stat);
+ free(local_cred_handle);
+ il_log(LOG_DEBUG, " freed old credentials, not used anymore\n");
+ }
+ /* use the new credentials, increment usage count */
+ local_cred_handle = cred_handle;
+ local_cred_handle->counter++;
+ pthread_setspecific(cred_handle_key, local_cred_handle);
+ }
+ if(pthread_mutex_unlock(&cred_handle_lock) < 0)
abort();
+ il_log(LOG_DEBUG, " trying to connect to %s:%d\n", eq->dest_name, eq->dest_port);
+ ret = edg_wll_gss_connect(local_cred_handle->creds, eq->dest_name, eq->dest_port, &tv, &eq->gss, &gss_stat);
if(ret < 0) {
char *gss_err = NULL;