/*___INFO__MARK_BEGIN__*/ /************************************************************************* * * The Contents of this file are made available subject to the terms of * the Sun Industry Standards Source License Version 1.2 * * Sun Microsystems Inc., March, 2001 * * * Sun Industry Standards Source License Version 1.2 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.2 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2001 by Sun Microsystems, Inc. * * All Rights Reserved. * ************************************************************************/ /*___INFO__MARK_END__*/ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef USE_POLL #include #endif #include "uti/sge_hostname.h" #include "uti/sge_string.h" #include "cl_commlib.h" #include "cl_util.h" #include "cl_data_types.h" #include "cl_tcp_framework.h" #include "cl_ssl_framework.h" #include "cl_message_list.h" #include "cl_host_list.h" #include "cl_host_alias_list.h" #include "cl_connection_list.h" #include "cl_endpoint_list.h" #include "cl_communication.h" #include "msg_commlib.h" #define CL_DO_COMMUNICATION_DEBUG 0 #if CL_DO_COMMUNICATION_DEBUG static void cl_dump_connection(cl_com_connection_t* connection); static void cl_dump_private(cl_com_connection_t* connection); #endif static int cl_com_gethostbyname(const char *hostname, cl_com_hostent_t **hostent, int* system_error ); static int cl_com_gethostbyaddr(struct in_addr *addr, cl_com_hostent_t **hostent, int* system_error_retval ); static int cl_com_dup_host(char** host_dest, const char* source, cl_host_resolve_method_t method, const char* domain); static cl_bool_t cl_com_default_ssl_verify_func(cl_ssl_verify_mode_t mode, cl_bool_t service_mode, const char* value); static cl_bool_t cl_ingore_timeout = CL_FALSE; static cl_bool_t cl_com_is_ip_address_string(const char* hostname, struct in_addr* addr); #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_default_ssl_verify_func()" static cl_bool_t cl_com_default_ssl_verify_func(cl_ssl_verify_mode_t mode, cl_bool_t service_mode, const char* value) { switch(mode) { case CL_SSL_PEER_NAME: { CL_LOG(CL_LOG_INFO,"checking peer name"); break; } case CL_SSL_USER_NAME: { CL_LOG(CL_LOG_INFO,"checking user name"); break; } } switch(service_mode) { case CL_TRUE: { CL_LOG(CL_LOG_INFO,"running in service mode"); break; } case CL_FALSE: { CL_LOG(CL_LOG_INFO,"running in client mode"); break; } } if (value != NULL) { CL_LOG_STR(CL_LOG_INFO,"compare value is:",value); } else { CL_LOG(CL_LOG_ERROR,"compare value is not set"); } return CL_TRUE; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_compare_endpoints()" int cl_com_compare_endpoints(cl_com_endpoint_t* endpoint1, cl_com_endpoint_t* endpoint2) { /* CR check */ if (endpoint1 != NULL && endpoint2 != NULL) { if (endpoint1->comp_id == endpoint2->comp_id) { if (endpoint1->comp_host && endpoint1->comp_name && endpoint2->comp_host && endpoint2->comp_name) { if (strcmp(endpoint1->comp_name,endpoint2->comp_name) == 0) { if (cl_com_compare_hosts(endpoint1->comp_host, endpoint2->comp_host) == CL_RETVAL_OK) { return 1; } } } } } return 0; } #if CL_DO_COMMUNICATION_DEBUG #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_dump_endpoint()" void cl_com_dump_endpoint(cl_com_endpoint_t* endpoint, const char* text) { if (endpoint == NULL) { CL_LOG(CL_LOG_DEBUG,"endpoint is NULL"); return; } if (endpoint->comp_host == NULL || endpoint->comp_name == NULL ) { CL_LOG(CL_LOG_DEBUG,"endpoint data is NULL"); return; } if (text != NULL) { CL_LOG_STR_STR_INT(CL_LOG_DEBUG, text, endpoint->comp_host, endpoint->comp_name, (int)endpoint->comp_id ); } else { CL_LOG_STR_STR_INT(CL_LOG_DEBUG, "", endpoint->comp_host, endpoint->comp_name, (int)endpoint->comp_id ); } } #endif #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_free_message()" int cl_com_free_message(cl_com_message_t** message) { /* CR check */ if (message == NULL || *message == NULL) { return CL_RETVAL_PARAMS; } if ((*message)->message_sirm != NULL) { CL_LOG(CL_LOG_WARNING,"freeing sirm in message struct"); cl_com_free_sirm_message(&((*message)->message_sirm)); } if ((*message)->message != NULL) { free((*message)->message); } free(*message); *message = NULL; return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_add_debug_message()" /* WARNING: connection_list must be locked by caller */ int cl_com_add_debug_message(cl_com_connection_t* connection, const char* message, cl_com_message_t* ms) { #define CL_DEBUG_MESSAGE_FORMAT_STRING "%lu\t%.6f\t%s\t%s\t%s\t%s\t%s\t%s\t%lu\t%lu\t%lu\t%s\t%s\t%s\t%s\t%lu\n" cl_com_handle_t* handle = NULL; int ret_val = CL_RETVAL_OK; struct timeval now; char* dm_buffer = NULL; unsigned long dm_buffer_len = 0; char* xml_msg_buffer = NULL; cl_com_debug_message_tag_t debug_message_tag = CL_DMT_MESSAGE; char sender[256]; char receiver[256]; char message_time[256]; char commlib_time[256]; char message_tag_number[256]; const char* message_tag = NULL; char* xml_data = "n.a."; char* snd_host = "?"; char* snd_comp = "?"; unsigned long snd_id = 0; char* rcv_host = "?"; char* rcv_comp = "?"; unsigned long rcv_id = 0; cl_bool_t outgoing = CL_FALSE; char* direction = "<-"; unsigned long nr_of_connections = 0; double time_now = 0.0; double msg_time = 0.0; double com_time = 0.0; char* info = NULL; if (connection == NULL || ms == NULL ) { return CL_RETVAL_PARAMS; } handle = connection->handler; if (handle == NULL) { return CL_RETVAL_HANDLE_NOT_FOUND; } /* don't add default case for this switch! */ switch(handle->debug_client_setup->dc_mode) { case CL_DEBUG_CLIENT_OFF: case CL_DEBUG_CLIENT_APP: return CL_RETVAL_DEBUG_CLIENTS_NOT_ENABLED; case CL_DEBUG_CLIENT_MSG: case CL_DEBUG_CLIENT_ALL: break; } if (handle->debug_client_setup->dc_debug_list == NULL) { return CL_RETVAL_PARAMS; } if (handle->connection_list != NULL) { nr_of_connections = cl_raw_list_get_elem_count(handle->connection_list); } if (message == NULL) { info = "n.a."; } else { info = (char*)message; } gettimeofday(&now,NULL); time_now = now.tv_sec + (now.tv_usec / 1000000.0); if (ms->message_send_time.tv_sec != 0) { outgoing = CL_TRUE; /* set message_time to message creation time */ msg_time = ms->message_insert_time.tv_sec + (ms->message_insert_time.tv_usec / 1000000.0); snprintf(message_time,256,"%.6f", msg_time); /* set commlib_time to commlib linger time */ msg_time = ms->message_send_time.tv_sec + (ms->message_send_time.tv_usec / 1000000.0); com_time = msg_time - (ms->message_insert_time.tv_sec + (ms->message_insert_time.tv_usec / 1000000.0)); snprintf(commlib_time,256,"%.6f", com_time); } else { msg_time = ms->message_receive_time.tv_sec + (ms->message_receive_time.tv_usec / 1000000.0); snprintf(message_time,256,"%.6f", msg_time); if (ms->message_remove_time.tv_sec != 0) { com_time = (ms->message_remove_time.tv_sec + (ms->message_remove_time.tv_usec / 1000000.0)) - msg_time; snprintf(commlib_time,256,"%.6f", com_time); } else { snprintf(commlib_time,256,"%.6s", "-.-"); } } if (outgoing == CL_TRUE) { direction = "->"; } if (connection->local != NULL) { if (connection->local->comp_host != NULL) { snd_host = connection->local->comp_host; } if (connection->local->comp_name != NULL) { snd_comp = connection->local->comp_name; } snd_id = connection->local->comp_id; } if (connection->remote != NULL) { if (connection->remote->comp_host != NULL) { rcv_host = connection->remote->comp_host; } if (connection->remote->comp_name != NULL) { rcv_comp = connection->remote->comp_name; } rcv_id = connection->remote->comp_id; } snprintf(sender, 256, "%s/%s/%lu", snd_host, snd_comp, snd_id); snprintf(receiver, 256, "%s/%s/%lu", rcv_host, rcv_comp, rcv_id); if (connection->tag_name_func != NULL && ms->message_tag != 0) { message_tag = connection->tag_name_func(ms->message_tag); } else { CL_LOG(CL_LOG_INFO,"no message tag function set"); } if (handle->debug_client_setup->dc_dump_flag == CL_TRUE) { switch(ms->message_df) { case CL_MIH_DF_UNDEFINED: break; case CL_MIH_DF_BIN: { cl_util_get_ascii_hex_buffer((unsigned char*)ms->message, ms->message_length, &xml_msg_buffer, NULL); if (xml_msg_buffer != NULL) { xml_data = xml_msg_buffer; } } break; default: { xml_msg_buffer = (char*) malloc( (ms->message_length + 1) * sizeof(char) ); if (xml_msg_buffer != NULL) { memcpy(xml_msg_buffer, ms->message, ms->message_length); xml_msg_buffer[ms->message_length] = 0; xml_data = xml_msg_buffer; } } } } if (message_tag == NULL) { snprintf(message_tag_number,256,"%lu", ms->message_tag ); message_tag = message_tag_number; } dm_buffer_len += cl_util_get_ulong_number_length((unsigned long)debug_message_tag); dm_buffer_len += cl_util_get_double_number_length(time_now); dm_buffer_len += strlen(sender); dm_buffer_len += strlen(direction); dm_buffer_len += strlen(receiver); dm_buffer_len += strlen(cl_com_get_mih_df_string(ms->message_df)); dm_buffer_len += strlen(cl_com_get_mih_mat_string(ms->message_mat)); dm_buffer_len += strlen(message_tag); dm_buffer_len += cl_util_get_ulong_number_length(ms->message_id); dm_buffer_len += cl_util_get_ulong_number_length(ms->message_response_id); dm_buffer_len += cl_util_get_ulong_number_length(ms->message_length); dm_buffer_len += strlen(message_time); dm_buffer_len += strlen(xml_data); dm_buffer_len += strlen(info); dm_buffer_len += strlen(commlib_time); dm_buffer_len += cl_util_get_ulong_number_length(nr_of_connections); dm_buffer_len += strlen(CL_DEBUG_MESSAGE_FORMAT_STRING); dm_buffer_len += 1; dm_buffer = (char*) malloc(sizeof(char)*dm_buffer_len); if (dm_buffer == NULL) { ret_val = CL_RETVAL_MALLOC; } else { snprintf(dm_buffer,dm_buffer_len,CL_DEBUG_MESSAGE_FORMAT_STRING, (unsigned long)debug_message_tag, time_now, sender, direction, receiver, cl_com_get_mih_df_string(ms->message_df), cl_com_get_mih_mat_string(ms->message_mat), message_tag, ms->message_id, ms->message_response_id, ms->message_length, message_time, xml_data, info, commlib_time, nr_of_connections); ret_val = cl_string_list_append_string(handle->debug_client_setup->dc_debug_list, dm_buffer , 1); free(dm_buffer); dm_buffer = NULL; } if (xml_msg_buffer != NULL) { free(xml_msg_buffer); xml_msg_buffer = NULL; } return ret_val; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_create_debug_client_setup()" int cl_com_create_debug_client_setup(cl_debug_client_setup_t** new_setup, cl_debug_client_t dc_mode, /* debug_client_mode */ cl_bool_t dc_dump_flag, /* flag for sending message data */ int dc_app_log_level) { /* application log level */ int return_value = CL_RETVAL_OK; cl_debug_client_setup_t* tmp_setup = NULL; if (new_setup == NULL) { return CL_RETVAL_PARAMS; } if (*new_setup != NULL) { return CL_RETVAL_PARAMS; } tmp_setup = (cl_debug_client_setup_t*) malloc(sizeof(cl_debug_client_setup_t)); if (tmp_setup == NULL) { return CL_RETVAL_MALLOC; } tmp_setup->dc_debug_list = NULL; if ((return_value=cl_string_list_setup(&(tmp_setup->dc_debug_list), "debug list")) != CL_RETVAL_OK) { CL_LOG_STR(CL_LOG_ERROR,"could not setup debug client information list:", cl_get_error_text(return_value)); cl_com_free_debug_client_setup(&tmp_setup); return return_value; } /* set values */ tmp_setup->dc_mode = dc_mode; tmp_setup->dc_dump_flag = dc_dump_flag; tmp_setup->dc_app_log_level = dc_app_log_level; *new_setup = tmp_setup; return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_free_debug_client_setup()" int cl_com_free_debug_client_setup(cl_debug_client_setup_t** dc_setup) { int ret_val = CL_RETVAL_OK; if (dc_setup == NULL) { return CL_RETVAL_PARAMS; } if (*dc_setup == NULL) { return CL_RETVAL_PARAMS; } ret_val = cl_string_list_cleanup(&((*dc_setup)->dc_debug_list)); if (ret_val != CL_RETVAL_OK) { return ret_val; } free(*dc_setup); dc_setup = NULL; return ret_val; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_create_ssl_setup()" int cl_com_create_ssl_setup(cl_ssl_setup_t** new_setup, cl_ssl_cert_mode_t ssl_cert_mode, cl_ssl_method_t ssl_method, const char* ssl_CA_cert_pem_file, const char* ssl_CA_key_pem_file, const char* ssl_cert_pem_file, const char* ssl_key_pem_file, const char* ssl_rand_file, const char* ssl_reconnect_file, const char* ssl_crl_file, unsigned long ssl_refresh_time, const char* ssl_password, cl_ssl_verify_func_t ssl_verify_func) { cl_ssl_setup_t* tmp_setup = NULL; if (new_setup == NULL) { return CL_RETVAL_PARAMS; } if (*new_setup != NULL) { CL_LOG(CL_LOG_ERROR,"setup configuration pointer is not NULL"); return CL_RETVAL_PARAMS; } switch(ssl_method) { case CL_SSL_v23: break; default: CL_LOG(CL_LOG_ERROR,"unsupported ssl method"); return CL_RETVAL_PARAMS; } tmp_setup = (cl_ssl_setup_t*) malloc(sizeof(cl_ssl_setup_t)); if (tmp_setup == NULL) { return CL_RETVAL_MALLOC; } memset(tmp_setup, 0, sizeof(cl_ssl_setup_t)); tmp_setup->ssl_cert_mode = ssl_cert_mode; tmp_setup->ssl_method = ssl_method; if (ssl_CA_cert_pem_file != NULL) { tmp_setup->ssl_CA_cert_pem_file = strdup(ssl_CA_cert_pem_file); if (tmp_setup->ssl_CA_cert_pem_file == NULL) { cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_MALLOC; } } else { CL_LOG(CL_LOG_ERROR,"CA certificate file not set"); cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_PARAMS; } if (ssl_CA_key_pem_file != NULL) { tmp_setup->ssl_CA_key_pem_file = strdup(ssl_CA_key_pem_file); if (tmp_setup->ssl_CA_key_pem_file == NULL) { cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_MALLOC; } } if (ssl_cert_pem_file != NULL) { tmp_setup->ssl_cert_pem_file = strdup(ssl_cert_pem_file); if (tmp_setup->ssl_cert_pem_file == NULL) { cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_MALLOC; } } else { CL_LOG(CL_LOG_ERROR,"certificates file not set"); cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_PARAMS; } if (ssl_key_pem_file != NULL) { tmp_setup->ssl_key_pem_file = strdup(ssl_key_pem_file); if (tmp_setup->ssl_key_pem_file == NULL) { cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_MALLOC; } } else { CL_LOG(CL_LOG_ERROR,"key file not set"); cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_PARAMS; } if (ssl_rand_file != NULL) { tmp_setup->ssl_rand_file = strdup(ssl_rand_file); if (tmp_setup->ssl_rand_file == NULL) { cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_MALLOC; } } if (ssl_reconnect_file != NULL) { tmp_setup->ssl_reconnect_file = strdup(ssl_reconnect_file); if (tmp_setup->ssl_reconnect_file == NULL) { cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_MALLOC; } } if (ssl_crl_file != NULL) { tmp_setup->ssl_crl_file = strdup(ssl_crl_file); if (tmp_setup->ssl_crl_file == NULL) { cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_MALLOC; } } tmp_setup->ssl_refresh_time = ssl_refresh_time; if (ssl_password != NULL) { tmp_setup->ssl_password = strdup(ssl_password); if (tmp_setup->ssl_password == NULL) { cl_com_free_ssl_setup(&tmp_setup); return CL_RETVAL_MALLOC; } } if (ssl_verify_func != NULL) { tmp_setup->ssl_verify_func = ssl_verify_func; } else { CL_LOG(CL_LOG_WARNING,"no verify func set, doing no additional certificate checks"); tmp_setup->ssl_verify_func = cl_com_default_ssl_verify_func; } *new_setup = tmp_setup; return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_dup_ssl_setup()" int cl_com_dup_ssl_setup(cl_ssl_setup_t** new_setup, cl_ssl_setup_t* source) { if ( source == NULL) { return CL_RETVAL_PARAMS; } return cl_com_create_ssl_setup(new_setup, source->ssl_cert_mode, source->ssl_method, source->ssl_CA_cert_pem_file, source->ssl_CA_key_pem_file, source->ssl_cert_pem_file, source->ssl_key_pem_file, source->ssl_rand_file, source->ssl_reconnect_file, source->ssl_crl_file, source->ssl_refresh_time, source->ssl_password, source->ssl_verify_func); } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_free_ssl_setup()" int cl_com_free_ssl_setup(cl_ssl_setup_t** del_setup) { if (del_setup == NULL) { return CL_RETVAL_PARAMS; } if (*del_setup == NULL) { return CL_RETVAL_PARAMS; } /* free structure members */ if ((*del_setup)->ssl_CA_cert_pem_file != NULL) { free((*del_setup)->ssl_CA_cert_pem_file); } if ((*del_setup)->ssl_CA_key_pem_file != NULL) { free((*del_setup)->ssl_CA_key_pem_file); } if ((*del_setup)->ssl_cert_pem_file != NULL) { free((*del_setup)->ssl_cert_pem_file); } if ((*del_setup)->ssl_key_pem_file != NULL) { free((*del_setup)->ssl_key_pem_file); } if ((*del_setup)->ssl_rand_file != NULL) { free((*del_setup)->ssl_rand_file); } if ((*del_setup)->ssl_reconnect_file != NULL) { free((*del_setup)->ssl_reconnect_file); } if ((*del_setup)->ssl_crl_file != NULL) { free((*del_setup)->ssl_crl_file); } if ((*del_setup)->ssl_password != NULL) { free((*del_setup)->ssl_password); } /* free structure itself */ free(*del_setup); *del_setup = NULL; return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_setup_message()" int cl_com_setup_message(cl_com_message_t** message, cl_com_connection_t* connection, cl_byte_t* data, unsigned long size, cl_xml_ack_type_t ack_type, unsigned long response_id, unsigned long tag) { int return_value = CL_RETVAL_OK; if (message == NULL || *message != NULL || connection == NULL || data == NULL) { return CL_RETVAL_PARAMS; } return_value = cl_com_create_message(message); if (return_value != CL_RETVAL_OK) { return return_value; } (*message)->message_state = CL_MS_INIT_SND; (*message)->message_df = CL_MIH_DF_BIN; (*message)->message_mat = ack_type; (*message)->message = data; if ( connection->last_send_message_id == 0) { /* the first send message will set last_send_message_id to 1 */ /* last_send_message_id is initialized with 0 */ connection->last_send_message_id = 1; } (*message)->message_id = connection->last_send_message_id; (*message)->message_tag = tag; (*message)->message_response_id = response_id; if (connection->last_send_message_id >= CL_DEFINE_MAX_MESSAGE_ID) { connection->last_send_message_id = 1; } else { connection->last_send_message_id = connection->last_send_message_id + 1; } (*message)->message_length = size; switch (connection->connection_state) { case CL_CONNECTED: case CL_CLOSING: connection->data_write_flag = CL_COM_DATA_READY; break; case CL_DISCONNECTED: case CL_OPENING: case CL_ACCEPTING: case CL_CONNECTING: break; } return return_value; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_create_message()" int cl_com_create_message(cl_com_message_t** message) { if (message == NULL || *message != NULL) { return CL_RETVAL_PARAMS; } *message = (cl_com_message_t*)malloc(sizeof(cl_com_message_t)); if (*message == NULL) { return CL_RETVAL_MALLOC; } memset( *message, 0, sizeof(cl_com_message_t)); (*message)->message_state = CL_MS_UNDEFINED; (*message)->message_df = CL_MIH_DF_UNDEFINED; (*message)->message_mat = CL_MIH_MAT_UNDEFINED; return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_create_connection()" int cl_com_create_connection(cl_com_connection_t** connection) { int ret_val; if (connection == NULL || *connection != NULL) { return CL_RETVAL_PARAMS; } *connection = (cl_com_connection_t*) malloc(sizeof(cl_com_connection_t)); if (*connection == NULL) { return CL_RETVAL_MALLOC; } /* init connection struct */ (*connection)->check_endpoint_flag = CL_FALSE; (*connection)->is_read_selected = CL_FALSE; (*connection)->is_write_selected = CL_FALSE; (*connection)->check_endpoint_mid = 0; (*connection)->crm_state = CL_CRM_CS_UNDEFINED; (*connection)->crm_state_error = NULL; (*connection)->error_func = NULL; (*connection)->tag_name_func = NULL; (*connection)->com_private = NULL; (*connection)->data_buffer_size = CL_DEFINE_DATA_BUFFER_SIZE; (*connection)->auto_close_type = CL_CM_AC_UNDEFINED; (*connection)->read_buffer_timeout_time = 0; (*connection)->write_buffer_timeout_time = 0; (*connection)->data_write_buffer_pos = 0; (*connection)->data_write_buffer_processed = 0; (*connection)->data_write_buffer_to_send = 0; (*connection)->data_read_buffer_pos = 0; (*connection)->data_read_buffer_processed = 0; (*connection)->handler = NULL; (*connection)->last_send_message_id = 0; (*connection)->last_received_message_id = 0; (*connection)->received_message_list = NULL; (*connection)->send_message_list = NULL; (*connection)->shutdown_timeout = 0; (*connection)->local = NULL; (*connection)->remote = NULL; (*connection)->client_dst = NULL; (*connection)->service_handler_flag = CL_COM_SERVICE_UNDEFINED; (*connection)->framework_type = CL_CT_UNDEFINED; (*connection)->connection_type = CL_COM_UNDEFINED; (*connection)->data_write_flag = CL_COM_DATA_NOT_READY; (*connection)->data_read_flag = CL_COM_DATA_NOT_READY; (*connection)->fd_ready_for_write = CL_COM_DATA_NOT_READY; (*connection)->connection_state = CL_DISCONNECTED; (*connection)->connection_sub_state = CL_COM_SUB_STATE_UNDEFINED; (*connection)->data_flow_type = CL_CM_CT_UNDEFINED; (*connection)->was_accepted = CL_FALSE; (*connection)->was_opened = CL_FALSE; (*connection)->client_host_name = NULL; (*connection)->data_format_type = CL_CM_DF_UNDEFINED; gettimeofday(&((*connection)->last_transfer_time),NULL); memset(&((*connection)->connection_connect_time), 0, sizeof(struct timeval)); memset(&((*connection)->connection_close_time), 0, sizeof(struct timeval)); (*connection)->data_read_buffer = (cl_byte_t*) malloc (sizeof(cl_byte_t) * ((*connection)->data_buffer_size) ); (*connection)->data_write_buffer = (cl_byte_t*) malloc (sizeof(cl_byte_t) * ((*connection)->data_buffer_size) ); (*connection)->read_gmsh_header = (cl_com_GMSH_t*) malloc (sizeof(cl_com_GMSH_t)); (*connection)->statistic = (cl_com_con_statistic_t*) malloc(sizeof(cl_com_con_statistic_t)); if ( (*connection)->data_read_buffer == NULL || (*connection)->data_write_buffer == NULL || (*connection)->read_gmsh_header == NULL || (*connection)->statistic == NULL ) { cl_com_close_connection(connection); return CL_RETVAL_MALLOC; } (*connection)->read_gmsh_header->dl = 0; memset((*connection)->statistic, 0, sizeof(cl_com_con_statistic_t)); gettimeofday(&((*connection)->statistic->last_update),NULL); if ( (ret_val=cl_message_list_setup(&((*connection)->received_message_list), "rcv messages")) != CL_RETVAL_OK ) { cl_com_close_connection(connection); return ret_val; } if ( (ret_val=cl_message_list_setup(&((*connection)->send_message_list), "snd messages")) != CL_RETVAL_OK ) { cl_com_close_connection(connection); return ret_val; } /* set application callback function pionters */ cl_com_setup_callback_functions(*connection); return CL_RETVAL_OK; } #if CL_DO_COMMUNICATION_DEBUG #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_dump_connection()" static void cl_dump_connection(cl_com_connection_t* connection) { /* CR check */ if (connection == NULL) { CL_LOG(CL_LOG_DEBUG, "connection is NULL"); } else { if (connection->service_handler_flag != CL_COM_SERVICE_HANDLER ) { cl_com_dump_endpoint(connection->local, "local: "); cl_com_dump_endpoint(connection->remote, "remote: "); } else { CL_LOG(CL_LOG_DEBUG,"this is local service handler:"); cl_com_dump_endpoint(connection->local, "local: "); } #if CL_DO_COMMUNICATION_DEBUG CL_LOG_INT(CL_LOG_DEBUG,"elements in received_message_list:", (int)cl_raw_list_get_elem_count(connection->received_message_list)); CL_LOG_INT(CL_LOG_DEBUG,"elements in send_message_list:", (int)cl_raw_list_get_elem_count(connection->send_message_list)); #endif if (connection->handler == NULL) { CL_LOG(CL_LOG_DEBUG,"no handler pointer is set"); } else { CL_LOG(CL_LOG_DEBUG,"handler pointer is set"); } CL_LOG_STR(CL_LOG_DEBUG,"framework_type:",cl_com_get_framework_type(connection) ); CL_LOG_STR(CL_LOG_DEBUG,"connection_type:", cl_com_get_connection_type(connection) ); CL_LOG_STR(CL_LOG_DEBUG,"service_handler_flag:", cl_com_get_service_handler_flag(connection) ); CL_LOG_STR(CL_LOG_DEBUG,"data_write_flag:", cl_com_get_data_write_flag(connection) ); CL_LOG_STR(CL_LOG_DEBUG,"data_read_flag:", cl_com_get_data_read_flag(connection) ); CL_LOG_STR(CL_LOG_DEBUG,"connection_state:", cl_com_get_connection_state(connection) ); CL_LOG_STR(CL_LOG_DEBUG,"data_flow_type:", cl_com_get_data_flow_type(connection) ); if (connection->com_private == NULL) { CL_LOG(CL_LOG_DEBUG,"com_private is not set"); } else { cl_dump_private(connection); } } } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_dump_private()" static void cl_dump_private(cl_com_connection_t* connection) { /* CR check */ if (connection != NULL) { switch(connection->framework_type) { case CL_CT_TCP: { cl_dump_tcp_private(connection); break; } case CL_CT_SSL: { cl_dump_ssl_private(connection); break; } case CL_CT_UNDEFINED: { break; } } } else { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); } } #endif #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_read_GMSH()" int cl_com_read_GMSH(cl_com_connection_t* connection, unsigned long *only_one_read) { if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return CL_RETVAL_PARAMS; } switch(connection->framework_type ) { case CL_CT_TCP: { return cl_com_tcp_read_GMSH(connection, only_one_read); } case CL_CT_SSL: { return cl_com_ssl_read_GMSH(connection, only_one_read); } case CL_CT_UNDEFINED: { break; } } return CL_RETVAL_UNDEFINED_FRAMEWORK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_framework_type()" const char* cl_com_get_framework_type(cl_com_connection_t* connection) { /* CR check */ if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return "NULL"; } switch(connection->framework_type ) { case CL_CT_TCP: { return "CL_CT_TCP"; } case CL_CT_SSL: { return "CL_CT_SSL"; } case CL_CT_UNDEFINED: { return "CL_CT_UNDEFINED"; } } return "unexpected framework type"; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_connection_type()" const char* cl_com_get_connection_type(cl_com_connection_t* connection) { /* CR check */ if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return "NULL"; } switch(connection->connection_type ) { case CL_COM_RECEIVE: { return "CL_COM_RECEIVE"; } case CL_COM_SEND: { return "CL_COM_SEND"; } case CL_COM_SEND_RECEIVE: { return "CL_COM_SEND_RECEIVE"; } case CL_COM_UNDEFINED: { return "CL_COM_UNDEFINED"; } } CL_LOG(CL_LOG_WARNING,"undefined connection type"); return "unknown"; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_service_handler_flag()" const char* cl_com_get_service_handler_flag(cl_com_connection_t* connection) { /* CR check */ if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return "NULL"; } switch(connection->service_handler_flag ) { case CL_COM_SERVICE_HANDLER: { return "CL_COM_SERVICE_HANDLER"; } case CL_COM_CONNECTION: { return "CL_COM_CONNECTION"; } case CL_COM_SERVICE_UNDEFINED: { return "CL_COM_SERVICE_UNDEFINED"; } default: { CL_LOG(CL_LOG_ERROR,"undefined service handler flag type"); return "unknown"; } } } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_data_write_flag()" const char* cl_com_get_data_write_flag(cl_com_connection_t* connection) { /* CR check */ if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return "NULL"; } switch(connection->data_write_flag ) { case CL_COM_DATA_READY: { return "CL_COM_DATA_READY"; } case CL_COM_DATA_NOT_READY: { return "CL_COM_DATA_NOT_READY"; } default: { CL_LOG(CL_LOG_ERROR,"undefined data write flag type"); return "unknown"; } } } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_data_read_flag()" const char* cl_com_get_data_read_flag(cl_com_connection_t* connection) { /* CR check */ if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return "NULL"; } switch(connection->data_read_flag ) { case CL_COM_DATA_READY: { return "CL_COM_DATA_READY"; } case CL_COM_DATA_NOT_READY: { return "CL_COM_DATA_NOT_READY"; } default: { CL_LOG(CL_LOG_ERROR,"undefined data read flag type"); return "unknown"; } } } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_connection_state()" const char* cl_com_get_connection_state(cl_com_connection_t* connection) { /* CR check */ if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return "NULL"; } switch(connection->connection_state ) { case CL_DISCONNECTED: { return "CL_DISCONNECTED"; } case CL_CLOSING: { return "CL_CLOSING"; } case CL_OPENING: { return "CL_OPENING"; } case CL_ACCEPTING: { return "CL_ACCEPTING"; } case CL_CONNECTED: { return "CL_CONNECTED"; } case CL_CONNECTING: { return "CL_CONNECTING"; } } CL_LOG(CL_LOG_ERROR, "undefined marked to close flag type"); return "unknown"; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_connection_sub_state()" const char* cl_com_get_connection_sub_state(cl_com_connection_t* connection) { if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return "NULL"; } switch(connection->connection_state ) { case CL_DISCONNECTED: { switch( connection->connection_sub_state ) { case CL_COM_SUB_STATE_UNDEFINED: return "CL_COM_SUB_STATE_UNDEFINED"; default: return "UNEXPECTED CONNECTION SUB STATE"; } } case CL_CLOSING: { switch( connection->connection_sub_state ) { case CL_COM_DO_SHUTDOWN: return "CL_COM_DO_SHUTDOWN"; case CL_COM_SHUTDOWN_DONE: return "CL_COM_SHUTDOWN_DONE"; default: return "UNEXPECTED CONNECTION SUB STATE"; } } case CL_OPENING: { switch( connection->connection_sub_state ) { case CL_COM_OPEN_INIT: return "CL_COM_OPEN_INIT"; case CL_COM_OPEN_CONNECT: return "CL_COM_OPEN_CONNECT"; case CL_COM_OPEN_CONNECTED: return "CL_COM_OPEN_CONNECTED"; case CL_COM_OPEN_CONNECT_IN_PROGRESS: return "CL_COM_OPEN_CONNECT_IN_PROGRESS"; case CL_COM_OPEN_SSL_CONNECT_INIT: return "CL_COM_OPEN_SSL_CONNECT_INIT"; case CL_COM_OPEN_SSL_CONNECT: return "CL_COM_OPEN_SSL_CONNECT"; default: return "UNEXPECTED CONNECTION SUB STATE"; } } case CL_CONNECTED: { switch( connection->connection_sub_state ) { case CL_COM_WORK: return "CL_COM_WORK"; case CL_COM_RECEIVED_CCM: return "CL_COM_RECEIVED_CCM"; case CL_COM_SENDING_CCM: return "CL_COM_SENDING_CCM"; case CL_COM_WAIT_FOR_CCRM: return "CL_COM_WAIT_FOR_CCRM"; case CL_COM_SENDING_CCRM: return "CL_COM_SENDING_CCRM"; case CL_COM_DONE: return "CL_COM_DONE"; default: return "UNEXPECTED CONNECTION SUB STATE"; } } case CL_CONNECTING: { switch( connection->connection_sub_state ) { case CL_COM_READ_INIT: return "CL_COM_READ_INIT"; case CL_COM_READ_GMSH: return "CL_COM_READ_GMSH"; case CL_COM_READ_CM: return "CL_COM_READ_CM"; case CL_COM_READ_INIT_CRM: return "CL_COM_READ_INIT_CRM"; case CL_COM_READ_SEND_CRM: return "CL_COM_READ_SEND_CRM"; case CL_COM_SEND_INIT: return "CL_COM_SEND_INIT"; case CL_COM_SEND_CM: return "CL_COM_SEND_CM"; case CL_COM_SEND_READ_GMSH: return "CL_COM_SEND_READ_GMSH"; case CL_COM_SEND_READ_CRM: return "CL_COM_SEND_READ_CRM"; default: return "UNEXPECTED CONNECTION SUB STATE"; } } case CL_ACCEPTING: { switch( connection->connection_sub_state ) { case CL_COM_ACCEPT_INIT: return "CL_COM_ACCEPT_INIT"; case CL_COM_ACCEPT: return "CL_COM_ACCEPT"; default: return "UNEXPECTED CONNECTION SUB STATE"; } } } CL_LOG(CL_LOG_ERROR,"undefined marked to close flag type"); return "UNEXPECTED CONNECTION SUB STATE"; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_data_flow_type()" const char* cl_com_get_data_flow_type(cl_com_connection_t* connection) { /* CR check */ if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return "NULL"; } switch(connection->data_flow_type ) { case CL_CM_CT_STREAM: { return "CL_COM_STREAM"; } case CL_CM_CT_MESSAGE: { return "CL_COM_MESSAGE"; } default: { CL_LOG(CL_LOG_ERROR,"undefined data flow flag type"); return "unknown"; } } } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_ignore_timeouts()" void cl_com_ignore_timeouts(cl_bool_t flag) { /* * ATTENTION: This function must be signal handler save!!! * DO NOT call functions which call lock functions !!! */ cl_ingore_timeout = flag; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_ignore_timeouts_flag()" cl_bool_t cl_com_get_ignore_timeouts_flag(void) { if (cl_ingore_timeout == CL_TRUE) { CL_LOG(CL_LOG_WARNING,"ignoring all communication timeouts"); } return cl_ingore_timeout; } /****** cl_communication/cl_com_open_connection() ****************************** * NAME * cl_com_open_connection() -- open a connection to a service handler * * SYNOPSIS * int cl_com_open_connection(cl_com_connection_t* connection, const char* * comp_host, const char* comp_name, int comp_id, int timeout) * * FUNCTION * This function is called to setup a connection to a service handler. The * connection object (cl_com_connection_t) must be initalized with a call * to cl_com_setup_xxx_connection (e.g. cl_com_setup_tcp_connection() for * a CL_CT_TCP connection which is using tcp/ip for transport) * * INPUTS * cl_com_connection_t* connection - pointer to a connection object * const char* comp_host - host of service * const char* comp_name - component name of service * int comp_id - component id of service * int timeout - timeout for connection establishment * * RESULT * int - CL_COMM_XXXX error value or CL_RETVAL_OK for no errors * * SEE ALSO * * cl_communication/cl_com_close_connection() * cl_communication/cl_com_setup_tcp_connection() *******************************************************************************/ #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_open_connection()" int cl_com_open_connection(cl_com_connection_t* connection, int timeout, cl_com_endpoint_t* remote_endpoint, cl_com_endpoint_t* local_endpoint) { int retval = CL_RETVAL_UNKNOWN; /* check parameters and duplicate */ if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return CL_RETVAL_PARAMS; } if (connection->connection_state != CL_DISCONNECTED && connection->connection_state != CL_OPENING) { CL_LOG(CL_LOG_ERROR,"unexpected connection state"); return CL_RETVAL_CONNECTION_STATE_ERROR; } #if CL_DO_COMMUNICATION_DEBUG CL_LOG_STR(CL_LOG_INFO,"connection state: ",cl_com_get_connection_state(connection)); CL_LOG_STR(CL_LOG_INFO,"connection sub state:",cl_com_get_connection_sub_state(connection)); #endif /* starting this function the first time */ if (connection->connection_state == CL_DISCONNECTED) { if (remote_endpoint == NULL || local_endpoint == NULL) { CL_LOG(CL_LOG_ERROR,"endpoint pointer parameter not initialized"); return CL_RETVAL_PARAMS; } /* check endpoint structure pointer to be free */ if (connection->local != NULL || connection->remote != NULL ) { CL_LOG(CL_LOG_ERROR,cl_get_error_text(CL_RETVAL_PARAMS)); return CL_RETVAL_PARAMS; } /* copy the endpoint structures */ connection->remote = cl_com_dup_endpoint(remote_endpoint); connection->local = cl_com_dup_endpoint(local_endpoint); /* check new endpoints */ if (connection->remote == NULL || connection->local == NULL) { cl_com_free_endpoint(&(connection->remote)); cl_com_free_endpoint(&(connection->local)); CL_LOG(CL_LOG_ERROR,"malloc() error"); return CL_RETVAL_MALLOC; } /* check comp ids */ if (connection->remote->comp_id == 0 ) { cl_com_free_endpoint(&(connection->remote)); cl_com_free_endpoint(&(connection->local)); CL_LOG(CL_LOG_ERROR,"remote endpoint id can not be 0"); return CL_RETVAL_PARAMS; } /* init connection */ connection->data_write_flag = CL_COM_DATA_NOT_READY; connection->data_read_flag = CL_COM_DATA_NOT_READY; connection->service_handler_flag = CL_COM_CONNECTION; connection->connection_state = CL_OPENING; connection->connection_sub_state = CL_COM_OPEN_INIT; connection->was_opened = CL_TRUE; } /* try to connect (open connection) */ if (connection->connection_state == CL_OPENING) { int connect_port = 0; int tcp_port = 0; cl_xml_connection_autoclose_t autoclose = CL_CM_AC_UNDEFINED; /* set connection autoclose mode set connection connect port */ if ((retval = cl_com_connection_get_connect_port(connection, &connect_port)) != CL_RETVAL_OK) { return retval; } if (connect_port <= 0) { /* The connection has no port set, try to find out correct port */ if (cl_com_get_known_endpoint_port(connection->remote, &tcp_port) == CL_RETVAL_OK) { if ((retval=cl_com_connection_set_connect_port(connection, tcp_port)) != CL_RETVAL_OK) { CL_LOG(CL_LOG_ERROR,"could not set connect port"); return retval; } CL_LOG_INT(CL_LOG_INFO,"using port:", (int) tcp_port); } else { CL_LOG(CL_LOG_ERROR,"endpoint port not found"); } if (cl_com_get_known_endpoint_autoclose_mode(connection->remote, &autoclose) == CL_RETVAL_OK) { if ( autoclose == CL_CM_AC_ENABLED ) { connection->auto_close_type = autoclose; } switch ( connection->auto_close_type ) { case CL_CM_AC_ENABLED: CL_LOG(CL_LOG_INFO,"autoclose is enabled"); break; case CL_CM_AC_DISABLED: CL_LOG(CL_LOG_INFO,"autoclose is disabled"); break; default: CL_LOG(CL_LOG_INFO,"unexpected autoclose value"); } } else { CL_LOG(CL_LOG_ERROR,"endpoint autoclose mode not found"); } } /* check if connection count is reached */ if ( connection->handler != NULL) { if ( connection->handler->max_connection_count_reached == CL_TRUE ) { CL_LOG(CL_LOG_WARNING,cl_get_error_text(CL_RETVAL_MAX_CON_COUNT_REACHED)); return CL_RETVAL_UNCOMPLETE_WRITE; /* wait till connection count is ok */ } } switch(connection->framework_type) { case CL_CT_TCP: { connection->connection_type = CL_COM_SEND_RECEIVE; retval = cl_com_tcp_open_connection(connection,timeout); if (retval == CL_RETVAL_OK) { /* OK set follow state */ connection->connection_state = CL_CONNECTING; connection->connection_sub_state = CL_COM_SEND_INIT; connection->data_write_flag = CL_COM_DATA_READY; } else if (retval != CL_RETVAL_UNCOMPLETE_WRITE) { CL_LOG(CL_LOG_ERROR,"connect error"); connection->connection_type = CL_COM_UNDEFINED; } return retval; } case CL_CT_SSL: { connection->connection_type = CL_COM_SEND_RECEIVE; retval = cl_com_ssl_open_connection(connection,timeout); if (retval == CL_RETVAL_OK) { /* OK set follow state */ connection->connection_state = CL_CONNECTING; connection->connection_sub_state = CL_COM_SEND_INIT; connection->data_write_flag = CL_COM_DATA_READY; } else if (retval != CL_RETVAL_UNCOMPLETE_WRITE) { CL_LOG(CL_LOG_ERROR,"connect error"); connection->connection_type = CL_COM_UNDEFINED; } return retval; } case CL_CT_UNDEFINED: { CL_LOG(CL_LOG_ERROR,"undefined framework type"); retval = CL_RETVAL_UNDEFINED_FRAMEWORK; break; } } } return retval; } /****** cl_communication/cl_com_close_connection() ***************************** * NAME * cl_com_close_connection() -- cleanup a connection * * SYNOPSIS * int cl_com_close_connection(cl_com_connection_t* connection) * * FUNCTION * This wrapper function will call the correct cl_com_xxx_close_connection() * function for the selected framework. The called function must free * the memory for the connection->com_private pointer. * * INPUTS * cl_com_connection_t* connection - pointer to a cl_com_connection_t * structure * * RESULT * int - CL_RETVAL_XXXX error or CL_RETVAL_OK on success * * SEE ALSO * cl_communication/cl_com_setup_tcp_connection() * *******************************************************************************/ #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_close_connection()" /* connection_list must be locked */ int cl_com_close_connection(cl_com_connection_t** connection) { int retval = CL_RETVAL_OK; if (connection == NULL) { return CL_RETVAL_PARAMS; } if (*connection != NULL) { cl_message_list_elem_t* elem = NULL; cl_message_list_elem_t* elem2 = NULL; cl_com_message_t* message = NULL; CL_LOG(CL_LOG_INFO,"CLOSING CONNECTION"); #if CL_DO_COMMUNICATION_DEBUG cl_dump_connection(*connection); #endif /* rcv messages list */ cl_raw_list_lock((*connection)->received_message_list); elem = cl_message_list_get_first_elem((*connection)->received_message_list); while(elem != NULL) { elem2 = elem; elem = cl_message_list_get_next_elem(elem); message = elem2->message; if (message->message_state == CL_MS_READY) { CL_LOG(CL_LOG_ERROR,"unread message for this connection in received message list"); } else { CL_LOG(CL_LOG_WARNING,"uncompled received message in received messages list"); CL_LOG_INT(CL_LOG_WARNING,"message state:", message->message_state); } /* delete elem */ CL_LOG(CL_LOG_ERROR,"deleting message"); cl_raw_list_remove_elem((*connection)->received_message_list , elem2->raw_elem); free(elem2); elem2 = NULL; cl_com_free_message(&message); } cl_raw_list_unlock((*connection)->received_message_list ); cl_message_list_cleanup(&((*connection)->received_message_list)); /* snd messages list */ cl_raw_list_lock( (*connection)->send_message_list ); elem = cl_message_list_get_first_elem((*connection)->send_message_list); while(elem != NULL) { elem2 = elem; elem = cl_message_list_get_next_elem(elem); message = elem2->message; CL_LOG(CL_LOG_ERROR,"unsent message for this connection in send message list"); CL_LOG_INT(CL_LOG_WARNING,"message state:", message->message_state); /* delete elem */ CL_LOG(CL_LOG_ERROR,"deleting message"); cl_raw_list_remove_elem( (*connection)->send_message_list , elem2->raw_elem ); free(elem2); elem2 = NULL; cl_com_free_message(&message); } cl_raw_list_unlock( (*connection)->send_message_list ); cl_message_list_cleanup(&((*connection)->send_message_list)); cl_com_free_endpoint(&((*connection)->remote)); cl_com_free_endpoint(&((*connection)->local)); cl_com_free_endpoint(&((*connection)->client_dst)); free( (*connection)->data_read_buffer); (*connection)->data_read_buffer = NULL; free( (*connection)->data_write_buffer); (*connection)->data_write_buffer = NULL; free( (*connection)->read_gmsh_header); (*connection)->read_gmsh_header = NULL; (*connection)->data_flow_type = CL_CM_CT_UNDEFINED; free( (*connection)->client_host_name); (*connection)->client_host_name = NULL; free( (*connection)->crm_state_error); (*connection)->crm_state_error = NULL; free( (*connection)->statistic ); (*connection)->statistic = NULL; switch((*connection)->framework_type) { case CL_CT_TCP: { retval = cl_com_tcp_close_connection(connection); break; } case CL_CT_SSL: { retval = cl_com_ssl_close_connection(connection); break; } case CL_CT_UNDEFINED: { retval = CL_RETVAL_UNDEFINED_FRAMEWORK; break; } } (*connection)->handler = NULL; /* com_private is set to NULL by cl_com_tcp_close_connection() or cl_com_ssl_close_connection() */ free(*connection); *connection = NULL; return retval; } else { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); } return CL_RETVAL_PARAMS; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_get_service_port()" int cl_com_connection_get_service_port(cl_com_connection_t* connection, int* port) { if (connection == NULL) { return CL_RETVAL_PARAMS; } switch(connection->framework_type) { case CL_CT_TCP: { return cl_com_tcp_get_service_port(connection,port); } case CL_CT_SSL: { return cl_com_ssl_get_service_port(connection,port); } case CL_CT_UNDEFINED: { break; } } return CL_RETVAL_UNKNOWN; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_get_client_socket_in_port()" int cl_com_connection_get_client_socket_in_port(cl_com_connection_t* connection, int* port) { if (connection == NULL) { return CL_RETVAL_PARAMS; } switch(connection->framework_type) { case CL_CT_TCP: { return cl_com_tcp_get_client_socket_in_port(connection,port); } case CL_CT_SSL: { return cl_com_ssl_get_client_socket_in_port(connection,port); } case CL_CT_UNDEFINED: { break; } } return CL_RETVAL_UNKNOWN; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_get_fd()" int cl_com_connection_get_fd(cl_com_connection_t* connection, int* fd) { int ret_val = CL_RETVAL_PARAMS; if (fd == NULL || connection == NULL) { return ret_val; } switch(connection->framework_type) { case CL_CT_TCP: { ret_val = cl_com_tcp_get_fd(connection,fd); break; } case CL_CT_SSL: { ret_val = cl_com_ssl_get_fd(connection,fd); break; } case CL_CT_UNDEFINED: { ret_val = CL_RETVAL_NO_FRAMEWORK_INIT; break; } } if (ret_val == CL_RETVAL_OK && (*fd < 0)) { CL_LOG_INT(CL_LOG_ERROR, "got no valid port: ", *fd); ret_val = CL_RETVAL_NO_PORT_ERROR; } if (ret_val != CL_RETVAL_OK) { CL_LOG_STR(CL_LOG_WARNING, "Cannot get fd for connection:", cl_get_error_text(ret_val)); } return ret_val; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_get_connect_port()" int cl_com_connection_get_connect_port(cl_com_connection_t* connection, int* port) { if (connection == NULL) { return CL_RETVAL_PARAMS; } switch(connection->framework_type) { case CL_CT_TCP: { return cl_com_tcp_get_connect_port(connection,port); } case CL_CT_SSL: { return cl_com_ssl_get_connect_port(connection,port); } case CL_CT_UNDEFINED: { break; } } return CL_RETVAL_UNKNOWN; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_set_connect_port()" int cl_com_connection_set_connect_port(cl_com_connection_t* connection, int port) { if (connection == NULL) { return CL_RETVAL_PARAMS; } switch(connection->framework_type) { case CL_CT_TCP: { return cl_com_tcp_set_connect_port(connection,port); } case CL_CT_SSL: { return cl_com_ssl_set_connect_port(connection,port); } case CL_CT_UNDEFINED: { break; } } return CL_RETVAL_UNKNOWN; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_free_handle_statistic()" int cl_com_free_handle_statistic(cl_com_handle_statistic_t** statistic) { if (statistic == NULL || *statistic == NULL) { return CL_RETVAL_PARAMS; } if ((*statistic)->application_info != NULL ) { free( (*statistic)->application_info); (*statistic)->application_info = NULL; } free(*statistic); *statistic = NULL; return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_free_hostent()" int cl_com_free_hostent(cl_com_hostent_t **hostent_p) { /* CR check */ if (hostent_p == NULL || *hostent_p == NULL) { return CL_RETVAL_PARAMS; } /* free hostent structure */ sge_free_hostent(&((*hostent_p)->he) ); /* finally free the struct */ free(*hostent_p); *hostent_p = NULL; return CL_RETVAL_OK; } int cl_com_free_hostspec(cl_com_host_spec_t **hostspec) { if (hostspec == NULL || *hostspec == NULL) { CL_LOG(CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_PARAMS)); return CL_RETVAL_PARAMS; } cl_com_free_hostent(&((*hostspec)->hostent)); if ( (*hostspec)->hostent != NULL) { CL_LOG(CL_LOG_ERROR,"could not free hostent structure"); } free((*hostspec)->unresolved_name ); free((*hostspec)->resolved_name ); free((*hostspec)->in_addr); free(*hostspec); *hostspec = NULL; return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_h_error_string()" char* cl_com_get_h_error_string(int h_error) { if (h_error == HOST_NOT_FOUND) { return strdup("h_errno = HOST_NOT_FOUND"); } else if (h_error == TRY_AGAIN) { return strdup("h_errno = TRY_AGAIN"); } else if (h_error == NO_RECOVERY) { return strdup("h_errno = NO_RECOVERY"); } else if (NO_DATA == NO_ADDRESS && h_error == NO_DATA) { return strdup("h_errno = NO_DATA or NO_ADDRESS"); } else if (h_error == NO_DATA) { return strdup("h_errno = NO_DATA"); } else if (h_error == NO_ADDRESS) { return strdup("h_errno = NO_ADDRESS"); } return NULL; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_gethostname()" int cl_com_gethostname(char **unique_hostname, struct in_addr *copy_addr, struct hostent **he_copy, int* system_error_value) { /* CR check */ char localhostname[CL_MAXHOSTNAMELEN_LENGTH + 1]; errno = 0; if (gethostname(localhostname,CL_MAXHOSTNAMELEN_LENGTH) != 0) { if (system_error_value != NULL) { *system_error_value = errno; } CL_LOG(CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_LOCAL_HOSTNAME_ERROR)); return CL_RETVAL_LOCAL_HOSTNAME_ERROR; } CL_LOG_STR( CL_LOG_DEBUG, "local gethostname() returned: ", localhostname); return cl_com_cached_gethostbyname(localhostname, unique_hostname, copy_addr, he_copy , system_error_value); } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_gethostbyname()" static int cl_com_gethostbyname(const char *hostname_unresolved, cl_com_hostent_t **hostent, int* system_error) { #if defined(CRAY) struct sockaddr_in tmp_addr; #else struct in_addr tmp_addr; #endif struct hostent* he = NULL; char* hostname = NULL; cl_com_hostent_t *hostent_p = NULL; int ret_val = CL_RETVAL_OK; cl_bool_t do_free_host = CL_FALSE; /* check parameters */ if (hostent == NULL || *hostent != NULL || hostname_unresolved == NULL) { CL_LOG( CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_PARAMS)); return CL_RETVAL_PARAMS; /* we don't accept NULL pointers */ } /* check if the incoming hostname is an ip address string */ if (cl_com_is_ip_address_string(hostname_unresolved, &tmp_addr) == CL_TRUE) { cl_com_hostent_t* tmp_hostent = NULL; CL_LOG(CL_LOG_INFO,"got ip address string as host name argument"); ret_val = cl_com_gethostbyaddr(&tmp_addr, &tmp_hostent, NULL); if (ret_val == CL_RETVAL_OK) { hostname = strdup(tmp_hostent->he->h_name); cl_com_free_hostent(&tmp_hostent); if (hostname == NULL) { ret_val = CL_RETVAL_MALLOC; } } if (ret_val != CL_RETVAL_OK) { if (hostname != NULL) { free(hostname); hostname = NULL; } return ret_val; } do_free_host = CL_TRUE; CL_LOG_STR(CL_LOG_INFO,"ip address string :", hostname_unresolved); CL_LOG_STR(CL_LOG_INFO,"resulting host name:", hostname); } else { hostname = (char *)hostname_unresolved; } /* was there a malloc() error */ if (hostname == NULL) { return CL_RETVAL_MALLOC; } /* get memory for cl_com_hostent_t struct */ hostent_p = (cl_com_hostent_t*)malloc(sizeof(cl_com_hostent_t)); if (hostent_p == NULL) { CL_LOG(CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_MALLOC)); if (do_free_host == CL_TRUE) { free(hostname); hostname = NULL; } return CL_RETVAL_MALLOC; /* could not get memory */ } hostent_p->he = NULL; /* use sge_gethostbyname() */ he = sge_gethostbyname(hostname, system_error); if (he == NULL) { CL_LOG( CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_UNKOWN_HOST_ERROR)); cl_com_free_hostent(&hostent_p); /* could not find host */ if (do_free_host == CL_TRUE) { free(hostname); hostname = NULL; } return CL_RETVAL_UNKOWN_HOST_ERROR; } else { hostent_p->he = he; } if (hostent_p->he->h_addr == NULL) { cl_com_free_hostent(&hostent_p); if (do_free_host == CL_TRUE) { free(hostname); hostname = NULL; } return CL_RETVAL_IP_NOT_RESOLVED_ERROR; } *hostent = hostent_p; #if CL_DO_COMMUNICATION_DEBUG cl_com_print_host_info(hostent_p); #endif if (do_free_host == CL_TRUE) { free(hostname); hostname = NULL; } return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_gethostbyaddr()" static int cl_com_gethostbyaddr(struct in_addr *addr, cl_com_hostent_t **hostent, int* system_error_retval) { struct hostent *he = NULL; cl_com_hostent_t *hostent_p = NULL; /* check parameters */ if (hostent == NULL || *hostent != NULL || addr == NULL) { CL_LOG( CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_PARAMS)); return CL_RETVAL_PARAMS; /* we don't accept NULL pointers */ } /* get memory for cl_com_hostent_t struct */ hostent_p = (cl_com_hostent_t*)malloc(sizeof(cl_com_hostent_t)); if (hostent_p == NULL) { CL_LOG(CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_MALLOC)); return CL_RETVAL_MALLOC; /* could not get memory */ } hostent_p->he = NULL; he = sge_gethostbyaddr(addr, system_error_retval); if (he == NULL) { CL_LOG( CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_UNKOWN_HOST_ERROR)); cl_com_free_hostent(&hostent_p); /* could not find host */ return CL_RETVAL_UNKOWN_HOST_ERROR; } else { hostent_p->he = he; } if (hostent_p->he->h_addr == NULL) { cl_com_free_hostent(&hostent_p); return CL_RETVAL_IP_NOT_RESOLVED_ERROR; } *hostent = hostent_p; #if CL_DO_COMMUNICATION_DEBUG cl_com_print_host_info(hostent_p); #endif return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_dup_host()" static int cl_com_dup_host(char** host_dest, const char* source, cl_host_resolve_method_t method, const char* domain) { int retval = CL_RETVAL_OK; cl_bool_t is_static_buffer = CL_FALSE; char* the_dot = NULL; if (host_dest == NULL || source == NULL) { return CL_RETVAL_PARAMS; } if (*host_dest != NULL) { is_static_buffer = CL_TRUE; } switch(method) { case CL_SHORT: if ((the_dot = strchr(source, '.')) != NULL) { int size = the_dot - source; if (is_static_buffer == CL_FALSE) { *host_dest = malloc(sizeof(char) * (size + 1)); } *host_dest = strncpy(*host_dest, source, size); (*host_dest)[size] = '\0'; } else { if (is_static_buffer == CL_FALSE) { *host_dest = strdup(source); } else { *host_dest = strcpy(*host_dest, source); } } retval = CL_RETVAL_OK; break; case CL_LONG: { unsigned long hostlen = strlen(source); the_dot = strchr(source, '.'); if (the_dot == NULL) { if (domain == NULL) { CL_LOG(CL_LOG_ERROR,"can't dup host with domain name without default domain"); /* error copy host without domain name , host is short */ if (is_static_buffer == CL_FALSE) { *host_dest = (char*) malloc( sizeof(char) * (hostlen + 1) ); if (*host_dest == NULL) { return CL_RETVAL_MALLOC; } } *host_dest = strncpy(*host_dest, source, hostlen); (*host_dest)[hostlen] = '\0'; } else { /* length = hostlength + domainlength + '.' */ unsigned long length = hostlen + strlen(domain) + 1; unsigned long domain_counter = 0; unsigned long counter = 0; /* we have a short hostname, add the default domain */ if (is_static_buffer == CL_FALSE) { *host_dest = (char*) malloc( sizeof(char) * ( length + 1) ); if (*host_dest == NULL) { return CL_RETVAL_MALLOC; } } for (counter = 0; counter < hostlen ; counter++) { (*host_dest)[counter] = source[counter]; } (*host_dest)[hostlen]='.'; for (counter = hostlen+1; counter < length ; counter++) { (*host_dest)[counter] = domain[domain_counter++]; } (*host_dest)[length]=0; } } else { /* we have a long hostname, return original name */ if (is_static_buffer == CL_FALSE) { *host_dest = (char*) malloc( sizeof(char) * (hostlen + 1)); if (*host_dest == NULL) { return CL_RETVAL_MALLOC; } } *host_dest = strncpy(*host_dest, source, hostlen); (*host_dest)[hostlen] = '\0'; } retval = CL_RETVAL_OK; } break; default: CL_LOG(CL_LOG_ERROR,"unexpected hostname resolve method"); retval = CL_RETVAL_UNKNOWN; break; } return retval; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_set_resolve_method()" int cl_com_set_resolve_method(cl_host_resolve_method_t method, char* local_domain_name) { cl_raw_list_t* host_list = NULL; cl_host_list_data_t* host_list_data = NULL; if (local_domain_name == NULL && method == CL_LONG) { CL_LOG(CL_LOG_WARNING,"can't compare short host names without default domain when method is CL_LONG"); } host_list = cl_com_get_host_list(); if (host_list == NULL) { CL_LOG(CL_LOG_WARNING,"communication library setup error"); return CL_RETVAL_PARAMS; } cl_raw_list_lock(host_list); host_list_data = cl_host_list_get_data(host_list); if (host_list_data == NULL) { CL_LOG(CL_LOG_ERROR,"communication library setup error for hostlist"); cl_raw_list_unlock(host_list); return CL_RETVAL_RESOLVING_SETUP_ERROR; } if (local_domain_name != NULL) { char* new_domain = strdup(local_domain_name); if (new_domain == NULL) { cl_raw_list_unlock(host_list); return CL_RETVAL_MALLOC; } /* free old local domain */ if (host_list_data->local_domain_name != NULL) { free(host_list_data->local_domain_name); } host_list_data->local_domain_name = new_domain; } else { /* free old local domain */ if (host_list_data->local_domain_name != NULL) { free(host_list_data->local_domain_name); host_list_data->local_domain_name = NULL; } } if (host_list_data->local_domain_name != NULL) { CL_LOG_STR(CL_LOG_INFO,"using local domain name:", host_list_data->local_domain_name); } else { CL_LOG(CL_LOG_INFO,"no local domain specified"); } host_list_data->resolve_method = method; switch(host_list_data->resolve_method) { case CL_SHORT: CL_LOG(CL_LOG_INFO,"using short hostname for host compare operations"); break; case CL_LONG: CL_LOG(CL_LOG_INFO,"using long hostname for host compare operations"); break; default: CL_LOG(CL_LOG_ERROR,"undefined resolving method"); break; } cl_raw_list_unlock(host_list); return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_compare_hosts()" int cl_com_compare_hosts(const char* host1, const char* host2) { #define CL_COM_COMPARE_HOSTS_STATIC_BUFFER_SIZE 512 int retval = CL_RETVAL_UNKNOWN; char* malloc_hostbuf1 = NULL; char* malloc_hostbuf2 = NULL; char* hostbuf1 = NULL; char* hostbuf2 = NULL; cl_raw_list_t* host_list = NULL; cl_host_list_data_t* host_list_data = NULL; cl_host_resolve_method_t resolve_method; char* local_domain_name = NULL; int domain_length = 0; char fixed_host_buffer1[CL_COM_COMPARE_HOSTS_STATIC_BUFFER_SIZE]; char fixed_host_buffer2[CL_COM_COMPARE_HOSTS_STATIC_BUFFER_SIZE]; if (host1 == NULL || host2 == NULL) { return CL_RETVAL_PARAMS; } host_list = cl_com_get_host_list(); if (host_list == NULL) { CL_LOG(CL_LOG_WARNING,"communication library setup error, just do strcasecmp()"); if ( strcasecmp(host1,host2) == 0 ) { return CL_RETVAL_OK; } else { return CL_RETVAL_UNKNOWN; } } cl_raw_list_lock(host_list); host_list_data = cl_host_list_get_data(host_list); if (host_list_data == NULL) { cl_raw_list_unlock(host_list); CL_LOG(CL_LOG_ERROR,"communication library setup error for hostlist"); return CL_RETVAL_RESOLVING_SETUP_ERROR; } resolve_method = host_list_data->resolve_method; if (host_list_data->local_domain_name != NULL) { local_domain_name = strdup(host_list_data->local_domain_name); if (local_domain_name == NULL) { cl_raw_list_unlock(host_list); return CL_RETVAL_MALLOC; } domain_length = strlen(local_domain_name); } cl_raw_list_unlock(host_list); if (domain_length + strlen(host1) + 2 < CL_COM_COMPARE_HOSTS_STATIC_BUFFER_SIZE) { malloc_hostbuf1 = fixed_host_buffer1; if ( (retval = cl_com_dup_host(&malloc_hostbuf1, host1, resolve_method, local_domain_name)) != CL_RETVAL_OK) { free(local_domain_name); return retval; } malloc_hostbuf1 = NULL; hostbuf1 = fixed_host_buffer1; } else { if ( (retval = cl_com_dup_host(&malloc_hostbuf1, host1, resolve_method, local_domain_name)) != CL_RETVAL_OK) { free(local_domain_name); return retval; } hostbuf1 = malloc_hostbuf1; } if (domain_length + strlen(host2) + 2 < CL_COM_COMPARE_HOSTS_STATIC_BUFFER_SIZE) { malloc_hostbuf2 = fixed_host_buffer2; if ( ( retval = cl_com_dup_host(&malloc_hostbuf2, host2, resolve_method, local_domain_name)) != CL_RETVAL_OK) { if (malloc_hostbuf1) { free(malloc_hostbuf1); malloc_hostbuf1 = NULL; } free(local_domain_name); return retval; } malloc_hostbuf2 = NULL; hostbuf2 = fixed_host_buffer2; } else { if ( ( retval = cl_com_dup_host(&malloc_hostbuf2, host2, resolve_method, local_domain_name)) != CL_RETVAL_OK) { if (malloc_hostbuf1) { free(malloc_hostbuf1); malloc_hostbuf1 = NULL; } free(local_domain_name); return retval; } hostbuf2 = malloc_hostbuf2; } if (local_domain_name) { free(local_domain_name); local_domain_name = NULL; } #if CL_DO_COMMUNICATION_DEBUG CL_LOG_STR(CL_LOG_DEBUG,"compareing host 1:", hostbuf1); CL_LOG_STR(CL_LOG_DEBUG,"compareing host 2:", hostbuf2); #endif if ( strcasecmp(hostbuf1,hostbuf2) == 0 ) { /* hostname compare OK */ #if CL_DO_COMMUNICATION_DEBUG CL_LOG(CL_LOG_DEBUG,"hosts are equal"); #endif retval = CL_RETVAL_OK; } else { #if CL_DO_COMMUNICATION_DEBUG CL_LOG(CL_LOG_DEBUG,"hosts are NOT equal"); #endif retval = CL_RETVAL_UNKNOWN; } if (malloc_hostbuf1) { free(malloc_hostbuf1); } if (malloc_hostbuf2) { free(malloc_hostbuf2); } return retval; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_is_ip_address_string()" static cl_bool_t cl_com_is_ip_address_string(const char* resolve_hostname, struct in_addr* addr) { if (resolve_hostname == NULL || addr == NULL) { CL_LOG(CL_LOG_ERROR,"got NULL pointer for hostname parameter"); return CL_FALSE; } addr->s_addr = inet_addr(resolve_hostname); if (addr->s_addr == -1) { int v1 = 0; int v2 = 0; int v3 = 0; int v4 = 0; /* check if it is not the host address 255.255.255.255 */ sscanf(resolve_hostname, "%d.%d.%d.%d", &v1, &v2, &v3, &v4); if (v1 == 255 && v2 == 255 && v3 == 255 && v4 == 255) { CL_LOG(CL_LOG_WARNING,"got ip address 255.255.255.255 as host name!"); return CL_TRUE; } return CL_FALSE; } return CL_TRUE; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_cached_gethostbyname()" int cl_com_cached_gethostbyname(const char *unresolved_host, char **unique_hostname, struct in_addr *copy_addr, struct hostent **he_copy, int* system_error_value) { cl_host_list_elem_t* elem = NULL; cl_com_host_spec_t* elem_host = NULL; cl_host_list_data_t* ldata = NULL; cl_raw_list_t* hostlist = NULL; int function_return = CL_RETVAL_GETHOSTNAME_ERROR; int ret_val = CL_RETVAL_OK; char* alias_name = NULL; char* help = NULL; if (unresolved_host == NULL || unique_hostname == NULL || *unique_hostname != NULL) { CL_LOG(CL_LOG_ERROR,cl_get_error_text(CL_RETVAL_PARAMS)); return CL_RETVAL_PARAMS; } if (he_copy != NULL && *he_copy != NULL) { return CL_RETVAL_PARAMS; } /* If the host name is set in SGE_COMMLIB_DEBUG_NO_RESOLVE, fail. */ if ((help=cl_com_get_unresolvable_hosts()) != NULL) { if (strstr(help, unresolved_host) != NULL) { CL_LOG_STR(CL_LOG_WARNING, "host is in not resolvable host list:", unresolved_host); return CL_RETVAL_GETHOSTNAME_ERROR; } } /* If the host name is set in SGE_COMMLIB_DEBUG_RESOLVE, use the hostname as * the unique hostname and return success. */ if ((help=cl_com_get_resolvable_hosts()) != NULL) { if (strstr(help, unresolved_host) != NULL) { CL_LOG_STR(CL_LOG_WARNING, "host is in only resolvable host list:", unresolved_host); *unique_hostname = strdup(unresolved_host); if (*unique_hostname == NULL) { return CL_RETVAL_MALLOC; } /* Problem: * * copy_addr and he_copy will NOT contain any information * ====================================================== * * Reason: Can't assume any IP addr or alias names */ return CL_RETVAL_OK; } } hostlist = cl_com_get_host_list(); if (hostlist == NULL) { cl_com_hostent_t* myhostent = NULL; int retval; CL_LOG(CL_LOG_ERROR,"no global hostlist, resolving without cache"); retval = cl_com_gethostbyname(unresolved_host, &myhostent, system_error_value); if (retval != CL_RETVAL_OK) { cl_com_free_hostent(&myhostent); return retval; } *unique_hostname = strdup(myhostent->he->h_name); if (*unique_hostname == NULL) { cl_com_free_hostent(&myhostent); return CL_RETVAL_MALLOC; } if (copy_addr != NULL) { memcpy((char*) copy_addr, myhostent->he->h_addr, sizeof(struct in_addr)); } if (he_copy != NULL) { *he_copy = sge_copy_hostent(myhostent->he); } cl_com_free_hostent(&myhostent); return CL_RETVAL_OK; } if (hostlist->list_data == NULL) { CL_LOG( CL_LOG_ERROR, "hostlist not initalized"); return CL_RETVAL_PARAMS; } ldata = (cl_host_list_data_t*) hostlist->list_data; if (cl_commlib_get_thread_state() == CL_NO_THREAD || ldata->alias_file_changed != 0) { cl_com_host_list_refresh(hostlist); } #if 0 /* CR: * * enable this code for 1:1 mapping or for virtual host mapping * (e.g. my_virtual_hostname real_host_name in alias file ) * * DO NOT FORGET TO ALSO ENABLE CODE IN cl_host_alias_list_append_host() */ if ( cl_host_alias_list_get_local_resolved_name(ldata->host_alias_list,unresolved_host, &alias_name) == CL_RETVAL_OK) { CL_LOG_STR(CL_LOG_INFO,"unresolved host name is aliased to", alias_name); } #endif /* Try to find unresolved hostname in hostlist */ cl_raw_list_lock(hostlist); elem = cl_host_list_get_elem_host(hostlist, unresolved_host); if (elem == NULL && alias_name != NULL) { elem = cl_host_list_get_elem_host(hostlist, alias_name); } if (elem != NULL) { elem_host = elem->host_spec; if (alias_name != NULL) { free(alias_name); alias_name = NULL; } #if CL_DO_COMMUNICATION_DEBUG CL_LOG_STR(CL_LOG_DEBUG,"found host in cache, unresolved name:", unresolved_host ); #endif if (elem_host->resolved_name == NULL) { cl_raw_list_unlock(hostlist); return CL_RETVAL_GETHOSTNAME_ERROR; } if (copy_addr != NULL && elem_host->hostent != NULL) { memcpy((char*) copy_addr, elem_host->hostent->he->h_addr, sizeof(struct in_addr)); } *unique_hostname = strdup(elem_host->resolved_name); if (he_copy != NULL && elem_host->hostent != NULL ) { *he_copy = sge_copy_hostent(elem_host->hostent->he); } cl_raw_list_unlock(hostlist); if (*unique_hostname == NULL) { return CL_RETVAL_MALLOC; } } else { /* resolve the host and add the host to cache */ int retval = CL_RETVAL_OK; struct timeval now; cl_com_hostent_t* hostent = NULL; cl_com_host_spec_t* hostspec = NULL; if (alias_name == NULL) { CL_LOG_STR(CL_LOG_INFO,"NOT found in cache, unresolved name:", unresolved_host); } else { CL_LOG_STR(CL_LOG_INFO,"NOT found in cache, aliased name:", alias_name); } cl_raw_list_unlock(hostlist); hostspec = (cl_com_host_spec_t*) malloc( sizeof(cl_com_host_spec_t)); if (hostspec == NULL) { return CL_RETVAL_MALLOC; } hostspec->in_addr = NULL; hostspec->resolved_name = NULL; if (alias_name == NULL) { hostspec->unresolved_name = strdup(unresolved_host); } else { hostspec->unresolved_name = alias_name; /* to not free alias_name !!! */ alias_name = NULL; } if (hostspec->unresolved_name == NULL) { cl_com_free_hostspec(&hostspec); return CL_RETVAL_MALLOC; } retval = cl_com_gethostbyname(hostspec->unresolved_name, &hostent, system_error_value); hostspec->hostent = hostent; hostspec->resolve_error = retval; gettimeofday(&now,NULL); hostspec->last_resolve_time = now.tv_sec; hostspec->creation_time = now.tv_sec; if (hostspec->hostent != NULL) { hostspec->resolved_name = NULL; hostspec->resolved_name = strdup(hostspec->hostent->he->h_name); if (hostspec->resolved_name == NULL) { cl_com_free_hostspec(&hostspec); return CL_RETVAL_MALLOC; } hostspec->in_addr = (struct in_addr*) malloc (sizeof(struct in_addr)); if (hostspec->in_addr == NULL) { cl_com_free_hostspec(&hostspec); return CL_RETVAL_MALLOC; } memcpy(hostspec->in_addr,hostspec->hostent->he->h_addr,sizeof(struct in_addr) ); } else { hostspec->resolved_name = NULL; } cl_raw_list_lock(hostlist); function_return = cl_host_list_append_host(hostlist, hostspec, 0); if (function_return != CL_RETVAL_OK) { cl_raw_list_unlock(hostlist); cl_com_free_hostspec(&hostspec); return function_return; } if (hostspec->resolved_name == NULL) { cl_raw_list_unlock(hostlist); return CL_RETVAL_GETHOSTNAME_ERROR; } if (copy_addr != NULL) { memcpy((char*) copy_addr, hostspec->hostent->he->h_addr, sizeof(struct in_addr) ); } *unique_hostname = strdup(hostspec->resolved_name); if (he_copy != NULL && hostspec->hostent->he != NULL) { *he_copy = sge_copy_hostent(hostspec->hostent->he); } cl_raw_list_unlock(hostlist); if (*unique_hostname == NULL) { return CL_RETVAL_MALLOC; } } #if CL_DO_COMMUNICATION_DEBUG CL_LOG_STR(CL_LOG_DEBUG,"resolved name:", *unique_hostname ); #endif ret_val = cl_host_alias_list_get_alias_name(ldata->host_alias_list, *unique_hostname, &alias_name); if (ret_val == CL_RETVAL_OK) { #if CL_DO_COMMUNICATION_DEBUG CL_LOG_STR(CL_LOG_DEBUG,"resolved name aliased to", alias_name); #endif free(*unique_hostname); *unique_hostname = alias_name; } return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_read_alias_file()" /* hostlist must be locked */ int cl_com_read_alias_file(cl_raw_list_t* hostlist) { cl_host_list_data_t* ldata = NULL; SGE_STRUCT_STAT sb; FILE *fp; char alias_file_buffer[LINE_MAX*4]; int max_line = LINE_MAX*4; char* alias_delemiters="\n\t ,;"; char printbuf[ (2*CL_MAXHOSTLEN) + 100 ]; if (hostlist == NULL) { return CL_RETVAL_PARAMS; } if (hostlist->list_data == NULL) { CL_LOG( CL_LOG_ERROR, "hostlist not initalized"); return CL_RETVAL_PARAMS; } ldata = (cl_host_list_data_t*) hostlist->list_data; ldata->alias_file_changed = 0; if (ldata->host_alias_file == NULL) { CL_LOG(CL_LOG_ERROR,"host alias file is not specified"); return CL_RETVAL_NO_ALIAS_FILE; } if (SGE_STAT(ldata->host_alias_file, &sb)) { CL_LOG(CL_LOG_WARNING,"host alias file is not existing"); return CL_RETVAL_ALIAS_FILE_NOT_FOUND; } fp = fopen(ldata->host_alias_file, "r"); if (!fp) { CL_LOG(CL_LOG_ERROR,"can't open host alias file"); return CL_RETVAL_OPEN_ALIAS_FILE_FAILED; } CL_LOG_INT(CL_LOG_INFO,"max. supported line length:", max_line ); while (fgets(alias_file_buffer, sizeof(alias_file_buffer), fp)) { char* help = NULL; char *lasts = NULL; char* main_name = NULL; help = strrchr(alias_file_buffer,'\r'); if (help != NULL) { help[0] = '\0'; } help = strrchr(alias_file_buffer,'\n'); if (help != NULL) { help[0] = '\0'; } if (alias_file_buffer[0] == '#') { CL_LOG_STR(CL_LOG_INFO,"ignoring comment:",alias_file_buffer ); continue; } CL_LOG_STR(CL_LOG_INFO,"line:",alias_file_buffer); help = strtok_r(alias_file_buffer,alias_delemiters,&lasts); if (help != NULL) { cl_com_hostent_t* he = NULL; if ( cl_com_gethostbyname(help, &he, NULL) == CL_RETVAL_OK) { main_name = strdup(help); /* he->he->h_name */ cl_com_free_hostent(&he); if (main_name == NULL) { CL_LOG(CL_LOG_ERROR,"malloc() error"); /* Don't check close state, we already have a malloc() error */ fclose(fp); return CL_RETVAL_MALLOC; } } else { CL_LOG_STR(CL_LOG_ERROR,"mainname in alias file is not resolveable:", help); continue; } while ( cl_com_remove_host_alias(main_name) == CL_RETVAL_OK); while( (help = strtok_r(NULL,alias_delemiters,&lasts)) != NULL ) { int retval = cl_com_append_host_alias(help, main_name); if (retval == CL_RETVAL_OK) { snprintf(printbuf, sizeof(printbuf), "\"%s\" aliased to \"%s\"", help,main_name); CL_LOG(CL_LOG_INFO,printbuf); } } free(main_name); main_name = NULL; } } if ( fclose(fp) != 0) { return CL_RETVAL_CLOSE_ALIAS_FILE_FAILED; } return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_host_list_refresh()" int cl_com_host_list_refresh(cl_raw_list_t* list_p) { struct timeval now; cl_host_list_elem_t* elem = NULL; cl_host_list_elem_t* act_elem = NULL; cl_host_list_data_t* ldata = NULL; int resolve_host = 0; int ret_val = CL_RETVAL_OK; cl_com_host_spec_t* elem_host = NULL; if (list_p == NULL) { return CL_RETVAL_PARAMS; } gettimeofday(&now,NULL); cl_raw_list_lock(list_p); if (list_p->list_data == NULL) { cl_raw_list_unlock(list_p); CL_LOG( CL_LOG_ERROR, "hostlist not initalized"); return CL_RETVAL_PARAMS; } ldata = (cl_host_list_data_t*) list_p->list_data; if (ldata->alias_file_changed != 0) { CL_LOG(CL_LOG_INFO,"host alias file dirty flag is set"); cl_com_read_alias_file(list_p); if (list_p->list_data == NULL) { cl_raw_list_unlock(list_p); CL_LOG( CL_LOG_ERROR, "hostlist not initalized"); return CL_RETVAL_PARAMS; } ldata = (cl_host_list_data_t*) list_p->list_data; } if (now.tv_sec == ldata->last_refresh_time) { cl_raw_list_unlock(list_p); return CL_RETVAL_OK; } ldata->last_refresh_time = now.tv_sec; CL_LOG(CL_LOG_INFO,"checking host entries"); CL_LOG_INT(CL_LOG_INFO,"number of cached host entries:", (int)cl_raw_list_get_elem_count(list_p)); elem = cl_host_list_get_first_elem(list_p); while(elem != NULL) { act_elem = elem; elem = cl_host_list_get_next_elem(elem); elem_host = act_elem->host_spec; if (elem_host->creation_time + ldata->entry_life_time < now.tv_sec ) { /* max entry life time reached, remove entry */ if (elem_host->unresolved_name != NULL) { CL_LOG_STR(CL_LOG_WARNING,"entry life timeout for elem:", elem_host->unresolved_name); if (ldata->ht != NULL) { sge_htable_delete(ldata->ht, elem_host->unresolved_name); } } else { CL_LOG(CL_LOG_WARNING,"entry life timeout for addr"); } cl_raw_list_remove_elem(list_p, act_elem->raw_elem); /* remove element from hash table */ cl_com_free_hostspec(&elem_host); free(act_elem); act_elem = NULL; continue; /* removed entry, continue with next */ } if (resolve_host != 0) { /* we already know that we have to resolve at least one host */ continue; } if (elem_host->last_resolve_time + ldata->entry_update_time < now.tv_sec) { /* max update timeout is reached, resolving entry */ if (elem_host->unresolved_name != NULL) { CL_LOG_STR(CL_LOG_WARNING,"update timeout for elem:", elem_host->unresolved_name); } else { CL_LOG(CL_LOG_WARNING,"update timeout for addr"); } resolve_host = 1; } if (elem_host->resolve_error != CL_RETVAL_OK) { /* this is only for hosts with error state */ if (elem_host->last_resolve_time + ldata->entry_reresolve_time < now.tv_sec) { if (elem_host->unresolved_name != NULL) { CL_LOG_STR(CL_LOG_WARNING,"reresolve timeout for elem:", elem_host->unresolved_name); } else { CL_LOG(CL_LOG_WARNING,"reresolve timeout for addr"); } resolve_host = 1; } } } cl_raw_list_unlock(list_p); if (resolve_host != 0) { cl_raw_list_t* host_list_copy = NULL; /* we have to resolve at least one host in this list. Make a copy of this list and resolve it, because we don't want to lock the list when hosts are resolved */ CL_LOG(CL_LOG_WARNING,"do a list copy"); ret_val = cl_host_list_copy(&host_list_copy, list_p, CL_FALSE); if (ret_val == CL_RETVAL_OK ) { cl_host_list_elem_t* act_elem = NULL; cl_host_list_data_t* dummy_list_data_source = NULL; cl_raw_list_t* dummy_list_copy = NULL; elem = cl_host_list_get_first_elem(host_list_copy); while(elem != NULL) { act_elem = elem; elem = cl_host_list_get_next_elem(elem); elem_host = act_elem->host_spec; if (elem_host->last_resolve_time + ldata->entry_update_time < now.tv_sec || elem_host->resolve_error != CL_RETVAL_OK) { int resolve_error = CL_RETVAL_OK; cl_com_hostent_t* hostent = NULL; if (elem_host->unresolved_name != NULL) { CL_LOG_STR(CL_LOG_INFO,"resolving host:", elem_host->unresolved_name); resolve_error = cl_com_gethostbyname(elem_host->unresolved_name, &hostent, NULL); } else { CL_LOG(CL_LOG_INFO,"resolving addr"); resolve_error = cl_com_gethostbyaddr(elem_host->in_addr, &hostent, NULL); } /* free old entries */ cl_com_free_hostent(&(elem_host->hostent)); free(elem_host->resolved_name); elem_host->resolved_name = NULL; elem_host->hostent = hostent; elem_host->resolve_error = resolve_error; elem_host->last_resolve_time = now.tv_sec; if (elem_host->hostent != NULL) { elem_host->resolved_name = strdup(elem_host->hostent->he->h_name); if (elem_host->resolved_name == NULL) { cl_raw_list_remove_elem(host_list_copy, act_elem->raw_elem); cl_com_free_hostspec(&elem_host); free(act_elem); CL_LOG(CL_LOG_ERROR,"malloc() error"); continue; } CL_LOG_STR(CL_LOG_WARNING,"host resolved as:", elem_host->resolved_name); } } } /* now we have a up-to-date copy of the original host list */ cl_raw_list_lock(list_p); dummy_list_data_source = list_p->list_data; cl_host_list_setup(&dummy_list_copy, list_p->list_name, dummy_list_data_source->resolve_method, dummy_list_data_source->host_alias_file, dummy_list_data_source->local_domain_name, dummy_list_data_source->entry_life_time, dummy_list_data_source->entry_update_time, dummy_list_data_source->entry_reresolve_time, CL_FALSE); /* first remove all entries from original list */ while((elem = cl_host_list_get_first_elem(list_p)) ) { elem_host = elem->host_spec; cl_raw_list_dechain_elem(list_p, elem->raw_elem); /* remove element from hash table */ if (elem_host->unresolved_name != NULL) { if (ldata->ht != NULL) { sge_htable_delete(ldata->ht, elem_host->unresolved_name); } } cl_raw_list_append_dechained_elem(dummy_list_copy, elem->raw_elem); } /* now dechain elements from copied list into original list */ while((elem = cl_host_list_get_first_elem(host_list_copy)) ) { elem_host = elem->host_spec; cl_raw_list_dechain_elem(host_list_copy, elem->raw_elem); if (elem_host->unresolved_name != NULL) { if (ldata->ht != NULL) { sge_htable_store(ldata->ht, elem_host->unresolved_name, elem); } } cl_raw_list_append_dechained_elem(list_p, elem->raw_elem); } cl_raw_list_unlock(list_p); CL_LOG(CL_LOG_WARNING,"free list copy"); cl_host_list_cleanup(&dummy_list_copy); ret_val = cl_host_list_cleanup(&host_list_copy); } } return ret_val; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_endpoint_list_refresh()" int cl_com_endpoint_list_refresh(cl_raw_list_t* list_p) { struct timeval now; cl_endpoint_list_elem_t* act_elem = NULL; cl_endpoint_list_elem_t* elem = NULL; cl_endpoint_list_data_t* ldata = NULL; if (list_p == NULL || list_p->list_data == NULL) { return CL_RETVAL_PARAMS; } ldata = (cl_endpoint_list_data_t*) list_p->list_data; gettimeofday(&now,NULL); if (now.tv_sec < ldata->refresh_interval + ldata->last_refresh_time) { return CL_RETVAL_OK; } ldata->last_refresh_time = now.tv_sec; CL_LOG_INT(CL_LOG_INFO, "number of endpoint entries:",(int)cl_raw_list_get_elem_count(list_p)); cl_raw_list_lock(list_p); elem = cl_endpoint_list_get_first_elem(list_p); while(elem != NULL) { act_elem = elem; elem = cl_endpoint_list_get_next_elem(elem); /* static elements aren't removed */ if (act_elem->is_static == 0) { if (act_elem->last_used + ldata->entry_life_time < now.tv_sec ) { CL_LOG_STR(CL_LOG_INFO,"removing non static element (life timeout) with comp host:", act_elem->endpoint->comp_host); cl_raw_list_remove_elem(list_p, act_elem->raw_elem); if (ldata->ht != NULL && act_elem->endpoint != NULL && act_elem->endpoint->hash_id != NULL) { sge_htable_delete(ldata->ht, act_elem->endpoint->hash_id); } cl_com_free_endpoint(&(act_elem->endpoint)); free(act_elem); act_elem = NULL; continue; } } else { CL_LOG_STR(CL_LOG_INFO,"ignoring static element with comp host:", act_elem->endpoint->comp_host); } } cl_raw_list_unlock(list_p); return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_get_ip_string()" static int cl_com_get_ip_string(struct in_addr *addr, char **ipstr) { char tmp_buffer[256]; unsigned long ip,A,B,C,D; /* * This function is NOT using inet_ntoa() because on some platforms this * function is NOT threadsave. * * WARNING: Currently only used for error case. Might be not performant for general * use! */ if (addr == NULL || ipstr == NULL) { CL_LOG(CL_LOG_ERROR, "one of the parameters is NULL"); return CL_RETVAL_PARAMS; } if (*ipstr != NULL) { CL_LOG(CL_LOG_ERROR, "*ipstr must be NULL"); return CL_RETVAL_PARAMS; } ip = (unsigned long) ntohl(addr->s_addr); A = ip / (256*256*256); B = (ip - (A * 256*256*256)) / (256 * 256); C = (ip - (A * 256*256*256) - (B*256*256)) / 256; D = ip - (A * 256*256*256) - (B*256*256) - (C*256); snprintf(tmp_buffer, 256, "%ld.%ld.%ld.%ld", A, B, C, D); *ipstr = strdup(tmp_buffer); if (*ipstr == NULL) { return CL_RETVAL_MALLOC; } return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_cached_gethostbyaddr()" int cl_com_cached_gethostbyaddr(struct in_addr *addr, char **unique_hostname, struct hostent **he_copy, int* system_error_val) { cl_host_list_elem_t* elem = NULL; cl_com_host_spec_t* elem_host = NULL; cl_host_list_data_t* ldata = NULL; cl_raw_list_t* hostlist = NULL; int ret_val = CL_RETVAL_OK; char* alias_name = NULL; int resolve_name_ok = 0; if (addr == NULL || unique_hostname == NULL || *unique_hostname != NULL) { CL_LOG( CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_PARAMS)); return CL_RETVAL_PARAMS; } if (he_copy != NULL && *he_copy != NULL) { return CL_RETVAL_PARAMS; } hostlist = cl_com_get_host_list(); if (hostlist == NULL) { int retval; cl_com_hostent_t* hostent = NULL; CL_LOG(CL_LOG_WARNING,"no global hostlist, resolving without cache"); retval = cl_com_gethostbyaddr(addr, &hostent, system_error_val); if (retval != CL_RETVAL_OK) { cl_com_free_hostent(&hostent); return retval; } *unique_hostname = strdup(hostent->he->h_name); if (he_copy != NULL) { *he_copy = sge_copy_hostent(hostent->he); } if (*unique_hostname == NULL) { cl_com_free_hostent(&hostent); return CL_RETVAL_MALLOC; } cl_com_free_hostent(&hostent); return CL_RETVAL_OK; } if (hostlist->list_data == NULL) { CL_LOG( CL_LOG_ERROR, "hostlist not initalized"); return CL_RETVAL_PARAMS; } ldata = (cl_host_list_data_t*) hostlist->list_data; if (cl_commlib_get_thread_state() == CL_NO_THREAD || ldata->alias_file_changed != 0) { cl_com_host_list_refresh(hostlist); } cl_raw_list_lock(hostlist); elem = cl_host_list_get_first_elem(hostlist); while(elem != NULL) { elem_host = elem->host_spec; /* do we have an unresolved name for this host ? */ if (elem_host->in_addr != NULL) { if (memcmp(elem_host->in_addr , addr ,sizeof(struct in_addr)) == 0) { break; /* found addr in cache */ } } elem_host = NULL; elem = cl_host_list_get_next_elem(elem); } if (elem_host != NULL) { if (elem_host->resolved_name == NULL) { CL_LOG(CL_LOG_INFO,"found addr in cache - not resolveable"); cl_raw_list_unlock(hostlist); return CL_RETVAL_GETHOSTADDR_ERROR; } #if CL_DO_COMMUNICATION_DEBUG CL_LOG_STR(CL_LOG_INFO,"found addr in cache, resolved name:",elem_host->resolved_name); #endif *unique_hostname = strdup(elem_host->resolved_name); if (he_copy != NULL && elem_host->hostent != NULL) { *he_copy = sge_copy_hostent(elem_host->hostent->he); } cl_raw_list_unlock(hostlist); if (*unique_hostname == NULL) { return CL_RETVAL_MALLOC; } } else { /* resolve the host and add the host to cache */ struct timeval now; int retval = CL_RETVAL_OK; cl_com_hostent_t* hostent = NULL; cl_com_host_spec_t* hostspec = NULL; char* hostname = NULL; CL_LOG(CL_LOG_INFO,"addr NOT found in cache"); cl_raw_list_unlock(hostlist); hostspec = ( cl_com_host_spec_t*) malloc( sizeof(cl_com_host_spec_t) ); if (hostspec == NULL) { return CL_RETVAL_MALLOC; } hostspec->unresolved_name = NULL; hostspec->in_addr = (struct in_addr*) malloc (sizeof(struct in_addr)); if (hostspec->in_addr == NULL) { cl_com_free_hostspec(&hostspec); return CL_RETVAL_MALLOC; } memcpy(hostspec->in_addr,addr,sizeof(struct in_addr) ); /* resolve host with cl_com_gethostbyaddr() */ retval = cl_com_gethostbyaddr(addr, &hostent, system_error_val); hostspec->hostent = hostent; hostspec->resolve_error = retval; gettimeofday(&now,NULL); hostspec->last_resolve_time = now.tv_sec; hostspec->creation_time = now.tv_sec; hostspec->resolved_name = NULL; if (hostspec->hostent != NULL) { /* CHECK for correct resolving */ retval = cl_com_cached_gethostbyname(hostent->he->h_name, &hostname , NULL, he_copy, NULL); if (retval != CL_RETVAL_OK) { CL_LOG_STR(CL_LOG_WARNING,"can't resolve host name", hostent->he->h_name); hostspec->resolve_error = CL_RETVAL_GETHOSTADDR_ERROR; /* add dummy host entry */ cl_raw_list_lock(hostlist); retval = cl_host_list_append_host(hostlist, hostspec, 0); if (retval != CL_RETVAL_OK) { cl_raw_list_unlock(hostlist); cl_com_free_hostspec(&hostspec); return retval; } cl_raw_list_unlock(hostlist); return CL_RETVAL_GETHOSTADDR_ERROR; } resolve_name_ok = 1; ret_val = cl_host_alias_list_get_alias_name(ldata->host_alias_list,hostent->he->h_name , &alias_name); if (ret_val == CL_RETVAL_OK) { CL_LOG_STR(CL_LOG_INFO,"resolved addr name aliased to", alias_name); if (cl_com_compare_hosts(hostname, alias_name) != CL_RETVAL_OK) { resolve_name_ok = 0; } free(alias_name); alias_name = NULL; } else { if (cl_com_compare_hosts(hostname, hostent->he->h_name) != CL_RETVAL_OK && strcasecmp(hostent->he->h_name, "localhost") != 0 ) { resolve_name_ok = 0; } } /* if names are not equal -> report error */ if (resolve_name_ok != 1) { /* hostname compare OK ? */ /* create application error message */ char error_tmp_string[1024]; char* help = NULL; cl_com_get_ip_string(addr, &help); snprintf(error_tmp_string, 1024, MSG_CL_TCP_FW_ADDR_NAME_RESOLVE_HOST_ERROR_SSSS, help ? help : "(NULL)", hostent->he->h_name, hostname, hostent->he->h_name); if (help != NULL) { free(help); help = NULL; } cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_GETHOSTADDR_ERROR, error_tmp_string); hostspec->resolve_error = CL_RETVAL_GETHOSTADDR_ERROR; /* add dummy host entry */ cl_raw_list_lock(hostlist); retval = cl_host_list_append_host(hostlist, hostspec, 0); if (retval != CL_RETVAL_OK) { cl_raw_list_unlock(hostlist); cl_com_free_hostspec(&hostspec); return retval; } cl_raw_list_unlock(hostlist); return CL_RETVAL_GETHOSTADDR_ERROR; } /* if names are equal -> perfect ! , return resolved hostname */ *unique_hostname = hostname; } else { /* add dummy host entry */ cl_raw_list_lock(hostlist); retval = cl_host_list_append_host(hostlist, hostspec, 0); if (retval != CL_RETVAL_OK) { cl_raw_list_unlock(hostlist); cl_com_free_hostspec(&hostspec); return retval; } cl_raw_list_unlock(hostlist); return CL_RETVAL_GETHOSTADDR_ERROR; } cl_com_free_hostspec(&hostspec); } #if CL_DO_COMMUNICATION_DEBUG CL_LOG_STR(CL_LOG_DEBUG,"resolved name:", *unique_hostname ); #endif ret_val = cl_host_alias_list_get_alias_name(ldata->host_alias_list, *unique_hostname, &alias_name ); if (ret_val == CL_RETVAL_OK) { CL_LOG_STR(CL_LOG_DEBUG,"resolved name aliased to", alias_name); free(*unique_hostname); *unique_hostname = alias_name; } return CL_RETVAL_OK; } #if CL_DO_COMMUNICATION_DEBUG /* cl_com_print_host_info - log a hostent struct params: cl_com_hostent_t* hostent_p -> pointer to filled cl_com_hostent_t return: - int - CL_RETVAL_XXXX error number */ #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_print_host_info()" int cl_com_print_host_info(cl_com_hostent_t *hostent_p ) { char** tp = NULL; struct in_addr in; if (hostent_p == NULL) { CL_LOG(CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_PARAMS)); return CL_RETVAL_PARAMS; } if (hostent_p->he == NULL ) { CL_LOG(CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_PARAMS)); return CL_RETVAL_PARAMS; } if (hostent_p->he->h_addr == NULL || hostent_p->he->h_name == NULL || hostent_p->he->h_aliases == NULL || hostent_p->he->h_addr_list == NULL) { CL_LOG(CL_LOG_ERROR, cl_get_error_text(CL_RETVAL_PARAMS)); return CL_RETVAL_PARAMS; } memcpy(&in.s_addr,hostent_p->he->h_addr,sizeof (in.s_addr)); CL_LOG_STR( CL_LOG_INFO, "official name of host : ", hostent_p->he->h_name ); for (tp = hostent_p->he->h_aliases; *tp; tp++) { CL_LOG_STR( CL_LOG_INFO, "alias : ", *tp ); } return CL_RETVAL_OK; } #endif /****** cl_communication/cl_com_connection_request_handler_setup() ************* * NAME * cl_com_connection_request_handler_setup() -- Setup service * * SYNOPSIS * int cl_com_connection_request_handler_setup(cl_com_connection_t* * connection) * * FUNCTION * This function is used to setup a connection service handler. All service * specific setup is done here. When the setup was done the connection can * be used to call cl_com_connection_request_handler(). To shutdown the * service a call to cl_com_connection_request_handler_cleanup() must be done. * * This function is only a wrapper for the correct * cl_com_xxx_connection_request_handler_setup() function of the selected * framework. * * INPUTS * cl_com_connection_t* connection - pointer to a inizialized connection * * RESULT * int - CL_RETVAL_XXXX error or CL_RETVAL_OK on success * * SEE ALSO * cl_communication/cl_com_connection_request_handler_cleanup() * cl_communication/cl_com_connection_request_handler() *******************************************************************************/ #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_request_handler_setup()" int cl_com_connection_request_handler_setup(cl_com_connection_t* connection, cl_com_endpoint_t* local_endpoint) { int retval = CL_RETVAL_OK; cl_bool_t only_prepare_service = CL_FALSE; if (connection != NULL) { if (connection->local != NULL || connection->remote != NULL ) { CL_LOG(CL_LOG_ERROR,"no free connection"); return CL_RETVAL_PARAMS; } /* create local endpoint */ connection->local = cl_com_dup_endpoint(local_endpoint); if (connection->local == NULL) { return CL_RETVAL_MALLOC; } /* set service handler flag */ connection->service_handler_flag = CL_COM_SERVICE_HANDLER; retval = CL_RETVAL_UNKNOWN; only_prepare_service = cl_commlib_get_global_param(CL_COMMLIB_DELAYED_LISTEN); switch(connection->framework_type) { case CL_CT_TCP: { retval = cl_com_tcp_connection_request_handler_setup(connection, only_prepare_service); break; } case CL_CT_SSL: { retval = cl_com_ssl_connection_request_handler_setup(connection, only_prepare_service); break; } case CL_CT_UNDEFINED: { retval = CL_RETVAL_UNDEFINED_FRAMEWORK; break; } } if (retval != CL_RETVAL_OK) { /* free endpoint */ cl_com_free_endpoint(&(connection->local)); /* reset service handler flag */ connection->service_handler_flag = CL_COM_SERVICE_UNDEFINED; } return retval; } else { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); } return CL_RETVAL_UNDEFINED_FRAMEWORK; } /****** cl_communication/cl_com_connection_request_handler() ******************* * NAME * cl_com_connection_request_handler() -- Get new incomming connections * * SYNOPSIS * int cl_com_connection_request_handler(cl_com_connection_t* connection, * cl_com_connection_t** new_connection, int timeout_val_sec, int * timeout_val_usec) * * FUNCTION * This wrapper function will call the correct * cl_com_xxx_connection_request_handler() function for the selected * framework. * * It will create a new connection pointer and sets new_connection to the * new connection when connection requests are queueing. new_connection * must point to NULL when calling this function. * * The new connection must be handled (and erased) by the caller of this * function. * * INPUTS * cl_com_connection_t* connection - pointer to service connection * struct. (Created with a call to * cl_com_connection_request_handler_setup()) * cl_com_connection_t** new_connection - pointer to an address of a cl_com_connection_t * struct. (will be set to a new * connection) * int timeout_val_sec - timeout in sec * int timeout_val_usec - timeout in usec * * RESULT * int - CL_RETVAL_XXXX error or CL_RETVAL_OK on success * * SEE ALSO * cl_communication/cl_com_connection_request_handler_cleanup() * cl_communication/cl_com_connection_request_handler_setup() * cl_communication/cl_com_connection_request_handler() *******************************************************************************/ #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_request_handler()" int cl_com_connection_request_handler(cl_com_connection_t* connection, cl_com_connection_t** new_connection) { int retval = CL_RETVAL_OK; if (connection != NULL) { if (connection->service_handler_flag != CL_COM_SERVICE_HANDLER) { CL_LOG(CL_LOG_ERROR,"connection service handler flag not set"); return CL_RETVAL_NOT_SERVICE_HANDLER; } switch(connection->framework_type) { case CL_CT_TCP: { retval = cl_com_tcp_connection_request_handler(connection, new_connection); break; } case CL_CT_SSL: { retval = cl_com_ssl_connection_request_handler(connection, new_connection); break; } case CL_CT_UNDEFINED: { retval = CL_RETVAL_UNDEFINED_FRAMEWORK; break; } } connection->data_read_flag = CL_COM_DATA_NOT_READY; if (*new_connection != NULL && retval == CL_RETVAL_OK) { /* setup new cl_com_connection_t */ switch(connection->framework_type) { case CL_CT_TCP: { (*new_connection)->connection_state = CL_CONNECTING; (*new_connection)->connection_sub_state = CL_COM_READ_INIT; break; } case CL_CT_SSL: { (*new_connection)->connection_state = CL_ACCEPTING; (*new_connection)->connection_sub_state = CL_COM_ACCEPT_INIT; break; } case CL_CT_UNDEFINED: { break; } } (*new_connection)->service_handler_flag = CL_COM_CONNECTION; (*new_connection)->was_accepted = CL_TRUE; (*new_connection)->local = cl_com_dup_endpoint(connection->local); if ( (*new_connection)->local == NULL ) { cl_com_close_connection(new_connection); retval = CL_RETVAL_MALLOC; } } return retval; }else { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); } return CL_RETVAL_UNDEFINED_FRAMEWORK; } /****** cl_communication/cl_com_connection_request_handler_cleanup() *********** * NAME * cl_com_connection_request_handler_cleanup() -- cleanup service * * SYNOPSIS * int cl_com_connection_request_handler_cleanup(cl_com_connection_t* * connection) * * FUNCTION * This wrapper function calls the correct * cl_com_xxx_connection_request_handler_cleanup() function to shutdown a * server connection. * * INPUTS * cl_com_connection_t* connection - open service connection struct * * RESULT * int - CL_RETVAL_XXXX error or CL_RETVAL_OK on success * * SEE ALSO * cl_communication/cl_com_connection_request_handler() * cl_communication/cl_com_connection_request_handler_setup() *******************************************************************************/ #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_request_handler_cleanup()" int cl_com_connection_request_handler_cleanup(cl_com_connection_t* connection) { /* CR check */ if (connection != NULL) { if (connection->service_handler_flag != CL_COM_SERVICE_HANDLER) { return CL_RETVAL_NOT_SERVICE_HANDLER; } switch(connection->framework_type) { case CL_CT_TCP: { return cl_com_tcp_connection_request_handler_cleanup(connection); } case CL_CT_SSL: { return cl_com_ssl_connection_request_handler_cleanup(connection); } case CL_CT_UNDEFINED: { break; } } } else { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); } return CL_RETVAL_UNDEFINED_FRAMEWORK; } /****** cl_communication/cl_com_open_connection_request_handler() ************** * NAME * cl_com_open_connection_request_handler() -- Check for incomming data * * SYNOPSIS * int cl_com_open_connection_request_handler(int framework_type, * cl_raw_list_t* connection_list, int timeout) * * FUNCTION * This function is a wrapper for the correct * cl_com_xxx_open_connection_request_handler() function of the selected * framework. * * This function will set the connection data_read_flag if there is any * data to read from this connection. * * INPUTS * int framework_type - framework type of connection list * cl_raw_list_t* connection_list - list of connections to check * int timeout - timeout * * RESULT * int - CL_RETVAL_XXXX error or CL_RETVAL_OK on success * * SEE ALSO * cl_tcp_framework/cl_com_tcp_open_connection_request_handler() *******************************************************************************/ #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_open_connection_request_handler()" /* WARNING connection list must be locked */ #ifdef USE_POLL int cl_com_open_connection_request_handler(cl_com_poll_t* poll_handle, cl_com_handle_t* handle, int timeout_val_sec, int timeout_val_usec, cl_select_method_t select_mode) #else int cl_com_open_connection_request_handler(cl_com_handle_t* handle, int timeout_val_sec, int timeout_val_usec, cl_select_method_t select_mode) #endif { cl_com_connection_t* service_connection = NULL; int usec_rest = timeout_val_usec; int sec_param = timeout_val_sec; if (handle == NULL) { return CL_RETVAL_PARAMS; } service_connection = handle->service_handler; /* as long as global CL_COMMLIB_DELAYED_LISTEN is enabled we don't want to do a select on the service connection */ if (cl_commlib_get_global_param(CL_COMMLIB_DELAYED_LISTEN) == CL_TRUE) { service_connection = NULL; } else { /* for read select calls we have to check if max. conneciton count is reached or handle is going down ... */ if (select_mode == CL_RW_SELECT || select_mode == CL_R_SELECT) { if (handle->do_shutdown != 0 || handle->max_connection_count_reached == CL_TRUE) { service_connection = NULL; } } } /* service_handler flag must be reseted in any case */ if (service_connection == NULL && handle->service_handler != NULL) { handle->service_handler->data_read_flag = CL_COM_DATA_NOT_READY; } if (timeout_val_usec >= 1000000) { int full_usec_seconds = 0; usec_rest = timeout_val_usec % 1000000; /* usec parameter for select should not be > 1000000 !!!*/ full_usec_seconds = timeout_val_usec / 1000000; /* full seconds from timeout_val_usec parameter */ sec_param = timeout_val_sec + full_usec_seconds; /* add full seconds from usec parameter to timeout_val_sec parameter */ } if (handle->connection_list != NULL) { switch(handle->framework) { case CL_CT_TCP: { #ifdef USE_POLL return cl_com_tcp_open_connection_request_handler(poll_handle, handle, handle->connection_list, service_connection, sec_param , usec_rest, select_mode); #else return cl_com_tcp_open_connection_request_handler(handle, handle->connection_list, service_connection, sec_param , usec_rest, select_mode); #endif } case CL_CT_SSL: { #ifdef USE_POLL return cl_com_ssl_open_connection_request_handler(poll_handle, handle, handle->connection_list, service_connection, sec_param , usec_rest, select_mode); #else return cl_com_ssl_open_connection_request_handler(handle, handle->connection_list, service_connection, sec_param , usec_rest, select_mode); #endif } case CL_CT_UNDEFINED: { break; } } }else { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); } return CL_RETVAL_UNDEFINED_FRAMEWORK; } #ifdef USE_POLL #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_free_poll_array()" int cl_com_free_poll_array(cl_com_poll_t* poll_handle) { /* * This procedure releases the memory malloc()ed inside * the specified cl_com_poll_t structure. */ if (poll_handle == NULL) { return CL_RETVAL_PARAMS; } if (poll_handle->poll_array != NULL) { free(poll_handle->poll_array); } if (poll_handle->poll_con != NULL) { free(poll_handle->poll_con); } poll_handle->poll_array = NULL; poll_handle->poll_con = NULL; poll_handle->poll_fd_count = 0; CL_LOG(CL_LOG_INFO, "Freed poll_handle"); return CL_RETVAL_OK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_malloc_poll_array()" int cl_com_malloc_poll_array(cl_com_poll_t* poll_handle, unsigned long nr_of_malloced_connections) { /* * Free and re-malloc() the buffers of the specified poll_handle to the * so that nr_of_malloced_connections fit into the buffers. */ if (poll_handle == NULL) { return CL_RETVAL_PARAMS; } cl_com_free_poll_array(poll_handle); poll_handle->poll_array = (struct pollfd*) malloc(nr_of_malloced_connections * sizeof(struct pollfd)); if (poll_handle->poll_array == NULL) { cl_com_free_poll_array(poll_handle); return CL_RETVAL_MALLOC; } poll_handle->poll_con = (cl_com_connection_t**) malloc(nr_of_malloced_connections * sizeof(cl_com_connection_t*)); if (poll_handle->poll_con == NULL) { cl_com_free_poll_array(poll_handle); return CL_RETVAL_MALLOC; } poll_handle->poll_fd_count = nr_of_malloced_connections; CL_LOG_INT(CL_LOG_INFO, "nr of file descriptors fitting into the poll_array: ", (int)poll_handle->poll_fd_count); return CL_RETVAL_OK; } #endif /* If timeout is 0 then the function will return after one read try, the caller has to call this function again */ /* return values CL_RETVAL_OK - connection is connected CL_RETVAL_UNCOMPLETE_READ - waiting for client data CL_RETVAL_UNCOMPLETE_WRITE - could not send all data */ /* caller has to lock the connection list */ #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_complete_request()" int cl_com_connection_complete_request(cl_raw_list_t* connection_list, cl_connection_list_elem_t* elem, long timeout, cl_select_method_t select_mode) { struct timeval now; int retval = CL_RETVAL_OK; cl_com_CM_t* cm_message = NULL; cl_com_CRM_t* crm_message = NULL; char* unique_host = NULL; struct in_addr tmp_addr; int do_read_select = 0; int do_write_select = 0; char tmp_buffer[256]; cl_com_connection_t* connection = NULL; cl_connection_list_data_t* ldata = NULL; unsigned long data_read = 0; unsigned long data_to_read; unsigned long data_written = 0; int connect_port = -1; if (elem == NULL) { CL_LOG(CL_LOG_ERROR,"no connection elem"); return CL_RETVAL_PARAMS; } else { connection = elem->connection; } if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"no connection"); return CL_RETVAL_PARAMS; } if (connection->connection_state != CL_CONNECTING) { CL_LOG(CL_LOG_ERROR,"connection state is not connecting"); return CL_RETVAL_ALLREADY_CONNECTED; } if (connection_list == NULL) { CL_LOG(CL_LOG_ERROR,"no connection list"); return CL_RETVAL_PARAMS; } if (connection_list->list_data == NULL) { CL_LOG(CL_LOG_ERROR,"no connection data struct"); return CL_RETVAL_PARAMS; } else { ldata = connection_list->list_data; } if (ldata->r_ht == NULL) { CL_LOG(CL_LOG_ERROR,"no hash table availabe"); return CL_RETVAL_NO_FRAMEWORK_INIT; } switch(select_mode) { case CL_RW_SELECT: do_read_select = 1; do_write_select = 1; break; case CL_R_SELECT: do_read_select = 1; break; case CL_W_SELECT: do_write_select = 1; break; } if (do_read_select) { if (connection->connection_sub_state == CL_COM_READ_INIT) { CL_LOG(CL_LOG_INFO,"connection state: CL_COM_READ_INIT"); if (connection->remote != NULL) { CL_LOG(CL_LOG_ERROR,"connection is not free"); return CL_RETVAL_PARAMS; } /* set connecting timeout in private structure */ gettimeofday(&now,NULL); connection->read_buffer_timeout_time = now.tv_sec + timeout; connection->read_gmsh_header->dl = 0; connection->data_read_buffer_pos = 0; connection->data_read_buffer_processed = 0; connection->connection_sub_state = CL_COM_READ_GMSH; connection->data_write_flag = CL_COM_DATA_NOT_READY; } if (connection->connection_sub_state == CL_COM_READ_GMSH) { CL_LOG(CL_LOG_INFO,"connection state: CL_COM_READ_GMSH"); /* read in GMSH header (General Message Size Header)*/ data_read = 0; retval = cl_com_read_GMSH(connection, &data_read); if (retval != CL_RETVAL_OK) { return retval; } connection->connection_sub_state = CL_COM_READ_CM; } if (connection->connection_sub_state == CL_COM_READ_CM) { cl_byte_t* tmp_connect_message_buffer = NULL; CL_LOG(CL_LOG_INFO,"connection state: CL_COM_READ_CM"); /* calculate (rest) data size to read = data length - stream buff position */ data_to_read = connection->read_gmsh_header->dl - (connection->data_read_buffer_pos - connection->data_read_buffer_processed); #if CL_DO_COMMUNICATION_DEBUG CL_LOG_INT(CL_LOG_INFO,"data to read=",(int)data_to_read); #endif if ( (data_to_read + connection->data_read_buffer_pos) >= connection->data_buffer_size ) { CL_LOG(CL_LOG_ERROR,"stream buffer to small"); return CL_RETVAL_STREAM_BUFFER_OVERFLOW; } /* is data already in buffer ? */ if (data_to_read > 0) { data_read = 0; retval = cl_com_read(connection, &(connection->data_read_buffer[(connection->data_read_buffer_pos)]), /* position to continue */ data_to_read, &data_read); /* returns the data bytes read */ connection->data_read_buffer_pos = connection->data_read_buffer_pos + data_read; /* add data read count to buff position */ if (retval != CL_RETVAL_OK) { return retval; } } /* * Since xml parsing will destroy specified buffer (putting string termination chars into) * we have to make a copy of the buffer if debug clients are connected. */ if (connection->handler != NULL) { switch(connection->handler->debug_client_setup->dc_mode) { /* don't add default case for this switch! */ case CL_DEBUG_CLIENT_ALL: case CL_DEBUG_CLIENT_MSG: { tmp_connect_message_buffer = (cl_byte_t*) malloc(connection->read_gmsh_header->dl * sizeof(cl_byte_t)); memcpy(tmp_connect_message_buffer, &(connection->data_read_buffer[(connection->data_read_buffer_processed)]), connection->read_gmsh_header->dl); break; } case CL_DEBUG_CLIENT_OFF: case CL_DEBUG_CLIENT_APP: { break; } } } retval = cl_xml_parse_CM(&(connection->data_read_buffer[(connection->data_read_buffer_processed)]),connection->read_gmsh_header->dl, &cm_message); if (retval != CL_RETVAL_OK) { cl_com_free_cm_message(&cm_message); if (tmp_connect_message_buffer != NULL) { free(tmp_connect_message_buffer); } return retval; } connection->data_read_buffer_processed = connection->data_read_buffer_processed + connection->read_gmsh_header->dl; /* resolve hostnames */ connection->crm_state = CL_CRM_CS_UNDEFINED; if ( (retval=cl_com_cached_gethostbyname(cm_message->dst->comp_host, &unique_host, &tmp_addr, NULL, NULL)) != CL_RETVAL_OK) { if ( cm_message->dst->comp_host != NULL ) { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_CANT_RESOLVE_DESTINATION_HOST_S, cm_message->dst->comp_host ); } else { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_EMPTY_DESTINATION_HOST ); } cl_commlib_push_application_error(CL_LOG_ERROR, retval , tmp_buffer ); unique_host = strdup("(HOST_NOT_RESOLVABLE)"); } if (connection->crm_state == CL_CRM_CS_UNDEFINED && cl_com_compare_hosts( cm_message->dst->comp_host , unique_host ) != CL_RETVAL_OK) { int string_size = 1; CL_LOG(CL_LOG_ERROR,"hostname resolve error (destination):"); CL_LOG_STR(CL_LOG_ERROR,"remote host name from connect message:", cm_message->dst->comp_host); CL_LOG_STR(CL_LOG_ERROR,"local resolving of remote host name :", unique_host); if ( cm_message->dst->comp_host != NULL && unique_host != NULL ) { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_REMOTE_DESTINATION_HOSTNAME_X_NOT_Y_SS, cm_message->dst->comp_host, unique_host); } else { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_EMPTY_DESTINATION_HOST ); } cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_LOCAL_HOSTNAME_ERROR, tmp_buffer ); /* deny access to connected client */ connection->crm_state = CL_CRM_CS_DENIED; /* overwrite and free last error */ if ( connection->crm_state_error != NULL) { free( connection->crm_state_error ); connection->crm_state_error = NULL; } /* calculate string size */ string_size += strlen(MSG_CL_CRM_ERROR_MESSAGE2_SS); if ( cm_message->dst->comp_host != NULL ) { string_size += strlen(cm_message->dst->comp_host); } if ( unique_host != NULL ) { string_size += strlen(unique_host); } /* malloc error message text (destroyed when connection is deleted) */ connection->crm_state_error = (char*) malloc(sizeof(char) * string_size ); /* copy error message into connection->crm_state_error */ if ( connection->crm_state_error != NULL ) { if ( cm_message->dst->comp_host != NULL && unique_host != NULL ) { snprintf( connection->crm_state_error, string_size ,MSG_CL_CRM_ERROR_MESSAGE2_SS, cm_message->dst->comp_host, unique_host); } else { snprintf( connection->crm_state_error, string_size ,MSG_CL_CRM_ERROR_MESSAGE2_SS, "" , "" ); } } } connection->client_dst = cl_com_create_endpoint(unique_host ,cm_message->dst->comp_name,cm_message->dst->comp_id, &tmp_addr); free(unique_host); unique_host = NULL; if (cm_message->rdata != NULL) { if ( (retval=cl_com_cached_gethostbyname(cm_message->rdata->comp_host, &unique_host, &tmp_addr, NULL, NULL)) != CL_RETVAL_OK) { if (cm_message->rdata->comp_host != NULL) { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_CANT_RESOLVE_RDATA_HOST_S , cm_message->rdata->comp_host); } else { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_EMPTY_RDATA_HOST); } cl_commlib_push_application_error(CL_LOG_ERROR, retval , tmp_buffer ); unique_host = strdup("(HOST_NOT_RESOLVABLE)"); } connection->remote = cl_com_create_endpoint(unique_host, cm_message->rdata->comp_name, cm_message->rdata->comp_id, &tmp_addr); if (connection->crm_state == CL_CRM_CS_UNDEFINED && cl_com_compare_hosts(cm_message->rdata->comp_host , unique_host) != CL_RETVAL_OK) { int string_size = 1; CL_LOG(CL_LOG_ERROR,"hostname resolve error (rdata):"); CL_LOG_STR(CL_LOG_ERROR,"remote host name from connect message:", cm_message->rdata->comp_host); CL_LOG_STR(CL_LOG_ERROR,"local resolving of remote host name :", unique_host); if ( cm_message->rdata->comp_host != NULL && unique_host != NULL ) { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_REMOTE_RDATA_HOSTNAME_X_NOT_Y_SS, cm_message->rdata->comp_host, unique_host); } else { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_EMPTY_RDATA_HOST ); } cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_LOCAL_HOSTNAME_ERROR, tmp_buffer ); /* deny access to connected client */ connection->crm_state = CL_CRM_CS_DENIED; /* overwrite and free last error */ if ( connection->crm_state_error != NULL) { free(connection->crm_state_error); connection->crm_state_error = NULL; } /* calculate string size */ string_size += strlen(MSG_CL_CRM_ERROR_MESSAGE3_SS); if ( cm_message->rdata->comp_host != NULL ) { string_size += strlen(cm_message->rdata->comp_host); } if ( unique_host != NULL ) { string_size += strlen(unique_host); } /* malloc error message text (destroyed when connection is deleted) */ connection->crm_state_error = (char*) malloc(sizeof(char) * string_size ); /* copy error message into connection->crm_state_error */ if (connection->crm_state_error != NULL) { if (cm_message->rdata->comp_host != NULL && unique_host != NULL) { snprintf( connection->crm_state_error, string_size , MSG_CL_CRM_ERROR_MESSAGE3_SS, cm_message->rdata->comp_host , unique_host ); } else { snprintf( connection->crm_state_error, string_size , MSG_CL_CRM_ERROR_MESSAGE3_SS, "" , "" ); } } } free(unique_host); unique_host = NULL; } connection->data_flow_type = cm_message->ct; connection->data_format_type = cm_message->df; connection->auto_close_type = cm_message->ac; switch(connection->auto_close_type) { case CL_CM_AC_ENABLED: CL_LOG(CL_LOG_INFO,"client's auto close mode is enabled"); break; case CL_CM_AC_DISABLED: CL_LOG(CL_LOG_INFO,"client's auto close mode is disabled"); break; default: CL_LOG(CL_LOG_ERROR,"unexpeced auto close mode request from client"); } if (connection->data_read_buffer_pos != connection->data_read_buffer_processed ) { unsigned long unexpected = connection->data_read_buffer_pos - connection->data_read_buffer_processed; CL_LOG_INT(CL_LOG_ERROR,"recevied more or less than expected:", (int)unexpected); } if (connection->remote == NULL) { cl_com_free_endpoint(&(connection->client_dst)); cl_com_free_cm_message(&cm_message); if (tmp_connect_message_buffer != NULL) { free(tmp_connect_message_buffer); } return CL_RETVAL_MALLOC; } if (connection->client_dst == NULL) { cl_com_free_endpoint(&(connection->remote)); cl_com_free_cm_message(&cm_message); if (tmp_connect_message_buffer != NULL) { free(tmp_connect_message_buffer); } return CL_RETVAL_MALLOC; } if ( (retval=cl_com_connection_get_connect_port(connection, &connect_port)) != CL_RETVAL_OK) { cl_com_free_endpoint(&(connection->remote)); cl_com_free_cm_message(&cm_message); if (tmp_connect_message_buffer != NULL) { free(tmp_connect_message_buffer); } return retval; } if (connect_port != 0) { CL_LOG(CL_LOG_ERROR,"unexpected error: connect port should be still 0 here"); } else if ( (retval=cl_com_connection_set_connect_port(connection, (int)cm_message->port)) != CL_RETVAL_OK) { cl_com_free_endpoint(&(connection->remote)); cl_com_free_cm_message(&cm_message); if (tmp_connect_message_buffer != NULL) { free(tmp_connect_message_buffer); } return retval; } if (connection->handler != NULL) { switch(connection->handler->debug_client_setup->dc_mode) { /* don't add default case for this switch! */ case CL_DEBUG_CLIENT_ALL: case CL_DEBUG_CLIENT_MSG: { cl_com_message_t* dummy_message = NULL; cl_com_create_message(&dummy_message); if (dummy_message != NULL) { dummy_message->message_df = CL_MIH_DF_CM; dummy_message->message_mat = CL_MIH_MAT_NAK; gettimeofday(&dummy_message->message_receive_time,NULL); gettimeofday(&dummy_message->message_remove_time,NULL); dummy_message->message = tmp_connect_message_buffer; tmp_connect_message_buffer = NULL; dummy_message->message_length = connection->read_gmsh_header->dl; cl_com_add_debug_message(connection, NULL , dummy_message); cl_com_free_message(&dummy_message); } break; } case CL_DEBUG_CLIENT_OFF: case CL_DEBUG_CLIENT_APP: { break; } } } if (tmp_connect_message_buffer != NULL) { free(tmp_connect_message_buffer); } cl_com_free_cm_message(&cm_message); /* check if remote connection matches resolved client host name */ if (connection->crm_state == CL_CRM_CS_UNDEFINED && cl_com_compare_hosts(connection->remote->comp_host, connection->client_host_name) != CL_RETVAL_OK) { int string_size = 1; CL_LOG(CL_LOG_ERROR,"hostname address resolving error (IP based)"); CL_LOG_STR(CL_LOG_ERROR,"hostname from address resolving:", connection->client_host_name ); CL_LOG_STR(CL_LOG_ERROR,"resolved hostname from client:",connection->remote->comp_host ); if (connection->client_host_name != NULL && connection->remote->comp_host != NULL) { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_IP_ADDRESS_RESOLVING_X_NOT_Y_SS, connection->client_host_name, connection->remote->comp_host ); } else { if (connection->client_host_name == NULL) { snprintf(tmp_buffer,256, MSG_CL_TCP_FW_CANT_RESOLVE_CLIENT_IP ); } else { snprintf(tmp_buffer,256, MSG_CL_TCP_FW_EMPTY_REMOTE_HOST ); } } cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_LOCAL_HOSTNAME_ERROR, tmp_buffer ); /* deny access to connected client */ connection->crm_state = CL_CRM_CS_DENIED; /* overwrite and free last error */ if ( connection->crm_state_error != NULL) { free(connection->crm_state_error); connection->crm_state_error = NULL; } /* calculate string size */ string_size += strlen(MSG_CL_CRM_ERROR_MESSAGE4_SS); if (connection->remote->comp_host != NULL) { string_size += strlen(connection->remote->comp_host); } if (connection->client_host_name != NULL) { string_size += strlen(connection->client_host_name); } /* malloc error message text (destroyed when connection is deleted) */ connection->crm_state_error = (char*) malloc(sizeof(char) * string_size ); /* copy error message into connection->crm_state_error */ if (connection->crm_state_error != NULL) { if (connection->client_host_name != NULL && connection->remote->comp_host != NULL) { snprintf(connection->crm_state_error,string_size , MSG_CL_CRM_ERROR_MESSAGE4_SS, connection->client_host_name , connection->remote->comp_host); } else { snprintf( connection->crm_state_error,string_size , MSG_CL_CRM_ERROR_MESSAGE4_SS, "" , "" ); } } } if (connection->remote->comp_id == 0) { cl_com_handle_t* handle = connection->handler; /* connection list should be locked in higher framework */ if (handle != NULL) { unsigned long counter = 0; /************************************ * search unique client id * ************************************/ /* connection list is locked by calling function , so we do not need to lock the connection list */ connection->remote->comp_id = handle->next_free_client_id; free(connection->remote->hash_id); connection->remote->hash_id = cl_create_endpoint_string(connection->remote); if (connection->remote->hash_id == NULL) { return CL_RETVAL_MALLOC; } /* This is not working for disabled hash */ while (cl_connection_list_get_elem_endpoint(connection_list, connection->remote) != NULL) { /* break in case of to many connections */ if (counter > CL_DEFINE_MAX_MESSAGE_ID) { break; } /* this id is not unique, increment client id */ if (handle->next_free_client_id >= CL_DEFINE_MAX_MESSAGE_ID) { handle->next_free_client_id = 1; } else { handle->next_free_client_id++; } connection->remote->comp_id = handle->next_free_client_id; free(connection->remote->hash_id); connection->remote->hash_id = cl_create_endpoint_string(connection->remote); if (connection->remote->hash_id == NULL) { return CL_RETVAL_MALLOC; } counter++; } CL_LOG_INT(CL_LOG_INFO,"client got auto client id:", (int)connection->remote->comp_id); /* always increment client id */ if (handle->next_free_client_id >= CL_DEFINE_MAX_MESSAGE_ID ) { handle->next_free_client_id = 1; } else { handle->next_free_client_id = handle->next_free_client_id + 1; } } else { CL_LOG(CL_LOG_WARNING,"handle of connection is not set"); if (connection->remote->comp_id == 0) { connection->remote->comp_id = 1; } } } connection->read_buffer_timeout_time = 0; connection->statistic->real_bytes_received += connection->data_read_buffer_processed; connection->connection_sub_state = CL_COM_READ_INIT_CRM; } if (connection->connection_sub_state == CL_COM_READ_INIT_CRM ) { char *params = NULL; char* connection_status = CL_CONNECT_RESPONSE_MESSAGE_CONNECTION_STATUS_OK; const char* connection_status_text = MSG_CL_TCP_FW_CONNECTION_STATUS_TEXT_OK; unsigned long connect_response_message_size = 0; unsigned long gmsh_message_size = 0; CL_LOG(CL_LOG_INFO,"connection state: CL_COM_READ_INIT_CRM"); if ( connection->crm_state == CL_CRM_CS_DENIED) { if (connection->crm_state_error == NULL) { connection_status_text = MSG_CL_TCP_FW_CONNECTION_STATUS_TEXT_HOSTNAME_RESOLVING_ERROR; } else { connection_status_text = connection->crm_state_error; } connection_status = CL_CONNECT_RESPONSE_MESSAGE_CONNECTION_STATUS_DENIED; CL_LOG(CL_LOG_ERROR, connection_status_text ); } if (connection->crm_state == CL_CRM_CS_UNDEFINED) { connection->crm_state = CL_CRM_CS_CONNECTED; /* if is ok, this is ok */ if ( strcmp(connection->local->comp_name, connection->client_dst->comp_name) != 0 || connection->local->comp_id != connection->client_dst->comp_id ) { snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_ENDPOINT_X_DOESNT_MATCH_Y_SSUSSU, connection->local->comp_host, connection->local->comp_name, sge_u32c(connection->local->comp_id), connection->client_dst->comp_host, connection->client_dst->comp_name, sge_u32c(connection->client_dst->comp_id)); cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_ACCESS_DENIED, tmp_buffer ); connection->crm_state = CL_CRM_CS_DENIED; connection_status = CL_CONNECT_RESPONSE_MESSAGE_CONNECTION_STATUS_DENIED; /* overwrite and free last error */ if ( connection->crm_state_error != NULL) { free(connection->crm_state_error); connection->crm_state_error = NULL; } connection->crm_state_error = strdup(tmp_buffer); if (connection->crm_state_error == NULL) { connection_status_text = MSG_CL_TCP_FW_CONNECTION_STATUS_TEXT_COMPONENT_NOT_FOUND; } else { connection_status_text = connection->crm_state_error; } } } if (connection->crm_state == CL_CRM_CS_CONNECTED) { cl_com_handle_t* handler = connection->handler; if (handler != NULL) { cl_connection_list_elem_t* tmp_elem = NULL; /************************************ * check duplicate endpoint entries * ************************************/ /* connection list is locked by calling function , so we do not need to lock the connection list */ /* This is not working for disabled hash */ if ((tmp_elem = cl_connection_list_get_elem_endpoint(connection_list, connection->remote)) != NULL) { /* endpoint is not unique, check already connected endpoint */ cl_com_connection_t* tmp_con = tmp_elem->connection; tmp_con->check_endpoint_flag = CL_TRUE; /* * delete the hash_id of the connection, otherwise the * current one would not have a hash key anymore */ if (connection->remote != NULL && connection->remote->hash_id != NULL) { free(connection->remote->hash_id); connection->remote->hash_id = NULL; } snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_ENDPOINT_X_ALREADY_CONNECTED_SSU, connection->remote->comp_host, connection->remote->comp_name, sge_u32c(connection->remote->comp_id)); cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_ENDPOINT_NOT_UNIQUE, tmp_buffer ); connection->crm_state = CL_CRM_CS_ENDPOINT_NOT_UNIQUE; /* CL_CRM_CS_DENIED; */ connection_status = CL_CONNECT_RESPONSE_MESSAGE_CONNECTION_STATUS_NOT_UNIQUE; /* overwrite and free last error */ if ( connection->crm_state_error != NULL) { free(connection->crm_state_error); connection->crm_state_error = NULL; } connection->crm_state_error = strdup(tmp_buffer); if (connection->crm_state_error == NULL) { connection_status_text = MSG_CL_TCP_FW_CONNECTION_STATUS_TEXT_ENDPOINT_NOT_UNIQUE_ERROR; } else { connection_status_text = connection->crm_state_error; } CL_LOG(CL_LOG_ERROR, connection_status_text); } else { cl_connection_list_data_t * ldata = connection_list->list_data; CL_LOG(CL_LOG_INFO,"new client is unique, add it to hash"); /* * insert into hash * * Incoming (accepted) connections are added to the hash when the * client endpoint name is resovled. Here the client is unique and * we can create a hash key for the endpoint. */ if (ldata->r_ht != NULL && connection->remote != NULL && connection->remote->hash_id != NULL) { sge_htable_store(ldata->r_ht, connection->remote->hash_id, elem); } } } else { CL_LOG(CL_LOG_WARNING,"connection list has no handler"); } } if (connection->crm_state == CL_CRM_CS_CONNECTED) { /************************************* * check new debug client * *************************************/ if (connection->data_flow_type == CL_CM_CT_STREAM) { CL_LOG(CL_LOG_ERROR,"new STREAM connection"); if (strcmp(connection->remote->comp_name, CL_COM_DEBUG_CLIENT_NAME) == 0) { int in_port = 0; int ret = 0; cl_bool_t client_ok = CL_TRUE; if ( (ret=cl_com_connection_get_client_socket_in_port(connection, &in_port)) != CL_RETVAL_OK) { CL_LOG_STR(CL_LOG_ERROR,"could not get client in socket connect port:", cl_get_error_text(ret)); } CL_LOG_INT(CL_LOG_INFO,"new debug client connection from port", in_port ); /* check debug client reserved port */ if (in_port <= 0 || in_port >= IPPORT_RESERVED) { CL_LOG(CL_LOG_ERROR,"new debug client connection is not from a reserved port"); client_ok = CL_FALSE; snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_ENDPOINT_X_NOT_FROM_RESERVED_PORT_SSU, connection->remote->comp_host, connection->remote->comp_name, sge_u32c(connection->remote->comp_id)); cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_NO_RESERVED_PORT_CONNECTION, tmp_buffer ); connection->crm_state = CL_CRM_CS_DENIED; connection_status = CL_CONNECT_RESPONSE_MESSAGE_CONNECTION_STATUS_DENIED; /* overwrite and free last error */ if ( connection->crm_state_error != NULL) { free(connection->crm_state_error); connection->crm_state_error = NULL; } connection->crm_state_error = strdup(tmp_buffer); if (connection->crm_state_error == NULL) { connection_status_text = MSG_CL_TCP_FW_RESERVED_PORT_CONNECT_ERROR; } else { connection_status_text = connection->crm_state_error; } CL_LOG(CL_LOG_ERROR, connection_status_text ); } /* check debug client host name */ if (cl_com_compare_hosts(connection->remote->comp_host, connection->local->comp_host) != CL_RETVAL_OK) { CL_LOG(CL_LOG_ERROR,"new debug client connection is not from local host"); client_ok = CL_FALSE; snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_ENDPOINT_X_NOT_FROM_LOCAL_HOST_SSUS, connection->remote->comp_host, connection->remote->comp_name, sge_u32c(connection->remote->comp_id), connection->local->comp_host); cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_NO_LOCAL_HOST_CONNECTION, tmp_buffer ); connection->crm_state = CL_CRM_CS_DENIED; connection_status = CL_CONNECT_RESPONSE_MESSAGE_CONNECTION_STATUS_DENIED; /* overwrite and free last error */ if ( connection->crm_state_error != NULL) { free(connection->crm_state_error); connection->crm_state_error = NULL; } connection->crm_state_error = strdup(tmp_buffer); if (connection->crm_state_error == NULL) { connection_status_text = MSG_CL_TCP_FW_LOCAL_HOST_CONNECT_ERROR; } else { connection_status_text = connection->crm_state_error; } CL_LOG(CL_LOG_ERROR, connection_status_text ); } if (client_ok == CL_TRUE) { cl_com_handle_t* handler = NULL; /* enable debug message creation in handler */ /* this is switched off automatically in cl_commlib_handle_debug_clients() */ handler = connection->handler; if (handler != NULL) { CL_LOG(CL_LOG_ERROR,"enable debug client message creation"); handler->debug_client_setup->dc_mode = CL_DEBUG_CLIENT_ALL; } } } } } if (connection->crm_state == CL_CRM_CS_CONNECTED) { cl_com_handle_t* handle = connection->handler; /* * check for reserved port security when service is using it * */ if (handle != NULL) { if (handle->tcp_connect_mode == CL_TCP_RESERVED_PORT) { int in_port = 0; int ret = 0; if ( (ret=cl_com_connection_get_client_socket_in_port(connection, &in_port)) != CL_RETVAL_OK) { CL_LOG_STR(CL_LOG_ERROR,"could not get client in socket connect port:", cl_get_error_text(ret)); } if (in_port <= 0 || in_port >= IPPORT_RESERVED) { CL_LOG(CL_LOG_ERROR,"new debug client connection is not from a reserved port"); CL_LOG_INT(CL_LOG_ERROR,"client port =", in_port); snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_STANDARD_ENDPOINT_X_NOT_FROM_RESERVED_PORT_SSU, connection->remote->comp_host, connection->remote->comp_name, sge_u32c(connection->remote->comp_id)); cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_NO_RESERVED_PORT_CONNECTION, tmp_buffer ); connection->crm_state = CL_CRM_CS_DENIED; connection_status = CL_CONNECT_RESPONSE_MESSAGE_CONNECTION_STATUS_DENIED; /* overwrite and free last error */ if ( connection->crm_state_error != NULL) { free(connection->crm_state_error); connection->crm_state_error = NULL; } connection->crm_state_error = strdup(tmp_buffer); if (connection->crm_state_error == NULL) { connection_status_text = MSG_CL_TCP_FW_RESERVED_PORT_CONNECT_ERROR; } else { connection_status_text = connection->crm_state_error; } CL_LOG(CL_LOG_ERROR, connection_status_text ); } } } } #if 0 /* This code is currently not used but should be used in the future, don't remove it */ if (connection->crm_state == CL_CRM_CS_CONNECTED) { if ( connection->handler != NULL && connection->was_accepted == CL_TRUE ) { /* TODO */ /* set check_allowed_host_list to 1 if the commlib should check the allowed host list to enable cl_com_add_allowed_host() calls */ int check_allowed_host_list = 0; if (connection->handler->allowed_host_list == NULL && check_allowed_host_list != 0) { connection_status_text = MSG_CL_TCP_FW_CONNECTION_STATUS_TEXT_CLIENT_NOT_IN_ALLOWED_HOST_LIST; cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_ACCESS_DENIED, MSG_CL_TCP_FW_ALLOWED_HOST_LIST_NOT_DEFINED ); connection_status = CL_CONNECT_RESPONSE_MESSAGE_CONNECTION_STATUS_DENIED; connection->crm_state = CL_CRM_CS_DENIED; CL_LOG(CL_LOG_ERROR, connection_status_text ); } else { cl_string_list_elem_t* elem = NULL; int is_ok = 0; if ( check_allowed_host_list != 0) { cl_raw_list_lock(connection->handler->allowed_host_list); for (elem = cl_string_list_get_first_elem(connection->handler->allowed_host_list) ; elem != NULL; elem = cl_string_list_get_next_elem(elem)) { char* resolved_host = NULL; retval = cl_com_cached_gethostbyname(elem->string, &resolved_host, NULL, NULL, NULL ); if (retval == CL_RETVAL_OK && resolved_host != NULL) { if(cl_com_compare_hosts(resolved_host, connection->client_host_name) == CL_RETVAL_OK) { is_ok = 1; free(resolved_host); break; } } free(resolved_host); resolved_host = NULL; } cl_raw_list_unlock(connection->handler->allowed_host_list); } else { CL_LOG(CL_LOG_INFO,"allowed host list check is not activated"); is_ok = 1; } if (is_ok != 1) { connection_status_text = MSG_CL_TCP_FW_CONNECTION_STATUS_TEXT_CLIENT_NOT_IN_ALLOWED_HOST_LIST; snprintf(tmp_buffer, 256, MSG_CL_TCP_FW_HOST_X_NOT_IN_ALOWED_HOST_LIST_S, connection->client_host_name); cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_ACCESS_DENIED,tmp_buffer); connection->crm_state = CL_CRM_CS_DENIED; connection_status = CL_CONNECT_RESPONSE_MESSAGE_CONNECTION_STATUS_DENIED; /* overwrite and free last error */ if ( connection->crm_state_error != NULL) { free(connection->crm_state_error); connection->crm_state_error = NULL; } connection->crm_state_error = strdup(tmp_buffer); if (connection->crm_state_error == NULL) { connection_status_text = MSG_CL_TCP_FW_CONNECTION_STATUS_TEXT_CLIENT_NOT_IN_ALLOWED_HOST_LIST; } else { connection_status_text = connection->crm_state_error; } } } } } #endif { char* tmp_str = NULL; int tmp_retval; tmp_retval = cl_com_get_parameter_list_string(&tmp_str); if (tmp_retval != CL_RETVAL_OK) { return tmp_retval; } cl_com_transformString2XML(tmp_str, ¶ms); free(tmp_str); } connect_response_message_size = CL_CONNECT_RESPONSE_MESSAGE_SIZE; connect_response_message_size += strlen(connection_status); connect_response_message_size += strlen(connection_status_text); connect_response_message_size += strlen(connection->remote->comp_host); connect_response_message_size += strlen(connection->remote->comp_name); connect_response_message_size += cl_util_get_ulong_number_length(connection->remote->comp_id); if (params != NULL) { connect_response_message_size += strlen(params); } gmsh_message_size = CL_GMSH_MESSAGE_SIZE + cl_util_get_ulong_number_length(connect_response_message_size); if (connection->data_buffer_size < (gmsh_message_size + connect_response_message_size + 1) ) { if (params != NULL) { free(params); } return CL_RETVAL_STREAM_BUFFER_OVERFLOW; } sprintf((char*)connection->data_write_buffer, CL_GMSH_MESSAGE , connect_response_message_size); sprintf((char*)&((connection->data_write_buffer)[gmsh_message_size]), CL_CONNECT_RESPONSE_MESSAGE, CL_CONNECT_RESPONSE_MESSAGE_VERSION, connection_status, connection_status_text, connection->remote->comp_host, connection->remote->comp_name, connection->remote->comp_id, params ? params : ""); connection->data_write_buffer_pos = 0; connection->data_write_buffer_processed = 0; connection->data_write_buffer_to_send = gmsh_message_size + connect_response_message_size ; gettimeofday(&now,NULL); connection->write_buffer_timeout_time = now.tv_sec + timeout; connection->data_write_flag = CL_COM_DATA_READY; connection->connection_sub_state = CL_COM_READ_SEND_CRM; if (params != NULL) { free(params); } } } if (do_write_select) { if (connection->connection_sub_state == CL_COM_READ_SEND_CRM ) { CL_LOG(CL_LOG_INFO,"state is CL_COM_READ_SEND_CRM"); data_written = 0; retval = cl_com_write(connection, &(connection->data_write_buffer[(connection->data_write_buffer_pos)]), /* position to continue */ connection->data_write_buffer_to_send, &data_written); /* returns the data bytes read */ connection->data_write_buffer_pos = connection->data_write_buffer_pos + data_written; /* add data read count to buff position */ connection->data_write_buffer_to_send = connection->data_write_buffer_to_send - data_written; if (retval != CL_RETVAL_OK) { return retval; } if (connection->handler != NULL) { switch(connection->handler->debug_client_setup->dc_mode) { /* don't add default case for this switch! */ case CL_DEBUG_CLIENT_ALL: case CL_DEBUG_CLIENT_MSG: { cl_com_message_t* dummy_message = NULL; cl_com_create_message(&dummy_message); if (dummy_message != NULL) { int crm_pos = 0; dummy_message->message_df = CL_MIH_DF_CRM; dummy_message->message_mat = CL_MIH_MAT_NAK; gettimeofday(&dummy_message->message_insert_time,NULL); gettimeofday(&dummy_message->message_send_time,NULL); for (crm_pos = 0; crm_pos < connection->data_write_buffer_pos - 3; crm_pos++) { if ( connection->data_write_buffer[crm_pos] == '<' && connection->data_write_buffer[crm_pos+1] == 'c' && connection->data_write_buffer[crm_pos+2] == 'r' && connection->data_write_buffer[crm_pos+3] == 'm' ) { dummy_message->message = (cl_byte_t*) &connection->data_write_buffer[crm_pos]; dummy_message->message_length = connection->data_write_buffer_pos - crm_pos; break; } } cl_com_add_debug_message(connection, NULL , dummy_message); dummy_message->message = NULL; cl_com_free_message(&dummy_message); } break; } case CL_DEBUG_CLIENT_OFF: case CL_DEBUG_CLIENT_APP: { break; } } } if (cl_raw_list_get_elem_count(connection->send_message_list) == 0) { connection->data_write_flag = CL_COM_DATA_NOT_READY; } else { connection->data_write_flag = CL_COM_DATA_READY; } connection->write_buffer_timeout_time = 0; if (connection->crm_state == CL_CRM_CS_CONNECTED) { connection->connection_state = CL_CONNECTED; /* That was it! */ connection->connection_sub_state = CL_COM_WORK; gettimeofday(&(connection->connection_connect_time), NULL); #if CL_DO_COMMUNICATION_DEBUG cl_dump_connection(connection); #endif } else { connection->connection_state = CL_CLOSING; /* That was it! */ connection->connection_sub_state = CL_COM_DO_SHUTDOWN; CL_LOG(CL_LOG_WARNING,"access to client denied"); #if CL_DO_COMMUNICATION_DEBUG cl_dump_connection(connection); #endif } connection->statistic->real_bytes_sent = connection->statistic->real_bytes_sent + connection->data_write_buffer_pos; } if (connection->connection_sub_state == CL_COM_SEND_INIT) { unsigned long connect_message_size = 0; unsigned long gmsh_message_size = 0; unsigned long local_service_port_number = 0; int service_port = 0; char* format_type = ""; char* flow_type = ""; char* autoclose = ""; CL_LOG(CL_LOG_INFO,"connection state: CL_COM_SEND_INIT"); if ((retval = cl_com_connection_get_service_port(connection, &service_port)) != CL_RETVAL_OK) { return retval; } local_service_port_number = service_port; /* set connecting timeout in private structure */ gettimeofday(&now,NULL); connection->write_buffer_timeout_time = now.tv_sec + timeout ; connect_message_size = CL_CONNECT_MESSAGE_SIZE; if (connection->data_format_type == CL_CM_DF_BIN) { format_type = CL_CONNECT_MESSAGE_DATA_FORMAT_BIN; } else if (connection->data_format_type == CL_CM_DF_XML) { format_type = CL_CONNECT_MESSAGE_DATA_FORMAT_XML; } connect_message_size = connect_message_size + strlen(format_type); if (connection->data_flow_type == CL_CM_CT_STREAM) { flow_type = CL_CONNECT_MESSAGE_DATA_FLOW_STREAM; } else if (connection->data_flow_type == CL_CM_CT_MESSAGE) { flow_type = CL_CONNECT_MESSAGE_DATA_FLOW_MESSAGE; } connect_message_size += strlen(flow_type); /* add port length and length of auto close */ connect_message_size += cl_util_get_ulong_number_length(local_service_port_number); if (connection->auto_close_type == CL_CM_AC_ENABLED) { autoclose = CL_CONNECT_MESSAGE_AUTOCLOSE_ENABLED; } else if (connection->auto_close_type == CL_CM_AC_DISABLED) { autoclose = CL_CONNECT_MESSAGE_AUTOCLOSE_DISABLED; } connect_message_size += strlen(autoclose); connect_message_size += strlen(connection->local->comp_host); connect_message_size += strlen(connection->local->comp_name); connect_message_size += cl_util_get_ulong_number_length(connection->local->comp_id); connect_message_size += strlen(connection->remote->comp_host); connect_message_size += strlen(connection->remote->comp_name); connect_message_size += cl_util_get_ulong_number_length(connection->remote->comp_id); gmsh_message_size = CL_GMSH_MESSAGE_SIZE + cl_util_get_ulong_number_length(connect_message_size); if (connection->data_buffer_size < (connect_message_size + gmsh_message_size + 1) ) { return CL_RETVAL_STREAM_BUFFER_OVERFLOW; } snprintf((char*)connection->data_write_buffer, connection->data_buffer_size, CL_GMSH_MESSAGE , connect_message_size); snprintf((char*)&((connection->data_write_buffer)[gmsh_message_size]), connection->data_buffer_size - gmsh_message_size, CL_CONNECT_MESSAGE, CL_CONNECT_MESSAGE_VERSION, format_type, flow_type, connection->remote->comp_host, connection->remote->comp_name, connection->remote->comp_id, connection->local->comp_host, connection->local->comp_name, connection->local->comp_id, local_service_port_number, autoclose ); connection->data_write_buffer_pos = 0; connection->data_write_buffer_processed = 0; connection->data_write_buffer_to_send = connect_message_size + gmsh_message_size; connection->data_write_flag = CL_COM_DATA_READY; connection->connection_sub_state = CL_COM_SEND_CM; } if (connection->connection_sub_state == CL_COM_SEND_CM) { CL_LOG(CL_LOG_INFO,"connection state: CL_COM_SEND_CM"); data_written = 0; retval = cl_com_write(connection, &(connection->data_write_buffer[(connection->data_write_buffer_pos)]), /* position to continue */ connection->data_write_buffer_to_send, &data_written); /* returns the data bytes read */ connection->data_write_buffer_pos = connection->data_write_buffer_pos + data_written; /* add data read count to buff position */ connection->data_write_buffer_to_send = connection->data_write_buffer_to_send - data_written; if (retval != CL_RETVAL_OK) { return retval; } connection->statistic->real_bytes_sent = connection->statistic->real_bytes_sent + connection->data_write_buffer_pos; gettimeofday(&now,NULL); connection->read_buffer_timeout_time = now.tv_sec + timeout; connection->data_read_buffer_pos = 0; connection->data_read_buffer_processed = 0; connection->read_gmsh_header->dl = 0; connection->data_write_flag = CL_COM_DATA_NOT_READY; connection->connection_sub_state = CL_COM_SEND_READ_GMSH; connection->write_buffer_timeout_time = 0; } } if (do_read_select) { if (connection->connection_sub_state == CL_COM_SEND_READ_GMSH ) { CL_LOG(CL_LOG_INFO,"connection state: CL_COM_SEND_READ_GMSH"); /* read in GMSH header (General Message Size Header)*/ retval = cl_com_read_GMSH(connection, &data_read); if (retval != CL_RETVAL_OK) { return retval; } connection->connection_sub_state = CL_COM_SEND_READ_CRM; } if (connection->connection_sub_state == CL_COM_SEND_READ_CRM ) { cl_com_handle_t* handler = NULL; CL_LOG(CL_LOG_INFO,"connection state: CL_COM_SEND_READ_CRM"); CL_LOG_INT(CL_LOG_INFO,"GMSH dl:",(int)connection->read_gmsh_header->dl ); /* calculate (rest) data size to read = data length - stream buff position */ data_to_read = connection->read_gmsh_header->dl - (connection->data_read_buffer_pos - connection->data_read_buffer_processed); CL_LOG_INT(CL_LOG_INFO,"data to read=",(int)data_to_read); if ( (data_to_read + connection->data_read_buffer_pos) >= connection->data_buffer_size ) { CL_LOG(CL_LOG_ERROR,"stream buffer to small"); return CL_RETVAL_STREAM_BUFFER_OVERFLOW; } /* is data already in buffer ? */ if (data_to_read > 0) { data_read = 0; retval = cl_com_read(connection, &(connection->data_read_buffer[(connection->data_read_buffer_pos)]), /* position to continue */ data_to_read, &data_read); /* returns the data bytes read */ connection->data_read_buffer_pos = connection->data_read_buffer_pos + data_read; /* add data read count to buff position */ if (retval != CL_RETVAL_OK) { return retval; } } retval = cl_xml_parse_CRM(&(connection->data_read_buffer[(connection->data_read_buffer_processed)]),connection->read_gmsh_header->dl, &crm_message); if (retval != CL_RETVAL_OK) { cl_com_free_crm_message(&crm_message); return retval; } if (cl_raw_list_get_elem_count(connection->send_message_list) == 0) { connection->data_write_flag = CL_COM_DATA_NOT_READY; } else { connection->data_write_flag = CL_COM_DATA_READY; } connection->read_buffer_timeout_time = 0; if (crm_message->cs_condition == CL_CRM_CS_CONNECTED) { connection->connection_state = CL_CONNECTED; /* That was it */ connection->connection_sub_state = CL_COM_WORK; gettimeofday(&(connection->connection_connect_time), NULL); #if CL_DO_COMMUNICATION_DEBUG cl_dump_connection(connection); #endif } else { CL_LOG_INT(CL_LOG_ERROR,"Connect Error:",crm_message->cs_condition); CL_LOG_STR(CL_LOG_ERROR,"error:",crm_message->cs_text); connection->connection_state = CL_CLOSING; /* That was it */ connection->connection_sub_state = CL_COM_DO_SHUTDOWN; switch(crm_message->cs_condition) { case CL_CRM_CS_DENIED: cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_ACCESS_DENIED, crm_message->cs_text); break; case CL_CRM_CS_ENDPOINT_NOT_UNIQUE: cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_ENDPOINT_NOT_UNIQUE, crm_message->cs_text); break; default: cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_UNKNOWN, crm_message->cs_text ); break; } } CL_LOG_STR(CL_LOG_INFO,"remote resolved component host name (local host) :", crm_message->rdata->comp_host); CL_LOG_STR(CL_LOG_INFO,"local resolved component host name (local host) :", connection->local->comp_host); connection->statistic->real_bytes_received = connection->statistic->real_bytes_received + connection->data_read_buffer_pos; if (cl_com_compare_hosts(crm_message->rdata->comp_host, connection->local->comp_host) != CL_RETVAL_OK) { CL_LOG(CL_LOG_ERROR,"host names are not resolved equal"); connection->connection_state = CL_CLOSING; /* That was it */ connection->connection_sub_state = CL_COM_DO_SHUTDOWN; } if (connection->local->comp_id == 0) { connection->local->comp_id = crm_message->rdata->comp_id; CL_LOG_INT(CL_LOG_INFO,"requested local component id from server is", (int)connection->local->comp_id); } /* here we are fetching the parameter from crm_message, parse it into tokens an set the parameter list values */ if (crm_message->params != NULL && *crm_message->params != '\0') { char* token = NULL; struct saved_vars_s *context = NULL; token = sge_strtok_r(crm_message->params, ":", &context); while (token != NULL) { char* sub_token1 = NULL; char* sub_token2 = NULL; struct saved_vars_s *context2 = NULL; sub_token1 = sge_strtok_r(token, "=", &context2); sub_token2 = sge_strtok_r(NULL, "=", &context2); CL_LOG_STR(CL_LOG_INFO,"setting parameter, got from CRM:", sub_token1); CL_LOG_STR(CL_LOG_INFO,"setting value, got from CRM:", sub_token2); cl_com_set_parameter_list_value(sub_token1, sub_token2); sge_free_saved_vars(context2); token = sge_strtok_r(NULL, ":", &context); } sge_free_saved_vars(context); } { char* gdi_timeout = NULL; cl_com_get_parameter_list_value("gdi_timeout", &gdi_timeout); if (gdi_timeout != NULL) { int timeout = atoi(gdi_timeout); cl_com_set_synchron_receive_timeout(connection->handler, timeout); free(gdi_timeout); } } cl_com_free_crm_message(&crm_message); CL_LOG_INT(CL_LOG_INFO,"our local comp_id is:", (int)connection->local->comp_id); handler = connection->handler; if (handler != NULL) { if ( handler->local->comp_id == 0 ) { handler->local->comp_id = connection->local->comp_id; CL_LOG_INT(CL_LOG_INFO,"setting handler comp_id to reported client id:", (int)handler->local->comp_id); if ( handler->service_provider == CL_TRUE ) { CL_LOG_INT(CL_LOG_INFO,"setting service handle comp_id to reported client id:", (int)connection->local->comp_id); handler->service_handler->local->comp_id = connection->local->comp_id; } } } else { CL_LOG(CL_LOG_WARNING,"connection has no handler"); } } } return CL_RETVAL_OK; } /* caller has to lock the connection list */ #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_complete_accept()" int cl_com_connection_complete_accept(cl_com_connection_t* connection, long timeout) { if (connection == NULL) { CL_LOG(CL_LOG_ERROR,"connection pointer is NULL"); return CL_RETVAL_PARAMS; } if (connection->connection_state != CL_ACCEPTING) { CL_LOG(CL_LOG_ERROR,"unexpected connection state"); return CL_RETVAL_CONNECTION_STATE_ERROR; } switch(connection->framework_type) { case CL_CT_TCP: { /* tcp framework does not support this state */ return CL_RETVAL_OK; } case CL_CT_SSL: { return cl_com_ssl_connection_complete_accept(connection, timeout); } case CL_CT_UNDEFINED: { break; } } return CL_RETVAL_UNDEFINED_FRAMEWORK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_read()" int cl_com_read(cl_com_connection_t* connection, cl_byte_t* message, unsigned long size, unsigned long* only_one_read) { if (connection == NULL) { return CL_RETVAL_PARAMS; } switch(connection->framework_type) { case CL_CT_TCP: { return cl_com_tcp_read(connection, message, size, only_one_read); } case CL_CT_SSL: { return cl_com_ssl_read(connection, message, size, only_one_read); } case CL_CT_UNDEFINED: { break; } } return CL_RETVAL_UNDEFINED_FRAMEWORK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_connection_complete_shutdown()" int cl_com_connection_complete_shutdown(cl_com_connection_t* connection) { if (connection == NULL) { return CL_RETVAL_PARAMS; } if (connection->connection_state != CL_CLOSING) { CL_LOG(CL_LOG_ERROR,"unexpected connection state"); return CL_RETVAL_CONNECTION_STATE_ERROR; } switch(connection->framework_type) { case CL_CT_TCP: { /* tcp framework does not support this state */ return CL_RETVAL_OK; } case CL_CT_SSL: { return cl_com_ssl_connection_complete_shutdown(connection); } case CL_CT_UNDEFINED: { break; } } return CL_RETVAL_UNDEFINED_FRAMEWORK; } #ifdef __CL_FUNCTION__ #undef __CL_FUNCTION__ #endif #define __CL_FUNCTION__ "cl_com_write()" int cl_com_write(cl_com_connection_t* connection, cl_byte_t* message, unsigned long size, unsigned long *only_one_write) { if (connection == NULL) { return CL_RETVAL_PARAMS; } switch(connection->framework_type) { case CL_CT_TCP: { return cl_com_tcp_write(connection, message, size, only_one_write); } case CL_CT_SSL: { return cl_com_ssl_write(connection, message, size, only_one_write); } case CL_CT_UNDEFINED: { break; } } return CL_RETVAL_UNDEFINED_FRAMEWORK; }