00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdnet.h"
00027
00028 #include "nel/misc/hierarchical_timer.h"
00029
00030 #include "nel/net/buf_sock.h"
00031 #include "nel/net/buf_server.h"
00032
00033 #ifdef NL_OS_WINDOWS
00034 #include <winsock2.h>
00035 #elif defined NL_OS_UNIX
00036 #include <netinet/in.h>
00037 #endif
00038
00039 using namespace NLMISC;
00040 using namespace std;
00041
00042
00043 namespace NLNET {
00044
00045
00046 NLMISC::CMutex nettrace_mutex("nettrace_mutex");
00047
00048
00049
00050
00051
00052 CBufSock::CBufSock( CTcpSock *sock ) :
00053 SendNextValue(0),
00054 ReceiveNextValue(0),
00055 Sock( sock ),
00056 _KnowConnected( false ),
00057 _LastFlushTime( 0 ),
00058 _TriggerTime( 20 ),
00059 _TriggerSize( -1 ),
00060 _RTSBIndex( 0 ),
00061 _AppId( 0 ),
00062 _ConnectedState( false )
00063 {
00064 nlnettrace( "CBufSock::CBufSock" );
00065
00066 if ( Sock == NULL )
00067 {
00068 Sock = new CTcpSock();
00069 }
00070
00071 #ifdef NL_DEBUG
00072 _FlushTrigger = FTManual;
00073 #endif
00074 _LastFlushTime = CTime::getLocalTime();
00075 }
00076
00077
00078
00079
00080
00081 CBufSock::~CBufSock()
00082 {
00083 nlassert (this != InvalidSockId);
00084
00085 nlnettrace( "CBufSock::~CBufSock" );
00086
00087 delete Sock;
00088
00089
00090 AuthorizedCallback = "";
00091 Sock = NULL;
00092 _KnowConnected = false;
00093 _LastFlushTime = 0;
00094 _TriggerTime = 0;
00095 _TriggerSize = 0;
00096 _ReadyToSendBuffer.clear ();
00097 _RTSBIndex = 0;
00098 _AppId = 0;
00099 _ConnectedState = false;
00100 }
00101
00102
00103
00104
00105
00106 string stringFromVectorPart( const vector<uint8>& v, uint32 pos, uint32 len )
00107 {
00108 nlassertex( pos+len <= v.size(), ("pos=%u len=%u size=%u", pos, len, v.size()) );
00109
00110 string s;
00111 if ( (! v.empty()) && (len!=0) )
00112 {
00113
00114 s.resize( len );
00115 memcpy( &*s.begin(), &*v.begin()+pos, len );
00116
00117
00118 string::iterator is;
00119 for ( is=s.begin(); is!=s.end(); ++is )
00120 {
00121 if ( ! isprint((uint8)(*is)) || (*is) == '%' )
00122 {
00123 (*is) = '?';
00124 }
00125 }
00126 }
00127
00128 return s;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138 bool CBufSock::flush()
00139 {
00140 nlassert (this != InvalidSockId);
00141
00142
00143
00144 TBlockSize netlen;
00145
00146
00147
00148 while ( ! SendFifo.empty() )
00149 {
00150 uint8 *tmpbuffer;
00151 uint32 size;
00152 SendFifo.front( tmpbuffer, size );
00153
00154
00155 netlen = htonl( (TBlockSize)size );
00156 uint32 oldBufferSize = _ReadyToSendBuffer.size();
00157 _ReadyToSendBuffer.resize (oldBufferSize+sizeof(TBlockSize)+size);
00158 *(TBlockSize*)&(_ReadyToSendBuffer[oldBufferSize])=netlen;
00159
00160
00161 CFastMem::memcpy (&_ReadyToSendBuffer[oldBufferSize+sizeof(TBlockSize)], tmpbuffer, size);
00162 SendFifo.pop();
00163 }
00164
00165
00166
00167 if ( _ReadyToSendBuffer.size() != 0 )
00168 {
00169
00170 CSock::TSockResult res;
00171 TBlockSize len = _ReadyToSendBuffer.size() - _RTSBIndex;
00172
00173 res = Sock->send( _ReadyToSendBuffer.getPtr()+_RTSBIndex, len, false );
00174
00175 if ( res == CSock::Ok )
00176 {
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 if ( _RTSBIndex+len == _ReadyToSendBuffer.size() )
00192 {
00193
00194 _ReadyToSendBuffer.clear();
00195 _RTSBIndex = 0;
00196 }
00197 else
00198 {
00199
00200 nlassertex( _RTSBIndex+len < _ReadyToSendBuffer.size(), ("index=%u len=%u size=%u", _RTSBIndex, len, _ReadyToSendBuffer.size()) );
00201 _RTSBIndex += len;
00202 if ( _ReadyToSendBuffer.size() > 20480 )
00203 {
00204 uint nbcpy = _ReadyToSendBuffer.size() - len;
00205 for (uint i = 0; i < nbcpy; i++)
00206 {
00207 _ReadyToSendBuffer[i] = _ReadyToSendBuffer[i+len];
00208 }
00209 _ReadyToSendBuffer.resize(nbcpy);
00210
00211 _RTSBIndex = 0;
00212 }
00213 }
00214 }
00215 else
00216 {
00217 #ifdef NL_DEBUG
00218
00219 nldebug( "LNETL1: %s failed to send effectively a buffer of %d bytes", asString().c_str(), _ReadyToSendBuffer.size() );
00220 #endif
00221 return false;
00222 }
00223 }
00224
00225 return true;
00226 }
00227
00228
00229
00230
00231
00232 void CBufSock::setTimeFlushTrigger( sint32 ms )
00233 {
00234 nlassert (this != InvalidSockId);
00235 _TriggerTime = ms;
00236 _LastFlushTime = CTime::getLocalTime();
00237 }
00238
00239
00240
00241
00242
00243 bool CBufSock::update()
00244 {
00245 nlassert (this != InvalidSockId);
00246
00247
00248
00249 if ( _TriggerTime != -1 )
00250 {
00251 TTime now = CTime::getLocalTime();
00252 if ( (sint32)(now-_LastFlushTime) >= _TriggerTime )
00253 {
00254 #ifdef NL_DEBUG
00255 _FlushTrigger = FTTime;
00256 #endif
00257 if ( flush() )
00258 {
00259 _LastFlushTime = now;
00260
00261 return true;
00262 }
00263 else
00264 {
00265
00266 return false;
00267 }
00268 }
00269 }
00270
00271 if ( _TriggerSize != -1 )
00272 {
00273 if ( (sint32)SendFifo.size() > _TriggerSize )
00274 {
00275 #ifdef NL_DEBUG
00276 _FlushTrigger = FTSize;
00277 #endif
00278
00279 return flush();
00280 }
00281 }
00282
00283 return true;
00284 }
00285
00286
00287
00288
00289
00290
00291 void CBufSock::connect( const CInetAddress& addr, bool nodelay, bool connectedstate )
00292 {
00293 nlassert (this != InvalidSockId);
00294 nlassert( ! Sock->connected() );
00295
00296 SendNextValue = ReceiveNextValue = 0;
00297
00298 Sock->connect( addr );
00299 _ConnectedState = connectedstate;
00300 _KnowConnected = connectedstate;
00301 if ( nodelay )
00302 {
00303 Sock->setNoDelay( true );
00304 }
00305 }
00306
00307
00308
00309
00310
00311 void CBufSock::disconnect( bool connectedstate )
00312 {
00313 nlassert (this != InvalidSockId);
00314 Sock->disconnect();
00315 _ConnectedState = connectedstate;
00316 _KnowConnected = connectedstate;
00317
00318 SendNextValue = ReceiveNextValue = 0;
00319 }
00320
00321
00322
00323
00324
00325 string CBufSock::asString() const
00326 {
00327 stringstream ss;
00328 if (this == InvalidSockId)
00329 ss << "<Null>";
00330 else
00331 {
00332
00333
00334 ss << typeStr();
00335 ss << hex << this << dec << " (socket ";
00336
00337 if (Sock == NULL)
00338 ss << "<Null>";
00339 else
00340 ss << Sock->descriptor();
00341
00342 ss << ")";
00343 }
00344 return ss.str();
00345 }
00346
00347
00348
00349
00350
00351 CServerBufSock::CServerBufSock( CTcpSock *sock ) :
00352 CBufSock( sock ),
00353 _Advertised( false ),
00354 _NowReadingBuffer( false ),
00355 _BytesRead( 0 ),
00356 _Length( 0 ),
00357 _OwnerTask( NULL )
00358 {
00359 nlassert (this != InvalidSockId);
00360 nlnettrace( "CServerBufSock::CServerBufSock" );
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370 bool CServerBufSock::receivePart()
00371 {
00372 nlassert (this != InvalidSockId);
00373 nlnettrace( "CServerBufSock::receivePart" );
00374
00375 TBlockSize actuallen;
00376 if ( ! _NowReadingBuffer )
00377 {
00378
00379 actuallen = sizeof(_Length)-_BytesRead;
00380 Sock->receive( (uint8*)(&_Length)+_BytesRead, actuallen );
00381 _BytesRead += actuallen;
00382 if ( _BytesRead == sizeof(_Length ) )
00383 {
00384 if ( _Length != 0 )
00385 {
00386 _Length = ntohl( _Length );
00387
00388
00389 if ( _Length > _OwnerTask->server()->maxExpectedBlockSize() )
00390 {
00391 nlwarning( "LNETL1: Socket %s received length exceeding max expected, in block header... Disconnecting", asString().c_str() );
00392 throw ESocket( "Received length exceeding max expected", false );
00393 }
00394
00395 _NowReadingBuffer = true;
00396 _ReceiveBuffer.resize( _Length );
00397 }
00398 else
00399 {
00400 nlwarning( "LNETL1: Socket %s received null length in block header", asString().c_str() );
00401 }
00402 _BytesRead = 0;
00403 }
00404 }
00405
00406 if ( _NowReadingBuffer )
00407 {
00408
00409 actuallen = _Length-_BytesRead;
00410 Sock->receive( &*_ReceiveBuffer.begin()+_BytesRead, actuallen );
00411 _BytesRead += actuallen;
00412
00413 if ( _BytesRead == _Length )
00414 {
00415 #ifdef NL_DEBUG
00416 nldebug( "LNETL1: %s received buffer (%u bytes): [%s]", asString().c_str(), _ReceiveBuffer.size(), stringFromVector(_ReceiveBuffer).c_str() );
00417 #endif
00418 _NowReadingBuffer = false;
00419 _BytesRead = 0;
00420 return true;
00421 }
00422 }
00423
00424 return false;
00425 }
00426
00427 }