#include "CcCollectdClientSocket.h" #include #include #include #include #include #include #include #include #ifdef __FreeBSD__ #include #include #include #else #include #include #endif #define HOSTNAME_SIZE 256 // »ý¼ºÀÚ. CCcCollectdClientSocket::CCcCollectdClientSocket() : CBaseSocket( SOCKET_NOT_VALID ) , m_nPacketHeaderLen ( sizeof(m_packetHeader)) , m_nPacketDataLen( 0 ) { } // ¼Ò¸êÀÚ CCcCollectdClientSocket::~CCcCollectdClientSocket() { // ¼Ò¸êÀÚ Socket ¸í½ÃÀû Close ó¸®. Close(); } // Packet Header Á¤º¸¸¦ Log ÆÄÀÏ¿¡ Logging ó¸® void CCcCollectdClientSocket::PrintHeaderToLog() { _LOG( LINF, "------------------------------------" ); _LOG( LINF, "stx [%02x]", m_packetHeader.stx ); _LOG( LINF, "type [%02x]", m_packetHeader.type ); _LOG( LINF, "command [%02x][%02x][%02x][%02x]", m_packetHeader.command[0], m_packetHeader.command[1], m_packetHeader.command[2], m_packetHeader.command[3] ); _LOG( LINF, "result [%02x][%02x][%02x][%02x]", m_packetHeader.result[0], m_packetHeader.result[1], m_packetHeader.result[2], m_packetHeader.result[3] ); _LOG( LINF, "data_length [%u]", m_nPacketDataLen ); _LOG( LINF, "extend_code [%02x][%02x]", m_packetHeader.extend_code[0], m_packetHeader.extend_code[1] ); _LOG( LINF, "------------------------------------" ); } // socket ¿¡¼­ ÁöÁ¤µÈ Å©±â¸¸Å­ÀÇ µ¥ÀÌÅ͸¦ ÀÐ¾î ³»ºÎ ÀӽùöÆÛÀÎ m_tempBuffer ¿¡ ÀúÀåó¸®. // @param size [in] read ÇÒ µ¥ÀÌÅÍ Å©±â // @return On success return true, otherwise return false. bool CCcCollectdClientSocket::GetPacketData( unsigned int size ) { // 1. ¼ö½ÅÇÒ Å©±â°¡ ÀӽùöÆÛº¸´Ù Å« °æ¿ì ¿À·ù ¹Ýȯ. if( size > DEFAULT_SOCKET_TEMP_BUFFER_SIZE ) return false; // 2. µ¥ÀÌÅÍ ¼ö½Å ó¸®. int nRead = ReadNTimeout( m_tempBuffer, size ); // ¿À·ù ¹ß»ý½Ã if( nRead <= 0 ) return false; // 3. Á¤»óÀÎ °æ¿ì´Â ReadNTimeout ÇÔ¼ö°¡ ¹«Á¶°Ç ¿äû Å©±â¸¸Å­ read ó¸®ÇϹǷΠÁ¤»ó¼ö½ÅÀÓ. return true; } // socket ¿¡¼­ ÁöÁ¤µÈ Å©±â¸¸Å­ÀÇ µ¥ÀÌÅ͸¦ Àоî Ãâ·Âº¯¼ö¿¡ ÀúÀåó¸®. // @param size [in] read ÇÒ µ¥ÀÌÅÍ Å©±â // @param value [out] ÀÐÀº µ¥ÀÌÅ͸¦ ÀúÀåÇÒ string º¯¼ö // @return On success return true, otherwise return false. bool CCcCollectdClientSocket::GetPacketData( unsigned int& size, std::string& value ) { // 1. ¼ö½ÅÇÒ Å©±â°¡ ÀӽùöÆÛº¸´Ù Å« °æ¿ì »õ·Î¿î ¹öÆÛ¸¦ »ý¼ºÇÑ´Ù. BYTE * pBuffer = NULL; bool bNewBufferCreated = false; if( size > DEFAULT_SOCKET_TEMP_BUFFER_SIZE ) { pBuffer = new BYTE[size]; // ½Å±Ô ¸Þ¸ð¸® ÇÒ´ç. bNewBufferCreated = true; } else pBuffer = m_tempBuffer; // 2. µ¥ÀÌÅÍ ¼ö½Å ó¸®. int nRead = ReadNTimeout( pBuffer, size ); // ¿À·ù ¹ß»ý½Ã if( nRead <= 0 ) { // ½Å±Ô·Î »ý¼ºµÈ ¹öÆÛÀÎ °æ¿ì ¸Þ¸ð¸® ÇØÁ¦ ó¸®. if( bNewBufferCreated == true ) delete[] pBuffer; return false; } // 3. ¼ö½Å µ¥ÀÌÅÍ ÀúÀå ó¸® - ±âÁ¸ µ¥ÀÌÅÍ µÚ¿¡ ºÙ¿© ÁØ´Ù=> ÀÌ°Ô »ç¿ëÇÏ±â ÆíÇÔ. value.append( (char *)pBuffer, size ); // ½Å±Ô·Î »ý¼ºµÈ ¹öÆÛÀÎ °æ¿ì ¸Þ¸ð¸® ÇØÁ¦ ó¸®. if( bNewBufferCreated == true ) delete[] pBuffer; return true; } // pValue ¿¡ ÀúÀåµÈ µ¥ÀÌÅ͸¦ unsigned long long (64Byte) ÇüÀ¸·Î º¯È¯Ã³¸® ¹× Endian º¯È¯ unsigned long long CCcCollectdClientSocket::GetDataToUInt64( BYTE * pValue, bool bConvertEndian ) { BYTE tempBuffer[8]; unsigned long long result; memcpy( tempBuffer, pValue, 8 ); unsigned long long * pResult = ( unsigned long long * )tempBuffer; // Endian º¯È¯Ã³¸®. if( bConvertEndian == true ) { // Network byte order (big endian) À» Host byte order ·Î º¯È¯ ó¸® //result = be64toh( *pResult ); result = do_ntohll( *pResult ); } else result = *pResult; return result; } // Packet Á¤º¸ Áß String Á¤º¸¸¦ Àü¼ÛÇϱâ À§ÇÑ ÇÔ¼ö. bool CCcCollectdClientSocket::SendString( const std::string& strData ) { if( IsValidSocket() == false ) return false; // Å©±â°ªÀ» ÀúÀåÇϱâ À§ÇÑ Àӽà º¯¼ö. unsigned int nSize = 0; // String Data Àü¼Û nSize = htonl( strData.size() ); WriteN( &nSize, 4 ); if( strData.size() > 0 ) WriteN( strData.c_str(), strData.size() ); return true; } // byte ordering function for 64bit variable uint64_t CCcCollectdClientSocket::do_htonll( uint64_t hostlonglong ) { int x = 1; /* little endian */ if( *(char *)&x == 1 ) return ( ( ( (uint64_t)htonl( hostlonglong ) ) << 32 ) + htonl( hostlonglong >> 32 ) ); /* big endian */ else return hostlonglong; } uint64_t CCcCollectdClientSocket::do_ntohll( uint64_t netlonglong ) { int x = 1; /* little endian */ if( *(char *)&x == 1 ) return ( ( ( (uint64_t)ntohl( netlonglong ) ) << 32 ) + ntohl( netlonglong >> 32 ) ); /* big endian */ else return netlonglong; } ///////////////////////////////////////////////////////////////// // Àü´Þ¹ÞÀº Target À¸·Î Socket Á¢¼ÓÀ» ¼öÇà bool CCcCollectdClientSocket::ConnectTarget( const std::string& szTarget, int nPort ) { return Connect( szTarget, nPort ); } // cc_collect ·ÎºÎÅÍ available size Á¤º¸¸¦ ¿äû, °á°ú¸¦ ¼ö½Åó¸®ÇÑ´Ù. bool CCcCollectdClientSocket::GetAvailableSize( unsigned long long& uSize ) { if( IsValidSocket() == false ) return false; // Á¤º¸ ¿äûÀ» À§ÇÑ Packet Header »ý¼º. struct CcCollectdPacketHeader stHeader; memset( &stHeader, 0x00, sizeof( struct CcCollectdPacketHeader ) ); stHeader.stx = HEADER_STX_CODE; stHeader.type = HEADER_TYPE_REQUEST; stHeader.command[0] = REQUEST_AVAILABLE_SIZE; // Data ºÎºÐÀÇ ±æÀ̸¦ °è»êÇÑ´Ù. // - Data ºÎºÐ ±æÀÌ´Â ¾øÀ½. stHeader.data_length = htonl( 0 ); // Packet Header Á¤º¸ Àü¼Û if( WriteN( &stHeader, m_nPacketHeaderLen ) != m_nPacketHeaderLen ) { LOG( LERR, "request [REQUEST_AVAILABLE_SIZE] send fail to cc_collectd. " ); return false; } // ÀÀ´ä ´ë±â... // ÃÖ´ë 3ºÐ ´ë±â int nTimeout = 60 * 3; // ÃÖ´ë 3ºÐ°£ ´ë±â int nRead; // Socket À¸·Î ºÎÅÍ Packet Header ºÎºÐ ¼ö½Å. // ¼ö½ÅµÈ Á¤º¸´Â ¸â¹öº¯¼ö¿¡ ÀúÀåó¸®. nRead = ReadNTimeout( &m_packetHeader, m_nPacketHeaderLen, nTimeout ); // nRead 0: Socket Closed // -1: error // -2: Timeout À̹ǷΠif( nRead == -2 ) { // Timeout ¹ß»ý½Ã LOG( LERR, "cc_collectd REQUEST_AVAILABLE_SIZE reponse wait. but timeout[%d sec] occured.", nTimeout ); return false; } else if( nRead == 0 || nRead == -1 ) { // Socket Close ¶Ç´Â ¿À·ù ¹ß»ý½Ã LOG( LERR, "cc_collectd REQUEST_AVAILABLE_SIZE reponse wait. but socket closed or error [%d]", nRead ); return false; } // STX code °Ë»ç. if( m_packetHeader.stx != HEADER_STX_CODE ) { LOG( LERR, "Not valid stx code." ); PrintHeaderToLog(); return false; } // Data Length ºÎºÐ °ªÀ» ¸â¹ö º¯¼ö¿¡ ÀúÀåó¸®. m_nPacketDataLen = ntohl( m_packetHeader.data_length ); // ÇØ´ç Packet ¿¡ ´ëÇÑ ÀÀ´äÆÐŶÀÎÁö °Ë»ç. if( m_packetHeader.type != HEADER_TYPE_RESPONSE || m_packetHeader.command[0] != REQUEST_AVAILABLE_SIZE ) { // ´Ù¸¥ ÆÐŶÀÌ µé¾î¿Â °æ¿ì // ** Á¤¼®´ë·Î¶ó¸é ±×³É ³ÀµÖ¾î ¼ö½ÅºÎ¿¡¼­ ó¸®ÇØ¾ß ÇÏÁö¸¸ // ÇöÀç ¼ö½Å 󸮺ΰ¡ ¾ø¾î ´çÀå ¹®Á¦°¡ »ý±æ¼ö ÀÖÀ¸¹Ç·Î // µ¥ÀÌÅÍ ºÎºÐ±îÁö ¼ö½ÅÇÏ¿© ÀӽùöÆÛ¿¡ ÀúÀåó¸® ÇØ ³õ´Â´Ù. GetPacketData( m_nPacketDataLen ); return false; } // Data ºÎºÐÀÌ Á¸ÀçÇÏ´Â °æ¿ì.. ¼ö½Å ó¸®. if( m_nPacketDataLen > 0 ) { // Data Ç׸ñÀº // - 8 Byte Network byte order ·Î ±¸¼ºµÈ available size Á¤º¸°¡ µé¾î ÀÖÀ½. if( GetPacketData( m_nPacketDataLen ) == false ) { LOG( LERR, "available size body receive failed." ); return false; } BYTE * pPos = m_tempBuffer; uSize = GetDataToUInt64( pPos, true ); } else { // cc_collectd ·Î ºÎÅÍ Available size ÀÀ´äÀ» ¹Þ¾ÒÁö¸¸.. body °¡ ¾ø´Â °æ¿ì. // ÀÌ·± °æ¿ì´Â ¾øÁö¸¸.. ¿À·ù 󸮸¦ À§ÇØ ÄÚµù. LOG( LERR, "available size body length zero. check." ); return false; } _LOG( LDBG, "cc_collectd available size result received. [%llu]", uSize ); return true; } // cc_collect ·Î File ÀúÀå ¸ñÀûÀ¸·Î Àü¼Û bool CCcCollectdClientSocket::SendFile( const std::string strProcessName, const std::string strFileName , const int& fd, const unsigned long long& uFileSize , std::string& strMessage ) { // ÀÔ·Â ¹ÞÀº Á¤º¸°¡ À¯È¿ÇÑÁö °Ë»ç. // strProcessName : »ý·« °¡´ÉÇÏÁö¸¸.. ¹®ÀÚ¿­¿¡ '/' °¡ Æ÷ÇԵǼ­´Â ¾ÈµÈ´Ù. // strFileName : »ý·« ºÒ°¡, ¹®ÀÚ¿­¿¡ '/' °¡ Æ÷ÇԵǼ­´Â ¾ÈµÈ´Ù. if( strProcessName.empty() == false ) { std::string::size_type pos = strProcessName.find( '/' ); if( pos != std::string::npos ) { // '/' ¹®ÀÚ°¡ Æ÷ÇÔµÈ °æ¿ì... char tempBuffer[1024]; snprintf( tempBuffer, sizeof( tempBuffer ) - 1 , "process name[%s] not valid that include slash." , strProcessName.c_str() ); strMessage.append( tempBuffer ); LOG( LERR, "%s", strMessage.c_str() ); return false; } } if( strFileName.empty() == false ) { std::string::size_type pos = strFileName.find( '/' ); if( pos != std::string::npos ) { // '/' ¹®ÀÚ°¡ Æ÷ÇÔµÈ °æ¿ì... char tempBuffer[1024]; snprintf( tempBuffer, sizeof( tempBuffer ) - 1 , "file name[%s] not valid that include slash." , strFileName.c_str() ); strMessage.append( tempBuffer ); LOG( LERR, "%s", strMessage.c_str() ); return false; } } else { // filename ÀÌ ¾ø´Â °æ¿ì. strMessage = "filename not vaild. empty."; LOG( LERR, "filename not vaild. empty." ); return false; } unsigned long long uAvailableSize = 0; // 1. cc_collectd ·Î ºÎÅÍ available size Á¤º¸¸¦ ¼ö½Å if( GetAvailableSize( uAvailableSize ) == false ) { // available size üũ ½ÇÆÐ½Ã... strMessage = "cc_collectd available size check fail."; return false; } // 2. ¼ö½ÅµÈ uAvailableSize °ú Àü¼ÛÇÒ File size ºñ±³ if( uAvailableSize <= uFileSize ) { char tempBuffer[1024]; snprintf( tempBuffer, sizeof( tempBuffer ) - 1 , "file size[%llu] too large than cc_collect available size [%llu]" , uFileSize, uAvailableSize ); strMessage.append( tempBuffer ); LOG( LERR, "%s", strMessage.c_str() ); return false; } // 3. ÀåºñÀÇ hostname Á¤º¸¸¦ ÃßÃâÇÑ´Ù. char szHostName[HOSTNAME_SIZE]; memset( szHostName, 0x00, HOSTNAME_SIZE ); if( gethostname( szHostName, HOSTNAME_SIZE - 1 ) != 0 ) { int errorNum = errno; strMessage = "hostname get failed. check hostname."; LOG( LERR, "hostname get failed. [%d][%s]", errorNum, strerror( errorNum ) ); return false; } if( strlen( szHostName ) == 0 ) { strMessage = "hostname not vaild. check hostname."; LOG( LERR, "hostname not valid. length 0" ); return false; } std::string strHostName = szHostName; // ÃßÃâµÈ hostname Á¤º¸¸¦ Àü¼ÛÇÏ±â ÆíÇϵµ·Ï string °´Ã¼¿¡ ÀúÀåó¸®. // 4. ÆÄÀÏ Àü¼Û °ü·Ã ¿äû ¼Û½Å struct CcCollectdPacketHeader stHeader; memset( &stHeader, 0x00, sizeof( struct CcCollectdPacketHeader ) ); stHeader.stx = HEADER_STX_CODE; stHeader.type = HEADER_TYPE_REQUEST; stHeader.command[0] = REQUEST_FILE_SAVE; // Data ºÎºÐ // strHostName : string ( 4 + string.size() ) // strProcessName : string ( 4 + string.size() ) // strFileName : string ( 4 + string.size() ) // uFileSize : 8 Byte ---------->º» Ç׸ñ±îÁö¸¸ header data_length ¿¡ Æ÷ÇÔ½ÃŲ´Ù. // ÀúÀåÇÒ ÆÄÀÏ ³»¿ë. // Data ºÎºÐÀÇ ±æÀ̸¦ °è»êÇÑ´Ù. unsigned int nTemp = 0; nTemp += ( 4 + strHostName.size() ); // strHostName nTemp += ( 4 + strProcessName.size() ); // strProcessName nTemp += ( 4 + strFileName.size() ); // strFileName nTemp += 8; // uFileSize stHeader.data_length = htonl( nTemp ); // Packet Header Á¤º¸ Àü¼Û if( WriteN( &stHeader, m_nPacketHeaderLen ) != m_nPacketHeaderLen ) { strMessage = "request [REQUEST_FILE_SAVE] send fail to cc_collectd."; LOG( LERR, "%s", strMessage.c_str() ); return false; } // Body ºÎºÐ Àü¼Û // strHostName SendString( strHostName ); // strProcessName SendString( strProcessName ); // strFileName SendString( strFileName ); // uFileSize (Network byte order ) //uAvailableSize = htobe64( uFileSize ); uAvailableSize = do_htonll( uFileSize ); WriteN( &uAvailableSize, 8 ); // ÆÄÀÏ ³»¿ë Àü¼Û if( uFileSize > 0 ) { off_t offset = 0; // sendfile() ¿¡ ´ëÇÑ ÇÔ¼ö Á¤Àǰ¡ Linux, FreeBSD ¿¡¼­ ´Ù¸£¹Ç·Î.. OS º°·Î ó¸®ÇÑ´Ù. #ifdef __FreeBSD__ // FreeBSD ÀÇ °æ¿ì.. 10G ±îÁö Àü¼Û Å×½ºÆ® µÊ. off_t sbytes; int ret = sendfile( fd, m_sock, offset, uFileSize, NULL, &sbytes, 0 ); if( ret == -1 ) { int errorNum = errno; LOG( LERR, "sendfile function error. [%d][%s]", errorNum, strerror( errorNum ) ); // Àü¼Û ½ÇÆÐ ¹ß»ý½Ã... strMessage = "file send fail to cc_collectd"; return false; } else if( ( unsigned long long )sbytes != uFileSize ) { LOG( LERR, "sendfile error. file[%s] size[%llu] send size[%ld]", strFileName.c_str(), uFileSize, sbytes ); strMessage = "file send fail to cc_collectd. file size not match."; return false; } #else // Linux ÀÇ °æ¿ì sendfile ÇÔ¼ö°¡ 2G ±îÁö¸¸ Àü¼Û °¡´ÉÇϹǷÎ....·çÇÁ·Î Àü¼Û 󸮰¡ µÇµµ·Ï ó¸®ÇÑ´Ù. ssize_t bytes_sent; size_t total_bytes_sent = 0; while( total_bytes_sent < uFileSize ) { if( (bytes_sent = sendfile(m_sock, fd, &offset, uFileSize - total_bytes_sent)) <= 0 ) { int errorNum = errno; if (errorNum == EINTR || errorNum == EAGAIN) { // Interrupted system call/try again // Just skip to the top of the loop and try again continue; } else { LOG( LERR, "sendfile function error. [%d][%s]", errorNum, strerror( errorNum ) ); // Àü¼Û ½ÇÆÐ ¹ß»ý½Ã... strMessage = "file send fail to cc_collectd"; return false; } } total_bytes_sent += bytes_sent; } if( ( unsigned long long )total_bytes_sent != uFileSize ) { LOG( LERR, "sendfile error. file[%s] size[%llu] send size[%ld]", strFileName.c_str(), uFileSize, total_bytes_sent ); strMessage = "file send fail to cc_collectd. file size not match."; return false; } #endif } // 5. File Àü¼Û ó¸® °á°ú ¼ö½Å. // - ÃÖ´ë 10 ºÐ µ¿¾È ÀÀ´ä ´ë±â int nTimeout = 60 * 10; // ÃÖ´ë 10ºÐ°£ ´ë±â int nRead; // Socket À¸·Î ºÎÅÍ Packet Header ºÎºÐ ¼ö½Å. // ¼ö½ÅµÈ Á¤º¸´Â ¸â¹öº¯¼ö¿¡ ÀúÀåó¸®. nRead = ReadNTimeout( &m_packetHeader, m_nPacketHeaderLen, nTimeout ); // nRead 0: Socket Closed // -1: error // -2: Timeout À̹ǷΠif( nRead == -2 ) { // Timeout ¹ß»ý½Ã LOG( LERR, "cc_collectd REQUEST_FILE_SAVE reponse wait. but timeout[%d sec] occured.", nTimeout ); strMessage = "cc_collectd REQUEST_FILE_SAVE reponse timeout[10 min] occured."; return false; } else if( nRead == 0 || nRead == -1 ) { // Socket Close ¶Ç´Â ¿À·ù ¹ß»ý½Ã LOG( LERR, "cc_collectd REQUEST_FILE_SAVE reponse wait. but socket closed or error [%d]", nRead ); strMessage = "cc_collectd REQUEST_FILE_SAVE reponse wait. but session closed."; return false; } // STX code °Ë»ç. if( m_packetHeader.stx != HEADER_STX_CODE ) { LOG( LERR, "Not valid stx code." ); strMessage = "cc_collectd REQUEST_FILE_SAVE reponse not valid."; PrintHeaderToLog(); return false; } // Data Length ºÎºÐ °ªÀ» ¸â¹ö º¯¼ö¿¡ ÀúÀåó¸®. m_nPacketDataLen = ntohl( m_packetHeader.data_length ); // ÇØ´ç Packet ¿¡ ´ëÇÑ ÀÀ´äÆÐŶÀÎÁö °Ë»ç. if( m_packetHeader.type != HEADER_TYPE_RESPONSE || m_packetHeader.command[0] != REQUEST_FILE_SAVE ) { // ´Ù¸¥ ÆÐŶÀÌ µé¾î¿Â °æ¿ì // ** Á¤¼®´ë·Î¶ó¸é ±×³É ³ÀµÖ¾î ¼ö½ÅºÎ¿¡¼­ ó¸®ÇØ¾ß ÇÏÁö¸¸ // ÇöÀç ¼ö½Å 󸮺ΰ¡ ¾ø¾î ´çÀå ¹®Á¦°¡ »ý±æ¼ö ÀÖÀ¸¹Ç·Î // µ¥ÀÌÅÍ ºÎºÐ±îÁö ¼ö½ÅÇÏ¿© ÀӽùöÆÛ¿¡ ÀúÀåó¸® ÇØ ³õ´Â´Ù. GetPacketData( m_nPacketDataLen ); strMessage = "cc_collectd REQUEST_FILE_SAVE reponse not valid."; return false; } // Data ºÎºÐÀÌ Á¸ÀçÇÏ´Â °æ¿ì.. ¼ö½Å ó¸®. if( m_nPacketDataLen > 0 ) { if( GetPacketData( m_nPacketDataLen, strMessage ) == false ) { LOG( LERR, "cc_collectd REQUEST_FILE_SAVE body receive failed." ); strMessage = "cc_collectd REQUEST_FILE_SAVE body receive failed."; return false; } } // ¼º°ø ½ÇÆÐ ¿©ºÎ È®ÀÎ if( m_packetHeader.result[0] != HEADER_RESULT_SUCCESS ) { _LOG( LDBG, "cc_collectd REQUEST_FILE_SAVE result received. error[%s]", strMessage.c_str() ); return false; } else { _LOG( LDBG, "cc_collectd REQUEST_FILE_SAVE result received. success." ); return true; } } // cc_collect ·Î File Á¸Àç ¿©ºÎ È®ÀÎ bool CCcCollectdClientSocket::CheckFile( const std::string strProcessName, const std::string strFileName , unsigned long long& uFileSize, std::string& strErrorMessage ) { // ÀÔ·Â ¹ÞÀº Á¤º¸°¡ À¯È¿ÇÑÁö °Ë»ç. // strProcessName : »ý·« °¡´ÉÇÏÁö¸¸.. ¹®ÀÚ¿­¿¡ '/' °¡ Æ÷ÇԵǼ­´Â ¾ÈµÈ´Ù. // strFileName : »ý·« ºÒ°¡, ¹®ÀÚ¿­¿¡ '/' °¡ Æ÷ÇԵǼ­´Â ¾ÈµÈ´Ù. if( strProcessName.empty() == false ) { std::string::size_type pos = strProcessName.find( '/' ); if( pos != std::string::npos ) { // '/' ¹®ÀÚ°¡ Æ÷ÇÔµÈ °æ¿ì... char tempBuffer[1024]; snprintf( tempBuffer, sizeof( tempBuffer ) - 1 , "process name[%s] not valid that include slash." , strProcessName.c_str() ); strErrorMessage.append( tempBuffer ); LOG( LERR, "%s", strErrorMessage.c_str() ); return false; } } if( strFileName.empty() == false ) { std::string::size_type pos = strFileName.find( '/' ); if( pos != std::string::npos ) { // '/' ¹®ÀÚ°¡ Æ÷ÇÔµÈ °æ¿ì... char tempBuffer[1024]; snprintf( tempBuffer, sizeof( tempBuffer ) - 1 , "file name[%s] not valid that include slash." , strFileName.c_str() ); strErrorMessage.append( tempBuffer ); LOG( LERR, "%s", strErrorMessage.c_str() ); return false; } } else { // filename ÀÌ ¾ø´Â °æ¿ì. strErrorMessage = "filename not vaild. empty."; LOG( LERR, "filename not vaild. empty." ); return false; } // ÀåºñÀÇ hostname Á¤º¸¸¦ ÃßÃâÇÑ´Ù. char szHostName[HOSTNAME_SIZE]; memset( szHostName, 0x00, HOSTNAME_SIZE ); if( gethostname( szHostName, HOSTNAME_SIZE - 1 ) != 0 ) { int errorNum = errno; strErrorMessage = "hostname get failed. check hostname."; LOG( LERR, "hostname get failed. [%d][%s]", errorNum, strerror( errorNum ) ); return false; } if( strlen( szHostName ) == 0 ) { strErrorMessage = "hostname not vaild. check hostname."; LOG( LERR, "hostname not valid. length 0" ); return false; } std::string strHostName = szHostName; // ÃßÃâµÈ hostname Á¤º¸¸¦ Àü¼ÛÇÏ±â ÆíÇϵµ·Ï string °´Ã¼¿¡ ÀúÀåó¸®. // ÆÄÀÏ Check °ü·Ã ¿äû ¼Û½Å struct CcCollectdPacketHeader stHeader; memset( &stHeader, 0x00, sizeof( struct CcCollectdPacketHeader ) ); stHeader.stx = HEADER_STX_CODE; stHeader.type = HEADER_TYPE_REQUEST; stHeader.command[0] = REQUEST_FILE_CHECK; // Data ºÎºÐ // strHostName : string ( 4 + string.size() ) // strProcessName : string ( 4 + string.size() ) // strFileName : string ( 4 + string.size() ) // Data ºÎºÐÀÇ ±æÀ̸¦ °è»êÇÑ´Ù. unsigned int nTemp = 0; nTemp += ( 4 + strHostName.size() ); // strHostName nTemp += ( 4 + strProcessName.size() ); // strProcessName nTemp += ( 4 + strFileName.size() ); // strFileName stHeader.data_length = htonl( nTemp ); // Packet Header Á¤º¸ Àü¼Û if( WriteN( &stHeader, m_nPacketHeaderLen ) != m_nPacketHeaderLen ) { strErrorMessage = "request [REQUEST_FILE_CHECK] send fail to cc_collectd."; LOG( LERR, "%s", strErrorMessage.c_str() ); return false; } // Body ºÎºÐ Àü¼Û // strHostName SendString( strHostName ); // strProcessName SendString( strProcessName ); // strFileName SendString( strFileName ); // File Check ó¸® °á°ú ¼ö½Å. // - ÃÖ´ë 30 sec µ¿¾È ÀÀ´ä ´ë±â int nTimeout = 30; int nRead; // Socket À¸·Î ºÎÅÍ Packet Header ºÎºÐ ¼ö½Å. // ¼ö½ÅµÈ Á¤º¸´Â ¸â¹öº¯¼ö¿¡ ÀúÀåó¸®. nRead = ReadNTimeout( &m_packetHeader, m_nPacketHeaderLen, nTimeout ); // nRead 0: Socket Closed // -1: error // -2: Timeout À̹ǷΠif( nRead == -2 ) { // Timeout ¹ß»ý½Ã LOG( LERR, "cc_collectd REQUEST_FILE_CHECK reponse wait. but timeout[%d sec] occured.", nTimeout ); strErrorMessage = "cc_collectd REQUEST_FILE_CHECK reponse timeout[30 sec] occured."; return false; } else if( nRead == 0 || nRead == -1 ) { // Socket Close ¶Ç´Â ¿À·ù ¹ß»ý½Ã LOG( LERR, "cc_collectd REQUEST_FILE_CHECK reponse wait. but socket closed or error [%d]", nRead ); strErrorMessage = "cc_collectd REQUEST_FILE_CHECK reponse wait. but session closed."; return false; } // STX code °Ë»ç. if( m_packetHeader.stx != HEADER_STX_CODE ) { LOG( LERR, "Not valid stx code." ); strErrorMessage = "cc_collectd REQUEST_FILE_CHECK reponse not valid."; PrintHeaderToLog(); return false; } // Data Length ºÎºÐ °ªÀ» ¸â¹ö º¯¼ö¿¡ ÀúÀåó¸®. m_nPacketDataLen = ntohl( m_packetHeader.data_length ); // ÇØ´ç Packet ¿¡ ´ëÇÑ ÀÀ´äÆÐŶÀÎÁö °Ë»ç. if( m_packetHeader.type != HEADER_TYPE_RESPONSE || m_packetHeader.command[0] != REQUEST_FILE_CHECK ) { // ´Ù¸¥ ÆÐŶÀÌ µé¾î¿Â °æ¿ì // ** Á¤¼®´ë·Î¶ó¸é ±×³É ³ÀµÖ¾î ¼ö½ÅºÎ¿¡¼­ ó¸®ÇØ¾ß ÇÏÁö¸¸ // ÇöÀç ¼ö½Å 󸮺ΰ¡ ¾ø¾î ´çÀå ¹®Á¦°¡ »ý±æ¼ö ÀÖÀ¸¹Ç·Î // µ¥ÀÌÅÍ ºÎºÐ±îÁö ¼ö½ÅÇÏ¿© ÀӽùöÆÛ¿¡ ÀúÀåó¸® ÇØ ³õ´Â´Ù. GetPacketData( m_nPacketDataLen ); strErrorMessage = "cc_collectd REQUEST_FILE_CHECK reponse not valid."; return false; } // ¼º°ø ½ÇÆÐ ¿©ºÎ È®ÀÎ if( m_packetHeader.result[0] == HEADER_RESULT_SUCCESS ) { // ¼º°øÀÎ °æ¿ì... // - File Size Á¤º¸¸¦ ¼ö½Å ó¸®ÇÑ´Ù. // Data Ç׸ñÀº // - 8 Byte Network byte order ·Î ±¸¼ºµÈ available size Á¤º¸°¡ µé¾î ÀÖÀ½. if( GetPacketData( m_nPacketDataLen ) == false ) { LOG( LERR, "cc_collectd REQUEST_FILE_CHECK file size body receive failed." ); strErrorMessage = "cc_collectd REQUEST_FILE_CHECK file size body receive failed."; return false; } BYTE * pPos = m_tempBuffer; uFileSize = GetDataToUInt64( pPos, true ); return true; } else { // ¿À·ù°¡ ¹ß»ýÇÑ °æ¿ì.. // - ¼ö½ÅÇÒ ¸Þ½ÃÁö°¡ Á¸ÀçÇÏ´Â °æ¿ì.. ¼ö½Å ó¸®ÇÑ´Ù. if( m_nPacketDataLen > 0 ) { if( GetPacketData( m_nPacketDataLen, strErrorMessage ) == false ) { LOG( LERR, "cc_collectd REQUEST_FILE_CHECK error body receive failed." ); strErrorMessage = "cc_collectd REQUEST_FILE_CHECK error body receive failed."; return false; } } // ¿À·ù ¹Ýȯ ó¸®. return false; } }