00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <string.h>
00021 #include <sys/socket.h>
00022 #include <netinet/in.h>
00023 #include <arpa/inet.h>
00024 #include <time.h>
00025 #include <poll.h>
00026 #include <unistd.h>
00027 #include <fcntl.h>
00028
00029
00030 #include <sys/syscall.h>
00031
00032
00033 #include <httpd.h>
00034
00035
00036 #include "RioError.h"
00037 #include "RioUnix.h"
00038 #include "UserLogs.h"
00039
00040
00041 CServerUserLogs::CServerUserLogs( server_rec *Server )
00042 {
00043
00044 m_Initialized = false;
00045 m_ServerUserLogsThread = 0;
00046 m_LogRotation = NULL;
00047 m_Socket = 0;
00048 memset( &m_SocketAddr, 0, sizeof( m_SocketAddr ) );
00049 m_Server = Server;
00050 m_LogsServerPort = 0;
00051 }
00052
00053
00054 CServerUserLogs::~CServerUserLogs()
00055 {
00056
00057
00058 char NullStr[ MAXLOGLINESIZE ];
00059
00060
00061 pthread_t ServerUserLogsThread;
00062
00063
00064
00065
00066 if( m_ServerUserLogsThread != 0 )
00067 {
00068
00069 ServerUserLogsThread = m_ServerUserLogsThread;
00070
00071 memset( NullStr, 0, MAXLOGLINESIZE );
00072
00073
00074 if( sendto( m_Socket, NullStr, MAXLOGLINESIZE, UDP_FLAGS_SENDDATA,
00075 ( struct sockaddr * ) &m_SocketAddr,
00076 sizeof( m_SocketAddr ) ) < 0 )
00077 {
00078
00079
00080 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error %u (%s) "
00081 "when finalizing object! killing the thread!", errno,
00082 strerror( errno ) );
00083 pthread_cancel( ServerUserLogsThread );
00084 }
00085 else
00086 {
00087 #ifdef RIO_DEBUG2
00088 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Esperando a "
00089 "thread que recebe os logs terminar de executar!" );
00090 #endif
00091
00092 pthread_join( ServerUserLogsThread, NULL );
00093 }
00094 }
00095
00096
00097 if( m_LogRotation != NULL )
00098 delete m_LogRotation;
00099
00100
00101 if( m_Socket != 0 )
00102 {
00103 shutdown( m_Socket, SHUT_RDWR );
00104 close( m_Socket );
00105 }
00106 }
00107
00108
00109 RioResult CServerUserLogs::ReceiveLogLine( char *LogLine, int *Port )
00110 {
00111
00112 ssize_t BytesReceived;
00113
00114
00115
00116 struct sockaddr_in SourceAddr;
00117
00118 socklen_t SourceAddrSize;
00119
00120
00121
00122 memset( LogLine, 0, MAXLOGLINESIZE + 1 );
00123
00124
00125 #ifdef RIO_DEBUG2
00126 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Tentando receber a "
00127 "linha com %u bytes pelo socket UDP!", MAXLOGLINESIZE );
00128 #endif
00129
00130 SourceAddrSize = sizeof( SourceAddr );
00131 BytesReceived = recvfrom( m_Socket, LogLine, MAXLOGLINESIZE,
00132 UDP_FLAGS_RECEIVE,
00133 ( struct sockaddr * ) &SourceAddr,
00134 &SourceAddrSize );
00135
00136 *Port = SourceAddr.sin_port;
00137
00138 if( BytesReceived < 0 )
00139 {
00140 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error %d (%s) "
00141 "receiving log line from UDP socket!", errno,
00142 strerror( errno ) );
00143
00144 return ERROR_SERVERUSERLOGS + ERROR_SOCKET_RECEIVE;
00145 }
00146 else if( SourceAddr.sin_addr.s_addr != m_SocketAddr.sin_addr.s_addr )
00147 {
00148 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Log Line "
00149 "received from invalid address ip %s and port %u, "
00150 "different from ip %s and port %u!",
00151 inet_ntoa( SourceAddr.sin_addr ),
00152 ntohs( SourceAddr.sin_port ),
00153 inet_ntoa( m_SocketAddr.sin_addr ),
00154 ntohs( m_SocketAddr.sin_port ) );
00155
00156 return ERROR_SERVERUSERLOGS + ERROR_INVALID_HOST;
00157
00158 }
00159 else if( ( unsigned int ) BytesReceived != MAXLOGLINESIZE )
00160 {
00161 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error receiving "
00162 "log line from UDP socket! Only %u bytes of %u has "
00163 "received!", BytesReceived, MAXLOGLINESIZE );
00164
00165 return ERROR_SERVERUSERLOGS + ERROR_SOCKET_RECEIVE;
00166 }
00167
00168 #ifdef RIO_DEBUG2
00169 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Linha de log %s "
00170 "recebida com sucesso pela conexao UDP pela porta %u!",
00171 LogLine, ntohs( *Port ) );
00172 #endif
00173
00174 return S_OK;
00175 }
00176
00177
00178
00179 RioResult CServerUserLogs::SendResult( int Result, int Port )
00180 {
00181
00182 struct sockaddr_in DestAddr;
00183
00184 ssize_t BytesSent;
00185
00186
00187 memset( &DestAddr, 0, sizeof( DestAddr ) );
00188
00189
00190 DestAddr.sin_family = AF_INET;
00191 DestAddr.sin_addr.s_addr = m_SocketAddr.sin_addr.s_addr;
00192 DestAddr.sin_port = Port;
00193
00194 #ifdef RIO_DEBUG2
00195 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Tentando enviar o "
00196 "resultado %08X pelo socket UDP para o IP %s e a porta %u, a "
00197 "partir do IP %s e da porta %u!", Result,
00198 inet_ntoa( DestAddr.sin_addr ), ntohs( DestAddr.sin_port ),
00199 inet_ntoa( m_SocketAddr.sin_addr ),
00200 ntohs( m_SocketAddr.sin_port ) );
00201 #endif
00202
00203
00204 BytesSent = sendto( m_Socket, &Result, sizeof( Result ),
00205 UDP_FLAGS_SENDDATA, ( struct sockaddr * ) &DestAddr,
00206 sizeof( DestAddr ) );
00207 if( BytesSent < 0 )
00208 {
00209 #ifdef RIO_DEBUG2
00210 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error %d (%s) "
00211 "sending result value %08X to UDP socket!", errno,
00212 strerror( errno ), Result );
00213 #endif
00214
00215 return ERROR_SERVERUSERLOGS + ERROR_SOCKET_SEND;
00216 }
00217 else if( BytesSent != sizeof( Result ) )
00218 {
00219 #ifdef RIO_DEBUG2
00220 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error sending "
00221 "result value %08X to UDP socket! Only %u bytes of "
00222 "%u has sent!", Result, BytesSent, sizeof( Result ) );
00223 #endif
00224
00225 return ERROR_SERVERUSERLOGS + ERROR_SOCKET_SEND;
00226 }
00227
00228 #ifdef RIO_DEBUG2
00229 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u enviado com "
00230 "sucesso a porta %u!", Result, ntohs( Port ) );
00231 #endif
00232
00233
00234 return S_OK;
00235 }
00236
00237
00238 bool CServerUserLogs::ServerUserLogsThread()
00239 {
00240
00241
00242 RioResult RioStatus, RioStatus2;
00243
00244 int SystemStatus;
00245
00246 bool ExecuteThread;
00247
00248
00249
00250 bool RemoveObject;
00251
00252 char LogLine[ MAXLOGLINESIZE + 1 ];
00253
00254 struct pollfd SoketsInfo[ USERLOGSSOCKETSNUMBER ];
00255
00256 int LogLinePort;
00257
00258 #ifdef RIO_DEBUG2
00259 RioErr << "SERVERUSERLOGSTHREADID " << syscall( SYS_gettid ) << endl;
00260 #endif
00261
00262
00263
00264
00265 ExecuteThread = true;
00266
00267
00268
00269
00270
00271 RemoveObject = false;
00272
00273
00274 SoketsInfo[ USERLOGSSOCKETUDP ].fd = m_Socket;
00275 SoketsInfo[ USERLOGSSOCKETUDP ].events = POLLIN;
00276
00277 while( ExecuteThread )
00278 {
00279 #ifdef RIO_DEBUG2
00280 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Antes de executar "
00281 "a funcao poll, com o socket %u!", m_Socket );
00282 #endif
00283
00284
00285
00286
00287 SystemStatus = poll( SoketsInfo, USERLOGSSOCKETSNUMBER, -1 );
00288 if( SystemStatus < 0 )
00289 {
00290
00291
00292 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error %d (%s) "
00293 "when executing poll function. Trying again!", errno,
00294 strerror( errno ) );
00295
00296 }
00297 else
00298 {
00299 #ifdef RIO_DEBUG2
00300 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Sucesso ao "
00301 "executar a funcao poll!" );
00302 #endif
00303
00304
00305
00306 if( ( SoketsInfo[ USERLOGSSOCKETUDP ].revents & POLLIN ) != 0 )
00307 {
00308 #ifdef RIO_DEBUG2
00309 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Existem "
00310 "mensagens a serem recebidas!" );
00311 #endif
00312
00313
00314
00315 RioStatus = ReceiveLogLine( LogLine, &LogLinePort );
00316 if( FAILED( RioStatus ) )
00317 {
00318
00319
00320
00321 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error "
00322 "%8x (%s) when executing "
00323 "ReceiveLogLinefunction!", RioStatus,
00324 GetErrorDescription( RioStatus ).c_str() );
00325 }
00326 else if( strlen( LogLine ) == 0 )
00327 {
00328 #ifdef RIO_DEBUG2
00329 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00330 "Recebida uma mensagem para finalizar a "
00331 "classe! Mensagem recebida %s! Finalizando a "
00332 "thread!",
00333 ( LogLinePort != ntohs( m_LogsServerPort ) ) ?
00334 "de um cliente" : "do destrutor" );
00335 #endif
00336
00337
00338 ExecuteThread = false;
00339
00340 delete m_LogRotation;
00341 m_LogRotation = NULL;
00342
00343
00344
00345 if( LogLinePort != ntohs( m_LogsServerPort ) )
00346 {
00347
00348
00349
00350 RemoveObject = true;
00351
00352
00353
00354
00355 RioStatus = SendResult( S_OK, LogLinePort );
00356 if( FAILED( RioStatus ) )
00357 {
00358
00359
00360
00361 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00362 "Error %8x (%s) when executing "
00363 "SendResult to send result S_OK!",
00364 RioStatus,
00365 GetErrorDescription( RioStatus ).
00366 c_str() );
00367 }
00368 #ifdef RIO_DEBUG2
00369 else
00370 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00371 "Resposta S_OK a mensagem de "
00372 "finalizacao enviada com sucesso ao "
00373 "objeto cliente!"
00374 );
00375 #endif
00376 }
00377 }
00378 else
00379 {
00380 #ifdef RIO_DEBUG2
00381 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00382 "Recebida a linha %s para o log da porta %u. "
00383 "Tentando repassa-la ao objeto que gerencia "
00384 "os logs!", LogLine, ntohs( LogLinePort ) );
00385 #endif
00386
00387
00388
00389 RioStatus = m_LogRotation->NewLogLine( time( NULL ),
00390 LogLine );
00391 if( FAILED( RioStatus ) )
00392 {
00393
00394
00395
00396 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00397 "Error %8x (%s) when executing "
00398 "NewLogLine to insert log line %s!",
00399 RioStatus,
00400 GetErrorDescription( RioStatus ).c_str(),
00401 LogLine );
00402 }
00403 #ifdef RIO_DEBUG2
00404 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00405 "Linha %s recebida da porta UDP %u passada "
00406 "com sucesso para o objeto de gerenciamento "
00407 "dos logs!", LogLine, ntohs( LogLinePort ) );
00408 #endif
00409
00410 #ifdef RIO_DEBUG2
00411 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00412 "Linha de log removida com sucesso!" );
00413 #endif
00414
00415
00416
00417 if( LogLinePort != ntohs( m_LogsServerPort ) )
00418 {
00419 RioStatus2 = SendResult( RioStatus, LogLinePort );
00420 if( FAILED( RioStatus2 ) )
00421 {
00422
00423
00424
00425 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00426 "Error %8x (%s) when executing "
00427 "SendResult to send result %8X (%s)!",
00428 RioStatus2,
00429 GetErrorDescription( RioStatus2 ).
00430 c_str(),
00431 RioStatus,
00432 GetErrorDescription( RioStatus2 ).
00433 c_str() );
00434 }
00435 #ifdef RIO_DEBUG2
00436 else
00437 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00438 "Resposta %u (%s) ao envio de uma "
00439 "linha de log enviada com sucesso "
00440 "ao objeto cliente!", RioStatus,
00441 GetErrorDescription( RioStatus ).c_str()
00442 );
00443 #endif
00444 }
00445 #ifdef RIO_DEBUG2
00446 else
00447 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00448 "Erro! Linha de log recebida da porta "
00449 "%u somente usada para finalizar a "
00450 "thread! Mensagem ignorada!",
00451 m_LogsServerPort );
00452 #endif
00453 }
00454 }
00455 }
00456 }
00457
00458
00459 shutdown( m_Socket, SHUT_RDWR );
00460 close( m_Socket );
00461 m_Socket = 0;
00462
00463
00464
00465 m_ServerUserLogsThread = 0;
00466
00467
00468 return RemoveObject;
00469 }
00470
00471
00472
00473 void* CServerUserLogs::ServerUserLogsThreadEp( void *Param )
00474 {
00475 CServerUserLogs *ServerUserLogs;
00476
00477
00478 ServerUserLogs = ( CServerUserLogs * ) Param;
00479
00480 #ifdef RIO_DEBUG2
00481 RioErr << "CServerUserLogs::ServerUserLogsThreadEp chamando a funcao "
00482 << "ServerUserLogsThread do objeto que executa a thread!" << endl;
00483 #endif
00484
00485
00486
00487
00488 if( ServerUserLogs->ServerUserLogsThread() )
00489 {
00490 #ifdef RIO_DEBUG2
00491 RioErr << "CServerUserLogs::ServerUserLogsThreadEp a funcao retornou "
00492 << "true! Deletando o objeto!" << endl;
00493 #endif
00494
00495
00496
00497 delete ServerUserLogs;
00498 }
00499
00500 #ifdef RIO_DEBUG2
00501 RioErr << "CServerUserLogs::ServerUserLogsThreadEp depois de executar a "
00502 << "funcao ServerUserLogsThread!" << endl;
00503 #endif
00504
00505 return NULL;
00506 }
00507
00508
00509
00510
00511
00512 int CServerUserLogs::Initialize( char *LogsFilePrefixPath,
00513 unsigned int MaxLogFileSize,
00514 unsigned long long int MaxCombinedLogFilesSize,
00515 int LogsPort )
00516 {
00517
00518 pthread_attr_t attribServerUserLogsThread;
00519
00520 struct sockaddr_in TempAddr;
00521
00522 socklen_t AddrSize;
00523
00524
00525 RioResult RioStatus;
00526
00527
00528 if( m_Initialized )
00529 {
00530 #ifdef RIO_DEBUG2
00531 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00532 "Objeto ja foi inicializado!" );
00533 #endif
00534
00535 return ERROR_SERVERUSERLOGS + ERROR_INITIALIZED;
00536 }
00537
00538
00539 m_Socket = socket( AF_INET, SOCK_DGRAM, 0 );
00540 if( m_Socket < 0 )
00541 {
00542 #ifdef RIO_DEBUG2
00543 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00544 "criaro socket UDP usado pelo objeto!", errno,
00545 strerror( errno ) );
00546 #endif
00547
00548 return ERROR_SERVERUSERLOGS + ERROR_SOCKET_CREATE;
00549 }
00550
00551
00552
00553
00554
00555
00556 if( fcntl( m_Socket, F_SETFD, FD_CLOEXEC ) < 0 )
00557 {
00558 #ifdef RIO_DEBUG2
00559 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00560 "fazer o socket UDP recem criado ser exclusivo ao "
00561 "processo!", errno, strerror( errno ) );
00562 #endif
00563
00564 return ERROR_SERVERUSERLOGS + ERROR_SOCKET_OPTIONS;
00565 }
00566
00567
00568 m_LogsServerPort = LogsPort;
00569
00570
00571 memset( &TempAddr, 0, sizeof( TempAddr ) );
00572
00573
00574
00575 TempAddr.sin_family = AF_INET;
00576 TempAddr.sin_addr.s_addr = INADDR_ANY;
00577
00578
00579
00580 TempAddr.sin_addr.s_addr = USERLOGS_UDP_IP;
00581 TempAddr.sin_port = htons( m_LogsServerPort );
00582
00583 if( bind( m_Socket, ( struct sockaddr * ) &TempAddr,
00584 sizeof( TempAddr ) ) < 0 )
00585 {
00586 #ifdef RIO_DEBUG2
00587 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00588 "ligar o socket UDP a uma porta %u!", errno,
00589 strerror( errno ), m_LogsServerPort );
00590 #endif
00591
00592 return ERROR_SERVERUSERLOGS + ERROR_SOCKET_BIND;
00593 }
00594
00595 AddrSize = sizeof( m_SocketAddr );
00596 if( getsockname( m_Socket, ( struct sockaddr * ) &m_SocketAddr,
00597 &AddrSize ) != 0 )
00598 {
00599 #ifdef RIO_DEBUG2
00600 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00601 "obter as informacoes do socket UDP!", errno,
00602 strerror( errno ) );
00603 #endif
00604
00605 return ERROR_SERVERUSERLOGS + ERROR_SOCKET_OPTIONS;
00606 }
00607
00608
00609
00610 try
00611 {
00612 m_LogRotation = new CLogRotation( false );
00613 }
00614 catch( bad_alloc &ba )
00615 {
00616 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Memory error ("
00617 "bad_alloc, error = %s) when allocating log rotation "
00618 "object!", ba.what() );
00619
00620 m_LogRotation = NULL;
00621
00622
00623 shutdown( m_Socket, SHUT_RDWR );
00624 close( m_Socket );
00625
00626 return ERROR_SERVERUSERLOGS + ERROR_MEMORY;
00627 }
00628
00629 #ifdef RIO_DEBUG2
00630 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Tentando inicializar o "
00631 "objeto de gerenciamento de logs!" );
00632 #endif
00633
00634
00635 RioStatus = m_LogRotation->Initialize( LogsFilePrefixPath, MaxLogFileSize,
00636 MaxCombinedLogFilesSize );
00637 if( FAILED( RioStatus ) )
00638 {
00639 #ifdef RIO_DEBUG2
00640 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %8x (%s) ao "
00641 "inicializar o objeto de gerenciamento dos logs!",
00642 RioStatus, GetErrorDescription( RioStatus ).c_str() );
00643 #endif
00644
00645 return RioStatus;
00646 }
00647 #ifdef RIO_DEBUG2
00648 else
00649 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Objeto de "
00650 "gerenciamento de logs inicializado com sucesso! Tentando "
00651 "criar a thread!" );
00652 #endif
00653
00654
00655
00656
00657
00658 pthread_attr_init( &attribServerUserLogsThread );
00659
00660
00661 pthread_attr_setstacksize( &attribServerUserLogsThread,
00662 2 * PTHREAD_STACK_MIN );
00663
00664
00665 if( pthread_create( &m_ServerUserLogsThread, &attribServerUserLogsThread,
00666 ServerUserLogsThreadEp, ( void * ) this ) != 0 )
00667 {
00668 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00669 "criar a thread que recebe as mensagens via UDP!",
00670 errno, strerror( errno ) );
00671
00672 return ERROR_TCPCONNECTION + ERROR_CREATE_THREAD;
00673 }
00674 #ifdef RIO_DEBUG2
00675 else
00676 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Thread criada com "
00677 "sucesso! O ID da thread e igual a %u",
00678 ( unsigned int ) m_ServerUserLogsThread );
00679 #endif
00680
00681
00682 m_Initialized = true;
00683
00684 return S_OK;
00685 }
00686
00687
00688
00689 void CServerUserLogs::JoinThread()
00690 {
00691 pthread_join( m_ServerUserLogsThread, NULL );
00692 }
00693
00694
00695
00696 CClientUserLogs::CClientUserLogs( request_rec *Request )
00697 {
00698
00699 m_Initialized = false;
00700 m_Socket = 0;
00701 memset( &m_SocketAddr, 0, sizeof( m_SocketAddr ) );
00702 m_Request = Request;
00703 m_LogsServerPort = 0;
00704 }
00705
00706
00707 CClientUserLogs::~CClientUserLogs()
00708 {
00709
00710 if( m_Socket != 0 )
00711 {
00712 shutdown( m_Socket, SHUT_RDWR );
00713 close( m_Socket );
00714 }
00715 }
00716
00717
00718 RioResult CClientUserLogs::SendLogLine( char *LogLine )
00719 {
00720
00721 ssize_t BytesSent;
00722
00723 ssize_t BytesReceived;
00724
00725
00726
00727 struct sockaddr_in SourceAddr;
00728
00729 socklen_t SourceAddrSize;
00730
00731 int Result;
00732
00733 struct sockaddr_in DestAddr;
00734
00735
00736
00737 char SendLogLine[ MAXLOGLINESIZE + 1 ];
00738
00739
00740
00741 memset( SendLogLine, 0, MAXLOGLINESIZE + 1 );
00742
00743
00744 if( LogLine != NULL )
00745 strcpy( SendLogLine, LogLine );
00746
00747
00748 memset( &DestAddr, 0, sizeof( DestAddr ) );
00749
00750 DestAddr.sin_family = AF_INET;
00751 DestAddr.sin_addr.s_addr = m_SocketAddr.sin_addr.s_addr;
00752
00753 DestAddr.sin_port = htons( m_LogsServerPort );
00754
00755 #ifdef RIO_DEBUG2
00756 if( m_Request != NULL )
00757 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Tentando enviar a "
00758 "linha %s pelo socket UDP para o IP %s e a porta %u, a "
00759 "partir do IP %s e da porta %u!", SendLogLine,
00760 inet_ntoa( DestAddr.sin_addr ),
00761 ntohs( DestAddr.sin_port ),
00762 inet_ntoa( m_SocketAddr.sin_addr ),
00763 ntohs( m_SocketAddr.sin_port ) );
00764 else
00765 RioErr << "Tentando enviar a linha " << SendLogLine << " pelo socket "
00766 << "UDP para o IP " << inet_ntoa( DestAddr.sin_addr ) << " e a "
00767 << "porta " << ntohs( DestAddr.sin_port ) << ", a partir do IP "
00768 << inet_ntoa( m_SocketAddr.sin_addr ) << " e da porta "
00769 << ntohs( m_SocketAddr.sin_port ) << endl;
00770 #endif
00771
00772
00773
00774
00775 BytesSent = sendto( m_Socket, SendLogLine, MAXLOGLINESIZE,
00776 UDP_FLAGS_SENDDATA, ( struct sockaddr * ) &DestAddr,
00777 sizeof( DestAddr ) );
00778 if( BytesSent < 0 )
00779 {
00780 #ifdef RIO_DEBUG2
00781 if( m_Request != NULL )
00782 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error %d "
00783 "(%s) when sending log line %s to UDP socket!",
00784 errno, strerror( errno ), SendLogLine );
00785 else
00786 RioErr << "Erro " << errno << " (" << strerror( errno ) << ") when "
00787 << "sending log line " << SendLogLine << " to UDP socket!"
00788 << endl;
00789 #endif
00790
00791 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_SEND;
00792 }
00793 else if( BytesSent != MAXLOGLINESIZE )
00794 {
00795 #ifdef RIO_DEBUG2
00796 if( m_Request != NULL )
00797 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error when "
00798 "sending log line %s to UDP socket! Only %u "
00799 "bytes of %u has sent!", SendLogLine, BytesSent,
00800 MAXLOGLINESIZE );
00801 else
00802 RioErr << "Error when sending log line " << SendLogLine << " to "
00803 << "UDP socket! Only " << BytesSent << " of "
00804 << MAXLOGLINESIZE << " has sent!" << endl;
00805 #endif
00806
00807 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_SEND;
00808 }
00809
00810 #ifdef RIO_DEBUG2
00811 if( m_Request != NULL )
00812 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Linha de log %s "
00813 "enviada com sucesso pela conexao UDP! Esperando pelo "
00814 "resultado da operacao! ", SendLogLine );
00815 else
00816 RioErr << "Linha de log " << SendLogLine << " enviada com sucesso pela "
00817 << "conexao UDP! Esperando pelo resultado da operacao! " << endl;
00818 #endif
00819
00820
00821
00822
00823 SourceAddrSize = sizeof( SourceAddr );
00824 BytesReceived = recvfrom( m_Socket, &Result, sizeof( Result ),
00825 UDP_FLAGS_RECEIVE,
00826 ( struct sockaddr * ) &SourceAddr,
00827 &SourceAddrSize );
00828 if( BytesReceived < 0 )
00829 {
00830 #ifdef RIO_DEBUG2
00831 if( m_Request != NULL )
00832 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error %d (%s) "
00833 "when receiving result from UDP socket!", errno,
00834 strerror( errno ) );
00835 else
00836 RioErr << "Error " << errno << " (" << strerror( errno ) << ") "
00837 << "when receiving result from UDP socket!" << endl;
00838 #endif
00839
00840 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_RECEIVE;
00841 }
00842 else if( ( SourceAddr.sin_addr.s_addr != DestAddr.sin_addr.s_addr ) &&
00843 ( SourceAddr.sin_port != DestAddr.sin_port ) )
00844 {
00845 #ifdef RIO_DEBUG2
00846 if( m_Request != NULL )
00847 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Result value "
00848 "received from invalid address ip %s and port %u, "
00849 "different from ip %s and port %u!",
00850 inet_ntoa( SourceAddr.sin_addr ),
00851 ntohs( SourceAddr.sin_port ),
00852 inet_ntoa( DestAddr.sin_addr ),
00853 ntohs( DestAddr.sin_port ) );
00854 else
00855 RioErr << "Result value received from invalid address ip "
00856 << inet_ntoa( SourceAddr.sin_addr ) << " and port "
00857 << inet_ntoa( SourceAddr.sin_addr ) << ", different from ip "
00858 << inet_ntoa( DestAddr.sin_addr ) << " and port "
00859 << ntohs( DestAddr.sin_port ) << "!" << endl;
00860 #endif
00861
00862 return ERROR_CLIENTUSERLOGS + ERROR_INVALID_HOST;
00863
00864 }
00865 else if( BytesReceived != sizeof( Result ) )
00866 {
00867 #ifdef RIO_DEBUG2
00868 if( m_Request != NULL )
00869 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error "
00870 "receiving result from UDP socket! Only %u bytes of "
00871 "%u has received!", BytesReceived,
00872 sizeof( Result ) );
00873 else
00874 RioErr << "Error receiving result from UDP socket! Only "
00875 << BytesReceived << " bytes of " << sizeof( Result )
00876 << " has received!" << endl;
00877 #endif
00878
00879 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_RECEIVE;
00880 }
00881
00882 #ifdef RIO_DEBUG2
00883 if( m_Request != NULL )
00884 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "O resultado da "
00885 "operacao foi recebido com sucesso: RioError = %08X "
00886 "(%s)! ", ( RioResult ) Result,
00887 GetErrorDescription( ( RioResult ) Result ).c_str() );
00888 else
00889 RioErr << "O resultado da operacao foi recebido com sucesso: RioError "
00890 << "= " << hex << ( RioResult ) Result << dec << "("
00891 << GetErrorDescription( ( RioResult ) Result ) << ")!" << endl;
00892 #endif
00893
00894
00895 return( ( RioResult ) Result );
00896 }
00897
00898
00899
00900
00901
00902 RioResult CClientUserLogs::Initialize( int LogsServerPort )
00903 {
00904
00905 struct sockaddr_in TempAddr;
00906
00907 socklen_t AddrSize;
00908
00909
00910 if( m_Initialized )
00911 {
00912 #ifdef RIO_DEBUG2
00913 if( m_Request != NULL )
00914 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00915 "Objeto ja foi inicializado!" );
00916 else
00917 RioErr << "Objeto ja foi inicializado!" << endl;
00918
00919 #endif
00920
00921 return ERROR_CLIENTUSERLOGS + ERROR_INITIALIZED;
00922 }
00923
00924
00925 m_Socket = socket( AF_INET, SOCK_DGRAM, 0 );
00926 if( m_Socket < 0 )
00927 {
00928 #ifdef RIO_DEBUG2
00929 if( m_Request != NULL )
00930 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Erro %u (%s) "
00931 "ao criar o socket UDP usado pelo objeto!", errno,
00932 strerror( errno ) );
00933 else
00934 RioErr << "Erro " << errno << " (" << strerror( errno ) << ") ao "
00935 << "criar o socket UDP usado pelo objeto!" << endl;
00936 #endif
00937
00938 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_CREATE;
00939 }
00940
00941
00942 memset( &TempAddr, 0, sizeof( TempAddr ) );
00943
00944
00945
00946 TempAddr.sin_family = AF_INET;
00947 TempAddr.sin_addr.s_addr = USERLOGS_UDP_IP;
00948 TempAddr.sin_port = 0;
00949 if( bind( m_Socket, ( struct sockaddr * ) &TempAddr,
00950 sizeof( TempAddr ) ) < 0 )
00951 {
00952 #ifdef RIO_DEBUG2
00953 if( m_Request != NULL )
00954 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Erro %u (%s) "
00955 "ao ligar o socket UDP ao IP %s e a uma porta "
00956 "generica", errno, strerror( errno ),
00957 inet_ntoa( TempAddr.sin_addr ) );
00958 else
00959 RioErr << "Erro " << errno << " (" << strerror( errno ) << ") ao "
00960 << "ligar o socket UDP ao IP "
00961 << inet_ntoa( TempAddr.sin_addr ) << " e a uma porta "
00962 << "generica" << endl;
00963 #endif
00964
00965 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_BIND;
00966 }
00967
00968 AddrSize = sizeof( m_SocketAddr );
00969 if( getsockname( m_Socket, ( struct sockaddr * ) &m_SocketAddr,
00970 &AddrSize ) != 0 )
00971 {
00972 #ifdef RIO_DEBUG2
00973 if( m_Request != NULL )
00974 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Erro %u (%s) ao "
00975 "obter as informacoes do socket UDP!", errno,
00976 strerror( errno ) );
00977 else
00978 RioErr << "Erro " << errno << " (" << strerror( errno ) << ") ao "
00979 << "obter as informacoes do socket UDP!" << endl;
00980 #endif
00981
00982 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_OPTIONS;
00983 }
00984
00985
00986 m_LogsServerPort = LogsServerPort;
00987
00988
00989 m_Initialized = true;
00990
00991
00992 return S_OK;
00993 }
00994
00995
00996 RioResult CClientUserLogs::NewLogLine( char *LogInfo )
00997 {
00998
00999
01000 RioResult RioStatus;
01001
01002
01003
01004
01005
01006 if( !m_Initialized )
01007 {
01008 #ifdef RIO_DEBUG2
01009 if( m_Request != NULL )
01010 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01011 "Objeto nao foi inicializado!" );
01012 else
01013 RioErr << "Objeto ja foi inicializado!" << endl;
01014 #endif
01015
01016 return ERROR_CLIENTUSERLOGS + ERROR_NOT_INITIALIZED;
01017 }
01018
01019
01020 if( ( LogInfo != NULL ) && ( strlen( LogInfo ) > MAXLOGLINESIZE ) )
01021 {
01022 #ifdef RIO_DEBUG2
01023 if( m_Request != NULL )
01024 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01025 "Linha de log com %u bytes muito grande! A linha "
01026 "deve ter ate %u caracteres!", strlen( LogInfo ),
01027 MAXLOGLINESIZE );
01028 else
01029 RioErr << "Linha de log com " << strlen( LogInfo ) << " bytes "
01030 << "muito grande! A linha deve ter ate "
01031 << MAXLOGLINESIZE << " caracteres!" << endl;
01032 #endif
01033
01034 return ERROR_CLIENTUSERLOGS + ERROR_LOGLINE_TOOLARGE;
01035 }
01036
01037
01038 RioStatus = SendLogLine( LogInfo );
01039
01040 #ifdef RIO_DEBUG2
01041 if( FAILED( RioStatus ) )
01042 {
01043 if( m_Request != NULL )
01044 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error %8x "
01045 "(%s) when executing function SendLogLine! Log "
01046 "ignored!", RioStatus,
01047 GetErrorDescription( RioStatus ).c_str() );
01048 else
01049 RioErr << "Error 0x" << hex << RioStatus << dec << " ("
01050 << GetErrorDescription( RioStatus ) << ") when executing "
01051 << "function SendLogLine! Log ignored!" << endl;
01052 }
01053 #endif
01054
01055 return RioStatus;
01056 }