From 5deee0f7c312572aa60d32e1bcaa3127d4d3b6d0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Posp=C3=AD=C5=A1il?= Date: Sun, 11 Feb 2007 15:20:54 +0000 Subject: [PATCH] - added again the missing select (for reused connections) - added accept and connection timeouts - better error handling if a system error occurs - small cleanup --- org.glite.lb.logger/src/logd.c | 303 ++++++++++++++++++++++++----------------- 1 file changed, 179 insertions(+), 124 deletions(-) diff --git a/org.glite.lb.logger/src/logd.c b/org.glite.lb.logger/src/logd.c index 775f789..3e4dee1 100644 --- a/org.glite.lb.logger/src/logd.c +++ b/org.glite.lb.logger/src/logd.c @@ -148,63 +148,120 @@ static int doit(int socket, gss_cred_id_t cred_handle, char *file_name_prefix, int noipc, int noparse) { char *subject; - int ret; - struct timeval timeout = {10,0}; + int ret,fd,count; + struct timeval timeout; edg_wll_GssConnection con; edg_wll_GssStatus gss_stat; gss_buffer_desc gss_token = GSS_C_EMPTY_BUFFER; gss_name_t client_name = GSS_C_NO_NAME; OM_uint32 min_stat; gss_OID name_type = GSS_C_NO_OID; - - /* authentication */ - edg_wll_ll_log(LOG_INFO,"Processing authentication:\n"); -// FIXME - put here some meaningfull value of timeout + do somthing if timeouted - ret = edg_wll_gss_accept(cred_handle,socket,&timeout,&con, &gss_stat); - if (ret) { - edg_wll_ll_log(LOG_ERR,"edg_wll_gss_accept() failed\n"); - return(-1); + fd_set fdset; + + ret = count = 0; + FD_ZERO(&fdset); + + /* accept */ + timeout.tv_sec = ACCEPT_TIMEOUT; + timeout.tv_usec = 0; + edg_wll_ll_log(LOG_DEBUG,"Accepting connection (remaining timeout %d.%06d sec)\n", + (int)timeout.tv_sec, (int) timeout.tv_usec); + if ((ret = edg_wll_gss_accept(cred_handle,socket,&timeout,&con, &gss_stat)) < 0) { + edg_wll_ll_log(LOG_DEBUG,"timeout after gss_accept is %d.%06d sec\n", + (int)timeout.tv_sec, (int) timeout.tv_usec); + return edg_wll_log_proto_server_failure(ret,&gss_stat,"edg_wll_gss_accept() failed\n"); } + /* authenticate */ + edg_wll_ll_log(LOG_INFO,"Processing authentication:\n"); gss_stat.major_status = gss_inquire_context(&gss_stat.minor_status, con.context, &client_name, NULL, NULL, NULL, NULL, NULL, NULL); if (GSS_ERROR(gss_stat.major_status)) { - char *gss_err; - edg_wll_gss_get_error(&gss_stat, "Cannot read client identification", &gss_err); - edg_wll_ll_log(LOG_WARNING, "%s\n", gss_err); - free(gss_err); + char *gss_err; + edg_wll_gss_get_error(&gss_stat, "Cannot read client identification", &gss_err); + edg_wll_ll_log(LOG_WARNING, "%s\n", gss_err); + free(gss_err); } else { - gss_stat.major_status = gss_display_name(&gss_stat.minor_status, client_name, - &gss_token, &name_type); - if (GSS_ERROR(gss_stat.major_status)) { - char *gss_err; - edg_wll_gss_get_error(&gss_stat, "Cannot process client identification", &gss_err); - edg_wll_ll_log(LOG_WARNING, "%s\n", gss_err); - free(gss_err); + gss_stat.major_status = gss_display_name(&gss_stat.minor_status, client_name, + &gss_token, &name_type); + if (GSS_ERROR(gss_stat.major_status)) { + char *gss_err; + edg_wll_gss_get_error(&gss_stat, "Cannot process client identification", &gss_err); + edg_wll_ll_log(LOG_WARNING, "%s\n", gss_err); + free(gss_err); } } - if (GSS_ERROR(gss_stat.major_status) || - edg_wll_gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS)) { - edg_wll_ll_log(LOG_INFO," User not authenticated, setting as \"%s\". \n",EDG_WLL_LOG_USER_DEFAULT); - subject=strdup(EDG_WLL_LOG_USER_DEFAULT); + if (GSS_ERROR(gss_stat.major_status) || edg_wll_gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS)) { + edg_wll_ll_log(LOG_INFO," User not authenticated, setting as \"%s\". \n",EDG_WLL_LOG_USER_DEFAULT); + subject=strdup(EDG_WLL_LOG_USER_DEFAULT); } else { - edg_wll_ll_log(LOG_INFO," User successfully authenticated as:\n"); - edg_wll_ll_log(LOG_INFO, " %s\n", (char *)gss_token.value); - subject=gss_token.value; - memset(&gss_token.value, 0, sizeof(gss_token.value)); + edg_wll_ll_log(LOG_INFO," User successfully authenticated as:\n"); + edg_wll_ll_log(LOG_INFO, " %s\n", (char *)gss_token.value); + subject=gss_token.value; + memset(&gss_token.value, 0, sizeof(gss_token.value)); } - ret = edg_wll_log_proto_server(&con,subject,file_name_prefix,noipc,noparse); + /* get and process the data */ + timeout.tv_sec = CONNECTION_TIMEOUT; + timeout.tv_usec = 0; + + while (timeout.tv_sec > 0) { + count++; + edg_wll_ll_log(LOG_DEBUG,"Waiting for data delivery no. %d (remaining timeout %d.%06d sec)\n", + count, (int)timeout.tv_sec, (int) timeout.tv_usec); + FD_SET(con.sock,&fdset); + fd = select(con.sock+1,&fdset,NULL,NULL,&timeout); + switch (fd) { + case 0: /* timeout */ + edg_wll_ll_log(LOG_DEBUG,"Connection timeout expired\n"); + timeout.tv_sec = 0; + break; + case -1: /* error */ + switch(errno) { + case EINTR: + edg_wll_ll_log(LOG_DEBUG,"XXX: Waking up (remaining timeout %d.%06d sec)\n", + (int)timeout.tv_sec, (int) timeout.tv_usec); + continue; + default: + SYSTEM_ERROR("select"); + timeout.tv_sec = 0; + break; + } + break; + default: + edg_wll_ll_log(LOG_DEBUG,"Waking up (remaining timeout %d.%06d sec)\n", + (int)timeout.tv_sec, (int) timeout.tv_usec); + break; + } + if (FD_ISSET(con.sock,&fdset)) { + if ((ret = edg_wll_log_proto_server(&con,&timeout,subject,file_name_prefix,noipc,noparse)) != 0) { + edg_wll_ll_log(LOG_DEBUG,"timeout after edg_wll_log_proto_server is %d.%06d sec\n", + (int)timeout.tv_sec, (int) timeout.tv_usec); + edg_wll_ll_log(LOG_ERR,"edg_wll_log_proto_server() error\n"); + timeout.tv_sec = 0; + timeout.tv_usec = 0; + break; + } else { + timeout.tv_sec = CONNECTION_TIMEOUT; + timeout.tv_usec = 0; + } + } - edg_wll_gss_close(&con, NULL); - if (subject) free(subject); - if (gss_token.length) - gss_release_buffer(&min_stat, &gss_token); - if (client_name != GSS_C_NO_NAME) - gss_release_name(&min_stat, &client_name); - return ret; + } + +doit_end: + edg_wll_ll_log(LOG_DEBUG, "Closing descriptor '%d'...",con.sock); + edg_wll_gss_close(&con, NULL); + if (con.sock == -1) + edg_wll_ll_log(LOG_DEBUG, "o.k.\n"); + if (subject) free(subject); + if (gss_token.length) + gss_release_buffer(&min_stat, &gss_token); + if (client_name != GSS_C_NO_NAME) + gss_release_name(&min_stat, &client_name); + return ret; } /* @@ -283,44 +340,41 @@ This is LocalLogger, part of Workload Management System in EU DataGrid & EGEE.\n edg_wll_ll_log(LOG_INFO,"Initializing...\n"); /* check noParse */ - edg_wll_ll_log(LOG_INFO,"Parse messages for correctness..."); if (noParse) { - edg_wll_ll_log(LOG_INFO,"no.\n"); + edg_wll_ll_log(LOG_INFO,"Parse messages for correctness... [no]\n"); } else { - edg_wll_ll_log(LOG_INFO,"yes.\n"); + edg_wll_ll_log(LOG_INFO,"Parse messages for correctness... [yes]\n"); } /* check noIPC */ - edg_wll_ll_log(LOG_INFO,"Send messages also to inter-logger..."); if (noIPC) { - edg_wll_ll_log(LOG_INFO,"no.\n"); + edg_wll_ll_log(LOG_INFO,"Send messages also to inter-logger... [no]\n"); } else { - edg_wll_ll_log(LOG_INFO,"yes.\n"); + edg_wll_ll_log(LOG_INFO,"Send messages also to inter-logger... [yes]\n"); } /* check prefix correctness */ -/* XXX: check probably also write permisions */ - edg_wll_ll_log(LOG_INFO,"Store messages with the filename prefix \"%s\"...",prefix); if (strlen(prefix) > FILENAME_MAX - 34) { - edg_wll_ll_log(LOG_INFO,"no.\n"); - edg_wll_ll_log(LOG_CRIT,"Too long prefix for file names, would not be able to write to log files. Exiting.\n"); + edg_wll_ll_log(LOG_CRIT,"Too long prefix (%s) for file names, would not be able to write to log files. Exiting.\n",prefix); exit(1); - } else { - edg_wll_ll_log(LOG_INFO,"yes.\n"); } + /* TODO: check for write permisions */ + edg_wll_ll_log(LOG_INFO,"Messages will be stored with the filename prefix \"%s\".\n",prefix); if (CAcert_dir) - setenv("X509_CERT_DIR", CAcert_dir, 1); + setenv("X509_CERT_DIR", CAcert_dir, 1); /* initialize Globus common module */ +/* XXX: obsolete? edg_wll_ll_log(LOG_INFO,"Initializing Globus common module..."); if (globus_module_activate(GLOBUS_COMMON_MODULE) != GLOBUS_SUCCESS) { - edg_wll_ll_log(LOG_NOTICE,"no.\n"); - edg_wll_ll_log(LOG_CRIT, "Failed to initialize Globus common module. Exiting.\n"); - exit(1); + edg_wll_ll_log(LOG_NOTICE,"no.\n"); + edg_wll_ll_log(LOG_CRIT, "Failed to initialize Globus common module. Exiting.\n"); + exit(1); } else { - edg_wll_ll_log(LOG_INFO,"yes.\n"); + edg_wll_ll_log(LOG_INFO,"yes.\n"); } +*/ /* initialize signal handling */ if (mysignal(SIGUSR1, handle_signal) == SIG_ERR) { perror("signal"); exit(1); } @@ -338,24 +392,24 @@ This is LocalLogger, part of Workload Management System in EU DataGrid & EGEE.\n edg_wll_gss_watch_creds(cert_file,&cert_mtime); /* XXX DK: support noAuth */ - ret = edg_wll_gss_acquire_cred_gsi(cert_file, key_file, &cred, &my_subject_name, - &gss_stat); + ret = edg_wll_gss_acquire_cred_gsi(cert_file, key_file, &cred, &my_subject_name, + &gss_stat); if (ret) { - /* XXX DK: call edg_wll_gss_get_error() */ - edg_wll_ll_log(LOG_CRIT, "Failed to get GSI credentials. Exiting.\n"); - exit(1); + /* XXX DK: call edg_wll_gss_get_error() */ + edg_wll_ll_log(LOG_CRIT,"Failed to get GSI credentials. Exiting.\n"); + exit(1); } if (my_subject_name!=NULL) { - edg_wll_ll_log(LOG_INFO," server running with certificate: %s\n",my_subject_name); - free(my_subject_name); + edg_wll_ll_log(LOG_INFO,"Server running with certificate: %s\n",my_subject_name); + free(my_subject_name); } else if (noAuth) { - edg_wll_ll_log(LOG_INFO," running without certificate\n"); + edg_wll_ll_log(LOG_INFO,"Server running without certificate\n"); #if 0 /* XXX DK: */ } else { - edg_wll_ll_log(LOG_CRIT,"No server credential found. Exiting.\n"); - exit(1); + edg_wll_ll_log(LOG_CRIT,"No server credential found. Exiting.\n"); + exit(1); #endif } @@ -363,85 +417,86 @@ This is LocalLogger, part of Workload Management System in EU DataGrid & EGEE.\n edg_wll_ll_log(LOG_INFO,"Listening on port %d\n",port); listener_fd = do_listen(port); if (listener_fd == -1) { - edg_wll_ll_log(LOG_CRIT,"Failed to listen on port %d\n",port); - gss_release_cred(&min_stat, &cred); - exit(-1); + edg_wll_ll_log(LOG_CRIT,"Failed to listen on port %d\n",port); + gss_release_cred(&min_stat, &cred); + exit(-1); + } else { + edg_wll_ll_log(LOG_DEBUG,"Listener's socket descriptor is '%d'\n",listener_fd); } client_addr_len = sizeof(client_addr); bzero((char *) &client_addr, client_addr_len); /* daemonize */ - edg_wll_ll_log(LOG_INFO,"Running as daemon..."); if (debug) { - edg_wll_ll_log(LOG_NOTICE,"no.\n"); - } - else if (daemon(0,0) < 0) { - edg_wll_ll_log(LOG_CRIT,"Failed to run as daemon. Exiting.\n"); - perror("daemon"); - exit(1); - } - else { - edg_wll_ll_log(LOG_INFO,"yes.\n"); + edg_wll_ll_log(LOG_INFO,"Running as daemon... [no]\n"); + } else { + edg_wll_ll_log(LOG_INFO,"Running as daemon... [yes]\n"); + if (daemon(0,0) < 0) { + edg_wll_ll_log(LOG_CRIT,"Failed to run as daemon. Exiting.\n"); + SYSTEM_ERROR("daemon"); + exit(1); + } } /* * Main loop */ while (1) { - edg_wll_ll_log(LOG_INFO,"Accepting incomming connections...\n"); - client_fd = accept(listener_fd, (struct sockaddr *) &client_addr, - &client_addr_len); - if (client_fd < 0) { - close(listener_fd); - edg_wll_ll_log(LOG_CRIT,"Failed to accept incomming connections\n"); - perror("accept"); - gss_release_cred(&min_stat, &cred); - exit(-1); - } - - switch (edg_wll_gss_watch_creds(cert_file,&cert_mtime)) { - gss_cred_id_t newcred; - case 0: break; - case 1: - ret = edg_wll_gss_acquire_cred_gsi(cert_file,key_file,&newcred,NULL,&gss_stat); - if (ret) { - edg_wll_ll_log(LOG_WARNING, "Reloading credentials failed, continue with older\n"); - } else { - edg_wll_ll_log(LOG_INFO, "Reloading credentials\n"); + edg_wll_ll_log(LOG_INFO,"Accepting incomming connections...\n"); + client_fd = accept(listener_fd, (struct sockaddr *) &client_addr, + &client_addr_len); + if (client_fd < 0) { + close(listener_fd); + edg_wll_ll_log(LOG_CRIT,"Failed to accept incomming connections\n"); + SYSTEM_ERROR("accept"); gss_release_cred(&min_stat, &cred); - cred = newcred; - } - break; - case -1: - edg_wll_ll_log(LOG_WARNING, "edg_wll_gss_watch_creds failed\n"); - break; - } + exit(-1); + } else { + edg_wll_ll_log(LOG_DEBUG,"Incomming connection on socket '%d'\n",client_fd); + } - /* FORK - change next line if fork() is not needed (for debugging for - * example - */ + switch (edg_wll_gss_watch_creds(cert_file,&cert_mtime)) { + gss_cred_id_t newcred; + case 0: break; + case 1: + ret = edg_wll_gss_acquire_cred_gsi(cert_file,key_file,&newcred,NULL,&gss_stat); + if (ret) { + edg_wll_ll_log(LOG_WARNING,"Reloading credentials failed, continue with older\n"); + } else { + edg_wll_ll_log(LOG_INFO,"Reloading credentials\n"); + gss_release_cred(&min_stat, &cred); + cred = newcred; + } + break; + case -1: + edg_wll_ll_log(LOG_WARNING,"edg_wll_gss_watch_creds failed\n"); + break; + } + + /* FORK - change next line if fork() is not needed (for debugging for example) */ #if 1 - if ((childpid = fork()) < 0) { - perror("fork()"); - close(client_fd); - } - if (childpid == 0) { - ret=doit(client_fd,cred,prefix,noIPC,noParse); - close(client_fd); - goto end; - } - if (childpid > 0) { - close(client_fd); - } + if ((childpid = fork()) < 0) { + SYSTEM_ERROR("fork"); + if (client_fd) close(client_fd); + } + if (childpid == 0) { + ret = doit(client_fd,cred,prefix,noIPC,noParse); + if (client_fd) close(client_fd); + } + if (childpid > 0) { + edg_wll_ll_log(LOG_DEBUG,"Forked a new child with PID %d\n",childpid); + if (client_fd) close(client_fd); + } #else - ret=doit(client_fd,cred,prefix,noIPC,noParse); - close(client_fd); + ret = doit(client_fd,cred,prefix,noIPC,noParse); + if (client_fd) close(client_fd); + #endif } /* while */ end: - close(listener_fd); - gss_release_cred(&min_stat, &cred); - exit(ret); + if (listener_fd) close(listener_fd); + gss_release_cred(&min_stat, &cred); + exit(ret); } -- 1.8.2.3