00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifdef __Rio_Win
00042
00043
00044 #include "stdafx.h"
00045 #else
00046
00047 #endif
00048
00049
00050 #include "NetMgr.h"
00051 #include "NetMgr.pkt"
00052
00053 #include "RioNeti.h"
00054
00055 #include "RioError.h"
00056
00057 #include <iostream>
00058
00059 using namespace std;
00060
00061 NetMgr::NetMgr( bool serverInstance )
00062 {
00063 this->serverInstance = serverInstance;
00064 d_neti = NULL;
00065 d_cmdproc = 0;
00066 d_myip = 0;
00067 d_myport = 0;
00068 d_seq = 0;
00069 d_cmdparm = NULL;
00070
00071 #ifdef WINDOWS
00072
00073 d_seqlock = CreateMutex(NULL, FALSE, NULL);
00074 #else
00075
00076 pthread_mutex_init(&d_seqlock, NULL);
00077 #endif
00078
00079
00080
00081 m_semalidmap = new CSemaphore( 0, 1 );
00082 }
00083
00084
00085 NetMgr::~NetMgr()
00086 {
00087 if( d_neti )
00088 {
00089 d_neti->Stop();
00090 delete d_neti;
00091 d_neti = 0;
00092
00093 #ifdef WINDOWS
00094
00095 CloseHandle(d_seqlock);
00096 #else
00097
00098 pthread_mutex_destroy(&d_seqlock);
00099 #endif
00100 }
00101
00102
00103
00104 delete m_semalidmap;
00105 }
00106
00107
00108
00109
00110
00111
00112
00113 #ifdef RIO_DEBUG_FILE
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 int NetMgr::Start( int port, int maxdiskl, int maxpktl,
00128 const char *RioNetiLogPath,
00129 unsigned int MaxClientsCredits,
00130 unsigned int MaxNetworkCredits, unsigned int NetworkRate )
00131 #else
00132 int NetMgr::Start( int port, int maxdiskl, int maxpktl,
00133 unsigned int MaxClientsCredits,
00134 unsigned int MaxNetworkCredits, unsigned int NetworkRate )
00135 #endif
00136 {
00137 int rc;
00138
00139 d_neti = new RioNeti( serverInstance );
00140
00141
00142 #ifdef RIO_DEBUG_FILE
00143 rc = d_neti->Start( port, maxdiskl, maxpktl, RioNetiLogPath,
00144 MaxClientsCredits, MaxNetworkCredits, NetworkRate );
00145 #else
00146 rc = d_neti->Start( port, maxdiskl, maxpktl, MaxClientsCredits,
00147 MaxNetworkCredits, NetworkRate );
00148 #endif
00149
00150 if( rc )
00151 return rc;
00152
00153 d_neti->getmyaddrport( &d_myip, &d_myport );
00154 return rc;
00155 }
00156
00157
00158 void NetMgr::Getmyaddr( int *my_address, int *my_port )
00159 {
00160 *my_address = d_myip;
00161 *my_port = d_myport;
00162 }
00163
00164
00165 bool NetMgr::SetMulticastSocket( unsigned short multicastport,
00166 char* multicast_addr,
00167 void *callback,
00168 BufferStream *buffer_stream,
00169 int enable_join )
00170 {
00171 return d_neti->SetMulticastSocket( multicastport,
00172 multicast_addr,
00173 callback,
00174 buffer_stream,
00175 enable_join );
00176 }
00177
00178
00179 void NetMgr::LeaveGroup( unsigned short multicastport )
00180 {
00181 d_neti->LeaveGroup( multicastport );
00182 }
00183
00184
00185 void NetMgr::LeaveAllGroups( void )
00186 {
00187 d_neti->LeaveAllGroups();
00188 }
00189
00190
00191
00192 void NetMgr::getmyaddrport(int *ipaddr, int *port, int server)
00193 {
00194 d_neti->getmyaddrport( ipaddr, port, server );
00195 }
00196
00197
00198
00199 void NetMgr::getalladdrport( int **ipaddr, int **port)
00200 {
00201 d_neti->getalladdrport( ipaddr, port );
00202 }
00203
00204
00205
00206
00207
00208 int NetMgr::getipaddr()
00209 {
00210 return d_neti->getipaddr();
00211 }
00212
00213
00214 int NetMgr::Stop()
00215 {
00216 return d_neti->Stop();
00217 }
00218
00219 void NetMgr::SetCmdProc( cmdcallback_t cmdproc, void *cmdparm )
00220 {
00221 d_cmdproc = cmdproc;
00222 d_cmdparm = cmdparm;
00223
00224 d_neti->SetCmdProc(mycmdproc, (void *)this);
00225 }
00226
00227
00228 void NetMgr::mycmdproc(void *cmdparm, char *cmdp, int cmdl)
00229 {
00230 NetMgr *x = (NetMgr *) cmdparm;
00231
00232 (*x->d_cmdproc)(x->d_cmdparm, cmdp, cmdl);
00233 }
00234
00235
00236
00237
00238
00239 void NetMgr::SendCmd( int ipadr, int port, int reqid, char *cmdp, int cmdl,
00240 callback_t callback, void *callbackparm )
00241 {
00242 #ifdef RIO_DEBUG1
00243 RioErr << "[NetMgr] SendCmd Start" << endl;
00244 #endif
00245 d_neti->SendCmd(ipadr, port, reqid, cmdp, cmdl, callback, callbackparm);
00246 #ifdef RIO_DEBUG1
00247 RioErr << "[NetMgr] SendCmd Finish" << endl;
00248 #endif
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 void NetMgr::SendBlock( int ip, int port, int reqid, char *bufadr, int buflen,
00258 callback_t callback, void *callbackparm,
00259 int StreamTraffic, unsigned int VideoRate )
00260 {
00261 #ifdef RIO_DEBUG1
00262 RioErr << "[NetMgr] SendBlock Start" << endl;
00263 #endif
00264 d_neti->SendData( ip, port, reqid, bufadr, buflen, callback, callbackparm,
00265 StreamTraffic, VideoRate );
00266 #ifdef RIO_DEBUG1
00267 RioErr << "[NetMgr] SendBlock Finish" << endl;
00268 #endif
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 int NetMgr::ExpectBlock( char *bufadr, int buflen,
00281 callback_t callback, void *callbackparm, int sendack )
00282 {
00283 #ifdef RIO_DEBUG2
00284 RioErr << "[NetMgr] ExpectBlock chamando ExpectData." << endl;
00285 #endif
00286
00287 return d_neti->ExpectData( bufadr, buflen, callback, callbackparm,
00288 UNICASTTRAFFIC, sendack );
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 int NetMgr::CancelExpect(int reqid, int result)
00306 {
00307 return d_neti->CancelExpect(reqid, result);
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 void NetMgr::SendResult(int ipadr, int port, int reqid, int result)
00321 {
00322 d_neti->SendResult( ipadr, port, reqid, result,
00323 &sendresultcb, (void *)this);
00324 }
00325
00326
00327 void NetMgr::sendresultcb(void *parm, int result)
00328 {
00329 }
00330
00331
00332
00333
00334
00335 void NetMgr::TellId( int ipadr, int port, int reqid,
00336 int tellip, int tellport, int tellreqid,
00337 callback_t callback, void *callbackparm )
00338 {
00339 u32 data[5];
00340
00341 data[0] = htonl(RioPktC::CMD_TELLID);
00342 data[1] = tellip;
00343 data[2] = htonl(ntohs((short) tellport));
00344 data[3] = tellreqid;
00345
00346 #ifdef WINDOWS
00347
00348 WaitForSingleObject(d_seqlock,INFINITE);
00349 #else
00350
00351 pthread_mutex_lock(&d_seqlock);
00352 #endif
00353
00354
00355 data[4] = htonl(d_seq++);
00356
00357 #ifdef WINDOWS
00358
00359 ReleaseMutex(d_seqlock);
00360 #else
00361
00362 pthread_mutex_unlock(&d_seqlock);
00363 #endif
00364
00365
00366 d_neti->SendCmd( ipadr, port, reqid, (char *) data, 5*sizeof(data[0]),
00367 callback, callbackparm );
00368 }
00369
00370
00371 struct gbwork
00372 {
00373 bool tellcmplt;
00374 bool expectcmplt;
00375 int result;
00376 int myreqid;
00377 NetMgr *mgr;
00378 callback_t callback;
00379 void *callbackparm;
00380 };
00381
00382
00383
00384
00385
00386
00387
00388 void NetMgr::GetBlock( int ipadr, int port, int reqid, char *buf, int len,
00389 callback_t callback, void *callbackparm )
00390 {
00391 gbwork *wp = new gbwork;
00392
00393 wp->tellcmplt = false;
00394 wp->expectcmplt = false;
00395 wp->result = 0;
00396 wp->mgr = this;
00397 wp->callback = callback;
00398 wp->callbackparm = callbackparm;
00399 wp->myreqid = ExpectBlock( buf, len, &getblockcb1, wp, 1 );
00400
00401 TellId( ipadr, port, reqid, d_myip, d_myport, wp->myreqid,
00402 &getblockcb2, wp );
00403 }
00404
00405
00406
00407 void NetMgr::getblockcbx(void *parm, int result)
00408 {
00409 #ifdef RIO_DEBUG1
00410 RioErr << "[NetMgr] getblockcbx - Start" << endl;
00411 #endif
00412 gbwork *wp = (gbwork *) parm;
00413
00414 if(!wp->result)
00415 wp->result = result;
00416
00417 if(wp->tellcmplt && wp->expectcmplt)
00418 {
00419 #ifdef RIO_DEBUG2
00420 RioErr << "[NetMgr] getblockcbx - Chamando a MulticastCallBack da "
00421 << "RioMMVideo" << endl;
00422 #endif
00423
00424 (*wp->callback)(wp->callbackparm, wp->result);
00425 delete wp;
00426 }
00427 #ifdef RIO_DEBUG1
00428 RioErr << "[NetMgr] getblockcbx - Finish" << endl;
00429 #endif
00430 }
00431
00432
00433
00434
00435
00436 void NetMgr::getblockcb1( void *parm, int result )
00437 {
00438 #ifdef RIO_DEBUG1
00439 RioErr << "[NetMgr] getblockcb1 - Start" << endl;
00440 #endif
00441 gbwork *wp = (gbwork *) parm;
00442
00443 wp->expectcmplt = true;
00444
00445 getblockcbx( wp, result );
00446 #ifdef RIO_DEBUG1
00447 RioErr << "[NetMgr] getblockcb1 - Finish" << endl;
00448 #endif
00449 }
00450
00451
00452
00453 void NetMgr::getblockcb2( void *parm, int result )
00454 {
00455 #ifdef RIO_DEBUG1
00456 RioErr << "[NetMgr] getblockcb2 - Start" << endl;
00457 #endif
00458 gbwork *wp = (gbwork *) parm;
00459
00460 wp->tellcmplt = true;
00461
00462 if(result)
00463 {
00464 #ifdef RIO_DEBUG1
00465 RioErr << "[NetMgr] getblockcb1 - Error" << endl;
00466 #endif
00467 wp->mgr->CancelExpect(wp->myreqid, ERROR_NETMGR+0xf0);
00468 }
00469
00470 getblockcbx(wp, result);
00471 #ifdef RIO_DEBUG1
00472 RioErr << "[NetMgr] getblockcb2 - Finish" << endl;
00473 #endif
00474 }
00475
00476
00477 struct xduptab
00478 {
00479 unsigned int ip;
00480 unsigned int port;
00481 unsigned int reqid;
00482 unsigned int seq;
00483
00484
00485 unsigned int sendreqid;
00486 };
00487
00488 struct xtwork
00489 {
00490 NetMgr *mgr;
00491 callback_t callback;
00492 void *callbackparm;
00493 char *bufp;
00494 int bufl;
00495 int result;
00496 int pendingsends;
00497 int cmplt;
00498 int myreqid;
00499
00500 #ifdef WINDOWS
00501
00502 static const int DUPTABN;
00503 xduptab duptab[10];
00504 #else
00505
00506 static const int DUPTABN = 10;
00507 xduptab duptab[DUPTABN];
00508 #endif
00509
00510 int dupix;
00511 int dupct;
00512
00513 #ifdef WINDOWS
00514
00515 const int xtwork::DUPTABN = 10;
00516 #endif
00517 };
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 int NetMgr::ExpectTellId( char *bufadr, int buflen,
00534 callback_t callback, void *callbackparm )
00535 {
00536 xtwork *wp = new xtwork;
00537
00538 wp->mgr = this;
00539 wp->callback = callback;
00540 wp->callbackparm = callbackparm;
00541 wp->bufp = bufadr;
00542 wp->bufl = buflen;
00543 wp->result = 0;
00544 wp->dupix = 0;
00545 wp->dupct = 0;
00546 wp->pendingsends = 0;
00547 wp->cmplt = 0;
00548
00549 for( int i = 0; i < xtwork::DUPTABN; i++ )
00550 {
00551 wp->duptab[ i ].ip = 0;
00552 wp->duptab[ i ].port = 0;
00553 wp->duptab[ i ].reqid = 0;
00554 wp->duptab[ i ].seq = 0;
00555 }
00556 wp->myreqid = d_neti->ExpectCmd( &expecttellcmplt,
00557 (void *) wp, &expecttellcmd);
00558
00559 return wp->myreqid;
00560 }
00561
00562
00563
00564 void NetMgr::expecttellcmd(void *parm, char *pktp, int pktl)
00565 {
00566 xtwork *wp = (xtwork *) parm;
00567 int i;
00568 u32 data[5], *dp;
00569
00570 dp = (u32 *) pktp;
00571 for(i = 0; i < 5; i++)
00572 {
00573 data[i] = *dp++;
00574 }
00575
00576
00577 data[0] = ntohl(data[0]);
00578 data[2] = htons( (short) (ntohl(data[2])));
00579 data[4] = ntohl(data[4]);
00580
00581 if(data[0] != (unsigned) RioPktC::CMD_TELLID)
00582 {
00583 return;
00584 }
00585
00586
00587 for(i = 0; i < wp->dupct; i++)
00588 {
00589 if( data[1] == wp->duptab[i].ip &&
00590 data[2] == wp->duptab[i].port &&
00591 data[3] == wp->duptab[i].reqid &&
00592 data[4] == wp->duptab[i].seq
00593 )
00594 {
00595 #ifdef RIO_DEBUG2
00596 RioErr << " -- duplicate --" << endl;
00597 #endif
00598 return;
00599 }
00600 }
00601
00602 if(wp->dupct < xtwork::DUPTABN-1)
00603 {
00604 wp->dupix = ++wp->dupct;
00605 }
00606 else
00607 {
00608 ++wp->dupix;
00609 if(wp->dupix >= xtwork::DUPTABN-1)
00610 {
00611 wp->dupix = 0;
00612 }
00613 }
00614
00615 i = wp->dupix;
00616 wp->duptab[i].ip = data[1];
00617 wp->duptab[i].port = data[2];
00618 wp->duptab[i].reqid = data[3];
00619 wp->duptab[i].seq = data[4];
00620
00621 wp->pendingsends++;
00622
00623 #ifdef RIO_DEBUG2
00624 in_addr dest;
00625 dest.s_addr = wp->duptab[ i ].ip;
00626 RioErr << "NetMgr::expecttellcmd recebido as informacoes do bloco "
00627 << "ao NetBuf com o identificador wp->myreqid = " << wp->myreqid
00628 << ", associado a posicao " << i << " de wp->duptab, com as "
00629 << "seguintes informacoes: ip = " << inet_ntoa( dest )
00630 << ", porta = " << ntohs( wp->duptab[ i ].port ) << ", reqid = "
00631 << wp->duptab[ i ].reqid << " e seq = " << wp->duptab[ i ].seq
00632 << ". wp->pendingsends = " << wp->pendingsends << endl;
00633
00634 RioErr << "[NetMgr] expecttellcmd - chamando a SendData" << endl;
00635 #endif
00636
00637 wp->mgr->d_neti->SendData( data[1], data[2], data[3], wp->bufp, wp->bufl,
00638 &expecttellsend, (void *) wp, 1, 0,
00639 &wp->duptab[i].sendreqid );
00640 }
00641
00642
00643
00644 void NetMgr::expecttellcom( void *parm )
00645 {
00646 xtwork *wp = (xtwork *) parm;
00647
00648 #ifdef RIO_DEBUG2
00649 RioErr << "[NetMgr] expecttellcom - Chamando a MulticastCallBack da "
00650 << "RioMMVideo" << endl;
00651 #endif
00652
00653 if(wp->cmplt && wp->pendingsends == 0)
00654 {
00655 #ifdef RIO_DEBUG2
00656 RioErr << "[NetMgr] expecttellcom - Chamando a callback" << endl;
00657 #endif
00658 (*wp->callback)(wp->callbackparm, wp->result);
00659 delete wp;
00660 }
00661 }
00662
00663
00664
00665 void NetMgr::expecttellcmplt(void *parm, int result)
00666 {
00667 xtwork *wp = (xtwork *) parm;
00668
00669 wp->cmplt = 1;
00670
00671 wp->result = result;
00672
00673
00674 if( result != S_OK )
00675 {
00676 #ifdef RIO_DEBUG2
00677 RioErr << "NetMgr::expecttellcmplt a copia do bloco terminou com o "
00678 << "erro 0x" << hex << ( unsigned int ) result << dec << " ("
00679 << GetErrorDescription( result ) << "). Abortando todas as "
00680 << "copias pendentes para o NetBuf com a identificacao "
00681 << "wp->myreqid = " << wp->myreqid << endl;
00682 RioErr << "NetMgr::expecttellcmplt wp->pendingsends = "
00683 << wp->pendingsends << ", wp->dupix = " << wp->dupix
00684 << " e xtwork::DUPTABN = " << xtwork::DUPTABN << endl;
00685 #endif
00686
00687
00688
00689 for( int i = 0; i < xtwork::DUPTABN; i++ )
00690 {
00691 if( wp->duptab[ i ].ip != 0 )
00692 {
00693
00694 #ifdef RIO_DEBUG2
00695 in_addr sip;
00696 sip.s_addr = wp->duptab[ i ].ip;
00697 RioErr << "NetMgr::expecttellcmplt cancelando o envio do bloco "
00698 << "na posicao " << i << " de wp->duptab, com as "
00699 << "seguintes informacoes: ip = " << inet_ntoa( sip )
00700 << ", porta = " << ntohs( wp->duptab[ i ].port )
00701 << ", reqid = " << wp->duptab[ i ].reqid << ", seq = "
00702 << wp->duptab[ i ].seq << " e sendreqid = "
00703 << wp->duptab[ i ].sendreqid << endl;
00704 #endif
00705
00706 if( !wp->mgr->d_neti->CancelCopyBlock( wp->duptab[ i ].sendreqid,
00707 result ) )
00708 {
00709 #ifdef RIO_DEBUG2
00710 RioErr << "NetMgr::expecttellcmplt erro ao cancelar o envio "
00711 << "do bloco com a seqreqid "
00712 << wp->duptab[ i ].sendreqid << endl;
00713 #endif
00714 }
00715 }
00716 }
00717 }
00718
00719 expecttellcom((void *) wp);
00720 }
00721
00722
00723
00724
00725
00726
00727
00728 void NetMgr::expecttellsend(void *parm, int result)
00729 {
00730 xtwork *wp = (xtwork *) parm;
00731
00732 #ifdef RIO_DEBUG2
00733 RioErr << "NetMgr::expecttellsend recebido a confirmacao do envio de um "
00734 << "bloco: wp->pendingsends = " << wp->pendingsends
00735 << ", wp->cmplt = " << wp->cmplt << ", result = 0x"
00736 << hex << result << dec << " (" << GetErrorDescription( result )
00737 << ")" << endl;
00738 #endif
00739
00740 wp->pendingsends--;
00741 expecttellcom((void *) wp);
00742 }
00743
00744
00745 void NetMgr::dumppkt(const char *label, char *data, int datal)
00746 {
00747 int off;
00748 int i;
00749 char *s;
00750 char line[100];
00751
00752 RioErr << label;
00753
00754 off = 0;
00755 do
00756 {
00757 s = line;
00758 s += sprintf(s,"%4.4x ", (unsigned) off);
00759
00760 for(i = 0; i < 16 && i < datal; i++, data++)
00761 {
00762 s += sprintf(s, "%2.2x", (unsigned)(*data & 0xff));
00763 if((i & 3) == 3)
00764 {
00765 *s++ = ' ';
00766 }
00767 }
00768
00769 *s++ = '\n';
00770 *s++ = '\0';
00771
00772 if(off > 0x20 && off < 0x5a0)
00773 ;
00774 else
00775 RioErr << line;
00776
00777 datal -= 16;
00778 off += 16;
00779 } while(datal > 0);
00780
00781 RioErr << endl;
00782
00783 }
00784
00785
00786 int NetMgr::FreeBlock( unsigned int block_id, RioStreamType traffic )
00787 {
00788 return( d_neti->FreeBlock( block_id, traffic ) );
00789 }
00790
00791 int NetMgr::FreePendentBlocks( bool useCache, int nbuffers )
00792 {
00793 return( d_neti->FreePendentBlocks( useCache, nbuffers ) );
00794 }
00795
00796 bool NetMgr::thereAreFragments( RioBlock block )
00797 {
00798 return( d_neti->thereAreFragments( block ) );
00799 }
00800
00801 #ifdef RIO_DEBUG2
00802 void NetMgr::printDebug( short debugCode, string message )
00803 {
00804 d_neti->printDebug( debugCode, message );
00805 }
00806 #endif
00807
00808
00809
00810
00811
00812
00813
00814 int NetMgr::CreateKeepaliveThread( void )
00815
00816 {
00817 return( d_neti->CreateKeepaliveThread( ) );
00818 }
00819
00820
00821
00822 bool NetMgr::IsBehindNAT()
00823 {
00824 return( d_neti->IsBehindNAT() );
00825 }
00826
00827
00828
00829 void NetMgr::RequestMapping( int ipaddr, int port )
00830 {
00831 d_neti->RequestMapping( ipaddr, port, 0, &CallbackRequestMapping, this );
00832
00833 m_semalidmap->P();
00834 d_neti->getmyaddrport( &d_myip, &d_myport );
00835 }
00836
00837
00838
00839 void NetMgr::RequestMultipleMappings( struct sockaddr_in *addr, int size )
00840 {
00841 int ipaddr, port;
00842 d_neti->allocMappingVectors( size );
00843 for( int i = 0; i < size; i++ )
00844 {
00845 ipaddr = addr[ i ].sin_addr.s_addr;
00846 port = addr[ i ].sin_port;
00847 d_neti->RequestMapping( ipaddr, port, i, &CallbackRequestMapping,
00848 this );
00849
00850 m_semalidmap->P();
00851
00852
00853 if( i == 0 )
00854 d_neti->getmyaddrport( &d_myip, &d_myport );
00855 }
00856 }
00857
00858
00859
00860
00861 void NetMgr::CallbackRequestMapping( void *param, int result )
00862 {
00863 NetMgr *PNetMgr;
00864 #ifdef RIO_DEBUG1
00865 RioErr << "NetMgr::CallbackRequestMapping chamada. Result = 0x" << hex
00866 << ( unsigned int ) result << dec << endl;
00867 #endif
00868 PNetMgr = (NetMgr *) param;
00869
00870
00871 PNetMgr->m_semalidmap->V();
00872 }
00873
00874
00875
00876 void NetMgr::setLogRotation( CLogRotation *LogRotation )
00877 {
00878 d_neti->setLogRotation( LogRotation );
00879 }
00880
00881
00882
00883 int NetMgr::ExpectCmd( callback_t callback, void *callbackparm,
00884 cmdcallback_t cmdcallback )
00885 {
00886 return d_neti->ExpectCmd( callback, callbackparm, cmdcallback );
00887 }
00888
00889
00890 void NetMgr::SendRst( int ipaddr, int port, int reqid, int result )
00891 {
00892 d_neti->SendRst( ipaddr, port, reqid, result );
00893 }