00001
00002
00003
00004
00005
00006
00007 #include <arpa/inet.h>
00008 #include "ComPlusPlus/SSrv.h"
00009
00010 #include "SysPlusPlus/Tools.h"
00011 #include "SysPlusPlus/Logger.h"
00012
00013 #include "Sig.h"
00014
00015 compp::SSrv::~SSrv () {
00016 Server.Shutdown();
00017 }
00018 compp::SSrv::SSrv () {
00019
00020 }
00021
00022 compp::SSrv::SSrv (const int p) {
00023
00024 setPort ( p );
00025 setIPAddr ( "0.0.0.0" );
00026
00027 }
00028
00029 compp::SSrv::SSrv (const std::string & IPAddr, const int p) {
00030
00031 setPort ( p );
00032 setIPAddr ( IPAddr );
00033
00034 }
00035
00036 compp::SSrv::SSrv (const std::string & IPAddr, const int p, const SSrvProperties & prop) {
00037 setPort ( p );
00038 setIPAddr ( IPAddr );
00039 ServerProperties = prop;
00040 }
00041
00042 void compp::SSrv::SetProperties ( const SSrvProperties & prop) {
00043 ServerProperties = prop;
00044 }
00045
00046 void compp::SSrv::commenceWork () {
00047
00048 syspp::Logger *Log = syspp::Logger::Instance();
00049
00050 Log->Info ("SSR Instance commencing main loop.");
00051 Server.Bind (IPAddr, port) ;
00052 Log->Info ("SSR Instance listening on %s:%d.", IPAddr.c_str(), port);
00053 Server.Listen ();
00054 Log->Info ("SSR Instance listening on %s:%d.", IPAddr.c_str(), port);
00055
00056 Server.AttachFD();
00057 Server.SetSockOptReuseAddress ( true);
00058 Server.SetSockOptTcpNoDelay ( true ) ;
00059 Server.SetReadTimeout(ServerProperties.ReadTimeout);
00060 Server.SetWriteTimeout(ServerProperties.WriteTimeout);
00061 Server.SetLingerTime(0);
00062
00063 Log->Info ("SSR Instance ReadTimeout=%d Writetimeout=%d",ServerProperties.ReadTimeout,ServerProperties.WriteTimeout);
00064
00065 compp::SocketTcp *srv1;
00066
00067 while ( true ) {
00068
00069 if ( NULL != ( srv1 = Server.Accept( ) )) {
00070 Log->Info ("SSR Instance received new connection.");
00071 this->Start ( (void *) srv1 );
00072 this->Detach();
00073
00074 } else {
00075 std::string msg = "Server Accept failed: ";
00076 msg += strerror ( errno );
00077 Log->Info ( msg.c_str() );
00078 throw syspp::ComException ( msg.c_str() );
00079 }
00080 }
00081 }
00082
00083 void *compp::SSrv::Run (void*v) {
00084
00085 syspp::Logger *Log = syspp::Logger::Instance();
00086
00087 compp::SocketTcp * worker = (compp::SocketTcp *) v;
00088 if ( worker == NULL ) {
00089 Log->Error ("SSR Instance not a TCP Socket");
00090 return NULL;
00091 }
00092
00093 int LRequest, LSEC;
00094 std::string retval, request;
00095
00096 SSrvContext Context;
00097
00098 Context.SetAuth(false);
00099 Context.SetContextString ( worker->GetContextString());
00100 Log->Error ("SSR Instance received connection from %s:%d", worker->GetSocketAddress().c_str(), worker->GetSocketPort());
00101 try {
00102 do {
00103 int i ;
00104 if ( ( i = worker->Readn ( (char *) & LSEC, sizeof ( LSEC ))) <= 0 ) {
00105 worker->Shutdown ();
00106 worker->Close();
00107 delete worker;
00108 if ( i < 0 ) {
00109 Log->Info ("SSR Instance. Read failed. dropping. (%s)", strerror ( errno ) );
00110 } else {
00111 Log->Info ("SSR Instance. Client closed connection." );
00112 }
00113 return NULL;
00114 }
00115
00116 LSEC = ntohl ( LSEC );
00117
00118 if ( LSEC != _COMM_SEC && LSEC != _COMM_CYPH ) {
00119 worker->Shutdown ();
00120 worker->Close();
00121 delete worker;
00122 Log->Info ("SSR Instance. Signature not valid. dropping." );
00123 return NULL;
00124 }
00125
00126 if ( worker->Readn ( (char *) & LRequest, sizeof ( LRequest )) <= 0 ) {
00127 worker->Shutdown ();
00128 worker->Close();
00129 delete worker;
00130 Log->Info ("SSR Instance. Packet malformed. dropping.(%s)", strerror ( errno ) );
00131 return NULL;
00132 }
00133 LRequest = ntohl ( LRequest );
00134 if ( LRequest <= 0 ) {
00135 worker->Shutdown ();
00136 worker->Close();
00137 delete worker;
00138 Log->Info ("SSR Instance. Packet malformed. dropping." );
00139 return NULL;
00140 }
00141
00142 if ( worker->Readn ( request, LRequest ) < 0 ) {
00143 worker->Shutdown ();
00144 worker->Close();
00145 Log->Info ("SSR Instance. Read failed (2). dropping. (%s)", strerror ( errno ) );
00146 delete worker;
00147 }
00148
00149 if ( LSEC == _COMM_CYPH) {
00150
00151 Log->Debug ("SSR Instance. Cyphering." );
00152 syspp::Tools::Dec (request);
00153 }
00154
00155
00156 retval = executeTransaction ( request, Context ) ;
00157
00158 Log->Debug ("SSR Instance. Request executed. Response of length %d received.", retval.size() );
00159
00160 if ( LSEC == _COMM_CYPH) {
00161 Log->Debug ("SSR Instance. Decypering." );
00162 syspp::Tools::Enc (retval);
00163 }
00164
00165
00166 int Len = htonl ( retval.size() );
00167 char c[sizeof (int)];
00168 memcpy ( (void*) c, (void*) &Len, sizeof (Len));
00169
00170 std::string R = "";
00171 R.append ( c, sizeof ( Len ) );
00172 R.append ( retval );
00173 if ( worker->Writen ( R) < 0 ) {
00174 worker->Shutdown ();
00175 worker->Close();
00176 Log->Info ("SSR Instance. Cannot send response. (%s)", strerror ( errno ) );
00177 delete worker;
00178 }
00179
00180 Log->Debug ("SSR Instance. Response sent." );
00181
00182
00183 } while ( true ) ;
00184 } catch ( syspp::ComException & e ) {
00185 worker->Shutdown ();
00186 worker->Close();
00187 delete worker;
00188 Log->Info ("SSR Instance. Received ComException: %s (%s)", e.what (), strerror ( errno ) );
00189 std::cout << "Abnormal Client Termination. " << e.what () << "\n";
00190 } catch ( ... ) {
00191 worker->Shutdown ();
00192 worker->Close();
00193 delete worker;
00194 Log->Info ("SSR Instance. Received genException: (%s)", strerror ( errno ) );
00195 std::cout << "Abnormal Termination\n" ;
00196 }
00197 return NULL;
00198 }
00199
00200 std::string compp::SSrv::executeTransaction ( const std::string & request, SSrvContext & Context ) {
00201 std::string ret = "SSRvTest";
00202 ret += Context.GetContextString();
00203 ret += "HOWDI";
00204 return ret ;
00205 }